Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update (take 2)
On Thu, Feb 22, 2007 at 02:17:28AM +0900, Atsushi Nemoto wrote: > Update the serial_txx9 driver. > > * Use platform_device. > * Fix and cleanup suspend/resume/initialization codes. > > Signed-off-by: Atsushi Nemoto <[EMAIL PROTECTED]> > Acked-by: Alan Cox <[EMAIL PROTECTED]> Andrew, I've applied this patch on linux-mips.org and if nobody else raises any issues I'll take care of merging this. Ralf - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2.6.21-rc1] serial: serial_txx9 driver update (take 2)
Update the serial_txx9 driver. * Use platform_device. * Fix and cleanup suspend/resume/initialization codes. Signed-off-by: Atsushi Nemoto <[EMAIL PROTECTED]> Acked-by: Alan Cox <[EMAIL PROTECTED]> --- diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index f4440d3..509ace7 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -38,6 +38,8 @@ * Fix some spin_locks. * Do not call uart_add_one_port for absent ports. * 1.07Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. + * 1.08Use platform_device. + * Fix and cleanup suspend/resume/initialization codes. */ #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -50,7 +52,7 @@ #include #include #include -#include +#include #include #include #include @@ -60,7 +62,7 @@ #include -static char *serial_version = "1.07"; +static char *serial_version = "1.08"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -94,12 +96,7 @@ static char *serial_name = "TX39/49 Seri struct uart_txx9_port { struct uart_portport; - - /* -* We provide a per-port pm hook. -*/ - void(*pm)(struct uart_port *port, - unsigned int state, unsigned int old); + /* No additional info for now */ }; #define TXX9_REGION_SIZE 0x24 @@ -277,6 +274,31 @@ static void serial_txx9_enable_ms(struct /* TXX9-SIO can not control DTR... */ } +static void serial_txx9_initialize(struct uart_port *port) +{ + struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned int tmout = 1; + + sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); + /* TX4925 BUG WORKAROUND. Accessing SIOC register +* immediately after soft reset causes bus error. */ + mmiowb(); + udelay(1); + while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout) + udelay(1); + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + sio_set(up, TXX9_SIFCR, + TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); + /* initial settings */ + sio_out(up, TXX9_SILCR, + TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | + ((up->port.flags & UPF_TXX9_USE_SCLK) ? +TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); + sio_quot_set(up, uart_get_divisor(port, 9600)); + sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); + sio_out(up, TXX9_SIDICR, 0); +} + static inline void receive_chars(struct uart_txx9_port *up, unsigned int *status) { @@ -657,9 +679,8 @@ static void serial_txx9_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { - struct uart_txx9_port *up = (struct uart_txx9_port *)port; - if (up->pm) - up->pm(port, state, oldstate); + if (state == 0) + serial_txx9_initialize(port); } static int serial_txx9_request_resource(struct uart_txx9_port *up) @@ -732,7 +753,6 @@ static int serial_txx9_request_port(stru static void serial_txx9_config_port(struct uart_port *port, int uflags) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; int ret; /* @@ -749,30 +769,7 @@ static void serial_txx9_config_port(stru if (up->port.line == up->port.cons->index) return; #endif - spin_lock_irqsave(>port.lock, flags); - /* -* Reset the UART. -*/ - sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); -#ifdef CONFIG_CPU_TX49XX - /* TX4925 BUG WORKAROUND. Accessing SIOC register -* immediately after soft reset causes bus error. */ - iob(); - udelay(1); -#endif - while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) - ; - /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ - sio_set(up, TXX9_SIFCR, - TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); - /* initial settings */ - sio_out(up, TXX9_SILCR, - TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | - ((up->port.flags & UPF_TXX9_USE_SCLK) ? -TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); - sio_quot_set(up, uart_get_divisor(port, 9600)); - sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); - spin_unlock_irqrestore(>port.lock, flags); + serial_txx9_initialize(port); } static int @@ -818,7 +815,8 @@ static struct uart_ops serial_txx9_pops static struct uart_txx9_port serial_txx9_ports[UART_NR]; -static void __init serial_txx9_register_ports(struct uart_driver *drv) +static void __init serial_txx9_register_ports(struct uart_driver *drv, + struct device *dev) { int i; @@ -827,6 +825,7 @@ static void __init serial_txx9_register_
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
> Then I'll put udelay() and a timeout counter for it. If udelay() was > in the busy loop, cpu_relax() is still recommended? The udelay should deal with it for you. > Here is a patch on top of the previous one. If this was OK I'll fold > it into one patch. Looks good to me > + while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout) > + udelay(1); > /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ > sio_set(up, TXX9_SIFCR, > TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); -- -- Sick of rip off UK rail fares ? Learn how to get far cheaper fares http://zeniv.linux.org.uk/~alan/GTR/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
On Wed, 21 Feb 2007 16:48:26 +, Alan <[EMAIL PROTECTED]> wrote: > > +#ifdef CONFIG_CPU_TX49XX > > + /* TX4925 BUG WORKAROUND. Accessing SIOC register > > +* immediately after soft reset causes bus error. */ > > + iob(); > > + udelay(1); > > +#endif > > Given this costs 1uS in a path that is not performance critical is it > worth putting the #ifdef/#endif in instead of having one set of code that > works for all ? Thank you for review. I'll drop the #ifdef. Also I'll replace iob() with mmiowb() since it is MIPS specific. > > + while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) > > + ; > > Suppose it doesn't clear ? Should also use cpu_relax() in busy loops > so any processor variant with power management can do the right thing. Then I'll put udelay() and a timeout counter for it. If udelay() was in the busy loop, cpu_relax() is still recommended? Here is a patch on top of the previous one. If this was OK I'll fold it into one patch. --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -277,16 +277,15 @@ static void serial_txx9_enable_ms(struct static void serial_txx9_initialize(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned int tmout = 1; sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); -#ifdef CONFIG_CPU_TX49XX /* TX4925 BUG WORKAROUND. Accessing SIOC register * immediately after soft reset causes bus error. */ - iob(); + mmiowb(); udelay(1); -#endif - while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) - ; + while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout) + udelay(1); /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ sio_set(up, TXX9_SIFCR, TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
On Wed, Feb 21, 2007 at 04:48:26PM +, Alan wrote: > Given this costs 1uS in a path that is not performance critical is it > worth putting the #ifdef/#endif in instead of having one set of code that > works for all ? > > > + while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) > > + ; > > Suppose it doesn't clear ? Should also use cpu_relax() in busy loops > so any processor variant with power management can do the right thing. Right now we don't have much that we could do in cpu_relax() on MIPS. The average CPU core makes extensive use of clock gating to the point where there are few powersaving knobs left in the core. Of course I'm also ignoring things outside the CPU core and clockscaling for which cpu_relax() would simply be the wrong place. Of course this driver in rare instances might run on an x86 CPU ... Ralf - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
> +static void serial_txx9_initialize(struct uart_port *port) > +{ > + struct uart_txx9_port *up = (struct uart_txx9_port *)port; > + > + sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); > +#ifdef CONFIG_CPU_TX49XX > + /* TX4925 BUG WORKAROUND. Accessing SIOC register > + * immediately after soft reset causes bus error. */ > + iob(); > + udelay(1); > +#endif Given this costs 1uS in a path that is not performance critical is it worth putting the #ifdef/#endif in instead of having one set of code that works for all ? > + while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) > + ; Suppose it doesn't clear ? Should also use cpu_relax() in busy loops so any processor variant with power management can do the right thing. Neither of course are bugs you have added, just things you have moved that seem worth asking about. Acked-by: Alan Cox <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2.6.21-rc1] serial: serial_txx9 driver update
Update the serial_txx9 driver. * Use platform_device. * Fix and cleanup suspend/resume codes. Signed-off-by: Atsushi Nemoto <[EMAIL PROTECTED]> --- diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index f4440d3..124d056 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -38,6 +38,8 @@ * Fix some spin_locks. * Do not call uart_add_one_port for absent ports. * 1.07Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. + * 1.08Use platform_device. + * Fix and cleanup suspend/resume codes. */ #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -50,7 +52,7 @@ #include #include #include -#include +#include #include #include #include @@ -60,7 +62,7 @@ #include -static char *serial_version = "1.07"; +static char *serial_version = "1.08"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -94,12 +96,7 @@ static char *serial_name = "TX39/49 Seri struct uart_txx9_port { struct uart_portport; - - /* -* We provide a per-port pm hook. -*/ - void(*pm)(struct uart_port *port, - unsigned int state, unsigned int old); + /* No additional info for now */ }; #define TXX9_REGION_SIZE 0x24 @@ -277,6 +274,32 @@ static void serial_txx9_enable_ms(struct /* TXX9-SIO can not control DTR... */ } +static void serial_txx9_initialize(struct uart_port *port) +{ + struct uart_txx9_port *up = (struct uart_txx9_port *)port; + + sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); +#ifdef CONFIG_CPU_TX49XX + /* TX4925 BUG WORKAROUND. Accessing SIOC register +* immediately after soft reset causes bus error. */ + iob(); + udelay(1); +#endif + while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) + ; + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + sio_set(up, TXX9_SIFCR, + TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); + /* initial settings */ + sio_out(up, TXX9_SILCR, + TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | + ((up->port.flags & UPF_TXX9_USE_SCLK) ? +TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); + sio_quot_set(up, uart_get_divisor(port, 9600)); + sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); + sio_out(up, TXX9_SIDICR, 0); +} + static inline void receive_chars(struct uart_txx9_port *up, unsigned int *status) { @@ -657,9 +680,8 @@ static void serial_txx9_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { - struct uart_txx9_port *up = (struct uart_txx9_port *)port; - if (up->pm) - up->pm(port, state, oldstate); + if (state == 0) + serial_txx9_initialize(port); } static int serial_txx9_request_resource(struct uart_txx9_port *up) @@ -732,7 +754,6 @@ static int serial_txx9_request_port(stru static void serial_txx9_config_port(struct uart_port *port, int uflags) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; int ret; /* @@ -749,30 +770,7 @@ static void serial_txx9_config_port(stru if (up->port.line == up->port.cons->index) return; #endif - spin_lock_irqsave(>port.lock, flags); - /* -* Reset the UART. -*/ - sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); -#ifdef CONFIG_CPU_TX49XX - /* TX4925 BUG WORKAROUND. Accessing SIOC register -* immediately after soft reset causes bus error. */ - iob(); - udelay(1); -#endif - while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) - ; - /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ - sio_set(up, TXX9_SIFCR, - TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); - /* initial settings */ - sio_out(up, TXX9_SILCR, - TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | - ((up->port.flags & UPF_TXX9_USE_SCLK) ? -TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); - sio_quot_set(up, uart_get_divisor(port, 9600)); - sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); - spin_unlock_irqrestore(>port.lock, flags); + serial_txx9_initialize(port); } static int @@ -818,7 +816,8 @@ static struct uart_ops serial_txx9_pops static struct uart_txx9_port serial_txx9_ports[UART_NR]; -static void __init serial_txx9_register_ports(struct uart_driver *drv) +static void __init serial_txx9_register_ports(struct uart_driver *drv, + struct device *dev) { int i; @@ -827,6 +826,7 @@ static void __init serial_txx9_register_ up->port.line = i; up->port.ops = _txx9_pops; + up->port.dev = dev;
[PATCH 2.6.21-rc1] serial: serial_txx9 driver update
Update the serial_txx9 driver. * Use platform_device. * Fix and cleanup suspend/resume codes. Signed-off-by: Atsushi Nemoto [EMAIL PROTECTED] --- diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index f4440d3..124d056 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -38,6 +38,8 @@ * Fix some spin_locks. * Do not call uart_add_one_port for absent ports. * 1.07Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. + * 1.08Use platform_device. + * Fix and cleanup suspend/resume codes. */ #if defined(CONFIG_SERIAL_TXX9_CONSOLE) defined(CONFIG_MAGIC_SYSRQ) @@ -50,7 +52,7 @@ #include linux/console.h #include linux/sysrq.h #include linux/delay.h -#include linux/device.h +#include linux/platform_device.h #include linux/pci.h #include linux/tty.h #include linux/tty_flip.h @@ -60,7 +62,7 @@ #include asm/io.h -static char *serial_version = 1.07; +static char *serial_version = 1.08; static char *serial_name = TX39/49 Serial driver; #define PASS_LIMIT 256 @@ -94,12 +96,7 @@ static char *serial_name = TX39/49 Seri struct uart_txx9_port { struct uart_portport; - - /* -* We provide a per-port pm hook. -*/ - void(*pm)(struct uart_port *port, - unsigned int state, unsigned int old); + /* No additional info for now */ }; #define TXX9_REGION_SIZE 0x24 @@ -277,6 +274,32 @@ static void serial_txx9_enable_ms(struct /* TXX9-SIO can not control DTR... */ } +static void serial_txx9_initialize(struct uart_port *port) +{ + struct uart_txx9_port *up = (struct uart_txx9_port *)port; + + sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); +#ifdef CONFIG_CPU_TX49XX + /* TX4925 BUG WORKAROUND. Accessing SIOC register +* immediately after soft reset causes bus error. */ + iob(); + udelay(1); +#endif + while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) + ; + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + sio_set(up, TXX9_SIFCR, + TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); + /* initial settings */ + sio_out(up, TXX9_SILCR, + TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | + ((up-port.flags UPF_TXX9_USE_SCLK) ? +TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); + sio_quot_set(up, uart_get_divisor(port, 9600)); + sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); + sio_out(up, TXX9_SIDICR, 0); +} + static inline void receive_chars(struct uart_txx9_port *up, unsigned int *status) { @@ -657,9 +680,8 @@ static void serial_txx9_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { - struct uart_txx9_port *up = (struct uart_txx9_port *)port; - if (up-pm) - up-pm(port, state, oldstate); + if (state == 0) + serial_txx9_initialize(port); } static int serial_txx9_request_resource(struct uart_txx9_port *up) @@ -732,7 +754,6 @@ static int serial_txx9_request_port(stru static void serial_txx9_config_port(struct uart_port *port, int uflags) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; int ret; /* @@ -749,30 +770,7 @@ static void serial_txx9_config_port(stru if (up-port.line == up-port.cons-index) return; #endif - spin_lock_irqsave(up-port.lock, flags); - /* -* Reset the UART. -*/ - sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); -#ifdef CONFIG_CPU_TX49XX - /* TX4925 BUG WORKAROUND. Accessing SIOC register -* immediately after soft reset causes bus error. */ - iob(); - udelay(1); -#endif - while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) - ; - /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ - sio_set(up, TXX9_SIFCR, - TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); - /* initial settings */ - sio_out(up, TXX9_SILCR, - TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | - ((up-port.flags UPF_TXX9_USE_SCLK) ? -TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); - sio_quot_set(up, uart_get_divisor(port, 9600)); - sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); - spin_unlock_irqrestore(up-port.lock, flags); + serial_txx9_initialize(port); } static int @@ -818,7 +816,8 @@ static struct uart_ops serial_txx9_pops static struct uart_txx9_port serial_txx9_ports[UART_NR]; -static void __init serial_txx9_register_ports(struct uart_driver *drv) +static void __init serial_txx9_register_ports(struct uart_driver *drv, + struct device *dev) { int i; @@ -827,6 +826,7 @@ static void __init serial_txx9_register_
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
+static void serial_txx9_initialize(struct uart_port *port) +{ + struct uart_txx9_port *up = (struct uart_txx9_port *)port; + + sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); +#ifdef CONFIG_CPU_TX49XX + /* TX4925 BUG WORKAROUND. Accessing SIOC register + * immediately after soft reset causes bus error. */ + iob(); + udelay(1); +#endif Given this costs 1uS in a path that is not performance critical is it worth putting the #ifdef/#endif in instead of having one set of code that works for all ? + while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) + ; Suppose it doesn't clear ? Should also use cpu_relax() in busy loops so any processor variant with power management can do the right thing. Neither of course are bugs you have added, just things you have moved that seem worth asking about. Acked-by: Alan Cox [EMAIL PROTECTED] - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
On Wed, Feb 21, 2007 at 04:48:26PM +, Alan wrote: Given this costs 1uS in a path that is not performance critical is it worth putting the #ifdef/#endif in instead of having one set of code that works for all ? + while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) + ; Suppose it doesn't clear ? Should also use cpu_relax() in busy loops so any processor variant with power management can do the right thing. Right now we don't have much that we could do in cpu_relax() on MIPS. The average CPU core makes extensive use of clock gating to the point where there are few powersaving knobs left in the core. Of course I'm also ignoring things outside the CPU core and clockscaling for which cpu_relax() would simply be the wrong place. Of course this driver in rare instances might run on an x86 CPU ... Ralf - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
On Wed, 21 Feb 2007 16:48:26 +, Alan [EMAIL PROTECTED] wrote: +#ifdef CONFIG_CPU_TX49XX + /* TX4925 BUG WORKAROUND. Accessing SIOC register +* immediately after soft reset causes bus error. */ + iob(); + udelay(1); +#endif Given this costs 1uS in a path that is not performance critical is it worth putting the #ifdef/#endif in instead of having one set of code that works for all ? Thank you for review. I'll drop the #ifdef. Also I'll replace iob() with mmiowb() since it is MIPS specific. + while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) + ; Suppose it doesn't clear ? Should also use cpu_relax() in busy loops so any processor variant with power management can do the right thing. Then I'll put udelay() and a timeout counter for it. If udelay() was in the busy loop, cpu_relax() is still recommended? Here is a patch on top of the previous one. If this was OK I'll fold it into one patch. --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -277,16 +277,15 @@ static void serial_txx9_enable_ms(struct static void serial_txx9_initialize(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned int tmout = 1; sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); -#ifdef CONFIG_CPU_TX49XX /* TX4925 BUG WORKAROUND. Accessing SIOC register * immediately after soft reset causes bus error. */ - iob(); + mmiowb(); udelay(1); -#endif - while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) - ; + while ((sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) --tmout) + udelay(1); /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ sio_set(up, TXX9_SIFCR, TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update
Then I'll put udelay() and a timeout counter for it. If udelay() was in the busy loop, cpu_relax() is still recommended? The udelay should deal with it for you. Here is a patch on top of the previous one. If this was OK I'll fold it into one patch. Looks good to me + while ((sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) --tmout) + udelay(1); /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ sio_set(up, TXX9_SIFCR, TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); -- -- Sick of rip off UK rail fares ? Learn how to get far cheaper fares http://zeniv.linux.org.uk/~alan/GTR/ - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2.6.21-rc1] serial: serial_txx9 driver update (take 2)
Update the serial_txx9 driver. * Use platform_device. * Fix and cleanup suspend/resume/initialization codes. Signed-off-by: Atsushi Nemoto [EMAIL PROTECTED] Acked-by: Alan Cox [EMAIL PROTECTED] --- diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index f4440d3..509ace7 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -38,6 +38,8 @@ * Fix some spin_locks. * Do not call uart_add_one_port for absent ports. * 1.07Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. + * 1.08Use platform_device. + * Fix and cleanup suspend/resume/initialization codes. */ #if defined(CONFIG_SERIAL_TXX9_CONSOLE) defined(CONFIG_MAGIC_SYSRQ) @@ -50,7 +52,7 @@ #include linux/console.h #include linux/sysrq.h #include linux/delay.h -#include linux/device.h +#include linux/platform_device.h #include linux/pci.h #include linux/tty.h #include linux/tty_flip.h @@ -60,7 +62,7 @@ #include asm/io.h -static char *serial_version = 1.07; +static char *serial_version = 1.08; static char *serial_name = TX39/49 Serial driver; #define PASS_LIMIT 256 @@ -94,12 +96,7 @@ static char *serial_name = TX39/49 Seri struct uart_txx9_port { struct uart_portport; - - /* -* We provide a per-port pm hook. -*/ - void(*pm)(struct uart_port *port, - unsigned int state, unsigned int old); + /* No additional info for now */ }; #define TXX9_REGION_SIZE 0x24 @@ -277,6 +274,31 @@ static void serial_txx9_enable_ms(struct /* TXX9-SIO can not control DTR... */ } +static void serial_txx9_initialize(struct uart_port *port) +{ + struct uart_txx9_port *up = (struct uart_txx9_port *)port; + unsigned int tmout = 1; + + sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); + /* TX4925 BUG WORKAROUND. Accessing SIOC register +* immediately after soft reset causes bus error. */ + mmiowb(); + udelay(1); + while ((sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) --tmout) + udelay(1); + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + sio_set(up, TXX9_SIFCR, + TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); + /* initial settings */ + sio_out(up, TXX9_SILCR, + TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | + ((up-port.flags UPF_TXX9_USE_SCLK) ? +TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); + sio_quot_set(up, uart_get_divisor(port, 9600)); + sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); + sio_out(up, TXX9_SIDICR, 0); +} + static inline void receive_chars(struct uart_txx9_port *up, unsigned int *status) { @@ -657,9 +679,8 @@ static void serial_txx9_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { - struct uart_txx9_port *up = (struct uart_txx9_port *)port; - if (up-pm) - up-pm(port, state, oldstate); + if (state == 0) + serial_txx9_initialize(port); } static int serial_txx9_request_resource(struct uart_txx9_port *up) @@ -732,7 +753,6 @@ static int serial_txx9_request_port(stru static void serial_txx9_config_port(struct uart_port *port, int uflags) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; int ret; /* @@ -749,30 +769,7 @@ static void serial_txx9_config_port(stru if (up-port.line == up-port.cons-index) return; #endif - spin_lock_irqsave(up-port.lock, flags); - /* -* Reset the UART. -*/ - sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); -#ifdef CONFIG_CPU_TX49XX - /* TX4925 BUG WORKAROUND. Accessing SIOC register -* immediately after soft reset causes bus error. */ - iob(); - udelay(1); -#endif - while (sio_in(up, TXX9_SIFCR) TXX9_SIFCR_SWRST) - ; - /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ - sio_set(up, TXX9_SIFCR, - TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); - /* initial settings */ - sio_out(up, TXX9_SILCR, - TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | - ((up-port.flags UPF_TXX9_USE_SCLK) ? -TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG)); - sio_quot_set(up, uart_get_divisor(port, 9600)); - sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); - spin_unlock_irqrestore(up-port.lock, flags); + serial_txx9_initialize(port); } static int @@ -818,7 +815,8 @@ static struct uart_ops serial_txx9_pops static struct uart_txx9_port serial_txx9_ports[UART_NR]; -static void __init serial_txx9_register_ports(struct uart_driver *drv) +static void __init serial_txx9_register_ports(struct uart_driver *drv, + struct device *dev) {
Re: [PATCH 2.6.21-rc1] serial: serial_txx9 driver update (take 2)
On Thu, Feb 22, 2007 at 02:17:28AM +0900, Atsushi Nemoto wrote: Update the serial_txx9 driver. * Use platform_device. * Fix and cleanup suspend/resume/initialization codes. Signed-off-by: Atsushi Nemoto [EMAIL PROTECTED] Acked-by: Alan Cox [EMAIL PROTECTED] Andrew, I've applied this patch on linux-mips.org and if nobody else raises any issues I'll take care of merging this. Ralf - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/