* [PATCHv3 03/10] serdev: implement get/set tiocm
From: Sebastian Reichel @ 2017-03-28 15:59 UTC (permalink / raw)
To: Sebastian Reichel, Marcel Holtmann, Gustavo Padovan,
Johan Hedberg, Rob Herring
Cc: Samuel Thibault, Pavel Machek, Tony Lindgren, Greg Kroah-Hartman,
Jiri Slaby, Mark Rutland, linux-bluetooth, linux-serial,
devicetree, linux-kernel
In-Reply-To: <20170328155939.31566-1-sre@kernel.org>
Add method for getting and setting tiocm.
Acked-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
drivers/tty/serdev/core.c | 22 ++++++++++++++++++++++
drivers/tty/serdev/serdev-ttyport.c | 24 ++++++++++++++++++++++++
include/linux/serdev.h | 13 +++++++++++++
3 files changed, 59 insertions(+)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index a63b74031e22..1e1cbae3a0ea 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -184,6 +184,28 @@ void serdev_device_wait_until_sent(struct serdev_device *serdev, long timeout)
}
EXPORT_SYMBOL_GPL(serdev_device_wait_until_sent);
+int serdev_device_get_tiocm(struct serdev_device *serdev)
+{
+ struct serdev_controller *ctrl = serdev->ctrl;
+
+ if (!ctrl || !ctrl->ops->get_tiocm)
+ return -ENOTSUPP;
+
+ return ctrl->ops->get_tiocm(ctrl);
+}
+EXPORT_SYMBOL_GPL(serdev_device_get_tiocm);
+
+int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
+{
+ struct serdev_controller *ctrl = serdev->ctrl;
+
+ if (!ctrl || !ctrl->ops->set_tiocm)
+ return -ENOTSUPP;
+
+ return ctrl->ops->set_tiocm(ctrl, set, clear);
+}
+EXPORT_SYMBOL_GPL(serdev_device_set_tiocm);
+
static int serdev_drv_probe(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index 50dc75c4d204..487c88f6aa0e 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -176,6 +176,28 @@ static void ttyport_wait_until_sent(struct serdev_controller *ctrl, long timeout
tty_wait_until_sent(tty, timeout);
}
+static int ttyport_get_tiocm(struct serdev_controller *ctrl)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ if (!tty->ops->tiocmget)
+ return -ENOTSUPP;
+
+ return tty->driver->ops->tiocmget(tty);
+}
+
+static int ttyport_set_tiocm(struct serdev_controller *ctrl, unsigned int set, unsigned int clear)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ if (!tty->ops->tiocmset)
+ return -ENOTSUPP;
+
+ return tty->driver->ops->tiocmset(tty, set, clear);
+}
+
static const struct serdev_controller_ops ctrl_ops = {
.write_buf = ttyport_write_buf,
.write_flush = ttyport_write_flush,
@@ -185,6 +207,8 @@ static const struct serdev_controller_ops ctrl_ops = {
.set_flow_control = ttyport_set_flow_control,
.set_baudrate = ttyport_set_baudrate,
.wait_until_sent = ttyport_wait_until_sent,
+ .get_tiocm = ttyport_get_tiocm,
+ .set_tiocm = ttyport_set_tiocm,
};
struct device *serdev_tty_port_register(struct tty_port *port,
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index a308b206d204..e29a270f603c 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/device.h>
+#include <linux/termios.h>
struct serdev_controller;
struct serdev_device;
@@ -82,6 +83,8 @@ struct serdev_controller_ops {
void (*set_flow_control)(struct serdev_controller *, bool);
unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
void (*wait_until_sent)(struct serdev_controller *, long);
+ int (*get_tiocm)(struct serdev_controller *);
+ int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int);
};
/**
@@ -188,6 +191,8 @@ void serdev_device_close(struct serdev_device *);
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
void serdev_device_set_flow_control(struct serdev_device *, bool);
void serdev_device_wait_until_sent(struct serdev_device *, long);
+int serdev_device_get_tiocm(struct serdev_device *);
+int serdev_device_set_tiocm(struct serdev_device *, int, int);
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
void serdev_device_write_flush(struct serdev_device *);
int serdev_device_write_room(struct serdev_device *);
@@ -226,6 +231,14 @@ static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev
}
static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
+static inline int serdev_device_get_tiocm(struct serdev_device *serdev)
+{
+ return -ENOTSUPP;
+}
+static inline int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
+{
+ return -ENOTSUPP;
+}
static inline int serdev_device_write_buf(struct serdev_device *sdev, const unsigned char *buf, size_t count)
{
return -ENODEV;
--
2.11.0
^ permalink raw reply related
* [PATCHv3 02/10] serdev: add serdev_device_wait_until_sent
From: Sebastian Reichel @ 2017-03-28 15:59 UTC (permalink / raw)
To: Sebastian Reichel, Marcel Holtmann, Gustavo Padovan,
Johan Hedberg, Rob Herring
Cc: Samuel Thibault, Pavel Machek, Tony Lindgren, Greg Kroah-Hartman,
Jiri Slaby, Mark Rutland, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170328155939.31566-1-sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Add method, which waits until the transmission buffer has been sent.
Note, that the change in ttyport_write_wakeup is related, since
tty_wait_until_sent will hang without that change.
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Acked-by: Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>
Signed-off-by: Sebastian Reichel <sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
Changes since PATCHv2:
* Avoid goto in ttyport_write_wakeup
---
drivers/tty/serdev/core.c | 11 +++++++++++
drivers/tty/serdev/serdev-ttyport.c | 18 ++++++++++++++----
include/linux/serdev.h | 3 +++
3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index f4c6c90add78..a63b74031e22 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -173,6 +173,17 @@ void serdev_device_set_flow_control(struct serdev_device *serdev, bool enable)
}
EXPORT_SYMBOL_GPL(serdev_device_set_flow_control);
+void serdev_device_wait_until_sent(struct serdev_device *serdev, long timeout)
+{
+ struct serdev_controller *ctrl = serdev->ctrl;
+
+ if (!ctrl || !ctrl->ops->wait_until_sent)
+ return;
+
+ ctrl->ops->wait_until_sent(ctrl, timeout);
+}
+EXPORT_SYMBOL_GPL(serdev_device_wait_until_sent);
+
static int serdev_drv_probe(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index d05393594f15..50dc75c4d204 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -14,6 +14,7 @@
#include <linux/serdev.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
+#include <linux/poll.h>
#define SERPORT_ACTIVE 1
@@ -46,11 +47,11 @@ static void ttyport_write_wakeup(struct tty_port *port)
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
- if (!test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags))
- return;
-
- if (test_bit(SERPORT_ACTIVE, &serport->flags))
+ if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) &&
+ test_bit(SERPORT_ACTIVE, &serport->flags))
serdev_controller_write_wakeup(ctrl);
+
+ wake_up_interruptible_poll(&port->tty->write_wait, POLLOUT);
}
static const struct tty_port_client_operations client_ops = {
@@ -167,6 +168,14 @@ static void ttyport_set_flow_control(struct serdev_controller *ctrl, bool enable
tty_set_termios(tty, &ktermios);
}
+static void ttyport_wait_until_sent(struct serdev_controller *ctrl, long timeout)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ tty_wait_until_sent(tty, timeout);
+}
+
static const struct serdev_controller_ops ctrl_ops = {
.write_buf = ttyport_write_buf,
.write_flush = ttyport_write_flush,
@@ -175,6 +184,7 @@ static const struct serdev_controller_ops ctrl_ops = {
.close = ttyport_close,
.set_flow_control = ttyport_set_flow_control,
.set_baudrate = ttyport_set_baudrate,
+ .wait_until_sent = ttyport_wait_until_sent,
};
struct device *serdev_tty_port_register(struct tty_port *port,
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index 9519da6253a8..a308b206d204 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -81,6 +81,7 @@ struct serdev_controller_ops {
void (*close)(struct serdev_controller *);
void (*set_flow_control)(struct serdev_controller *, bool);
unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
+ void (*wait_until_sent)(struct serdev_controller *, long);
};
/**
@@ -186,6 +187,7 @@ int serdev_device_open(struct serdev_device *);
void serdev_device_close(struct serdev_device *);
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
void serdev_device_set_flow_control(struct serdev_device *, bool);
+void serdev_device_wait_until_sent(struct serdev_device *, long);
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
void serdev_device_write_flush(struct serdev_device *);
int serdev_device_write_room(struct serdev_device *);
@@ -223,6 +225,7 @@ static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev
return 0;
}
static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
+static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
static inline int serdev_device_write_buf(struct serdev_device *sdev, const unsigned char *buf, size_t count)
{
return -ENODEV;
--
2.11.0
^ permalink raw reply related
* [PATCHv3 01/10] tty: serial: omap: add UPF_BOOT_AUTOCONF flag for DT init
From: Sebastian Reichel @ 2017-03-28 15:59 UTC (permalink / raw)
To: Sebastian Reichel, Marcel Holtmann, Gustavo Padovan,
Johan Hedberg, Rob Herring
Cc: Samuel Thibault, Pavel Machek, Tony Lindgren, Greg Kroah-Hartman,
Jiri Slaby, Mark Rutland, linux-bluetooth, linux-serial,
devicetree, linux-kernel
In-Reply-To: <20170328155939.31566-1-sre@kernel.org>
The UPF_BOOT_AUTOCONF flag is needed for proper
flow control support.
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
Hi,
This patch can be queued independently - there is no compile time dependency
regarding nokia-bluetooth. Also 8250_omap.c can be used with nokia-bluetooth
(I use this driver nowadays), which does flow control right already.
-- Sebastian
---
drivers/tty/serial/omap-serial.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 6c6f82ad8d5c..a4734649a0f0 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1597,6 +1597,9 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev)
of_property_read_u32(dev->of_node, "clock-frequency",
&omap_up_info->uartclk);
+
+ omap_up_info->flags = UPF_BOOT_AUTOCONF;
+
return omap_up_info;
}
--
2.11.0
^ permalink raw reply related
* [PATCHv3 00/10] Nokia H4+ support
From: Sebastian Reichel @ 2017-03-28 15:59 UTC (permalink / raw)
To: Sebastian Reichel, Marcel Holtmann, Gustavo Padovan,
Johan Hedberg, Rob Herring
Cc: Samuel Thibault, Pavel Machek, Tony Lindgren, Greg Kroah-Hartman,
Jiri Slaby, Mark Rutland, linux-bluetooth, linux-serial,
devicetree, linux-kernel
Hi,
Here is PATCHv3 for the Nokia bluetooth patchset. I addressed all comments from
Rob and Pavel regarding the serdev patches and dropped the *.dts patches, since
they were queued by Tony. I also changed the patch order, so that the serdev
patches come first. All of them have Acked-by from Rob, so I think it makes
sense to merge them to serdev subsystem (now) and provide an immutable branch
for the bluetooth subsystem.
The patchset is based upon 4.11-rc1 and is also available from the following
branch:
https://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-n900.git/log/?h=nokia-bt-serdev-v3
-- Sebastian
Rob Herring (1):
Bluetooth: hci_uart: add serdev driver support library
Sebastian Reichel (9):
tty: serial: omap: add UPF_BOOT_AUTOCONF flag for DT init
serdev: add serdev_device_wait_until_sent
serdev: implement get/set tiocm
serdev: add helpers for cts and rts handling
Bluetooth: hci_uart: add support for word alignment
Bluetooth: hci_serdev: do not open device in hci open
Bluetooth: hci_serdev: allow modular drivers
dt-bindings: net: bluetooth: Add nokia-bluetooth
Bluetooth: add nokia driver
.../devicetree/bindings/net/nokia-bluetooth.txt | 51 ++
drivers/bluetooth/Kconfig | 12 +
drivers/bluetooth/Makefile | 3 +
drivers/bluetooth/hci_h4.c | 17 +
drivers/bluetooth/hci_ldisc.c | 5 +
drivers/bluetooth/hci_nokia.c | 819 +++++++++++++++++++++
drivers/bluetooth/hci_serdev.c | 356 +++++++++
drivers/bluetooth/hci_uart.h | 7 +
drivers/tty/serdev/core.c | 33 +
drivers/tty/serdev/serdev-ttyport.c | 42 +-
drivers/tty/serial/omap-serial.c | 3 +
include/linux/serdev.h | 47 ++
12 files changed, 1391 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/nokia-bluetooth.txt
create mode 100644 drivers/bluetooth/hci_nokia.c
create mode 100644 drivers/bluetooth/hci_serdev.c
--
2.11.0
^ permalink raw reply
* Re: [PATCH v8 3/3] printk: fix double printing with earlycon
From: Petr Mladek @ 2017-03-28 12:56 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Aleksey Makarov, linux-serial, linux-kernel, Sudeep Holla,
Greg Kroah-Hartman, Peter Hurley, Jiri Slaby, Robin Murphy,
Steven Rostedt, Nair, Jayachandran, Sergey Senozhatsky
In-Reply-To: <20170328020404.GA10573@jagdpanzerIV.localdomain>
On Tue 2017-03-28 11:04:04, Sergey Senozhatsky wrote:
> On (03/27/17 19:28), Aleksey Makarov wrote:
> [..]
> > > > + /*
> > > > + * Maintain an invariant that will help to find if
> > > > + * the matching console is preferred, see
> > > > + * register_console():
> > > > + *
> > > > + * The last non-braille console is always
> > > > + * the preferred one.
> > > > + */
> > > > + for (last = MAX_CMDLINECONSOLES - 1;
> > > > + last >= 0 && !console_cmdline[last].name[0];
> > > > + last--)
> > > > + ;
> > >
> > > This is a rather non-trivial code to find the last element.
> > > I might make sense to count it in a global variable.
> > > Then we might remove the check for console_cmdline[i].name[0]
> > > also in the other for cycles and make them better readable.
> >
> > Having an additional variable console_cmdline_last pointing to the last element
> > would require maintaining consistency between this variable and
> > contents of console_cmdline. For the code we have it is not hard, but when code
> > is changed we need to check this. Also there exists preferred_console that
> > has almost the same meaning but it points not to the last element, but to the
> > last non-braille element. Also we need to have a special value (-1) for this
> > variable for empty array. So I personally would instead try to rewrite this:
> >
> > for (last = MAX_CMDLINECONSOLES - 1; last >= 0; last--)
> > if (console_cmdline[last].name[0])
> > break;
> >
> > Is it better? If not, I will send a version with console_cmdline_last.
>
> personally I'm fine with the nested loop. the latest version
> "for (last = MAX_CMDLINECONSOLES - 1; last >= 0;..."
>
> is even easier to read.
The number of elements is bumped on a single location, so there
is not much to synchronize. The old approach was fine because
the for cycles were needed anyway, they started on the 0th element,
and NULL ended arrays are rather common practice.
But we are searching the array from the end now. Also we use the
for cycle just to get the number here. This is not a common
practice and it makes the code more complicated and strange from
my point of view.
If you do not like -1, you could use console_cmdline_cnt and
start with 0. I would actually do so because it is a common
approach and easy to understand.
>
> so we do not just iterate console_cmdline anymore, but also modify it.
> this, probably, has impact on the following scenario
>
> CPU0 CPU1
>
> add_preferred_console() add_preferred_console()
> __add_preferred_console() __add_preferred_console()
> swap(i1, last) swap(i2, last)
>
> temp1 = i1
> i1 = last temp2 = i2
> last = temp1 i2 = last
> last = temp2
>
> so both i1 and i2 will point to 'last' now, IOW, we will have two
> identical entries in console_cmdline, while i1 or i2 will be lost.
>
>
> neither add_preferred_console() nor __add_preferred_console() have any
> serialization. and I assume that we can call add_preferred_console()
> concurrently, can't we?
Very good point!
Well, if this race exists, it was racy even before. Of course,
the old race was only when new entry was added. It would
be more visible now because also shuffling would be racy.
OK, most add_preferred_console() calls are in functions
that are defined as console_initcall(). They seem to
be defined only when the respective drivers are built in.
It seems that these initcalls are serialized, see console_init().
add_preferred_console() is used also in uart_add_one_port():
-> uart_add_one_port()
-> of_console_check()
-> add_preferred_console()
But there the calls are synchronized as well via
port_mutex.
Finally, __add_preferred_console() is called also from
console_setup(). It is called via do_early_param()
even before the console_initcall() functions. It is
serialized as well.
If I did not miss anything, it would seem that
__add_preferred_console() are called synchronously
and only during boot by design.
Best Regards,
Petr
^ permalink raw reply
* [PATCH v2, 3/3] tty/serial: meson_uart: add the core clock handling to the driver
From: Helmut Klein @ 2017-03-28 9:25 UTC (permalink / raw)
To: gregkh, carlo, khilman
Cc: linux-amlogic, Helmut Klein, linux-arm-kernel, linux-serial,
linux-kernel
In-Reply-To: <20170328092545.4644-1-hgkr.klein@gmail.com>
This patch gets the core clock as provided by the DT and enables it.
The code was taken from Amlogic's serial driver, and was tested on my
board.
Signed-off-by: Helmut Klein <hgkr.klein@gmail.com>
---
drivers/tty/serial/meson_uart.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 60f16795d16b..cb99112288eb 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -600,6 +600,7 @@ static int meson_uart_probe(struct platform_device *pdev)
struct resource *res_mem, *res_irq;
struct uart_port *port;
struct clk *clk;
+ struct clk *core_clk;
int ret = 0;
if (pdev->dev.of_node)
@@ -625,6 +626,15 @@ static int meson_uart_probe(struct platform_device *pdev)
if (!port)
return -ENOMEM;
+ core_clk = devm_clk_get(&pdev->dev, "core");
+ if (!IS_ERR(core_clk)) {
+ ret = clk_prepare_enable(core_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "couldn't enable clkc\n");
+ return ret;
+ }
+ }
+
clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
--
2.11.0
^ permalink raw reply related
* [PATCH v2, 0/3] tty/serial: meson_uart: add support for core clock handling
From: Helmut Klein @ 2017-03-28 9:25 UTC (permalink / raw)
Cc: devicetree, linux-kernel, Helmut Klein, linux-serial,
linux-amlogic, linux-clk, linux-arm-kernel
To be able to use the three none AO uarts of the s905 SoCs (uart_A, uart_B
& uart_C), the core clock has to be enabled. (see chapter 22.3 of the
public s905 data sheet) At least the u-boot of my s905 based media player
(netxeon minimx) doesn't do this. so the driver must do it.
This patch set does:
- exposes the clock ids to the dtb
- adds documentation for the dt-bindings of meson_uart
- adds the core clock handling to the driver
The patchset is based on the branch master of the repository in [1]
Changes since v1
- use git to produce the patch set
- added the clock ids for uart_B and uart_C
None of the available s905 dts use uart_A actively. So there is no patch
for any of the existing dts files.
[1] git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git
Helmut Klein (3):
tty/serial: meson_uart: expose CLKID_UARTx
tty/serial: meson_uart: add documentation for the dt-bindings
tty/serial: meson_uart: add the core clock handling to the driver
.../bindings/serial/amlogic,meson_uart.txt | 25 ++++++++++++++++++++++
drivers/clk/meson/gxbb.h | 6 +++---
drivers/tty/serial/meson_uart.c | 10 +++++++++
include/dt-bindings/clock/gxbb-clkc.h | 3 +++
4 files changed, 41 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/serial/amlogic,meson_uart.txt
--
2.11.0
^ permalink raw reply
* [PATCH v2 3/3] serial: sh-sci: Fix (AUTO)RTS in sci_init_pins()
From: Geert Uytterhoeven @ 2017-03-28 9:13 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: Yoshihiro Shimoda, Laurent Pinchart, Wolfram Sang,
Christoph Baumann, linux-serial, linux-renesas-soc, linux-kernel,
Geert Uytterhoeven
In-Reply-To: <1490692426-19252-1-git-send-email-geert+renesas@glider.be>
If a UART has dedicated RTS/CTS pins, and hardware control flow is
disabled (or AUTORTS is not yet effective), changing any serial port
configuration deasserts RTS, as .set_termios() calls sci_init_pins().
To fix this, consider the current (AUTO)RTS state when (re)initializing
the pins. Note that for SCIFA/SCIFB, AUTORTS needs explicit
configuration of the RTS# pin function, while (H)SCIF handles this
automatically.
Fixes: d2b9775d795ec05f ("serial: sh-sci: Correct pin initialization on (H)SCIF")
Fixes: e9d7a45a03991349 ("serial: sh-sci: Add pin initialization for SCIFA/SCIFB")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v2:
- New.
---
drivers/tty/serial/sh-sci.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 6e405fb5a23f0b4a..71707e8e6e3ffe76 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -683,24 +683,37 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
}
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ u16 data = serial_port_in(port, SCPDR);
u16 ctrl = serial_port_in(port, SCPCR);
/* Enable RXD and TXD pin functions */
ctrl &= ~(SCPCR_RXDC | SCPCR_TXDC);
if (to_sci_port(port)->has_rtscts) {
- /* RTS# is output, driven 1 */
- ctrl |= SCPCR_RTSC;
- serial_port_out(port, SCPDR,
- serial_port_in(port, SCPDR) | SCPDR_RTSD);
+ /* RTS# is output, active low, unless autorts */
+ if (!(port->mctrl & TIOCM_RTS)) {
+ ctrl |= SCPCR_RTSC;
+ data |= SCPDR_RTSD;
+ } else if (!s->autorts) {
+ ctrl |= SCPCR_RTSC;
+ data &= ~SCPDR_RTSD;
+ } else {
+ /* Enable RTS# pin function */
+ ctrl &= ~SCPCR_RTSC;
+ }
/* Enable CTS# pin function */
ctrl &= ~SCPCR_CTSC;
}
+ serial_port_out(port, SCPDR, data);
serial_port_out(port, SCPCR, ctrl);
} else if (sci_getreg(port, SCSPTR)->size) {
u16 status = serial_port_in(port, SCSPTR);
- /* RTS# is output, driven 1 */
- status |= SCSPTR_RTSIO | SCSPTR_RTSDT;
+ /* RTS# is always output; and active low, unless autorts */
+ status |= SCSPTR_RTSIO;
+ if (!(port->mctrl & TIOCM_RTS))
+ status |= SCSPTR_RTSDT;
+ else if (!s->autorts)
+ status &= ~SCSPTR_RTSDT;
/* CTS# and SCK are inputs */
status &= ~(SCSPTR_CTSIO | SCSPTR_SCKIO);
serial_port_out(port, SCSPTR, status);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/3] serial: sh-sci: Fix late enablement of AUTORTS
From: Geert Uytterhoeven @ 2017-03-28 9:13 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: Yoshihiro Shimoda, Laurent Pinchart, Wolfram Sang,
Christoph Baumann, linux-serial, linux-renesas-soc, linux-kernel,
Geert Uytterhoeven
In-Reply-To: <1490692426-19252-1-git-send-email-geert+renesas@glider.be>
When changing hardware control flow for a UART with dedicated RTS/CTS
pins, the new AUTORTS state is not immediately reflected in the
hardware, but only when RTS is raised. However, the serial core does
not call .set_mctrl() after .set_termios(), hence AUTORTS may only
become effective when the port is closed, and reopened later.
Note that this problem does not happen when manually using stty to
change CRTSCTS, as AUTORTS will work fine on next open.
To fix this, call .set_mctrl() from .set_termios() when dedicated
RTS/CTS pins are present, to refresh the AUTORTS or RTS state.
This is similar to what other drivers supporting AUTORTS do (e.g.
omap-serial).
Reported-by: Baumann, Christoph (C.) <cbaumann@visteon.com>
Fixes: 33f50ffc253854cf ("serial: sh-sci: Fix support for hardware-assisted RTS/CTS")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Tested on r8a7791/koelsch with HSCIF1 (GPIO hardware flow control),
and HSCIF2 and SCIFB0 (dedicated hardware flow control).
A simple test program (basically "cat" with CRTSCTS configuration
capability) can be found at https://github.com/geertu/sercat
Without this patch the following will fail:
1. sercat -f /dev/hscif2 &
seq 100 120 | sercat -f -w /dev/hscif1 # hangs
2. seq 200 220 | sercat -f -w /dev/hscif2 &
sercat -f /dev/hscif1 # no data received
v2:
- Remove the paragraph about sci_init_pins() and reword.
When hardware control flow is disabled, there can still be small
glitches in the RTS signal.
These glitches are now addressed in a separate patch.
---
drivers/tty/serial/sh-sci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 446a23bee14008bb..6e405fb5a23f0b4a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2372,6 +2372,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
serial_port_out(port, SCFCR, ctrl);
}
+ if (port->flags & UPF_HARD_FLOW) {
+ /* Refresh (Auto) RTS */
+ sci_set_mctrl(port, port->mctrl);
+ }
scr_val |= SCSCR_RE | SCSCR_TE |
(s->cfg->scscr & ~(SCSCR_CKE1 | SCSCR_CKE0));
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/3] serial: sh-sci: Fix hang in sci_reset()
From: Geert Uytterhoeven @ 2017-03-28 9:13 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: Yoshihiro Shimoda, Laurent Pinchart, Wolfram Sang,
Christoph Baumann, linux-serial, linux-renesas-soc, linux-kernel,
Geert Uytterhoeven
In-Reply-To: <1490692426-19252-1-git-send-email-geert+renesas@glider.be>
When the .set_termios() callback resets the UART, it first waits (busy
loops) until all characters in the transmit FIFO have been transmitted,
to prevent a port configuration change from impacting these characters.
However, if the UART has dedicated RTS/CTS hardware flow control
enabled, these characters may have been stuck in the FIFO due to CTS not
being asserted by the remote side.
- When a new user opens the port, .set_termios() is called while
transmission is still disabled, leading to an infinite loop:
NMI watchdog: BUG: soft lockup - CPU#0 stuck for 22s!
- When an active user changes port configuration without waiting for
the draining of the transmit FIFO, this may also block indefinitely,
until CTS is asserted by the remote side.
This has been observed with SCIFA (on r8a7740/armadillo), and SCIFB and
HSCIF (on r8a7791/koelsch).
To fix this, remove the code that waits for the draining of the transmit
FIFO.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
To reproduce:
stty -echo < /dev/scifb0
stty crtscts < /dev/scifb0
echo hello > /dev/scifb0 # returns early (wrote to FIFO)
echo hello > /dev/scifb0 # hangs
v2:
- Remove the draining of the transmit FIFO completely, instead of
skipping it when tranmission was not enabled, as the hang could
still be reproduced when an active user changes port configuration
without waiting for the draining of the transmit FIFO.
---
drivers/tty/serial/sh-sci.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1df57461ece4337b..446a23bee14008bb 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2159,10 +2159,6 @@ static void sci_reset(struct uart_port *port)
unsigned int status;
struct sci_port *s = to_sci_port(port);
- do {
- status = serial_port_in(port, SCxSR);
- } while (!(status & SCxSR_TEND(port)));
-
serial_port_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
reg = sci_getreg(port, SCFCR);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/3] serial: sh-sci: Assorted flow control fixes
From: Geert Uytterhoeven @ 2017-03-28 9:13 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby
Cc: Yoshihiro Shimoda, Laurent Pinchart, Wolfram Sang,
Christoph Baumann, linux-serial, linux-renesas-soc, linux-kernel,
Geert Uytterhoeven
Hi Greg, Jiri,
This patch series fixes several issues related to hardware flow control
on Renesas SCIF UARTs.
For changes compared to v1 ("[PATCH 0/2] serial: sh-sci: Assorted flow
control fixes", https://lkml.org/lkml/2016/12/2/226), please refer to
the comments in the individual patches.
Thanks!
Geert Uytterhoeven (3):
serial: sh-sci: Fix hang in sci_reset()
serial: sh-sci: Fix late enablement of AUTORTS
serial: sh-sci: Fix (AUTO)RTS in sci_init_pins()
drivers/tty/serial/sh-sci.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
--
2.7.4
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] serial: 8250_EXAR: fix duplicate Kconfig text and add missing help text
From: Sudip Mukherjee @ 2017-03-28 7:52 UTC (permalink / raw)
To: Paul Gortmaker
Cc: linux-kernel, Andy Shevchenko, Sudip Mukherjee,
Greg Kroah-Hartman, Jiri Slaby, linux-serial
In-Reply-To: <20170327233910.13122-1-paul.gortmaker@windriver.com>
On Mon, Mar 27, 2017 at 07:39:10PM -0400, Paul Gortmaker wrote:
> In commit d0aeaa83f0b0f7a92615bbdd6b1f96812f7dcfd2 ("serial: exar:
> split out the exar code from 8250_pci") the exar driver got its own
> Kconfig. However the text for the new option was never changed from
> the original 8250_PCI text, and hence it appears confusing when you
> get asked the same question twice:
>
> 8250/16550 PCI device support (SERIAL_8250_PCI) [Y/n/m/?] (NEW)
> 8250/16550 PCI device support (SERIAL_8250_EXAR) [Y/n/m] (NEW)
>
> Adding to the confusion, is that there is no help text for this new
> option to indicate it is specific to a certain family of cards.
>
> Fix both issues at the same time, as well as the space vs. tab issues
> introduced in the same commit.
>
> Fixes: d0aeaa83f0b0 ("serial: exar: split out the exar code from 8250_pci")
> Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
> Cc: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
Acked-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
^ permalink raw reply
* Re: [PATCH] serial: 8250_EXAR: fix duplicate Kconfig text and add missing help text
From: Andy Shevchenko @ 2017-03-28 7:10 UTC (permalink / raw)
To: Paul Gortmaker
Cc: linux-kernel@vger.kernel.org, Sudip Mukherjee, Greg Kroah-Hartman,
Jiri Slaby, linux-serial@vger.kernel.org
In-Reply-To: <20170327233910.13122-1-paul.gortmaker@windriver.com>
On Tue, Mar 28, 2017 at 2:39 AM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:
> In commit d0aeaa83f0b0f7a92615bbdd6b1f96812f7dcfd2 ("serial: exar:
> split out the exar code from 8250_pci") the exar driver got its own
> Kconfig. However the text for the new option was never changed from
> the original 8250_PCI text, and hence it appears confusing when you
> get asked the same question twice:
>
> 8250/16550 PCI device support (SERIAL_8250_PCI) [Y/n/m/?] (NEW)
> 8250/16550 PCI device support (SERIAL_8250_EXAR) [Y/n/m] (NEW)
>
> Adding to the confusion, is that there is no help text for this new
> option to indicate it is specific to a certain family of cards.
>
> Fix both issues at the same time, as well as the space vs. tab issues
> introduced in the same commit.
>
Good catch!
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Fixes: d0aeaa83f0b0 ("serial: exar: split out the exar code from 8250_pci")
> Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
> Cc: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: linux-serial@vger.kernel.org
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> ---
> drivers/tty/serial/8250/Kconfig | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index a65fb8197aec..0e3f529d50e9 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -128,9 +128,13 @@ config SERIAL_8250_PCI
> by the parport_serial driver, enabled with CONFIG_PARPORT_SERIAL.
>
> config SERIAL_8250_EXAR
> - tristate "8250/16550 PCI device support"
> - depends on SERIAL_8250_PCI
> + tristate "8250/16550 Exar/Commtech PCI/PCIe device support"
> + depends on SERIAL_8250_PCI
> default SERIAL_8250
> + help
> + This builds support for XR17C1xx, XR17V3xx and some Commtech
> + 422x PCIe serial cards that are not covered by the more generic
> + SERIAL_8250_PCI option.
>
> config SERIAL_8250_HP300
> tristate
> --
> 2.11.0
>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH 2/2] drivers/serial: Add driver for Aspeed virtual UART
From: Joel Stanley @ 2017-03-28 5:44 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Mark Rutland, Rob Herring
Cc: Jeremy Kerr, linux-serial, linux-kernel, openbmc, devicetree,
Benjamin Herrenschmidt
In-Reply-To: <20170328054458.29341-1-joel@jms.id.au>
From: Jeremy Kerr <jk@ozlabs.org>
This change adds a driver for the 16550-based Aspeed virtual UART
device. We use a similar process to the of_serial driver for device
probe, but expose some VUART-specific functions through sysfs too.
OpenPOWER host firmware doesn't like it when the host-side of the
VUART's FIFO is not drained. This driver only disables host TX discard
mode when the port is in use. We set the VUART enabled bit when we bind
to the device, and clear it on unbind.
We don't want to do this on open/release, as the host may be using this
bit to configure serial output modes, which is independent of whether
the devices has been opened by BMC userspace.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
Documentation/devicetree/bindings/serial/8250.txt | 2 +
drivers/tty/serial/Kconfig | 10 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/aspeed-vuart.c | 335 ++++++++++++++++++++++
4 files changed, 348 insertions(+)
create mode 100644 drivers/tty/serial/aspeed-vuart.c
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
index f86bb06c39e9..a12e9277ac5d 100644
--- a/Documentation/devicetree/bindings/serial/8250.txt
+++ b/Documentation/devicetree/bindings/serial/8250.txt
@@ -19,6 +19,8 @@ Required properties:
- "altr,16550-FIFO128"
- "fsl,16550-FIFO64"
- "fsl,ns16550"
+ - "aspeed,ast2400-vuart"
+ - "aspeed,ast2500-vuart"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index e9cf5b67f1b7..758b69a51078 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1129,6 +1129,16 @@ config SERIAL_NETX_CONSOLE
If you have enabled the serial port on the Hilscher NetX SoC
you can make it the console by answering Y to this option.
+config SERIAL_ASPEED_VUART
+ tristate "Aspeed Virtual UART"
+ depends on OF
+ depends on SERIAL_8250
+ help
+ If you want to use the virtual UART (VUART) device on Aspeed
+ BMC platforms, enable this option. This enables the 16550A-
+ compatible device on the local LPC bus, giving a UART device
+ with no physical RS232 connections.
+
config SERIAL_OMAP
tristate "OMAP serial port support"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 2d6288bc4554..5b97b0fa29e2 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250/
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
+obj-$(CONFIG_SERIAL_ASPEED_VUART) += aspeed-vuart.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
diff --git a/drivers/tty/serial/aspeed-vuart.c b/drivers/tty/serial/aspeed-vuart.c
new file mode 100644
index 000000000000..fc6fa6d243c8
--- /dev/null
+++ b/drivers/tty/serial/aspeed-vuart.c
@@ -0,0 +1,335 @@
+/*
+ * Serial Port driver for Aspeed VUART device
+ *
+ * Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp.
+ * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+
+#include "8250/8250.h"
+
+#define AST_VUART_GCRA 0x20
+#define AST_VUART_GCRA_VUART_EN 0x01
+#define AST_VUART_GCRA_HOST_TX_DISCARD 0x20
+#define AST_VUART_GCRB 0x24
+#define AST_VUART_GCRB_HOST_SIRQ_MASK 0xf0
+#define AST_VUART_GCRB_HOST_SIRQ_SHIFT 4
+#define AST_VUART_ADDRL 0x28
+#define AST_VUART_ADDRH 0x2c
+
+struct ast_vuart {
+ struct platform_device *pdev;
+ void __iomem *regs;
+ struct clk *clk;
+ int line;
+};
+
+static ssize_t ast_vuart_show_addr(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ast_vuart *vuart = dev_get_drvdata(dev);
+ u16 addr;
+
+ addr = (readb(vuart->regs + AST_VUART_ADDRH) << 8) |
+ (readb(vuart->regs + AST_VUART_ADDRL));
+
+ return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr);
+}
+
+static ssize_t ast_vuart_set_addr(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ast_vuart *vuart = dev_get_drvdata(dev);
+ unsigned long val;
+ int err;
+
+ err = kstrtoul(buf, 0, &val);
+ if (err)
+ return err;
+
+ writeb((val >> 8) & 0xff, vuart->regs + AST_VUART_ADDRH);
+ writeb((val >> 0) & 0xff, vuart->regs + AST_VUART_ADDRL);
+
+ return count;
+}
+
+static DEVICE_ATTR(lpc_address, 0664,
+ ast_vuart_show_addr, ast_vuart_set_addr);
+
+static ssize_t ast_vuart_show_sirq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ast_vuart *vuart = dev_get_drvdata(dev);
+ u8 reg;
+
+ reg = readb(vuart->regs + AST_VUART_GCRB);
+ reg &= AST_VUART_GCRB_HOST_SIRQ_MASK;
+ reg >>= AST_VUART_GCRB_HOST_SIRQ_SHIFT;
+
+ return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg);
+}
+
+static ssize_t ast_vuart_set_sirq(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ast_vuart *vuart = dev_get_drvdata(dev);
+ unsigned long val;
+ int err;
+ u8 reg;
+
+ err = kstrtoul(buf, 0, &val);
+ if (err)
+ return err;
+
+ val <<= AST_VUART_GCRB_HOST_SIRQ_SHIFT;
+ val &= AST_VUART_GCRB_HOST_SIRQ_MASK;
+
+ reg = readb(vuart->regs + AST_VUART_GCRB);
+ reg &= ~AST_VUART_GCRB_HOST_SIRQ_MASK;
+ reg |= val;
+ writeb(reg, vuart->regs + AST_VUART_GCRB);
+
+ return count;
+}
+
+static DEVICE_ATTR(sirq, 0664,
+ ast_vuart_show_sirq, ast_vuart_set_sirq);
+
+static void ast_vuart_set_enabled(struct ast_vuart *vuart, bool enabled)
+{
+ u8 reg;
+
+ reg = readb(vuart->regs + AST_VUART_GCRA);
+ reg &= ~AST_VUART_GCRA_VUART_EN;
+ if (enabled)
+ reg |= AST_VUART_GCRA_VUART_EN;
+ writeb(reg, vuart->regs + AST_VUART_GCRA);
+}
+
+static void ast_vuart_set_host_tx_discard(struct ast_vuart *vuart, bool discard)
+{
+ u8 reg;
+
+ reg = readb(vuart->regs + AST_VUART_GCRA);
+
+ /* if the HOST_TX_DISCARD bit is set, discard is *disabled* */
+ reg &= ~AST_VUART_GCRA_HOST_TX_DISCARD;
+ if (!discard)
+ reg |= AST_VUART_GCRA_HOST_TX_DISCARD;
+
+ writeb(reg, vuart->regs + AST_VUART_GCRA);
+}
+
+static int ast_vuart_startup(struct uart_port *uart_port)
+{
+ struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port);
+ struct ast_vuart *vuart = uart_8250_port->port.private_data;
+ int rc;
+
+ rc = serial8250_do_startup(uart_port);
+ if (rc)
+ return rc;
+
+ ast_vuart_set_host_tx_discard(vuart, false);
+
+ return 0;
+}
+
+static void ast_vuart_shutdown(struct uart_port *uart_port)
+{
+ struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port);
+ struct ast_vuart *vuart = uart_8250_port->port.private_data;
+
+ ast_vuart_set_host_tx_discard(vuart, true);
+
+ serial8250_do_shutdown(uart_port);
+}
+
+
+/**
+ * The device tree parsing code here is heavily based on that of the of_serial
+ * driver, but we have a few core differences, as we need to use our own
+ * ioremapping for extra register support
+ */
+static int ast_vuart_probe(struct platform_device *pdev)
+{
+ struct uart_8250_port port;
+ struct resource resource;
+ struct ast_vuart *vuart;
+ struct device_node *np;
+ u32 clk, prop;
+ int rc;
+
+ np = pdev->dev.of_node;
+
+ vuart = devm_kzalloc(&pdev->dev, sizeof(*vuart), GFP_KERNEL);
+ if (!vuart)
+ return -ENOMEM;
+
+ vuart->pdev = pdev;
+ rc = of_address_to_resource(np, 0, &resource);
+ if (rc) {
+ dev_warn(&pdev->dev, "invalid address\n");
+ return rc;
+ }
+
+ /* create our own mapping for VUART-specific registers */
+ vuart->regs = devm_ioremap_resource(&pdev->dev, &resource);
+ if (IS_ERR(vuart->regs)) {
+ dev_warn(&pdev->dev, "failed to map registers\n");
+ return PTR_ERR(vuart->regs);
+ }
+
+ memset(&port, 0, sizeof(port));
+ port.port.private_data = vuart;
+ port.port.membase = vuart->regs;
+ port.port.mapbase = resource.start;
+ port.port.mapsize = resource_size(&resource);
+ port.port.startup = ast_vuart_startup;
+ port.port.shutdown = ast_vuart_shutdown;
+
+ if (of_property_read_u32(np, "clock-frequency", &clk)) {
+ vuart->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(vuart->clk)) {
+ dev_warn(&pdev->dev,
+ "clk or clock-frequency not defined\n");
+ return PTR_ERR(vuart->clk);
+ }
+
+ rc = clk_prepare_enable(vuart->clk);
+ if (rc < 0)
+ return rc;
+
+ clk = clk_get_rate(vuart->clk);
+ }
+
+ /* If current-speed was set, then try not to change it. */
+ if (of_property_read_u32(np, "current-speed", &prop) == 0)
+ port.port.custom_divisor = clk / (16 * prop);
+
+ /* Check for shifted address mapping */
+ if (of_property_read_u32(np, "reg-offset", &prop) == 0)
+ port.port.mapbase += prop;
+
+ /* Check for registers offset within the devices address range */
+ if (of_property_read_u32(np, "reg-shift", &prop) == 0)
+ port.port.regshift = prop;
+
+ /* Check for fifo size */
+ if (of_property_read_u32(np, "fifo-size", &prop) == 0)
+ port.port.fifosize = prop;
+
+ /* Check for a fixed line number */
+ rc = of_alias_get_id(np, "serial");
+ if (rc >= 0)
+ port.port.line = rc;
+
+ port.port.irq = irq_of_parse_and_map(np, 0);
+ port.port.irqflags = IRQF_SHARED;
+ port.port.iotype = UPIO_MEM;
+ if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
+ switch (prop) {
+ case 1:
+ port.port.iotype = UPIO_MEM;
+ break;
+ case 4:
+ port.port.iotype = of_device_is_big_endian(np) ?
+ UPIO_MEM32BE : UPIO_MEM32;
+ break;
+ default:
+ dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n",
+ prop);
+ rc = -EINVAL;
+ goto err_clk_disable;
+ }
+ }
+
+ port.port.type = PORT_16550A;
+ port.port.uartclk = clk;
+ port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
+ | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST;
+
+ if (of_find_property(np, "no-loopback-test", NULL))
+ port.port.flags |= UPF_SKIP_TEST;
+
+ port.port.dev = &pdev->dev;
+
+ if (port.port.fifosize)
+ port.capabilities = UART_CAP_FIFO;
+
+ if (of_property_read_bool(pdev->dev.of_node,
+ "auto-flow-control"))
+ port.capabilities |= UART_CAP_AFE;
+
+ rc = serial8250_register_8250_port(&port);
+ if (rc < 0)
+ goto err_clk_disable;
+
+
+ vuart->line = rc;
+ ast_vuart_set_enabled(vuart, true);
+ ast_vuart_set_host_tx_discard(vuart, true);
+ platform_set_drvdata(pdev, vuart);
+
+ /* extra sysfs control */
+ rc = device_create_file(&pdev->dev, &dev_attr_lpc_address);
+ if (rc)
+ dev_warn(&pdev->dev, "can't create lpc_address file\n");
+ rc = device_create_file(&pdev->dev, &dev_attr_sirq);
+ if (rc)
+ dev_warn(&pdev->dev, "can't create sirq file\n");
+
+ return 0;
+
+err_clk_disable:
+ if (vuart->clk)
+ clk_disable_unprepare(vuart->clk);
+
+ irq_dispose_mapping(port.port.irq);
+ return rc;
+}
+
+static int ast_vuart_remove(struct platform_device *pdev)
+{
+ struct ast_vuart *vuart = platform_get_drvdata(pdev);
+
+ ast_vuart_set_enabled(vuart, false);
+
+ if (vuart->clk)
+ clk_disable_unprepare(vuart->clk);
+ return 0;
+}
+
+static const struct of_device_id ast_vuart_table[] = {
+ { .compatible = "aspeed,ast2400-vuart" },
+ { .compatible = "aspeed,ast2500-vuart" },
+ { },
+};
+
+static struct platform_driver ast_vuart_driver = {
+ .driver = {
+ .name = "aspeed-vuart",
+ .of_match_table = ast_vuart_table,
+ },
+ .probe = ast_vuart_probe,
+ .remove = ast_vuart_remove,
+};
+
+module_platform_driver(ast_vuart_driver);
+
+MODULE_AUTHOR("Jeremy Kerr <jk@ozlabs.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Driver for Aspeed VUART device");
--
2.11.0
^ permalink raw reply related
* [PATCH 1/2] serial: 8250: Add flag so drivers can avoid THRE probe
From: Joel Stanley @ 2017-03-28 5:44 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Mark Rutland, Rob Herring
Cc: linux-serial, linux-kernel, openbmc, devicetree,
Benjamin Herrenschmidt, Jeremy Kerr
In-Reply-To: <20170328054458.29341-1-joel@jms.id.au>
The probing of THRE irq behaviour assumes the other end will be reading
bytes out of the buffer in order to probe the port at driver init. In
some cases the other end cannot be relied upon to read these bytes, so
provide a flag for them to skip this step.
Bit 16 was chosen as the flags are a int and the top bits are taken.
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
drivers/tty/serial/8250/8250_port.c | 2 +-
include/linux/serial_core.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fe4399b41df6..f4c6da107dec 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2205,7 +2205,7 @@ int serial8250_do_startup(struct uart_port *port)
}
}
- if (port->irq) {
+ if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
unsigned char iir1;
/*
* Test for UARTs that do not reassert THRE when the
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 5def8e830fb0..f9e1fa39f553 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -195,6 +195,7 @@ struct uart_port {
#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
#define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ )
+#define UPF_NO_THRE_TEST ((__force upf_t) (1 << 19))
/* Port has hardware-assisted h/w flow control */
#define UPF_AUTO_CTS ((__force upf_t) (1 << 20))
#define UPF_AUTO_RTS ((__force upf_t) (1 << 21))
--
2.11.0
^ permalink raw reply related
* [PATCH 0/2] drivers: serial: Aspeed VUART driver
From: Joel Stanley @ 2017-03-28 5:44 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Mark Rutland, Rob Herring
Cc: linux-serial-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
openbmc-uLR06cmDAlY/bJ5BZ2RsiQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
Benjamin Herrenschmidt, Jeremy Kerr
This is a driver for the Aspeed VUART. The VUART is a serial device on the BMC
side of the LPC bus that connects a BMC to it's host processor.
We add a flag to the serial core to allow the driver to skip probing of the
THRE irq behaviour, which could hang due to the host not reading bytes out of
the buffer.
We've been using this on systems for over a year, so it has seen a good amount
of testing.
Cheers,
Joel
Jeremy Kerr (1):
drivers/serial: Add driver for Aspeed virtual UART
Joel Stanley (1):
serial: 8250: Add flag so drivers can avoid THRE probe
Documentation/devicetree/bindings/serial/8250.txt | 2 +
drivers/tty/serial/8250/8250_port.c | 2 +-
drivers/tty/serial/Kconfig | 10 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/aspeed-vuart.c | 335 ++++++++++++++++++++++
include/linux/serial_core.h | 1 +
6 files changed, 350 insertions(+), 1 deletion(-)
create mode 100644 drivers/tty/serial/aspeed-vuart.c
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v8 3/3] printk: fix double printing with earlycon
From: Sergey Senozhatsky @ 2017-03-28 2:04 UTC (permalink / raw)
To: Aleksey Makarov
Cc: Petr Mladek, linux-serial, linux-kernel, Sudeep Holla,
Greg Kroah-Hartman, Peter Hurley, Jiri Slaby, Robin Murphy,
Steven Rostedt, Nair, Jayachandran, Sergey Senozhatsky
In-Reply-To: <4b561f81-67af-f6a3-76c9-d0d8499c52bd@linaro.org>
On (03/27/17 19:28), Aleksey Makarov wrote:
[..]
> > > + /*
> > > + * Maintain an invariant that will help to find if
> > > + * the matching console is preferred, see
> > > + * register_console():
> > > + *
> > > + * The last non-braille console is always
> > > + * the preferred one.
> > > + */
> > > + for (last = MAX_CMDLINECONSOLES - 1;
> > > + last >= 0 && !console_cmdline[last].name[0];
> > > + last--)
> > > + ;
> >
> > This is a rather non-trivial code to find the last element.
> > I might make sense to count it in a global variable.
> > Then we might remove the check for console_cmdline[i].name[0]
> > also in the other for cycles and make them better readable.
>
> Having an additional variable console_cmdline_last pointing to the last element
> would require maintaining consistency between this variable and
> contents of console_cmdline. For the code we have it is not hard, but when code
> is changed we need to check this. Also there exists preferred_console that
> has almost the same meaning but it points not to the last element, but to the
> last non-braille element. Also we need to have a special value (-1) for this
> variable for empty array. So I personally would instead try to rewrite this:
>
> for (last = MAX_CMDLINECONSOLES - 1; last >= 0; last--)
> if (console_cmdline[last].name[0])
> break;
>
> Is it better? If not, I will send a version with console_cmdline_last.
personally I'm fine with the nested loop. the latest version
"for (last = MAX_CMDLINECONSOLES - 1; last >= 0;..."
is even easier to read.
so we do not just iterate console_cmdline anymore, but also modify it.
this, probably, has impact on the following scenario
CPU0 CPU1
add_preferred_console() add_preferred_console()
__add_preferred_console() __add_preferred_console()
swap(i1, last) swap(i2, last)
temp1 = i1
i1 = last temp2 = i2
last = temp1 i2 = last
last = temp2
so both i1 and i2 will point to 'last' now, IOW, we will have two
identical entries in console_cmdline, while i1 or i2 will be lost.
neither add_preferred_console() nor __add_preferred_console() have any
serialization. and I assume that we can call add_preferred_console()
concurrently, can't we?
-ss
^ permalink raw reply
* [PATCH] serial: 8250_EXAR: fix duplicate Kconfig text and add missing help text
From: Paul Gortmaker @ 2017-03-27 23:39 UTC (permalink / raw)
To: linux-kernel
Cc: Paul Gortmaker, Andy Shevchenko, Sudip Mukherjee,
Greg Kroah-Hartman, Jiri Slaby, linux-serial
In commit d0aeaa83f0b0f7a92615bbdd6b1f96812f7dcfd2 ("serial: exar:
split out the exar code from 8250_pci") the exar driver got its own
Kconfig. However the text for the new option was never changed from
the original 8250_PCI text, and hence it appears confusing when you
get asked the same question twice:
8250/16550 PCI device support (SERIAL_8250_PCI) [Y/n/m/?] (NEW)
8250/16550 PCI device support (SERIAL_8250_EXAR) [Y/n/m] (NEW)
Adding to the confusion, is that there is no help text for this new
option to indicate it is specific to a certain family of cards.
Fix both issues at the same time, as well as the space vs. tab issues
introduced in the same commit.
Fixes: d0aeaa83f0b0 ("serial: exar: split out the exar code from 8250_pci")
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-serial@vger.kernel.org
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
drivers/tty/serial/8250/Kconfig | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index a65fb8197aec..0e3f529d50e9 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -128,9 +128,13 @@ config SERIAL_8250_PCI
by the parport_serial driver, enabled with CONFIG_PARPORT_SERIAL.
config SERIAL_8250_EXAR
- tristate "8250/16550 PCI device support"
- depends on SERIAL_8250_PCI
+ tristate "8250/16550 Exar/Commtech PCI/PCIe device support"
+ depends on SERIAL_8250_PCI
default SERIAL_8250
+ help
+ This builds support for XR17C1xx, XR17V3xx and some Commtech
+ 422x PCIe serial cards that are not covered by the more generic
+ SERIAL_8250_PCI option.
config SERIAL_8250_HP300
tristate
--
2.11.0
^ permalink raw reply related
* Re: [PATCH RFC v4 07/10] dt-bindings: net: add binding for QCA7000 UART
From: Rob Herring @ 2017-03-27 20:30 UTC (permalink / raw)
To: Stefan Wahren
Cc: Mark Rutland, David S. Miller, Greg Kroah-Hartman, Jiri Slaby,
Marcel Holtmann, Sebastian Reichel, netdev,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1490621848-24828-8-git-send-email-stefan.wahren-eS4NqCHxEME@public.gmane.org>
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org> wrote:
> This is the serdev binding for the QCA7000 UART driver (Ethernet over UART).
>
> Signed-off-by: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
> ---
>
> According to this binding are still some questions:
>
> Where should be the optional hardware flow control defined (at master or slave side)?
Probably should be in the slave side. We already have uart-has-rtscts
and rts/cts-gpios for the UART. Those mean we have RTS/CTS, but not
necessarily that we want to enable them.
In many cases, the driver may know what it needs.
> Is it okay to have two bindings (qca-qca7000-spi and qca-qca7000-uart) or should they be merged?
Are they mutually-exclusive or both are used at the same time? What
are the dependencies between the interfaces?
>
>
> .../devicetree/bindings/net/qca-qca7000-uart.txt | 31 ++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/qca-qca7000-uart.txt
>
> diff --git a/Documentation/devicetree/bindings/net/qca-qca7000-uart.txt b/Documentation/devicetree/bindings/net/qca-qca7000-uart.txt
> new file mode 100644
> index 0000000..f2e0450
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/qca-qca7000-uart.txt
> @@ -0,0 +1,31 @@
> +* Qualcomm QCA7000 (Ethernet over UART protocol)
> +
> +Note: This binding applies in case the QCA7000 is configured as a
> +UART slave device. It is possible to preconfigure the UART settings
> +of the QCA7000 firmware, which can't be changed during runtime.
> +
> +Required properties:
> +- compatible : Should be "qca,qca7000-uart"
> +
> +Optional properties:
> +- local-mac-address : 6 bytes, Specifies MAC address
The description can be "see ./ethernet.txt"
> +- current-speed : Specifies the serial device speed in
> + bits per second (default = 115200), which is
> + predefined by the QCA7000 firmware configuration
Add this to the slave binding doc with some caveats as to when this
should or should not be used as we discussed.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH RFC v4 10/10] tty: serdev: add functions to retrieve common UART settings
From: Rob Herring @ 2017-03-27 20:00 UTC (permalink / raw)
To: Stefan Wahren
Cc: Mark Rutland, David S. Miller, Greg Kroah-Hartman, Jiri Slaby,
Marcel Holtmann, Sebastian Reichel, netdev,
devicetree@vger.kernel.org, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1490621848-24828-11-git-send-email-stefan.wahren@i2se.com>
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren <stefan.wahren@i2se.com> wrote:
> Currently serdev core doesn't provide functions to retrieve common
> UART settings like data bits, stop bits or parity. This patch adds
> the interface to the core and the necessary implementation for
> serdev-ttyport.
It doesn't provide them because why do you need to know? The attached
device should request the settings it needs and be done with it. Maybe
some devices can support a number of settings and you could want
negotiate the settings with the UART, though surely 8N1 is in that
list. It's rare to see something that's not 8N1 from what I've seen.
Rob
^ permalink raw reply
* Re: [PATCH RFC v4 09/10] tty: serdev-ttyport: return actual baudrate from ttyport_set_baudrate
From: Rob Herring @ 2017-03-27 19:50 UTC (permalink / raw)
To: Stefan Wahren
Cc: Mark Rutland, David S. Miller, Greg Kroah-Hartman, Jiri Slaby,
Marcel Holtmann, Sebastian Reichel, netdev,
devicetree@vger.kernel.org, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1490621848-24828-10-git-send-email-stefan.wahren@i2se.com>
On Mon, Mar 27, 2017 at 8:37 AM, Stefan Wahren <stefan.wahren@i2se.com> wrote:
> Instead of returning the requested baudrate, we better return the
> actual one because it isn't always the same.
>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> ---
> drivers/tty/serdev/serdev-ttyport.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH V7 2/7] PCI: Apply the new generic I/O management on PCI IO hosts
From: dann frazier @ 2017-03-27 19:46 UTC (permalink / raw)
To: zhichang.yuan
Cc: Catalin Marinas, Will Deacon, Rob Herring, frowand.list,
Bjorn Helgaas, rafael, Mark Rutland, rjw, Arnd Bergmann,
linux-arm-kernel, linux-acpi, lorenzo.pieralisi, benh,
linux-kernel@vger.kernel.org, linuxarm,
devicetree@vger.kernel.org, linux-pci,
linux-serial@vger.kernel.org, minyard, liviu.dudau, zourongrong,
john.garry, gabriele.paoloni, zhich
In-Reply-To: <1489372963-9000-3-git-send-email-yuanzhichang@hisilicon.com>
On Sun, Mar 12, 2017 at 8:42 PM, zhichang.yuan
<yuanzhichang@hisilicon.com> wrote:
> After introducing the new generic I/O space management(LIBIO), the original PCI
> MMIO relevant helpers need to be updated based on the new interfaces defined in
> LIBIO.
> This patch adapts the corresponding code to match the changes introduced by
> LIBIO.
> Signed-off-by: zhichang.yuan <yuanzhichang@hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de> #earlier draft
> Acked-by: Bjorn Helgaas <bhelgaas@google.com> #drivers/pci parts
> ---
> drivers/acpi/pci_root.c | 8 +++--
> drivers/of/address.c | 4 ++-
> drivers/pci/pci.c | 96 +++++++++++--------------------------------------
> include/linux/pci.h | 3 +-
> 4 files changed, 30 insertions(+), 81 deletions(-)
>
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index 919be0a..4d8cc24 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -730,7 +730,8 @@ static void acpi_pci_root_validate_resources(struct device *dev,
> }
> }
>
> -static void acpi_pci_root_remap_iospace(struct resource_entry *entry)
> +static void acpi_pci_root_remap_iospace(struct fwnode_handle *fwnode,
> + struct resource_entry *entry)
> {
> #ifdef PCI_IOBASE
> struct resource *res = entry->res;
> @@ -739,7 +740,7 @@ static void acpi_pci_root_remap_iospace(struct resource_entry *entry)
> resource_size_t length = resource_size(res);
> unsigned long port;
>
> - if (pci_register_io_range(cpu_addr, length))
> + if (pci_register_io_range(fwnode, cpu_addr, length))
> goto err;
>
> port = pci_address_to_pio(cpu_addr);
> @@ -781,7 +782,8 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
> else {
> resource_list_for_each_entry_safe(entry, tmp, list) {
> if (entry->res->flags & IORESOURCE_IO)
> - acpi_pci_root_remap_iospace(entry);
> + acpi_pci_root_remap_iospace(&device->fwnode,
> + entry);
>
> if (entry->res->flags & IORESOURCE_DISABLED)
> resource_list_destroy_entry(entry);
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 02b2903..fb5d16a 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -2,6 +2,7 @@
> #define pr_fmt(fmt) "OF: " fmt
>
> #include <linux/device.h>
> +#include <linux/fwnode.h>
> #include <linux/io.h>
> #include <linux/ioport.h>
> #include <linux/module.h>
> @@ -323,7 +324,8 @@ int of_pci_range_to_resource(struct of_pci_range *range,
>
> if (res->flags & IORESOURCE_IO) {
> unsigned long port;
> - err = pci_register_io_range(range->cpu_addr, range->size);
> + err = pci_register_io_range(&np->fwnode, range->cpu_addr,
> + range->size);
> if (err)
> goto invalid_range;
> port = pci_address_to_pio(range->cpu_addr);
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 7904d02..079319f 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3238,65 +3238,37 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
> }
> EXPORT_SYMBOL(pci_request_regions_exclusive);
>
> -#ifdef PCI_IOBASE
> -struct io_range {
> - struct list_head list;
> - phys_addr_t start;
> - resource_size_t size;
> -};
> -
> -static LIST_HEAD(io_range_list);
> -static DEFINE_SPINLOCK(io_range_lock);
> -#endif
> -
> /*
> * Record the PCI IO range (expressed as CPU physical address + size).
> * Return a negative value if an error has occured, zero otherwise
> */
> -int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
> +int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
> + resource_size_t size)
> {
> int err = 0;
>
> #ifdef PCI_IOBASE
> - struct io_range *range;
> - resource_size_t allocated_size = 0;
> -
> - /* check if the range hasn't been previously recorded */
> - spin_lock(&io_range_lock);
> - list_for_each_entry(range, &io_range_list, list) {
> - if (addr >= range->start && addr + size <= range->start + size) {
> - /* range already registered, bail out */
> - goto end_register;
> - }
> - allocated_size += range->size;
> - }
> -
> - /* range not registed yet, check for available space */
> - if (allocated_size + size - 1 > IO_SPACE_LIMIT) {
> - /* if it's too big check if 64K space can be reserved */
> - if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) {
> - err = -E2BIG;
> - goto end_register;
> - }
> + struct libio_range *range, *tmprange;
>
> - size = SZ_64K;
> - pr_warn("Requested IO range too big, new size set to 64K\n");
> - }
> + if (!size || addr + size < addr)
> + return -EINVAL;
>
> - /* add the range to the list */
> - range = kzalloc(sizeof(*range), GFP_ATOMIC);
> - if (!range) {
> - err = -ENOMEM;
> - goto end_register;
> - }
> + WARN_ON(!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(size));
>
> - range->start = addr;
> + range = kzalloc(sizeof(*range), GFP_KERNEL);
> + if (!range)
> + return -ENOMEM;
> + range->node = fwnode;
> + range->flags = IO_CPU_MMIO;
> range->size = size;
> + range->hw_start = addr;
>
> - list_add_tail(&range->list, &io_range_list);
> -
> -end_register:
> - spin_unlock(&io_range_lock);
> + tmprange = register_libio_range(range);
> + if (tmprange != range) {
> + kfree(range);
> + if (!IS_ERR(tmprange))
> + err = 0;
> + }
> #endif
>
> return err;
> @@ -3307,21 +3279,10 @@ phys_addr_t pci_pio_to_address(unsigned long pio)
> phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
>
> #ifdef PCI_IOBASE
> - struct io_range *range;
> - resource_size_t allocated_size = 0;
> -
> if (pio > IO_SPACE_LIMIT)
> return address;
>
> - spin_lock(&io_range_lock);
> - list_for_each_entry(range, &io_range_list, list) {
> - if (pio >= allocated_size && pio < allocated_size + range->size) {
> - address = range->start + pio - allocated_size;
> - break;
> - }
> - allocated_size += range->size;
> - }
> - spin_unlock(&io_range_lock);
> + address = libio_to_hwaddr(pio);
> #endif
>
> return address;
> @@ -3330,25 +3291,8 @@ phys_addr_t pci_pio_to_address(unsigned long pio)
> unsigned long __weak pci_address_to_pio(phys_addr_t address)
> {
> #ifdef PCI_IOBASE
> - struct io_range *res;
> - resource_size_t offset = 0;
> - unsigned long addr = -1;
> -
> - spin_lock(&io_range_lock);
> - list_for_each_entry(res, &io_range_list, list) {
> - if (address >= res->start && address < res->start + res->size) {
> - addr = address - res->start + offset;
> - break;
> - }
> - offset += res->size;
> - }
> - spin_unlock(&io_range_lock);
> -
> - return addr;
> + return libio_translate_cpuaddr(address);
> #else
> - if (address > IO_SPACE_LIMIT)
> - return (unsigned long)-1;
> -
> return (unsigned long) address;
> #endif
> }
fyi, this fails to build if PCI_IOBASE is defined and CONFIG_LIBIO=n:
drivers/built-in.o: In function `pci_register_io_range':
/home/ubuntu/linux-4.10.0/drivers/pci/pci.c:3266: undefined reference
to `register_libio_range'
drivers/built-in.o: In function `pci_pio_to_address':
/home/ubuntu/linux-4.10.0/drivers/pci/pci.c:3285: undefined reference
to `libio_to_hwaddr'
drivers/built-in.o: In function `pci_address_to_pio':
/home/ubuntu/linux-4.10.0/drivers/pci/pci.c:3294: undefined reference
to `libio_translate_cpuaddr'
-dann
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index eb3da1a..6401327 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1194,7 +1194,8 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
> void *alignf_data);
>
>
> -int pci_register_io_range(phys_addr_t addr, resource_size_t size);
> +int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
> + resource_size_t size);
> unsigned long pci_address_to_pio(phys_addr_t addr);
> phys_addr_t pci_pio_to_address(unsigned long pio);
> int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v8 3/3] printk: fix double printing with earlycon
From: Aleksey Makarov @ 2017-03-27 16:28 UTC (permalink / raw)
To: Petr Mladek, Aleksey Makarov
Cc: linux-serial, linux-kernel, Sudeep Holla, Greg Kroah-Hartman,
Peter Hurley, Jiri Slaby, Robin Murphy, Steven Rostedt,
Nair, Jayachandran, Sergey Senozhatsky
In-Reply-To: <20170327141432.GH2846@pathway.suse.cz>
On 03/27/2017 05:14 PM, Petr Mladek wrote:
> On Mon 2017-03-20 13:03:00, Aleksey Makarov wrote:
[..]
>> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
>> index fd752f0c8ef1..462036e7a767 100644
>> --- a/kernel/printk/printk.c
>> +++ b/kernel/printk/printk.c
>> @@ -1909,8 +1909,28 @@ static int __add_preferred_console(char *name, int idx, char *options,
>> i < MAX_CMDLINECONSOLES && c->name[0];
>> i++, c++) {
>> if (strcmp(c->name, name) == 0 && c->index == idx) {
>> - if (!brl_options)
>> - preferred_console = i;
>> + int last;
>> +
>> + if (brl_options)
>> + return 0;
>> +
>> + /*
>> + * Maintain an invariant that will help to find if
>> + * the matching console is preferred, see
>> + * register_console():
>> + *
>> + * The last non-braille console is always
>> + * the preferred one.
>> + */
>> + for (last = MAX_CMDLINECONSOLES - 1;
>> + last >= 0 && !console_cmdline[last].name[0];
>> + last--)
>> + ;
>
> This is a rather non-trivial code to find the last element.
> I might make sense to count it in a global variable.
> Then we might remove the check for console_cmdline[i].name[0]
> also in the other for cycles and make them better readable.
Having an additional variable console_cmdline_last pointing to the last element
would require maintaining consistency between this variable and
contents of console_cmdline. For the code we have it is not hard, but when code
is changed we need to check this. Also there exists preferred_console that
has almost the same meaning but it points not to the last element, but to the
last non-braille element. Also we need to have a special value (-1) for this
variable for empty array. So I personally would instead try to rewrite this:
for (last = MAX_CMDLINECONSOLES - 1; last >= 0; last--)
if (console_cmdline[last].name[0])
break;
Is it better? If not, I will send a version with console_cmdline_last.
>> +
>> + if (i != last)
>> + swap(console_cmdline[i], console_cmdline[last]);
>
> I was not aware of the swap() function. It is great to know ;-)
Yes, same for me. Thanks to Sergey Senozhatsky.
Thank you for review
Aleksey Makarov
^ permalink raw reply
* Re: [PATCH RFC v4 06/10] net: qualcomm: make qca_common a separate kernel module
From: Dan Williams @ 2017-03-27 15:44 UTC (permalink / raw)
To: Stefan Wahren, Rob Herring, Mark Rutland, David S. Miller
Cc: Greg Kroah-Hartman, Jiri Slaby, Marcel Holtmann,
Sebastian Reichel, netdev, devicetree, linux-serial, linux-kernel
In-Reply-To: <1490621848-24828-7-git-send-email-stefan.wahren@i2se.com>
On Mon, 2017-03-27 at 15:37 +0200, Stefan Wahren wrote:
> In order to share common functions between QCA7000 SPI and UART
> protocol
> driver the qca_common needs to be a separate kernel module.
Maybe "qca_eth_common"? There are many things Qualcomm, slightly fewer
things Qualcomm Atheros, and "qca_common" isn't very descriptive.
Dan
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> ---
> drivers/net/ethernet/qualcomm/Kconfig | 8 +++++++-
> drivers/net/ethernet/qualcomm/Makefile | 5 +++--
> drivers/net/ethernet/qualcomm/qca_common.c | 10 ++++++++++
> 3 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/qualcomm/Kconfig
> b/drivers/net/ethernet/qualcomm/Kconfig
> index d7720bf..b4c369d 100644
> --- a/drivers/net/ethernet/qualcomm/Kconfig
> +++ b/drivers/net/ethernet/qualcomm/Kconfig
> @@ -16,7 +16,13 @@ config NET_VENDOR_QUALCOMM
> if NET_VENDOR_QUALCOMM
>
> config QCA7000
> - tristate "Qualcomm Atheros QCA7000 support"
> + tristate
> + help
> + This enables support for the Qualcomm Atheros QCA7000.
> +
> +config QCA7000_SPI
> + tristate "Qualcomm Atheros QCA7000 SPI support"
> + select QCA7000
> depends on SPI_MASTER && OF
> ---help---
> This SPI protocol driver supports the Qualcomm Atheros
> QCA7000.
> diff --git a/drivers/net/ethernet/qualcomm/Makefile
> b/drivers/net/ethernet/qualcomm/Makefile
> index 8080570..00d8729 100644
> --- a/drivers/net/ethernet/qualcomm/Makefile
> +++ b/drivers/net/ethernet/qualcomm/Makefile
> @@ -2,7 +2,8 @@
> # Makefile for the Qualcomm network device drivers.
> #
>
> -obj-$(CONFIG_QCA7000) += qcaspi.o
> -qcaspi-objs := qca_spi.o qca_common.o qca_7k.o qca_debug.o
> +obj-$(CONFIG_QCA7000) += qca_common.o
> +obj-$(CONFIG_QCA7000_SPI) += qcaspi.o
> +qcaspi-objs := qca_7k.o qca_debug.o qca_spi.o
>
> obj-y += emac/
> diff --git a/drivers/net/ethernet/qualcomm/qca_common.c
> b/drivers/net/ethernet/qualcomm/qca_common.c
> index d930524..f2c9e76 100644
> --- a/drivers/net/ethernet/qualcomm/qca_common.c
> +++ b/drivers/net/ethernet/qualcomm/qca_common.c
> @@ -21,7 +21,9 @@
> * by an atheros frame while transmitted over a serial channel;
> */
>
> +#include <linux/init.h>
> #include <linux/kernel.h>
> +#include <linux/module.h>
>
> #include "qca_common.h"
>
> @@ -46,6 +48,7 @@ qcafrm_create_header(u8 *buf, u16 length)
>
> return QCAFRM_HEADER_LEN;
> }
> +EXPORT_SYMBOL_GPL(qcafrm_create_header);
>
> u16
> qcafrm_create_footer(u8 *buf)
> @@ -57,6 +60,7 @@ qcafrm_create_footer(u8 *buf)
> buf[1] = 0x55;
> return QCAFRM_FOOTER_LEN;
> }
> +EXPORT_SYMBOL_GPL(qcafrm_create_footer);
>
> /* Gather received bytes and try to extract a full ethernet frame
> by
> * following a simple state machine.
> @@ -154,3 +158,9 @@ qcafrm_fsm_decode(struct qcafrm_handle *handle,
> u8 *buf, u16 buf_len, u8 recv_by
>
> return ret;
> }
> +EXPORT_SYMBOL_GPL(qcafrm_fsm_decode);
> +
> +MODULE_DESCRIPTION("Qualcomm Atheros Common");
> +MODULE_AUTHOR("Qualcomm Atheros Communications");
> +MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
> +MODULE_LICENSE("Dual BSD/GPL");
^ permalink raw reply
* Re: [PATCHv2] braille-console: Fix value returned by _braille_console_setup
From: Sergey Senozhatsky @ 2017-03-27 15:43 UTC (permalink / raw)
To: Samuel Thibault, Petr Mladek
Cc: Steven Rostedt, Ming Lei, Aleksey Makarov, linux-serial,
Joe Perches, linux-kernel, Sergey Senozhatsky
In-Reply-To: <20170326204736.65jjbfrfvammgxqy@var.youpi.perso.aquilenet.fr>
On (03/26/17 22:47), Samuel Thibault wrote:
> commit bbeddf52adc1 ("printk: move braille console support into
> separate braille.[ch] files") introduced _braille_console_setup()
> to outline the braille initialization code. There was however some
> confusion over the value it was supposed to return. commit 2cfe6c4ac7ee
> ("printk: Fix return of braille_register_console()") tried to fix it
> but failed to.
>
> This fixes and documents the returned value according to the use
> in printk.c: non-zero return means a parsing error, and thus this
> console configuration should be ignored.
I just found this patch in my gmail "spam" folder.
sorry.
the patch looks OK to me.
btw, is there any reason why _braille_console_setup() and
_braille_register_console()/_braille_unregister_console()
names start with a dash? do we also want to "clean this up"?
well since we are at it.
-ss
^ 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