Received: from milmhbs0.lsil.com (147.145.1.30) by coscas01.lsi.com
 (172.21.36.60) with Microsoft SMTP Server id 8.1.393.1; Wed, 7 Oct 2009
 15:36:01 -0600
Received: from exch1.onstor.com ([10.0.0.225])	by milmhbs0.lsil.com
 (8.12.11/8.12.11) with ESMTP id n97La000016786	for <andy.sharp@lsi.com>; Wed,
 7 Oct 2009 14:36:01 -0700
Received: from mail.onstor.com (66.201.51.107) by exch1.onstor.net
 (10.0.0.225) with Microsoft SMTP Server id 8.1.358.0; Wed, 7 Oct 2009
 14:35:59 -0700
Received: from psmtp.com ([64.18.0.52]) by mail.onstor.com with Microsoft
 SMTPSVC(6.0.3790.3959);	 Wed, 7 Oct 2009 14:35:58 -0700
Received: from source ([213.215.222.73]) by exprod5mx256.postini.com
 ([64.18.4.13]) with SMTP;	Wed, 07 Oct 2009 17:35:58 EDT
Received: (qmail 6971 invoked from network); 7 Oct 2009 23:35:54 +0200
Received: from unknown (HELO i1501.lan.towertech.it) (93.39.33.189)  by
 mx0.towertech.it with SMTP; 7 Oct 2009 23:35:54 +0200
From: Alessandro Zummo <alessandro.zummo@towertech.it>
To: Andrew Morton <akpm@linux-foundation.org>
CC: Hans-Christian Egtvedt <hcegtvedt@atmel.com>, Thomas Bogendoerfer
	<tsbogend@alpha.franken.de>, Andrew Sharp <andy.sharp@onstor.com>, Atsushi
 Nemoto <anemo@mba.ocn.ne.jp>, Alexander Bigga <ab@mycable.de>, Thomas
 Bogendoerfer <tsbogend@alpha.franken.de>, Mark Zhan
	<rongkai.zhan@windriver.com>, Thomas Hommel <thomas.hommel@gefanuc.com>,
	Atsushi Nemoto <anemo@mba.ocn.ne.jp>, Paul Mundt <lethal@linux-sh.org>,
	Raphael Assenat <raph@8d.com>, Russell King <rmk@arm.linux.org.uk>,
	"rtc-linux@googlegroups.com" <rtc-linux@googlegroups.com>
Date: Wed, 7 Oct 2009 15:35:49 -0600
Subject: [PATCH v2] fix driver data issues in several rtc drivers
Thread-Topic: [PATCH v2] fix driver data issues in several rtc drivers
Thread-Index: AcpHlixDzzOE5RkiQn6NxoUa5DjjhA==
Message-ID: <20091007233549.4c4e9da1@i1501.lan.towertech.it>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Anonymous
X-MS-Exchange-Organization-AuthSource: coscas01.lsi.com
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
x-originalarrivaltime: 07 Oct 2009 21:35:58.0078 (UTC)
 FILETIME=[285499E0:01CA4796]
x-scanned-by: MIMEDefang 2.39
x-pstn-levels: (S:34.16943/99.90000 CV:99.9000 FC:95.5390 LC:95.5390
 R:95.9108 P:95.9108 M:97.0282 C:98.6951 )
x-pstn-neptune: 0/0/0.00/0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0


  fix driver data issues in several rtc drivers

  Herton Ronaldo Krzesinski recently raised up, and fixed,
  an issue with the rtc_cmos driver, which was referring
  to an inconsistent driver data.

  This patch ensures that driver data registration
  happens before rtc_device_register().

  Changes since V1:
   - modified patch description
   - included modifications by Hans-Christian Egtvedt

  Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
  Acked-by: Thomas Hommel <thomas.hommel@gefanuc.com>
  Cc: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
  Cc: David S. Miller <davem@davemloft.net>
  Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
  Cc: Andrew Sharp <andy.sharp@onstor.com>
  Cc: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
  Cc: Alexander Bigga <ab@mycable.de>
  Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
  Cc: Mark Zhan <rongkai.zhan@windriver.com>

diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c
index e1ec33e..8825695 100644
--- a/drivers/rtc/rtc-at32ap700x.c
+++ b/drivers/rtc/rtc-at32ap700x.c
@@ -256,6 +256,8 @@ static int __init at32_rtc_probe(struct platform_device=
 *pdev)
                goto out_iounmap;
        }

+       platform_set_drvdata(pdev, rtc);
+
        rtc->rtc =3D rtc_device_register(pdev->name, &pdev->dev,
                                &at32_rtc_ops, THIS_MODULE);
        if (IS_ERR(rtc->rtc)) {
@@ -264,7 +266,6 @@ static int __init at32_rtc_probe(struct platform_device=
 *pdev)
                goto out_free_irq;
        }

-       platform_set_drvdata(pdev, rtc);
        device_init_wakeup(&pdev->dev, 1);

        dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n",
@@ -273,6 +274,7 @@ static int __init at32_rtc_probe(struct platform_device=
 *pdev)
        return 0;

 out_free_irq:
+       platform_set_drvdata(pdev, NULL);
        free_irq(irq, rtc);
 out_iounmap:
        iounmap(rtc->regs);
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c
index d00a274..280fe48 100644
--- a/drivers/rtc/rtc-bq4802.c
+++ b/drivers/rtc/rtc-bq4802.c
@@ -169,6 +169,8 @@ static int __devinit bq4802_probe(struct platform_devic=
e *pdev)
                goto out_free;
        }

+       platform_set_drvdata(pdev, p);
+
        p->rtc =3D rtc_device_register("bq4802", &pdev->dev,
                                     &bq4802_ops, THIS_MODULE);
        if (IS_ERR(p->rtc)) {
@@ -176,7 +178,6 @@ static int __devinit bq4802_probe(struct platform_devic=
e *pdev)
                goto out_iounmap;
        }

-       platform_set_drvdata(pdev, p);
        err =3D 0;
 out:
        return err;
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index 4fcb16b..11d6cc2 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -325,7 +325,6 @@ static const struct rtc_class_ops ds1286_ops =3D {

 static int __devinit ds1286_probe(struct platform_device *pdev)
 {
-       struct rtc_device *rtc;
        struct resource *res;
        struct ds1286_priv *priv;
        int ret =3D 0;
@@ -349,14 +348,16 @@ static int __devinit ds1286_probe(struct platform_dev=
ice *pdev)
                goto out;
        }
        spin_lock_init(&priv->lock);
-       rtc =3D rtc_device_register("ds1286", &pdev->dev,
+
+       platform_set_drvdata(pdev, priv);
+
+       priv->rtc =3D rtc_device_register("ds1286", &pdev->dev,
                                  &ds1286_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               ret =3D PTR_ERR(rtc);
+       if (IS_ERR(priv->rtc)) {
+               ret =3D PTR_ERR(priv->rtc);
                goto out;
        }
-       priv->rtc =3D rtc;
-       platform_set_drvdata(pdev, priv);
+
        return 0;

 out:
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index d490628..7c35d14 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -143,7 +143,6 @@ static int ds1302_rtc_ioctl(struct device *dev, unsigne=
d int cmd,
 #ifdef RTC_SET_CHARGE
        case RTC_SET_CHARGE:
        {
-               struct ds1302_rtc *rtc =3D dev_get_drvdata(dev);
                int tcs_val;

                if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)=
))
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index 8f410e5..c76a194 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -617,7 +617,6 @@ static struct bin_attribute nvram =3D {
 static int __devinit ds1305_probe(struct spi_device *spi)
 {
        struct ds1305                   *ds1305;
-       struct rtc_device               *rtc;
        int                             status;
        u8                              addr, value;
        struct ds1305_platform_data     *pdata =3D spi->dev.platform_data;
@@ -756,14 +755,13 @@ static int __devinit ds1305_probe(struct spi_device *=
spi)
                dev_dbg(&spi->dev, "AM/PM\n");

        /* register RTC ... from here on, ds1305->ctrl needs locking */
-       rtc =3D rtc_device_register("ds1305", &spi->dev,
+       ds1305->rtc =3D rtc_device_register("ds1305", &spi->dev,
                        &ds1305_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               status =3D PTR_ERR(rtc);
+       if (IS_ERR(ds1305->rtc)) {
+               status =3D PTR_ERR(ds1305->rtc);
                dev_dbg(&spi->dev, "register rtc --> %d\n", status);
                goto fail0;
        }
-       ds1305->rtc =3D rtc;

        /* Maybe set up alarm IRQ; be ready to handle it triggering right
         * away.  NOTE that we don't share this.  The signal is active low,
@@ -774,7 +772,7 @@ static int __devinit ds1305_probe(struct spi_device *sp=
i)
        if (spi->irq) {
                INIT_WORK(&ds1305->work, ds1305_work);
                status =3D request_irq(spi->irq, ds1305_irq,
-                               0, dev_name(&rtc->dev), ds1305);
+                               0, dev_name(&ds1305->rtc->dev), ds1305);
                if (status < 0) {
                        dev_dbg(&spi->dev, "request_irq %d --> %d\n",
                                        spi->irq, status);
@@ -794,7 +792,7 @@ static int __devinit ds1305_probe(struct spi_device *sp=
i)
 fail2:
        free_irq(spi->irq, ds1305);
 fail1:
-       rtc_device_unregister(rtc);
+       rtc_device_unregister(ds1305->rtc);
 fail0:
        kfree(ds1305);
        return status;
@@ -802,7 +800,7 @@ fail0:

 static int __devexit ds1305_remove(struct spi_device *spi)
 {
-       struct ds1305   *ds1305 =3D spi_get_drvdata(spi);
+       struct ds1305 *ds1305 =3D spi_get_drvdata(spi);

        sysfs_remove_bin_file(&spi->dev.kobj, &nvram);

diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 0b6b773..cfdceaa 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -490,7 +490,6 @@ static struct bin_attribute ds1511_nvram_attr =3D {
  static int __devinit
 ds1511_rtc_probe(struct platform_device *pdev)
 {
-       struct rtc_device *rtc;
        struct resource *res;
        struct rtc_plat_data *pdata =3D NULL;
        int ret =3D 0;
@@ -554,14 +553,15 @@ ds1511_rtc_probe(struct platform_device *pdev)
                }
        }

-       rtc =3D rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops=
,
+       platform_set_drvdata(pdev, pdata);
+
+       pdata->rtc =3D rtc_device_register(pdev->name, &pdev->dev, &ds1511_=
rtc_ops,
                THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               ret =3D PTR_ERR(rtc);
+       if (IS_ERR(pdata->rtc)) {
+               ret =3D PTR_ERR(pdata->rtc);
                goto out;
        }
-       pdata->rtc =3D rtc;
-       platform_set_drvdata(pdev, pdata);
+
        ret =3D sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);
        if (ret) {
                goto out;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 60fe266..5033c70 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -768,37 +768,32 @@ static int m41t80_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
        int rc =3D 0;
-       struct rtc_device *rtc =3D NULL;
        struct rtc_time tm;
        struct m41t80_data *clientdata =3D NULL;

        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
                                     | I2C_FUNC_SMBUS_BYTE_DATA)) {
-               rc =3D -ENODEV;
-               goto exit;
+               return -ENODEV;
        }

        dev_info(&client->dev,
                 "chip found, driver version " DRV_VERSION "\n");

        clientdata =3D kzalloc(sizeof(*clientdata), GFP_KERNEL);
-       if (!clientdata) {
-               rc =3D -ENOMEM;
-               goto exit;
-       }
+       if (!clientdata)
+               return -ENOMEM;
+
+       clientdata->features =3D id->driver_data;
+       i2c_set_clientdata(client, clientdata);

-       rtc =3D rtc_device_register(client->name, &client->dev,
+
+       clientdata->rtc =3D rtc_device_register(client->name, &client->dev,
                                  &m41t80_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               rc =3D PTR_ERR(rtc);
-               rtc =3D NULL;
+       if (IS_ERR(clientdata->rtc)) {
+               rc =3D PTR_ERR(clientdata->rtc);
                goto exit;
        }

-       clientdata->rtc =3D rtc;
-       clientdata->features =3D id->driver_data;
-       i2c_set_clientdata(client, clientdata);
-
        /* Make sure HT (Halt Update) bit is cleared */
        rc =3D i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
        if (rc < 0)
@@ -861,8 +856,8 @@ ht_err:
        goto exit;

 exit:
-       if (rtc)
-               rtc_device_unregister(rtc);
+       if (clientdata->rtc)
+               rtc_device_unregister(clientdata->rtc);
        kfree(clientdata);
        return rc;
 }
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index 0b21975..8cb5b89 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -142,7 +142,6 @@ static const struct rtc_class_ops m48t35_ops =3D {

 static int __devinit m48t35_probe(struct platform_device *pdev)
 {
-       struct rtc_device *rtc;
        struct resource *res;
        struct m48t35_priv *priv;
        int ret =3D 0;
@@ -171,20 +170,21 @@ static int __devinit m48t35_probe(struct platform_dev=
ice *pdev)
                ret =3D -ENOMEM;
                goto out;
        }
+
        spin_lock_init(&priv->lock);
-       rtc =3D rtc_device_register("m48t35", &pdev->dev,
+
+       platform_set_drvdata(pdev, priv);
+
+       priv->rtc =3D rtc_device_register("m48t35", &pdev->dev,
                                  &m48t35_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               ret =3D PTR_ERR(rtc);
+       if (IS_ERR(priv->rtc)) {
+               ret =3D PTR_ERR(priv->rtc);
                goto out;
        }
-       priv->rtc =3D rtc;
-       platform_set_drvdata(pdev, priv);
+
        return 0;

 out:
-       if (priv->rtc)
-               rtc_device_unregister(priv->rtc);
        if (priv->reg)
                iounmap(priv->reg);
        if (priv->baseaddr)
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index 33921a6..ede43b8 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -481,6 +481,9 @@ static int __devinit m48t59_rtc_probe(struct platform_d=
evice *pdev)
                goto out;
        }

+       spin_lock_init(&m48t59->lock);
+       platform_set_drvdata(pdev, m48t59);
+
        m48t59->rtc =3D rtc_device_register(name, &pdev->dev, ops, THIS_MOD=
ULE);
        if (IS_ERR(m48t59->rtc)) {
                ret =3D PTR_ERR(m48t59->rtc);
@@ -490,16 +493,14 @@ static int __devinit m48t59_rtc_probe(struct platform=
_device *pdev)
        m48t59_nvram_attr.size =3D pdata->offset;

        ret =3D sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
-       if (ret)
+       if (ret) {
+               rtc_device_unregister(m48t59->rtc);
                goto out;
+       }

-       spin_lock_init(&m48t59->lock);
-       platform_set_drvdata(pdev, m48t59);
        return 0;

 out:
-       if (!IS_ERR(m48t59->rtc))
-               rtc_device_unregister(m48t59->rtc);
        if (m48t59->irq !=3D NO_IRQ)
                free_irq(m48t59->irq, &pdev->dev);
        if (m48t59->ioaddr)
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index b725913..65f346b 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -212,6 +212,8 @@ static int pcf8563_probe(struct i2c_client *client,

        dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\=
n");

+       i2c_set_clientdata(client, pcf8563);
+
        pcf8563->rtc =3D rtc_device_register(pcf8563_driver.driver.name,
                                &client->dev, &pcf8563_rtc_ops, THIS_MODULE=
);

@@ -220,8 +222,6 @@ static int pcf8563_probe(struct i2c_client *client,
                goto exit_kfree;
        }

-       i2c_set_clientdata(client, pcf8563);
-
        return 0;

 exit_kfree:
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index 7d33cda..2d201af 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -277,6 +277,8 @@ static int pcf8583_probe(struct i2c_client *client,
        if (!pcf8583)
                return -ENOMEM;

+       i2c_set_clientdata(client, pcf8583);
+
        pcf8583->rtc =3D rtc_device_register(pcf8583_driver.driver.name,
                        &client->dev, &pcf8583_rtc_ops, THIS_MODULE);

@@ -285,7 +287,6 @@ static int pcf8583_probe(struct i2c_client *client,
                goto exit_kfree;
        }

-       i2c_set_clientdata(client, pcf8583);
        return 0;

 exit_kfree:
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 7d1547b..78d9d07 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -288,7 +288,6 @@ static struct bin_attribute stk17ta8_nvram_attr =3D {

 static int __init stk17ta8_rtc_probe(struct platform_device *pdev)
 {
-       struct rtc_device *rtc;
        struct resource *res;
        unsigned int cal;
        unsigned int flags;
@@ -338,22 +337,23 @@ static int __init stk17ta8_rtc_probe(struct platform_=
device *pdev)
                }
        }

-       rtc =3D rtc_device_register(pdev->name, &pdev->dev,
+       pdata->last_jiffies =3D jiffies;
+       platform_set_drvdata(pdev, pdata);
+
+       pdata->rtc =3D rtc_device_register(pdev->name, &pdev->dev,
                                  &stk17ta8_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               ret =3D PTR_ERR(rtc);
+       if (IS_ERR(pdata->rtc)) {
+               ret =3D PTR_ERR(pdata->rtc);
                goto out;
        }
-       pdata->rtc =3D rtc;
-       pdata->last_jiffies =3D jiffies;
-       platform_set_drvdata(pdev, pdata);
+
        ret =3D sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr=
);
-       if (ret)
+       if (ret) {
+               rtc_device_unregister(pdata->rtc);
                goto out;
+       }
        return 0;
  out:
-       if (pdata->rtc)
-               rtc_device_unregister(pdata->rtc);
        if (pdata->irq > 0)
                free_irq(pdata->irq, pdev);
        if (ioaddr)
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index ad16405..6c00f75 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -304,7 +304,6 @@ static int rtc_probe(struct platform_device *pdev)
 {
        struct v3020_platform_data *pdata =3D pdev->dev.platform_data;
        struct v3020 *chip;
-       struct rtc_device *rtc;
        int retval =3D -EBUSY;
        int i;
        int temp;
@@ -353,13 +352,12 @@ static int rtc_probe(struct platform_device *pdev)

        platform_set_drvdata(pdev, chip);

-       rtc =3D rtc_device_register("v3020",
+       chip->rtc =3D rtc_device_register("v3020",
                                &pdev->dev, &v3020_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               retval =3D PTR_ERR(rtc);
+       if (IS_ERR(chip->rtc)) {
+               retval =3D PTR_ERR(chip->rtc);
                goto err_io;
        }
-       chip->rtc =3D rtc;

        return 0;




--

 Best regards,

 Alessandro Zummo,
  Tower Technologies - Torino, Italy

  http://www.towertech.it

