* [PATCH 01/11] resolve PXA<->8250 serial device address conflict [not found] <1385879185-22455-1-git-send-email-ynvich@gmail.com> @ 2013-12-01 6:26 ` Sergei Ianovich 2013-12-02 9:02 ` Heikki Krogerus 2014-01-28 14:14 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Pavel Machek 2013-12-01 6:26 ` [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x Sergei Ianovich 1 sibling, 2 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-01 6:26 UTC (permalink / raw) To: linux-kernel, linux-arm-kernel Cc: Sergei Ianovich, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS PXA serial ports have "standard" UART names (ttyS[0-3]), major device number (4) and first minor device number (64) by default. If the system has extra 8250 serial port hardware in addition to onboard PXA serial ports, default settings produce a device allocation conflict. The patch provides a configuration option which can move onboard ports out of the way of 8250_core by assigning a different (204) major number and corresponding device names (ttySA[0-3]). Signed-off-by: Sergei Ianovich <ynvich@gmail.com> --- drivers/tty/serial/Kconfig | 19 +++++++++++++++++++ drivers/tty/serial/pxa.c | 22 ++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a3817ab..328b716 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -419,6 +419,25 @@ config SERIAL_PXA_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_PXA_AS_TTYSA + bool "PXA serial ports with SA-1100 name and major number" + depends on SERIAL_PXA + default N + help + PXA serial ports have "standard" UART names (ttyS[0-3]), major + device number (4) and first minor device number (64) by default. + + If the system has extra 8250 serial port hardware in addition + to onboard PXA serial ports, default settings produce a device + allocation conflict. + + Selecting this option will move onboard ports out of the way of + 8250_core by assigning a different (204) major number and + corresponding device names (ttySA[0-3]). + + Say Y here, if you need to support extra 8250 serial port hardware + on a PXA system. + config SERIAL_SA1100 bool "SA1100 serial port support" depends on ARCH_SA1100 diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index f9f20f3..2b5a8ad 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -593,6 +593,20 @@ serial_pxa_type(struct uart_port *port) static struct uart_pxa_port *serial_pxa_ports[4]; static struct uart_driver serial_pxa_reg; +#ifndef CONFIG_SERIAL_PXA_AS_TTYSA + +#define PXA_TTY_NAME "ttyS" +#define PXA_TTY_MAJOR TTY_MAJOR +#define PXA_TTY_MINOR 64 + +#else + +#define PXA_TTY_NAME "ttySA" +#define PXA_TTY_MAJOR 204 +#define PXA_TTY_MINOR 5 + +#endif + #ifdef CONFIG_SERIAL_PXA_CONSOLE #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) @@ -751,7 +765,7 @@ serial_pxa_console_setup(struct console *co, char *options) } static struct console serial_pxa_console = { - .name = "ttyS", + .name = PXA_TTY_NAME, .write = serial_pxa_console_write, .device = uart_console_device, .setup = serial_pxa_console_setup, @@ -792,9 +806,9 @@ static struct uart_ops serial_pxa_pops = { static struct uart_driver serial_pxa_reg = { .owner = THIS_MODULE, .driver_name = "PXA serial", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, + .dev_name = PXA_TTY_NAME, + .major = PXA_TTY_MAJOR, + .minor = PXA_TTY_MINOR, .nr = 4, .cons = PXA_CONSOLE, }; -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-01 6:26 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Sergei Ianovich @ 2013-12-02 9:02 ` Heikki Krogerus 2013-12-02 9:23 ` Sergei Ianovich 2014-01-28 14:14 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Pavel Machek 1 sibling, 1 reply; 36+ messages in thread From: Heikki Krogerus @ 2013-12-02 9:02 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS Hi, On Sun, Dec 01, 2013 at 10:26:14AM +0400, Sergei Ianovich wrote: > PXA serial ports have "standard" UART names (ttyS[0-3]), major > device number (4) and first minor device number (64) by default. > > If the system has extra 8250 serial port hardware in addition > to onboard PXA serial ports, default settings produce a device > allocation conflict. > > The patch provides a configuration option which can move onboard > ports out of the way of 8250_core by assigning a different (204) > major number and corresponding device names (ttySA[0-3]). > > Signed-off-by: Sergei Ianovich <ynvich@gmail.com> > --- > drivers/tty/serial/Kconfig | 19 +++++++++++++++++++ > drivers/tty/serial/pxa.c | 22 ++++++++++++++++++---- > 2 files changed, 37 insertions(+), 4 deletions(-) > diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c <snip> > --- a/drivers/tty/serial/pxa.c > +++ b/drivers/tty/serial/pxa.c > @@ -593,6 +593,20 @@ serial_pxa_type(struct uart_port *port) > static struct uart_pxa_port *serial_pxa_ports[4]; > static struct uart_driver serial_pxa_reg; > > +#ifndef CONFIG_SERIAL_PXA_AS_TTYSA > + > +#define PXA_TTY_NAME "ttyS" > +#define PXA_TTY_MAJOR TTY_MAJOR > +#define PXA_TTY_MINOR 64 > + > +#else > + > +#define PXA_TTY_NAME "ttySA" > +#define PXA_TTY_MAJOR 204 > +#define PXA_TTY_MINOR 5 > + > +#endif > + > #ifdef CONFIG_SERIAL_PXA_CONSOLE > > #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) > @@ -751,7 +765,7 @@ serial_pxa_console_setup(struct console *co, char *options) > } > > static struct console serial_pxa_console = { > - .name = "ttyS", > + .name = PXA_TTY_NAME, > .write = serial_pxa_console_write, > .device = uart_console_device, > .setup = serial_pxa_console_setup, > @@ -792,9 +806,9 @@ static struct uart_ops serial_pxa_pops = { > static struct uart_driver serial_pxa_reg = { > .owner = THIS_MODULE, > .driver_name = "PXA serial", > - .dev_name = "ttyS", > - .major = TTY_MAJOR, > - .minor = 64, > + .dev_name = PXA_TTY_NAME, > + .major = PXA_TTY_MAJOR, > + .minor = PXA_TTY_MINOR, > .nr = 4, > .cons = PXA_CONSOLE, > }; If drivers/tty/serial/pxa.c was converted to an other probe driver for the 8250, this would not be an issue. Br, -- heikki ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-02 9:02 ` Heikki Krogerus @ 2013-12-02 9:23 ` Sergei Ianovich 2013-12-02 9:49 ` Heikki Krogerus 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-02 9:23 UTC (permalink / raw) To: Heikki Krogerus Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS On Mon, 2013-12-02 at 11:02 +0200, Heikki Krogerus wrote: > On Sun, Dec 01, 2013 at 10:26:14AM +0400, Sergei Ianovich wrote: > > PXA serial ports have "standard" UART names (ttyS[0-3]), major > > device number (4) and first minor device number (64) by default. > > > > If the system has extra 8250 serial port hardware in addition > > to onboard PXA serial ports, default settings produce a device > > allocation conflict. > > > > The patch provides a configuration option which can move onboard > > ports out of the way of 8250_core by assigning a different (204) > > major number and corresponding device names (ttySA[0-3]). > > > <snip> > > If drivers/tty/serial/pxa.c was converted to an other probe driver for > the 8250, this would not be an issue. It seems that my patch is not going to be accepted. However, there is a device which has both PXA ports and a additional 8250 accent chip. As a result, there is a device allocation conflict. For the device to be usable the conflict needs to be resolved. Do you mean that drivers/tty/serial/pxa.c needs to be rewritten to support lp8x4x special case? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-02 9:23 ` Sergei Ianovich @ 2013-12-02 9:49 ` Heikki Krogerus 2013-12-02 10:26 ` Sergei Ianovich 0 siblings, 1 reply; 36+ messages in thread From: Heikki Krogerus @ 2013-12-02 9:49 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS Hi, On Mon, Dec 02, 2013 at 01:23:58PM +0400, Sergei Ianovich wrote: > On Mon, 2013-12-02 at 11:02 +0200, Heikki Krogerus wrote: > > On Sun, Dec 01, 2013 at 10:26:14AM +0400, Sergei Ianovich wrote: > > > PXA serial ports have "standard" UART names (ttyS[0-3]), major > > > device number (4) and first minor device number (64) by default. > > > > > > If the system has extra 8250 serial port hardware in addition > > > to onboard PXA serial ports, default settings produce a device > > > allocation conflict. > > > > > > The patch provides a configuration option which can move onboard > > > ports out of the way of 8250_core by assigning a different (204) > > > major number and corresponding device names (ttySA[0-3]). > > > > > <snip> > > > > If drivers/tty/serial/pxa.c was converted to an other probe driver for > > the 8250, this would not be an issue. > > It seems that my patch is not going to be accepted. However, there is a > device which has both PXA ports and a additional 8250 accent chip. As a > result, there is a device allocation conflict. For the device to be > usable the conflict needs to be resolved. > > Do you mean that drivers/tty/serial/pxa.c needs to be rewritten to > support lp8x4x special case? Sorry I was not clear. I was suggesting that drivers/tty/serial/pxa.c would be converted to drivers/tty/serial/8250/8250_pxa.c since it looks to me like just an other 16x50 compatible UART. That would fix the issue with the name conflict. You would then simply register 8250 ports from two probe drivers (drivers/tty/serial/8250/8250_pxa.c and drivers/tty/serial/8250/8250_lp8x4x.c). Depending on the order you register your platform devices (which you decide in your platform code), but let's say the pxa gets registered first and let's say it only has one port. You will then have in your system /dev/ttyS0 for the pxa port and /dev/ttyS[1-4] for the other UART. I hope I was able to explain what I mean this time :) Thanks, -- heikki ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-02 9:49 ` Heikki Krogerus @ 2013-12-02 10:26 ` Sergei Ianovich 2013-12-02 14:10 ` Heikki Krogerus 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-02 10:26 UTC (permalink / raw) To: Heikki Krogerus Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS On Mon, 2013-12-02 at 11:49 +0200, Heikki Krogerus wrote: > On Mon, Dec 02, 2013 at 01:23:58PM +0400, Sergei Ianovich wrote: > > On Mon, 2013-12-02 at 11:02 +0200, Heikki Krogerus wrote: > > > On Sun, Dec 01, 2013 at 10:26:14AM +0400, Sergei Ianovich wrote: > > > > PXA serial ports have "standard" UART names (ttyS[0-3]), major > > > > device number (4) and first minor device number (64) by default. > > > > > > > > If the system has extra 8250 serial port hardware in addition > > > > to onboard PXA serial ports, default settings produce a device > > > > allocation conflict. > > > > > > > > The patch provides a configuration option which can move onboard > > > > ports out of the way of 8250_core by assigning a different (204) > > > > major number and corresponding device names (ttySA[0-3]). > > > > > > > <snip> > > > > > > If drivers/tty/serial/pxa.c was converted to an other probe driver for > > > the 8250, this would not be an issue. > > > > It seems that my patch is not going to be accepted. However, there is a > > device which has both PXA ports and a additional 8250 accent chip. As a > > result, there is a device allocation conflict. For the device to be > > usable the conflict needs to be resolved. > > > > Do you mean that drivers/tty/serial/pxa.c needs to be rewritten to > > support lp8x4x special case? > > Sorry I was not clear. I was suggesting that drivers/tty/serial/pxa.c > would be converted to drivers/tty/serial/8250/8250_pxa.c since it > looks to me like just an other 16x50 compatible UART. That would fix > the issue with the name conflict. You would then simply register 8250 > ports from two probe drivers (drivers/tty/serial/8250/8250_pxa.c and > drivers/tty/serial/8250/8250_lp8x4x.c). > > Depending on the order you register your platform devices (which you > decide in your platform code), but let's say the pxa gets registered > first and let's say it only has one port. You will then have in your > system /dev/ttyS0 for the pxa port and /dev/ttyS[1-4] for the other > UART. > > I hope I was able to explain what I mean this time :) Sorry, I wasn't clear as well. I got it right the first time. You mean pxa.c needs to merged into 8250. This will solve the conflict in question, and do it the right way. However, this will be a *much* bigger patch, and it will affect everyone on pxa. Who makes the decision which way to go? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-02 10:26 ` Sergei Ianovich @ 2013-12-02 14:10 ` Heikki Krogerus 2013-12-05 4:12 ` Greg Kroah-Hartman 0 siblings, 1 reply; 36+ messages in thread From: Heikki Krogerus @ 2013-12-02 14:10 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS Hi, On Mon, Dec 02, 2013 at 02:26:45PM +0400, Sergei Ianovich wrote: > On Mon, 2013-12-02 at 11:49 +0200, Heikki Krogerus wrote: > > On Mon, Dec 02, 2013 at 01:23:58PM +0400, Sergei Ianovich wrote: > > > On Mon, 2013-12-02 at 11:02 +0200, Heikki Krogerus wrote: > > > > > > > > If drivers/tty/serial/pxa.c was converted to an other probe driver for > > > > the 8250, this would not be an issue. > > > > > > It seems that my patch is not going to be accepted. However, there is a > > > device which has both PXA ports and a additional 8250 accent chip. As a > > > result, there is a device allocation conflict. For the device to be > > > usable the conflict needs to be resolved. > > > > > > Do you mean that drivers/tty/serial/pxa.c needs to be rewritten to > > > support lp8x4x special case? > > > > Sorry I was not clear. I was suggesting that drivers/tty/serial/pxa.c > > would be converted to drivers/tty/serial/8250/8250_pxa.c since it > > looks to me like just an other 16x50 compatible UART. That would fix > > the issue with the name conflict. You would then simply register 8250 > > ports from two probe drivers (drivers/tty/serial/8250/8250_pxa.c and > > drivers/tty/serial/8250/8250_lp8x4x.c). > > > > Depending on the order you register your platform devices (which you > > decide in your platform code), but let's say the pxa gets registered > > first and let's say it only has one port. You will then have in your > > system /dev/ttyS0 for the pxa port and /dev/ttyS[1-4] for the other > > UART. > > > > I hope I was able to explain what I mean this time :) > > Sorry, I wasn't clear as well. I got it right the first time. You mean > pxa.c needs to merged into 8250. This will solve the conflict in > question, and do it the right way. However, this will be a *much* bigger > patch, and it will affect everyone on pxa. > > Who makes the decision which way to go? Greg and Russel make this decision. By having the pxa driver simply register 8250 ports would probable reduce the code. Thats about the biggest benefit from it. It would still be something nice to have IMO. Ideally all the 8250/16x50 UARTs should register the ports with 8250_core.c, and not create complete uart driver on their own. Br, -- heikki ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-02 14:10 ` Heikki Krogerus @ 2013-12-05 4:12 ` Greg Kroah-Hartman 2013-12-05 4:31 ` Sergei Ianovich 0 siblings, 1 reply; 36+ messages in thread From: Greg Kroah-Hartman @ 2013-12-05 4:12 UTC (permalink / raw) To: Heikki Krogerus Cc: Sergei Ianovich, linux-kernel, linux-arm-kernel, Jiri Slaby, open list:SERIAL DRIVERS On Mon, Dec 02, 2013 at 04:10:33PM +0200, Heikki Krogerus wrote: > Hi, > > On Mon, Dec 02, 2013 at 02:26:45PM +0400, Sergei Ianovich wrote: > > On Mon, 2013-12-02 at 11:49 +0200, Heikki Krogerus wrote: > > > On Mon, Dec 02, 2013 at 01:23:58PM +0400, Sergei Ianovich wrote: > > > > On Mon, 2013-12-02 at 11:02 +0200, Heikki Krogerus wrote: > > > > > > > > > > If drivers/tty/serial/pxa.c was converted to an other probe driver for > > > > > the 8250, this would not be an issue. > > > > > > > > It seems that my patch is not going to be accepted. However, there is a > > > > device which has both PXA ports and a additional 8250 accent chip. As a > > > > result, there is a device allocation conflict. For the device to be > > > > usable the conflict needs to be resolved. > > > > > > > > Do you mean that drivers/tty/serial/pxa.c needs to be rewritten to > > > > support lp8x4x special case? > > > > > > Sorry I was not clear. I was suggesting that drivers/tty/serial/pxa.c > > > would be converted to drivers/tty/serial/8250/8250_pxa.c since it > > > looks to me like just an other 16x50 compatible UART. That would fix > > > the issue with the name conflict. You would then simply register 8250 > > > ports from two probe drivers (drivers/tty/serial/8250/8250_pxa.c and > > > drivers/tty/serial/8250/8250_lp8x4x.c). > > > > > > Depending on the order you register your platform devices (which you > > > decide in your platform code), but let's say the pxa gets registered > > > first and let's say it only has one port. You will then have in your > > > system /dev/ttyS0 for the pxa port and /dev/ttyS[1-4] for the other > > > UART. > > > > > > I hope I was able to explain what I mean this time :) > > > > Sorry, I wasn't clear as well. I got it right the first time. You mean > > pxa.c needs to merged into 8250. This will solve the conflict in > > question, and do it the right way. However, this will be a *much* bigger > > patch, and it will affect everyone on pxa. > > > > Who makes the decision which way to go? > > Greg and Russel make this decision. By having the pxa driver simply > register 8250 ports would probable reduce the code. Thats about the > biggest benefit from it. > > It would still be something nice to have IMO. Ideally all the > 8250/16x50 UARTs should register the ports with 8250_core.c, and not > create complete uart driver on their own. I agree, this is the best way to resolve this, having a separate uart driver isn't that good at all to be doing, if at all possible. thanks, greg k-h ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-05 4:12 ` Greg Kroah-Hartman @ 2013-12-05 4:31 ` Sergei Ianovich 2013-12-05 4:35 ` Greg Kroah-Hartman 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-05 4:31 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Heikki Krogerus, linux-kernel, linux-arm-kernel, Jiri Slaby, open list:SERIAL DRIVERS On Wed, 2013-12-04 at 20:12 -0800, Greg Kroah-Hartman wrote: > On Mon, Dec 02, 2013 at 04:10:33PM +0200, Heikki Krogerus wrote: > > On Mon, Dec 02, 2013 at 02:26:45PM +0400, Sergei Ianovich wrote: > > > Who makes the decision which way to go? > > > > Greg and Russel make this decision. By having the pxa driver simply > > register 8250 ports would probable reduce the code. Thats about the > > biggest benefit from it. > > > > It would still be something nice to have IMO. Ideally all the > > 8250/16x50 UARTs should register the ports with 8250_core.c, and not > > create complete uart driver on their own. > > I agree, this is the best way to resolve this, having a separate uart > driver isn't that good at all to be doing, if at all possible. I'm reading the last message as a confirmation that drivers/tty/serial/pxa.c needs to be rewritten using 8250_core.c. However, "if at all possible" confuses me, since we have pxa.c in the tree and it works. Greg, could you please clarify? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-05 4:31 ` Sergei Ianovich @ 2013-12-05 4:35 ` Greg Kroah-Hartman 2013-12-05 4:36 ` Sergei Ianovich [not found] ` <20131205043544.GA28580-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> 0 siblings, 2 replies; 36+ messages in thread From: Greg Kroah-Hartman @ 2013-12-05 4:35 UTC (permalink / raw) To: Sergei Ianovich Cc: Heikki Krogerus, linux-kernel, linux-arm-kernel, Jiri Slaby, open list:SERIAL DRIVERS On Thu, Dec 05, 2013 at 08:31:36AM +0400, Sergei Ianovich wrote: > On Wed, 2013-12-04 at 20:12 -0800, Greg Kroah-Hartman wrote: > > On Mon, Dec 02, 2013 at 04:10:33PM +0200, Heikki Krogerus wrote: > > > On Mon, Dec 02, 2013 at 02:26:45PM +0400, Sergei Ianovich wrote: > > > > Who makes the decision which way to go? > > > > > > Greg and Russel make this decision. By having the pxa driver simply > > > register 8250 ports would probable reduce the code. Thats about the > > > biggest benefit from it. > > > > > > It would still be something nice to have IMO. Ideally all the > > > 8250/16x50 UARTs should register the ports with 8250_core.c, and not > > > create complete uart driver on their own. > > > > I agree, this is the best way to resolve this, having a separate uart > > driver isn't that good at all to be doing, if at all possible. > > I'm reading the last message as a confirmation that > drivers/tty/serial/pxa.c needs to be rewritten using 8250_core.c. Yes, how much work is this really? thanks, greg k-h ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-05 4:35 ` Greg Kroah-Hartman @ 2013-12-05 4:36 ` Sergei Ianovich [not found] ` <20131205043544.GA28580-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> 1 sibling, 0 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-05 4:36 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Heikki Krogerus, linux-kernel, linux-arm-kernel, Jiri Slaby, open list:SERIAL DRIVERS On Wed, 2013-12-04 at 20:35 -0800, Greg Kroah-Hartman wrote: > On Thu, Dec 05, 2013 at 08:31:36AM +0400, Sergei Ianovich wrote: > > I'm reading the last message as a confirmation that > > drivers/tty/serial/pxa.c needs to be rewritten using 8250_core.c. > > Yes, how much work is this really? Great. It seems two drivers practically match. I'll do and submit a merge patch. ^ permalink raw reply [flat|nested] 36+ messages in thread
[parent not found: <20131205043544.GA28580-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>]
* [PATCH] serial: rewrite pxa2xx-uart to use 8250_core [not found] ` <20131205043544.GA28580-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> @ 2013-12-05 23:28 ` Sergei Ianovich [not found] ` <1386286149-2855-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> ` (3 more replies) 0 siblings, 4 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-05 23:28 UTC (permalink / raw) To: linux-kernel-u79uwXL29TY76Z2rM5mHXA Cc: Sergei Ianovich, Heikki Krogerus, Greg Kroah-Hartman, Russell King, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Ralf Baechle, John Crispin, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... pxa2xx-uart was a separate uart platform driver. It was declaring the same device names and numbers as 8250 driver. As a result, it was impossible to use 8250 driver on PXA SoCs. Upon closer examination pxa2xx-uart turned out to be a clone of 8250_core driver. Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> CC: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> CC: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org> --- arch/arm/configs/am200epdkit_defconfig | 3 +- arch/arm/configs/cm_x2xx_defconfig | 3 +- arch/arm/configs/cm_x300_defconfig | 3 +- arch/arm/configs/colibri_pxa270_defconfig | 3 +- arch/arm/configs/colibri_pxa300_defconfig | 3 +- arch/arm/configs/corgi_defconfig | 4 +- arch/arm/configs/em_x270_defconfig | 3 +- arch/arm/configs/ezx_defconfig | 3 +- arch/arm/configs/h5000_defconfig | 3 +- arch/arm/configs/imote2_defconfig | 3 +- arch/arm/configs/lpd270_defconfig | 3 +- arch/arm/configs/lubbock_defconfig | 3 +- arch/arm/configs/mainstone_defconfig | 3 +- arch/arm/configs/mmp2_defconfig | 3 +- arch/arm/configs/pcm027_defconfig | 3 +- arch/arm/configs/pxa168_defconfig | 3 +- arch/arm/configs/pxa255-idp_defconfig | 3 +- arch/arm/configs/pxa3xx_defconfig | 3 +- arch/arm/configs/pxa910_defconfig | 3 +- arch/arm/configs/raumfeld_defconfig | 3 +- arch/arm/configs/spitz_defconfig | 4 +- arch/arm/configs/trizeps4_defconfig | 3 +- arch/arm/configs/viper_defconfig | 4 +- arch/arm/configs/xcep_defconfig | 3 +- drivers/tty/serial/8250/8250_pxa.c | 180 ++++++ drivers/tty/serial/8250/Kconfig | 9 + drivers/tty/serial/8250/Makefile | 1 + drivers/tty/serial/Kconfig | 23 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/pxa.c | 971 ------------------------------ 30 files changed, 238 insertions(+), 1022 deletions(-) create mode 100644 drivers/tty/serial/8250/8250_pxa.c delete mode 100644 drivers/tty/serial/pxa.c diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig index f0dea52..0cde234 100644 --- a/arch/arm/configs/am200epdkit_defconfig +++ b/arch/arm/configs/am200epdkit_defconfig @@ -60,8 +60,9 @@ CONFIG_BLK_DEV_IDECS=m CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig index a93ff8d..b9fbe65 100644 --- a/arch/arm/configs/cm_x2xx_defconfig +++ b/arch/arm/configs/cm_x2xx_defconfig @@ -96,8 +96,9 @@ CONFIG_KEYBOARD_PXA27x=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=16 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index f4b7672..53a82ae 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -80,8 +80,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m # CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_SERIO is not set # CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_PXA=y diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 2ef2c5e..1ce0409 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig @@ -103,8 +103,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_SERIO_LIBPS2=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig index b985334..f96bda0 100644 --- a/arch/arm/configs/colibri_pxa300_defconfig +++ b/arch/arm/configs/colibri_pxa300_defconfig @@ -31,8 +31,9 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_MISC=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_DEBUG_GPIO=y # CONFIG_HWMON is not set diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 1fd1d1d..bb4842d 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -131,10 +131,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_SERIO is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_I2C=y CONFIG_I2C_PXA=y diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index 60a21e0..ec0ec54 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig @@ -90,8 +90,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m # CONFIG_TOUCHSCREEN_WM9705 is not set # CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=16 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index d95763d..631e2ec 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -215,8 +215,9 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_PCAP=y # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=8 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig index 37903e3..655b735 100644 --- a/arch/arm/configs/h5000_defconfig +++ b/arch/arm/configs/h5000_defconfig @@ -47,8 +47,9 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=32 # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig index fd996bb..49d45e9 100644 --- a/arch/arm/configs/imote2_defconfig +++ b/arch/arm/configs/imote2_defconfig @@ -193,8 +193,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=8 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index 1c8c9ee..c3927b6 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -38,8 +38,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_FB=y CONFIG_FB_PXA=y diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig index c4ba274..c8b0436 100644 --- a/arch/arm/configs/lubbock_defconfig +++ b/arch/arm/configs/lubbock_defconfig @@ -37,8 +37,9 @@ CONFIG_PCMCIA_PCNET=y CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_SA1111=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_VGA_CONSOLE is not set CONFIG_USB_GADGET=y CONFIG_USB_G_SERIAL=m diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig index 04efa1b..768892c 100644 --- a/arch/arm/configs/mainstone_defconfig +++ b/arch/arm/configs/mainstone_defconfig @@ -34,8 +34,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index f1cb95e..1ced9df 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig @@ -44,8 +44,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig index 2f136c3..1280128 100644 --- a/arch/arm/configs/pcm027_defconfig +++ b/arch/arm/configs/pcm027_defconfig @@ -60,8 +60,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig index 74d7e01..1668dac 100644 --- a/arch/arm/configs/pxa168_defconfig +++ b/arch/arm/configs/pxa168_defconfig @@ -40,8 +40,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig index 917a070..399a706 100644 --- a/arch/arm/configs/pxa255-idp_defconfig +++ b/arch/arm/configs/pxa255-idp_defconfig @@ -35,8 +35,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index 60e3138..7c3e052 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig @@ -56,8 +56,9 @@ CONFIG_KEYBOARD_PXA27x=y CONFIG_KEYBOARD_PXA930_ROTARY=y CONFIG_MOUSE_PXA930_TRKBALL=y CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig index 3bb7771..cdacfcb 100644 --- a/arch/arm/configs/pxa910_defconfig +++ b/arch/arm/configs/pxa910_defconfig @@ -40,8 +40,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_SPI=y CONFIG_FB=y CONFIG_MMP_DISP=y diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig index f7caa90..f1e16f2 100644 --- a/arch/arm/configs/raumfeld_defconfig +++ b/arch/arm/configs/raumfeld_defconfig @@ -67,8 +67,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_EETI=m CONFIG_INPUT_MISC=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 2e0419d..b6efcf5 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -128,10 +128,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_SERIO is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_SPI=y CONFIG_SPI_PXA2XX=y diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 3162173..453c79c 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -132,8 +132,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_SERIO_LIBPS2=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index d36e0d3..4efac06 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -101,11 +101,11 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_CONSOLE_TRANSLATIONS is not set # CONFIG_VT_CONSOLE is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=5 CONFIG_SERIAL_8250_RUNTIME_UARTS=5 CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig index 721832f..b67aeaf 100644 --- a/arch/arm/configs/xcep_defconfig +++ b/arch/arm/configs/xcep_defconfig @@ -60,8 +60,9 @@ CONFIG_NET_ETHERNET=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=m diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c new file mode 100644 index 0000000..5658fc9 --- /dev/null +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -0,0 +1,180 @@ +/* + * drivers/tty/serial/8250/8250_pxa.c -- driver for PXA on-board UARTS + * Copyright: (C) 2013 Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> + * + * replaces drivers/serial/pxa.c by Nicolas Pitre + * Created: Feb 20, 2003 + * Copyright: (C) 2003 Monta Vista Software, Inc. + * + * Based on drivers/serial/8250.c by Russell King. + * + * 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/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/serial_8250.h> +#include <linux/serial_core.h> +#include <linux/serial_reg.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/pm_runtime.h> + +#include "8250.h" + +struct pxa8250_data { + int line; + struct clk *clk; +}; + +#ifdef CONFIG_PM +static int serial_pxa_suspend(struct device *dev) +{ + struct pxa8250_data *data = dev_get_drvdata(dev); + + serial8250_suspend_port(data->line); + + return 0; +} + +static int serial_pxa_resume(struct device *dev) +{ + struct pxa8250_data *data = dev_get_drvdata(dev); + + serial8250_resume_port(data->line); + + return 0; +} + +static const struct dev_pm_ops serial_pxa_pm_ops = { + .suspend = serial_pxa_suspend, + .resume = serial_pxa_resume, +}; +#endif + +static struct of_device_id serial_pxa_dt_ids[] = { + { .compatible = "mrvl,pxa-uart", }, + { .compatible = "mrvl,mmp-uart", }, + {} +}; +MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); + +/* Uart divisor latch write */ +static void serial_pxa_dl_write(struct uart_8250_port *up, int value) +{ + serial_out(up, UART_DLL, value & 0xff); + serial_out(up, UART_DLM, value >> 8 & 0xff); +} + + +static void serial_pxa_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct pxa8250_data *data = port->private_data; + + if (!state) + clk_prepare_enable(data->clk); + else + clk_disable_unprepare(data->clk); +} + +static int serial_pxa_probe(struct platform_device *pdev) +{ + struct uart_8250_port uart = {}; + struct pxa8250_data *data; + struct resource *mmres, *irqres; + int ret; + + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mmres || !irqres) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(data->clk)) { + ret = PTR_ERR(data->clk); + goto err_free; + } + + ret = clk_prepare(data->clk); + if (ret) + goto err_free_clk; + + uart.port.type = PORT_XSCALE; + uart.port.iotype = UPIO_MEM32; + uart.port.mapbase = mmres->start; + uart.port.regshift = 2; + uart.port.irq = irqres->start; + uart.port.fifosize = 64; + uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST; + uart.port.dev = &pdev->dev; + uart.port.uartclk = clk_get_rate(data->clk); + uart.port.pm = serial_pxa_pm; + uart.port.private_data = data; + uart.dl_write = serial_pxa_dl_write; + + ret = serial8250_register_8250_port(&uart); + if (ret < 0) + goto err_clk; + + data->line = ret; + + platform_set_drvdata(pdev, data); + + return 0; + + err_clk: + clk_unprepare(data->clk); + err_free_clk: + devm_clk_put(&pdev->dev, data->clk); + err_free: + devm_kfree(&pdev->dev, data); + return ret; +} + +static int serial_pxa_remove(struct platform_device *pdev) +{ + struct pxa8250_data *data = platform_get_drvdata(pdev); + + serial8250_unregister_port(data->line); + + clk_unprepare(data->clk); + devm_clk_put(&pdev->dev, data->clk); + devm_kfree(&pdev->dev, data); + + return 0; +} + +static struct platform_driver serial_pxa_driver = { + .probe = serial_pxa_probe, + .remove = serial_pxa_remove, + + .driver = { + .name = "pxa2xx-uart", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &serial_pxa_pm_ops, +#endif + .of_match_table = serial_pxa_dt_ids, + }, +}; + +module_platform_driver(serial_pxa_driver); + +MODULE_AUTHOR("Sergei Ianovich"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-uart"); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 2332991..81bd7c9 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -302,3 +302,12 @@ config SERIAL_8250_RT288X If you have a Ralink RT288x/RT305x SoC based board and want to use the serial port, say Y to this option. The driver can handle up to 2 serial ports. If unsure, say N. + +config SERIAL_PXA + tristate "PXA serial port support" + depends on SERIAL_8250 && (ARCH_PXA || ARCH_MMP) + help + If you have a machine based on an Intel XScale PXA2xx CPU you + can enable its onboard serial ports by enabling this option. + + If you choose M here, the module name will be 8250_pxa. diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 36d68d0..b7d1b61 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o +obj-$(CONFIG_SERIAL_PXA) += 8250_pxa.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a3817ab..2ad7184b 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -396,29 +396,6 @@ config SERIAL_MPSC_CONSOLE help Say Y here if you want to support a serial console on a Marvell MPSC. -config SERIAL_PXA - bool "PXA serial port support" - depends on ARCH_PXA || ARCH_MMP - select SERIAL_CORE - help - If you have a machine based on an Intel XScale PXA2xx CPU you - can enable its onboard serial ports by enabling this option. - -config SERIAL_PXA_CONSOLE - bool "Console on PXA serial port" - depends on SERIAL_PXA - select SERIAL_CORE_CONSOLE - help - If you have enabled the serial port on the Intel XScale PXA - CPU you can make it the console by answering Y to this option. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttySA0". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - config SERIAL_SA1100 bool "SA1100 serial port support" depends on ARCH_SA1100 diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 3068c77..4ac337b 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_SERIAL_8250) += 8250/ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o -obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c deleted file mode 100644 index f9f20f3..0000000 --- a/drivers/tty/serial/pxa.c +++ /dev/null @@ -1,971 +0,0 @@ -/* - * Based on drivers/serial/8250.c by Russell King. - * - * Author: Nicolas Pitre - * Created: Feb 20, 2003 - * Copyright: (C) 2003 Monta Vista Software, Inc. - * - * 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. - * - * Note 1: This driver is made separate from the already too overloaded - * 8250.c because it needs some kirks of its own and that'll make it - * easier to add DMA support. - * - * Note 2: I'm too sick of device allocation policies for serial ports. - * If someone else wants to request an "official" allocation of major/minor - * for this driver please be my guest. And don't forget that new hardware - * to come from Intel might have more than 3 or 4 of those UARTs. Let's - * hope for a better port registration and dynamic device allocation scheme - * with the serial core maintainer satisfaction to appear soon. - */ - - -#if defined(CONFIG_SERIAL_PXA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include <linux/module.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/sysrq.h> -#include <linux/serial_reg.h> -#include <linux/circ_buf.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial_core.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/slab.h> - -#define PXA_NAME_LEN 8 - -struct uart_pxa_port { - struct uart_port port; - unsigned char ier; - unsigned char lcr; - unsigned char mcr; - unsigned int lsr_break_flag; - struct clk *clk; - char name[PXA_NAME_LEN]; -}; - -static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) -{ - offset <<= 2; - return readl(up->port.membase + offset); -} - -static inline void serial_out(struct uart_pxa_port *up, int offset, int value) -{ - offset <<= 2; - writel(value, up->port.membase + offset); -} - -static void serial_pxa_enable_ms(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - up->ier |= UART_IER_MSI; - serial_out(up, UART_IER, up->ier); -} - -static void serial_pxa_stop_tx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static void serial_pxa_stop_rx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - up->ier &= ~UART_IER_RLSI; - up->port.read_status_mask &= ~UART_LSR_DR; - serial_out(up, UART_IER, up->ier); -} - -static inline void receive_chars(struct uart_pxa_port *up, int *status) -{ - unsigned int ch, flag; - int max_count = 256; - - do { - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 2 - * Disable the Reciever Time Out Interrupt via IER[RTOEI] - */ - up->ier &= ~UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); - - ch = serial_in(up, UART_RX); - flag = TTY_NORMAL; - up->port.icount.rx++; - - if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { - /* - * For statistics only - */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - up->port.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&up->port)) - goto ignore_char; - } else if (*status & UART_LSR_PE) - up->port.icount.parity++; - else if (*status & UART_LSR_FE) - up->port.icount.frame++; - if (*status & UART_LSR_OE) - up->port.icount.overrun++; - - /* - * Mask off conditions which should be ignored. - */ - *status &= up->port.read_status_mask; - -#ifdef CONFIG_SERIAL_PXA_CONSOLE - if (up->port.line == up->port.cons->index) { - /* Recover the break flag from console xmit */ - *status |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif - if (*status & UART_LSR_BI) { - flag = TTY_BREAK; - } else if (*status & UART_LSR_PE) - flag = TTY_PARITY; - else if (*status & UART_LSR_FE) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char(&up->port, ch)) - goto ignore_char; - - uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); - - ignore_char: - *status = serial_in(up, UART_LSR); - } while ((*status & UART_LSR_DR) && (max_count-- > 0)); - tty_flip_buffer_push(&up->port.state->port); - - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 6: - * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE] - */ - up->ier |= UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); -} - -static void transmit_chars(struct uart_pxa_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - int count; - - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_pxa_stop_tx(&up->port); - return; - } - - count = up->port.fifosize / 2; - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - - if (uart_circ_empty(xmit)) - serial_pxa_stop_tx(&up->port); -} - -static void serial_pxa_start_tx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (!(up->ier & UART_IER_THRI)) { - up->ier |= UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static inline void check_modem_status(struct uart_pxa_port *up) -{ - int status; - - status = serial_in(up, UART_MSR); - - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - - if (status & UART_MSR_TERI) - up->port.icount.rng++; - if (status & UART_MSR_DDSR) - up->port.icount.dsr++; - if (status & UART_MSR_DDCD) - uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); - if (status & UART_MSR_DCTS) - uart_handle_cts_change(&up->port, status & UART_MSR_CTS); - - wake_up_interruptible(&up->port.state->port.delta_msr_wait); -} - -/* - * This handles the interrupt from one port. - */ -static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) -{ - struct uart_pxa_port *up = dev_id; - unsigned int iir, lsr; - - iir = serial_in(up, UART_IIR); - if (iir & UART_IIR_NO_INT) - return IRQ_NONE; - lsr = serial_in(up, UART_LSR); - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); - check_modem_status(up); - if (lsr & UART_LSR_THRE) - transmit_chars(up); - return IRQ_HANDLED; -} - -static unsigned int serial_pxa_tx_empty(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret; -} - -static unsigned int serial_pxa_get_mctrl(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char status; - unsigned int ret; - - status = serial_in(up, UART_MSR); - - ret = 0; - if (status & UART_MSR_DCD) - ret |= TIOCM_CAR; - if (status & UART_MSR_RI) - ret |= TIOCM_RNG; - if (status & UART_MSR_DSR) - ret |= TIOCM_DSR; - if (status & UART_MSR_CTS) - ret |= TIOCM_CTS; - return ret; -} - -static void serial_pxa_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char mcr = 0; - - if (mctrl & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (mctrl & TIOCM_DTR) - mcr |= UART_MCR_DTR; - if (mctrl & TIOCM_OUT1) - mcr |= UART_MCR_OUT1; - if (mctrl & TIOCM_OUT2) - mcr |= UART_MCR_OUT2; - if (mctrl & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - - mcr |= up->mcr; - - serial_out(up, UART_MCR, mcr); -} - -static void serial_pxa_break_ctl(struct uart_port *port, int break_state) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - if (break_state == -1) - up->lcr |= UART_LCR_SBC; - else - up->lcr &= ~UART_LCR_SBC; - serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static int serial_pxa_startup(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - int retval; - - if (port->line == 3) /* HWUART */ - up->mcr |= UART_MCR_AFE; - else - up->mcr = 0; - - up->port.uartclk = clk_get_rate(up->clk); - - /* - * Allocate the IRQ - */ - retval = request_irq(up->port.irq, serial_pxa_irq, 0, up->name, up); - if (retval) - return retval; - - /* - * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) - */ - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); - - /* - * Clear the interrupt registers. - */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - /* - * Now, initialize the UART - */ - serial_out(up, UART_LCR, UART_LCR_WLEN8); - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl |= TIOCM_OUT2; - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* - * Finally, enable interrupts. Note: Modem status interrupts - * are set via set_termios(), which will be occurring imminently - * anyway, so we don't enable them here. - */ - up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE; - serial_out(up, UART_IER, up->ier); - - /* - * And clear the interrupt registers again for luck. - */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - return 0; -} - -static void serial_pxa_shutdown(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - - free_irq(up->port.irq, up); - - /* - * Disable interrupts from this port - */ - up->ier = 0; - serial_out(up, UART_IER, 0); - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl &= ~TIOCM_OUT2; - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* - * Disable break condition and FIFOs - */ - serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); -} - -static void -serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char cval, fcr = 0; - unsigned long flags; - unsigned int baud, quot; - unsigned int dll; - - switch (termios->c_cflag & CSIZE) { - case CS5: - cval = UART_LCR_WLEN5; - break; - case CS6: - cval = UART_LCR_WLEN6; - break; - case CS7: - cval = UART_LCR_WLEN7; - break; - default: - case CS8: - cval = UART_LCR_WLEN8; - break; - } - - if (termios->c_cflag & CSTOPB) - cval |= UART_LCR_STOP; - if (termios->c_cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(termios->c_cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - - if ((up->port.uartclk / quot) < (2400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1; - else if ((up->port.uartclk / quot) < (230400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32; - - /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - spin_lock_irqsave(&up->port.lock, flags); - - /* - * Ensure the port will be enabled. - * This is required especially for serial console. - */ - up->ier |= UART_IER_UUE; - - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - - up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (termios->c_iflag & INPCK) - up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (termios->c_iflag & (BRKINT | PARMRK)) - up->port.read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - up->port.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (termios->c_iflag & IGNBRK) { - up->port.ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_OE; - } - - /* - * ignore all characters if CREAD is not set - */ - if ((termios->c_cflag & CREAD) == 0) - up->port.ignore_status_mask |= UART_LSR_DR; - - /* - * CTS flow control flag and modem status interrupts - */ - up->ier &= ~UART_IER_MSI; - if (UART_ENABLE_MS(&up->port, termios->c_cflag)) - up->ier |= UART_IER_MSI; - - serial_out(up, UART_IER, up->ier); - - if (termios->c_cflag & CRTSCTS) - up->mcr |= UART_MCR_AFE; - else - up->mcr &= ~UART_MCR_AFE; - - serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ - serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ - - /* - * work around Errata #75 according to Intel(R) PXA27x Processor Family - * Specification Update (Nov 2005) - */ - dll = serial_in(up, UART_DLL); - WARN_ON(dll != (quot & 0xff)); - - serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ - serial_out(up, UART_LCR, cval); /* reset DLAB */ - up->lcr = cval; /* Save LCR */ - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void -serial_pxa_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (!state) - clk_prepare_enable(up->clk); - else - clk_disable_unprepare(up->clk); -} - -static void serial_pxa_release_port(struct uart_port *port) -{ -} - -static int serial_pxa_request_port(struct uart_port *port) -{ - return 0; -} - -static void serial_pxa_config_port(struct uart_port *port, int flags) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - up->port.type = PORT_PXA; -} - -static int -serial_pxa_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* we don't want the core code to modify any port params */ - return -EINVAL; -} - -static const char * -serial_pxa_type(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - return up->name; -} - -static struct uart_pxa_port *serial_pxa_ports[4]; -static struct uart_driver serial_pxa_reg; - -#ifdef CONFIG_SERIAL_PXA_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct uart_pxa_port *up) -{ - unsigned int status, tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - do { - status = serial_in(up, UART_LSR); - - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - udelay(1); - } while ((status & BOTH_EMPTY) != BOTH_EMPTY); - - /* Wait up to 1s for flow control if necessary */ - if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) - udelay(1); - } -} - -static void serial_pxa_console_putchar(struct uart_port *port, int ch) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void -serial_pxa_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_pxa_port *up = serial_pxa_ports[co->index]; - unsigned int ier; - unsigned long flags; - int locked = 1; - - clk_enable(up->clk); - local_irq_save(flags); - if (up->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); - else - spin_lock(&up->port.lock); - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, UART_IER_UUE); - - uart_console_write(&up->port, s, count, serial_pxa_console_putchar); - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); - clk_disable(up->clk); - -} - -#ifdef CONFIG_CONSOLE_POLL -/* - * Console polling routines for writing and reading from the uart while - * in an interrupt or debug context. - */ - -static int serial_pxa_get_poll_char(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char lsr = serial_in(up, UART_LSR); - - while (!(lsr & UART_LSR_DR)) - lsr = serial_in(up, UART_LSR); - - return serial_in(up, UART_RX); -} - - -static void serial_pxa_put_poll_char(struct uart_port *port, - unsigned char c) -{ - unsigned int ier; - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, UART_IER_UUE); - - wait_for_xmitr(up); - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_out(up, UART_TX, c); - if (c == 10) { - wait_for_xmitr(up); - serial_out(up, UART_TX, 13); - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); -} - -#endif /* CONFIG_CONSOLE_POLL */ - -static int __init -serial_pxa_console_setup(struct console *co, char *options) -{ - struct uart_pxa_port *up; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index == -1 || co->index >= serial_pxa_reg.nr) - co->index = 0; - up = serial_pxa_ports[co->index]; - if (!up) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(&up->port, co, baud, parity, bits, flow); -} - -static struct console serial_pxa_console = { - .name = "ttyS", - .write = serial_pxa_console_write, - .device = uart_console_device, - .setup = serial_pxa_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &serial_pxa_reg, -}; - -#define PXA_CONSOLE &serial_pxa_console -#else -#define PXA_CONSOLE NULL -#endif - -static struct uart_ops serial_pxa_pops = { - .tx_empty = serial_pxa_tx_empty, - .set_mctrl = serial_pxa_set_mctrl, - .get_mctrl = serial_pxa_get_mctrl, - .stop_tx = serial_pxa_stop_tx, - .start_tx = serial_pxa_start_tx, - .stop_rx = serial_pxa_stop_rx, - .enable_ms = serial_pxa_enable_ms, - .break_ctl = serial_pxa_break_ctl, - .startup = serial_pxa_startup, - .shutdown = serial_pxa_shutdown, - .set_termios = serial_pxa_set_termios, - .pm = serial_pxa_pm, - .type = serial_pxa_type, - .release_port = serial_pxa_release_port, - .request_port = serial_pxa_request_port, - .config_port = serial_pxa_config_port, - .verify_port = serial_pxa_verify_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_get_char = serial_pxa_get_poll_char, - .poll_put_char = serial_pxa_put_poll_char, -#endif -}; - -static struct uart_driver serial_pxa_reg = { - .owner = THIS_MODULE, - .driver_name = "PXA serial", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, - .nr = 4, - .cons = PXA_CONSOLE, -}; - -#ifdef CONFIG_PM -static int serial_pxa_suspend(struct device *dev) -{ - struct uart_pxa_port *sport = dev_get_drvdata(dev); - - if (sport) - uart_suspend_port(&serial_pxa_reg, &sport->port); - - return 0; -} - -static int serial_pxa_resume(struct device *dev) -{ - struct uart_pxa_port *sport = dev_get_drvdata(dev); - - if (sport) - uart_resume_port(&serial_pxa_reg, &sport->port); - - return 0; -} - -static const struct dev_pm_ops serial_pxa_pm_ops = { - .suspend = serial_pxa_suspend, - .resume = serial_pxa_resume, -}; -#endif - -static struct of_device_id serial_pxa_dt_ids[] = { - { .compatible = "mrvl,pxa-uart", }, - { .compatible = "mrvl,mmp-uart", }, - {} -}; -MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); - -static int serial_pxa_probe_dt(struct platform_device *pdev, - struct uart_pxa_port *sport) -{ - struct device_node *np = pdev->dev.of_node; - int ret; - - if (!np) - return 1; - - ret = of_alias_get_id(np, "serial"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); - return ret; - } - sport->port.line = ret; - return 0; -} - -static int serial_pxa_probe(struct platform_device *dev) -{ - struct uart_pxa_port *sport; - struct resource *mmres, *irqres; - int ret; - - mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); - irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); - if (!mmres || !irqres) - return -ENODEV; - - sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); - if (!sport) - return -ENOMEM; - - sport->clk = clk_get(&dev->dev, NULL); - if (IS_ERR(sport->clk)) { - ret = PTR_ERR(sport->clk); - goto err_free; - } - - ret = clk_prepare(sport->clk); - if (ret) { - clk_put(sport->clk); - goto err_free; - } - - sport->port.type = PORT_PXA; - sport->port.iotype = UPIO_MEM; - sport->port.mapbase = mmres->start; - sport->port.irq = irqres->start; - sport->port.fifosize = 64; - sport->port.ops = &serial_pxa_pops; - sport->port.dev = &dev->dev; - sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - sport->port.uartclk = clk_get_rate(sport->clk); - - ret = serial_pxa_probe_dt(dev, sport); - if (ret > 0) - sport->port.line = dev->id; - else if (ret < 0) - goto err_clk; - snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1); - - sport->port.membase = ioremap(mmres->start, resource_size(mmres)); - if (!sport->port.membase) { - ret = -ENOMEM; - goto err_clk; - } - - serial_pxa_ports[sport->port.line] = sport; - - uart_add_one_port(&serial_pxa_reg, &sport->port); - platform_set_drvdata(dev, sport); - - return 0; - - err_clk: - clk_unprepare(sport->clk); - clk_put(sport->clk); - err_free: - kfree(sport); - return ret; -} - -static int serial_pxa_remove(struct platform_device *dev) -{ - struct uart_pxa_port *sport = platform_get_drvdata(dev); - - uart_remove_one_port(&serial_pxa_reg, &sport->port); - - clk_unprepare(sport->clk); - clk_put(sport->clk); - kfree(sport); - - return 0; -} - -static struct platform_driver serial_pxa_driver = { - .probe = serial_pxa_probe, - .remove = serial_pxa_remove, - - .driver = { - .name = "pxa2xx-uart", - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &serial_pxa_pm_ops, -#endif - .of_match_table = serial_pxa_dt_ids, - }, -}; - -static int __init serial_pxa_init(void) -{ - int ret; - - ret = uart_register_driver(&serial_pxa_reg); - if (ret != 0) - return ret; - - ret = platform_driver_register(&serial_pxa_driver); - if (ret != 0) - uart_unregister_driver(&serial_pxa_reg); - - return ret; -} - -static void __exit serial_pxa_exit(void) -{ - platform_driver_unregister(&serial_pxa_driver); - uart_unregister_driver(&serial_pxa_reg); -} - -module_init(serial_pxa_init); -module_exit(serial_pxa_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:pxa2xx-uart"); -- 1.8.4.3 -- 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 related [flat|nested] 36+ messages in thread
[parent not found: <1386286149-2855-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core [not found] ` <1386286149-2855-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2013-12-06 0:02 ` Greg Kroah-Hartman [not found] ` <20131206000253.GC21358-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> 0 siblings, 1 reply; 36+ messages in thread From: Greg Kroah-Hartman @ 2013-12-06 0:02 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Heikki Krogerus, Russell King, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Ralf Baechle, John Crispin, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... On Fri, Dec 06, 2013 at 03:28:37AM +0400, Sergei Ianovich wrote: > pxa2xx-uart was a separate uart platform driver. It was declaring > the same device names and numbers as 8250 driver. As a result, > it was impossible to use 8250 driver on PXA SoCs. > > Upon closer examination pxa2xx-uart turned out to be a clone of > 8250_core driver. > > Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > CC: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> > CC: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org> Wonderful! Can someone else test this to verify it works for them on their platform as well? thanks, greg k-h -- 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 [flat|nested] 36+ messages in thread
[parent not found: <20131206000253.GC21358-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core [not found] ` <20131206000253.GC21358-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org> @ 2013-12-06 0:17 ` Russell King - ARM Linux 2013-12-06 9:28 ` Sergei Ianovich 0 siblings, 1 reply; 36+ messages in thread From: Russell King - ARM Linux @ 2013-12-06 0:17 UTC (permalink / raw) To: Greg Kroah-Hartman Cc: Sergei Ianovich, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Heikki Krogerus, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Ralf Baechle, John Crispin, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... On Thu, Dec 05, 2013 at 04:02:53PM -0800, Greg Kroah-Hartman wrote: > On Fri, Dec 06, 2013 at 03:28:37AM +0400, Sergei Ianovich wrote: > > pxa2xx-uart was a separate uart platform driver. It was declaring > > the same device names and numbers as 8250 driver. As a result, > > it was impossible to use 8250 driver on PXA SoCs. > > > > Upon closer examination pxa2xx-uart turned out to be a clone of > > 8250_core driver. > > > > Signed-off-by: Sergei Ianovich <ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > > CC: Heikki Krogerus <heikki.krogerus-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> > > CC: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org> > > Wonderful! > > Can someone else test this to verify it works for them on their platform > as well? I may be able to - one of the downsides though is that many of these systems had hard-coded scripts which started a getty on the original port - and that kind of makes it difficult to sort out. This kind of change becomes very much one of Linus' "flag days". So I'd suggest that we have a period where the old driver is still available, so at least people can choose to use the old major/minor numbers for a while. -- 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 [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 0:17 ` Russell King - ARM Linux @ 2013-12-06 9:28 ` Sergei Ianovich 2013-12-06 9:53 ` James Cameron 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-06 9:28 UTC (permalink / raw) To: Russell King - ARM Linux Cc: Greg Kroah-Hartman, linux-kernel, Heikki Krogerus, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Ralf Baechle, John Crispin, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... On Fri, 2013-12-06 at 00:17 +0000, Russell King - ARM Linux wrote: > I may be able to - one of the downsides though is that many of these > systems had hard-coded scripts which started a getty on the original > port - and that kind of makes it difficult to sort out. This kind of > change becomes very much one of Linus' "flag days". > So I'd suggest that we have a period where the old driver is still > available, so at least people can choose to use the old major/minor > numbers for a while. The patch doesn't change how the driver looks from the outside. The old driver was using 8250 name (ttyS), major (4) and first minor (64). So we only resolve an internal conflict. Kernel configuration is the place where issues may appear, since the patch removes CONFIG_SERIAL_PXA_CONSOLE option. I've updated all in-kernel users. However, out-of-kernel configs will no longer provide serial console, unless manually reconfigured. Is this the case we should worry about? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 9:28 ` Sergei Ianovich @ 2013-12-06 9:53 ` James Cameron 2013-12-06 10:34 ` Sergei Ianovich 0 siblings, 1 reply; 36+ messages in thread From: James Cameron @ 2013-12-06 9:53 UTC (permalink / raw) To: Sergei Ianovich Cc: Russell King - ARM Linux, open list:OPEN FIRMWARE AND..., Heikki Krogerus, Greg Kroah-Hartman, Ralf Baechle, linux-kernel, Rob Herring, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu On Fri, Dec 06, 2013 at 01:28:51PM +0400, Sergei Ianovich wrote: > On Fri, 2013-12-06 at 00:17 +0000, Russell King - ARM Linux wrote: > > > I may be able to - one of the downsides though is that many of these > > systems had hard-coded scripts which started a getty on the original > > port - and that kind of makes it difficult to sort out. This kind of > > change becomes very much one of Linus' "flag days". > > > So I'd suggest that we have a period where the old driver is still > > available, so at least people can choose to use the old major/minor > > numbers for a while. > > The patch doesn't change how the driver looks from the outside. The old > driver was using 8250 name (ttyS), major (4) and first minor (64). So we > only resolve an internal conflict. I don't understand why /dev/ttyS2 (4,66) changed to /dev/ttyS0 (4,64) after the patch was applied to olpc-kernel/arm-3.5 but, as you say it doesn't change, perhaps there is something between 3.5 and now for me to watch out for. My problem. > Kernel configuration is the place where issues may appear, since the > patch removes CONFIG_SERIAL_PXA_CONSOLE option. I've updated all > in-kernel users. However, out-of-kernel configs will no longer provide > serial console, unless manually reconfigured. Is this the case we should > worry about? OLPC holds an out-of-kernel config (xo_4_defconfig); but no, I don't think we'd have trouble with this. Go for it. -- James Cameron http://quozl.linux.org.au/ ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 9:53 ` James Cameron @ 2013-12-06 10:34 ` Sergei Ianovich 2013-12-06 11:05 ` James Cameron 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-06 10:34 UTC (permalink / raw) To: James Cameron Cc: Russell King - ARM Linux, open list:OPEN FIRMWARE AND..., Heikki Krogerus, Greg Kroah-Hartman, Ralf Baechle, linux-kernel, Rob Herring, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu On Fri, 2013-12-06 at 20:53 +1100, James Cameron wrote: > I don't understand why /dev/ttyS2 (4,66) changed to /dev/ttyS0 (4,64) > after the patch was applied to olpc-kernel/arm-3.5 but, as you say it > doesn't change, perhaps there is something between 3.5 and now for me > to watch out for. My problem. The old pxa.c set device ids explicitly: -static int serial_pxa_probe_dt(struct platform_device *pdev, - struct uart_pxa_port *sport) -{ - struct device_node *np = pdev->dev.of_node; - int ret; - - if (!np) - return 1; - - ret = of_alias_get_id(np, "serial"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get alias id, errno %d \n", ret); - return ret; - } - sport->port.line = ret; - return 0; -} and - ret = serial_pxa_probe_dt(dev, sport); - if (ret > 0) - sport->port.line = dev->id; However, this is not possible with 8250_core. The latter assigns device ids strictly in the call order of serial8250_register_8250_port(). Hope it helps. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 10:34 ` Sergei Ianovich @ 2013-12-06 11:05 ` James Cameron 0 siblings, 0 replies; 36+ messages in thread From: James Cameron @ 2013-12-06 11:05 UTC (permalink / raw) To: Sergei Ianovich Cc: Russell King - ARM Linux, open list:OPEN FIRMWARE AND..., Heikki Krogerus, Greg Kroah-Hartman, Ralf Baechle, linux-kernel, Rob Herring, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu On Fri, Dec 06, 2013 at 02:34:17PM +0400, Sergei Ianovich wrote: > On Fri, 2013-12-06 at 20:53 +1100, James Cameron wrote: > > I don't understand why /dev/ttyS2 (4,66) changed to /dev/ttyS0 (4,64) > > after the patch was applied to olpc-kernel/arm-3.5 but, as you say it > > doesn't change, perhaps there is something between 3.5 and now for me > > to watch out for. My problem. > > The old pxa.c set device ids explicitly: > -static int serial_pxa_probe_dt(struct platform_device *pdev, > - struct uart_pxa_port *sport) > -{ > - struct device_node *np = pdev->dev.of_node; > - int ret; > - > - if (!np) > - return 1; > - > - ret = of_alias_get_id(np, "serial"); > - if (ret < 0) { > - dev_err(&pdev->dev, "failed to get alias id, errno %d > \n", ret); > - return ret; > - } > - sport->port.line = ret; > - return 0; > -} > > and > > - ret = serial_pxa_probe_dt(dev, sport); > - if (ret > 0) > - sport->port.line = dev->id; > > > However, this is not possible with 8250_core. The latter assigns device > ids strictly in the call order of serial8250_register_8250_port(). > > Hope it helps. Yes, thanks, that explains it. Your patch deprecates the use of property "linux,unit#" in the device tree for serial ports, or the numbering according to the ordering of the device tree. (On OLPC XO-4, we set the numbering according to the ordering, we don't use "linux,unit#".) It is sad to see device tree sawdust. ;-) -- James Cameron http://quozl.linux.org.au/ ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-05 23:28 ` [PATCH] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich [not found] ` <1386286149-2855-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2013-12-06 0:38 ` James Cameron 2013-12-06 2:55 ` James Cameron 2013-12-06 2:42 ` James Cameron 2013-12-06 9:09 ` [PATCH v2] " Sergei Ianovich 3 siblings, 1 reply; 36+ messages in thread From: James Cameron @ 2013-12-06 0:38 UTC (permalink / raw) To: Sergei Ianovich Cc: open list:OPEN FIRMWARE AND..., Heikki Krogerus, Russell King, Greg Kroah-Hartman, linux-kernel, Ralf Baechle, Haojian Zhuang, Rob Herring, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, Zhou Zhu, Jiri Slaby, moderated list:ARM PORT, John Crispin On Fri, Dec 06, 2013 at 03:28:37AM +0400, Sergei Ianovich wrote: > pxa2xx-uart was a separate uart platform driver. It was declaring > the same device names and numbers as 8250 driver. As a result, > it was impossible to use 8250 driver on PXA SoCs. > > Upon closer examination pxa2xx-uart turned out to be a clone of > 8250_core driver. I'm testing this backported to 3.5 on the OLPC XO-4 [1] [2]. As Russell says, the getty had to change, but after that the shell worked fine; no more or no less responsive. What hasn't worked yet is the console; no kernel messages appear. I have tried changing command line to console=ttyS0,115200. 1. http://dev.laptop.org/~quozl/y/1VojGn.txt (diff relative to olpc-kernel/arm-3.5) 2. http://dev.laptop.org/~quozl/z/1VojLz.txt (dmesg) -- James Cameron http://quozl.linux.org.au/ ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 0:38 ` James Cameron @ 2013-12-06 2:55 ` James Cameron 0 siblings, 0 replies; 36+ messages in thread From: James Cameron @ 2013-12-06 2:55 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, open list:OPEN FIRMWARE AND..., Heikki Krogerus, Russell King, Greg Kroah-Hartman, Ralf Baechle, Rob Herring, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu On Fri, Dec 06, 2013 at 11:38:51AM +1100, James Cameron wrote: > On Fri, Dec 06, 2013 at 03:28:37AM +0400, Sergei Ianovich wrote: > > pxa2xx-uart was a separate uart platform driver. It was declaring > > the same device names and numbers as 8250 driver. As a result, > > it was impossible to use 8250 driver on PXA SoCs. > > > > Upon closer examination pxa2xx-uart turned out to be a clone of > > 8250_core driver. > > I'm testing this backported to 3.5 on the OLPC XO-4 [1] [2]. > > As Russell says, the getty had to change, but after that the shell > worked fine; no more or no less responsive. > > What hasn't worked yet is the console; no kernel messages appear. I > have tried changing command line to console=ttyS0,115200. My error. Our kernel had CONFIG_CMDLINE set, changing that fixed it. Console is working fine. -- James Cameron http://quozl.linux.org.au/ ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-05 23:28 ` [PATCH] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich [not found] ` <1386286149-2855-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2013-12-06 0:38 ` James Cameron @ 2013-12-06 2:42 ` James Cameron 2013-12-06 9:16 ` Sergei Ianovich 2013-12-06 9:09 ` [PATCH v2] " Sergei Ianovich 3 siblings, 1 reply; 36+ messages in thread From: James Cameron @ 2013-12-06 2:42 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, open list:OPEN FIRMWARE AND..., Heikki Krogerus, Russell King, Greg Kroah-Hartman, Ralf Baechle, Rob Herring, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu On Fri, Dec 06, 2013 at 03:28:37AM +0400, Sergei Ianovich wrote: > pxa2xx-uart was a separate uart platform driver. It was declaring > the same device names and numbers as 8250 driver. As a result, > it was impossible to use 8250 driver on PXA SoCs. > > Upon closer examination pxa2xx-uart turned out to be a clone of > 8250_core driver. [...] > +/* Uart divisor latch write */ > +static void serial_pxa_dl_write(struct uart_8250_port *up, int value) > +{ > + serial_out(up, UART_DLL, value & 0xff); > + serial_out(up, UART_DLM, value >> 8 & 0xff); > +} This is a change. drivers/tty/serial/pxa.c did read back UART_DLL as an errata work around: > - /* > - * work around Errata #75 according to Intel(R) PXA27x Processor Family > - * Specification Update (Nov 2005) > - */ > - dll = serial_in(up, UART_DLL); > - WARN_ON(dll != (quot & 0xff)); If this is no longer needed, serial_pxa_dl_write can be removed because it is same as default_serial_dl_write. I did not check the other errata work arounds. -- James Cameron http://quozl.linux.org.au/ ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 2:42 ` James Cameron @ 2013-12-06 9:16 ` Sergei Ianovich 0 siblings, 0 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-06 9:16 UTC (permalink / raw) To: James Cameron Cc: linux-kernel, open list:OPEN FIRMWARE AND..., Heikki Krogerus, Russell King, Greg Kroah-Hartman, Ralf Baechle, Rob Herring, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu On Fri, 2013-12-06 at 13:42 +1100, James Cameron wrote: > On Fri, Dec 06, 2013 at 03:28:37AM +0400, Sergei Ianovich wrote: > > +/* Uart divisor latch write */ > > +static void serial_pxa_dl_write(struct uart_8250_port *up, int value) > > +{ > > + serial_out(up, UART_DLL, value & 0xff); > > + serial_out(up, UART_DLM, value >> 8 & 0xff); > > +} > > This is a change. drivers/tty/serial/pxa.c did read back UART_DLL as > an errata work around: > > > - /* > > - * work around Errata #75 according to Intel(R) PXA27x Processor Family > > - * Specification Update (Nov 2005) > > - */ > > - dll = serial_in(up, UART_DLL); > > - WARN_ON(dll != (quot & 0xff)); > > If this is no longer needed, serial_pxa_dl_write can be removed > because it is same as default_serial_dl_write. Thanks for spotting this. I prepared infrastructure, but the tests never failed so I never returned here. I've filed v2 with correct dl_write. > I did not check the other errata work arounds. I've intentionally dropped workaround for E20 from old pxa.c receive_chars(). 8250_core reads FIFO immediately after it checks DR bit in LSR, so that issue never happens. New version states this in commit message. ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v2] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-05 23:28 ` [PATCH] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich ` (2 preceding siblings ...) 2013-12-06 2:42 ` James Cameron @ 2013-12-06 9:09 ` Sergei Ianovich 2013-12-06 9:28 ` James Cameron ` (2 more replies) 3 siblings, 3 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-06 9:09 UTC (permalink / raw) To: linux-kernel Cc: Sergei Ianovich, Heikki Krogerus, Greg Kroah-Hartman, James Cameron, Russell King, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Stefan Seyfried, John Crispin, Paul Bolle, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... pxa2xx-uart was a separate uart platform driver. It was declaring the same device names and numbers as 8250 driver. As a result, it was impossible to use 8250 driver on PXA SoCs. Upon closer examination pxa2xx-uart turned out to be a clone of 8250_core driver. Workaround for Erratum #19 according to Marvel(R) PXA270M Processor Specification Update (April 19, 2010) is dropped. 8250_core reads from FIFO immediately after checking DR bit in LSR. Signed-off-by: Sergei Ianovich <ynvich@gmail.com> CC: Heikki Krogerus <heikki.krogerus@linux.intel.com> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> CC: James Cameron <quozl@laptop.org> --- changes v1..v2 * actually implement workaround for E74 in dl_write as spooted by James Cameron * added comment about E19 in commit message arch/arm/configs/am200epdkit_defconfig | 3 +- arch/arm/configs/cm_x2xx_defconfig | 3 +- arch/arm/configs/cm_x300_defconfig | 3 +- arch/arm/configs/colibri_pxa270_defconfig | 3 +- arch/arm/configs/colibri_pxa300_defconfig | 3 +- arch/arm/configs/corgi_defconfig | 4 +- arch/arm/configs/em_x270_defconfig | 3 +- arch/arm/configs/ezx_defconfig | 3 +- arch/arm/configs/h5000_defconfig | 3 +- arch/arm/configs/imote2_defconfig | 3 +- arch/arm/configs/lpd270_defconfig | 3 +- arch/arm/configs/lubbock_defconfig | 3 +- arch/arm/configs/mainstone_defconfig | 3 +- arch/arm/configs/mmp2_defconfig | 3 +- arch/arm/configs/pcm027_defconfig | 3 +- arch/arm/configs/pxa168_defconfig | 3 +- arch/arm/configs/pxa255-idp_defconfig | 3 +- arch/arm/configs/pxa3xx_defconfig | 3 +- arch/arm/configs/pxa910_defconfig | 3 +- arch/arm/configs/raumfeld_defconfig | 3 +- arch/arm/configs/spitz_defconfig | 4 +- arch/arm/configs/trizeps4_defconfig | 3 +- arch/arm/configs/viper_defconfig | 4 +- arch/arm/configs/xcep_defconfig | 3 +- drivers/tty/serial/8250/8250_pxa.c | 189 ++++++ drivers/tty/serial/8250/Kconfig | 9 + drivers/tty/serial/8250/Makefile | 1 + drivers/tty/serial/Kconfig | 23 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/pxa.c | 971 ------------------------------ 30 files changed, 247 insertions(+), 1022 deletions(-) create mode 100644 drivers/tty/serial/8250/8250_pxa.c delete mode 100644 drivers/tty/serial/pxa.c diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig index f0dea52..0cde234 100644 --- a/arch/arm/configs/am200epdkit_defconfig +++ b/arch/arm/configs/am200epdkit_defconfig @@ -60,8 +60,9 @@ CONFIG_BLK_DEV_IDECS=m CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig index a93ff8d..b9fbe65 100644 --- a/arch/arm/configs/cm_x2xx_defconfig +++ b/arch/arm/configs/cm_x2xx_defconfig @@ -96,8 +96,9 @@ CONFIG_KEYBOARD_PXA27x=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=16 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index f4b7672..53a82ae 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -80,8 +80,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m # CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_SERIO is not set # CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_PXA=y diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 2ef2c5e..1ce0409 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig @@ -103,8 +103,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_SERIO_LIBPS2=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig index b985334..f96bda0 100644 --- a/arch/arm/configs/colibri_pxa300_defconfig +++ b/arch/arm/configs/colibri_pxa300_defconfig @@ -31,8 +31,9 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_MISC=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_DEBUG_GPIO=y # CONFIG_HWMON is not set diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 1fd1d1d..bb4842d 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -131,10 +131,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_SERIO is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_I2C=y CONFIG_I2C_PXA=y diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index 60a21e0..ec0ec54 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig @@ -90,8 +90,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m # CONFIG_TOUCHSCREEN_WM9705 is not set # CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=16 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index d95763d..631e2ec 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -215,8 +215,9 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_PCAP=y # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=8 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig index 37903e3..655b735 100644 --- a/arch/arm/configs/h5000_defconfig +++ b/arch/arm/configs/h5000_defconfig @@ -47,8 +47,9 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=32 # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig index fd996bb..49d45e9 100644 --- a/arch/arm/configs/imote2_defconfig +++ b/arch/arm/configs/imote2_defconfig @@ -193,8 +193,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=8 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index 1c8c9ee..c3927b6 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -38,8 +38,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_FB=y CONFIG_FB_PXA=y diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig index c4ba274..c8b0436 100644 --- a/arch/arm/configs/lubbock_defconfig +++ b/arch/arm/configs/lubbock_defconfig @@ -37,8 +37,9 @@ CONFIG_PCMCIA_PCNET=y CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_SA1111=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_VGA_CONSOLE is not set CONFIG_USB_GADGET=y CONFIG_USB_G_SERIAL=m diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig index 04efa1b..768892c 100644 --- a/arch/arm/configs/mainstone_defconfig +++ b/arch/arm/configs/mainstone_defconfig @@ -34,8 +34,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index f1cb95e..1ced9df 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig @@ -44,8 +44,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig index 2f136c3..1280128 100644 --- a/arch/arm/configs/pcm027_defconfig +++ b/arch/arm/configs/pcm027_defconfig @@ -60,8 +60,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig index 74d7e01..1668dac 100644 --- a/arch/arm/configs/pxa168_defconfig +++ b/arch/arm/configs/pxa168_defconfig @@ -40,8 +40,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig index 917a070..399a706 100644 --- a/arch/arm/configs/pxa255-idp_defconfig +++ b/arch/arm/configs/pxa255-idp_defconfig @@ -35,8 +35,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index 60e3138..7c3e052 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig @@ -56,8 +56,9 @@ CONFIG_KEYBOARD_PXA27x=y CONFIG_KEYBOARD_PXA930_ROTARY=y CONFIG_MOUSE_PXA930_TRKBALL=y CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig index 3bb7771..cdacfcb 100644 --- a/arch/arm/configs/pxa910_defconfig +++ b/arch/arm/configs/pxa910_defconfig @@ -40,8 +40,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_SPI=y CONFIG_FB=y CONFIG_MMP_DISP=y diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig index f7caa90..f1e16f2 100644 --- a/arch/arm/configs/raumfeld_defconfig +++ b/arch/arm/configs/raumfeld_defconfig @@ -67,8 +67,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_EETI=m CONFIG_INPUT_MISC=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 2e0419d..b6efcf5 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -128,10 +128,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_SERIO is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_SPI=y CONFIG_SPI_PXA2XX=y diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 3162173..453c79c 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -132,8 +132,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_SERIO_LIBPS2=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index d36e0d3..4efac06 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -101,11 +101,11 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_CONSOLE_TRANSLATIONS is not set # CONFIG_VT_CONSOLE is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=5 CONFIG_SERIAL_8250_RUNTIME_UARTS=5 CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig index 721832f..b67aeaf 100644 --- a/arch/arm/configs/xcep_defconfig +++ b/arch/arm/configs/xcep_defconfig @@ -60,8 +60,9 @@ CONFIG_NET_ETHERNET=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=m diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c new file mode 100644 index 0000000..88ae73c --- /dev/null +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -0,0 +1,189 @@ +/* + * drivers/tty/serial/8250/8250_pxa.c -- driver for PXA on-board UARTS + * Copyright: (C) 2013 Sergei Ianovich <ynvich@gmail.com> + * + * replaces drivers/serial/pxa.c by Nicolas Pitre + * Created: Feb 20, 2003 + * Copyright: (C) 2003 Monta Vista Software, Inc. + * + * Based on drivers/serial/8250.c by Russell King. + * + * 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/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/serial_8250.h> +#include <linux/serial_core.h> +#include <linux/serial_reg.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/pm_runtime.h> + +#include "8250.h" + +struct pxa8250_data { + int line; + struct clk *clk; +}; + +#ifdef CONFIG_PM +static int serial_pxa_suspend(struct device *dev) +{ + struct pxa8250_data *data = dev_get_drvdata(dev); + + serial8250_suspend_port(data->line); + + return 0; +} + +static int serial_pxa_resume(struct device *dev) +{ + struct pxa8250_data *data = dev_get_drvdata(dev); + + serial8250_resume_port(data->line); + + return 0; +} + +static const struct dev_pm_ops serial_pxa_pm_ops = { + .suspend = serial_pxa_suspend, + .resume = serial_pxa_resume, +}; +#endif + +static struct of_device_id serial_pxa_dt_ids[] = { + { .compatible = "mrvl,pxa-uart", }, + { .compatible = "mrvl,mmp-uart", }, + {} +}; +MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); + +/* Uart divisor latch write */ +static void serial_pxa_dl_write(struct uart_8250_port *up, int value) +{ + unsigned int dll; + + serial_out(up, UART_DLL, value & 0xff); + /* + * work around Erratum #74 according to Marvel(R) PXA270M Processor + * Specification Update (April 19, 2010) + */ + dll = serial_in(up, UART_DLL); + WARN_ON(dll != (value & 0xff)); + + serial_out(up, UART_DLM, value >> 8 & 0xff); +} + + +static void serial_pxa_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct pxa8250_data *data = port->private_data; + + if (!state) + clk_prepare_enable(data->clk); + else + clk_disable_unprepare(data->clk); +} + +static int serial_pxa_probe(struct platform_device *pdev) +{ + struct uart_8250_port uart = {}; + struct pxa8250_data *data; + struct resource *mmres, *irqres; + int ret; + + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mmres || !irqres) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(data->clk)) { + ret = PTR_ERR(data->clk); + goto err_free; + } + + ret = clk_prepare(data->clk); + if (ret) + goto err_free_clk; + + uart.port.type = PORT_XSCALE; + uart.port.iotype = UPIO_MEM32; + uart.port.mapbase = mmres->start; + uart.port.regshift = 2; + uart.port.irq = irqres->start; + uart.port.fifosize = 64; + uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST; + uart.port.dev = &pdev->dev; + uart.port.uartclk = clk_get_rate(data->clk); + uart.port.pm = serial_pxa_pm; + uart.port.private_data = data; + uart.dl_write = serial_pxa_dl_write; + + ret = serial8250_register_8250_port(&uart); + if (ret < 0) + goto err_clk; + + data->line = ret; + + platform_set_drvdata(pdev, data); + + return 0; + + err_clk: + clk_unprepare(data->clk); + err_free_clk: + devm_clk_put(&pdev->dev, data->clk); + err_free: + devm_kfree(&pdev->dev, data); + return ret; +} + +static int serial_pxa_remove(struct platform_device *pdev) +{ + struct pxa8250_data *data = platform_get_drvdata(pdev); + + serial8250_unregister_port(data->line); + + clk_unprepare(data->clk); + devm_clk_put(&pdev->dev, data->clk); + devm_kfree(&pdev->dev, data); + + return 0; +} + +static struct platform_driver serial_pxa_driver = { + .probe = serial_pxa_probe, + .remove = serial_pxa_remove, + + .driver = { + .name = "pxa2xx-uart", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &serial_pxa_pm_ops, +#endif + .of_match_table = serial_pxa_dt_ids, + }, +}; + +module_platform_driver(serial_pxa_driver); + +MODULE_AUTHOR("Sergei Ianovich"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-uart"); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 2332991..81bd7c9 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -302,3 +302,12 @@ config SERIAL_8250_RT288X If you have a Ralink RT288x/RT305x SoC based board and want to use the serial port, say Y to this option. The driver can handle up to 2 serial ports. If unsure, say N. + +config SERIAL_PXA + tristate "PXA serial port support" + depends on SERIAL_8250 && (ARCH_PXA || ARCH_MMP) + help + If you have a machine based on an Intel XScale PXA2xx CPU you + can enable its onboard serial ports by enabling this option. + + If you choose M here, the module name will be 8250_pxa. diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 36d68d0..b7d1b61 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o +obj-$(CONFIG_SERIAL_PXA) += 8250_pxa.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a3817ab..2ad7184b 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -396,29 +396,6 @@ config SERIAL_MPSC_CONSOLE help Say Y here if you want to support a serial console on a Marvell MPSC. -config SERIAL_PXA - bool "PXA serial port support" - depends on ARCH_PXA || ARCH_MMP - select SERIAL_CORE - help - If you have a machine based on an Intel XScale PXA2xx CPU you - can enable its onboard serial ports by enabling this option. - -config SERIAL_PXA_CONSOLE - bool "Console on PXA serial port" - depends on SERIAL_PXA - select SERIAL_CORE_CONSOLE - help - If you have enabled the serial port on the Intel XScale PXA - CPU you can make it the console by answering Y to this option. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttySA0". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - config SERIAL_SA1100 bool "SA1100 serial port support" depends on ARCH_SA1100 diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 3068c77..4ac337b 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_SERIAL_8250) += 8250/ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o -obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c deleted file mode 100644 index f9f20f3..0000000 --- a/drivers/tty/serial/pxa.c +++ /dev/null @@ -1,971 +0,0 @@ -/* - * Based on drivers/serial/8250.c by Russell King. - * - * Author: Nicolas Pitre - * Created: Feb 20, 2003 - * Copyright: (C) 2003 Monta Vista Software, Inc. - * - * 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. - * - * Note 1: This driver is made separate from the already too overloaded - * 8250.c because it needs some kirks of its own and that'll make it - * easier to add DMA support. - * - * Note 2: I'm too sick of device allocation policies for serial ports. - * If someone else wants to request an "official" allocation of major/minor - * for this driver please be my guest. And don't forget that new hardware - * to come from Intel might have more than 3 or 4 of those UARTs. Let's - * hope for a better port registration and dynamic device allocation scheme - * with the serial core maintainer satisfaction to appear soon. - */ - - -#if defined(CONFIG_SERIAL_PXA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include <linux/module.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/sysrq.h> -#include <linux/serial_reg.h> -#include <linux/circ_buf.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial_core.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/slab.h> - -#define PXA_NAME_LEN 8 - -struct uart_pxa_port { - struct uart_port port; - unsigned char ier; - unsigned char lcr; - unsigned char mcr; - unsigned int lsr_break_flag; - struct clk *clk; - char name[PXA_NAME_LEN]; -}; - -static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) -{ - offset <<= 2; - return readl(up->port.membase + offset); -} - -static inline void serial_out(struct uart_pxa_port *up, int offset, int value) -{ - offset <<= 2; - writel(value, up->port.membase + offset); -} - -static void serial_pxa_enable_ms(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - up->ier |= UART_IER_MSI; - serial_out(up, UART_IER, up->ier); -} - -static void serial_pxa_stop_tx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static void serial_pxa_stop_rx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - up->ier &= ~UART_IER_RLSI; - up->port.read_status_mask &= ~UART_LSR_DR; - serial_out(up, UART_IER, up->ier); -} - -static inline void receive_chars(struct uart_pxa_port *up, int *status) -{ - unsigned int ch, flag; - int max_count = 256; - - do { - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 2 - * Disable the Reciever Time Out Interrupt via IER[RTOEI] - */ - up->ier &= ~UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); - - ch = serial_in(up, UART_RX); - flag = TTY_NORMAL; - up->port.icount.rx++; - - if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { - /* - * For statistics only - */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - up->port.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&up->port)) - goto ignore_char; - } else if (*status & UART_LSR_PE) - up->port.icount.parity++; - else if (*status & UART_LSR_FE) - up->port.icount.frame++; - if (*status & UART_LSR_OE) - up->port.icount.overrun++; - - /* - * Mask off conditions which should be ignored. - */ - *status &= up->port.read_status_mask; - -#ifdef CONFIG_SERIAL_PXA_CONSOLE - if (up->port.line == up->port.cons->index) { - /* Recover the break flag from console xmit */ - *status |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif - if (*status & UART_LSR_BI) { - flag = TTY_BREAK; - } else if (*status & UART_LSR_PE) - flag = TTY_PARITY; - else if (*status & UART_LSR_FE) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char(&up->port, ch)) - goto ignore_char; - - uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); - - ignore_char: - *status = serial_in(up, UART_LSR); - } while ((*status & UART_LSR_DR) && (max_count-- > 0)); - tty_flip_buffer_push(&up->port.state->port); - - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 6: - * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE] - */ - up->ier |= UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); -} - -static void transmit_chars(struct uart_pxa_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - int count; - - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_pxa_stop_tx(&up->port); - return; - } - - count = up->port.fifosize / 2; - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - - if (uart_circ_empty(xmit)) - serial_pxa_stop_tx(&up->port); -} - -static void serial_pxa_start_tx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (!(up->ier & UART_IER_THRI)) { - up->ier |= UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static inline void check_modem_status(struct uart_pxa_port *up) -{ - int status; - - status = serial_in(up, UART_MSR); - - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - - if (status & UART_MSR_TERI) - up->port.icount.rng++; - if (status & UART_MSR_DDSR) - up->port.icount.dsr++; - if (status & UART_MSR_DDCD) - uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); - if (status & UART_MSR_DCTS) - uart_handle_cts_change(&up->port, status & UART_MSR_CTS); - - wake_up_interruptible(&up->port.state->port.delta_msr_wait); -} - -/* - * This handles the interrupt from one port. - */ -static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) -{ - struct uart_pxa_port *up = dev_id; - unsigned int iir, lsr; - - iir = serial_in(up, UART_IIR); - if (iir & UART_IIR_NO_INT) - return IRQ_NONE; - lsr = serial_in(up, UART_LSR); - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); - check_modem_status(up); - if (lsr & UART_LSR_THRE) - transmit_chars(up); - return IRQ_HANDLED; -} - -static unsigned int serial_pxa_tx_empty(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret; -} - -static unsigned int serial_pxa_get_mctrl(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char status; - unsigned int ret; - - status = serial_in(up, UART_MSR); - - ret = 0; - if (status & UART_MSR_DCD) - ret |= TIOCM_CAR; - if (status & UART_MSR_RI) - ret |= TIOCM_RNG; - if (status & UART_MSR_DSR) - ret |= TIOCM_DSR; - if (status & UART_MSR_CTS) - ret |= TIOCM_CTS; - return ret; -} - -static void serial_pxa_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char mcr = 0; - - if (mctrl & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (mctrl & TIOCM_DTR) - mcr |= UART_MCR_DTR; - if (mctrl & TIOCM_OUT1) - mcr |= UART_MCR_OUT1; - if (mctrl & TIOCM_OUT2) - mcr |= UART_MCR_OUT2; - if (mctrl & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - - mcr |= up->mcr; - - serial_out(up, UART_MCR, mcr); -} - -static void serial_pxa_break_ctl(struct uart_port *port, int break_state) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - if (break_state == -1) - up->lcr |= UART_LCR_SBC; - else - up->lcr &= ~UART_LCR_SBC; - serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static int serial_pxa_startup(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - int retval; - - if (port->line == 3) /* HWUART */ - up->mcr |= UART_MCR_AFE; - else - up->mcr = 0; - - up->port.uartclk = clk_get_rate(up->clk); - - /* - * Allocate the IRQ - */ - retval = request_irq(up->port.irq, serial_pxa_irq, 0, up->name, up); - if (retval) - return retval; - - /* - * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) - */ - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); - - /* - * Clear the interrupt registers. - */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - /* - * Now, initialize the UART - */ - serial_out(up, UART_LCR, UART_LCR_WLEN8); - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl |= TIOCM_OUT2; - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* - * Finally, enable interrupts. Note: Modem status interrupts - * are set via set_termios(), which will be occurring imminently - * anyway, so we don't enable them here. - */ - up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE; - serial_out(up, UART_IER, up->ier); - - /* - * And clear the interrupt registers again for luck. - */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - return 0; -} - -static void serial_pxa_shutdown(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - - free_irq(up->port.irq, up); - - /* - * Disable interrupts from this port - */ - up->ier = 0; - serial_out(up, UART_IER, 0); - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl &= ~TIOCM_OUT2; - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* - * Disable break condition and FIFOs - */ - serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); -} - -static void -serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char cval, fcr = 0; - unsigned long flags; - unsigned int baud, quot; - unsigned int dll; - - switch (termios->c_cflag & CSIZE) { - case CS5: - cval = UART_LCR_WLEN5; - break; - case CS6: - cval = UART_LCR_WLEN6; - break; - case CS7: - cval = UART_LCR_WLEN7; - break; - default: - case CS8: - cval = UART_LCR_WLEN8; - break; - } - - if (termios->c_cflag & CSTOPB) - cval |= UART_LCR_STOP; - if (termios->c_cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(termios->c_cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - - if ((up->port.uartclk / quot) < (2400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1; - else if ((up->port.uartclk / quot) < (230400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32; - - /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - spin_lock_irqsave(&up->port.lock, flags); - - /* - * Ensure the port will be enabled. - * This is required especially for serial console. - */ - up->ier |= UART_IER_UUE; - - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - - up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (termios->c_iflag & INPCK) - up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (termios->c_iflag & (BRKINT | PARMRK)) - up->port.read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - up->port.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (termios->c_iflag & IGNBRK) { - up->port.ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_OE; - } - - /* - * ignore all characters if CREAD is not set - */ - if ((termios->c_cflag & CREAD) == 0) - up->port.ignore_status_mask |= UART_LSR_DR; - - /* - * CTS flow control flag and modem status interrupts - */ - up->ier &= ~UART_IER_MSI; - if (UART_ENABLE_MS(&up->port, termios->c_cflag)) - up->ier |= UART_IER_MSI; - - serial_out(up, UART_IER, up->ier); - - if (termios->c_cflag & CRTSCTS) - up->mcr |= UART_MCR_AFE; - else - up->mcr &= ~UART_MCR_AFE; - - serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ - serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ - - /* - * work around Errata #75 according to Intel(R) PXA27x Processor Family - * Specification Update (Nov 2005) - */ - dll = serial_in(up, UART_DLL); - WARN_ON(dll != (quot & 0xff)); - - serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ - serial_out(up, UART_LCR, cval); /* reset DLAB */ - up->lcr = cval; /* Save LCR */ - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void -serial_pxa_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (!state) - clk_prepare_enable(up->clk); - else - clk_disable_unprepare(up->clk); -} - -static void serial_pxa_release_port(struct uart_port *port) -{ -} - -static int serial_pxa_request_port(struct uart_port *port) -{ - return 0; -} - -static void serial_pxa_config_port(struct uart_port *port, int flags) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - up->port.type = PORT_PXA; -} - -static int -serial_pxa_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* we don't want the core code to modify any port params */ - return -EINVAL; -} - -static const char * -serial_pxa_type(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - return up->name; -} - -static struct uart_pxa_port *serial_pxa_ports[4]; -static struct uart_driver serial_pxa_reg; - -#ifdef CONFIG_SERIAL_PXA_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct uart_pxa_port *up) -{ - unsigned int status, tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - do { - status = serial_in(up, UART_LSR); - - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - udelay(1); - } while ((status & BOTH_EMPTY) != BOTH_EMPTY); - - /* Wait up to 1s for flow control if necessary */ - if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) - udelay(1); - } -} - -static void serial_pxa_console_putchar(struct uart_port *port, int ch) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void -serial_pxa_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_pxa_port *up = serial_pxa_ports[co->index]; - unsigned int ier; - unsigned long flags; - int locked = 1; - - clk_enable(up->clk); - local_irq_save(flags); - if (up->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); - else - spin_lock(&up->port.lock); - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, UART_IER_UUE); - - uart_console_write(&up->port, s, count, serial_pxa_console_putchar); - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); - clk_disable(up->clk); - -} - -#ifdef CONFIG_CONSOLE_POLL -/* - * Console polling routines for writing and reading from the uart while - * in an interrupt or debug context. - */ - -static int serial_pxa_get_poll_char(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char lsr = serial_in(up, UART_LSR); - - while (!(lsr & UART_LSR_DR)) - lsr = serial_in(up, UART_LSR); - - return serial_in(up, UART_RX); -} - - -static void serial_pxa_put_poll_char(struct uart_port *port, - unsigned char c) -{ - unsigned int ier; - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, UART_IER_UUE); - - wait_for_xmitr(up); - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_out(up, UART_TX, c); - if (c == 10) { - wait_for_xmitr(up); - serial_out(up, UART_TX, 13); - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); -} - -#endif /* CONFIG_CONSOLE_POLL */ - -static int __init -serial_pxa_console_setup(struct console *co, char *options) -{ - struct uart_pxa_port *up; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index == -1 || co->index >= serial_pxa_reg.nr) - co->index = 0; - up = serial_pxa_ports[co->index]; - if (!up) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(&up->port, co, baud, parity, bits, flow); -} - -static struct console serial_pxa_console = { - .name = "ttyS", - .write = serial_pxa_console_write, - .device = uart_console_device, - .setup = serial_pxa_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &serial_pxa_reg, -}; - -#define PXA_CONSOLE &serial_pxa_console -#else -#define PXA_CONSOLE NULL -#endif - -static struct uart_ops serial_pxa_pops = { - .tx_empty = serial_pxa_tx_empty, - .set_mctrl = serial_pxa_set_mctrl, - .get_mctrl = serial_pxa_get_mctrl, - .stop_tx = serial_pxa_stop_tx, - .start_tx = serial_pxa_start_tx, - .stop_rx = serial_pxa_stop_rx, - .enable_ms = serial_pxa_enable_ms, - .break_ctl = serial_pxa_break_ctl, - .startup = serial_pxa_startup, - .shutdown = serial_pxa_shutdown, - .set_termios = serial_pxa_set_termios, - .pm = serial_pxa_pm, - .type = serial_pxa_type, - .release_port = serial_pxa_release_port, - .request_port = serial_pxa_request_port, - .config_port = serial_pxa_config_port, - .verify_port = serial_pxa_verify_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_get_char = serial_pxa_get_poll_char, - .poll_put_char = serial_pxa_put_poll_char, -#endif -}; - -static struct uart_driver serial_pxa_reg = { - .owner = THIS_MODULE, - .driver_name = "PXA serial", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, - .nr = 4, - .cons = PXA_CONSOLE, -}; - -#ifdef CONFIG_PM -static int serial_pxa_suspend(struct device *dev) -{ - struct uart_pxa_port *sport = dev_get_drvdata(dev); - - if (sport) - uart_suspend_port(&serial_pxa_reg, &sport->port); - - return 0; -} - -static int serial_pxa_resume(struct device *dev) -{ - struct uart_pxa_port *sport = dev_get_drvdata(dev); - - if (sport) - uart_resume_port(&serial_pxa_reg, &sport->port); - - return 0; -} - -static const struct dev_pm_ops serial_pxa_pm_ops = { - .suspend = serial_pxa_suspend, - .resume = serial_pxa_resume, -}; -#endif - -static struct of_device_id serial_pxa_dt_ids[] = { - { .compatible = "mrvl,pxa-uart", }, - { .compatible = "mrvl,mmp-uart", }, - {} -}; -MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); - -static int serial_pxa_probe_dt(struct platform_device *pdev, - struct uart_pxa_port *sport) -{ - struct device_node *np = pdev->dev.of_node; - int ret; - - if (!np) - return 1; - - ret = of_alias_get_id(np, "serial"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); - return ret; - } - sport->port.line = ret; - return 0; -} - -static int serial_pxa_probe(struct platform_device *dev) -{ - struct uart_pxa_port *sport; - struct resource *mmres, *irqres; - int ret; - - mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); - irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); - if (!mmres || !irqres) - return -ENODEV; - - sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); - if (!sport) - return -ENOMEM; - - sport->clk = clk_get(&dev->dev, NULL); - if (IS_ERR(sport->clk)) { - ret = PTR_ERR(sport->clk); - goto err_free; - } - - ret = clk_prepare(sport->clk); - if (ret) { - clk_put(sport->clk); - goto err_free; - } - - sport->port.type = PORT_PXA; - sport->port.iotype = UPIO_MEM; - sport->port.mapbase = mmres->start; - sport->port.irq = irqres->start; - sport->port.fifosize = 64; - sport->port.ops = &serial_pxa_pops; - sport->port.dev = &dev->dev; - sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - sport->port.uartclk = clk_get_rate(sport->clk); - - ret = serial_pxa_probe_dt(dev, sport); - if (ret > 0) - sport->port.line = dev->id; - else if (ret < 0) - goto err_clk; - snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1); - - sport->port.membase = ioremap(mmres->start, resource_size(mmres)); - if (!sport->port.membase) { - ret = -ENOMEM; - goto err_clk; - } - - serial_pxa_ports[sport->port.line] = sport; - - uart_add_one_port(&serial_pxa_reg, &sport->port); - platform_set_drvdata(dev, sport); - - return 0; - - err_clk: - clk_unprepare(sport->clk); - clk_put(sport->clk); - err_free: - kfree(sport); - return ret; -} - -static int serial_pxa_remove(struct platform_device *dev) -{ - struct uart_pxa_port *sport = platform_get_drvdata(dev); - - uart_remove_one_port(&serial_pxa_reg, &sport->port); - - clk_unprepare(sport->clk); - clk_put(sport->clk); - kfree(sport); - - return 0; -} - -static struct platform_driver serial_pxa_driver = { - .probe = serial_pxa_probe, - .remove = serial_pxa_remove, - - .driver = { - .name = "pxa2xx-uart", - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &serial_pxa_pm_ops, -#endif - .of_match_table = serial_pxa_dt_ids, - }, -}; - -static int __init serial_pxa_init(void) -{ - int ret; - - ret = uart_register_driver(&serial_pxa_reg); - if (ret != 0) - return ret; - - ret = platform_driver_register(&serial_pxa_driver); - if (ret != 0) - uart_unregister_driver(&serial_pxa_reg); - - return ret; -} - -static void __exit serial_pxa_exit(void) -{ - platform_driver_unregister(&serial_pxa_driver); - uart_unregister_driver(&serial_pxa_reg); -} - -module_init(serial_pxa_init); -module_exit(serial_pxa_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:pxa2xx-uart"); -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v2] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 9:09 ` [PATCH v2] " Sergei Ianovich @ 2013-12-06 9:28 ` James Cameron 2013-12-09 8:38 ` Heikki Krogerus 2013-12-09 11:38 ` [PATCH v3] " Sergei Ianovich 2 siblings, 0 replies; 36+ messages in thread From: James Cameron @ 2013-12-06 9:28 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, Heikki Krogerus, Greg Kroah-Hartman, Russell King, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Stefan Seyfried, John Crispin, Paul Bolle, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... On Fri, Dec 06, 2013 at 01:09:31PM +0400, Sergei Ianovich wrote: > pxa2xx-uart was a separate uart platform driver. It was declaring > the same device names and numbers as 8250 driver. As a result, > it was impossible to use 8250 driver on PXA SoCs. > > Upon closer examination pxa2xx-uart turned out to be a clone of > 8250_core driver. > > Workaround for Erratum #19 according to Marvel(R) PXA270M Processor > Specification Update (April 19, 2010) is dropped. 8250_core reads > from FIFO immediately after checking DR bit in LSR. Reviewed-by: James Cameron <quozl@laptop.org> Thanks. (for my notes ... V1 has passed 4.5 hours in OLPC's RUNIN test.) -- James Cameron http://quozl.linux.org.au/ ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 9:09 ` [PATCH v2] " Sergei Ianovich 2013-12-06 9:28 ` James Cameron @ 2013-12-09 8:38 ` Heikki Krogerus 2013-12-09 8:44 ` Sascha Hauer 2013-12-09 11:38 ` [PATCH v3] " Sergei Ianovich 2 siblings, 1 reply; 36+ messages in thread From: Heikki Krogerus @ 2013-12-09 8:38 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, Greg Kroah-Hartman, James Cameron, Russell King, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Stefan Seyfried, John Crispin, Paul Bolle, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... Hi, On Fri, Dec 06, 2013 at 01:09:31PM +0400, Sergei Ianovich wrote: > pxa2xx-uart was a separate uart platform driver. It was declaring > the same device names and numbers as 8250 driver. As a result, > it was impossible to use 8250 driver on PXA SoCs. > > Upon closer examination pxa2xx-uart turned out to be a clone of > 8250_core driver. > > Workaround for Erratum #19 according to Marvel(R) PXA270M Processor > Specification Update (April 19, 2010) is dropped. 8250_core reads > from FIFO immediately after checking DR bit in LSR. > > Signed-off-by: Sergei Ianovich <ynvich@gmail.com> > CC: Heikki Krogerus <heikki.krogerus@linux.intel.com> > CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > CC: James Cameron <quozl@laptop.org> > --- > changes v1..v2 > * actually implement workaround for E74 in dl_write as spooted > by James Cameron > * added comment about E19 in commit message Nice job Sergei! I have a few minor nitpicks below, but if they are the only comments, don't bother with v3. I'm fine with this. For what it's worth: Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > arch/arm/configs/am200epdkit_defconfig | 3 +- > arch/arm/configs/cm_x2xx_defconfig | 3 +- > arch/arm/configs/cm_x300_defconfig | 3 +- > arch/arm/configs/colibri_pxa270_defconfig | 3 +- > arch/arm/configs/colibri_pxa300_defconfig | 3 +- > arch/arm/configs/corgi_defconfig | 4 +- > arch/arm/configs/em_x270_defconfig | 3 +- > arch/arm/configs/ezx_defconfig | 3 +- > arch/arm/configs/h5000_defconfig | 3 +- > arch/arm/configs/imote2_defconfig | 3 +- > arch/arm/configs/lpd270_defconfig | 3 +- > arch/arm/configs/lubbock_defconfig | 3 +- > arch/arm/configs/mainstone_defconfig | 3 +- > arch/arm/configs/mmp2_defconfig | 3 +- > arch/arm/configs/pcm027_defconfig | 3 +- > arch/arm/configs/pxa168_defconfig | 3 +- > arch/arm/configs/pxa255-idp_defconfig | 3 +- > arch/arm/configs/pxa3xx_defconfig | 3 +- > arch/arm/configs/pxa910_defconfig | 3 +- > arch/arm/configs/raumfeld_defconfig | 3 +- > arch/arm/configs/spitz_defconfig | 4 +- > arch/arm/configs/trizeps4_defconfig | 3 +- > arch/arm/configs/viper_defconfig | 4 +- > arch/arm/configs/xcep_defconfig | 3 +- > drivers/tty/serial/8250/8250_pxa.c | 189 ++++++ > drivers/tty/serial/8250/Kconfig | 9 + > drivers/tty/serial/8250/Makefile | 1 + > drivers/tty/serial/Kconfig | 23 - > drivers/tty/serial/Makefile | 1 - > drivers/tty/serial/pxa.c | 971 ------------------------------ > 30 files changed, 247 insertions(+), 1022 deletions(-) > create mode 100644 drivers/tty/serial/8250/8250_pxa.c > delete mode 100644 drivers/tty/serial/pxa.c <snip> > diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c > new file mode 100644 > index 0000000..88ae73c > --- /dev/null > +++ b/drivers/tty/serial/8250/8250_pxa.c > @@ -0,0 +1,189 @@ > +/* > + * drivers/tty/serial/8250/8250_pxa.c -- driver for PXA on-board UARTS > + * Copyright: (C) 2013 Sergei Ianovich <ynvich@gmail.com> > + * > + * replaces drivers/serial/pxa.c by Nicolas Pitre > + * Created: Feb 20, 2003 > + * Copyright: (C) 2003 Monta Vista Software, Inc. > + * > + * Based on drivers/serial/8250.c by Russell King. > + * > + * 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/init.h> > +#include <linux/io.h> > +#include <linux/module.h> > +#include <linux/serial_8250.h> > +#include <linux/serial_core.h> > +#include <linux/serial_reg.h> > +#include <linux/of.h> > +#include <linux/of_irq.h> > +#include <linux/of_platform.h> > +#include <linux/platform_device.h> > +#include <linux/slab.h> > +#include <linux/clk.h> > +#include <linux/pm_runtime.h> > + > +#include "8250.h" > + > +struct pxa8250_data { > + int line; > + struct clk *clk; > +}; > + > +#ifdef CONFIG_PM > +static int serial_pxa_suspend(struct device *dev) > +{ > + struct pxa8250_data *data = dev_get_drvdata(dev); > + > + serial8250_suspend_port(data->line); > + > + return 0; > +} > + > +static int serial_pxa_resume(struct device *dev) > +{ > + struct pxa8250_data *data = dev_get_drvdata(dev); > + > + serial8250_resume_port(data->line); > + > + return 0; > +} > + > +static const struct dev_pm_ops serial_pxa_pm_ops = { > + .suspend = serial_pxa_suspend, > + .resume = serial_pxa_resume, > +}; If you leave this structure outside the ifdef CONFIG_PM and use SET_SYSTEM_SLEEP_PM_OPS() macro, you don't need the ifdef when you set the driver pm ops below. > +#endif > + > +static struct of_device_id serial_pxa_dt_ids[] = { > + { .compatible = "mrvl,pxa-uart", }, > + { .compatible = "mrvl,mmp-uart", }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); > + > +/* Uart divisor latch write */ > +static void serial_pxa_dl_write(struct uart_8250_port *up, int value) > +{ > + unsigned int dll; > + > + serial_out(up, UART_DLL, value & 0xff); > + /* > + * work around Erratum #74 according to Marvel(R) PXA270M Processor > + * Specification Update (April 19, 2010) > + */ > + dll = serial_in(up, UART_DLL); > + WARN_ON(dll != (value & 0xff)); > + > + serial_out(up, UART_DLM, value >> 8 & 0xff); > +} > + > + > +static void serial_pxa_pm(struct uart_port *port, unsigned int state, > + unsigned int oldstate) > +{ > + struct pxa8250_data *data = port->private_data; > + > + if (!state) > + clk_prepare_enable(data->clk); > + else > + clk_disable_unprepare(data->clk); > +} > + > +static int serial_pxa_probe(struct platform_device *pdev) > +{ > + struct uart_8250_port uart = {}; > + struct pxa8250_data *data; > + struct resource *mmres, *irqres; > + int ret; > + > + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); > + if (!mmres || !irqres) > + return -ENODEV; > + > + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); > + if (!data) > + return -ENOMEM; > + > + data->clk = devm_clk_get(&pdev->dev, NULL); > + if (IS_ERR(data->clk)) { > + ret = PTR_ERR(data->clk); > + goto err_free; You can just return here. > + } > + > + ret = clk_prepare(data->clk); > + if (ret) > + goto err_free_clk; ditto > + uart.port.type = PORT_XSCALE; > + uart.port.iotype = UPIO_MEM32; > + uart.port.mapbase = mmres->start; > + uart.port.regshift = 2; > + uart.port.irq = irqres->start; > + uart.port.fifosize = 64; > + uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST; > + uart.port.dev = &pdev->dev; > + uart.port.uartclk = clk_get_rate(data->clk); > + uart.port.pm = serial_pxa_pm; > + uart.port.private_data = data; > + uart.dl_write = serial_pxa_dl_write; > + > + ret = serial8250_register_8250_port(&uart); > + if (ret < 0) > + goto err_clk; > + > + data->line = ret; > + > + platform_set_drvdata(pdev, data); > + > + return 0; > + > + err_clk: > + clk_unprepare(data->clk); > + err_free_clk: > + devm_clk_put(&pdev->dev, data->clk); > + err_free: > + devm_kfree(&pdev->dev, data); And there labels could be dropped. > + return ret; > +} > + > +static int serial_pxa_remove(struct platform_device *pdev) > +{ > + struct pxa8250_data *data = platform_get_drvdata(pdev); > + > + serial8250_unregister_port(data->line); > + > + clk_unprepare(data->clk); > + devm_clk_put(&pdev->dev, data->clk); > + devm_kfree(&pdev->dev, data); You also don't need to call these resource freeing functions here. > + return 0; > +} > + > +static struct platform_driver serial_pxa_driver = { > + .probe = serial_pxa_probe, > + .remove = serial_pxa_remove, > + > + .driver = { > + .name = "pxa2xx-uart", > + .owner = THIS_MODULE, > +#ifdef CONFIG_PM > + .pm = &serial_pxa_pm_ops, > +#endif > + .of_match_table = serial_pxa_dt_ids, > + }, > +}; > + > +module_platform_driver(serial_pxa_driver); > + > +MODULE_AUTHOR("Sergei Ianovich"); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:pxa2xx-uart"); Thanks, -- heikki ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v2] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-09 8:38 ` Heikki Krogerus @ 2013-12-09 8:44 ` Sascha Hauer 0 siblings, 0 replies; 36+ messages in thread From: Sascha Hauer @ 2013-12-09 8:44 UTC (permalink / raw) To: Heikki Krogerus Cc: Sergei Ianovich, linux-kernel, Greg Kroah-Hartman, James Cameron, Russell King, Jiri Slaby, Grant Likely, Rob Herring, Zhou Zhu, Andrew Morton, Haojian Zhuang, Stefan Seyfried, John Crispin, Paul Bolle, moderated list:ARM PORT, open list:SERIAL DRIVERS, open list:OPEN FIRMWARE AND... On Mon, Dec 09, 2013 at 10:38:15AM +0200, Heikki Krogerus wrote: > Hi, > > > + return 0; > > + > > + err_clk: > > + clk_unprepare(data->clk); > > + err_free_clk: > > + devm_clk_put(&pdev->dev, data->clk); > > + err_free: > > + devm_kfree(&pdev->dev, data); > > And there labels could be dropped. This should really be fixed. Explicitly releasing devm_* allocated resources invalidates the whole idea of the devm functions. People looking for templates shouldn't find examples for this in the kernel. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v3] serial: rewrite pxa2xx-uart to use 8250_core 2013-12-06 9:09 ` [PATCH v2] " Sergei Ianovich 2013-12-06 9:28 ` James Cameron 2013-12-09 8:38 ` Heikki Krogerus @ 2013-12-09 11:38 ` Sergei Ianovich 2 siblings, 0 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-09 11:38 UTC (permalink / raw) To: linux-kernel Cc: open list:OPEN FIRMWARE AND..., Heikki Krogerus, Russell King, James Cameron, Greg Kroah-Hartman, Rob Herring, Sergei Ianovich, Haojian Zhuang, open list:SERIAL DRIVERS, Grant Likely, Andrew Morton, John Crispin, Jiri Slaby, moderated list:ARM PORT, Zhou Zhu pxa2xx-uart was a separate uart platform driver. It was declaring the same device names and numbers as 8250 driver. As a result, it was impossible to use 8250 driver on PXA SoCs. Upon closer examination pxa2xx-uart turned out to be a clone of 8250_core driver. Workaround for Erratum #19 according to Marvel(R) PXA270M Processor Specification Update (April 19, 2010) is dropped. 8250_core reads from FIFO immediately after checking DR bit in LSR. Signed-off-by: Sergei Ianovich <ynvich@gmail.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Reviewed-by: James Cameron <quozl@laptop.org> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- changes v2..v3 * remove devm_free/put as suggested by Heikki Krogerus * use SET_SYSTEM_SLEEP_PM_OPS macro to set pm ops as suggested by Heikki Krogerus changes v1..v2 * actually implement workaround for E74 in dl_write as spooted by James Cameron * added comment about E19 in commit message arch/arm/configs/am200epdkit_defconfig | 3 +- arch/arm/configs/cm_x2xx_defconfig | 3 +- arch/arm/configs/cm_x300_defconfig | 3 +- arch/arm/configs/colibri_pxa270_defconfig | 3 +- arch/arm/configs/colibri_pxa300_defconfig | 3 +- arch/arm/configs/corgi_defconfig | 4 +- arch/arm/configs/em_x270_defconfig | 3 +- arch/arm/configs/ezx_defconfig | 3 +- arch/arm/configs/h5000_defconfig | 3 +- arch/arm/configs/imote2_defconfig | 3 +- arch/arm/configs/lpd270_defconfig | 3 +- arch/arm/configs/lubbock_defconfig | 3 +- arch/arm/configs/mainstone_defconfig | 3 +- arch/arm/configs/mmp2_defconfig | 3 +- arch/arm/configs/pcm027_defconfig | 3 +- arch/arm/configs/pxa168_defconfig | 3 +- arch/arm/configs/pxa255-idp_defconfig | 3 +- arch/arm/configs/pxa3xx_defconfig | 3 +- arch/arm/configs/pxa910_defconfig | 3 +- arch/arm/configs/raumfeld_defconfig | 3 +- arch/arm/configs/spitz_defconfig | 4 +- arch/arm/configs/trizeps4_defconfig | 3 +- arch/arm/configs/viper_defconfig | 4 +- arch/arm/configs/xcep_defconfig | 3 +- drivers/tty/serial/8250/8250_pxa.c | 178 ++++++ drivers/tty/serial/8250/Kconfig | 9 + drivers/tty/serial/8250/Makefile | 1 + drivers/tty/serial/Kconfig | 23 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/pxa.c | 971 ------------------------------ 30 files changed, 236 insertions(+), 1022 deletions(-) create mode 100644 drivers/tty/serial/8250/8250_pxa.c delete mode 100644 drivers/tty/serial/pxa.c diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig index f0dea52..0cde234 100644 --- a/arch/arm/configs/am200epdkit_defconfig +++ b/arch/arm/configs/am200epdkit_defconfig @@ -60,8 +60,9 @@ CONFIG_BLK_DEV_IDECS=m CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig index a93ff8d..b9fbe65 100644 --- a/arch/arm/configs/cm_x2xx_defconfig +++ b/arch/arm/configs/cm_x2xx_defconfig @@ -96,8 +96,9 @@ CONFIG_KEYBOARD_PXA27x=m CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=16 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index f4b7672..53a82ae 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -80,8 +80,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m # CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_SERIO is not set # CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_PXA=y diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 2ef2c5e..1ce0409 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig @@ -103,8 +103,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_SERIO_LIBPS2=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig index b985334..f96bda0 100644 --- a/arch/arm/configs/colibri_pxa300_defconfig +++ b/arch/arm/configs/colibri_pxa300_defconfig @@ -31,8 +31,9 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_MISC=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_DEBUG_GPIO=y # CONFIG_HWMON is not set diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 1fd1d1d..bb4842d 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -131,10 +131,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_SERIO is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_I2C=y CONFIG_I2C_PXA=y diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index 60a21e0..ec0ec54 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig @@ -90,8 +90,9 @@ CONFIG_TOUCHSCREEN_WM97XX=m # CONFIG_TOUCHSCREEN_WM9705 is not set # CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=16 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index d95763d..631e2ec 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -215,8 +215,9 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_PCAP=y # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=8 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig index 37903e3..655b735 100644 --- a/arch/arm/configs/h5000_defconfig +++ b/arch/arm/configs/h5000_defconfig @@ -47,8 +47,9 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=32 # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig index fd996bb..49d45e9 100644 --- a/arch/arm/configs/imote2_defconfig +++ b/arch/arm/configs/imote2_defconfig @@ -193,8 +193,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=8 # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index 1c8c9ee..c3927b6 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -38,8 +38,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_FB=y CONFIG_FB_PXA=y diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig index c4ba274..c8b0436 100644 --- a/arch/arm/configs/lubbock_defconfig +++ b/arch/arm/configs/lubbock_defconfig @@ -37,8 +37,9 @@ CONFIG_PCMCIA_PCNET=y CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_SA1111=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_VGA_CONSOLE is not set CONFIG_USB_GADGET=y CONFIG_USB_G_SERIAL=m diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig index 04efa1b..768892c 100644 --- a/arch/arm/configs/mainstone_defconfig +++ b/arch/arm/configs/mainstone_defconfig @@ -34,8 +34,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index f1cb95e..1ced9df 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig @@ -44,8 +44,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig index 2f136c3..1280128 100644 --- a/arch/arm/configs/pcm027_defconfig +++ b/arch/arm/configs/pcm027_defconfig @@ -60,8 +60,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig index 74d7e01..1668dac 100644 --- a/arch/arm/configs/pxa168_defconfig +++ b/arch/arm/configs/pxa168_defconfig @@ -40,8 +40,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig index 917a070..399a706 100644 --- a/arch/arm/configs/pxa255-idp_defconfig +++ b/arch/arm/configs/pxa255-idp_defconfig @@ -35,8 +35,9 @@ CONFIG_SMC91X=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_SERPORT is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_FB=y CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index 60e3138..7c3e052 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig @@ -56,8 +56,9 @@ CONFIG_KEYBOARD_PXA27x=y CONFIG_KEYBOARD_PXA930_ROTARY=y CONFIG_MOUSE_PXA930_TRKBALL=y CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=y diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig index 3bb7771..cdacfcb 100644 --- a/arch/arm/configs/pxa910_defconfig +++ b/arch/arm/configs/pxa910_defconfig @@ -40,8 +40,9 @@ CONFIG_SMC91X=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_SPI=y CONFIG_FB=y CONFIG_MMP_DISP=y diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig index f7caa90..f1e16f2 100644 --- a/arch/arm/configs/raumfeld_defconfig +++ b/arch/arm/configs/raumfeld_defconfig @@ -67,8 +67,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_EETI=m CONFIG_INPUT_MISC=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 2e0419d..b6efcf5 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -128,10 +128,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_SERIO is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_SPI=y CONFIG_SPI_PXA2XX=y diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 3162173..453c79c 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig @@ -132,8 +132,9 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_SERIO_LIBPS2=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index d36e0d3..4efac06 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -101,11 +101,11 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m # CONFIG_CONSOLE_TRANSLATIONS is not set # CONFIG_VT_CONSOLE is not set -CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=5 CONFIG_SERIAL_8250_RUNTIME_UARTS=5 CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set CONFIG_I2C=y CONFIG_I2C_CHARDEV=y diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig index 721832f..b67aeaf 100644 --- a/arch/arm/configs/xcep_defconfig +++ b/arch/arm/configs/xcep_defconfig @@ -60,8 +60,9 @@ CONFIG_NET_ETHERNET=y # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set CONFIG_I2C=m diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c new file mode 100644 index 0000000..0da0d40 --- /dev/null +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -0,0 +1,178 @@ +/* + * drivers/tty/serial/8250/8250_pxa.c -- driver for PXA on-board UARTS + * Copyright: (C) 2013 Sergei Ianovich <ynvich@gmail.com> + * + * replaces drivers/serial/pxa.c by Nicolas Pitre + * Created: Feb 20, 2003 + * Copyright: (C) 2003 Monta Vista Software, Inc. + * + * Based on drivers/serial/8250.c by Russell King. + * + * 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/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/serial_8250.h> +#include <linux/serial_core.h> +#include <linux/serial_reg.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/pm_runtime.h> + +#include "8250.h" + +struct pxa8250_data { + int line; + struct clk *clk; +}; + +#ifdef CONFIG_PM +static int serial_pxa_suspend(struct device *dev) +{ + struct pxa8250_data *data = dev_get_drvdata(dev); + + serial8250_suspend_port(data->line); + + return 0; +} + +static int serial_pxa_resume(struct device *dev) +{ + struct pxa8250_data *data = dev_get_drvdata(dev); + + serial8250_resume_port(data->line); + + return 0; +} +#endif + +static const struct dev_pm_ops serial_pxa_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(serial_pxa_suspend, serial_pxa_resume) +}; + +static struct of_device_id serial_pxa_dt_ids[] = { + { .compatible = "mrvl,pxa-uart", }, + { .compatible = "mrvl,mmp-uart", }, + {} +}; +MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); + +/* Uart divisor latch write */ +static void serial_pxa_dl_write(struct uart_8250_port *up, int value) +{ + unsigned int dll; + + serial_out(up, UART_DLL, value & 0xff); + /* + * work around Erratum #74 according to Marvel(R) PXA270M Processor + * Specification Update (April 19, 2010) + */ + dll = serial_in(up, UART_DLL); + WARN_ON(dll != (value & 0xff)); + + serial_out(up, UART_DLM, value >> 8 & 0xff); +} + + +static void serial_pxa_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct pxa8250_data *data = port->private_data; + + if (!state) + clk_prepare_enable(data->clk); + else + clk_disable_unprepare(data->clk); +} + +static int serial_pxa_probe(struct platform_device *pdev) +{ + struct uart_8250_port uart = {}; + struct pxa8250_data *data; + struct resource *mmres, *irqres; + int ret; + + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mmres || !irqres) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(data->clk)) + return PTR_ERR(data->clk); + + ret = clk_prepare(data->clk); + if (ret) + return ret; + + uart.port.type = PORT_XSCALE; + uart.port.iotype = UPIO_MEM32; + uart.port.mapbase = mmres->start; + uart.port.regshift = 2; + uart.port.irq = irqres->start; + uart.port.fifosize = 64; + uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST; + uart.port.dev = &pdev->dev; + uart.port.uartclk = clk_get_rate(data->clk); + uart.port.pm = serial_pxa_pm; + uart.port.private_data = data; + uart.dl_write = serial_pxa_dl_write; + + ret = serial8250_register_8250_port(&uart); + if (ret < 0) + goto err_clk; + + data->line = ret; + + platform_set_drvdata(pdev, data); + + return 0; + + err_clk: + clk_unprepare(data->clk); + return ret; +} + +static int serial_pxa_remove(struct platform_device *pdev) +{ + struct pxa8250_data *data = platform_get_drvdata(pdev); + + serial8250_unregister_port(data->line); + + clk_unprepare(data->clk); + + return 0; +} + +static struct platform_driver serial_pxa_driver = { + .probe = serial_pxa_probe, + .remove = serial_pxa_remove, + + .driver = { + .name = "pxa2xx-uart", + .owner = THIS_MODULE, + .pm = &serial_pxa_pm_ops, + .of_match_table = serial_pxa_dt_ids, + }, +}; + +module_platform_driver(serial_pxa_driver); + +MODULE_AUTHOR("Sergei Ianovich"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa2xx-uart"); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 2332991..81bd7c9 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -302,3 +302,12 @@ config SERIAL_8250_RT288X If you have a Ralink RT288x/RT305x SoC based board and want to use the serial port, say Y to this option. The driver can handle up to 2 serial ports. If unsure, say N. + +config SERIAL_PXA + tristate "PXA serial port support" + depends on SERIAL_8250 && (ARCH_PXA || ARCH_MMP) + help + If you have a machine based on an Intel XScale PXA2xx CPU you + can enable its onboard serial ports by enabling this option. + + If you choose M here, the module name will be 8250_pxa. diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 36d68d0..b7d1b61 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o +obj-$(CONFIG_SERIAL_PXA) += 8250_pxa.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index a3817ab..2ad7184b 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -396,29 +396,6 @@ config SERIAL_MPSC_CONSOLE help Say Y here if you want to support a serial console on a Marvell MPSC. -config SERIAL_PXA - bool "PXA serial port support" - depends on ARCH_PXA || ARCH_MMP - select SERIAL_CORE - help - If you have a machine based on an Intel XScale PXA2xx CPU you - can enable its onboard serial ports by enabling this option. - -config SERIAL_PXA_CONSOLE - bool "Console on PXA serial port" - depends on SERIAL_PXA - select SERIAL_CORE_CONSOLE - help - If you have enabled the serial port on the Intel XScale PXA - CPU you can make it the console by answering Y to this option. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttySA0". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - config SERIAL_SA1100 bool "SA1100 serial port support" depends on ARCH_SA1100 diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 3068c77..4ac337b 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_SERIAL_8250) += 8250/ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o -obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c deleted file mode 100644 index f9f20f3..0000000 --- a/drivers/tty/serial/pxa.c +++ /dev/null @@ -1,971 +0,0 @@ -/* - * Based on drivers/serial/8250.c by Russell King. - * - * Author: Nicolas Pitre - * Created: Feb 20, 2003 - * Copyright: (C) 2003 Monta Vista Software, Inc. - * - * 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. - * - * Note 1: This driver is made separate from the already too overloaded - * 8250.c because it needs some kirks of its own and that'll make it - * easier to add DMA support. - * - * Note 2: I'm too sick of device allocation policies for serial ports. - * If someone else wants to request an "official" allocation of major/minor - * for this driver please be my guest. And don't forget that new hardware - * to come from Intel might have more than 3 or 4 of those UARTs. Let's - * hope for a better port registration and dynamic device allocation scheme - * with the serial core maintainer satisfaction to appear soon. - */ - - -#if defined(CONFIG_SERIAL_PXA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include <linux/module.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/sysrq.h> -#include <linux/serial_reg.h> -#include <linux/circ_buf.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial_core.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/slab.h> - -#define PXA_NAME_LEN 8 - -struct uart_pxa_port { - struct uart_port port; - unsigned char ier; - unsigned char lcr; - unsigned char mcr; - unsigned int lsr_break_flag; - struct clk *clk; - char name[PXA_NAME_LEN]; -}; - -static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) -{ - offset <<= 2; - return readl(up->port.membase + offset); -} - -static inline void serial_out(struct uart_pxa_port *up, int offset, int value) -{ - offset <<= 2; - writel(value, up->port.membase + offset); -} - -static void serial_pxa_enable_ms(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - up->ier |= UART_IER_MSI; - serial_out(up, UART_IER, up->ier); -} - -static void serial_pxa_stop_tx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static void serial_pxa_stop_rx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - up->ier &= ~UART_IER_RLSI; - up->port.read_status_mask &= ~UART_LSR_DR; - serial_out(up, UART_IER, up->ier); -} - -static inline void receive_chars(struct uart_pxa_port *up, int *status) -{ - unsigned int ch, flag; - int max_count = 256; - - do { - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 2 - * Disable the Reciever Time Out Interrupt via IER[RTOEI] - */ - up->ier &= ~UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); - - ch = serial_in(up, UART_RX); - flag = TTY_NORMAL; - up->port.icount.rx++; - - if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { - /* - * For statistics only - */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - up->port.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&up->port)) - goto ignore_char; - } else if (*status & UART_LSR_PE) - up->port.icount.parity++; - else if (*status & UART_LSR_FE) - up->port.icount.frame++; - if (*status & UART_LSR_OE) - up->port.icount.overrun++; - - /* - * Mask off conditions which should be ignored. - */ - *status &= up->port.read_status_mask; - -#ifdef CONFIG_SERIAL_PXA_CONSOLE - if (up->port.line == up->port.cons->index) { - /* Recover the break flag from console xmit */ - *status |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif - if (*status & UART_LSR_BI) { - flag = TTY_BREAK; - } else if (*status & UART_LSR_PE) - flag = TTY_PARITY; - else if (*status & UART_LSR_FE) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char(&up->port, ch)) - goto ignore_char; - - uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); - - ignore_char: - *status = serial_in(up, UART_LSR); - } while ((*status & UART_LSR_DR) && (max_count-- > 0)); - tty_flip_buffer_push(&up->port.state->port); - - /* work around Errata #20 according to - * Intel(R) PXA27x Processor Family - * Specification Update (May 2005) - * - * Step 6: - * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE] - */ - up->ier |= UART_IER_RTOIE; - serial_out(up, UART_IER, up->ier); -} - -static void transmit_chars(struct uart_pxa_port *up) -{ - struct circ_buf *xmit = &up->port.state->xmit; - int count; - - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_pxa_stop_tx(&up->port); - return; - } - - count = up->port.fifosize / 2; - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - - if (uart_circ_empty(xmit)) - serial_pxa_stop_tx(&up->port); -} - -static void serial_pxa_start_tx(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (!(up->ier & UART_IER_THRI)) { - up->ier |= UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } -} - -static inline void check_modem_status(struct uart_pxa_port *up) -{ - int status; - - status = serial_in(up, UART_MSR); - - if ((status & UART_MSR_ANY_DELTA) == 0) - return; - - if (status & UART_MSR_TERI) - up->port.icount.rng++; - if (status & UART_MSR_DDSR) - up->port.icount.dsr++; - if (status & UART_MSR_DDCD) - uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); - if (status & UART_MSR_DCTS) - uart_handle_cts_change(&up->port, status & UART_MSR_CTS); - - wake_up_interruptible(&up->port.state->port.delta_msr_wait); -} - -/* - * This handles the interrupt from one port. - */ -static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) -{ - struct uart_pxa_port *up = dev_id; - unsigned int iir, lsr; - - iir = serial_in(up, UART_IIR); - if (iir & UART_IIR_NO_INT) - return IRQ_NONE; - lsr = serial_in(up, UART_LSR); - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); - check_modem_status(up); - if (lsr & UART_LSR_THRE) - transmit_chars(up); - return IRQ_HANDLED; -} - -static unsigned int serial_pxa_tx_empty(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - - return ret; -} - -static unsigned int serial_pxa_get_mctrl(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char status; - unsigned int ret; - - status = serial_in(up, UART_MSR); - - ret = 0; - if (status & UART_MSR_DCD) - ret |= TIOCM_CAR; - if (status & UART_MSR_RI) - ret |= TIOCM_RNG; - if (status & UART_MSR_DSR) - ret |= TIOCM_DSR; - if (status & UART_MSR_CTS) - ret |= TIOCM_CTS; - return ret; -} - -static void serial_pxa_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char mcr = 0; - - if (mctrl & TIOCM_RTS) - mcr |= UART_MCR_RTS; - if (mctrl & TIOCM_DTR) - mcr |= UART_MCR_DTR; - if (mctrl & TIOCM_OUT1) - mcr |= UART_MCR_OUT1; - if (mctrl & TIOCM_OUT2) - mcr |= UART_MCR_OUT2; - if (mctrl & TIOCM_LOOP) - mcr |= UART_MCR_LOOP; - - mcr |= up->mcr; - - serial_out(up, UART_MCR, mcr); -} - -static void serial_pxa_break_ctl(struct uart_port *port, int break_state) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - if (break_state == -1) - up->lcr |= UART_LCR_SBC; - else - up->lcr &= ~UART_LCR_SBC; - serial_out(up, UART_LCR, up->lcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static int serial_pxa_startup(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - int retval; - - if (port->line == 3) /* HWUART */ - up->mcr |= UART_MCR_AFE; - else - up->mcr = 0; - - up->port.uartclk = clk_get_rate(up->clk); - - /* - * Allocate the IRQ - */ - retval = request_irq(up->port.irq, serial_pxa_irq, 0, up->name, up); - if (retval) - return retval; - - /* - * Clear the FIFO buffers and disable them. - * (they will be reenabled in set_termios()) - */ - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); - - /* - * Clear the interrupt registers. - */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - /* - * Now, initialize the UART - */ - serial_out(up, UART_LCR, UART_LCR_WLEN8); - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl |= TIOCM_OUT2; - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* - * Finally, enable interrupts. Note: Modem status interrupts - * are set via set_termios(), which will be occurring imminently - * anyway, so we don't enable them here. - */ - up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE; - serial_out(up, UART_IER, up->ier); - - /* - * And clear the interrupt registers again for luck. - */ - (void) serial_in(up, UART_LSR); - (void) serial_in(up, UART_RX); - (void) serial_in(up, UART_IIR); - (void) serial_in(up, UART_MSR); - - return 0; -} - -static void serial_pxa_shutdown(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; - - free_irq(up->port.irq, up); - - /* - * Disable interrupts from this port - */ - up->ier = 0; - serial_out(up, UART_IER, 0); - - spin_lock_irqsave(&up->port.lock, flags); - up->port.mctrl &= ~TIOCM_OUT2; - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - spin_unlock_irqrestore(&up->port.lock, flags); - - /* - * Disable break condition and FIFOs - */ - serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT); - serial_out(up, UART_FCR, 0); -} - -static void -serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char cval, fcr = 0; - unsigned long flags; - unsigned int baud, quot; - unsigned int dll; - - switch (termios->c_cflag & CSIZE) { - case CS5: - cval = UART_LCR_WLEN5; - break; - case CS6: - cval = UART_LCR_WLEN6; - break; - case CS7: - cval = UART_LCR_WLEN7; - break; - default: - case CS8: - cval = UART_LCR_WLEN8; - break; - } - - if (termios->c_cflag & CSTOPB) - cval |= UART_LCR_STOP; - if (termios->c_cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(termios->c_cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - - if ((up->port.uartclk / quot) < (2400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1; - else if ((up->port.uartclk / quot) < (230400 * 16)) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32; - - /* - * Ok, we're now changing the port state. Do it with - * interrupts disabled. - */ - spin_lock_irqsave(&up->port.lock, flags); - - /* - * Ensure the port will be enabled. - * This is required especially for serial console. - */ - up->ier |= UART_IER_UUE; - - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - - up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (termios->c_iflag & INPCK) - up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (termios->c_iflag & (BRKINT | PARMRK)) - up->port.read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - up->port.ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (termios->c_iflag & IGNBRK) { - up->port.ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - up->port.ignore_status_mask |= UART_LSR_OE; - } - - /* - * ignore all characters if CREAD is not set - */ - if ((termios->c_cflag & CREAD) == 0) - up->port.ignore_status_mask |= UART_LSR_DR; - - /* - * CTS flow control flag and modem status interrupts - */ - up->ier &= ~UART_IER_MSI; - if (UART_ENABLE_MS(&up->port, termios->c_cflag)) - up->ier |= UART_IER_MSI; - - serial_out(up, UART_IER, up->ier); - - if (termios->c_cflag & CRTSCTS) - up->mcr |= UART_MCR_AFE; - else - up->mcr &= ~UART_MCR_AFE; - - serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ - serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ - - /* - * work around Errata #75 according to Intel(R) PXA27x Processor Family - * Specification Update (Nov 2005) - */ - dll = serial_in(up, UART_DLL); - WARN_ON(dll != (quot & 0xff)); - - serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ - serial_out(up, UART_LCR, cval); /* reset DLAB */ - up->lcr = cval; /* Save LCR */ - serial_pxa_set_mctrl(&up->port, up->port.mctrl); - serial_out(up, UART_FCR, fcr); - spin_unlock_irqrestore(&up->port.lock, flags); -} - -static void -serial_pxa_pm(struct uart_port *port, unsigned int state, - unsigned int oldstate) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - if (!state) - clk_prepare_enable(up->clk); - else - clk_disable_unprepare(up->clk); -} - -static void serial_pxa_release_port(struct uart_port *port) -{ -} - -static int serial_pxa_request_port(struct uart_port *port) -{ - return 0; -} - -static void serial_pxa_config_port(struct uart_port *port, int flags) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - up->port.type = PORT_PXA; -} - -static int -serial_pxa_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - /* we don't want the core code to modify any port params */ - return -EINVAL; -} - -static const char * -serial_pxa_type(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - return up->name; -} - -static struct uart_pxa_port *serial_pxa_ports[4]; -static struct uart_driver serial_pxa_reg; - -#ifdef CONFIG_SERIAL_PXA_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct uart_pxa_port *up) -{ - unsigned int status, tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - do { - status = serial_in(up, UART_LSR); - - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - udelay(1); - } while ((status & BOTH_EMPTY) != BOTH_EMPTY); - - /* Wait up to 1s for flow control if necessary */ - if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (--tmout && - ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) - udelay(1); - } -} - -static void serial_pxa_console_putchar(struct uart_port *port, int ch) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - wait_for_xmitr(up); - serial_out(up, UART_TX, ch); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void -serial_pxa_console_write(struct console *co, const char *s, unsigned int count) -{ - struct uart_pxa_port *up = serial_pxa_ports[co->index]; - unsigned int ier; - unsigned long flags; - int locked = 1; - - clk_enable(up->clk); - local_irq_save(flags); - if (up->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = spin_trylock(&up->port.lock); - else - spin_lock(&up->port.lock); - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, UART_IER_UUE); - - uart_console_write(&up->port, s, count, serial_pxa_console_putchar); - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); - - if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); - clk_disable(up->clk); - -} - -#ifdef CONFIG_CONSOLE_POLL -/* - * Console polling routines for writing and reading from the uart while - * in an interrupt or debug context. - */ - -static int serial_pxa_get_poll_char(struct uart_port *port) -{ - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned char lsr = serial_in(up, UART_LSR); - - while (!(lsr & UART_LSR_DR)) - lsr = serial_in(up, UART_LSR); - - return serial_in(up, UART_RX); -} - - -static void serial_pxa_put_poll_char(struct uart_port *port, - unsigned char c) -{ - unsigned int ier; - struct uart_pxa_port *up = (struct uart_pxa_port *)port; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(up, UART_IER); - serial_out(up, UART_IER, UART_IER_UUE); - - wait_for_xmitr(up); - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_out(up, UART_TX, c); - if (c == 10) { - wait_for_xmitr(up); - serial_out(up, UART_TX, 13); - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IER - */ - wait_for_xmitr(up); - serial_out(up, UART_IER, ier); -} - -#endif /* CONFIG_CONSOLE_POLL */ - -static int __init -serial_pxa_console_setup(struct console *co, char *options) -{ - struct uart_pxa_port *up; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index == -1 || co->index >= serial_pxa_reg.nr) - co->index = 0; - up = serial_pxa_ports[co->index]; - if (!up) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - - return uart_set_options(&up->port, co, baud, parity, bits, flow); -} - -static struct console serial_pxa_console = { - .name = "ttyS", - .write = serial_pxa_console_write, - .device = uart_console_device, - .setup = serial_pxa_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &serial_pxa_reg, -}; - -#define PXA_CONSOLE &serial_pxa_console -#else -#define PXA_CONSOLE NULL -#endif - -static struct uart_ops serial_pxa_pops = { - .tx_empty = serial_pxa_tx_empty, - .set_mctrl = serial_pxa_set_mctrl, - .get_mctrl = serial_pxa_get_mctrl, - .stop_tx = serial_pxa_stop_tx, - .start_tx = serial_pxa_start_tx, - .stop_rx = serial_pxa_stop_rx, - .enable_ms = serial_pxa_enable_ms, - .break_ctl = serial_pxa_break_ctl, - .startup = serial_pxa_startup, - .shutdown = serial_pxa_shutdown, - .set_termios = serial_pxa_set_termios, - .pm = serial_pxa_pm, - .type = serial_pxa_type, - .release_port = serial_pxa_release_port, - .request_port = serial_pxa_request_port, - .config_port = serial_pxa_config_port, - .verify_port = serial_pxa_verify_port, -#ifdef CONFIG_CONSOLE_POLL - .poll_get_char = serial_pxa_get_poll_char, - .poll_put_char = serial_pxa_put_poll_char, -#endif -}; - -static struct uart_driver serial_pxa_reg = { - .owner = THIS_MODULE, - .driver_name = "PXA serial", - .dev_name = "ttyS", - .major = TTY_MAJOR, - .minor = 64, - .nr = 4, - .cons = PXA_CONSOLE, -}; - -#ifdef CONFIG_PM -static int serial_pxa_suspend(struct device *dev) -{ - struct uart_pxa_port *sport = dev_get_drvdata(dev); - - if (sport) - uart_suspend_port(&serial_pxa_reg, &sport->port); - - return 0; -} - -static int serial_pxa_resume(struct device *dev) -{ - struct uart_pxa_port *sport = dev_get_drvdata(dev); - - if (sport) - uart_resume_port(&serial_pxa_reg, &sport->port); - - return 0; -} - -static const struct dev_pm_ops serial_pxa_pm_ops = { - .suspend = serial_pxa_suspend, - .resume = serial_pxa_resume, -}; -#endif - -static struct of_device_id serial_pxa_dt_ids[] = { - { .compatible = "mrvl,pxa-uart", }, - { .compatible = "mrvl,mmp-uart", }, - {} -}; -MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); - -static int serial_pxa_probe_dt(struct platform_device *pdev, - struct uart_pxa_port *sport) -{ - struct device_node *np = pdev->dev.of_node; - int ret; - - if (!np) - return 1; - - ret = of_alias_get_id(np, "serial"); - if (ret < 0) { - dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); - return ret; - } - sport->port.line = ret; - return 0; -} - -static int serial_pxa_probe(struct platform_device *dev) -{ - struct uart_pxa_port *sport; - struct resource *mmres, *irqres; - int ret; - - mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); - irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0); - if (!mmres || !irqres) - return -ENODEV; - - sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); - if (!sport) - return -ENOMEM; - - sport->clk = clk_get(&dev->dev, NULL); - if (IS_ERR(sport->clk)) { - ret = PTR_ERR(sport->clk); - goto err_free; - } - - ret = clk_prepare(sport->clk); - if (ret) { - clk_put(sport->clk); - goto err_free; - } - - sport->port.type = PORT_PXA; - sport->port.iotype = UPIO_MEM; - sport->port.mapbase = mmres->start; - sport->port.irq = irqres->start; - sport->port.fifosize = 64; - sport->port.ops = &serial_pxa_pops; - sport->port.dev = &dev->dev; - sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - sport->port.uartclk = clk_get_rate(sport->clk); - - ret = serial_pxa_probe_dt(dev, sport); - if (ret > 0) - sport->port.line = dev->id; - else if (ret < 0) - goto err_clk; - snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1); - - sport->port.membase = ioremap(mmres->start, resource_size(mmres)); - if (!sport->port.membase) { - ret = -ENOMEM; - goto err_clk; - } - - serial_pxa_ports[sport->port.line] = sport; - - uart_add_one_port(&serial_pxa_reg, &sport->port); - platform_set_drvdata(dev, sport); - - return 0; - - err_clk: - clk_unprepare(sport->clk); - clk_put(sport->clk); - err_free: - kfree(sport); - return ret; -} - -static int serial_pxa_remove(struct platform_device *dev) -{ - struct uart_pxa_port *sport = platform_get_drvdata(dev); - - uart_remove_one_port(&serial_pxa_reg, &sport->port); - - clk_unprepare(sport->clk); - clk_put(sport->clk); - kfree(sport); - - return 0; -} - -static struct platform_driver serial_pxa_driver = { - .probe = serial_pxa_probe, - .remove = serial_pxa_remove, - - .driver = { - .name = "pxa2xx-uart", - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &serial_pxa_pm_ops, -#endif - .of_match_table = serial_pxa_dt_ids, - }, -}; - -static int __init serial_pxa_init(void) -{ - int ret; - - ret = uart_register_driver(&serial_pxa_reg); - if (ret != 0) - return ret; - - ret = platform_driver_register(&serial_pxa_driver); - if (ret != 0) - uart_unregister_driver(&serial_pxa_reg); - - return ret; -} - -static void __exit serial_pxa_exit(void) -{ - platform_driver_unregister(&serial_pxa_driver); - uart_unregister_driver(&serial_pxa_reg); -} - -module_init(serial_pxa_init); -module_exit(serial_pxa_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:pxa2xx-uart"); -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2013-12-01 6:26 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Sergei Ianovich 2013-12-02 9:02 ` Heikki Krogerus @ 2014-01-28 14:14 ` Pavel Machek 2014-01-28 14:20 ` Sergei Ianovich 1 sibling, 1 reply; 36+ messages in thread From: Pavel Machek @ 2014-01-28 14:14 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS Hi! > PXA serial ports have "standard" UART names (ttyS[0-3]), major > device number (4) and first minor device number (64) by default. > > If the system has extra 8250 serial port hardware in addition > to onboard PXA serial ports, default settings produce a device > allocation conflict. > > The patch provides a configuration option which can move onboard > ports out of the way of 8250_core by assigning a different (204) > major number and corresponding device names (ttySA[0-3]). Yes, please. I was hitting the same issue with Sharp Zaurus and bluetooth CF card... Bluetooth card had 8250 inside... -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 01/11] resolve PXA<->8250 serial device address conflict 2014-01-28 14:14 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Pavel Machek @ 2014-01-28 14:20 ` Sergei Ianovich 0 siblings, 0 replies; 36+ messages in thread From: Sergei Ianovich @ 2014-01-28 14:20 UTC (permalink / raw) To: Pavel Machek Cc: linux-kernel, linux-arm-kernel, Greg Kroah-Hartman, Jiri Slaby, open list:SERIAL DRIVERS On Tue, 2014-01-28 at 15:14 +0100, Pavel Machek wrote: > Yes, please. I was hitting the same issue with Sharp Zaurus and bluetooth > CF card... Bluetooth card had 8250 inside... A better implementation is posted as v3 of the patch. http://linux-kernel.2935.n7.nabble.com/PATCH-00-11-ARM-support-for-ICP-DAS-LP-8x4x-tp761919p773485.html It would be great if you could test that patch add post back the results. ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x [not found] <1385879185-22455-1-git-send-email-ynvich@gmail.com> 2013-12-01 6:26 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Sergei Ianovich @ 2013-12-01 6:26 ` Sergei Ianovich 2013-12-02 8:48 ` Heikki Krogerus 2013-12-02 11:30 ` Russell King - ARM Linux 1 sibling, 2 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-01 6:26 UTC (permalink / raw) To: linux-kernel, linux-arm-kernel Cc: Sergei Ianovich, Russell King, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Arnd Bergmann, open list:SERIAL DRIVERS The patch adds support for 3 additional LP-8x4x built-in serial ports. The device can also host up to 8 extension cards with 4 serial ports on each card for a total of 35 ports. However, I don't have the hardware to test extension cards, so they are not supported, yet. Signed-off-by: Sergei Ianovich <ynvich@gmail.com> --- arch/arm/configs/lp8x4x_defconfig | 1 + arch/arm/mach-pxa/include/mach/lp8x4x.h | 6 ++ drivers/tty/serial/8250/8250_lp8x4x.c | 181 ++++++++++++++++++++++++++++++++ drivers/tty/serial/8250/Kconfig | 11 ++ drivers/tty/serial/8250/Makefile | 1 + 5 files changed, 200 insertions(+) create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig index 03c85bc..d297a67 100644 --- a/arch/arm/configs/lp8x4x_defconfig +++ b/arch/arm/configs/lp8x4x_defconfig @@ -1141,6 +1141,7 @@ CONFIG_SERIAL_8250_NR_UARTS=36 CONFIG_SERIAL_8250_RUNTIME_UARTS=36 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_LP8X4X=m CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set # CONFIG_SERIAL_8250_RSA is not set diff --git a/arch/arm/mach-pxa/include/mach/lp8x4x.h b/arch/arm/mach-pxa/include/mach/lp8x4x.h index a49df22..4d5474e 100644 --- a/arch/arm/mach-pxa/include/mach/lp8x4x.h +++ b/arch/arm/mach-pxa/include/mach/lp8x4x.h @@ -50,6 +50,12 @@ #define LP8X4X_CLRFALLINT LP8X4X_P2V(0x1700901a) #define LP8X4X_RWRTC LP8X4X_P2V(0x1700901c) #define LP8X4X_SRAMBANK 0x1700901e +#define LP8X4X_TTYS0_QUIRK 0x17009030 +#define LP8X4X_TTYS1_QUIRK 0x17009032 +#define LP8X4X_TTYS2_QUIRK 0x17009034 +#define LP8X4X_TTYS0_IOMEM 0x17009050 +#define LP8X4X_TTYS1_IOMEM 0x17009060 +#define LP8X4X_TTYS2_IOMEM 0x17009070 #define LP8X4X_SRAM 0x1700a000 /* board specific IRQs */ diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c new file mode 100644 index 0000000..27b01f0b --- /dev/null +++ b/drivers/tty/serial/8250/8250_lp8x4x.c @@ -0,0 +1,181 @@ +/* linux/drivers/tty/serial/8250/8250_lp8x4x.c + * + * Support for 16550 serial ports on ICP DAS LP-8x4x + * + * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com> + * Framework taken from linux/drivers/tty/serial/8250/8250_accent.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/delay.h> +#include <linux/serial_8250.h> +#include <mach/lp8x4x.h> +#include <linux/io.h> + +#define QUIRK_PORT(_base, _irq) \ + { \ + .iobase = _base, \ + .membase = (void *) _base, \ + .mapbase = _base, \ + .irq = _irq, \ + .uartclk = 14745600, \ + .regshift = 1, \ + .iotype = UPIO_MEM, \ + .flags = UPF_IOREMAP, \ + .set_termios = lp8x4x_set_termios, \ + .serial_in = lp8x4x_serial_in, \ + .serial_out = lp8x4x_serial_out, \ + } + +static void lp8x4x_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) +{ + unsigned int len; + unsigned int baud; + + switch (termios->c_cflag & CSIZE) { + case CS5: + len = 7; + break; + case CS6: + len = 8; + break; + case CS7: + len = 9; + break; + default: + case CS8: + len = 10; + break; + } + + if (termios->c_cflag & CSTOPB) + len++; + if (termios->c_cflag & PARENB) + len++; + if (!(termios->c_cflag & PARODD)) + len++; +#ifdef CMSPAR + if (termios->c_cflag & CMSPAR) + len++; +#endif + + len -= 9; + len &= 3; + len <<= 3; + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, + port->uartclk / 16 / 0xffff, + port->uartclk / 16); + switch (baud) { + case 2400: + len |= 1; + case 4800: + len |= 2; + case 19200: + len |= 4; + case 38400: + len |= 5; + case 57600: + len |= 6; + case 115200: + len |= 7; + case 9600: + default: + len |= 3; + }; + iowrite8(len, port->private_data); + + serial8250_do_set_termios(port, termios, old); +} + +static unsigned int lp8x4x_serial_in(struct uart_port *p, int offset) +{ + unsigned int b; + udelay(30); + offset = offset << p->regshift; + b = readb(p->membase + offset); + return b; +} + +static void lp8x4x_serial_out(struct uart_port *p, int offset, int value) +{ + offset = offset << p->regshift; + writeb(value, p->membase + offset); +} + +static struct plat_serial8250_port lp8x4x_data[] = { + QUIRK_PORT(LP8X4X_TTYS0_IOMEM, LP8X4X_TTYS0_IRQ), + QUIRK_PORT(LP8X4X_TTYS1_IOMEM, LP8X4X_TTYS1_IRQ), + QUIRK_PORT(LP8X4X_TTYS2_IOMEM, LP8X4X_TTYS2_IRQ), + { }, +}; + +/* Total number of ports can be 35. The first 3 ports are on + * the device, the rest are on extension slots. Only the first 3 + * require termios quirk */ +#define LP8X4X_QUIRK_PORTS 3 + +static unsigned int extra_mem[LP8X4X_QUIRK_PORTS] = { + LP8X4X_TTYS0_QUIRK, + LP8X4X_TTYS1_QUIRK, + LP8X4X_TTYS2_QUIRK +}; + +static int request_and_remap(int i) +{ + if (!request_mem_region(extra_mem[i], 1, "serial")) + return -EBUSY; + + lp8x4x_data[i].private_data = ioremap(extra_mem[i], 1); + if (lp8x4x_data[i].private_data) + return 0; + + release_mem_region(extra_mem[i], 1); + return -ENODEV; +} + +static void release_and_unmap(int i) +{ + iounmap((void *) lp8x4x_data[i].private_data); + release_mem_region(extra_mem[i], 1); +} + +static struct platform_device lp8x4x_device = { + .name = "serial8250", + .id = PLAT8250_DEV_ACCENT, + .dev = { + .platform_data = lp8x4x_data, + }, +}; + +static int __init lp8x4x_init(void) +{ + int i = 0; + int err = 0; + + for (i = 0; i < LP8X4X_QUIRK_PORTS; i++) { + err = request_and_remap(i); + if (err == 0) + continue; + + for (; i >= 0; i--) + release_and_unmap(i); + lp8x4x_device.dev.platform_data = NULL; + return err; + } + return platform_device_register(&lp8x4x_device); +} + +module_init(lp8x4x_init); + +MODULE_AUTHOR("Sergei Ianovich"); +MODULE_DESCRIPTION("8250 serial port module for LP-8x4x"); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index f3b306e..30b9af4 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -237,6 +237,17 @@ config SERIAL_8250_HUB6 To compile this driver as a module, choose M here: the module will be called 8250_hub6. +config SERIAL_8250_LP8X4X + tristate "Support 8250 ports on ICP DAS LP-8x4x" + depends on SERIAL_8250 != n && SERIAL_8250_MANY_PORTS && MACH_LP8X4X + help + In addition on serial ports on PXA270 SoC, LP-8x4x has 1 dual + RS232/RS485 port, 1 RS485 port and 1 RS232 port serial ports. + + Say N here, unless you plan to run this kernel on a LP-8x4x system. + + If you choose M, the module will be called 8250_lp8x4x. + # # Misc. options/drivers. # diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 36d68d0..451c558 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o -- 1.8.4.2 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-01 6:26 ` [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x Sergei Ianovich @ 2013-12-02 8:48 ` Heikki Krogerus 2013-12-02 11:46 ` Sergei Ianovich 2013-12-02 11:30 ` Russell King - ARM Linux 1 sibling, 1 reply; 36+ messages in thread From: Heikki Krogerus @ 2013-12-02 8:48 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Russell King, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, open list:SERIAL DRIVERS Hi, On Sun, Dec 01, 2013 at 10:26:18AM +0400, Sergei Ianovich wrote: > The patch adds support for 3 additional LP-8x4x built-in serial > ports. > > The device can also host up to 8 extension cards with 4 serial ports > on each card for a total of 35 ports. However, I don't have > the hardware to test extension cards, so they are not supported, yet. > > Signed-off-by: Sergei Ianovich <ynvich@gmail.com> > --- > arch/arm/configs/lp8x4x_defconfig | 1 + > arch/arm/mach-pxa/include/mach/lp8x4x.h | 6 ++ > drivers/tty/serial/8250/8250_lp8x4x.c | 181 ++++++++++++++++++++++++++++++++ > drivers/tty/serial/8250/Kconfig | 11 ++ > drivers/tty/serial/8250/Makefile | 1 + > 5 files changed, 200 insertions(+) > create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c > > diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig > index 03c85bc..d297a67 100644 > --- a/arch/arm/configs/lp8x4x_defconfig > +++ b/arch/arm/configs/lp8x4x_defconfig > @@ -1141,6 +1141,7 @@ CONFIG_SERIAL_8250_NR_UARTS=36 > CONFIG_SERIAL_8250_RUNTIME_UARTS=36 > CONFIG_SERIAL_8250_EXTENDED=y > CONFIG_SERIAL_8250_MANY_PORTS=y > +CONFIG_SERIAL_8250_LP8X4X=m > CONFIG_SERIAL_8250_SHARE_IRQ=y > # CONFIG_SERIAL_8250_DETECT_IRQ is not set > # CONFIG_SERIAL_8250_RSA is not set > diff --git a/arch/arm/mach-pxa/include/mach/lp8x4x.h b/arch/arm/mach-pxa/include/mach/lp8x4x.h > index a49df22..4d5474e 100644 > --- a/arch/arm/mach-pxa/include/mach/lp8x4x.h > +++ b/arch/arm/mach-pxa/include/mach/lp8x4x.h > @@ -50,6 +50,12 @@ > #define LP8X4X_CLRFALLINT LP8X4X_P2V(0x1700901a) > #define LP8X4X_RWRTC LP8X4X_P2V(0x1700901c) > #define LP8X4X_SRAMBANK 0x1700901e > +#define LP8X4X_TTYS0_QUIRK 0x17009030 > +#define LP8X4X_TTYS1_QUIRK 0x17009032 > +#define LP8X4X_TTYS2_QUIRK 0x17009034 > +#define LP8X4X_TTYS0_IOMEM 0x17009050 > +#define LP8X4X_TTYS1_IOMEM 0x17009060 > +#define LP8X4X_TTYS2_IOMEM 0x17009070 > #define LP8X4X_SRAM 0x1700a000 > > /* board specific IRQs */ > diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c > new file mode 100644 > index 0000000..27b01f0b > --- /dev/null > +++ b/drivers/tty/serial/8250/8250_lp8x4x.c > @@ -0,0 +1,181 @@ > +/* linux/drivers/tty/serial/8250/8250_lp8x4x.c > + * > + * Support for 16550 serial ports on ICP DAS LP-8x4x > + * > + * Copyright (C) 2013 Sergei Ianovich <ynvich@gmail.com> > + * Framework taken from linux/drivers/tty/serial/8250/8250_accent.c > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/irq.h> > +#include <linux/delay.h> > +#include <linux/serial_8250.h> > +#include <mach/lp8x4x.h> > +#include <linux/io.h> > + > +#define QUIRK_PORT(_base, _irq) \ > + { \ > + .iobase = _base, \ > + .membase = (void *) _base, \ > + .mapbase = _base, \ > + .irq = _irq, \ > + .uartclk = 14745600, \ > + .regshift = 1, \ > + .iotype = UPIO_MEM, \ > + .flags = UPF_IOREMAP, \ > + .set_termios = lp8x4x_set_termios, \ > + .serial_in = lp8x4x_serial_in, \ > + .serial_out = lp8x4x_serial_out, \ > + } > + > +static void lp8x4x_set_termios(struct uart_port *port, > + struct ktermios *termios, struct ktermios *old) > +{ <snip> > +} > + > +static unsigned int lp8x4x_serial_in(struct uart_port *p, int offset) > +{ > + unsigned int b; > + udelay(30); > + offset = offset << p->regshift; > + b = readb(p->membase + offset); > + return b; > +} > + > +static void lp8x4x_serial_out(struct uart_port *p, int offset, int value) > +{ > + offset = offset << p->regshift; > + writeb(value, p->membase + offset); > +} > + > +static struct plat_serial8250_port lp8x4x_data[] = { > + QUIRK_PORT(LP8X4X_TTYS0_IOMEM, LP8X4X_TTYS0_IRQ), > + QUIRK_PORT(LP8X4X_TTYS1_IOMEM, LP8X4X_TTYS1_IRQ), > + QUIRK_PORT(LP8X4X_TTYS2_IOMEM, LP8X4X_TTYS2_IRQ), > + { }, > +}; > + > +/* Total number of ports can be 35. The first 3 ports are on > + * the device, the rest are on extension slots. Only the first 3 > + * require termios quirk */ > +#define LP8X4X_QUIRK_PORTS 3 > + > +static unsigned int extra_mem[LP8X4X_QUIRK_PORTS] = { > + LP8X4X_TTYS0_QUIRK, > + LP8X4X_TTYS1_QUIRK, > + LP8X4X_TTYS2_QUIRK > +}; > + > +static int request_and_remap(int i) > +{ > + if (!request_mem_region(extra_mem[i], 1, "serial")) > + return -EBUSY; > + > + lp8x4x_data[i].private_data = ioremap(extra_mem[i], 1); > + if (lp8x4x_data[i].private_data) > + return 0; > + > + release_mem_region(extra_mem[i], 1); > + return -ENODEV; > +} > + > +static void release_and_unmap(int i) > +{ > + iounmap((void *) lp8x4x_data[i].private_data); > + release_mem_region(extra_mem[i], 1); > +} > + > +static struct platform_device lp8x4x_device = { > + .name = "serial8250", > + .id = PLAT8250_DEV_ACCENT, > + .dev = { > + .platform_data = lp8x4x_data, > + }, > +}; > + > +static int __init lp8x4x_init(void) > +{ > + int i = 0; > + int err = 0; > + > + for (i = 0; i < LP8X4X_QUIRK_PORTS; i++) { > + err = request_and_remap(i); > + if (err == 0) > + continue; > + > + for (; i >= 0; i--) > + release_and_unmap(i); > + lp8x4x_device.dev.platform_data = NULL; > + return err; > + } > + return platform_device_register(&lp8x4x_device); > +} > + > +module_init(lp8x4x_init); Instead of registering a platform device for serial8250 here, you need to simply register a platform driver for something like lp8x4x_serial. The platform code will to registers the platform devices for it. You will use serial8250_register_8250_port() in your probe to register a new port. Use 8250_em.c and 8250_dw.c under drivers/tty/serial/8250/ as an example. You don't need to introduce plat_serial8250_port so you won't need the QUIRK_PORT stuff. You deliver the iomem and the irq as normal resources that the driver uses when you create the platform device. That of course also means the driver does not need to care about the instances. The platform code will generate a platform device for as many ports you have and set to resources accordingly. Thanks, -- heikki ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-02 8:48 ` Heikki Krogerus @ 2013-12-02 11:46 ` Sergei Ianovich 2013-12-02 13:53 ` Heikki Krogerus 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-02 11:46 UTC (permalink / raw) To: Heikki Krogerus Cc: linux-kernel, linux-arm-kernel, Russell King, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, open list:SERIAL DRIVERS On Mon, 2013-12-02 at 10:48 +0200, Heikki Krogerus wrote: > On Sun, Dec 01, 2013 at 10:26:18AM +0400, Sergei Ianovich wrote: > > The patch adds support for 3 additional LP-8x4x built-in serial > > ports. > > > > The device can also host up to 8 extension cards with 4 serial ports > > on each card for a total of 35 ports. However, I don't have > > the hardware to test extension cards, so they are not supported, yet. > > --- a/arch/arm/mach-pxa/include/mach/lp8x4x.h > > +++ b/arch/arm/mach-pxa/include/mach/lp8x4x.h > > @@ -50,6 +50,12 @@ > > #define LP8X4X_CLRFALLINT LP8X4X_P2V(0x1700901a) > > #define LP8X4X_RWRTC LP8X4X_P2V(0x1700901c) > > #define LP8X4X_SRAMBANK 0x1700901e > > +#define LP8X4X_TTYS0_QUIRK 0x17009030 > > +#define LP8X4X_TTYS1_QUIRK 0x17009032 > > +#define LP8X4X_TTYS2_QUIRK 0x17009034 > > +#define LP8X4X_TTYS0_IOMEM 0x17009050 > > +#define LP8X4X_TTYS1_IOMEM 0x17009060 > > +#define LP8X4X_TTYS2_IOMEM 0x17009070 > > + > > +static void lp8x4x_set_termios(struct uart_port *port, > > + struct ktermios *termios, struct ktermios *old) > > +{ > > <snip> > > > +static int request_and_remap(int i) > > +{ > > + if (!request_mem_region(extra_mem[i], 1, "serial")) > > + return -EBUSY; > > + > > + lp8x4x_data[i].private_data = ioremap(extra_mem[i], 1); > > + if (lp8x4x_data[i].private_data) > > + return 0; > > + > > + release_mem_region(extra_mem[i], 1); > > + return -ENODEV; > Instead of registering a platform device for serial8250 here, you need > to simply register a platform driver for something like lp8x4x_serial. > The platform code will to registers the platform devices for it. You > will use serial8250_register_8250_port() in your probe to register a > new port. Use 8250_em.c and 8250_dw.c under drivers/tty/serial/8250/ > as an example. > > You don't need to introduce plat_serial8250_port so you won't need > the QUIRK_PORT stuff. You deliver the iomem and the irq as normal > resources that the driver uses when you create the platform device. > That of course also means the driver does not need to care about the > instances. The platform code will generate a platform device for as > many ports you have and set to resources accordingly. 8250_core.c doesn't use platform infrastructure to request and map IO memory. There will be a conflict (and an error in serial8250_request_std_resource()), if main IO memory is requested by the platform device, won't it? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-02 11:46 ` Sergei Ianovich @ 2013-12-02 13:53 ` Heikki Krogerus 0 siblings, 0 replies; 36+ messages in thread From: Heikki Krogerus @ 2013-12-02 13:53 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Russell King, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, open list:SERIAL DRIVERS Hi, On Mon, Dec 02, 2013 at 03:46:22PM +0400, Sergei Ianovich wrote: > On Mon, 2013-12-02 at 10:48 +0200, Heikki Krogerus wrote: > > On Sun, Dec 01, 2013 at 10:26:18AM +0400, Sergei Ianovich wrote: > > > +static int request_and_remap(int i) > > > +{ > > > + if (!request_mem_region(extra_mem[i], 1, "serial")) > > > + return -EBUSY; > > > + > > > + lp8x4x_data[i].private_data = ioremap(extra_mem[i], 1); > > > + if (lp8x4x_data[i].private_data) > > > + return 0; > > > + > > > + release_mem_region(extra_mem[i], 1); > > > + return -ENODEV; > > > Instead of registering a platform device for serial8250 here, you need > > to simply register a platform driver for something like lp8x4x_serial. > > The platform code will to registers the platform devices for it. You > > will use serial8250_register_8250_port() in your probe to register a > > new port. Use 8250_em.c and 8250_dw.c under drivers/tty/serial/8250/ > > as an example. > > > > You don't need to introduce plat_serial8250_port so you won't need > > the QUIRK_PORT stuff. You deliver the iomem and the irq as normal > > resources that the driver uses when you create the platform device. > > That of course also means the driver does not need to care about the > > instances. The platform code will generate a platform device for as > > many ports you have and set to resources accordingly. > > 8250_core.c doesn't use platform infrastructure to request and map IO > memory. There will be a conflict (and an error in > serial8250_request_std_resource()), if main IO memory is requested by > the platform device, won't it? You don't need to request the mem region in your probe driver. You can still map it. You have the flag UPF_IOREMAP that you can use to tell 8250_code.c to map the region. If you don't set the flag, 8250_core.c will in practice expect that port->membase is already set by the probe driver. Check 8250_dw.c. It does the mapping on it's own and simply doesn't set the flag. Br, -- heikki ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-01 6:26 ` [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x Sergei Ianovich 2013-12-02 8:48 ` Heikki Krogerus @ 2013-12-02 11:30 ` Russell King - ARM Linux 2013-12-02 11:39 ` Sergei Ianovich 1 sibling, 1 reply; 36+ messages in thread From: Russell King - ARM Linux @ 2013-12-02 11:30 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Arnd Bergmann, open list:SERIAL DRIVERS On Sun, Dec 01, 2013 at 10:26:18AM +0400, Sergei Ianovich wrote: > +static struct platform_device lp8x4x_device = { > + .name = "serial8250", > + .id = PLAT8250_DEV_ACCENT, You should not re-use the enum value here. The enum is designed as a method to provide the platform devices with a unique id, not as a means to identify the manufacturer or anything else like that. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-02 11:30 ` Russell King - ARM Linux @ 2013-12-02 11:39 ` Sergei Ianovich 2013-12-02 11:52 ` Russell King - ARM Linux 0 siblings, 1 reply; 36+ messages in thread From: Sergei Ianovich @ 2013-12-02 11:39 UTC (permalink / raw) To: Russell King - ARM Linux Cc: linux-kernel, linux-arm-kernel, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Arnd Bergmann, open list:SERIAL DRIVERS On Mon, 2013-12-02 at 11:30 +0000, Russell King - ARM Linux wrote: > On Sun, Dec 01, 2013 at 10:26:18AM +0400, Sergei Ianovich wrote: > > +static struct platform_device lp8x4x_device = { > > + .name = "serial8250", > > + .id = PLAT8250_DEV_ACCENT, > > You should not re-use the enum value here. The enum is designed as a > method to provide the platform devices with a unique id, not as a means > to identify the manufacturer or anything else like that. Should I add a new enum? Or should I use zero? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-02 11:39 ` Sergei Ianovich @ 2013-12-02 11:52 ` Russell King - ARM Linux 2013-12-02 12:01 ` Sergei Ianovich 0 siblings, 1 reply; 36+ messages in thread From: Russell King - ARM Linux @ 2013-12-02 11:52 UTC (permalink / raw) To: Sergei Ianovich Cc: linux-kernel, linux-arm-kernel, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Arnd Bergmann, open list:SERIAL DRIVERS On Mon, Dec 02, 2013 at 03:39:26PM +0400, Sergei Ianovich wrote: > On Mon, 2013-12-02 at 11:30 +0000, Russell King - ARM Linux wrote: > > On Sun, Dec 01, 2013 at 10:26:18AM +0400, Sergei Ianovich wrote: > > > +static struct platform_device lp8x4x_device = { > > > + .name = "serial8250", > > > + .id = PLAT8250_DEV_ACCENT, > > > > You should not re-use the enum value here. The enum is designed as a > > method to provide the platform devices with a unique id, not as a means > > to identify the manufacturer or anything else like that. > > Should I add a new enum? Add a new enum. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x 2013-12-02 11:52 ` Russell King - ARM Linux @ 2013-12-02 12:01 ` Sergei Ianovich 0 siblings, 0 replies; 36+ messages in thread From: Sergei Ianovich @ 2013-12-02 12:01 UTC (permalink / raw) To: Russell King - ARM Linux Cc: linux-kernel, linux-arm-kernel, Eric Miao, Haojian Zhuang, Greg Kroah-Hartman, Jiri Slaby, Heikki Krogerus, Arnd Bergmann, open list:SERIAL DRIVERS On Mon, 2013-12-02 at 11:52 +0000, Russell King - ARM Linux wrote: > Add a new enum. I will. Thanks for prompt replies. A side work process question: Should I respin this single patch? Or should I wait for other patch reviews and respin the whole series when ready? ^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2014-01-28 14:20 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1385879185-22455-1-git-send-email-ynvich@gmail.com>
2013-12-01 6:26 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Sergei Ianovich
2013-12-02 9:02 ` Heikki Krogerus
2013-12-02 9:23 ` Sergei Ianovich
2013-12-02 9:49 ` Heikki Krogerus
2013-12-02 10:26 ` Sergei Ianovich
2013-12-02 14:10 ` Heikki Krogerus
2013-12-05 4:12 ` Greg Kroah-Hartman
2013-12-05 4:31 ` Sergei Ianovich
2013-12-05 4:35 ` Greg Kroah-Hartman
2013-12-05 4:36 ` Sergei Ianovich
[not found] ` <20131205043544.GA28580-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2013-12-05 23:28 ` [PATCH] serial: rewrite pxa2xx-uart to use 8250_core Sergei Ianovich
[not found] ` <1386286149-2855-1-git-send-email-ynvich-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-12-06 0:02 ` Greg Kroah-Hartman
[not found] ` <20131206000253.GC21358-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2013-12-06 0:17 ` Russell King - ARM Linux
2013-12-06 9:28 ` Sergei Ianovich
2013-12-06 9:53 ` James Cameron
2013-12-06 10:34 ` Sergei Ianovich
2013-12-06 11:05 ` James Cameron
2013-12-06 0:38 ` James Cameron
2013-12-06 2:55 ` James Cameron
2013-12-06 2:42 ` James Cameron
2013-12-06 9:16 ` Sergei Ianovich
2013-12-06 9:09 ` [PATCH v2] " Sergei Ianovich
2013-12-06 9:28 ` James Cameron
2013-12-09 8:38 ` Heikki Krogerus
2013-12-09 8:44 ` Sascha Hauer
2013-12-09 11:38 ` [PATCH v3] " Sergei Ianovich
2014-01-28 14:14 ` [PATCH 01/11] resolve PXA<->8250 serial device address conflict Pavel Machek
2014-01-28 14:20 ` Sergei Ianovich
2013-12-01 6:26 ` [PATCH 05/11] serial: support for 16550 serial ports on LP-8x4x Sergei Ianovich
2013-12-02 8:48 ` Heikki Krogerus
2013-12-02 11:46 ` Sergei Ianovich
2013-12-02 13:53 ` Heikki Krogerus
2013-12-02 11:30 ` Russell King - ARM Linux
2013-12-02 11:39 ` Sergei Ianovich
2013-12-02 11:52 ` Russell King - ARM Linux
2013-12-02 12:01 ` Sergei Ianovich
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).