* [PATCH v2 1/2] tty/serial: atmel: remove atmel_default_console_device handling
From: Alexandre Belloni @ 2017-06-13 20:24 UTC (permalink / raw)
To: Richard Genoud, Greg Kroah-Hartman
Cc: Nicolas Ferre, linux-serial, linux-arm-kernel, linux-kernel,
Alexandre Belloni
atmel_default_console_device was only used by AVR32, in particular
arch/avr32/mach-at32ap/at32ap700x.c which is now gone. Remove it from the
driver.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
Changes in v2:
- added an empty line as suggested by Andy
- properly based the patch on v4.12-rc1
drivers/tty/serial/atmel_serial.c | 43 ---------------------------------------
1 file changed, 43 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index c355ac9abafc..906e2b91bf57 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -2460,8 +2460,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
return 0;
}
-struct platform_device *atmel_default_console_device; /* the serial console device */
-
#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
static void atmel_console_putchar(struct uart_port *port, int ch)
{
@@ -2594,47 +2592,6 @@ static struct console atmel_console = {
#define ATMEL_CONSOLE_DEVICE (&atmel_console)
-/*
- * Early console initialization (before VM subsystem initialized).
- */
-static int __init atmel_console_init(void)
-{
- int ret;
- if (atmel_default_console_device) {
- struct atmel_uart_data *pdata =
- dev_get_platdata(&atmel_default_console_device->dev);
- int id = pdata->num;
- struct atmel_uart_port *atmel_port = &atmel_ports[id];
-
- atmel_port->backup_imr = 0;
- atmel_port->uart.line = id;
-
- add_preferred_console(ATMEL_DEVICENAME, id, NULL);
- ret = atmel_init_port(atmel_port, atmel_default_console_device);
- if (ret)
- return ret;
- register_console(&atmel_console);
- }
-
- return 0;
-}
-
-console_initcall(atmel_console_init);
-
-/*
- * Late console initialization.
- */
-static int __init atmel_late_console_init(void)
-{
- if (atmel_default_console_device
- && !(atmel_console.flags & CON_ENABLED))
- register_console(&atmel_console);
-
- return 0;
-}
-
-core_initcall(atmel_late_console_init);
-
static inline bool atmel_is_console_port(struct uart_port *port)
{
return port->cons && port->cons->index == port->line;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 2/2] tty/serial: atmel: make the driver DT only
From: Alexandre Belloni @ 2017-06-13 19:56 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Richard Genoud, Greg Kroah-Hartman, Nicolas Ferre,
linux-serial@vger.kernel.org, linux-arm Mailing List,
linux-kernel@vger.kernel.org
In-Reply-To: <CAHp75VdQu=mm3hPb32+3osbx+wugH4iTFqAnz8-2GDmsYV8ViA@mail.gmail.com>
On 13/06/2017 at 17:50:25 +0300, Andy Shevchenko wrote:
> On Tue, Jun 13, 2017 at 4:40 PM, Alexandre Belloni
> <alexandre.belloni@free-electrons.com> wrote:
> > Now that AVR32 is gone, platform_data are not used to initialize the driver
> > anymore, remove that path from the driver. Also remove the now unused
> > struct atmel_uart_data.
>
> Nitpicks, not insisting on them at all, just a side comment.
>
> > + struct serial_rs485 *rs485conf = &port->rs485;
> > + u32 rs485_delay[2];
>
> + empty line?
>
Okay
> > + /* rs485 properties */
>
> > + if (of_property_read_u32_array(np, "rs485-rts-delay",
> > + rs485_delay, 2) == 0) {
>
> Now it can be one line I suppose (taking into account ...() == 0 ->
> !...() change)
>
No, it still doesn't fit, I'll leave it as-is
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH 2/2] tty/serial: atmel: make the driver DT only
From: Andy Shevchenko @ 2017-06-13 14:50 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Richard Genoud, Greg Kroah-Hartman, Nicolas Ferre,
linux-serial@vger.kernel.org, linux-arm Mailing List,
linux-kernel@vger.kernel.org
In-Reply-To: <20170613134038.5545-2-alexandre.belloni@free-electrons.com>
On Tue, Jun 13, 2017 at 4:40 PM, Alexandre Belloni
<alexandre.belloni@free-electrons.com> wrote:
> Now that AVR32 is gone, platform_data are not used to initialize the driver
> anymore, remove that path from the driver. Also remove the now unused
> struct atmel_uart_data.
Nitpicks, not insisting on them at all, just a side comment.
> + struct serial_rs485 *rs485conf = &port->rs485;
> + u32 rs485_delay[2];
+ empty line?
> + /* rs485 properties */
> + if (of_property_read_u32_array(np, "rs485-rts-delay",
> + rs485_delay, 2) == 0) {
Now it can be one line I suppose (taking into account ...() == 0 ->
!...() change)
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH 2/2] tty/serial: atmel: make the driver DT only
From: Alexandre Belloni @ 2017-06-13 13:40 UTC (permalink / raw)
To: Richard Genoud, Greg Kroah-Hartman
Cc: Nicolas Ferre, linux-serial, linux-arm-kernel, linux-kernel,
Alexandre Belloni
In-Reply-To: <20170613134038.5545-1-alexandre.belloni@free-electrons.com>
Now that AVR32 is gone, platform_data are not used to initialize the driver
anymore, remove that path from the driver. Also remove the now unused
struct atmel_uart_data.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/tty/serial/atmel_serial.c | 97 +++++++++++++------------------------
include/linux/platform_data/atmel.h | 11 -----
2 files changed, 33 insertions(+), 75 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 906e2b91bf57..1210a2632846 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1655,72 +1655,55 @@ static void atmel_init_property(struct atmel_uart_port *atmel_port,
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
-
- if (np) {
- /* DMA/PDC usage specification */
- if (of_property_read_bool(np, "atmel,use-dma-rx")) {
- if (of_property_read_bool(np, "dmas")) {
- atmel_port->use_dma_rx = true;
- atmel_port->use_pdc_rx = false;
- } else {
- atmel_port->use_dma_rx = false;
- atmel_port->use_pdc_rx = true;
- }
+
+ /* DMA/PDC usage specification */
+ if (of_property_read_bool(np, "atmel,use-dma-rx")) {
+ if (of_property_read_bool(np, "dmas")) {
+ atmel_port->use_dma_rx = true;
+ atmel_port->use_pdc_rx = false;
} else {
atmel_port->use_dma_rx = false;
- atmel_port->use_pdc_rx = false;
+ atmel_port->use_pdc_rx = true;
}
+ } else {
+ atmel_port->use_dma_rx = false;
+ atmel_port->use_pdc_rx = false;
+ }
- if (of_property_read_bool(np, "atmel,use-dma-tx")) {
- if (of_property_read_bool(np, "dmas")) {
- atmel_port->use_dma_tx = true;
- atmel_port->use_pdc_tx = false;
- } else {
- atmel_port->use_dma_tx = false;
- atmel_port->use_pdc_tx = true;
- }
+ if (of_property_read_bool(np, "atmel,use-dma-tx")) {
+ if (of_property_read_bool(np, "dmas")) {
+ atmel_port->use_dma_tx = true;
+ atmel_port->use_pdc_tx = false;
} else {
atmel_port->use_dma_tx = false;
- atmel_port->use_pdc_tx = false;
+ atmel_port->use_pdc_tx = true;
}
-
} else {
- atmel_port->use_pdc_rx = pdata->use_dma_rx;
- atmel_port->use_pdc_tx = pdata->use_dma_tx;
- atmel_port->use_dma_rx = false;
atmel_port->use_dma_tx = false;
+ atmel_port->use_pdc_tx = false;
}
-
}
static void atmel_init_rs485(struct uart_port *port,
struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
-
- if (np) {
- struct serial_rs485 *rs485conf = &port->rs485;
- u32 rs485_delay[2];
- /* rs485 properties */
- if (of_property_read_u32_array(np, "rs485-rts-delay",
- rs485_delay, 2) == 0) {
- rs485conf->delay_rts_before_send = rs485_delay[0];
- rs485conf->delay_rts_after_send = rs485_delay[1];
- rs485conf->flags = 0;
- }
-
- if (of_get_property(np, "rs485-rx-during-tx", NULL))
- rs485conf->flags |= SER_RS485_RX_DURING_TX;
- if (of_get_property(np, "linux,rs485-enabled-at-boot-time",
- NULL))
- rs485conf->flags |= SER_RS485_ENABLED;
- } else {
- port->rs485 = pdata->rs485;
+ struct serial_rs485 *rs485conf = &port->rs485;
+ u32 rs485_delay[2];
+ /* rs485 properties */
+ if (of_property_read_u32_array(np, "rs485-rts-delay",
+ rs485_delay, 2) == 0) {
+ rs485conf->delay_rts_before_send = rs485_delay[0];
+ rs485conf->delay_rts_after_send = rs485_delay[1];
+ rs485conf->flags = 0;
}
+ if (of_get_property(np, "rs485-rx-during-tx", NULL))
+ rs485conf->flags |= SER_RS485_RX_DURING_TX;
+
+ if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL))
+ rs485conf->flags |= SER_RS485_ENABLED;
}
static void atmel_set_ops(struct uart_port *port)
@@ -2402,7 +2385,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
{
int ret;
struct uart_port *port = &atmel_port->uart;
- struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
atmel_init_property(atmel_port, pdev);
atmel_set_ops(port);
@@ -2410,24 +2392,17 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
atmel_init_rs485(port, pdev);
port->iotype = UPIO_MEM;
- port->flags = UPF_BOOT_AUTOCONF;
+ port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
port->ops = &atmel_pops;
port->fifosize = 1;
port->dev = &pdev->dev;
port->mapbase = pdev->resource[0].start;
port->irq = pdev->resource[1].start;
port->rs485_config = atmel_config_rs485;
+ port->membase = NULL;
memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
- if (pdata && pdata->regs) {
- /* Already mapped by setup code */
- port->membase = pdata->regs;
- } else {
- port->flags |= UPF_IOREMAP;
- port->membase = NULL;
- }
-
/* for console, the clock could already be configured */
if (!atmel_port->clk) {
atmel_port->clk = clk_get(&pdev->dev, "usart");
@@ -2761,19 +2736,13 @@ static int atmel_serial_probe(struct platform_device *pdev)
{
struct atmel_uart_port *atmel_port;
struct device_node *np = pdev->dev.of_node;
- struct atmel_uart_data *pdata = dev_get_platdata(&pdev->dev);
void *data;
int ret = -ENODEV;
bool rs485_enabled;
BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
- if (np)
- ret = of_alias_get_id(np, "serial");
- else
- if (pdata)
- ret = pdata->num;
-
+ ret = of_alias_get_id(np, "serial");
if (ret < 0)
/* port id not found in platform data nor device-tree aliases:
* auto-enumerate it */
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 70c5c766628e..cdceb4d4ef9d 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -7,8 +7,6 @@
#ifndef __ATMEL_H__
#define __ATMEL_H__
-#include <linux/serial.h>
-
/* Compact Flash */
struct at91_cf_data {
int irq_pin; /* I/O IRQ */
@@ -21,15 +19,6 @@ struct at91_cf_data {
#define AT91_IDE_SWAP_A0_A2 0x02
};
- /* Serial */
-struct atmel_uart_data {
- int num; /* port num */
- short use_dma_tx; /* use transmit DMA? */
- short use_dma_rx; /* use receive DMA? */
- void __iomem *regs; /* virt. base address, if any */
- struct serial_rs485 rs485; /* rs485 settings */
-};
-
/* FIXME: this needs a better location, but gets stuff building again */
#ifdef CONFIG_ATMEL_PM
extern int at91_suspend_entering_slow_clock(void);
--
2.11.0
^ permalink raw reply related
* [PATCH 1/2] tty/serial: atmel: remove atmel_default_console_device handling
From: Alexandre Belloni @ 2017-06-13 13:40 UTC (permalink / raw)
To: Richard Genoud, Greg Kroah-Hartman
Cc: Nicolas Ferre, linux-serial, linux-arm-kernel, linux-kernel,
Alexandre Belloni
atmel_default_console_device was only used by AVR32, in particular
arch/avr32/mach-at32ap/at32ap700x.c which is now gone. Remove it from the
driver.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/tty/serial/atmel_serial.c | 43 ---------------------------------------
1 file changed, 43 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index c355ac9abafc..906e2b91bf57 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -2460,8 +2460,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
return 0;
}
-struct platform_device *atmel_default_console_device; /* the serial console device */
-
#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
static void atmel_console_putchar(struct uart_port *port, int ch)
{
@@ -2594,47 +2592,6 @@ static struct console atmel_console = {
#define ATMEL_CONSOLE_DEVICE (&atmel_console)
-/*
- * Early console initialization (before VM subsystem initialized).
- */
-static int __init atmel_console_init(void)
-{
- int ret;
- if (atmel_default_console_device) {
- struct atmel_uart_data *pdata =
- dev_get_platdata(&atmel_default_console_device->dev);
- int id = pdata->num;
- struct atmel_uart_port *atmel_port = &atmel_ports[id];
-
- atmel_port->backup_imr = 0;
- atmel_port->uart.line = id;
-
- add_preferred_console(ATMEL_DEVICENAME, id, NULL);
- ret = atmel_init_port(atmel_port, atmel_default_console_device);
- if (ret)
- return ret;
- register_console(&atmel_console);
- }
-
- return 0;
-}
-
-console_initcall(atmel_console_init);
-
-/*
- * Late console initialization.
- */
-static int __init atmel_late_console_init(void)
-{
- if (atmel_default_console_device
- && !(atmel_console.flags & CON_ENABLED))
- register_console(&atmel_console);
-
- return 0;
-}
-
-core_initcall(atmel_late_console_init);
-
static inline bool atmel_is_console_port(struct uart_port *port)
{
return port->cons && port->cons->index == port->line;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 8/9] tty: ircomm: remove dead and broken ioctl code
From: Greg Kroah-Hartman @ 2017-06-13 10:01 UTC (permalink / raw)
To: Johan Hovold
Cc: Alan Cox, Jiri Slaby, Tony Luck, Fenghua Yu, Samuel Ortiz,
David S. Miller, linux-kernel, linux-usb, linux-serial
In-Reply-To: <20170613095714.GJ10775@localhost>
On Tue, Jun 13, 2017 at 11:57:14AM +0200, Johan Hovold wrote:
> On Tue, Jun 13, 2017 at 11:48:41AM +0200, Greg Kroah-Hartman wrote:
> > On Tue, Jun 06, 2017 at 12:27:04PM +0100, Alan Cox wrote:
> > > On Tue, 6 Jun 2017 12:54:40 +0200
> > > Johan Hovold <johan@kernel.org> wrote:
> > >
> > > > Remove three ifdefed and broken implementations of TIOCSSERIAL and
> > > > TIOCGICOUNT, and parity handling in set_termios which had suffered
> > > > severe bit rot.
> > >
> > > I would be amazed if the IRDA code still works. It's not been tested
> > > properly for years and it never followed the tty rules properly in the
> > > first place - so this looks good, although moving IRDA into staging
> > > and /dev/null would IMHO be far better.
> > >
> > > IRDA is dead, and IR remotes are handled via completely different code.
> >
> > I agree, and we should move it into staging and out of the tree, I'll
> > send netdev some patches for that...
>
> Sounds good, but please consider applying this patch before moving to
> staging as people have been modifying this dead code as part of
> kernel-wide updates even though hasn't even compiled for quite some
> time.
I already applied it :)
I'll wait for 4.13-rc1 before doing it (if I remember...)
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 8/9] tty: ircomm: remove dead and broken ioctl code
From: Johan Hovold @ 2017-06-13 10:00 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Alan Cox, Johan Hovold, Jiri Slaby, Tony Luck, Fenghua Yu,
Samuel Ortiz, David S. Miller, linux-kernel, linux-usb,
linux-serial
In-Reply-To: <20170613095714.GJ10775@localhost>
On Tue, Jun 13, 2017 at 11:57:14AM +0200, Johan Hovold wrote:
> On Tue, Jun 13, 2017 at 11:48:41AM +0200, Greg Kroah-Hartman wrote:
> > On Tue, Jun 06, 2017 at 12:27:04PM +0100, Alan Cox wrote:
> > > On Tue, 6 Jun 2017 12:54:40 +0200
> > > Johan Hovold <johan@kernel.org> wrote:
> > >
> > > > Remove three ifdefed and broken implementations of TIOCSSERIAL and
> > > > TIOCGICOUNT, and parity handling in set_termios which had suffered
> > > > severe bit rot.
> > >
> > > I would be amazed if the IRDA code still works. It's not been tested
> > > properly for years and it never followed the tty rules properly in the
> > > first place - so this looks good, although moving IRDA into staging
> > > and /dev/null would IMHO be far better.
> > >
> > > IRDA is dead, and IR remotes are handled via completely different code.
> >
> > I agree, and we should move it into staging and out of the tree, I'll
> > send netdev some patches for that...
>
> Sounds good, but please consider applying this patch before moving to
> staging as people have been modifying this dead code as part of
> kernel-wide updates even though hasn't even compiled for quite some
> time.
That is, just that which you ended up doing. :)
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH 8/9] tty: ircomm: remove dead and broken ioctl code
From: Johan Hovold @ 2017-06-13 9:57 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Alan Cox, Johan Hovold, Jiri Slaby, Tony Luck, Fenghua Yu,
Samuel Ortiz, David S. Miller, linux-kernel, linux-usb,
linux-serial
In-Reply-To: <20170613094841.GA31846@kroah.com>
On Tue, Jun 13, 2017 at 11:48:41AM +0200, Greg Kroah-Hartman wrote:
> On Tue, Jun 06, 2017 at 12:27:04PM +0100, Alan Cox wrote:
> > On Tue, 6 Jun 2017 12:54:40 +0200
> > Johan Hovold <johan@kernel.org> wrote:
> >
> > > Remove three ifdefed and broken implementations of TIOCSSERIAL and
> > > TIOCGICOUNT, and parity handling in set_termios which had suffered
> > > severe bit rot.
> >
> > I would be amazed if the IRDA code still works. It's not been tested
> > properly for years and it never followed the tty rules properly in the
> > first place - so this looks good, although moving IRDA into staging
> > and /dev/null would IMHO be far better.
> >
> > IRDA is dead, and IR remotes are handled via completely different code.
>
> I agree, and we should move it into staging and out of the tree, I'll
> send netdev some patches for that...
Sounds good, but please consider applying this patch before moving to
staging as people have been modifying this dead code as part of
kernel-wide updates even though hasn't even compiled for quite some
time.
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH 0/9] tty: drop broken alt-speed handling
From: Greg Kroah-Hartman @ 2017-06-13 9:55 UTC (permalink / raw)
To: Johan Hovold
Cc: Jiri Slaby, Tony Luck, Fenghua Yu, Samuel Ortiz, David S. Miller,
linux-kernel, linux-usb, linux-serial
In-Reply-To: <20170606105441.689-1-johan@kernel.org>
On Tue, Jun 06, 2017 at 12:54:32PM +0200, Johan Hovold wrote:
> Setting an alt-speed using TIOCSSERIAL and SPD flags has been deprecated
> since v2.1.69 and has been broken for all tty drivers but serial-core
> since v3.10 and commit 6865ff222cca ("TTY: do not warn about setting
> speed via SPD_*") without anyone noticing (for four years).
>
> Instead of reverting the offending commit, lets get rid of this legacy
> code while adding back a warning about the SPD flags being deprecated to
> the drivers that once implemented it. Note that drivers implementing
> SPD_CUST will continue to support using a custom divisor.
>
> Also note that serial-core did not rely on the TTY layer for SPD
> handling and continues to support it while warning about deprecation
> (since 2003 at least).
>
> Greg, I suggest you take it all trough the TTY tree even if merging
> through multiple trees and applying the final patch once everything is
> upstream would be an option. Also the irda clean up does not depend on
> the rest of series as the code implementing SPD handling was ifdefed
> out.
I've taken these all through my tty tree, nice work, thanks for the
cleanups.
greg k-h
^ permalink raw reply
* Re: [PATCH 8/9] tty: ircomm: remove dead and broken ioctl code
From: Greg Kroah-Hartman @ 2017-06-13 9:48 UTC (permalink / raw)
To: Alan Cox
Cc: Johan Hovold, Jiri Slaby, Tony Luck, Fenghua Yu, Samuel Ortiz,
David S. Miller, linux-kernel, linux-usb, linux-serial
In-Reply-To: <20170606122704.3e328125@lxorguk.ukuu.org.uk>
On Tue, Jun 06, 2017 at 12:27:04PM +0100, Alan Cox wrote:
> On Tue, 6 Jun 2017 12:54:40 +0200
> Johan Hovold <johan@kernel.org> wrote:
>
> > Remove three ifdefed and broken implementations of TIOCSSERIAL and
> > TIOCGICOUNT, and parity handling in set_termios which had suffered
> > severe bit rot.
>
> I would be amazed if the IRDA code still works. It's not been tested
> properly for years and it never followed the tty rules properly in the
> first place - so this looks good, although moving IRDA into staging
> and /dev/null would IMHO be far better.
>
> IRDA is dead, and IR remotes are handled via completely different code.
I agree, and we should move it into staging and out of the tree, I'll
send netdev some patches for that...
thanks,
greg k-h
^ permalink raw reply
* RE: [PATCH V3 5/7] tty: serial: lpuart: add imx7ulp support
From: A.s. Dong @ 2017-06-13 3:32 UTC (permalink / raw)
To: Andy Duan, linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org,
jslaby@suse.com, stefan@agner.ch, Mingkai Hu, Y.b. Lu,
nikita.yoush@cogentembedded.com, andy.shevchenko@gmail.com,
dongas86@gmail.com
In-Reply-To: <AM4PR0401MB22607CE9EE3909A7A0B9451AFFC20@AM4PR0401MB2260.eurprd04.prod.outlook.com>
> -----Original Message-----
> From: Andy Duan
> Sent: Tuesday, June 13, 2017 11:02 AM
> To: A.s. Dong; linux-serial@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> gregkh@linuxfoundation.org; jslaby@suse.com; stefan@agner.ch; Mingkai Hu;
> Y.b. Lu; nikita.yoush@cogentembedded.com; andy.shevchenko@gmail.com;
> dongas86@gmail.com; A.s. Dong
> Subject: RE: [PATCH V3 5/7] tty: serial: lpuart: add imx7ulp support
>
> From: Dong Aisheng <aisheng.dong@nxp.com> Sent: Monday, June 12, 2017
> 11:37 PM
> >The lpuart of imx7ulp is basically the same as ls1021a. It's also
> >32 bit width register, but unlike ls1021a, it's little endian.
> >Besides that, imx7ulp lpuart has a minor different register layout from
> >ls1021a that it has four extra registers (verid, param, global,
> >pincfg) located at the beginning of register map, which are currently
> >not used by the driver and less to be used later.
> >
> >To ease the register difference handling, we add a reg_off member in
> >lpuart_soc_data structure to represent if the normal
> >lpuart32_{read|write} requires plus a offset to hide the issue.
> >
> >Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >Cc: Jiri Slaby <jslaby@suse.com>
> >Cc: Stefan Agner <stefan@agner.ch>
> >Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
> >Cc: Yangbo Lu <yangbo.lu@nxp.com>
> >Cc: Fugang Duan <fugang.duan@nxp.com>
> >Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> >
> >---
> >ChangeLog:
> >v2->v3:
> > * use standard port->iotype to represent the endians.
> >v1->v2:
> > * remove lpuart_reg_off according to Stefan's suggestion
> >---
> > drivers/tty/serial/fsl_lpuart.c | 10 ++++++++++
> > 1 file changed, 10 insertions(+)
> >
> >diff --git a/drivers/tty/serial/fsl_lpuart.c
> >b/drivers/tty/serial/fsl_lpuart.c index
> >bbf47a0..9d05e53 100644
> >--- a/drivers/tty/serial/fsl_lpuart.c
> >+++ b/drivers/tty/serial/fsl_lpuart.c
> >@@ -231,6 +231,9 @@
> > #define DEV_NAME "ttyLP"
> > #define UART_NR 6
> >
> >+/* IMX lpuart has four extra unused regs located at the beginning */
> >+#define IMX_REG_OFF 0x10
> >+
> > struct lpuart_port {
> > struct uart_port port;
> > struct clk *clk;
> >@@ -259,6 +262,7 @@ struct lpuart_port {
> >
> > struct lpuart_soc_data {
> > char iotype;
> >+ u8 reg_off;
> > };
> >
> > static const struct lpuart_soc_data vf_data = { @@ -267,12 +271,17 @@
> >static const struct lpuart_soc_data vf_data = {
> >
> > static const struct lpuart_soc_data ls_data = {
> > .iotype = UPIO_MEM32BE,
> >+};
> >
> >+static struct lpuart_soc_data imx_data = {
> >+ .iotype = UPIO_MEM32,
> >+ .reg_off = IMX_REG_OFF,
> > };
> >
> > static const struct of_device_id lpuart_dt_ids[] = {
> > { .compatible = "fsl,vf610-lpuart", .data = &vf_data, },
> > { .compatible = "fsl,ls1021a-lpuart", .data = &ls_data, },
> >+ { .compatible = "fsl,imx7ulp-lpuart", .data = &imx_data, },
> > { /* sentinel */ }
> > };
> > MODULE_DEVICE_TABLE(of, lpuart_dt_ids); @@ -2020,6 +2029,7 @@ static
> >int lpuart_probe(struct platform_device *pdev)
> > if (IS_ERR(sport->port.membase))
> > return PTR_ERR(sport->port.membase);
> >
> >+ sport->port.membase += sdata->reg_off;
> > sport->port.mapbase = res->start;
>
> Also update the mapbase.
>
The idea behind is only do the quirk for io remapped address.
Mapbase(physical address) is not needed for lpuart32 currently.
Probably it could be changed when lpuart32 DMA function is added.
Regards
Dong Aisheng
> > sport->port.dev = &pdev->dev;
> > sport->port.type = PORT_LPUART;
> >--
> >2.7.4
^ permalink raw reply
* RE: [PATCH V3 3/7] tty: serial: lpuart: add little endian 32 bit register support
From: A.s. Dong @ 2017-06-13 3:27 UTC (permalink / raw)
To: Andy Duan, linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org,
jslaby@suse.com, stefan@agner.ch, Mingkai Hu, Y.b. Lu,
nikita.yoush@cogentembedded.com, andy.shevchenko@gmail.com,
dongas86@gmail.com
In-Reply-To: <AM4PR0401MB226097F474202777C61AAE72FFC20@AM4PR0401MB2260.eurprd04.prod.outlook.com>
> -----Original Message-----
> From: Andy Duan
> Sent: Tuesday, June 13, 2017 11:09 AM
> To: A.s. Dong; linux-serial@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> gregkh@linuxfoundation.org; jslaby@suse.com; stefan@agner.ch; Mingkai Hu;
> Y.b. Lu; nikita.yoush@cogentembedded.com; andy.shevchenko@gmail.com;
> dongas86@gmail.com; A.s. Dong
> Subject: RE: [PATCH V3 3/7] tty: serial: lpuart: add little endian 32 bit
> register support
>
> From: Dong Aisheng <aisheng.dong@nxp.com> Sent: Monday, June 12, 2017
> 11:37 PM
> >To: linux-serial@vger.kernel.org
> >Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> >gregkh@linuxfoundation.org; jslaby@suse.com; Andy Duan
> ><fugang.duan@nxp.com>; stefan@agner.ch; Mingkai Hu
> ><mingkai.hu@nxp.com>; Y.b. Lu <yangbo.lu@nxp.com>;
> >nikita.yoush@cogentembedded.com; andy.shevchenko@gmail.com;
> >dongas86@gmail.com; A.S. Dong <aisheng.dong@nxp.com>
> >Subject: [PATCH V3 3/7] tty: serial: lpuart: add little endian 32 bit
> >register support
> >
> >Use standard port->iotype to distinguish endian difference. Note as we
> >read/write register by checking iotype dynamically, we need to
> >initialize the iotype correctly for earlycon as well to avoid a break.
> >
> >Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >Cc: Jiri Slaby <jslaby@suse.com> (supporter:TTY LAYER)
> >Cc: Stefan Agner <stefan@agner.ch>
> >Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
> >Cc: Yangbo Lu <yangbo.lu@nxp.com>
> >Cc: Fugang Duan <fugang.duan@nxp.com>
> >Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> >
> >ChangeLog:
> >v2->v3:
> > * Instead of using global var, use standard port->iotype to distinguish
> > endian difference.
> >v1->v2:
> > * No changes
> >---
> > drivers/tty/serial/fsl_lpuart.c | 43
> >+++++++++++++++++++++++++++----------
> >----
> > 1 file changed, 29 insertions(+), 14 deletions(-)
> >
> >diff --git a/drivers/tty/serial/fsl_lpuart.c
> >b/drivers/tty/serial/fsl_lpuart.c index
> >ed9db2f..bbf47a0 100644
> >--- a/drivers/tty/serial/fsl_lpuart.c
> >+++ b/drivers/tty/serial/fsl_lpuart.c
> >@@ -280,15 +280,29 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
> > /* Forward declare this for the dma callbacks*/ static void
> >lpuart_dma_tx_complete(void *arg);
> >
> >-static inline u32 lpuart32_read(struct uart_port *port, u32 reg_off) -{
> >- return ioread32be(port->membase + reg_off);
> >+static inline u32 lpuart32_read(struct uart_port *port, u32 off) {
> >+ switch (port->iotype) {
> >+ case UPIO_MEM32:
> >+ return readl(port->membase + off);
> >+ case UPIO_MEM32BE:
> >+ return ioread32be(port->membase + off);
> >+ default:
> >+ return 0;
> >+ };
> > }
> >
> > static inline void lpuart32_write(struct uart_port *port, u32 val,
> >- u32 reg_off)
> >+ u32 off)
> > {
> >- iowrite32be(val, port->membase + reg_off);
> >+ switch (port->iotype) {
> >+ case UPIO_MEM32:
> >+ writel(val, port->membase + off);
> >+ break;
> >+ case UPIO_MEM32BE:
> >+ iowrite32be(val, port->membase + off);
> >+ break;
> >+ };
> > }
> >
> > static void lpuart_stop_tx(struct uart_port *port) @@ -602,7 +616,7 @@
> >static irqreturn_t lpuart_txint(int irq, void *dev_id)
> >
> > spin_lock_irqsave(&sport->port.lock, flags);
> > if (sport->port.x_char) {
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> > lpuart32_write(&sport->port, sport->port.x_char,
> UARTDATA);
> > else
> > writeb(sport->port.x_char, sport->port.membase + UARTDR);
> @@
> >-610,14 +624,14 @@ static irqreturn_t lpuart_txint(int irq, void
> >*dev_id)
> > }
> >
> > if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
>
> Can use one macro instead of sport->port.iotype & (UPIO_MEM32 |
> UPIO_MEM32BE ?
>
UPIO_MEM32 and UPIO_MEM32BE are serial core definitions.
If we use one macro for it, then the macro seems be better in serial core.
But I don't think it's quite necessary.
Explicit using also make the code look clearer.
Regards
Dong Aisheng
> > lpuart32_stop_tx(&sport->port);
> > else
> > lpuart_stop_tx(&sport->port);
> > goto out;
> > }
> >
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> > lpuart32_transmit_buffer(sport);
> > else
> > lpuart_transmit_buffer(sport);
> >@@ -1890,12 +1904,12 @@ static int __init lpuart_console_setup(struct
> >console *co, char *options)
> > if (options)
> > uart_parse_options(options, &baud, &parity, &bits, &flow);
> > else
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> > lpuart32_console_get_options(sport, &baud, &parity,
> &bits);
> > else
> > lpuart_console_get_options(sport, &baud, &parity, &bits);
> >
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> > lpuart32_setup_watermark(sport);
> > else
> > lpuart_setup_watermark(sport);
> >@@ -1954,6 +1968,7 @@ static int __init
> >lpuart32_early_console_setup(struct
> >earlycon_device *device,
> > if (!device->port.membase)
> > return -ENODEV;
> >
> >+ device->port.iotype = UPIO_MEM32BE;
> > device->con->write = lpuart32_early_write;
> > return 0;
> > }
> >@@ -2015,7 +2030,7 @@ static int lpuart_probe(struct platform_device
> *pdev)
> > }
> > sport->port.irq = ret;
> > sport->port.iotype = sdata->iotype;
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> > sport->port.ops = &lpuart32_pops;
> > else
> > sport->port.ops = &lpuart_pops;
> >@@ -2042,7 +2057,7 @@ static int lpuart_probe(struct platform_device
> >*pdev)
> >
> > platform_set_drvdata(pdev, &sport->port);
> >
> >- if (sport->port.iotype & UPIO_MEM32BE)
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> > lpuart_reg.cons = LPUART32_CONSOLE;
> > else
> > lpuart_reg.cons = LPUART_CONSOLE;
> >@@ -2095,7 +2110,7 @@ static int lpuart_suspend(struct device *dev)
> > struct lpuart_port *sport = dev_get_drvdata(dev);
> > unsigned long temp;
> >
> >- if (sport->port.iotype & UPIO_MEM32BE) {
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
> > /* disable Rx/Tx and interrupts */
> > temp = lpuart32_read(&sport->port, UARTCTRL);
> > temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE); @@ -
> 2146,7
> >+2161,7 @@ static int lpuart_resume(struct device *dev)
> > if (sport->port.suspended && !sport->port.irq_wake)
> > clk_prepare_enable(sport->clk);
> >
> >- if (sport->port.iotype & UPIO_MEM32BE) {
> >+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
> > lpuart32_setup_watermark(sport);
> > temp = lpuart32_read(&sport->port, UARTCTRL);
> > temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
> >--
> >2.7.4
^ permalink raw reply
* RE: [PATCH V3 3/7] tty: serial: lpuart: add little endian 32 bit register support
From: Andy Duan @ 2017-06-13 3:09 UTC (permalink / raw)
To: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org,
jslaby@suse.com, stefan@agner.ch, Mingkai Hu, Y.b. Lu,
nikita.yoush@cogentembedded.com, andy.shevchenko@gmail.com,
dongas86@gmail.com, A.s. Dong
In-Reply-To: <1497281848-12995-4-git-send-email-aisheng.dong@nxp.com>
From: Dong Aisheng <aisheng.dong@nxp.com> Sent: Monday, June 12, 2017 11:37 PM
>To: linux-serial@vger.kernel.org
>Cc: linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
>gregkh@linuxfoundation.org; jslaby@suse.com; Andy Duan
><fugang.duan@nxp.com>; stefan@agner.ch; Mingkai Hu
><mingkai.hu@nxp.com>; Y.b. Lu <yangbo.lu@nxp.com>;
>nikita.yoush@cogentembedded.com; andy.shevchenko@gmail.com;
>dongas86@gmail.com; A.S. Dong <aisheng.dong@nxp.com>
>Subject: [PATCH V3 3/7] tty: serial: lpuart: add little endian 32 bit register
>support
>
>Use standard port->iotype to distinguish endian difference. Note as we
>read/write register by checking iotype dynamically, we need to initialize the
>iotype correctly for earlycon as well to avoid a break.
>
>Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>Cc: Jiri Slaby <jslaby@suse.com> (supporter:TTY LAYER)
>Cc: Stefan Agner <stefan@agner.ch>
>Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
>Cc: Yangbo Lu <yangbo.lu@nxp.com>
>Cc: Fugang Duan <fugang.duan@nxp.com>
>Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
>
>ChangeLog:
>v2->v3:
> * Instead of using global var, use standard port->iotype to distinguish
> endian difference.
>v1->v2:
> * No changes
>---
> drivers/tty/serial/fsl_lpuart.c | 43 +++++++++++++++++++++++++++----------
>----
> 1 file changed, 29 insertions(+), 14 deletions(-)
>
>diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index
>ed9db2f..bbf47a0 100644
>--- a/drivers/tty/serial/fsl_lpuart.c
>+++ b/drivers/tty/serial/fsl_lpuart.c
>@@ -280,15 +280,29 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
> /* Forward declare this for the dma callbacks*/ static void
>lpuart_dma_tx_complete(void *arg);
>
>-static inline u32 lpuart32_read(struct uart_port *port, u32 reg_off) -{
>- return ioread32be(port->membase + reg_off);
>+static inline u32 lpuart32_read(struct uart_port *port, u32 off) {
>+ switch (port->iotype) {
>+ case UPIO_MEM32:
>+ return readl(port->membase + off);
>+ case UPIO_MEM32BE:
>+ return ioread32be(port->membase + off);
>+ default:
>+ return 0;
>+ };
> }
>
> static inline void lpuart32_write(struct uart_port *port, u32 val,
>- u32 reg_off)
>+ u32 off)
> {
>- iowrite32be(val, port->membase + reg_off);
>+ switch (port->iotype) {
>+ case UPIO_MEM32:
>+ writel(val, port->membase + off);
>+ break;
>+ case UPIO_MEM32BE:
>+ iowrite32be(val, port->membase + off);
>+ break;
>+ };
> }
>
> static void lpuart_stop_tx(struct uart_port *port) @@ -602,7 +616,7 @@
>static irqreturn_t lpuart_txint(int irq, void *dev_id)
>
> spin_lock_irqsave(&sport->port.lock, flags);
> if (sport->port.x_char) {
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> lpuart32_write(&sport->port, sport->port.x_char,
>UARTDATA);
> else
> writeb(sport->port.x_char, sport->port.membase +
>UARTDR); @@ -610,14 +624,14 @@ static irqreturn_t lpuart_txint(int irq, void
>*dev_id)
> }
>
> if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
Can use one macro instead of sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE ?
> lpuart32_stop_tx(&sport->port);
> else
> lpuart_stop_tx(&sport->port);
> goto out;
> }
>
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> lpuart32_transmit_buffer(sport);
> else
> lpuart_transmit_buffer(sport);
>@@ -1890,12 +1904,12 @@ static int __init lpuart_console_setup(struct
>console *co, char *options)
> if (options)
> uart_parse_options(options, &baud, &parity, &bits, &flow);
> else
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> lpuart32_console_get_options(sport, &baud, &parity,
>&bits);
> else
> lpuart_console_get_options(sport, &baud, &parity,
>&bits);
>
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> lpuart32_setup_watermark(sport);
> else
> lpuart_setup_watermark(sport);
>@@ -1954,6 +1968,7 @@ static int __init lpuart32_early_console_setup(struct
>earlycon_device *device,
> if (!device->port.membase)
> return -ENODEV;
>
>+ device->port.iotype = UPIO_MEM32BE;
> device->con->write = lpuart32_early_write;
> return 0;
> }
>@@ -2015,7 +2030,7 @@ static int lpuart_probe(struct platform_device *pdev)
> }
> sport->port.irq = ret;
> sport->port.iotype = sdata->iotype;
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> sport->port.ops = &lpuart32_pops;
> else
> sport->port.ops = &lpuart_pops;
>@@ -2042,7 +2057,7 @@ static int lpuart_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, &sport->port);
>
>- if (sport->port.iotype & UPIO_MEM32BE)
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
> lpuart_reg.cons = LPUART32_CONSOLE;
> else
> lpuart_reg.cons = LPUART_CONSOLE;
>@@ -2095,7 +2110,7 @@ static int lpuart_suspend(struct device *dev)
> struct lpuart_port *sport = dev_get_drvdata(dev);
> unsigned long temp;
>
>- if (sport->port.iotype & UPIO_MEM32BE) {
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
> /* disable Rx/Tx and interrupts */
> temp = lpuart32_read(&sport->port, UARTCTRL);
> temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
>@@ -2146,7 +2161,7 @@ static int lpuart_resume(struct device *dev)
> if (sport->port.suspended && !sport->port.irq_wake)
> clk_prepare_enable(sport->clk);
>
>- if (sport->port.iotype & UPIO_MEM32BE) {
>+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
> lpuart32_setup_watermark(sport);
> temp = lpuart32_read(&sport->port, UARTCTRL);
> temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
>--
>2.7.4
^ permalink raw reply
* RE: [PATCH V3 5/7] tty: serial: lpuart: add imx7ulp support
From: Andy Duan @ 2017-06-13 3:02 UTC (permalink / raw)
To: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org,
jslaby@suse.com, stefan@agner.ch, Mingkai Hu, Y.b. Lu,
nikita.yoush@cogentembedded.com, andy.shevchenko@gmail.com,
dongas86@gmail.com, A.s. Dong
In-Reply-To: <1497281848-12995-6-git-send-email-aisheng.dong@nxp.com>
From: Dong Aisheng <aisheng.dong@nxp.com> Sent: Monday, June 12, 2017 11:37 PM
>The lpuart of imx7ulp is basically the same as ls1021a. It's also
>32 bit width register, but unlike ls1021a, it's little endian.
>Besides that, imx7ulp lpuart has a minor different register layout from ls1021a
>that it has four extra registers (verid, param, global,
>pincfg) located at the beginning of register map, which are currently not used
>by the driver and less to be used later.
>
>To ease the register difference handling, we add a reg_off member in
>lpuart_soc_data structure to represent if the normal lpuart32_{read|write}
>requires plus a offset to hide the issue.
>
>Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>Cc: Jiri Slaby <jslaby@suse.com>
>Cc: Stefan Agner <stefan@agner.ch>
>Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
>Cc: Yangbo Lu <yangbo.lu@nxp.com>
>Cc: Fugang Duan <fugang.duan@nxp.com>
>Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
>
>---
>ChangeLog:
>v2->v3:
> * use standard port->iotype to represent the endians.
>v1->v2:
> * remove lpuart_reg_off according to Stefan's suggestion
>---
> drivers/tty/serial/fsl_lpuart.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
>diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index
>bbf47a0..9d05e53 100644
>--- a/drivers/tty/serial/fsl_lpuart.c
>+++ b/drivers/tty/serial/fsl_lpuart.c
>@@ -231,6 +231,9 @@
> #define DEV_NAME "ttyLP"
> #define UART_NR 6
>
>+/* IMX lpuart has four extra unused regs located at the beginning */
>+#define IMX_REG_OFF 0x10
>+
> struct lpuart_port {
> struct uart_port port;
> struct clk *clk;
>@@ -259,6 +262,7 @@ struct lpuart_port {
>
> struct lpuart_soc_data {
> char iotype;
>+ u8 reg_off;
> };
>
> static const struct lpuart_soc_data vf_data = { @@ -267,12 +271,17 @@ static
>const struct lpuart_soc_data vf_data = {
>
> static const struct lpuart_soc_data ls_data = {
> .iotype = UPIO_MEM32BE,
>+};
>
>+static struct lpuart_soc_data imx_data = {
>+ .iotype = UPIO_MEM32,
>+ .reg_off = IMX_REG_OFF,
> };
>
> static const struct of_device_id lpuart_dt_ids[] = {
> { .compatible = "fsl,vf610-lpuart", .data = &vf_data, },
> { .compatible = "fsl,ls1021a-lpuart", .data = &ls_data, },
>+ { .compatible = "fsl,imx7ulp-lpuart", .data = &imx_data, },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, lpuart_dt_ids); @@ -2020,6 +2029,7 @@ static
>int lpuart_probe(struct platform_device *pdev)
> if (IS_ERR(sport->port.membase))
> return PTR_ERR(sport->port.membase);
>
>+ sport->port.membase += sdata->reg_off;
> sport->port.mapbase = res->start;
Also update the mapbase.
> sport->port.dev = &pdev->dev;
> sport->port.type = PORT_LPUART;
>--
>2.7.4
^ permalink raw reply
* [PATCH V4 7/7] tty: serial: lpuart: add a more accurate baud rate calculation method
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
On new LPUART versions, the oversampling ratio for the receiver can be
changed from 4x (00011) to 32x (11111) which could help us get a more
accurate baud rate divider.
The idea is to use the best OSR (over-sampling rate) possible.
Note, OSR is typically hard-set to 16 in other LPUART instantiations.
Loop to find the best OSR value possible, one that generates minimum
baud diff iterate through the rest of the supported values of OSR.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v3->v4:
* No changes
v2->v3:
* enable new baud rate calculation method by default to get Layerscape
platforms run and test.
* break out in case we already find the minum baud_diff
v1->v2:
* No changes
---
drivers/tty/serial/fsl_lpuart.c | 79 +++++++++++++++++++++++++++++++++++++----
1 file changed, 72 insertions(+), 7 deletions(-)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index a0f2666..343de8c 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -140,6 +140,8 @@
#define UARTBAUD_SBNS 0x00002000
#define UARTBAUD_SBR 0x00000000
#define UARTBAUD_SBR_MASK 0x1fff
+#define UARTBAUD_OSR_MASK 0x1f
+#define UARTBAUD_OSR_SHIFT 24
#define UARTSTAT_LBKDIF 0x80000000
#define UARTSTAT_RXEDGIF 0x40000000
@@ -1511,6 +1513,75 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
}
static void
+lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
+{
+ u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
+ u32 clk = sport->port.uartclk;
+
+ /*
+ * The idea is to use the best OSR (over-sampling rate) possible.
+ * Note, OSR is typically hard-set to 16 in other LPUART instantiations.
+ * Loop to find the best OSR value possible, one that generates minimum
+ * baud_diff iterate through the rest of the supported values of OSR.
+ *
+ * Calculation Formula:
+ * Baud Rate = baud clock / ((OSR+1) × SBR)
+ */
+ baud_diff = baudrate;
+ osr = 0;
+ sbr = 0;
+
+ for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
+ /* calculate the temporary sbr value */
+ tmp_sbr = (clk / (baudrate * tmp_osr));
+ if (tmp_sbr == 0)
+ tmp_sbr = 1;
+
+ /*
+ * calculate the baud rate difference based on the temporary
+ * osr and sbr values
+ */
+ tmp_diff = clk / (tmp_osr * tmp_sbr) - baudrate;
+
+ /* select best values between sbr and sbr+1 */
+ tmp = clk / (tmp_osr * (tmp_sbr + 1));
+ if (tmp_diff > (baudrate - tmp)) {
+ tmp_diff = baudrate - tmp;
+ tmp_sbr++;
+ }
+
+ if (tmp_diff <= baud_diff) {
+ baud_diff = tmp_diff;
+ osr = tmp_osr;
+ sbr = tmp_sbr;
+
+ if (!baud_diff)
+ break;
+ }
+ }
+
+ /* handle buadrate outside acceptable rate */
+ if (baud_diff > ((baudrate / 100) * 3))
+ dev_warn(sport->port.dev,
+ "unacceptable baud rate difference of more than 3%%\n");
+
+ tmp = lpuart32_read(&sport->port, UARTBAUD);
+
+ if ((osr > 3) && (osr < 8))
+ tmp |= UARTBAUD_BOTHEDGE;
+
+ tmp &= ~(UARTBAUD_OSR_MASK << UARTBAUD_OSR_SHIFT);
+ tmp |= (((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT);
+
+ tmp &= ~UARTBAUD_SBR_MASK;
+ tmp |= sbr & UARTBAUD_SBR_MASK;
+
+ tmp &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE);
+
+ lpuart32_write(&sport->port, tmp, UARTBAUD);
+}
+
+static void
lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
@@ -1519,7 +1590,6 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned long ctrl, old_ctrl, bd, modem;
unsigned int baud;
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
- unsigned int sbr;
ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL);
bd = lpuart32_read(&sport->port, UARTBAUD);
@@ -1616,12 +1686,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
UARTCTRL);
- sbr = sport->port.uartclk / (16 * baud);
- bd &= ~UARTBAUD_SBR_MASK;
- bd |= sbr & UARTBAUD_SBR_MASK;
- bd |= UARTBAUD_BOTHEDGE;
- bd &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE);
- lpuart32_write(&sport->port, bd, UARTBAUD);
+ lpuart32_serial_setbrg(sport, baud);
lpuart32_write(&sport->port, modem, UARTMODIR);
lpuart32_write(&sport->port, ctrl, UARTCTRL);
/* restore control register */
--
2.7.4
^ permalink raw reply related
* [PATCH V4 6/7] tty: serial: lpuart: add earlycon support for imx7ulp
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
earlycon is executed quite early before the device tree probe,
so we need correctly initialize the port membase and iotype for
imx7ulp during early console setup before using.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
Change Log:
v3->v4:
* No changes
v2->v3:
* use standard port->iotype to represent endians
v1->v2:
* updated due to lpuart_reg_off removed
---
drivers/tty/serial/fsl_lpuart.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 9486333..a0f2666 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1982,8 +1982,21 @@ static int __init lpuart32_early_console_setup(struct earlycon_device *device,
return 0;
}
+static int __init lpuart32_imx_early_console_setup(struct earlycon_device *device,
+ const char *opt)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ device->port.iotype = UPIO_MEM32;
+ device->port.membase += IMX_REG_OFF;
+ device->con->write = lpuart32_early_write;
+
+ return 0;
+}
OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup);
OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup);
+OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup);
EARLYCON_DECLARE(lpuart, lpuart_early_console_setup);
EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup);
--
2.7.4
^ permalink raw reply related
* [PATCH V4 5/7] tty: serial: lpuart: add imx7ulp support
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
The lpuart of imx7ulp is basically the same as ls1021a. It's also
32 bit width register, but unlike ls1021a, it's little endian.
Besides that, imx7ulp lpuart has a minor different register layout
from ls1021a that it has four extra registers (verid, param, global,
pincfg) located at the beginning of register map, which are currently
not used by the driver and less to be used later.
To ease the register difference handling, we add a reg_off member
in lpuart_soc_data structure to represent if the normal
lpuart32_{read|write} requires plus a offset to hide the issue.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v3->v4:
* No changes
v2->v3:
* use standard port->iotype to represent the endians.
v1->v2:
* remove lpuart_reg_off according to Stefan's suggestion
---
drivers/tty/serial/fsl_lpuart.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index ed0bf18..9486333 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -231,6 +231,9 @@
#define DEV_NAME "ttyLP"
#define UART_NR 6
+/* IMX lpuart has four extra unused regs located at the beginning */
+#define IMX_REG_OFF 0x10
+
struct lpuart_port {
struct uart_port port;
struct clk *clk;
@@ -259,6 +262,7 @@ struct lpuart_port {
struct lpuart_soc_data {
char iotype;
+ u8 reg_off;
};
static const struct lpuart_soc_data vf_data = {
@@ -269,9 +273,15 @@ static const struct lpuart_soc_data ls_data = {
.iotype = UPIO_MEM32BE,
};
+static struct lpuart_soc_data imx_data = {
+ .iotype = UPIO_MEM32,
+ .reg_off = IMX_REG_OFF,
+};
+
static const struct of_device_id lpuart_dt_ids[] = {
{ .compatible = "fsl,vf610-lpuart", .data = &vf_data, },
{ .compatible = "fsl,ls1021a-lpuart", .data = &ls_data, },
+ { .compatible = "fsl,imx7ulp-lpuart", .data = &imx_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
@@ -2019,6 +2029,7 @@ static int lpuart_probe(struct platform_device *pdev)
if (IS_ERR(sport->port.membase))
return PTR_ERR(sport->port.membase);
+ sport->port.membase += sdata->reg_off;
sport->port.mapbase = res->start;
sport->port.dev = &pdev->dev;
sport->port.type = PORT_LPUART;
--
2.7.4
^ permalink raw reply related
* [PATCH V4 4/7] dt-bindings: serial: fsl-lpuart: add i.MX7ULP support
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng, devicetree
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
The lpuart of imx7ulp is basically the same as ls1021a. It's also
32 bit width register, but unlike ls1021a, it's little endian.
Besides that, imx7ulp lpuart has a minor different register layout
from ls1021a.
Cc: devicetree@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
* No changes
---
Documentation/devicetree/bindings/serial/fsl-lpuart.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index c95005e..a1252a0 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -6,6 +6,8 @@ Required properties:
on Vybrid vf610 SoC with 8-bit register organization
- "fsl,ls1021a-lpuart" for lpuart compatible with the one integrated
on LS1021A SoC with 32-bit big-endian register organization
+ - "fsl,imx7ulp-lpuart" for lpuart compatible with the one integrated
+ on i.MX7ULP SoC with 32-bit little-endian register organization
- reg : Address and length of the register set for the device
- interrupts : Should contain uart interrupt
- clocks : phandle + clock specifier pairs, one for each entry in clock-names
--
2.7.4
^ permalink raw reply related
* [PATCH V4 3/7] tty: serial: lpuart: add little endian 32 bit register support
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
Use standard port->iotype to distinguish endian difference. Note as we
read/write register by checking iotype dynamically, we need to initialize
the iotype correctly for earlycon as well to avoid a break.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com> (supporter:TTY LAYER)
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
ChangeLog:
v3->v4:
* Removed unneeded semicolon catched by 0day Robot.
v2->v3:
* Instead of using global var, use standard port->iotype to distinguish
endian difference.
v1->v2:
* No changes
---
drivers/tty/serial/fsl_lpuart.c | 45 +++++++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 32d479b..ed0bf18 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -279,15 +279,29 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
/* Forward declare this for the dma callbacks*/
static void lpuart_dma_tx_complete(void *arg);
-static inline u32 lpuart32_read(struct uart_port *port, u32 reg_off)
-{
- return ioread32be(port->membase + reg_off);
+static inline u32 lpuart32_read(struct uart_port *port, u32 off)
+{
+ switch (port->iotype) {
+ case UPIO_MEM32:
+ return readl(port->membase + off);
+ case UPIO_MEM32BE:
+ return ioread32be(port->membase + off);
+ default:
+ return 0;
+ }
}
static inline void lpuart32_write(struct uart_port *port, u32 val,
- u32 reg_off)
-{
- iowrite32be(val, port->membase + reg_off);
+ u32 off)
+{
+ switch (port->iotype) {
+ case UPIO_MEM32:
+ writel(val, port->membase + off);
+ break;
+ case UPIO_MEM32BE:
+ iowrite32be(val, port->membase + off);
+ break;
+ }
}
static void lpuart_stop_tx(struct uart_port *port)
@@ -601,7 +615,7 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
spin_lock_irqsave(&sport->port.lock, flags);
if (sport->port.x_char) {
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
else
writeb(sport->port.x_char, sport->port.membase + UARTDR);
@@ -609,14 +623,14 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
lpuart32_stop_tx(&sport->port);
else
lpuart_stop_tx(&sport->port);
goto out;
}
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
lpuart32_transmit_buffer(sport);
else
lpuart_transmit_buffer(sport);
@@ -1889,12 +1903,12 @@ static int __init lpuart_console_setup(struct console *co, char *options)
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
lpuart32_console_get_options(sport, &baud, &parity, &bits);
else
lpuart_console_get_options(sport, &baud, &parity, &bits);
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
lpuart32_setup_watermark(sport);
else
lpuart_setup_watermark(sport);
@@ -1953,6 +1967,7 @@ static int __init lpuart32_early_console_setup(struct earlycon_device *device,
if (!device->port.membase)
return -ENODEV;
+ device->port.iotype = UPIO_MEM32BE;
device->con->write = lpuart32_early_write;
return 0;
}
@@ -2014,7 +2029,7 @@ static int lpuart_probe(struct platform_device *pdev)
}
sport->port.irq = ret;
sport->port.iotype = sdata->iotype;
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
sport->port.ops = &lpuart32_pops;
else
sport->port.ops = &lpuart_pops;
@@ -2041,7 +2056,7 @@ static int lpuart_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &sport->port);
- if (sport->port.iotype & UPIO_MEM32BE)
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
lpuart_reg.cons = LPUART32_CONSOLE;
else
lpuart_reg.cons = LPUART_CONSOLE;
@@ -2094,7 +2109,7 @@ static int lpuart_suspend(struct device *dev)
struct lpuart_port *sport = dev_get_drvdata(dev);
unsigned long temp;
- if (sport->port.iotype & UPIO_MEM32BE) {
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
/* disable Rx/Tx and interrupts */
temp = lpuart32_read(&sport->port, UARTCTRL);
temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
@@ -2145,7 +2160,7 @@ static int lpuart_resume(struct device *dev)
if (sport->port.suspended && !sport->port.irq_wake)
clk_prepare_enable(sport->clk);
- if (sport->port.iotype & UPIO_MEM32BE) {
+ if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
lpuart32_setup_watermark(sport);
temp = lpuart32_read(&sport->port, UARTCTRL);
temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
--
2.7.4
^ permalink raw reply related
* [PATCH V4 2/7] tty: serial: lpuart: refactor lpuart32_{read|write} prototype
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
Due to the original lpuart32_read/write takes no port specific
information arguments, it's hard to distinguish port difference
within the API. Although it works before, but not suitable anymore
when adding more new chips support.
So let's convert it to accept a new struct uart_port argument
to make it be able to retrieve more port specific information.
This is a preparation for the later adding new chips support
more easily. No functions changes.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v3->v4:
* No changes
v2->v3:
* newly introduced
---
drivers/tty/serial/fsl_lpuart.c | 123 ++++++++++++++++++++--------------------
1 file changed, 62 insertions(+), 61 deletions(-)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index c17a0ea..32d479b 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -279,14 +279,15 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
/* Forward declare this for the dma callbacks*/
static void lpuart_dma_tx_complete(void *arg);
-static u32 lpuart32_read(void __iomem *addr)
+static inline u32 lpuart32_read(struct uart_port *port, u32 reg_off)
{
- return ioread32be(addr);
+ return ioread32be(port->membase + reg_off);
}
-static void lpuart32_write(u32 val, void __iomem *addr)
+static inline void lpuart32_write(struct uart_port *port, u32 val,
+ u32 reg_off)
{
- iowrite32be(val, addr);
+ iowrite32be(val, port->membase + reg_off);
}
static void lpuart_stop_tx(struct uart_port *port)
@@ -302,9 +303,9 @@ static void lpuart32_stop_tx(struct uart_port *port)
{
unsigned long temp;
- temp = lpuart32_read(port->membase + UARTCTRL);
+ temp = lpuart32_read(port, UARTCTRL);
temp &= ~(UARTCTRL_TIE | UARTCTRL_TCIE);
- lpuart32_write(temp, port->membase + UARTCTRL);
+ lpuart32_write(port, temp, UARTCTRL);
}
static void lpuart_stop_rx(struct uart_port *port)
@@ -319,8 +320,8 @@ static void lpuart32_stop_rx(struct uart_port *port)
{
unsigned long temp;
- temp = lpuart32_read(port->membase + UARTCTRL);
- lpuart32_write(temp & ~UARTCTRL_RE, port->membase + UARTCTRL);
+ temp = lpuart32_read(port, UARTCTRL);
+ lpuart32_write(port, temp & ~UARTCTRL_RE, UARTCTRL);
}
static void lpuart_dma_tx(struct lpuart_port *sport)
@@ -519,14 +520,14 @@ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
struct circ_buf *xmit = &sport->port.state->xmit;
unsigned long txcnt;
- txcnt = lpuart32_read(sport->port.membase + UARTWATER);
+ txcnt = lpuart32_read(&sport->port, UARTWATER);
txcnt = txcnt >> UARTWATER_TXCNT_OFF;
txcnt &= UARTWATER_COUNT_MASK;
while (!uart_circ_empty(xmit) && (txcnt < sport->txfifo_size)) {
- lpuart32_write(xmit->buf[xmit->tail], sport->port.membase + UARTDATA);
+ lpuart32_write(&sport->port, xmit->buf[xmit->tail], UARTDATA);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
sport->port.icount.tx++;
- txcnt = lpuart32_read(sport->port.membase + UARTWATER);
+ txcnt = lpuart32_read(&sport->port, UARTWATER);
txcnt = txcnt >> UARTWATER_TXCNT_OFF;
txcnt &= UARTWATER_COUNT_MASK;
}
@@ -562,10 +563,10 @@ static void lpuart32_start_tx(struct uart_port *port)
struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
unsigned long temp;
- temp = lpuart32_read(port->membase + UARTCTRL);
- lpuart32_write(temp | UARTCTRL_TIE, port->membase + UARTCTRL);
+ temp = lpuart32_read(port, UARTCTRL);
+ lpuart32_write(port, temp | UARTCTRL_TIE, UARTCTRL);
- if (lpuart32_read(port->membase + UARTSTAT) & UARTSTAT_TDRE)
+ if (lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE)
lpuart32_transmit_buffer(sport);
}
@@ -588,7 +589,7 @@ static unsigned int lpuart_tx_empty(struct uart_port *port)
static unsigned int lpuart32_tx_empty(struct uart_port *port)
{
- return (lpuart32_read(port->membase + UARTSTAT) & UARTSTAT_TC) ?
+ return (lpuart32_read(port, UARTSTAT) & UARTSTAT_TC) ?
TIOCSER_TEMT : 0;
}
@@ -601,7 +602,7 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
spin_lock_irqsave(&sport->port.lock, flags);
if (sport->port.x_char) {
if (sport->port.iotype & UPIO_MEM32BE)
- lpuart32_write(sport->port.x_char, sport->port.membase + UARTDATA);
+ lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
else
writeb(sport->port.x_char, sport->port.membase + UARTDR);
goto out;
@@ -701,15 +702,15 @@ static irqreturn_t lpuart32_rxint(int irq, void *dev_id)
spin_lock_irqsave(&sport->port.lock, flags);
- while (!(lpuart32_read(sport->port.membase + UARTFIFO) & UARTFIFO_RXEMPT)) {
+ while (!(lpuart32_read(&sport->port, UARTFIFO) & UARTFIFO_RXEMPT)) {
flg = TTY_NORMAL;
sport->port.icount.rx++;
/*
* to clear the FE, OR, NF, FE, PE flags,
* read STAT then read DATA reg
*/
- sr = lpuart32_read(sport->port.membase + UARTSTAT);
- rx = lpuart32_read(sport->port.membase + UARTDATA);
+ sr = lpuart32_read(&sport->port, UARTSTAT);
+ rx = lpuart32_read(&sport->port, UARTDATA);
rx &= 0x3ff;
if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
@@ -776,18 +777,18 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id)
struct lpuart_port *sport = dev_id;
unsigned long sts, rxcount;
- sts = lpuart32_read(sport->port.membase + UARTSTAT);
- rxcount = lpuart32_read(sport->port.membase + UARTWATER);
+ sts = lpuart32_read(&sport->port, UARTSTAT);
+ rxcount = lpuart32_read(&sport->port, UARTWATER);
rxcount = rxcount >> UARTWATER_RXCNT_OFF;
if (sts & UARTSTAT_RDRF || rxcount > 0)
lpuart32_rxint(irq, dev_id);
if ((sts & UARTSTAT_TDRE) &&
- !(lpuart32_read(sport->port.membase + UARTBAUD) & UARTBAUD_TDMAE))
+ !(lpuart32_read(&sport->port, UARTBAUD) & UARTBAUD_TDMAE))
lpuart_txint(irq, dev_id);
- lpuart32_write(sts, sport->port.membase + UARTSTAT);
+ lpuart32_write(&sport->port, sts, UARTSTAT);
return IRQ_HANDLED;
}
@@ -1048,7 +1049,7 @@ static unsigned int lpuart32_get_mctrl(struct uart_port *port)
unsigned int temp = 0;
unsigned long reg;
- reg = lpuart32_read(port->membase + UARTMODIR);
+ reg = lpuart32_read(port, UARTMODIR);
if (reg & UARTMODIR_TXCTSE)
temp |= TIOCM_CTS;
@@ -1083,7 +1084,7 @@ static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
unsigned long temp;
- temp = lpuart32_read(port->membase + UARTMODIR) &
+ temp = lpuart32_read(port, UARTMODIR) &
~(UARTMODIR_RXRTSE | UARTMODIR_TXCTSE);
if (mctrl & TIOCM_RTS)
@@ -1092,7 +1093,7 @@ static void lpuart32_set_mctrl(struct uart_port *port, unsigned int mctrl)
if (mctrl & TIOCM_CTS)
temp |= UARTMODIR_TXCTSE;
- lpuart32_write(temp, port->membase + UARTMODIR);
+ lpuart32_write(port, temp, UARTMODIR);
}
static void lpuart_break_ctl(struct uart_port *port, int break_state)
@@ -1111,12 +1112,12 @@ static void lpuart32_break_ctl(struct uart_port *port, int break_state)
{
unsigned long temp;
- temp = lpuart32_read(port->membase + UARTCTRL) & ~UARTCTRL_SBK;
+ temp = lpuart32_read(port, UARTCTRL) & ~UARTCTRL_SBK;
if (break_state != 0)
temp |= UARTCTRL_SBK;
- lpuart32_write(temp, port->membase + UARTCTRL);
+ lpuart32_write(port, temp, UARTCTRL);
}
static void lpuart_setup_watermark(struct lpuart_port *sport)
@@ -1156,24 +1157,24 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
unsigned long val, ctrl;
unsigned long ctrl_saved;
- ctrl = lpuart32_read(sport->port.membase + UARTCTRL);
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
ctrl_saved = ctrl;
ctrl &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_TE |
UARTCTRL_RIE | UARTCTRL_RE);
- lpuart32_write(ctrl, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
/* enable FIFO mode */
- val = lpuart32_read(sport->port.membase + UARTFIFO);
+ val = lpuart32_read(&sport->port, UARTFIFO);
val |= UARTFIFO_TXFE | UARTFIFO_RXFE;
val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
- lpuart32_write(val, sport->port.membase + UARTFIFO);
+ lpuart32_write(&sport->port, val, UARTFIFO);
/* set the watermark */
val = (0x1 << UARTWATER_RXWATER_OFF) | (0x0 << UARTWATER_TXWATER_OFF);
- lpuart32_write(val, sport->port.membase + UARTWATER);
+ lpuart32_write(&sport->port, val, UARTWATER);
/* Restore cr2 */
- lpuart32_write(ctrl_saved, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, ctrl_saved, UARTCTRL);
}
static void rx_dma_timer_init(struct lpuart_port *sport)
@@ -1249,7 +1250,7 @@ static int lpuart32_startup(struct uart_port *port)
unsigned long temp;
/* determine FIFO size */
- temp = lpuart32_read(sport->port.membase + UARTFIFO);
+ temp = lpuart32_read(&sport->port, UARTFIFO);
sport->txfifo_size = 0x1 << (((temp >> UARTFIFO_TXSIZE_OFF) &
UARTFIFO_FIFOSIZE_MASK) - 1);
@@ -1266,10 +1267,10 @@ static int lpuart32_startup(struct uart_port *port)
lpuart32_setup_watermark(sport);
- temp = lpuart32_read(sport->port.membase + UARTCTRL);
+ temp = lpuart32_read(&sport->port, UARTCTRL);
temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE | UARTCTRL_TE);
temp |= UARTCTRL_ILIE;
- lpuart32_write(temp, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, temp, UARTCTRL);
spin_unlock_irqrestore(&sport->port.lock, flags);
return 0;
@@ -1318,10 +1319,10 @@ static void lpuart32_shutdown(struct uart_port *port)
spin_lock_irqsave(&port->lock, flags);
/* disable Rx/Tx and interrupts */
- temp = lpuart32_read(port->membase + UARTCTRL);
+ temp = lpuart32_read(port, UARTCTRL);
temp &= ~(UARTCTRL_TE | UARTCTRL_RE |
UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE);
- lpuart32_write(temp, port->membase + UARTCTRL);
+ lpuart32_write(port, temp, UARTCTRL);
spin_unlock_irqrestore(&port->lock, flags);
@@ -1496,9 +1497,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
unsigned int sbr;
- ctrl = old_ctrl = lpuart32_read(sport->port.membase + UARTCTRL);
- bd = lpuart32_read(sport->port.membase + UARTBAUD);
- modem = lpuart32_read(sport->port.membase + UARTMODIR);
+ ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL);
+ bd = lpuart32_read(&sport->port, UARTBAUD);
+ modem = lpuart32_read(&sport->port, UARTMODIR);
/*
* only support CS8 and CS7, and for CS7 must enable PE.
* supported mode:
@@ -1584,21 +1585,21 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
uart_update_timeout(port, termios->c_cflag, baud);
/* wait transmit engin complete */
- while (!(lpuart32_read(sport->port.membase + UARTSTAT) & UARTSTAT_TC))
+ while (!(lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_TC))
barrier();
/* disable transmit and receive */
- lpuart32_write(old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
- sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
+ UARTCTRL);
sbr = sport->port.uartclk / (16 * baud);
bd &= ~UARTBAUD_SBR_MASK;
bd |= sbr & UARTBAUD_SBR_MASK;
bd |= UARTBAUD_BOTHEDGE;
bd &= ~(UARTBAUD_TDMAE | UARTBAUD_RDMAE);
- lpuart32_write(bd, sport->port.membase + UARTBAUD);
- lpuart32_write(modem, sport->port.membase + UARTMODIR);
- lpuart32_write(ctrl, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, bd, UARTBAUD);
+ lpuart32_write(&sport->port, modem, UARTMODIR);
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
/* restore control register */
spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1701,10 +1702,10 @@ static void lpuart_console_putchar(struct uart_port *port, int ch)
static void lpuart32_console_putchar(struct uart_port *port, int ch)
{
- while (!(lpuart32_read(port->membase + UARTSTAT) & UARTSTAT_TDRE))
+ while (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE))
barrier();
- lpuart32_write(ch, port->membase + UARTDATA);
+ lpuart32_write(port, ch, UARTDATA);
}
static void
@@ -1752,18 +1753,18 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count)
spin_lock_irqsave(&sport->port.lock, flags);
/* first save CR2 and then disable interrupts */
- cr = old_cr = lpuart32_read(sport->port.membase + UARTCTRL);
+ cr = old_cr = lpuart32_read(&sport->port, UARTCTRL);
cr |= (UARTCTRL_TE | UARTCTRL_RE);
cr &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE);
- lpuart32_write(cr, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, cr, UARTCTRL);
uart_console_write(&sport->port, s, count, lpuart32_console_putchar);
/* wait for transmitter finish complete and restore CR2 */
- while (!(lpuart32_read(sport->port.membase + UARTSTAT) & UARTSTAT_TC))
+ while (!(lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_TC))
barrier();
- lpuart32_write(old_cr, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, old_cr, UARTCTRL);
if (locked)
spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1829,14 +1830,14 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
unsigned long cr, bd;
unsigned int sbr, uartclk, baud_raw;
- cr = lpuart32_read(sport->port.membase + UARTCTRL);
+ cr = lpuart32_read(&sport->port, UARTCTRL);
cr &= UARTCTRL_TE | UARTCTRL_RE;
if (!cr)
return;
/* ok, the port was enabled */
- cr = lpuart32_read(sport->port.membase + UARTCTRL);
+ cr = lpuart32_read(&sport->port, UARTCTRL);
*parity = 'n';
if (cr & UARTCTRL_PE) {
@@ -1851,7 +1852,7 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
else
*bits = 8;
- bd = lpuart32_read(sport->port.membase + UARTBAUD);
+ bd = lpuart32_read(&sport->port, UARTBAUD);
bd &= UARTBAUD_SBR_MASK;
sbr = bd;
uartclk = clk_get_rate(sport->clk);
@@ -2095,9 +2096,9 @@ static int lpuart_suspend(struct device *dev)
if (sport->port.iotype & UPIO_MEM32BE) {
/* disable Rx/Tx and interrupts */
- temp = lpuart32_read(sport->port.membase + UARTCTRL);
+ temp = lpuart32_read(&sport->port, UARTCTRL);
temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
- lpuart32_write(temp, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, temp, UARTCTRL);
} else {
/* disable Rx/Tx and interrupts */
temp = readb(sport->port.membase + UARTCR2);
@@ -2146,10 +2147,10 @@ static int lpuart_resume(struct device *dev)
if (sport->port.iotype & UPIO_MEM32BE) {
lpuart32_setup_watermark(sport);
- temp = lpuart32_read(sport->port.membase + UARTCTRL);
+ temp = lpuart32_read(&sport->port, UARTCTRL);
temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
UARTCTRL_TE | UARTCTRL_ILIE);
- lpuart32_write(temp, sport->port.membase + UARTCTRL);
+ lpuart32_write(&sport->port, temp, UARTCTRL);
} else {
lpuart_setup_watermark(sport);
temp = readb(sport->port.membase + UARTCR2);
--
2.7.4
^ permalink raw reply related
* [PATCH V4 1/7] tty: serial: lpuart: introduce lpuart_soc_data to represent SoC property
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
In-Reply-To: <1497322554-24463-1-git-send-email-aisheng.dong@nxp.com>
This is used to dynamically check the SoC specific lpuart properies.
Currently only the iotype is added, it functions the same as before.
With this, new chips with different iotype will be more easily added.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Mingkai Hu <Mingkai.Hu@nxp.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Fugang Duan <fugang.duan@nxp.com>
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
---
ChangeLog:
v3->v4:
* remove one duplicated blank line
v2->v3:
* use standard iotype flags instead of private is_32 member
v1->v2:
* make all soc_data const
---
drivers/tty/serial/fsl_lpuart.c | 47 +++++++++++++++++++++++------------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 15df1ba7..c17a0ea 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -236,7 +236,6 @@ struct lpuart_port {
struct clk *clk;
unsigned int txfifo_size;
unsigned int rxfifo_size;
- bool lpuart32;
bool lpuart_dma_tx_use;
bool lpuart_dma_rx_use;
@@ -258,13 +257,21 @@ struct lpuart_port {
wait_queue_head_t dma_wait;
};
+struct lpuart_soc_data {
+ char iotype;
+};
+
+static const struct lpuart_soc_data vf_data = {
+ .iotype = UPIO_MEM,
+};
+
+static const struct lpuart_soc_data ls_data = {
+ .iotype = UPIO_MEM32BE,
+};
+
static const struct of_device_id lpuart_dt_ids[] = {
- {
- .compatible = "fsl,vf610-lpuart",
- },
- {
- .compatible = "fsl,ls1021a-lpuart",
- },
+ { .compatible = "fsl,vf610-lpuart", .data = &vf_data, },
+ { .compatible = "fsl,ls1021a-lpuart", .data = &ls_data, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
@@ -593,7 +600,7 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
spin_lock_irqsave(&sport->port.lock, flags);
if (sport->port.x_char) {
- if (sport->lpuart32)
+ if (sport->port.iotype & UPIO_MEM32BE)
lpuart32_write(sport->port.x_char, sport->port.membase + UARTDATA);
else
writeb(sport->port.x_char, sport->port.membase + UARTDR);
@@ -601,14 +608,14 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
- if (sport->lpuart32)
+ if (sport->port.iotype & UPIO_MEM32BE)
lpuart32_stop_tx(&sport->port);
else
lpuart_stop_tx(&sport->port);
goto out;
}
- if (sport->lpuart32)
+ if (sport->port.iotype & UPIO_MEM32BE)
lpuart32_transmit_buffer(sport);
else
lpuart_transmit_buffer(sport);
@@ -1881,12 +1888,12 @@ static int __init lpuart_console_setup(struct console *co, char *options)
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
- if (sport->lpuart32)
+ if (sport->port.iotype & UPIO_MEM32BE)
lpuart32_console_get_options(sport, &baud, &parity, &bits);
else
lpuart_console_get_options(sport, &baud, &parity, &bits);
- if (sport->lpuart32)
+ if (sport->port.iotype & UPIO_MEM32BE)
lpuart32_setup_watermark(sport);
else
lpuart_setup_watermark(sport);
@@ -1971,6 +1978,9 @@ static struct uart_driver lpuart_reg = {
static int lpuart_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id = of_match_device(lpuart_dt_ids,
+ &pdev->dev);
+ const struct lpuart_soc_data *sdata = of_id->data;
struct device_node *np = pdev->dev.of_node;
struct lpuart_port *sport;
struct resource *res;
@@ -1988,8 +1998,6 @@ static int lpuart_probe(struct platform_device *pdev)
return ret;
}
sport->port.line = ret;
- sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart");
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(sport->port.membase))
@@ -1998,15 +2006,14 @@ static int lpuart_probe(struct platform_device *pdev)
sport->port.mapbase = res->start;
sport->port.dev = &pdev->dev;
sport->port.type = PORT_LPUART;
- sport->port.iotype = UPIO_MEM;
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
dev_err(&pdev->dev, "cannot obtain irq\n");
return ret;
}
sport->port.irq = ret;
-
- if (sport->lpuart32)
+ sport->port.iotype = sdata->iotype;
+ if (sport->port.iotype & UPIO_MEM32BE)
sport->port.ops = &lpuart32_pops;
else
sport->port.ops = &lpuart_pops;
@@ -2033,7 +2040,7 @@ static int lpuart_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &sport->port);
- if (sport->lpuart32)
+ if (sport->port.iotype & UPIO_MEM32BE)
lpuart_reg.cons = LPUART32_CONSOLE;
else
lpuart_reg.cons = LPUART_CONSOLE;
@@ -2086,7 +2093,7 @@ static int lpuart_suspend(struct device *dev)
struct lpuart_port *sport = dev_get_drvdata(dev);
unsigned long temp;
- if (sport->lpuart32) {
+ if (sport->port.iotype & UPIO_MEM32BE) {
/* disable Rx/Tx and interrupts */
temp = lpuart32_read(sport->port.membase + UARTCTRL);
temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
@@ -2137,7 +2144,7 @@ static int lpuart_resume(struct device *dev)
if (sport->port.suspended && !sport->port.irq_wake)
clk_prepare_enable(sport->clk);
- if (sport->lpuart32) {
+ if (sport->port.iotype & UPIO_MEM32BE) {
lpuart32_setup_watermark(sport);
temp = lpuart32_read(sport->port.membase + UARTCTRL);
temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
--
2.7.4
^ permalink raw reply related
* [PATCH V4 0/7] tty: serial: lpuart: add imx7ulp support
From: Dong Aisheng @ 2017-06-13 2:55 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, linux-arm-kernel, gregkh, jslaby, fugang.duan,
stefan, Mingkai.Hu, yangbo.lu, nikita.yoush, andy.shevchenko,
dongas86, Dong Aisheng
The lpuart in imx7ulp is basically the same as ls1021a. It's also
32 bit width register, but unlike ls1021a, it's little endian.
Besides that, imx7ulp lpuart has a minor different register layout
from ls1021a that it has four extra registers (verid, param, global,
pincfg) located at the beginning of register map, which are currently
not used by the driver and less to be used later.
Furthermore, this patch serial also add a new more accurate baud rate
calculation method as MX7ULP can't divide a suitable baud rate
with the default setting.
Currently the new baud rate calculation is only enabled on MX7ULP.
However, i guess the Layerscape may also be able to use it as there
seems to be no difference in baud rate setting register after checking
the Layerscape Reference Manual.
As i don't have Layerscape boards, i can't test it, so i only enable it
for MX7ULP by default to avoid a potential break.
I copied LayerScape guys in this series and hope they can help test later.
If it works on Layerscape as well, then they can switch to the new setting
too and totally remove the old stuff.
ChangeLog:
v3->v4:
* Minor changes.
1) Remove one duplicated blank line
2) Removed on unneeded semicolon in switch catched by 0day Robot
v2->v3:
* Remove global lpuart_is_be.
Instead use struct uart_port's iotype member.
lpuart32_read/write API prototype is also updated to use the iotype to
distingush the endians. And most importantly, this way also works with
earlycon.
v1->v2:
* Patch 2/4/5 chagned, other no changes.
See individuals for details.
Dong Aisheng (7):
tty: serial: lpuart: introduce lpuart_soc_data to represent SoC
property
tty: serial: lpuart: refactor lpuart32_{read|write} prototype
tty: serial: lpuart: add little endian 32 bit register support
dt-bindings: serial: fsl-lpuart: add i.MX7ULP support
tty: serial: lpuart: add imx7ulp support
tty: serial: lpuart: add earlycon support for imx7ulp
tty: serial: lpuart: add a more accurate baud rate calculation method
.../devicetree/bindings/serial/fsl-lpuart.txt | 2 +
drivers/tty/serial/fsl_lpuart.c | 286 ++++++++++++++-------
2 files changed, 201 insertions(+), 87 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH] tty: serial: lpuart: fix semicolon.cocci warnings
From: Dong Aisheng @ 2017-06-13 2:38 UTC (permalink / raw)
To: kbuild test robot
Cc: Dong Aisheng, kbuild-all, linux-serial, linux-kernel,
linux-arm-kernel, gregkh, jslaby, fugang.duan, stefan, Mingkai.Hu,
yangbo.lu, nikita.yoush, andy.shevchenko, fengguang.wu
In-Reply-To: <20170613002841.GA25353@lkp-wsm-ep1>
Hi Fengguang,
On Tue, Jun 13, 2017 at 08:28:41AM +0800, kbuild test robot wrote:
> drivers/tty/serial/fsl_lpuart.c:305:2-3: Unneeded semicolon
>
>
> Remove unneeded semicolon.
>
> Generated by: scripts/coccinelle/misc/semicolon.cocci
>
> CC: Dong Aisheng <aisheng.dong@nxp.com>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Seems not catched by checkpatch.
> ---
>
> fsl_lpuart.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> --- a/drivers/tty/serial/fsl_lpuart.c
> +++ b/drivers/tty/serial/fsl_lpuart.c
> @@ -302,7 +302,7 @@ static inline void lpuart32_write(struct
> case UPIO_MEM32BE:
> iowrite32be(val, port->membase + off);
> break;
> - };
> + }
lpuart32_read needs the same fixing.
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index a66ed23..ed0bf18 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -288,7 +288,7 @@ static inline u32 lpuart32_read(struct uart_port *port, u32 off)
return ioread32be(port->membase + off);
default:
return 0;
- };
+ }
}
static inline void lpuart32_write(struct uart_port *port, u32 val,
@@ -301,7 +301,7 @@ static inline void lpuart32_write(struct uart_port *port, u32 val,
case UPIO_MEM32BE:
iowrite32be(val, port->membase + off);
break;
- };
+ }
}
Thanks for the catching.
Regards
Dong Aisheng
> }
>
> static void lpuart_stop_tx(struct uart_port *port)
^ permalink raw reply related
* Re: [PATCH V3 1/7] tty: serial: lpuart: introduce lpuart_soc_data to represent SoC property
From: Dong Aisheng @ 2017-06-13 2:28 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Dong Aisheng, linux-serial@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm Mailing List,
Greg Kroah-Hartman, Jiri Slaby, Andy Duan, Stefan Agner,
Mingkai Hu, Y.B. Lu, Nikita Yushchenko
In-Reply-To: <CAHp75Vdi8_cxkVuwnvBo7TmceMuA1n1mUg+D5v3xN4ck67MTMA@mail.gmail.com>
On Mon, Jun 12, 2017 at 08:49:36PM +0300, Andy Shevchenko wrote:
> On Mon, Jun 12, 2017 at 6:37 PM, Dong Aisheng <aisheng.dong@nxp.com> wrote:
> > This is used to dynamically check the SoC specific lpuart properies.
> > Currently only the iotype is added, it functions the same as before.
> > With this, new chips with different iotype will be more easily added.
>
>
> > +struct lpuart_soc_data {
> > + char iotype;
> > +};
> > +
> > +static const struct lpuart_soc_data vf_data = {
> > + .iotype = UPIO_MEM,
> > +};
> > +
> > +static const struct lpuart_soc_data ls_data = {
> > + .iotype = UPIO_MEM32BE,
>
> > +
>
> Redundant.
My mistake to introduce one more extra blank line...
>
> > +};
>
> And now most interesting part...
>
> > - if (sport->lpuart32)
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > lpuart32_write(sport->port.x_char, sport->port.membase + UARTDATA);
> > else
> > writeb(sport->port.x_char, sport->port.membase + UARTDR);
>
> > - if (sport->lpuart32)
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > lpuart32_stop_tx(&sport->port);
> > else
> > lpuart_stop_tx(&sport->port);
>
> > - if (sport->lpuart32)
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > lpuart32_transmit_buffer(sport);
> > else
> > lpuart_transmit_buffer(sport);
>
> > - if (sport->lpuart32)
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > lpuart32_console_get_options(sport, &baud, &parity, &bits);
> > else
> > lpuart_console_get_options(sport, &baud, &parity, &bits);
>
> > - if (sport->lpuart32)
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > lpuart32_setup_watermark(sport);
> > else
> > lpuart_setup_watermark(sport);
>
> > - if (sport->lpuart32)
> > + sport->port.iotype = sdata->iotype;
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > sport->port.ops = &lpuart32_pops;
> > else
> > sport->port.ops = &lpuart_pops;
>
> > - if (sport->lpuart32)
> > + if (sport->port.iotype & UPIO_MEM32BE)
> > lpuart_reg.cons = LPUART32_CONSOLE;
> > else
> > lpuart_reg.cons = LPUART_CONSOLE;
>
> ...all above since you introduced nice struct, can get rid of conditionals.
> Instead it might be a members of the struct above.
>
> (I dunno if it's good to have in this patch, but at list a follow up
> could be nice to have)
>
Yes, to clean up all conditionals, much more things need to be done,
so a separate follow up patch may be better.
This patch only address iotype which is just the same as before.
> > - if (sport->lpuart32) {
> > + if (sport->port.iotype & UPIO_MEM32BE) {
> > /* disable Rx/Tx and interrupts */
> > temp = lpuart32_read(sport->port.membase + UARTCTRL);
> > temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
>
> > - if (sport->lpuart32) {
> > + if (sport->port.iotype & UPIO_MEM32BE) {
> > lpuart32_setup_watermark(sport);
> > temp = lpuart32_read(sport->port.membase + UARTCTRL);
> > temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
>
> Above are questionable, might be not need to convert them.
>
> So, in any case above is a sighting which you could address (separately).
Yes, seems not a easy convert which can be investigated later.
Thanks for the review.
Regards
Dong Aisheng
>
> --
> With Best Regards,
> Andy Shevchenko
^ permalink raw reply
* [PATCH] tty: serial: lpuart: fix semicolon.cocci warnings
From: kbuild test robot @ 2017-06-13 0:28 UTC (permalink / raw)
Cc: kbuild-all, linux-serial, linux-kernel, linux-arm-kernel, gregkh,
jslaby, fugang.duan, stefan, Mingkai.Hu, yangbo.lu, nikita.yoush,
andy.shevchenko, dongas86, Dong Aisheng
In-Reply-To: <1497281848-12995-4-git-send-email-aisheng.dong@nxp.com>
drivers/tty/serial/fsl_lpuart.c:305:2-3: Unneeded semicolon
Remove unneeded semicolon.
Generated by: scripts/coccinelle/misc/semicolon.cocci
CC: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
---
fsl_lpuart.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -302,7 +302,7 @@ static inline void lpuart32_write(struct
case UPIO_MEM32BE:
iowrite32be(val, port->membase + off);
break;
- };
+ }
}
static void lpuart_stop_tx(struct uart_port *port)
^ 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