* [PATCH RESEND 1/2] 8250: pm callback for platform uarts
@ 2010-09-24 16:13 Manuel Lauss
2010-09-24 16:13 ` [PATCH RESEND 2/2] Alchemy: UART PM through serial framework Manuel Lauss
2010-09-24 17:22 ` [PATCH RESEND 1/2] 8250: pm callback for platform uarts Alan Cox
0 siblings, 2 replies; 6+ messages in thread
From: Manuel Lauss @ 2010-09-24 16:13 UTC (permalink / raw)
To: linux-serial; +Cc: Greg KH, Andrew Morton, Alan Cox, Manuel Lauss
The 8250 driver provides in its uart_ops a pm callback which in turn
handles 8250 pm and, if it exists, calls a private callback.
However there's no way for platform 8250 devices to assign anything
to this callback.
This patch adds a new pm field to the plat_8250_port and uart_port
structures and modifies the 8250 pm callback to call the platform
method before powering up and after powering down (if the platform
is capable of cutting power/clks to the block).
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
drivers/serial/8250.c | 15 +++++++--------
include/linux/serial_8250.h | 2 ++
include/linux/serial_core.h | 2 ++
3 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 24110f6..06606d2 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -154,12 +154,6 @@ struct uart_8250_port {
unsigned char lsr_saved_flags;
#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
unsigned char msr_saved_flags;
-
- /*
- * We provide a per-port pm hook.
- */
- void (*pm)(struct uart_port *port,
- unsigned int state, unsigned int old);
};
struct irq_info {
@@ -2446,10 +2440,13 @@ serial8250_pm(struct uart_port *port, unsigned int state,
{
struct uart_8250_port *p = (struct uart_8250_port *)port;
+ if ((p->port.pm) && (state == 0)) /* power up: call platform first */
+ p->port.pm(port, state, oldstate);
+
serial8250_set_sleep(p, state != 0);
- if (p->pm)
- p->pm(port, state, oldstate);
+ if ((p->port.pm) && (state != 0)) /* power down */
+ p->port.pm(port, state, oldstate);
}
static unsigned int serial8250_port_size(struct uart_8250_port *pt)
@@ -3010,6 +3007,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
port.serial_in = p->serial_in;
port.serial_out = p->serial_out;
port.set_termios = p->set_termios;
+ port.pm = p->pm;
port.dev = &dev->dev;
port.irqflags |= irqflag;
ret = serial8250_register_port(&port);
@@ -3161,6 +3159,7 @@ int serial8250_register_port(struct uart_port *port)
uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
uart->port.mapbase = port->mapbase;
uart->port.private_data = port->private_data;
+ uart->port.pm = port->pm;
if (port->dev)
uart->port.dev = port->dev;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 7638dea..ce3af06 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -35,6 +35,8 @@ struct plat_serial8250_port {
void (*set_termios)(struct uart_port *,
struct ktermios *new,
struct ktermios *old);
+ void (*pm)(struct uart_port *, unsigned int state,
+ unsigned old);
};
/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 563e234..632a16b 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -289,6 +289,8 @@ struct uart_port {
void (*set_termios)(struct uart_port *,
struct ktermios *new,
struct ktermios *old);
+ void (*pm)(struct uart_port *, unsigned int state,
+ unsigned int old);
unsigned int irq; /* irq number */
unsigned long irqflags; /* irq flags */
unsigned int uartclk; /* base uart clock */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH RESEND 2/2] Alchemy: UART PM through serial framework.
2010-09-24 16:13 [PATCH RESEND 1/2] 8250: pm callback for platform uarts Manuel Lauss
@ 2010-09-24 16:13 ` Manuel Lauss
2010-09-24 17:22 ` [PATCH RESEND 1/2] 8250: pm callback for platform uarts Alan Cox
1 sibling, 0 replies; 6+ messages in thread
From: Manuel Lauss @ 2010-09-24 16:13 UTC (permalink / raw)
To: linux-serial; +Cc: Greg KH, Andrew Morton, Alan Cox, Manuel Lauss
Hook up the Alchemy on-chip uarts with the platform 8250 PM callback and
enable/disable clocks to the uart blocks as needed. This also allows to
get rid of the UART1 PM hack in the Alchemy PM code.
Tested on Au1200.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
arch/mips/alchemy/common/platform.c | 23 +++++++++++++++++++++++
arch/mips/alchemy/common/power.c | 35 -----------------------------------
2 files changed, 23 insertions(+), 35 deletions(-)
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 1dc55ee..6f0afca 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -24,6 +24,28 @@
#include <prom.h>
+static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
+ unsigned int old_state)
+{
+ switch (state) {
+ case 0:
+ if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
+ /* power-on sequence as suggested in the databooks */
+ __raw_writel(0, port->membase + UART_MOD_CNTRL);
+ wmb();
+ __raw_writel(1, port->membase + UART_MOD_CNTRL);
+ wmb();
+ }
+ __raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */
+ wmb();
+ break;
+ case 3: /* power off */
+ __raw_writel(0, port->membase + UART_MOD_CNTRL);
+ wmb();
+ break;
+ }
+}
+
#define PORT(_base, _irq) \
{ \
.mapbase = _base, \
@@ -33,6 +55,7 @@
.flags = UPF_SKIP_TEST | UPF_IOREMAP | \
UPF_FIXED_TYPE, \
.type = PORT_16550A, \
+ .pm = alchemy_8250_pm, \
}
static struct plat_serial8250_port au1x00_uart_data[] = {
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index 5ef06a1..e5916a5 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -49,11 +49,6 @@
* We only have to save/restore registers that aren't otherwise
* done as part of a driver pm_* function.
*/
-static unsigned int sleep_uart0_inten;
-static unsigned int sleep_uart0_fifoctl;
-static unsigned int sleep_uart0_linectl;
-static unsigned int sleep_uart0_clkdiv;
-static unsigned int sleep_uart0_enable;
static unsigned int sleep_usb[2];
static unsigned int sleep_sys_clocks[5];
static unsigned int sleep_sys_pinfunc;
@@ -62,22 +57,6 @@ static unsigned int sleep_static_memctlr[4][3];
static void save_core_regs(void)
{
- extern void save_au1xxx_intctl(void);
- extern void pm_eth0_shutdown(void);
-
- /*
- * Do the serial ports.....these really should be a pm_*
- * registered function by the driver......but of course the
- * standard serial driver doesn't understand our Au1xxx
- * unique registers.
- */
- sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER);
- sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR);
- sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
- sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
- sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
- au_sync();
-
#ifndef CONFIG_SOC_AU1200
/* Shutdown USB host/device. */
sleep_usb[0] = au_readl(USB_HOST_CONFIG);
@@ -175,20 +154,6 @@ static void restore_core_regs(void)
au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
-
- /*
- * Enable the UART if it was enabled before sleep.
- * I guess I should define module control bits........
- */
- if (sleep_uart0_enable & 0x02) {
- au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync();
- au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync();
- au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync();
- au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync();
- au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync();
- au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync();
- au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync();
- }
}
void au_sleep(void)
--
1.7.2.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH RESEND 1/2] 8250: pm callback for platform uarts
2010-09-24 16:13 [PATCH RESEND 1/2] 8250: pm callback for platform uarts Manuel Lauss
2010-09-24 16:13 ` [PATCH RESEND 2/2] Alchemy: UART PM through serial framework Manuel Lauss
@ 2010-09-24 17:22 ` Alan Cox
2010-09-24 17:15 ` Manuel Lauss
1 sibling, 1 reply; 6+ messages in thread
From: Alan Cox @ 2010-09-24 17:22 UTC (permalink / raw)
To: Manuel Lauss; +Cc: linux-serial, Greg KH, Andrew Morton
> This patch adds a new pm field to the plat_8250_port and uart_port
> structures and modifies the 8250 pm callback to call the platform
> method before powering up and after powering down (if the platform
> is capable of cutting power/clks to the block).
This doesn't entirely make sense. Any hook in uart_port would be one to
apply outside of 8250.c
You also don't want platform specific stuff in the core 8250 code or to
go removing stuff without being very careful about who or what uses it.
> + if ((p->port.pm) && (state != 0)) /* power down */
Excess brackets
> + p->port.pm(port, state, oldstate);
> }
>
> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
> index 7638dea..ce3af06 100644
> --- a/include/linux/serial_8250.h
> +++ b/include/linux/serial_8250.h
> @@ -35,6 +35,8 @@ struct plat_serial8250_port {
> void (*set_termios)(struct uart_port *,
> struct ktermios *new,
> struct ktermios *old);
> + void (*pm)(struct uart_port *, unsigned int state,
> + unsigned old);
> };
This bit makes sense - but why can't you simply propogate it to the
existing uart_8250_port callback when registering ?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RESEND 1/2] 8250: pm callback for platform uarts
2010-09-24 17:22 ` [PATCH RESEND 1/2] 8250: pm callback for platform uarts Alan Cox
@ 2010-09-24 17:15 ` Manuel Lauss
2010-09-24 23:50 ` Alan Cox
0 siblings, 1 reply; 6+ messages in thread
From: Manuel Lauss @ 2010-09-24 17:15 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-serial, Greg KH, Andrew Morton
Hello,
On Fri, Sep 24, 2010 at 7:22 PM, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> This patch adds a new pm field to the plat_8250_port and uart_port
>> structures and modifies the 8250 pm callback to call the platform
>> method before powering up and after powering down (if the platform
>> is capable of cutting power/clks to the block).
>
> This doesn't entirely make sense. Any hook in uart_port would be one to
> apply outside of 8250.c
>
> You also don't want platform specific stuff in the core 8250 code or to
> go removing stuff without being very careful about who or what uses it.
>
>
>> + if ((p->port.pm) && (state != 0)) /* power down */
>
> Excess brackets
Gone,
>> + p->port.pm(port, state, oldstate);
>> }
>>
>
>> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
>> index 7638dea..ce3af06 100644
>> --- a/include/linux/serial_8250.h
>> +++ b/include/linux/serial_8250.h
>> @@ -35,6 +35,8 @@ struct plat_serial8250_port {
>> void (*set_termios)(struct uart_port *,
>> struct ktermios *new,
>> struct ktermios *old);
>> + void (*pm)(struct uart_port *, unsigned int state,
>> + unsigned old);
>> };
>
> This bit makes sense - but why can't you simply propogate it to the
> existing uart_8250_port callback when registering ?
I need a hook for platform code to reenable the UART block clocks before
serial8250_set_sleep() is invoked on resume. The current code actually
works, it's just that on resume the bootloader disables the clocks for
all UART blocks except the debug one, which leaves all others dead.
So I added the these calls into these platform methods around
serial8250_set_sleep().
Thanks!
Manuel Lauss
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RESEND 1/2] 8250: pm callback for platform uarts
2010-09-24 17:15 ` Manuel Lauss
@ 2010-09-24 23:50 ` Alan Cox
2010-09-24 23:41 ` Greg KH
0 siblings, 1 reply; 6+ messages in thread
From: Alan Cox @ 2010-09-24 23:50 UTC (permalink / raw)
To: Manuel Lauss; +Cc: linux-serial, Greg KH, Andrew Morton
> > This bit makes sense - but why can't you simply propogate it to the
> > existing uart_8250_port callback when registering ?
>
>
> I need a hook for platform code to reenable the UART block clocks before
> serial8250_set_sleep() is invoked on resume. The current code actually
> works, it's just that on resume the bootloader disables the clocks for
> all UART blocks except the debug one, which leaves all others dead.
>
> So I added the these calls into these platform methods around
> serial8250_set_sleep().
Which isn't the right way to do this IMHO. It may work for your specific
case but a solution needs to be generic.
The comment about sticking it in the wrong structd also holds.
So NAK this patch.
Put the callback in the right struct, and make it do the whole work. One
way to do that would be to make the existing method
serial8250_do_...
and the main one call the _do_xxx method if no private one is defined.
For your specific hardware you'd have a replacement method which called
the default one in the middle.
Alan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH RESEND 1/2] 8250: pm callback for platform uarts
2010-09-24 23:50 ` Alan Cox
@ 2010-09-24 23:41 ` Greg KH
0 siblings, 0 replies; 6+ messages in thread
From: Greg KH @ 2010-09-24 23:41 UTC (permalink / raw)
To: Alan Cox; +Cc: Manuel Lauss, linux-serial, Andrew Morton
On Sat, Sep 25, 2010 at 12:50:40AM +0100, Alan Cox wrote:
> > > This bit makes sense - but why can't you simply propogate it to the
> > > existing uart_8250_port callback when registering ?
> >
> >
> > I need a hook for platform code to reenable the UART block clocks before
> > serial8250_set_sleep() is invoked on resume. The current code actually
> > works, it's just that on resume the bootloader disables the clocks for
> > all UART blocks except the debug one, which leaves all others dead.
> >
> > So I added the these calls into these platform methods around
> > serial8250_set_sleep().
>
> Which isn't the right way to do this IMHO. It may work for your specific
> case but a solution needs to be generic.
>
> The comment about sticking it in the wrong structd also holds.
>
> So NAK this patch.
Ok, I'll go drop the two patches in this series from my tree.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-09-24 23:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-24 16:13 [PATCH RESEND 1/2] 8250: pm callback for platform uarts Manuel Lauss
2010-09-24 16:13 ` [PATCH RESEND 2/2] Alchemy: UART PM through serial framework Manuel Lauss
2010-09-24 17:22 ` [PATCH RESEND 1/2] 8250: pm callback for platform uarts Alan Cox
2010-09-24 17:15 ` Manuel Lauss
2010-09-24 23:50 ` Alan Cox
2010-09-24 23:41 ` Greg KH
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).