diff mbox

[PATCHv4] serial: of-serial: fix up PM ops on no_console_suspend and port type

Message ID 1413276146-20388-1-git-send-email-jingchang.lu@freescale.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jingchang Lu Oct. 14, 2014, 8:42 a.m. UTC
This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
"serial: of-serial: add PM suspend/resume support", which disables
the uart clock on suspend, but also causes a hardware hang on register
access if no_console_suspend command line option is used.

Also, not every of_serial device is an 8250 port, so the serial8250
suspend/resume functions should only be applied to a real 8250 port.

Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
---
changes in v4:
 separate 8250 port suspend/resume from of_serial_suspend/resume.

changes in v3:
 fix up point reference and deference.

changes in v2:
 add switch selection on uart type.

 drivers/tty/serial/of_serial.c | 52 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 7 deletions(-)

Comments

Peter Hurley Oct. 14, 2014, 10:31 a.m. UTC | #1
On 10/14/2014 04:42 AM, Jingchang Lu wrote:
> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
> "serial: of-serial: add PM suspend/resume support", which disables
> the uart clock on suspend, but also causes a hardware hang on register
> access if no_console_suspend command line option is used.
> 
> Also, not every of_serial device is an 8250 port, so the serial8250
> suspend/resume functions should only be applied to a real 8250 port.

Thanks.

Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
Joseph Lo Oct. 15, 2014, 1:01 a.m. UTC | #2
On 10/14/2014 04:42 PM, Jingchang Lu wrote:
> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
> "serial: of-serial: add PM suspend/resume support", which disables
> the uart clock on suspend, but also causes a hardware hang on register
> access if no_console_suspend command line option is used.
>
> Also, not every of_serial device is an 8250 port, so the serial8250
> suspend/resume functions should only be applied to a real 8250 port.
>
> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>

If you can make sure this patch can build without include 
<linux/console.h>, then this patch

Tested-by: Joseph Lo <josephl@nvidia.com>

And thanks for your fix.

> ---
> changes in v4:
>   separate 8250 port suspend/resume from of_serial_suspend/resume.
>
> changes in v3:
>   fix up point reference and deference.
>
> changes in v2:
>   add switch selection on uart type.
>
>   drivers/tty/serial/of_serial.c | 52 ++++++++++++++++++++++++++++++++++++------
>   1 file changed, 45 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
> index 8bc2563..5281f8f 100644
> --- a/drivers/tty/serial/of_serial.c
> +++ b/drivers/tty/serial/of_serial.c
> @@ -241,13 +241,48 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
>   }
>
>   #ifdef CONFIG_PM_SLEEP
> -static int of_serial_suspend(struct device *dev)
> +#ifdef CONFIG_SERIAL_8250
> +static void of_serial_suspend_8250(struct of_serial_info *info)
>   {
> -	struct of_serial_info *info = dev_get_drvdata(dev);
> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
> +	struct uart_port *port = &port8250->port;
>
>   	serial8250_suspend_port(info->line);
> -	if (info->clk)
> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>   		clk_disable_unprepare(info->clk);
> +}
> +
> +static void of_serial_resume_8250(struct of_serial_info *info)
> +{
> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
> +	struct uart_port *port = &port8250->port;
> +
> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
> +		clk_prepare_enable(info->clk);
> +
> +	serial8250_resume_port(info->line);
> +}
> +#else
> +static inline void of_serial_suspend_8250(struct of_serial_info *info)
> +{
> +}
> +
> +static inline void of_serial_resume_8250(struct of_serial_info *info)
> +{
> +}
> +#endif
> +
> +static int of_serial_suspend(struct device *dev)
> +{
> +	struct of_serial_info *info = dev_get_drvdata(dev);
> +
> +	switch(info->type) {
> +	case PORT_8250 ... PORT_MAX_8250:
> +		of_serial_suspend_8250(info);
> +		break;
> +	default:
> +		break;
> +	}
>
>   	return 0;
>   }
> @@ -256,10 +291,13 @@ static int of_serial_resume(struct device *dev)
>   {
>   	struct of_serial_info *info = dev_get_drvdata(dev);
>
> -	if (info->clk)
> -		clk_prepare_enable(info->clk);
> -
> -	serial8250_resume_port(info->line);
> +	switch(info->type) {
> +	case PORT_8250 ... PORT_MAX_8250:
> +		of_serial_resume_8250(info);
> +		break;
> +	default:
> +		break;
> +	}
>
>   	return 0;
>   }
>
Jingchang Lu Oct. 15, 2014, 6:32 a.m. UTC | #3
>-----Original Message-----
>From: Joseph Lo [mailto:josephl@nvidia.com]
>Sent: Wednesday, October 15, 2014 9:01 AM
>To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>Cc: peter@hurleysoftware.com; arnd@arndb.de; linux-kernel@vger.kernel.org;
>linux-serial@vger.kernel.org; linux-arm-kernel@lists.infradead.org
>Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>no_console_suspend and port type
>
>On 10/14/2014 04:42 PM, Jingchang Lu wrote:
>> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
>> "serial: of-serial: add PM suspend/resume support", which disables the
>> uart clock on suspend, but also causes a hardware hang on register
>> access if no_console_suspend command line option is used.
>>
>> Also, not every of_serial device is an 8250 port, so the serial8250
>> suspend/resume functions should only be applied to a real 8250 port.
>>
>> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>
>If you can make sure this patch can build without include
><linux/console.h>, then this patch
The build passes on my cloned linux-next tree, include next-20141014,
but is required on my another kernel-3.12+ based tree, then I didn't
add this header file when upstream. 
Is the build broken on your source tree, and is the tree latest?
If the header is needed, I will add it.
Thanks.

Best Regards,
Jingchang
>
>Tested-by: Joseph Lo <josephl@nvidia.com>
>
>And thanks for your fix.
>
>> ---
>> changes in v4:
>>   separate 8250 port suspend/resume from of_serial_suspend/resume.
>>
>> changes in v3:
>>   fix up point reference and deference.
>>
>> changes in v2:
>>   add switch selection on uart type.
>>
>>   drivers/tty/serial/of_serial.c | 52
>++++++++++++++++++++++++++++++++++++------
>>   1 file changed, 45 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/tty/serial/of_serial.c
>> b/drivers/tty/serial/of_serial.c index 8bc2563..5281f8f 100644
>> --- a/drivers/tty/serial/of_serial.c
>> +++ b/drivers/tty/serial/of_serial.c
>> @@ -241,13 +241,48 @@ static int of_platform_serial_remove(struct
>platform_device *ofdev)
>>   }
>>
>>   #ifdef CONFIG_PM_SLEEP
>> -static int of_serial_suspend(struct device *dev)
>> +#ifdef CONFIG_SERIAL_8250
>> +static void of_serial_suspend_8250(struct of_serial_info *info)
>>   {
>> -	struct of_serial_info *info = dev_get_drvdata(dev);
>> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
>> +	struct uart_port *port = &port8250->port;
>>
>>   	serial8250_suspend_port(info->line);
>> -	if (info->clk)
>> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>>   		clk_disable_unprepare(info->clk);
>> +}
>> +
>> +static void of_serial_resume_8250(struct of_serial_info *info) {
>> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
>> +	struct uart_port *port = &port8250->port;
>> +
>> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>> +		clk_prepare_enable(info->clk);
>> +
>> +	serial8250_resume_port(info->line);
>> +}
>> +#else
>> +static inline void of_serial_suspend_8250(struct of_serial_info
>> +*info) { }
>> +
>> +static inline void of_serial_resume_8250(struct of_serial_info *info)
>> +{ } #endif
>> +
>> +static int of_serial_suspend(struct device *dev) {
>> +	struct of_serial_info *info = dev_get_drvdata(dev);
>> +
>> +	switch(info->type) {
>> +	case PORT_8250 ... PORT_MAX_8250:
>> +		of_serial_suspend_8250(info);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>>
>>   	return 0;
>>   }
>> @@ -256,10 +291,13 @@ static int of_serial_resume(struct device *dev)
>>   {
>>   	struct of_serial_info *info = dev_get_drvdata(dev);
>>
>> -	if (info->clk)
>> -		clk_prepare_enable(info->clk);
>> -
>> -	serial8250_resume_port(info->line);
>> +	switch(info->type) {
>> +	case PORT_8250 ... PORT_MAX_8250:
>> +		of_serial_resume_8250(info);
>> +		break;
>> +	default:
>> +		break;
>> +	}
>>
>>   	return 0;
>>   }
>>
Joseph Lo Oct. 15, 2014, 6:41 a.m. UTC | #4
On 10/15/2014 02:32 PM, Jingchang Lu wrote:
>> -----Original Message-----
>> From: Joseph Lo [mailto:josephl@nvidia.com]
>> Sent: Wednesday, October 15, 2014 9:01 AM
>> To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>> Cc: peter@hurleysoftware.com; arnd@arndb.de; linux-kernel@vger.kernel.org;
>> linux-serial@vger.kernel.org; linux-arm-kernel@lists.infradead.org
>> Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>> no_console_suspend and port type
>>
>> On 10/14/2014 04:42 PM, Jingchang Lu wrote:
>>> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
>>> "serial: of-serial: add PM suspend/resume support", which disables the
>>> uart clock on suspend, but also causes a hardware hang on register
>>> access if no_console_suspend command line option is used.
>>>
>>> Also, not every of_serial device is an 8250 port, so the serial8250
>>> suspend/resume functions should only be applied to a real 8250 port.
>>>
>>> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>>
>> If you can make sure this patch can build without include
>> <linux/console.h>, then this patch
> The build passes on my cloned linux-next tree, include next-20141014,
> but is required on my another kernel-3.12+ based tree, then I didn't
> add this header file when upstream.
> Is the build broken on your source tree, and is the tree latest?
> If the header is needed, I will add it.
I tested it on next-20141013 and k3.14, both of them need the fix. I can 
check it again against the latest linux-next tree later. Thanks.

-Joseph

> Thanks.
>
> Best Regards,
> Jingchang
>>
>> Tested-by: Joseph Lo <josephl@nvidia.com>
>>
>> And thanks for your fix.
>>
>>> ---
>>> changes in v4:
>>>    separate 8250 port suspend/resume from of_serial_suspend/resume.
>>>
>>> changes in v3:
>>>    fix up point reference and deference.
>>>
>>> changes in v2:
>>>    add switch selection on uart type.
>>>
>>>    drivers/tty/serial/of_serial.c | 52
>> ++++++++++++++++++++++++++++++++++++------
>>>    1 file changed, 45 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/tty/serial/of_serial.c
>>> b/drivers/tty/serial/of_serial.c index 8bc2563..5281f8f 100644
>>> --- a/drivers/tty/serial/of_serial.c
>>> +++ b/drivers/tty/serial/of_serial.c
>>> @@ -241,13 +241,48 @@ static int of_platform_serial_remove(struct
>> platform_device *ofdev)
>>>    }
>>>
>>>    #ifdef CONFIG_PM_SLEEP
>>> -static int of_serial_suspend(struct device *dev)
>>> +#ifdef CONFIG_SERIAL_8250
>>> +static void of_serial_suspend_8250(struct of_serial_info *info)
>>>    {
>>> -	struct of_serial_info *info = dev_get_drvdata(dev);
>>> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
>>> +	struct uart_port *port = &port8250->port;
>>>
>>>    	serial8250_suspend_port(info->line);
>>> -	if (info->clk)
>>> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>>>    		clk_disable_unprepare(info->clk);
>>> +}
>>> +
>>> +static void of_serial_resume_8250(struct of_serial_info *info) {
>>> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
>>> +	struct uart_port *port = &port8250->port;
>>> +
>>> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>>> +		clk_prepare_enable(info->clk);
>>> +
>>> +	serial8250_resume_port(info->line);
>>> +}
>>> +#else
>>> +static inline void of_serial_suspend_8250(struct of_serial_info
>>> +*info) { }
>>> +
>>> +static inline void of_serial_resume_8250(struct of_serial_info *info)
>>> +{ } #endif
>>> +
>>> +static int of_serial_suspend(struct device *dev) {
>>> +	struct of_serial_info *info = dev_get_drvdata(dev);
>>> +
>>> +	switch(info->type) {
>>> +	case PORT_8250 ... PORT_MAX_8250:
>>> +		of_serial_suspend_8250(info);
>>> +		break;
>>> +	default:
>>> +		break;
>>> +	}
>>>
>>>    	return 0;
>>>    }
>>> @@ -256,10 +291,13 @@ static int of_serial_resume(struct device *dev)
>>>    {
>>>    	struct of_serial_info *info = dev_get_drvdata(dev);
>>>
>>> -	if (info->clk)
>>> -		clk_prepare_enable(info->clk);
>>> -
>>> -	serial8250_resume_port(info->line);
>>> +	switch(info->type) {
>>> +	case PORT_8250 ... PORT_MAX_8250:
>>> +		of_serial_resume_8250(info);
>>> +		break;
>>> +	default:
>>> +		break;
>>> +	}
>>>
>>>    	return 0;
>>>    }
>>>
Joseph Lo Oct. 15, 2014, 6:52 a.m. UTC | #5
On 10/15/2014 02:41 PM, Joseph Lo wrote:
> On 10/15/2014 02:32 PM, Jingchang Lu wrote:
>>> -----Original Message-----
>>> From: Joseph Lo [mailto:josephl@nvidia.com]
>>> Sent: Wednesday, October 15, 2014 9:01 AM
>>> To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>>> Cc: peter@hurleysoftware.com; arnd@arndb.de; linux-kernel@vger.kernel.org;
>>> linux-serial@vger.kernel.org; linux-arm-kernel@lists.infradead.org
>>> Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>>> no_console_suspend and port type
>>>
>>> On 10/14/2014 04:42 PM, Jingchang Lu wrote:
>>>> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
>>>> "serial: of-serial: add PM suspend/resume support", which disables the
>>>> uart clock on suspend, but also causes a hardware hang on register
>>>> access if no_console_suspend command line option is used.
>>>>
>>>> Also, not every of_serial device is an 8250 port, so the serial8250
>>>> suspend/resume functions should only be applied to a real 8250 port.
>>>>
>>>> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>>>
>>> If you can make sure this patch can build without include
>>> <linux/console.h>, then this patch
>> The build passes on my cloned linux-next tree, include next-20141014,
>> but is required on my another kernel-3.12+ based tree, then I didn't
>> add this header file when upstream.
>> Is the build broken on your source tree, and is the tree latest?
>> If the header is needed, I will add it.
> I tested it on next-20141013 and k3.14, both of them need the fix. I can
> check it again against the latest linux-next tree later. Thanks.
>
OK, I confirmed it. You should add the header file. It also doesn't 
build for me with the latest linux-next tree. Maybe you missed to enable 
CONFIG_PM_SLEEP or CONFIG_SERIAL_8250 when doing the build test in 
linux-next tree.

-Joseph
Jingchang Lu Oct. 15, 2014, 6:53 a.m. UTC | #6
>-----Original Message-----
>From: Joseph Lo [mailto:josephl@nvidia.com]
>Sent: Wednesday, October 15, 2014 2:42 PM
>To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>Cc: peter@hurleysoftware.com; arnd@arndb.de; linux-kernel@vger.kernel.org;
>linux-serial@vger.kernel.org; linux-arm-kernel@lists.infradead.org
>Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>no_console_suspend and port type
>
>On 10/15/2014 02:32 PM, Jingchang Lu wrote:
>>> -----Original Message-----
>>> From: Joseph Lo [mailto:josephl@nvidia.com]
>>> Sent: Wednesday, October 15, 2014 9:01 AM
>>> To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>>> Cc: peter@hurleysoftware.com; arnd@arndb.de;
>>> linux-kernel@vger.kernel.org; linux-serial@vger.kernel.org;
>>> linux-arm-kernel@lists.infradead.org
>>> Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>>> no_console_suspend and port type
>>>
>>> On 10/14/2014 04:42 PM, Jingchang Lu wrote:
>>>> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
>>>> "serial: of-serial: add PM suspend/resume support", which disables
>>>> the uart clock on suspend, but also causes a hardware hang on
>>>> register access if no_console_suspend command line option is used.
>>>>
>>>> Also, not every of_serial device is an 8250 port, so the serial8250
>>>> suspend/resume functions should only be applied to a real 8250 port.
>>>>
>>>> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>>>
>>> If you can make sure this patch can build without include
>>> <linux/console.h>, then this patch
>> The build passes on my cloned linux-next tree, include next-20141014,
>> but is required on my another kernel-3.12+ based tree, then I didn't
>> add this header file when upstream.
>> Is the build broken on your source tree, and is the tree latest?
>> If the header is needed, I will add it.
>I tested it on next-20141013 and k3.14, both of them need the fix. I can
>check it again against the latest linux-next tree later. Thanks.
Sorry, it is needed indeed, I have forgotten enable the PM in the next tree
due the lack of PM supporting of my board, I test the function on my 3.12 tree.
I will add it right now.

Best Regards,
Jingchang
>
>-Joseph
>
>> Thanks.
>>
>> Best Regards,
>> Jingchang
>>>
>>> Tested-by: Joseph Lo <josephl@nvidia.com>
>>>
>>> And thanks for your fix.
>>>
>>>> ---
>>>> changes in v4:
>>>>    separate 8250 port suspend/resume from of_serial_suspend/resume.
>>>>
>>>> changes in v3:
>>>>    fix up point reference and deference.
>>>>
>>>> changes in v2:
>>>>    add switch selection on uart type.
>>>>
>>>>    drivers/tty/serial/of_serial.c | 52
>>> ++++++++++++++++++++++++++++++++++++------
>>>>    1 file changed, 45 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/of_serial.c
>>>> b/drivers/tty/serial/of_serial.c index 8bc2563..5281f8f 100644
>>>> --- a/drivers/tty/serial/of_serial.c
>>>> +++ b/drivers/tty/serial/of_serial.c
>>>> @@ -241,13 +241,48 @@ static int of_platform_serial_remove(struct
>>> platform_device *ofdev)
>>>>    }
>>>>
>>>>    #ifdef CONFIG_PM_SLEEP
>>>> -static int of_serial_suspend(struct device *dev)
>>>> +#ifdef CONFIG_SERIAL_8250
>>>> +static void of_serial_suspend_8250(struct of_serial_info *info)
>>>>    {
>>>> -	struct of_serial_info *info = dev_get_drvdata(dev);
>>>> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
>>>> +	struct uart_port *port = &port8250->port;
>>>>
>>>>    	serial8250_suspend_port(info->line);
>>>> -	if (info->clk)
>>>> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>>>>    		clk_disable_unprepare(info->clk);
>>>> +}
>>>> +
>>>> +static void of_serial_resume_8250(struct of_serial_info *info) {
>>>> +	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
>>>> +	struct uart_port *port = &port8250->port;
>>>> +
>>>> +	if (info->clk && (!uart_console(port) || console_suspend_enabled))
>>>> +		clk_prepare_enable(info->clk);
>>>> +
>>>> +	serial8250_resume_port(info->line);
>>>> +}
>>>> +#else
>>>> +static inline void of_serial_suspend_8250(struct of_serial_info
>>>> +*info) { }
>>>> +
>>>> +static inline void of_serial_resume_8250(struct of_serial_info
>>>> +*info) { } #endif
>>>> +
>>>> +static int of_serial_suspend(struct device *dev) {
>>>> +	struct of_serial_info *info = dev_get_drvdata(dev);
>>>> +
>>>> +	switch(info->type) {
>>>> +	case PORT_8250 ... PORT_MAX_8250:
>>>> +		of_serial_suspend_8250(info);
>>>> +		break;
>>>> +	default:
>>>> +		break;
>>>> +	}
>>>>
>>>>    	return 0;
>>>>    }
>>>> @@ -256,10 +291,13 @@ static int of_serial_resume(struct device *dev)
>>>>    {
>>>>    	struct of_serial_info *info = dev_get_drvdata(dev);
>>>>
>>>> -	if (info->clk)
>>>> -		clk_prepare_enable(info->clk);
>>>> -
>>>> -	serial8250_resume_port(info->line);
>>>> +	switch(info->type) {
>>>> +	case PORT_8250 ... PORT_MAX_8250:
>>>> +		of_serial_resume_8250(info);
>>>> +		break;
>>>> +	default:
>>>> +		break;
>>>> +	}
>>>>
>>>>    	return 0;
>>>>    }
>>>>
Jingchang Lu Oct. 15, 2014, 7:16 a.m. UTC | #7
>-----Original Message-----
>From: Joseph Lo [mailto:josephl@nvidia.com]
>Sent: Wednesday, October 15, 2014 2:53 PM
>To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>Cc: linux-arm-kernel@lists.infradead.org; linux-serial@vger.kernel.org;
>peter@hurleysoftware.com; arnd@arndb.de; linux-kernel@vger.kernel.org
>Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>no_console_suspend and port type
>
>On 10/15/2014 02:41 PM, Joseph Lo wrote:
>> On 10/15/2014 02:32 PM, Jingchang Lu wrote:
>>>> -----Original Message-----
>>>> From: Joseph Lo [mailto:josephl@nvidia.com]
>>>> Sent: Wednesday, October 15, 2014 9:01 AM
>>>> To: Lu Jingchang-B35083; gregkh@linuxfoundation.org
>>>> Cc: peter@hurleysoftware.com; arnd@arndb.de;
>>>> linux-kernel@vger.kernel.org; linux-serial@vger.kernel.org;
>>>> linux-arm-kernel@lists.infradead.org
>>>> Subject: Re: [PATCHv4] serial: of-serial: fix up PM ops on
>>>> no_console_suspend and port type
>>>>
>>>> On 10/14/2014 04:42 PM, Jingchang Lu wrote:
>>>>> This patch fixes commit 2dea53bf57783f243c892e99c10c6921e956aa7e,
>>>>> "serial: of-serial: add PM suspend/resume support", which disables
>>>>> the uart clock on suspend, but also causes a hardware hang on
>>>>> register access if no_console_suspend command line option is used.
>>>>>
>>>>> Also, not every of_serial device is an 8250 port, so the serial8250
>>>>> suspend/resume functions should only be applied to a real 8250 port.
>>>>>
>>>>> Signed-off-by: Jingchang Lu <jingchang.lu@freescale.com>
>>>>
>>>> If you can make sure this patch can build without include
>>>> <linux/console.h>, then this patch
>>> The build passes on my cloned linux-next tree, include next-20141014,
>>> but is required on my another kernel-3.12+ based tree, then I didn't
>>> add this header file when upstream.
>>> Is the build broken on your source tree, and is the tree latest?
>>> If the header is needed, I will add it.
>> I tested it on next-20141013 and k3.14, both of them need the fix. I
>> can check it again against the latest linux-next tree later. Thanks.
>>
>OK, I confirmed it. You should add the header file. It also doesn't build
>for me with the latest linux-next tree. Maybe you missed to enable
>CONFIG_PM_SLEEP or CONFIG_SERIAL_8250 when doing the build test in linux-
>next tree.
I have sent out the v5 patch with last git-send-email command line,
didn't realized the missing of your email address in the cc list when sending.
Please help review the v5 patch. Thanks.

Best Regards,
Jingchang
>
>-Joseph
diff mbox

Patch

diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 8bc2563..5281f8f 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -241,13 +241,48 @@  static int of_platform_serial_remove(struct platform_device *ofdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int of_serial_suspend(struct device *dev)
+#ifdef CONFIG_SERIAL_8250
+static void of_serial_suspend_8250(struct of_serial_info *info)
 {
-	struct of_serial_info *info = dev_get_drvdata(dev);
+	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
+	struct uart_port *port = &port8250->port;
 
 	serial8250_suspend_port(info->line);
-	if (info->clk)
+	if (info->clk && (!uart_console(port) || console_suspend_enabled))
 		clk_disable_unprepare(info->clk);
+}
+
+static void of_serial_resume_8250(struct of_serial_info *info)
+{
+	struct uart_8250_port *port8250 = serial8250_get_port(info->line);
+	struct uart_port *port = &port8250->port;
+
+	if (info->clk && (!uart_console(port) || console_suspend_enabled))
+		clk_prepare_enable(info->clk);
+
+	serial8250_resume_port(info->line);
+}
+#else
+static inline void of_serial_suspend_8250(struct of_serial_info *info)
+{
+}
+
+static inline void of_serial_resume_8250(struct of_serial_info *info)
+{
+}
+#endif
+
+static int of_serial_suspend(struct device *dev)
+{
+	struct of_serial_info *info = dev_get_drvdata(dev);
+
+	switch(info->type) {
+	case PORT_8250 ... PORT_MAX_8250:
+		of_serial_suspend_8250(info);
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }
@@ -256,10 +291,13 @@  static int of_serial_resume(struct device *dev)
 {
 	struct of_serial_info *info = dev_get_drvdata(dev);
 
-	if (info->clk)
-		clk_prepare_enable(info->clk);
-
-	serial8250_resume_port(info->line);
+	switch(info->type) {
+	case PORT_8250 ... PORT_MAX_8250:
+		of_serial_resume_8250(info);
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }