提交 b74d2caa 编写于 作者: A Alessandro Zummo 提交者: Linus Torvalds

rtc: 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().
Signed-off-by: NAlessandro Zummo <a.zummo@towertech.it>
Acked-by: NThomas Hommel <thomas.hommel@gefanuc.com>
Acked-by: NHans-Christian Egtvedt <hcegtvedt@atmel.com>
Acked-by: NPaul Mundt <lethal@linux-sh.org>
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>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 d1b2efa8
...@@ -256,6 +256,8 @@ static int __init at32_rtc_probe(struct platform_device *pdev) ...@@ -256,6 +256,8 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
goto out_iounmap; goto out_iounmap;
} }
platform_set_drvdata(pdev, rtc);
rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
&at32_rtc_ops, THIS_MODULE); &at32_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) { if (IS_ERR(rtc->rtc)) {
...@@ -264,7 +266,6 @@ static int __init at32_rtc_probe(struct platform_device *pdev) ...@@ -264,7 +266,6 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
goto out_free_irq; goto out_free_irq;
} }
platform_set_drvdata(pdev, rtc);
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n", 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) ...@@ -273,6 +274,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev)
return 0; return 0;
out_free_irq: out_free_irq:
platform_set_drvdata(pdev, NULL);
free_irq(irq, rtc); free_irq(irq, rtc);
out_iounmap: out_iounmap:
iounmap(rtc->regs); iounmap(rtc->regs);
......
...@@ -169,6 +169,8 @@ static int __devinit bq4802_probe(struct platform_device *pdev) ...@@ -169,6 +169,8 @@ static int __devinit bq4802_probe(struct platform_device *pdev)
goto out_free; goto out_free;
} }
platform_set_drvdata(pdev, p);
p->rtc = rtc_device_register("bq4802", &pdev->dev, p->rtc = rtc_device_register("bq4802", &pdev->dev,
&bq4802_ops, THIS_MODULE); &bq4802_ops, THIS_MODULE);
if (IS_ERR(p->rtc)) { if (IS_ERR(p->rtc)) {
...@@ -176,7 +178,6 @@ static int __devinit bq4802_probe(struct platform_device *pdev) ...@@ -176,7 +178,6 @@ static int __devinit bq4802_probe(struct platform_device *pdev)
goto out_iounmap; goto out_iounmap;
} }
platform_set_drvdata(pdev, p);
err = 0; err = 0;
out: out:
return err; return err;
......
...@@ -143,7 +143,6 @@ static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd, ...@@ -143,7 +143,6 @@ static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
#ifdef RTC_SET_CHARGE #ifdef RTC_SET_CHARGE
case RTC_SET_CHARGE: case RTC_SET_CHARGE:
{ {
struct ds1302_rtc *rtc = dev_get_drvdata(dev);
int tcs_val; int tcs_val;
if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int))) if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
......
...@@ -617,7 +617,6 @@ static struct bin_attribute nvram = { ...@@ -617,7 +617,6 @@ static struct bin_attribute nvram = {
static int __devinit ds1305_probe(struct spi_device *spi) static int __devinit ds1305_probe(struct spi_device *spi)
{ {
struct ds1305 *ds1305; struct ds1305 *ds1305;
struct rtc_device *rtc;
int status; int status;
u8 addr, value; u8 addr, value;
struct ds1305_platform_data *pdata = spi->dev.platform_data; struct ds1305_platform_data *pdata = spi->dev.platform_data;
...@@ -756,14 +755,13 @@ static int __devinit ds1305_probe(struct spi_device *spi) ...@@ -756,14 +755,13 @@ static int __devinit ds1305_probe(struct spi_device *spi)
dev_dbg(&spi->dev, "AM/PM\n"); dev_dbg(&spi->dev, "AM/PM\n");
/* register RTC ... from here on, ds1305->ctrl needs locking */ /* register RTC ... from here on, ds1305->ctrl needs locking */
rtc = rtc_device_register("ds1305", &spi->dev, ds1305->rtc = rtc_device_register("ds1305", &spi->dev,
&ds1305_ops, THIS_MODULE); &ds1305_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(ds1305->rtc)) {
status = PTR_ERR(rtc); status = PTR_ERR(ds1305->rtc);
dev_dbg(&spi->dev, "register rtc --> %d\n", status); dev_dbg(&spi->dev, "register rtc --> %d\n", status);
goto fail0; goto fail0;
} }
ds1305->rtc = rtc;
/* Maybe set up alarm IRQ; be ready to handle it triggering right /* 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, * 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 *spi) ...@@ -774,7 +772,7 @@ static int __devinit ds1305_probe(struct spi_device *spi)
if (spi->irq) { if (spi->irq) {
INIT_WORK(&ds1305->work, ds1305_work); INIT_WORK(&ds1305->work, ds1305_work);
status = request_irq(spi->irq, ds1305_irq, status = request_irq(spi->irq, ds1305_irq,
0, dev_name(&rtc->dev), ds1305); 0, dev_name(&ds1305->rtc->dev), ds1305);
if (status < 0) { if (status < 0) {
dev_dbg(&spi->dev, "request_irq %d --> %d\n", dev_dbg(&spi->dev, "request_irq %d --> %d\n",
spi->irq, status); spi->irq, status);
...@@ -794,7 +792,7 @@ static int __devinit ds1305_probe(struct spi_device *spi) ...@@ -794,7 +792,7 @@ static int __devinit ds1305_probe(struct spi_device *spi)
fail2: fail2:
free_irq(spi->irq, ds1305); free_irq(spi->irq, ds1305);
fail1: fail1:
rtc_device_unregister(rtc); rtc_device_unregister(ds1305->rtc);
fail0: fail0:
kfree(ds1305); kfree(ds1305);
return status; return status;
......
...@@ -142,7 +142,6 @@ static const struct rtc_class_ops m48t35_ops = { ...@@ -142,7 +142,6 @@ static const struct rtc_class_ops m48t35_ops = {
static int __devinit m48t35_probe(struct platform_device *pdev) static int __devinit m48t35_probe(struct platform_device *pdev)
{ {
struct rtc_device *rtc;
struct resource *res; struct resource *res;
struct m48t35_priv *priv; struct m48t35_priv *priv;
int ret = 0; int ret = 0;
...@@ -171,20 +170,21 @@ static int __devinit m48t35_probe(struct platform_device *pdev) ...@@ -171,20 +170,21 @@ static int __devinit m48t35_probe(struct platform_device *pdev)
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
rtc = rtc_device_register("m48t35", &pdev->dev,
platform_set_drvdata(pdev, priv);
priv->rtc = rtc_device_register("m48t35", &pdev->dev,
&m48t35_ops, THIS_MODULE); &m48t35_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(priv->rtc)) {
ret = PTR_ERR(rtc); ret = PTR_ERR(priv->rtc);
goto out; goto out;
} }
priv->rtc = rtc;
platform_set_drvdata(pdev, priv);
return 0; return 0;
out: out:
if (priv->rtc)
rtc_device_unregister(priv->rtc);
if (priv->reg) if (priv->reg)
iounmap(priv->reg); iounmap(priv->reg);
if (priv->baseaddr) if (priv->baseaddr)
......
...@@ -481,6 +481,9 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev) ...@@ -481,6 +481,9 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
goto out; goto out;
} }
spin_lock_init(&m48t59->lock);
platform_set_drvdata(pdev, m48t59);
m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE); m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
if (IS_ERR(m48t59->rtc)) { if (IS_ERR(m48t59->rtc)) {
ret = PTR_ERR(m48t59->rtc); ret = PTR_ERR(m48t59->rtc);
...@@ -490,16 +493,14 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev) ...@@ -490,16 +493,14 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
m48t59_nvram_attr.size = pdata->offset; m48t59_nvram_attr.size = pdata->offset;
ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
if (ret) if (ret) {
rtc_device_unregister(m48t59->rtc);
goto out; goto out;
}
spin_lock_init(&m48t59->lock);
platform_set_drvdata(pdev, m48t59);
return 0; return 0;
out: out:
if (!IS_ERR(m48t59->rtc))
rtc_device_unregister(m48t59->rtc);
if (m48t59->irq != NO_IRQ) if (m48t59->irq != NO_IRQ)
free_irq(m48t59->irq, &pdev->dev); free_irq(m48t59->irq, &pdev->dev);
if (m48t59->ioaddr) if (m48t59->ioaddr)
......
...@@ -212,6 +212,8 @@ static int pcf8563_probe(struct i2c_client *client, ...@@ -212,6 +212,8 @@ static int pcf8563_probe(struct i2c_client *client,
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
i2c_set_clientdata(client, pcf8563);
pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name, pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,
&client->dev, &pcf8563_rtc_ops, THIS_MODULE); &client->dev, &pcf8563_rtc_ops, THIS_MODULE);
...@@ -220,8 +222,6 @@ static int pcf8563_probe(struct i2c_client *client, ...@@ -220,8 +222,6 @@ static int pcf8563_probe(struct i2c_client *client,
goto exit_kfree; goto exit_kfree;
} }
i2c_set_clientdata(client, pcf8563);
return 0; return 0;
exit_kfree: exit_kfree:
......
...@@ -277,6 +277,8 @@ static int pcf8583_probe(struct i2c_client *client, ...@@ -277,6 +277,8 @@ static int pcf8583_probe(struct i2c_client *client,
if (!pcf8583) if (!pcf8583)
return -ENOMEM; return -ENOMEM;
i2c_set_clientdata(client, pcf8583);
pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name, pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name,
&client->dev, &pcf8583_rtc_ops, THIS_MODULE); &client->dev, &pcf8583_rtc_ops, THIS_MODULE);
...@@ -285,7 +287,6 @@ static int pcf8583_probe(struct i2c_client *client, ...@@ -285,7 +287,6 @@ static int pcf8583_probe(struct i2c_client *client,
goto exit_kfree; goto exit_kfree;
} }
i2c_set_clientdata(client, pcf8583);
return 0; return 0;
exit_kfree: exit_kfree:
......
...@@ -288,7 +288,6 @@ static struct bin_attribute stk17ta8_nvram_attr = { ...@@ -288,7 +288,6 @@ static struct bin_attribute stk17ta8_nvram_attr = {
static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev) static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
{ {
struct rtc_device *rtc;
struct resource *res; struct resource *res;
unsigned int cal; unsigned int cal;
unsigned int flags; unsigned int flags;
...@@ -338,22 +337,23 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev) ...@@ -338,22 +337,23 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
} }
} }
rtc = rtc_device_register(pdev->name, &pdev->dev, pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
&stk17ta8_rtc_ops, THIS_MODULE); &stk17ta8_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(pdata->rtc)) {
ret = PTR_ERR(rtc); ret = PTR_ERR(pdata->rtc);
goto out; goto out;
} }
pdata->rtc = rtc;
pdata->last_jiffies = jiffies;
platform_set_drvdata(pdev, pdata);
ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
if (ret) if (ret) {
rtc_device_unregister(pdata->rtc);
goto out; goto out;
}
return 0; return 0;
out: out:
if (pdata->rtc)
rtc_device_unregister(pdata->rtc);
if (pdata->irq > 0) if (pdata->irq > 0)
free_irq(pdata->irq, pdev); free_irq(pdata->irq, pdev);
if (ioaddr) if (ioaddr)
......
...@@ -304,7 +304,6 @@ static int rtc_probe(struct platform_device *pdev) ...@@ -304,7 +304,6 @@ static int rtc_probe(struct platform_device *pdev)
{ {
struct v3020_platform_data *pdata = pdev->dev.platform_data; struct v3020_platform_data *pdata = pdev->dev.platform_data;
struct v3020 *chip; struct v3020 *chip;
struct rtc_device *rtc;
int retval = -EBUSY; int retval = -EBUSY;
int i; int i;
int temp; int temp;
...@@ -353,13 +352,12 @@ static int rtc_probe(struct platform_device *pdev) ...@@ -353,13 +352,12 @@ static int rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chip); platform_set_drvdata(pdev, chip);
rtc = rtc_device_register("v3020", chip->rtc = rtc_device_register("v3020",
&pdev->dev, &v3020_rtc_ops, THIS_MODULE); &pdev->dev, &v3020_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(chip->rtc)) {
retval = PTR_ERR(rtc); retval = PTR_ERR(chip->rtc);
goto err_io; goto err_io;
} }
chip->rtc = rtc;
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册