From: Marc Kleine-Budde <mkl@pengutronix.de>
To: "AnilKumar, Chimata" <anilkumar@ti.com>
Cc: "wg@grandegger.com" <wg@grandegger.com>,
"tony@atomide.com" <tony@atomide.com>,
"linux-can@vger.kernel.org" <linux-can@vger.kernel.org>,
"linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH 4/4] can: c_can: Add d_can suspend resume support
Date: Tue, 04 Sep 2012 09:27:18 +0200 [thread overview]
Message-ID: <5045AD56.2050400@pengutronix.de> (raw)
In-Reply-To: <331ABD5ECB02734CA317220B2BBEABC13EA26300@DBDE01.ent.ti.com>
[-- Attachment #1: Type: text/plain, Size: 10412 bytes --]
On 09/04/2012 08:14 AM, AnilKumar, Chimata wrote:
> Marc,
>
> Thanks for the comments,
>
> On Tue, Sep 04, 2012 at 01:31:35, Marc Kleine-Budde wrote:
>> On 09/03/2012 01:52 PM, AnilKumar Ch wrote:
>>> Adds suspend resume support to DCAN driver which enables
>>> DCAN power down mode bit (PDR). Then DCAN will ack the local
>>> power-down mode by setting PDA bit in STATUS register.
>>>
>>> Also adds a status flag to know the status of DCAN module,
>>> whether it is opened or not.
>>
>> Use "ndev->flags & IFF_UP" for that. Have a look at the at91_can driver
>> [1]. I'm not sure if you need locking here.
>>
>
> Then I can use this to check the status, lock is not
> required.
>
>> [1] http://lxr.free-electrons.com/source/drivers/net/can/at91_can.c#L1198
>>
>>> Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
>>> ---
>>> drivers/net/can/c_can/c_can.c | 78 ++++++++++++++++++++++++++++++++
>>> drivers/net/can/c_can/c_can.h | 5 ++
>>> drivers/net/can/c_can/c_can_platform.c | 70 ++++++++++++++++++++++++++--
>>> 3 files changed, 150 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
>>> index c175410..36d5db4 100644
>>> --- a/drivers/net/can/c_can/c_can.c
>>> +++ b/drivers/net/can/c_can/c_can.c
>>> @@ -46,6 +46,9 @@
>>> #define IF_ENUM_REG_LEN 11
>>> #define C_CAN_IFACE(reg, iface) (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN)
>>>
>>> +/* control extension register D_CAN specific */
>>> +#define CONTROL_EX_PDR BIT(8)
>>> +
>>> /* control register */
>>> #define CONTROL_TEST BIT(7)
>>> #define CONTROL_CCE BIT(6)
>>> @@ -65,6 +68,7 @@
>>> #define TEST_BASIC BIT(2)
>>>
>>> /* status register */
>>> +#define STATUS_PDA BIT(10)
>>> #define STATUS_BOFF BIT(7)
>>> #define STATUS_EWARN BIT(6)
>>> #define STATUS_EPASS BIT(5)
>>> @@ -164,6 +168,9 @@
>>> /* minimum timeout for checking BUSY status */
>>> #define MIN_TIMEOUT_VALUE 6
>>>
>>> +/* Wait for ~1 sec for INIT bit */
>>> +#define INIT_WAIT_COUNT 1000
>>
>> What unit? INIT_WAIT_MS would be a better name.
>>
>
> Sure, will change
>
>>> +
>>> /* napi related */
>>> #define C_CAN_NAPI_WEIGHT C_CAN_MSG_OBJ_RX_NUM
>>>
>>> @@ -1102,6 +1109,7 @@ static int c_can_open(struct net_device *dev)
>>>
>>> netif_start_queue(dev);
>>>
>>> + priv->is_opened = true;
>>> return 0;
>>>
>>> exit_irq_fail:
>>> @@ -1126,6 +1134,7 @@ static int c_can_close(struct net_device *dev)
>>> /* De-Initialize DCAN RAM */
>>> c_can_reset_ram(priv, false);
>>> c_can_pm_runtime_put_sync(priv);
>>> + priv->is_opened = false;
>>>
>>> return 0;
>>> }
>>> @@ -1154,6 +1163,75 @@ struct net_device *alloc_c_can_dev(void)
>>> }
>>> EXPORT_SYMBOL_GPL(alloc_c_can_dev);
>>>
>>> +#ifdef CONFIG_PM
>>> +int c_can_power_down(struct net_device *dev)
>>> +{
>>> + unsigned long time_out;
>>> + struct c_can_priv *priv = netdev_priv(dev);
>>> +
>>> + if (!priv->is_opened)
>>> + return 0;
>>
>> Should we add a BUG_ON(id->driver_data != BOSCH_D_CAN)?
>
> These APIs are called from platform driver where device type
> device type is verified. I think we have to add BUG_ON() in
> platform driver.
The platform driver returns if not on D_CAN and will not call this
function. But this functions are exported, so can be called by someone
else. So if the caller is not D_CAN, it's a bug.
>>> +
>>> + /* set `PDR` value so the device goes to power down mode */
>>> + priv->write_reg(priv, C_CAN_CTRL_EX_REG,
>>> + priv->read_reg(priv, C_CAN_CTRL_EX_REG) | CONTROL_EX_PDR);
>>
>> Please use an intermediate variable:
>>
>> u32 val;
>>
>> val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
>> val |= CONTROL_EX_PDR;
>> priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
>
> I will change
>
>>
>>> +
>>> + /* Wait for the PDA bit to get set */
>>> + time_out = jiffies + msecs_to_jiffies(INIT_WAIT_COUNT);
>>> + while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
>>> + time_after(time_out, jiffies))
>>> + cpu_relax();
>>> +
>>> + if (time_after(jiffies, time_out))
>>> + return -ETIMEDOUT;
>>> +
>>> + c_can_stop(dev);
>>> +
>>> + /* De-initialize DCAN RAM */
>>> + c_can_reset_ram(priv, false);
>>> + c_can_pm_runtime_put_sync(priv);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(c_can_power_down);
>>> +
>>> +int c_can_power_up(struct net_device *dev)
>>> +{
>>> + unsigned long time_out;
>>> + struct c_can_priv *priv = netdev_priv(dev);
>>> +
>>
>> BUG_ON?
>>
>>> + if (!priv->is_opened)
>>> + return 0;
>>> +
>>> + c_can_pm_runtime_get_sync(priv);
>>> + /* Initialize DCAN RAM */
>>> + c_can_reset_ram(priv, true);
>>> +
>>> + /* Clear PDR and INIT bits */
>>> + priv->write_reg(priv, C_CAN_CTRL_EX_REG,
>>> + priv->read_reg(priv, C_CAN_CTRL_EX_REG) & ~CONTROL_EX_PDR);
>>> + priv->write_reg(priv, C_CAN_CTRL_REG,
>>> + priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_INIT);
>>> +
>>> + /* Wait for the PDA bit to get clear */
>>> + time_out = jiffies + msecs_to_jiffies(INIT_WAIT_COUNT);
>>> + while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
>>> + time_after(time_out, jiffies))
>>> + cpu_relax();
>>> +
>>> + if (time_after(jiffies, time_out))
>>> + return -ETIMEDOUT;
>>> +
>>> + c_can_start(dev);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(c_can_power_up);
>>> +#else
>>> +#define c_can_power_down NULL
>>> +#define c_can_power_up NULL
>>
>> These are not used, are they?
>
> Not used, I will remove this else part and adding
> #ifdef CONFIG_PM in header file as well.
okay.
>>> +#endif
>>> +
>>> void free_c_can_dev(struct net_device *dev)
>>> {
>>> free_candev(dev);
>>> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
>>> index 5f6339c..e5dd7ef 100644
>>> --- a/drivers/net/can/c_can/c_can.h
>>> +++ b/drivers/net/can/c_can/c_can.h
>>> @@ -24,6 +24,7 @@
>>>
>>> enum reg {
>>> C_CAN_CTRL_REG = 0,
>>> + C_CAN_CTRL_EX_REG,
>>> C_CAN_STS_REG,
>>> C_CAN_ERR_CNT_REG,
>>> C_CAN_BTR_REG,
>>> @@ -104,6 +105,7 @@ static const u16 reg_map_c_can[] = {
>>>
>>> static const u16 reg_map_d_can[] = {
>>> [C_CAN_CTRL_REG] = 0x00,
>>> + [C_CAN_CTRL_EX_REG] = 0x02,
>>> [C_CAN_STS_REG] = 0x04,
>>> [C_CAN_ERR_CNT_REG] = 0x08,
>>> [C_CAN_BTR_REG] = 0x0C,
>>> @@ -166,6 +168,7 @@ struct c_can_priv {
>>> unsigned int tx_echo;
>>> void *priv; /* for board-specific data */
>>> u16 irqstatus;
>>> + bool is_opened;
>>> unsigned int instance;
>>> void (*ram_init) (unsigned int instance, bool enable);
>>> };
>>> @@ -174,5 +177,7 @@ struct net_device *alloc_c_can_dev(void);
>>> void free_c_can_dev(struct net_device *dev);
>>> int register_c_can_dev(struct net_device *dev);
>>> void unregister_c_can_dev(struct net_device *dev);
>>> +int c_can_power_up(struct net_device *dev);
>>> +int c_can_power_down(struct net_device *dev);
>>>
>>> #endif /* C_CAN_H */
>>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>>> index c6963b2..65ec232 100644
>>> --- a/drivers/net/can/c_can/c_can_platform.c
>>> +++ b/drivers/net/can/c_can/c_can_platform.c
>>> @@ -255,15 +255,79 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev)
>>> return 0;
>>> }
>>>
>>> +#ifdef CONFIG_PM
>>> +static int c_can_suspend(struct platform_device *pdev, pm_message_t state)
>>> +{
>>> + int ret;
>>> + struct net_device *ndev = platform_get_drvdata(pdev);
>>> + struct c_can_priv *priv = netdev_priv(ndev);
>>> + const struct platform_device_id *id = platform_get_device_id(pdev);
>>
>> Does that work on DT probed devices? You probably have to save the
>> id->driver_data in struct c_can_priv.
>
> I will add extra variable to c_can_priv to save the dev_id so
> that it will work for dt case as well.
>
>>
>>> +
>>> + if (id->driver_data != BOSCH_D_CAN) {
>>> + dev_warn(&pdev->dev, "Not supported\n");
>>> + return 0;
>>> + }
>>> +
>>> + if (netif_running(ndev)) {
>>> + netif_stop_queue(ndev);
>>> + netif_device_detach(ndev);
>>> + }
>>> +
>>> + ret = c_can_power_down(ndev);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "failed to enter power down mode\n");
>> netdev_err
>>> + return ret;
>>> + }
>>> +
>>> + priv->can.state = CAN_STATE_SLEEPING;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int c_can_resume(struct platform_device *pdev)
>>> +{
>>> + int ret;
>>> +
>> please remove the empty line ^^
>
> Sure
>
>>> + struct net_device *ndev = platform_get_drvdata(pdev);
>>> + struct c_can_priv *priv = netdev_priv(ndev);
>>> + const struct platform_device_id *id = platform_get_device_id(pdev);
>>> +
>>> + if (id->driver_data != BOSCH_D_CAN) {
>>> + dev_warn(&pdev->dev, "Not supported\n");
>>> + return 0;
>>> + }
>>> +
>>> + ret = c_can_power_up(ndev);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "Still in power down mode\n");
>>
>> netdev_err
>
> I will change.
>
>>
>>> + return ret;
>>> + }
>>> +
>>> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>> +
>>> + if (netif_running(ndev)) {
>>> + netif_device_attach(ndev);
>>> + netif_start_queue(ndev);
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +#else
>>> +#define c_can_suspend NULL
>>> +#define c_can_resume NULL
>>> +#endif
>>> +
>>> static struct platform_driver c_can_plat_driver = {
>>> .driver = {
>>> .name = KBUILD_MODNAME,
>>> .owner = THIS_MODULE,
>>> .of_match_table = of_match_ptr(c_can_of_table),
>>> },
>>> - .probe = c_can_plat_probe,
>>> - .remove = __devexit_p(c_can_plat_remove),
>>> - .id_table = c_can_id_table,
>>> + .probe = c_can_plat_probe,
>>> + .remove = __devexit_p(c_can_plat_remove),
>>> + .suspend = c_can_suspend,
>>> + .resume = c_can_resume,
>>> + .id_table = c_can_id_table,
>>
>> Please don't indent here with tab. Just stay with one space on both
>> sides of the "=".
>>
>
> Point taken
>
> Thanks
> AnilKumar
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: mkl@pengutronix.de (Marc Kleine-Budde)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 4/4] can: c_can: Add d_can suspend resume support
Date: Tue, 04 Sep 2012 09:27:18 +0200 [thread overview]
Message-ID: <5045AD56.2050400@pengutronix.de> (raw)
In-Reply-To: <331ABD5ECB02734CA317220B2BBEABC13EA26300@DBDE01.ent.ti.com>
On 09/04/2012 08:14 AM, AnilKumar, Chimata wrote:
> Marc,
>
> Thanks for the comments,
>
> On Tue, Sep 04, 2012 at 01:31:35, Marc Kleine-Budde wrote:
>> On 09/03/2012 01:52 PM, AnilKumar Ch wrote:
>>> Adds suspend resume support to DCAN driver which enables
>>> DCAN power down mode bit (PDR). Then DCAN will ack the local
>>> power-down mode by setting PDA bit in STATUS register.
>>>
>>> Also adds a status flag to know the status of DCAN module,
>>> whether it is opened or not.
>>
>> Use "ndev->flags & IFF_UP" for that. Have a look at the at91_can driver
>> [1]. I'm not sure if you need locking here.
>>
>
> Then I can use this to check the status, lock is not
> required.
>
>> [1] http://lxr.free-electrons.com/source/drivers/net/can/at91_can.c#L1198
>>
>>> Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
>>> ---
>>> drivers/net/can/c_can/c_can.c | 78 ++++++++++++++++++++++++++++++++
>>> drivers/net/can/c_can/c_can.h | 5 ++
>>> drivers/net/can/c_can/c_can_platform.c | 70 ++++++++++++++++++++++++++--
>>> 3 files changed, 150 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
>>> index c175410..36d5db4 100644
>>> --- a/drivers/net/can/c_can/c_can.c
>>> +++ b/drivers/net/can/c_can/c_can.c
>>> @@ -46,6 +46,9 @@
>>> #define IF_ENUM_REG_LEN 11
>>> #define C_CAN_IFACE(reg, iface) (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN)
>>>
>>> +/* control extension register D_CAN specific */
>>> +#define CONTROL_EX_PDR BIT(8)
>>> +
>>> /* control register */
>>> #define CONTROL_TEST BIT(7)
>>> #define CONTROL_CCE BIT(6)
>>> @@ -65,6 +68,7 @@
>>> #define TEST_BASIC BIT(2)
>>>
>>> /* status register */
>>> +#define STATUS_PDA BIT(10)
>>> #define STATUS_BOFF BIT(7)
>>> #define STATUS_EWARN BIT(6)
>>> #define STATUS_EPASS BIT(5)
>>> @@ -164,6 +168,9 @@
>>> /* minimum timeout for checking BUSY status */
>>> #define MIN_TIMEOUT_VALUE 6
>>>
>>> +/* Wait for ~1 sec for INIT bit */
>>> +#define INIT_WAIT_COUNT 1000
>>
>> What unit? INIT_WAIT_MS would be a better name.
>>
>
> Sure, will change
>
>>> +
>>> /* napi related */
>>> #define C_CAN_NAPI_WEIGHT C_CAN_MSG_OBJ_RX_NUM
>>>
>>> @@ -1102,6 +1109,7 @@ static int c_can_open(struct net_device *dev)
>>>
>>> netif_start_queue(dev);
>>>
>>> + priv->is_opened = true;
>>> return 0;
>>>
>>> exit_irq_fail:
>>> @@ -1126,6 +1134,7 @@ static int c_can_close(struct net_device *dev)
>>> /* De-Initialize DCAN RAM */
>>> c_can_reset_ram(priv, false);
>>> c_can_pm_runtime_put_sync(priv);
>>> + priv->is_opened = false;
>>>
>>> return 0;
>>> }
>>> @@ -1154,6 +1163,75 @@ struct net_device *alloc_c_can_dev(void)
>>> }
>>> EXPORT_SYMBOL_GPL(alloc_c_can_dev);
>>>
>>> +#ifdef CONFIG_PM
>>> +int c_can_power_down(struct net_device *dev)
>>> +{
>>> + unsigned long time_out;
>>> + struct c_can_priv *priv = netdev_priv(dev);
>>> +
>>> + if (!priv->is_opened)
>>> + return 0;
>>
>> Should we add a BUG_ON(id->driver_data != BOSCH_D_CAN)?
>
> These APIs are called from platform driver where device type
> device type is verified. I think we have to add BUG_ON() in
> platform driver.
The platform driver returns if not on D_CAN and will not call this
function. But this functions are exported, so can be called by someone
else. So if the caller is not D_CAN, it's a bug.
>>> +
>>> + /* set `PDR` value so the device goes to power down mode */
>>> + priv->write_reg(priv, C_CAN_CTRL_EX_REG,
>>> + priv->read_reg(priv, C_CAN_CTRL_EX_REG) | CONTROL_EX_PDR);
>>
>> Please use an intermediate variable:
>>
>> u32 val;
>>
>> val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
>> val |= CONTROL_EX_PDR;
>> priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
>
> I will change
>
>>
>>> +
>>> + /* Wait for the PDA bit to get set */
>>> + time_out = jiffies + msecs_to_jiffies(INIT_WAIT_COUNT);
>>> + while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
>>> + time_after(time_out, jiffies))
>>> + cpu_relax();
>>> +
>>> + if (time_after(jiffies, time_out))
>>> + return -ETIMEDOUT;
>>> +
>>> + c_can_stop(dev);
>>> +
>>> + /* De-initialize DCAN RAM */
>>> + c_can_reset_ram(priv, false);
>>> + c_can_pm_runtime_put_sync(priv);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(c_can_power_down);
>>> +
>>> +int c_can_power_up(struct net_device *dev)
>>> +{
>>> + unsigned long time_out;
>>> + struct c_can_priv *priv = netdev_priv(dev);
>>> +
>>
>> BUG_ON?
>>
>>> + if (!priv->is_opened)
>>> + return 0;
>>> +
>>> + c_can_pm_runtime_get_sync(priv);
>>> + /* Initialize DCAN RAM */
>>> + c_can_reset_ram(priv, true);
>>> +
>>> + /* Clear PDR and INIT bits */
>>> + priv->write_reg(priv, C_CAN_CTRL_EX_REG,
>>> + priv->read_reg(priv, C_CAN_CTRL_EX_REG) & ~CONTROL_EX_PDR);
>>> + priv->write_reg(priv, C_CAN_CTRL_REG,
>>> + priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_INIT);
>>> +
>>> + /* Wait for the PDA bit to get clear */
>>> + time_out = jiffies + msecs_to_jiffies(INIT_WAIT_COUNT);
>>> + while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
>>> + time_after(time_out, jiffies))
>>> + cpu_relax();
>>> +
>>> + if (time_after(jiffies, time_out))
>>> + return -ETIMEDOUT;
>>> +
>>> + c_can_start(dev);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(c_can_power_up);
>>> +#else
>>> +#define c_can_power_down NULL
>>> +#define c_can_power_up NULL
>>
>> These are not used, are they?
>
> Not used, I will remove this else part and adding
> #ifdef CONFIG_PM in header file as well.
okay.
>>> +#endif
>>> +
>>> void free_c_can_dev(struct net_device *dev)
>>> {
>>> free_candev(dev);
>>> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
>>> index 5f6339c..e5dd7ef 100644
>>> --- a/drivers/net/can/c_can/c_can.h
>>> +++ b/drivers/net/can/c_can/c_can.h
>>> @@ -24,6 +24,7 @@
>>>
>>> enum reg {
>>> C_CAN_CTRL_REG = 0,
>>> + C_CAN_CTRL_EX_REG,
>>> C_CAN_STS_REG,
>>> C_CAN_ERR_CNT_REG,
>>> C_CAN_BTR_REG,
>>> @@ -104,6 +105,7 @@ static const u16 reg_map_c_can[] = {
>>>
>>> static const u16 reg_map_d_can[] = {
>>> [C_CAN_CTRL_REG] = 0x00,
>>> + [C_CAN_CTRL_EX_REG] = 0x02,
>>> [C_CAN_STS_REG] = 0x04,
>>> [C_CAN_ERR_CNT_REG] = 0x08,
>>> [C_CAN_BTR_REG] = 0x0C,
>>> @@ -166,6 +168,7 @@ struct c_can_priv {
>>> unsigned int tx_echo;
>>> void *priv; /* for board-specific data */
>>> u16 irqstatus;
>>> + bool is_opened;
>>> unsigned int instance;
>>> void (*ram_init) (unsigned int instance, bool enable);
>>> };
>>> @@ -174,5 +177,7 @@ struct net_device *alloc_c_can_dev(void);
>>> void free_c_can_dev(struct net_device *dev);
>>> int register_c_can_dev(struct net_device *dev);
>>> void unregister_c_can_dev(struct net_device *dev);
>>> +int c_can_power_up(struct net_device *dev);
>>> +int c_can_power_down(struct net_device *dev);
>>>
>>> #endif /* C_CAN_H */
>>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>>> index c6963b2..65ec232 100644
>>> --- a/drivers/net/can/c_can/c_can_platform.c
>>> +++ b/drivers/net/can/c_can/c_can_platform.c
>>> @@ -255,15 +255,79 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev)
>>> return 0;
>>> }
>>>
>>> +#ifdef CONFIG_PM
>>> +static int c_can_suspend(struct platform_device *pdev, pm_message_t state)
>>> +{
>>> + int ret;
>>> + struct net_device *ndev = platform_get_drvdata(pdev);
>>> + struct c_can_priv *priv = netdev_priv(ndev);
>>> + const struct platform_device_id *id = platform_get_device_id(pdev);
>>
>> Does that work on DT probed devices? You probably have to save the
>> id->driver_data in struct c_can_priv.
>
> I will add extra variable to c_can_priv to save the dev_id so
> that it will work for dt case as well.
>
>>
>>> +
>>> + if (id->driver_data != BOSCH_D_CAN) {
>>> + dev_warn(&pdev->dev, "Not supported\n");
>>> + return 0;
>>> + }
>>> +
>>> + if (netif_running(ndev)) {
>>> + netif_stop_queue(ndev);
>>> + netif_device_detach(ndev);
>>> + }
>>> +
>>> + ret = c_can_power_down(ndev);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "failed to enter power down mode\n");
>> netdev_err
>>> + return ret;
>>> + }
>>> +
>>> + priv->can.state = CAN_STATE_SLEEPING;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int c_can_resume(struct platform_device *pdev)
>>> +{
>>> + int ret;
>>> +
>> please remove the empty line ^^
>
> Sure
>
>>> + struct net_device *ndev = platform_get_drvdata(pdev);
>>> + struct c_can_priv *priv = netdev_priv(ndev);
>>> + const struct platform_device_id *id = platform_get_device_id(pdev);
>>> +
>>> + if (id->driver_data != BOSCH_D_CAN) {
>>> + dev_warn(&pdev->dev, "Not supported\n");
>>> + return 0;
>>> + }
>>> +
>>> + ret = c_can_power_up(ndev);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "Still in power down mode\n");
>>
>> netdev_err
>
> I will change.
>
>>
>>> + return ret;
>>> + }
>>> +
>>> + priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>> +
>>> + if (netif_running(ndev)) {
>>> + netif_device_attach(ndev);
>>> + netif_start_queue(ndev);
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +#else
>>> +#define c_can_suspend NULL
>>> +#define c_can_resume NULL
>>> +#endif
>>> +
>>> static struct platform_driver c_can_plat_driver = {
>>> .driver = {
>>> .name = KBUILD_MODNAME,
>>> .owner = THIS_MODULE,
>>> .of_match_table = of_match_ptr(c_can_of_table),
>>> },
>>> - .probe = c_can_plat_probe,
>>> - .remove = __devexit_p(c_can_plat_remove),
>>> - .id_table = c_can_id_table,
>>> + .probe = c_can_plat_probe,
>>> + .remove = __devexit_p(c_can_plat_remove),
>>> + .suspend = c_can_suspend,
>>> + .resume = c_can_resume,
>>> + .id_table = c_can_id_table,
>>
>> Please don't indent here with tab. Just stay with one space on both
>> sides of the "=".
>>
>
> Point taken
>
> Thanks
> AnilKumar
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 259 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120904/a0f96a43/attachment.sig>
next prev parent reply other threads:[~2012-09-04 7:27 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-03 11:52 [PATCH 0/4] can: c_can: Add suspend/resume and pinctrl support AnilKumar Ch
2012-09-03 11:52 ` AnilKumar Ch
2012-09-03 11:52 ` [PATCH 1/4] can: c_can: Adopt " AnilKumar Ch
2012-09-03 11:52 ` AnilKumar Ch
2012-09-03 20:42 ` Marc Kleine-Budde
2012-09-03 20:42 ` Marc Kleine-Budde
2012-09-04 6:14 ` AnilKumar, Chimata
2012-09-04 6:14 ` AnilKumar, Chimata
2012-09-04 7:42 ` Marc Kleine-Budde
2012-09-04 7:42 ` Marc Kleine-Budde
2012-09-04 8:34 ` AnilKumar, Chimata
2012-09-04 8:34 ` AnilKumar, Chimata
2012-09-03 11:52 ` [PATCH 2/4] can: c_can: Add d_can raminit support AnilKumar Ch
2012-09-03 11:52 ` AnilKumar Ch
2012-09-03 20:39 ` Marc Kleine-Budde
2012-09-03 20:39 ` Marc Kleine-Budde
2012-09-04 6:14 ` AnilKumar, Chimata
2012-09-04 6:14 ` AnilKumar, Chimata
2012-09-04 7:36 ` Vaibhav Hiremath
2012-09-04 7:36 ` Vaibhav Hiremath
2012-09-04 7:39 ` Marc Kleine-Budde
2012-09-04 7:39 ` Marc Kleine-Budde
2012-09-03 11:52 ` [PATCH 3/4] ARM: AM33XX: board-generic: Add of_dev_auxdata to pass d_can raminit AnilKumar Ch
2012-09-03 11:52 ` AnilKumar Ch
2012-09-03 20:11 ` Marc Kleine-Budde
2012-09-03 20:11 ` Marc Kleine-Budde
2012-09-04 6:26 ` AnilKumar, Chimata
2012-09-04 6:26 ` AnilKumar, Chimata
2012-09-04 7:35 ` Marc Kleine-Budde
2012-09-04 7:35 ` Marc Kleine-Budde
2012-09-03 11:52 ` [PATCH 4/4] can: c_can: Add d_can suspend resume support AnilKumar Ch
2012-09-03 11:52 ` AnilKumar Ch
2012-09-03 20:01 ` Marc Kleine-Budde
2012-09-03 20:01 ` Marc Kleine-Budde
2012-09-04 6:14 ` AnilKumar, Chimata
2012-09-04 6:14 ` AnilKumar, Chimata
2012-09-04 7:27 ` Marc Kleine-Budde [this message]
2012-09-04 7:27 ` Marc Kleine-Budde
2012-09-12 12:48 ` AnilKumar, Chimata
2012-09-12 12:48 ` AnilKumar, Chimata
2012-09-12 13:02 ` Marc Kleine-Budde
2012-09-12 13:02 ` Marc Kleine-Budde
2012-09-13 7:24 ` AnilKumar, Chimata
2012-09-13 7:24 ` AnilKumar, Chimata
2012-09-13 8:30 ` Marc Kleine-Budde
2012-09-13 8:30 ` Marc Kleine-Budde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5045AD56.2050400@pengutronix.de \
--to=mkl@pengutronix.de \
--cc=anilkumar@ti.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-can@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=tony@atomide.com \
--cc=wg@grandegger.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.