* [PATCH 06/25] tty: hvc: hvcs: Change return type to void
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>
Since tty_port_install() always returns 0, the return type has changed
to void. Now apply this and remove the obsolete error check.
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
---
drivers/tty/hvc/hvcs.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index cb4db1b..4dfa70c 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -1140,16 +1140,10 @@ static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty)
goto err_put;
}
- retval = tty_port_install(&hvcsd->port, driver, tty);
- if (retval)
- goto err_irq;
+ tty_port_install(&hvcsd->port, driver, tty);
return 0;
-err_irq:
- spin_lock_irqsave(&hvcsd->lock, flags);
- vio_disable_interrupts(hvcsd->vdev);
- spin_unlock_irqrestore(&hvcsd->lock, flags);
- free_irq(irq, hvcsd);
+
err_put:
tty_port_put(&hvcsd->port);
--
2.7.4
^ permalink raw reply related
* [PATCH 05/25] tty: hvc: hvc_console: Change return type to void
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>
Since tty_port_install() always returns 0, the return type has changed
to void. Now apply this and remove the obsolete error check.
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
---
drivers/tty/hvc/hvc_console.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 5414c4a..13fad62 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -329,7 +329,6 @@ static void hvc_unthrottle(struct tty_struct *tty)
static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
{
struct hvc_struct *hp;
- int rc;
/* Auto increments kref reference if found. */
hp = hvc_get_by_index(tty->index);
@@ -337,11 +336,9 @@ static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENODEV;
tty->driver_data = hp;
+ tty_port_install(&hp->port, driver, tty);
- rc = tty_port_install(&hp->port, driver, tty);
- if (rc)
- tty_port_put(&hp->port);
- return rc;
+ return 0;
}
/*
--
2.7.4
^ permalink raw reply related
* [PATCH 04/25] s390: char: tty3270: Change return type to void
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>
Since tty_port_install() always returns 0, the return type has changed
to void. Now apply this and remove the obsolete error check.
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
---
drivers/s390/char/tty3270.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 5b8af27..2915f95 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1017,12 +1017,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
raw3270_activate_view(&tp->view);
port_install:
- rc = tty_port_install(&tp->port, driver, tty);
- if (rc) {
- raw3270_put_view(&tp->view);
- return rc;
- }
-
+ tty_port_install(&tp->port, driver, tty);
tty->driver_data = tp;
return 0;
--
2.7.4
^ permalink raw reply related
* [PATCH 03/25] s390: char: con3215: Change return type to void
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>
Since tty_port_install() always returns 0, the return type has changed
to void. Now apply this and remove the obsolete error check.
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
---
drivers/s390/char/con3215.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 8c9d412..6a9f6d9 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -965,8 +965,9 @@ static int tty3215_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENODEV;
tty->driver_data = raw;
+ tty_port_install(&raw->port, driver, tty);
- return tty_port_install(&raw->port, driver, tty);
+ return 0;
}
/*
--
2.7.4
^ permalink raw reply related
* [PATCH 02/25] isdn: i4l: isdn_tty: Change return type to void
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>
Since tty_port_install() always returns 0, the return type has changed
to void. Now apply this and remove the obsolete error check.
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
---
drivers/isdn/i4l/isdn_tty.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index b730037..3d6b24e 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1481,8 +1481,9 @@ static int isdn_tty_install(struct tty_driver *driver, struct tty_struct *tty)
return -ENODEV;
tty->driver_data = info;
+ tty_port_install(&info->port, driver, tty);
- return tty_port_install(&info->port, driver, tty);
+ return 0;
}
/*
--
2.7.4
^ permalink raw reply related
* [PATCH 01/25] tty: Change return type to void
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
In-Reply-To: <1536029091-4426-1-git-send-email-climbbb.kim@gmail.com>
Many drivers with tty use the tty_stand_install(). But, there is no
need to handle the error, since it always returns 0. So, change the
return type of tty_standard_install() and tty_port_install() to void
type and remove unnecessary exception handling where we use these
functions.
Signed-off-by: Jaejoong Kim <climbbb.kim@gmail.com>
---
drivers/tty/tty_io.c | 10 ++++++----
drivers/tty/tty_port.c | 4 ++--
include/linux/tty.h | 4 ++--
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 32bc3e3..b01cec8 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1196,13 +1196,12 @@ void tty_init_termios(struct tty_struct *tty)
}
EXPORT_SYMBOL_GPL(tty_init_termios);
-int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty)
+void tty_standard_install(struct tty_driver *driver, struct tty_struct *tty)
{
tty_init_termios(tty);
tty_driver_kref_get(driver);
tty->count++;
driver->ttys[tty->index] = tty;
- return 0;
}
EXPORT_SYMBOL_GPL(tty_standard_install);
@@ -1221,8 +1220,11 @@ EXPORT_SYMBOL_GPL(tty_standard_install);
static int tty_driver_install_tty(struct tty_driver *driver,
struct tty_struct *tty)
{
- return driver->ops->install ? driver->ops->install(driver, tty) :
- tty_standard_install(driver, tty);
+ if (driver->ops->install)
+ return driver->ops->install(driver, tty);
+
+ tty_standard_install(driver, tty);
+ return 0;
}
/**
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 25d7368..fd8d40d 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -656,11 +656,11 @@ EXPORT_SYMBOL(tty_port_close);
* to a concrete tty specified by @tty. Use this or tty_port_register_device
* (or both). Call tty_port_link_device as a last resort.
*/
-int tty_port_install(struct tty_port *port, struct tty_driver *driver,
+void tty_port_install(struct tty_port *port, struct tty_driver *driver,
struct tty_struct *tty)
{
tty->port = port;
- return tty_standard_install(driver, tty);
+ tty_standard_install(driver, tty);
}
EXPORT_SYMBOL_GPL(tty_port_install);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index c56e397..63cdac1 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -556,7 +556,7 @@ extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx);
extern void tty_release_struct(struct tty_struct *tty, int idx);
extern int tty_release(struct inode *inode, struct file *filp);
extern void tty_init_termios(struct tty_struct *tty);
-extern int tty_standard_install(struct tty_driver *driver,
+extern void tty_standard_install(struct tty_driver *driver,
struct tty_struct *tty);
extern struct mutex tty_mutex;
@@ -688,7 +688,7 @@ extern int tty_port_close_start(struct tty_port *port,
extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
extern void tty_port_close(struct tty_port *port,
struct tty_struct *tty, struct file *filp);
-extern int tty_port_install(struct tty_port *port, struct tty_driver *driver,
+extern void tty_port_install(struct tty_port *port, struct tty_driver *driver,
struct tty_struct *tty);
extern int tty_port_open(struct tty_port *port,
struct tty_struct *tty, struct file *filp);
--
2.7.4
^ permalink raw reply related
* [PATCH 00/25] Change tty_port(standard)_install's return type
From: Jaejoong Kim @ 2018-09-04 2:44 UTC (permalink / raw)
To: linux-um, netdev, linux-mmc, linux-s390, devel, greybus-dev,
linuxppc-dev, linux-serial, sparclinux, linux-usb,
linux-bluetooth, linux-kernel
Cc: Greg Kroah-Hartman, Jiri Slaby
Many drivers with tty use the tty_stand_install(). But, there is no
need to handle the error, since it always returns 0. So, change the
return type of tty_standard_install() and tty_port_install() to void
type and remove unnecessary exception handling where we use these
functions.
Change return type for tty functions. Patch No.01
tty: Change return type to void
Apply tty_port_install() changes. Patch No.02~14
isdn: i4l: isdn_tty: Change return type to void
...
Bluetooth: Change return type to void
Apply tty_standard_install() changes. Patch No.15~25
um: Change return type to void
...
usb: usb-serial: Change return type to void
Jaejoong Kim (25):
tty: Change return type to void
isdn: i4l: isdn_tty: Change return type to void
s390: char: con3215: Change return type to void
s390: char: tty3270: Change return type to void
tty: hvc: hvc_console: Change return type to void
tty: hvc: hvcs: Change return type to void
tty: mips_ejtag_fdc: Change return type to void
tty: n_gsm: Change return type to void
tty: serial: kgdb_nmi: Change return type to void
tty: synclink: Change return type to void
tty: synclinkmp: Change return type to void
tty: vt: Change return type to void
usb: xhci: dbc: Change return type to void
Bluetooth: Change return type to void
um: Change return type to void
isdn: capi: Change return type to void
misc: pti: Change return type to void
mmc: core: sdio_uart: Change return type to void
staging: fwserial: Change return type to void
staging: gdm724x: gdm_tty: Change return type to void
staging: greybus: uart: Change return type to void
tty: nozomi: Change return type to void
tty: vcc: Change return type to void
usb: cdc-acm: Change return type to void
usb: usb-serial: Change return type to void
arch/um/drivers/line.c | 7 +------
drivers/isdn/capi/capi.c | 10 ++++------
drivers/isdn/i4l/isdn_tty.c | 3 ++-
drivers/misc/pti.c | 28 +++++++++++++---------------
drivers/mmc/core/sdio_uart.c | 11 ++++-------
drivers/s390/char/con3215.c | 3 ++-
drivers/s390/char/tty3270.c | 7 +------
drivers/staging/fwserial/fwserial.c | 22 ++++++++--------------
drivers/staging/gdm724x/gdm_tty.c | 11 +++--------
drivers/staging/greybus/uart.c | 10 ++--------
drivers/tty/hvc/hvc_console.c | 7 ++-----
drivers/tty/hvc/hvcs.c | 10 ++--------
drivers/tty/mips_ejtag_fdc.c | 4 +++-
drivers/tty/n_gsm.c | 9 +--------
drivers/tty/nozomi.c | 8 +++-----
drivers/tty/serial/kgdb_nmi.c | 11 +----------
drivers/tty/synclink.c | 3 ++-
drivers/tty/synclinkmp.c | 3 ++-
drivers/tty/tty_io.c | 10 ++++++----
drivers/tty/tty_port.c | 4 ++--
drivers/tty/vcc.c | 5 +----
drivers/tty/vt/vt.c | 5 +----
drivers/usb/class/cdc-acm.c | 10 +---------
drivers/usb/host/xhci-dbgtty.c | 3 ++-
drivers/usb/serial/usb-serial.c | 6 +-----
include/linux/tty.h | 4 ++--
net/bluetooth/rfcomm/tty.c | 7 +------
27 files changed, 73 insertions(+), 148 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH v7 1/4] gpiolib: Pass bitmaps, not integer arrays, to get/set array
From: Geert Uytterhoeven @ 2018-09-03 15:07 UTC (permalink / raw)
To: Janusz Krzysztofik
Cc: Linus Walleij, Jonathan Corbet, Miguel Ojeda Sandonis,
peter.korsgaard, Peter Rosin, Ulf Hansson, Andrew Lunn,
Florian Fainelli, David S. Miller, Dominik Brodowski, Greg KH,
Kishon Vijay Abraham I, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, Hartmut Knaack, Peter Meerwald, Jiri Slaby,
Willy Tarreau, open list:DOCUMENTATION
In-Reply-To: <20180902120144.6855-2-jmkrzyszt@gmail.com>
Hi Janusz,
On Sun, Sep 2, 2018 at 2:01 PM Janusz Krzysztofik <jmkrzyszt@gmail.com> wrote:
> Most users of get/set array functions iterate consecutive bits of data,
> usually a single integer, while processing array of results obtained
> from, or building an array of values to be passed to those functions.
> Save time wasted on those iterations by changing the functions' API to
> accept bitmaps.
>
> All current users are updated as well.
>
> More benefits from the change are expected as soon as planned support
> for accepting/passing those bitmaps directly from/to respective GPIO
> chip callbacks if applicable is implemented.
>
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Sebastien Bourdelin <sebastien.bourdelin@savoirfairelinux.com>
> Cc: Lukas Wunner <lukas@wunner.de>
> Cc: Peter Korsgaard <peter.korsgaard@barco.com>
> Cc: Peter Rosin <peda@axentia.se>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Rojhalat Ibrahim <imr@rtschenk.de>
> Cc: Dominik Brodowski <linux@dominikbrodowski.net>
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Cc: Kishon Vijay Abraham I <kishon@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: Michael Hennerich <Michael.Hennerich@analog.com>
> Cc: Jonathan Cameron <jic23@kernel.org>
> Cc: Hartmut Knaack <knaack.h@gmx.de>
> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: Yegor Yefremov <yegorslists@googlemail.com>
> Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
> Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
> --- a/drivers/auxdisplay/hd44780.c
> +++ b/drivers/auxdisplay/hd44780.c
> @@ -62,17 +62,12 @@ static void hd44780_strobe_gpio(struct hd44780 *hd)
> /* write to an LCD panel register in 8 bit GPIO mode */
> static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
> {
> - int values[10]; /* for DATA[0-7], RS, RW */
> - unsigned int i, n;
> -
> - for (i = 0; i < 8; i++)
> - values[PIN_DATA0 + i] = !!(val & BIT(i));
> - values[PIN_CTRL_RS] = rs;
> - n = 9;
> - if (hd->pins[PIN_CTRL_RW]) {
> - values[PIN_CTRL_RW] = 0;
> - n++;
> - }
> + DECLARE_BITMAP(values, 10); /* for DATA[0-7], RS, RW */
> + unsigned int n;
> +
> + *values = val;
Given DECLARE_BITMAP() creates an array, the above line looks a bit funny now.
IMHO, either you use
unsigned long values;
values = val;
__assign_bit(8, &values, rs);
or
DECLARE_BITMAP(values, 10);
values[0] = val;
__assign_bit(8, values, rs);
Nevertheless, for hd44780.c:
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v7 1/4] gpiolib: Pass bitmaps, not integer arrays, to get/set array
From: Geert Uytterhoeven @ 2018-09-03 14:24 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Janusz Krzysztofik, Linus Walleij, Jonathan Corbet,
Miguel Ojeda Sandonis, peter.korsgaard, Peter Rosin, Ulf Hansson,
Andrew Lunn, Florian Fainelli, David S. Miller, Dominik Brodowski,
Greg KH, Kishon Vijay Abraham I, Lars-Peter Clausen,
Michael Hennerich, Jonathan Cameron, Hartmut Knaack,
Peter Meerwald, Jiri Slaby, Willy Tarreau
In-Reply-To: <20180903043129.GA17856@bombadil.infradead.org>
On Mon, Sep 3, 2018 at 6:31 AM Matthew Wilcox <willy@infradead.org> wrote:
> > +++ b/drivers/auxdisplay/hd44780.c
> > @@ -62,17 +62,12 @@ static void hd44780_strobe_gpio(struct hd44780 *hd)
> > /* write to an LCD panel register in 8 bit GPIO mode */
> > static void hd44780_write_gpio8(struct hd44780 *hd, u8 val, unsigned int rs)
> > {
> > - int values[10]; /* for DATA[0-7], RS, RW */
> > - unsigned int i, n;
> > -
> > - for (i = 0; i < 8; i++)
> > - values[PIN_DATA0 + i] = !!(val & BIT(i));
> > - values[PIN_CTRL_RS] = rs;
> > - n = 9;
> > - if (hd->pins[PIN_CTRL_RW]) {
> > - values[PIN_CTRL_RW] = 0;
> > - n++;
> > - }
> > + DECLARE_BITMAP(values, 10); /* for DATA[0-7], RS, RW */
> > + unsigned int n;
> > +
> > + *values = val;
> > + __assign_bit(8, values, rs);
> > + n = hd->pins[PIN_CTRL_RW] ? 10 : 9;
>
> Doesn't this assume little endian bitmaps? Has anyone tested this on
> big-endian machines?
include/linux/bitops.h:
static __always_inline void __assign_bit(long nr, volatile unsigned long *addr,
bool value)
{
if (value)
__set_bit(nr, addr);
else
__clear_bit(nr, addr);
}
include/asm-generic/bitops/non-atomic.h:
static inline void __set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p |= mask;
}
include/linux/bits.h:
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
Looks like native endianness to me.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v7 3/4] gpiolib: Pass array info to get/set array functions
From: Geert Uytterhoeven @ 2018-09-03 14:21 UTC (permalink / raw)
To: Janusz Krzysztofik
Cc: Linus Walleij, Jonathan Corbet, Miguel Ojeda Sandonis,
peter.korsgaard, Peter Rosin, Ulf Hansson, Andrew Lunn,
Florian Fainelli, David S. Miller, Dominik Brodowski, Greg KH,
Kishon Vijay Abraham I, Lars-Peter Clausen, Michael Hennerich,
Jonathan Cameron, Hartmut Knaack, Peter Meerwald, Jiri Slaby,
Willy Tarreau, open list:DOCUMENTATION
In-Reply-To: <20180902120144.6855-4-jmkrzyszt@gmail.com>
On Sun, Sep 2, 2018 at 2:01 PM Janusz Krzysztofik <jmkrzyszt@gmail.com> wrote:
> In order to make use of array info obtained from gpiod_get_array() and
> speed up processing of arrays matching single GPIO chip layout, that
> information must be passed to get/set array functions. Extend the
> functions' API with that additional parameter and update all users.
> Pass NULL if a user bulids an array itself from single GPIOs.
builds
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 2/2] serial: uartps: Change uart ID port allocation
From: Michal Simek @ 2018-09-03 13:14 UTC (permalink / raw)
To: linux-kernel, monstr
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <0ee4683a7d3927c2ef20b1e106720e6154811cd7.1535980468.git.michal.simek@xilinx.com>
For IPs which have alias algorightm all the time using that alias and
minor number. It means serial20 alias ends up as ttyPS20.
If alias is not setup for probed IP instance the first unused position is
used but that needs to be checked if it is really empty because another
instance doesn't need to be probed at that time. of_alias_get_alias_list()
fills alias bitmap which exactly shows which ID is free.
If alias pointing to different not compatible IP, it is free to use.
cdns_get_id() call is placed below structure allocation to simplify
error path.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Needs to be applied on the top of
https://lkml.org/lkml/2018/9/3/404
https://lkml.org/lkml/2018/9/3/400 (minor that's why just in case)
---
drivers/tty/serial/xilinx_uartps.c | 106 ++++++++++++++++++++++++++++++++-----
1 file changed, 93 insertions(+), 13 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 71c032744dae..61c4a644e143 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -30,7 +30,6 @@
#define CDNS_UART_TTY_NAME "ttyPS"
#define CDNS_UART_NAME "xuartps"
#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
-#define CDNS_UART_NR_PORTS 2
#define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
#define CDNS_UART_REGISTER_SPACE 0x1000
@@ -1370,6 +1369,85 @@ static int __maybe_unused cdns_runtime_resume(struct device *dev)
};
MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
+/*
+ * Maximum number of instances without alias IDs but if there is alias
+ * which target "< MAX_UART_INSTANCES" range this ID can't be used.
+ */
+#define MAX_UART_INSTANCES 32
+
+/* Stores static aliases list */
+static DECLARE_BITMAP(alias_bitmap, MAX_UART_INSTANCES);
+static int alias_bitmap_initialized;
+
+/* Stores actual bitmap of allocated IDs with alias IDs together */
+static DECLARE_BITMAP(bitmap, MAX_UART_INSTANCES);
+/* Protect bitmap operations to have unique IDs */
+static DEFINE_MUTEX(bitmap_lock);
+
+static int cdns_get_id(struct platform_device *pdev)
+{
+ int id;
+
+ mutex_lock(&bitmap_lock);
+
+ /* Alias list is stable that's why get alias bitmap only once */
+ if (!alias_bitmap_initialized) {
+ of_alias_get_alias_list(cdns_uart_of_match, "serial",
+ alias_bitmap, MAX_UART_INSTANCES);
+ alias_bitmap_initialized++;
+ }
+
+ /* Make sure that alias ID is not taken by instance without alias */
+ bitmap_or(bitmap, bitmap, alias_bitmap, MAX_UART_INSTANCES);
+
+ dev_dbg(&pdev->dev, "Alias bitmap: %*pb\n",
+ MAX_UART_INSTANCES, bitmap);
+
+ /* Look for a serialN alias */
+ id = of_alias_get_id(pdev->dev.of_node, "serial");
+ if (id < 0) {
+ dev_warn(&pdev->dev,
+ "No serial alias passed. Using the first free id\n");
+
+ /*
+ * Start with id 0 and check if there is no serial0 alias
+ * which points to device which is compatible with this driver.
+ * If alias exists then try next free position.
+ */
+ id = 0;
+
+ for (;;) {
+ dev_info(&pdev->dev, "Checking id %d\n", id);
+ id = find_next_zero_bit(bitmap, MAX_UART_INSTANCES, id);
+
+ /* No free empty instance */
+ if (id == MAX_UART_INSTANCES) {
+ dev_err(&pdev->dev, "No free ID\n");
+ mutex_unlock(&bitmap_lock);
+ return -EINVAL;
+ }
+
+ dev_dbg(&pdev->dev, "The empty id is %d\n", id);
+ /* Check if ID is empty */
+ if (!test_and_set_bit(id, bitmap)) {
+ /* Break the loop if bit is taken */
+ dev_dbg(&pdev->dev,
+ "Selected ID %d allocation passed\n",
+ id);
+ break;
+ }
+ dev_dbg(&pdev->dev,
+ "Selected ID %d allocation failed\n", id);
+ /* if taking bit fails then try next one */
+ id++;
+ }
+ }
+
+ mutex_unlock(&bitmap_lock);
+
+ return id;
+}
+
/**
* cdns_uart_probe - Platform driver probe
* @pdev: Pointer to the platform device structure
@@ -1403,21 +1481,17 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (!cdns_uart_uart_driver)
return -ENOMEM;
- /* Look for a serialN alias */
- cdns_uart_data->id = of_alias_get_id(pdev->dev.of_node, "serial");
+ cdns_uart_data->id = cdns_get_id(pdev);
if (cdns_uart_data->id < 0)
- cdns_uart_data->id = 0;
-
- if (cdns_uart_data->id >= CDNS_UART_NR_PORTS) {
- dev_err(&pdev->dev, "Cannot get uart_port structure\n");
- return -ENODEV;
- }
+ return cdns_uart_data->id;
/* There is a need to use unique driver name */
driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
CDNS_UART_NAME, cdns_uart_data->id);
- if (!driver_name)
- return -ENOMEM;
+ if (!driver_name) {
+ rc = -ENOMEM;
+ goto err_out_id;
+ }
cdns_uart_uart_driver->owner = THIS_MODULE;
cdns_uart_uart_driver->driver_name = driver_name;
@@ -1446,7 +1520,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
rc = uart_register_driver(cdns_uart_uart_driver);
if (rc < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
- return rc;
+ goto err_out_id;
}
cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
@@ -1587,7 +1661,10 @@ static int cdns_uart_probe(struct platform_device *pdev)
clk_disable_unprepare(cdns_uart_data->pclk);
err_out_unregister_driver:
uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-
+err_out_id:
+ mutex_lock(&bitmap_lock);
+ clear_bit(cdns_uart_data->id, bitmap);
+ mutex_unlock(&bitmap_lock);
return rc;
}
@@ -1610,6 +1687,9 @@ static int cdns_uart_remove(struct platform_device *pdev)
#endif
rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
port->mapbase = 0;
+ mutex_lock(&bitmap_lock);
+ clear_bit(cdns_uart_data->id, bitmap);
+ mutex_unlock(&bitmap_lock);
clk_disable_unprepare(cdns_uart_data->uartclk);
clk_disable_unprepare(cdns_uart_data->pclk);
pm_runtime_disable(&pdev->dev);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 10/10] serial: uartps: Move Port ID to device data structure
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
Record port ID in device data structure to be have it connected to
certain instance.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- New patch in series
Changes in v2: None
drivers/tty/serial/xilinx_uartps.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index d838612eda6f..71c032744dae 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -181,6 +181,7 @@
* @pclk: APB clock
* @cdns_uart_driver: Pointer to UART driver
* @baud: Current baud rate
+ * @id: Port ID
* @clk_rate_change_nb: Notifier block for clock changes
* @quirks: Flags for RXBS support.
*/
@@ -190,6 +191,7 @@ struct cdns_uart {
struct clk *pclk;
struct uart_driver *cdns_uart_driver;
unsigned int baud;
+ int id;
struct notifier_block clk_rate_change_nb;
u32 quirks;
};
@@ -1376,7 +1378,7 @@ static int __maybe_unused cdns_runtime_resume(struct device *dev)
*/
static int cdns_uart_probe(struct platform_device *pdev)
{
- int rc, id, irq;
+ int rc, irq;
struct uart_port *port;
struct resource *res;
struct cdns_uart *cdns_uart_data;
@@ -1402,18 +1404,18 @@ static int cdns_uart_probe(struct platform_device *pdev)
return -ENOMEM;
/* Look for a serialN alias */
- id = of_alias_get_id(pdev->dev.of_node, "serial");
- if (id < 0)
- id = 0;
+ cdns_uart_data->id = of_alias_get_id(pdev->dev.of_node, "serial");
+ if (cdns_uart_data->id < 0)
+ cdns_uart_data->id = 0;
- if (id >= CDNS_UART_NR_PORTS) {
+ if (cdns_uart_data->id >= CDNS_UART_NR_PORTS) {
dev_err(&pdev->dev, "Cannot get uart_port structure\n");
return -ENODEV;
}
/* There is a need to use unique driver name */
driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
- CDNS_UART_NAME, id);
+ CDNS_UART_NAME, cdns_uart_data->id);
if (!driver_name)
return -ENOMEM;
@@ -1421,7 +1423,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
cdns_uart_uart_driver->driver_name = driver_name;
cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
- cdns_uart_uart_driver->minor = id;
+ cdns_uart_uart_driver->minor = cdns_uart_data->id;
cdns_uart_uart_driver->nr = 1;
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
@@ -1432,7 +1434,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
sizeof(cdns_uart_console->name));
- cdns_uart_console->index = id;
+ cdns_uart_console->index = cdns_uart_data->id;
cdns_uart_console->write = cdns_uart_console_write;
cdns_uart_console->device = uart_console_device;
cdns_uart_console->setup = cdns_uart_console_setup;
@@ -1454,7 +1456,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
* registration because tty_driver structure is not filled.
* name_base is 0 by default.
*/
- cdns_uart_uart_driver->tty_driver->name_base = id;
+ cdns_uart_uart_driver->tty_driver->name_base = cdns_uart_data->id;
match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
if (match && match->data) {
--
1.9.1
^ permalink raw reply related
* [PATCH v3 09/10] serial: uartps: Register own uart console and driver structures
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
Every instance is registering own struct console and struct uart_driver
with minor number which corresponds to alias ID (or 0 now) and with 1 uart
port. The same alias ID is saved to tty_driver->name_base which is key
field for creating ttyPSX name.
Because name_base and minor number are setup already there is no need to
setup any port->line number because 0 is the right value.
Unfortunately this driver is setting up major number to 0 for using
dynamic assignment and kernel is allocating different major numbers for
every instance instead of using the same major and different minor
number.
~# ls -la /dev/ttyPS*
crw------- 1 root root 252, 0 Jan 1 03:36 /dev/ttyPS0
crw--w---- 1 root root 253, 1 Jan 1 00:00 /dev/ttyPS1
When major number is not 0. For example 252 then major/minor
combinations are in expected form
~# ls -la /dev/ttyPS*
crw------- 1 root root 252, 0 Jan 1 04:04 /dev/ttyPS0
crw--w---- 1 root root 252, 1 Jan 1 00:00 /dev/ttyPS1
Driver is not freeing struct cdns_uart_console in case that instance is
not used as console. The reason is that console is incorrectly unregistred
and "console [0] disabled" message will be shown.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- Rebase on the top of previous broken patch
- Change patch subject ("was serial: uartps: Remove CDNS_UART_NR_PORTS
macro")
- Keep CDNS_UART_NR_PORTS in this patch and remove it in next one and
align commit message to reflect this
- Allocate struct console dynamically too to be unique for every
instance
- Cleanup error path
Changes in v2:
- Register one uart_driver with unique minor at probe time
---
drivers/tty/serial/xilinx_uartps.c | 93 ++++++++++++++++++++++----------------
1 file changed, 55 insertions(+), 38 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 0e578c0a8ce0..d838612eda6f 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -30,7 +30,6 @@
#define CDNS_UART_TTY_NAME "ttyPS"
#define CDNS_UART_NAME "xuartps"
#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
-#define CDNS_UART_MINOR 0 /* works best with devtmpfs */
#define CDNS_UART_NR_PORTS 2
#define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
#define CDNS_UART_REGISTER_SPACE 0x1000
@@ -1099,8 +1098,6 @@ static void cdns_uart_pm(struct uart_port *port, unsigned int state,
#endif
};
-static struct uart_driver cdns_uart_uart_driver;
-
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/**
* cdns_uart_console_putchar - write the character to the FIFO buffer
@@ -1240,16 +1237,6 @@ static int cdns_uart_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-
-static struct console cdns_uart_console = {
- .name = CDNS_UART_TTY_NAME,
- .write = cdns_uart_console_write,
- .device = uart_console_device,
- .setup = cdns_uart_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
- .data = &cdns_uart_uart_driver,
-};
#endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
#ifdef CONFIG_PM_SLEEP
@@ -1381,9 +1368,6 @@ static int __maybe_unused cdns_runtime_resume(struct device *dev)
};
MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
-/* Temporary variable for storing number of instances */
-static int instances;
-
/**
* cdns_uart_probe - Platform driver probe
* @pdev: Pointer to the platform device structure
@@ -1397,6 +1381,11 @@ static int cdns_uart_probe(struct platform_device *pdev)
struct resource *res;
struct cdns_uart *cdns_uart_data;
const struct of_device_id *match;
+ struct uart_driver *cdns_uart_uart_driver;
+ char *driver_name;
+#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
+ struct console *cdns_uart_console;
+#endif
cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data),
GFP_KERNEL);
@@ -1406,6 +1395,12 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (!port)
return -ENOMEM;
+ cdns_uart_uart_driver = devm_kzalloc(&pdev->dev,
+ sizeof(*cdns_uart_uart_driver),
+ GFP_KERNEL);
+ if (!cdns_uart_uart_driver)
+ return -ENOMEM;
+
/* Look for a serialN alias */
id = of_alias_get_id(pdev->dev.of_node, "serial");
if (id < 0)
@@ -1416,25 +1411,50 @@ static int cdns_uart_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (!cdns_uart_uart_driver.state) {
- cdns_uart_uart_driver.owner = THIS_MODULE;
- cdns_uart_uart_driver.driver_name = CDNS_UART_NAME;
- cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME;
- cdns_uart_uart_driver.major = CDNS_UART_MAJOR;
- cdns_uart_uart_driver.minor = CDNS_UART_MINOR;
- cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
+ /* There is a need to use unique driver name */
+ driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
+ CDNS_UART_NAME, id);
+ if (!driver_name)
+ return -ENOMEM;
+
+ cdns_uart_uart_driver->owner = THIS_MODULE;
+ cdns_uart_uart_driver->driver_name = driver_name;
+ cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
+ cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
+ cdns_uart_uart_driver->minor = id;
+ cdns_uart_uart_driver->nr = 1;
+
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
- cdns_uart_uart_driver.cons = &cdns_uart_console;
+ cdns_uart_console = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_console),
+ GFP_KERNEL);
+ if (!cdns_uart_console)
+ return -ENOMEM;
+
+ strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
+ sizeof(cdns_uart_console->name));
+ cdns_uart_console->index = id;
+ cdns_uart_console->write = cdns_uart_console_write;
+ cdns_uart_console->device = uart_console_device;
+ cdns_uart_console->setup = cdns_uart_console_setup;
+ cdns_uart_console->flags = CON_PRINTBUFFER;
+ cdns_uart_console->data = cdns_uart_uart_driver;
+ cdns_uart_uart_driver->cons = cdns_uart_console;
#endif
- rc = uart_register_driver(&cdns_uart_uart_driver);
- if (rc < 0) {
- dev_err(&pdev->dev, "Failed to register driver\n");
- return rc;
- }
+ rc = uart_register_driver(cdns_uart_uart_driver);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Failed to register driver\n");
+ return rc;
}
- cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
+ cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
+
+ /*
+ * Setting up proper name_base needs to be done after uart
+ * registration because tty_driver structure is not filled.
+ * name_base is 0 by default.
+ */
+ cdns_uart_uart_driver->tty_driver->name_base = id;
match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
if (match && match->data) {
@@ -1505,7 +1525,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
port->flags = UPF_BOOT_AUTOCONF;
port->ops = &cdns_uart_ops;
port->fifosize = CDNS_UART_FIFO_SIZE;
- port->line = id;
/*
* Register the port.
@@ -1536,7 +1555,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
console_port = port;
#endif
- rc = uart_add_one_port(&cdns_uart_uart_driver, port);
+ rc = uart_add_one_port(cdns_uart_uart_driver, port);
if (rc) {
dev_err(&pdev->dev,
"uart_add_one_port() failed; err=%i\n", rc);
@@ -1546,11 +1565,10 @@ static int cdns_uart_probe(struct platform_device *pdev)
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/* This is not port which is used for console that's why clean it up */
if (console_port == port &&
- !(cdns_uart_uart_driver.cons->flags & CON_ENABLED))
+ !(cdns_uart_uart_driver->cons->flags & CON_ENABLED))
console_port = NULL;
#endif
- instances++;
return 0;
err_out_pm_disable:
@@ -1566,8 +1584,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
err_out_clk_dis_pclk:
clk_disable_unprepare(cdns_uart_data->pclk);
err_out_unregister_driver:
- if (!instances)
- uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+ uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+
return rc;
}
@@ -1601,8 +1619,7 @@ static int cdns_uart_remove(struct platform_device *pdev)
console_port = NULL;
#endif
- if (!--instances)
- uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+ uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v3 08/10] serial: uartps: Change logic how console_port is setup
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
Change logic how console_port is setup by using CON_ENABLED flag
instead of index. There will be unique cdns_uart_console() structures
that's why code can't use id for console_port assignment.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- New patch in series
Changes in v2: None
drivers/tty/serial/xilinx_uartps.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 61087233f411..0e578c0a8ce0 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1532,7 +1532,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
* If register_console() don't assign value, then console_port pointer
* is cleanup.
*/
- if (cdns_uart_uart_driver.cons->index == -1)
+ if (!console_port)
console_port = port;
#endif
@@ -1545,7 +1545,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/* This is not port which is used for console that's why clean it up */
- if (cdns_uart_uart_driver.cons->index == -1)
+ if (console_port == port &&
+ !(cdns_uart_uart_driver.cons->flags & CON_ENABLED))
console_port = NULL;
#endif
@@ -1594,6 +1595,12 @@ static int cdns_uart_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
+
+#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
+ if (console_port == port)
+ console_port = NULL;
+#endif
+
if (!--instances)
uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 07/10] serial: uartps: Fill struct uart_driver in probe()
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
This is preparation step for dynamic port allocation without
CDNS_UART_NR_PORTS macro. Fill the structure only once at probe.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- s/,/;/ in filling structure
- get cdns_uart_uart_driver out of PS_UART_CONSOLE ifdefs
Changes in v2:
- new patch - it can be sent separately too
drivers/tty/serial/xilinx_uartps.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 54735a7f9960..61087233f411 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1099,6 +1099,8 @@ static void cdns_uart_pm(struct uart_port *port, unsigned int state,
#endif
};
+static struct uart_driver cdns_uart_uart_driver;
+
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
/**
* cdns_uart_console_putchar - write the character to the FIFO buffer
@@ -1239,8 +1241,6 @@ static int cdns_uart_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-static struct uart_driver cdns_uart_uart_driver;
-
static struct console cdns_uart_console = {
.name = CDNS_UART_TTY_NAME,
.write = cdns_uart_console_write,
@@ -1252,18 +1252,6 @@ static int cdns_uart_console_setup(struct console *co, char *options)
};
#endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
-static struct uart_driver cdns_uart_uart_driver = {
- .owner = THIS_MODULE,
- .driver_name = CDNS_UART_NAME,
- .dev_name = CDNS_UART_TTY_NAME,
- .major = CDNS_UART_MAJOR,
- .minor = CDNS_UART_MINOR,
- .nr = CDNS_UART_NR_PORTS,
-#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
- .cons = &cdns_uart_console,
-#endif
-};
-
#ifdef CONFIG_PM_SLEEP
/**
* cdns_uart_suspend - suspend event
@@ -1429,6 +1417,16 @@ static int cdns_uart_probe(struct platform_device *pdev)
}
if (!cdns_uart_uart_driver.state) {
+ cdns_uart_uart_driver.owner = THIS_MODULE;
+ cdns_uart_uart_driver.driver_name = CDNS_UART_NAME;
+ cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME;
+ cdns_uart_uart_driver.major = CDNS_UART_MAJOR;
+ cdns_uart_uart_driver.minor = CDNS_UART_MINOR;
+ cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
+#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
+ cdns_uart_uart_driver.cons = &cdns_uart_console;
+#endif
+
rc = uart_register_driver(&cdns_uart_uart_driver);
if (rc < 0) {
dev_err(&pdev->dev, "Failed to register driver\n");
--
1.9.1
^ permalink raw reply related
* [PATCH v3 06/10] serial: uartps: Move register to probe based on run time detection
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
Register uart driver in probe to be able to register one device with
unique major/minor separately. Also calculate number of instances of
this driver to be able to call uart_unregister_driver() when there is no
instance.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- Fix uart_unregister_driver() in error path or when driver is removed.
- Change commit message
Changes in v2:
- Remove nr field logic
Discussed here: https://patchwork.kernel.org/patch/9738445/
The same solution is done in pl011 driver.
---
drivers/tty/serial/xilinx_uartps.c | 42 +++++++++++++++++++++-----------------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index a3e97ccb376d..54735a7f9960 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1393,6 +1393,9 @@ static int __maybe_unused cdns_runtime_resume(struct device *dev)
};
MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
+/* Temporary variable for storing number of instances */
+static int instances;
+
/**
* cdns_uart_probe - Platform driver probe
* @pdev: Pointer to the platform device structure
@@ -1425,6 +1428,14 @@ static int cdns_uart_probe(struct platform_device *pdev)
return -ENODEV;
}
+ if (!cdns_uart_uart_driver.state) {
+ rc = uart_register_driver(&cdns_uart_uart_driver);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Failed to register driver\n");
+ return rc;
+ }
+ }
+
cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
@@ -1442,7 +1453,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
}
if (IS_ERR(cdns_uart_data->pclk)) {
dev_err(&pdev->dev, "pclk clock not found.\n");
- return PTR_ERR(cdns_uart_data->pclk);
+ rc = PTR_ERR(cdns_uart_data->pclk);
+ goto err_out_unregister_driver;
}
cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk");
@@ -1453,13 +1465,14 @@ static int cdns_uart_probe(struct platform_device *pdev)
}
if (IS_ERR(cdns_uart_data->uartclk)) {
dev_err(&pdev->dev, "uart_clk clock not found.\n");
- return PTR_ERR(cdns_uart_data->uartclk);
+ rc = PTR_ERR(cdns_uart_data->uartclk);
+ goto err_out_unregister_driver;
}
rc = clk_prepare_enable(cdns_uart_data->pclk);
if (rc) {
dev_err(&pdev->dev, "Unable to enable pclk clock.\n");
- return rc;
+ goto err_out_unregister_driver;
}
rc = clk_prepare_enable(cdns_uart_data->uartclk);
if (rc) {
@@ -1538,6 +1551,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
console_port = NULL;
#endif
+ instances++;
return 0;
err_out_pm_disable:
@@ -1552,7 +1566,9 @@ static int cdns_uart_probe(struct platform_device *pdev)
clk_disable_unprepare(cdns_uart_data->uartclk);
err_out_clk_dis_pclk:
clk_disable_unprepare(cdns_uart_data->pclk);
-
+err_out_unregister_driver:
+ if (!instances)
+ uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
}
@@ -1580,6 +1596,8 @@ static int cdns_uart_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
+ if (!--instances)
+ uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
return rc;
}
@@ -1595,28 +1613,14 @@ static int cdns_uart_remove(struct platform_device *pdev)
static int __init cdns_uart_init(void)
{
- int retval = 0;
-
- /* Register the cdns_uart driver with the serial core */
- retval = uart_register_driver(&cdns_uart_uart_driver);
- if (retval)
- return retval;
-
/* Register the platform driver */
- retval = platform_driver_register(&cdns_uart_platform_driver);
- if (retval)
- uart_unregister_driver(&cdns_uart_uart_driver);
-
- return retval;
+ return platform_driver_register(&cdns_uart_platform_driver);
}
static void __exit cdns_uart_exit(void)
{
/* Unregister the platform driver */
platform_driver_unregister(&cdns_uart_platform_driver);
-
- /* Unregister the cdns_uart driver */
- uart_unregister_driver(&cdns_uart_uart_driver);
}
arch_initcall(cdns_uart_init);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 05/10] serial: uartps: Move alias reading higher in probe()
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
This cosmetic change is done only for having next patch much easier to
read. Moving id setup higher in probe is not affecting any usage of this
driver and it also simplify error path.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3: None
Changes in v2:
- new patch - it can be sent separately too
drivers/tty/serial/xilinx_uartps.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 5bd2b0607df6..a3e97ccb376d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1415,6 +1415,16 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (!port)
return -ENOMEM;
+ /* Look for a serialN alias */
+ id = of_alias_get_id(pdev->dev.of_node, "serial");
+ if (id < 0)
+ id = 0;
+
+ if (id >= CDNS_UART_NR_PORTS) {
+ dev_err(&pdev->dev, "Cannot get uart_port structure\n");
+ return -ENODEV;
+ }
+
cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
@@ -1476,16 +1486,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
&cdns_uart_data->clk_rate_change_nb))
dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
#endif
- /* Look for a serialN alias */
- id = of_alias_get_id(pdev->dev.of_node, "serial");
- if (id < 0)
- id = 0;
-
- if (id >= CDNS_UART_NR_PORTS) {
- dev_err(&pdev->dev, "Cannot get uart_port structure\n");
- rc = -ENODEV;
- goto err_out_notif_unreg;
- }
/* At this point, we've got an empty uart_port struct, initialize it */
spin_lock_init(&port->lock);
@@ -1544,7 +1544,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
-err_out_notif_unreg:
#ifdef CONFIG_COMMON_CLK
clk_notifier_unregister(cdns_uart_data->uartclk,
&cdns_uart_data->clk_rate_change_nb);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 04/10] serial: uartps: Do not use static struct uart_driver out of probe()
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
cdns_uart_suspend()/resume() and remove() are using static reference
to struct uart_driver. Assign this reference to private data structure
as preparation step for dynamic struct uart_driver allocation.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3: None
Changes in v2:
- new patch - it can be sent separately too
drivers/tty/serial/xilinx_uartps.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index fc0ecaf3615d..5bd2b0607df6 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -180,6 +180,7 @@
* @port: Pointer to the UART port
* @uartclk: Reference clock
* @pclk: APB clock
+ * @cdns_uart_driver: Pointer to UART driver
* @baud: Current baud rate
* @clk_rate_change_nb: Notifier block for clock changes
* @quirks: Flags for RXBS support.
@@ -188,6 +189,7 @@ struct cdns_uart {
struct uart_port *port;
struct clk *uartclk;
struct clk *pclk;
+ struct uart_driver *cdns_uart_driver;
unsigned int baud;
struct notifier_block clk_rate_change_nb;
u32 quirks;
@@ -1272,6 +1274,7 @@ static int cdns_uart_console_setup(struct console *co, char *options)
static int cdns_uart_suspend(struct device *device)
{
struct uart_port *port = dev_get_drvdata(device);
+ struct cdns_uart *cdns_uart = port->private_data;
int may_wake;
may_wake = device_may_wakeup(device);
@@ -1295,7 +1298,7 @@ static int cdns_uart_suspend(struct device *device)
* Call the API provided in serial_core.c file which handles
* the suspend.
*/
- return uart_suspend_port(&cdns_uart_uart_driver, port);
+ return uart_suspend_port(cdns_uart->cdns_uart_driver, port);
}
/**
@@ -1307,6 +1310,7 @@ static int cdns_uart_suspend(struct device *device)
static int cdns_uart_resume(struct device *device)
{
struct uart_port *port = dev_get_drvdata(device);
+ struct cdns_uart *cdns_uart = port->private_data;
unsigned long flags = 0;
u32 ctrl_reg;
int may_wake;
@@ -1314,8 +1318,6 @@ static int cdns_uart_resume(struct device *device)
may_wake = device_may_wakeup(device);
if (console_suspend_enabled && !may_wake) {
- struct cdns_uart *cdns_uart = port->private_data;
-
clk_enable(cdns_uart->pclk);
clk_enable(cdns_uart->uartclk);
@@ -1349,7 +1351,7 @@ static int cdns_uart_resume(struct device *device)
spin_unlock_irqrestore(&port->lock, flags);
}
- return uart_resume_port(&cdns_uart_uart_driver, port);
+ return uart_resume_port(cdns_uart->cdns_uart_driver, port);
}
#endif /* ! CONFIG_PM_SLEEP */
static int __maybe_unused cdns_runtime_suspend(struct device *dev)
@@ -1413,6 +1415,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
if (!port)
return -ENOMEM;
+ cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
+
match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
if (match && match->data) {
const struct cdns_platform_data *data = match->data;
@@ -1570,7 +1574,7 @@ static int cdns_uart_remove(struct platform_device *pdev)
clk_notifier_unregister(cdns_uart_data->uartclk,
&cdns_uart_data->clk_rate_change_nb);
#endif
- rc = uart_remove_one_port(&cdns_uart_uart_driver, port);
+ rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
port->mapbase = 0;
clk_disable_unprepare(cdns_uart_data->uartclk);
clk_disable_unprepare(cdns_uart_data->pclk);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 03/10] serial: uartps: Fix suspend functionality
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Nava kishore Manne, Jiri Slaby, linux-serial, Greg Kroah-Hartman,
linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
From: Nava kishore Manne <nava.manne@xilinx.com>
The driver's suspend/resume functions were buggy.
If UART node contains any child node in the DT and
the child is established a communication path with
the parent UART. The relevant /dev/ttyPS* node will
be not available for other operations.
If the driver is trying to do any operations like
suspend/resume without checking the tty->dev status
it leads to the kernel crash/hang.
This patch fix this issue by call the device_may_wake()
with the generic parameter of type struct device.
in the uart suspend and resume paths.
It also fixes a race condition in the uart suspend
path(i.e uart_suspend_port() should be called at the
end of cdns_uart_suspend API this path updates the same)
Signed-off-by: Nava kishore Manne <navam@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- New patch - can be sent separately but there is dependency that's why
sent in this series
Changes in v2: None
drivers/tty/serial/xilinx_uartps.c | 41 +++++++++++---------------------------
1 file changed, 12 insertions(+), 29 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 9a08542cec47..fc0ecaf3615d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1272,24 +1272,11 @@ static int cdns_uart_console_setup(struct console *co, char *options)
static int cdns_uart_suspend(struct device *device)
{
struct uart_port *port = dev_get_drvdata(device);
- struct tty_struct *tty;
- struct device *tty_dev;
- int may_wake = 0;
-
- /* Get the tty which could be NULL so don't assume it's valid */
- tty = tty_port_tty_get(&port->state->port);
- if (tty) {
- tty_dev = tty->dev;
- may_wake = device_may_wakeup(tty_dev);
- tty_kref_put(tty);
- }
+ int may_wake;
- /*
- * Call the API provided in serial_core.c file which handles
- * the suspend.
- */
- uart_suspend_port(&cdns_uart_uart_driver, port);
- if (!(console_suspend_enabled && !may_wake)) {
+ may_wake = device_may_wakeup(device);
+
+ if (console_suspend_enabled && may_wake) {
unsigned long flags = 0;
spin_lock_irqsave(&port->lock, flags);
@@ -1304,7 +1291,11 @@ static int cdns_uart_suspend(struct device *device)
spin_unlock_irqrestore(&port->lock, flags);
}
- return 0;
+ /*
+ * Call the API provided in serial_core.c file which handles
+ * the suspend.
+ */
+ return uart_suspend_port(&cdns_uart_uart_driver, port);
}
/**
@@ -1318,17 +1309,9 @@ static int cdns_uart_resume(struct device *device)
struct uart_port *port = dev_get_drvdata(device);
unsigned long flags = 0;
u32 ctrl_reg;
- struct tty_struct *tty;
- struct device *tty_dev;
- int may_wake = 0;
-
- /* Get the tty which could be NULL so don't assume it's valid */
- tty = tty_port_tty_get(&port->state->port);
- if (tty) {
- tty_dev = tty->dev;
- may_wake = device_may_wakeup(tty_dev);
- tty_kref_put(tty);
- }
+ int may_wake;
+
+ may_wake = device_may_wakeup(device);
if (console_suspend_enabled && !may_wake) {
struct cdns_uart *cdns_uart = port->private_data;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 02/10] serial: uartps: Do not initialize field to zero again
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
Writing zero and NULLs to already initialized fields is not needed.
Remove this additional writes.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3: None
Changes in v2:
- new patch - it can be sent separately too
drivers/tty/serial/xilinx_uartps.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index dd905c981f67..9a08542cec47 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1502,15 +1502,12 @@ static int cdns_uart_probe(struct platform_device *pdev)
/* At this point, we've got an empty uart_port struct, initialize it */
spin_lock_init(&port->lock);
- port->membase = NULL;
- port->irq = 0;
port->type = PORT_UNKNOWN;
port->iotype = UPIO_MEM32;
port->flags = UPF_BOOT_AUTOCONF;
port->ops = &cdns_uart_ops;
port->fifosize = CDNS_UART_FIFO_SIZE;
port->line = id;
- port->dev = NULL;
/*
* Register the port.
--
1.9.1
^ permalink raw reply related
* [PATCH v3 01/10] serial: uartps: console_setup() can't be placed to init section
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
In-Reply-To: <cover.1535980253.git.michal.simek@xilinx.com>
When console device is rebinded, console_setup() is called again.
But marking it as __init means that function will be clear after boot is
complete. If console device is binded again console_setup() is not found
and error "Unable to handle kernel paging request at virtual address"
is reported.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
Changes in v3:
- New patch found by testing
Changes in v2: None
drivers/tty/serial/xilinx_uartps.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index e5d90611c03f..dd905c981f67 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1216,7 +1216,7 @@ static void cdns_uart_console_write(struct console *co, const char *s,
*
* Return: 0 on success, negative errno otherwise.
*/
-static int __init cdns_uart_console_setup(struct console *co, char *options)
+static int cdns_uart_console_setup(struct console *co, char *options)
{
struct uart_port *port = console_port;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 00/10] serial: uartps: Add run time support for more IPs than hardcoded 2
From: Michal Simek @ 2018-09-03 13:10 UTC (permalink / raw)
To: linux-kernel, monstr, gnomes, Alexander Graf, shubhraj, robh
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
Hi,
this series is trying to address discussion I had with Alan in past
https://patchwork.kernel.org/patch/9738445/ and also with Rob in v1
https://lkml.org/lkml/2018/4/26/551.
These patches are doing preparation to enable dynamic ID port allocation
which is capable to create devices with higher IDs.
For example this is how it works.
uart0 on higher alias
serial0 = &uart1;
serial30 = &uart0;
~# ls -la /dev/ttyPS*
crw------- 1 root root 252, 0 Jun 6 12:19 /dev/ttyPS0
crw--w---- 1 root root 253, 100 Jan 1 1970 /dev/ttyPS30
Thanks,
Michal
Changes in v3:
- New patch found by testing
- New patch - can be sent separately but there is dependency that's why
sent in this series
- Fix uart_unregister_driver() in error path or when driver is removed.
- Change commit message
- s/,/;/ in filling structure
- get cdns_uart_uart_driver out of PS_UART_CONSOLE ifdefs
- New patch in series
- Rebase on the top of previous broken patch
- Change patch subject ("was serial: uartps: Remove CDNS_UART_NR_PORTS
macro")
- Keep CDNS_UART_NR_PORTS in this patch and remove it in next one and
align commit message to reflect this
- Allocate struct console dynamically too to be unique for every
instance
- Cleanup error path
- New patch in series
Changes in v2:
- new patch - it can be sent separately too
- new patch - it can be sent separately too
- new patch - it can be sent separately too
- Remove nr field logic
- new patch - it can be sent separately too
- Register one uart_driver with unique minor at probe time
Michal Simek (9):
serial: uartps: console_setup() can't be placed to init section
serial: uartps: Do not initialize field to zero again
serial: uartps: Do not use static struct uart_driver out of probe()
serial: uartps: Move alias reading higher in probe()
serial: uartps: Move register to probe based on run time detection
serial: uartps: Fill struct uart_driver in probe()
serial: uartps: Change logic how console_port is setup
serial: uartps: Register own uart console and driver structures
serial: uartps: Move Port ID to device data structure
Nava kishore Manne (1):
serial: uartps: Fix suspend functionality
drivers/tty/serial/xilinx_uartps.c | 203 +++++++++++++++++++------------------
1 file changed, 107 insertions(+), 96 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH] serial: uartps: Enable automatic flow control
From: Michal Simek @ 2018-09-03 13:05 UTC (permalink / raw)
To: linux-kernel, monstr
Cc: Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel
Enable automatic flow control which should ensure that there is no
mainteinance in connection for zcu100 BT case.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Acked-by: Nava kishore Manne <navam@xilinx.com>
---
drivers/tty/serial/xilinx_uartps.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index a48f19b1b88f..e5d90611c03f 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1003,13 +1003,12 @@ static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
val = readl(port->membase + CDNS_UART_MODEMCR);
mode_reg = readl(port->membase + CDNS_UART_MR);
- val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR);
+ val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR |
+ CDNS_UART_MODEMCR_FCM);
mode_reg &= ~CDNS_UART_MR_CHMODE_MASK;
- if (mctrl & TIOCM_RTS)
- val |= CDNS_UART_MODEMCR_RTS;
- if (mctrl & TIOCM_DTR)
- val |= CDNS_UART_MODEMCR_DTR;
+ if (mctrl & TIOCM_RTS || mctrl & TIOCM_DTR)
+ val |= CDNS_UART_MODEMCR_FCM;
if (mctrl & TIOCM_LOOP)
mode_reg |= CDNS_UART_MR_CHMODE_L_LOOP;
else
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v2 02/18] clk: intel: Add clock driver for Intel MIPS SoCs
From: Zhu, Yi Xin @ 2018-09-03 10:52 UTC (permalink / raw)
To: Stephen Boyd, Songjun Wu, chuanhua.lei, hua.ma, qi-ming.wu
Cc: linux-mips, linux-clk, linux-serial, devicetree,
Michael Turquette, linux-kernel, Rob Herring, Mark Rutland
In-Reply-To: <153573558557.93865.3835503209987304514@swboyd.mtv.corp.google.com>
On 9/1/2018 1:13 AM, Stephen Boyd wrote:
> Quoting Zhu, Yi Xin (2018-08-29 03:34:26)
>>>>>> +}
>>>>>> +
>>>>>> +CLK_OF_DECLARE(intel_grx500_cgu, "intel,grx500-cgu", grx500_clk_init);
>>>>> Any reason a platform driver can't be used instead of CLK_OF_DECLARE()?
>>>> It provides CPU clock which is used in early boot stage.
>>>>
>>> Ok. What is the CPU clock doing in early boot stage? Some sort of timer
>>> frequency? If the driver can be split into two pieces, one to handle the
>>> really early stuff that must be in place to get timers up and running
>>> and the other to register the rest of the clks that aren't critical from
>>> a regular platform driver it would be good. That's preferred model if
>>> something is super critical.
>>>
>> Just to make sure my approach is same as you think.
>>
>> In the driver, there's two clock registrations.
>>
>> - One through CLK_OF_DECLARE for early stage clocks.
>>
>> - The other via platform driver for the non-critical clocks.
> You can use the same DT node for both parts, no need to split the node
> into two and use syscon here.
>
Thank you.
Will use CLK_OF_DECLARE_DRIVER to use the same DT node.
^ permalink raw reply
* Re: [PATCH v2 02/18] clk: intel: Add clock driver for Intel MIPS SoCs
From: Zhu, Yi Xin @ 2018-09-03 10:47 UTC (permalink / raw)
To: Stephen Boyd, Songjun Wu, chuanhua.lei, hua.ma, qi-ming.wu
Cc: linux-mips, linux-clk, linux-serial, devicetree,
Michael Turquette, linux-kernel, Rob Herring, Mark Rutland
In-Reply-To: <153573545028.93865.1832322708533849519@swboyd.mtv.corp.google.com>
On 9/1/2018 1:10 AM, Stephen Boyd wrote:
> Quoting Zhu, Yi Xin (2018-08-28 23:56:22)
>> On 8/28/2018 3:09 AM, Stephen Boyd wrote:
>>> Quoting yixin zhu (2018-08-08 01:52:20)
>>>> On 8/8/2018 1:50 PM, Stephen Boyd wrote:
>>>>>> +/* clock flags definition */
>>>>>> +#define CLOCK_FLAG_VAL_INIT BIT(16)
>>>>>> +#define GATE_CLK_HW BIT(17)
>>>>>> +#define GATE_CLK_SW BIT(18)
>>>>>> +#define GATE_CLK_VT BIT(19)
>>>>> What does VT mean? Virtual?
>>>> Yes. VT means virtual here.
>>>> Will change to GATE_CLK_VIRT.
>>>>
>>> Is it a hardware concept? Or virtualization with hypervisor?
>> Some peripheral drivers want to use same code cross platforms.
>>
>> But not all platforms provide HW gate clock. So in this case, clock
>> driver creates
>>
>> a virtual gate clock to make it work if no HW gate clock in the SoC.
> That's not how things are supposed to work. If a clk isn't there in the
> hardware we don't make them up in software so that the consumer software
> drivers can keep requesting clks on different platforms. On a different
> platform, the driver needs to know that the clks aren't there with a
> different compatible string.
OK. Will remove virtual gate clock.
>>
>>>>>> +}
>>>>>> +
>>>>>> +CLK_OF_DECLARE(intel_grx500_cgu, "intel,grx500-cgu", grx500_clk_init);
>>>>> Any reason a platform driver can't be used instead of CLK_OF_DECLARE()?
>>>> It provides CPU clock which is used in early boot stage.
>>>>
>>> Ok. What is the CPU clock doing in early boot stage? Some sort of timer
>>> frequency? If the driver can be split into two pieces, one to handle the
>>> really early stuff that must be in place to get timers up and running
>>> and the other to register the rest of the clks that aren't critical from
>>> a regular platform driver it would be good. That's preferred model if
>>> something is super critical.
>> Yes, CPU clock is providing CPU frequency in the early boot stage.
>>
>> Will put the non-critical clocks in the platform driver.
>>
>>
> Sure the CPU clock is handling frequency, but does that matter for early
> boot to get going? If timers aren't involved here then it doesn't sound
> like this needs CLK_OF_DECLARE.
Yes, timer is involved here.
CPU frequency get by early stage platform code used in clockevent
registration.
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox