diff options
author | Alessandro Zummo <a.zummo@towertech.it> | 2014-04-03 17:49:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 19:21:16 -0400 |
commit | 4071ea25cc08d41002746cca2d69ac700d67a2ac (patch) | |
tree | 43cf44f8265b885c8c1e4e81f0ced5c6babb53c7 /drivers | |
parent | a68b31080912dae377bee4994716b357dc74286d (diff) |
rtc: fix potential race condition
RTC drivers must not return an error after device registration.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Reported-by: Ales Novak <alnovak@suse.cz>
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Srikanth Srinivasan <srikanth.srinivasan@freescale.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/rtc-ds1305.c | 10 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 60 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1511.c | 18 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1553.c | 18 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1672.c | 11 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1742.c | 5 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds3232.c | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-test.c | 9 | ||||
-rw-r--r-- | drivers/rtc/rtc-x1205.c | 2 |
9 files changed, 70 insertions, 65 deletions
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 2dd586a19b59..129add77065d 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -756,19 +756,17 @@ static int ds1305_probe(struct spi_device *spi) | |||
756 | status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq, | 756 | status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq, |
757 | 0, dev_name(&ds1305->rtc->dev), ds1305); | 757 | 0, dev_name(&ds1305->rtc->dev), ds1305); |
758 | if (status < 0) { | 758 | if (status < 0) { |
759 | dev_dbg(&spi->dev, "request_irq %d --> %d\n", | 759 | dev_err(&spi->dev, "request_irq %d --> %d\n", |
760 | spi->irq, status); | 760 | spi->irq, status); |
761 | return status; | 761 | } else { |
762 | device_set_wakeup_capable(&spi->dev, 1); | ||
762 | } | 763 | } |
763 | |||
764 | device_set_wakeup_capable(&spi->dev, 1); | ||
765 | } | 764 | } |
766 | 765 | ||
767 | /* export NVRAM */ | 766 | /* export NVRAM */ |
768 | status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); | 767 | status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); |
769 | if (status < 0) { | 768 | if (status < 0) { |
770 | dev_dbg(&spi->dev, "register nvram --> %d\n", status); | 769 | dev_err(&spi->dev, "register nvram --> %d\n", status); |
771 | return status; | ||
772 | } | 770 | } |
773 | 771 | ||
774 | return 0; | 772 | return 0; |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4e75345a559a..9e2aad68f96d 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -930,52 +930,58 @@ read_rtc: | |||
930 | ds1307->rtc = devm_rtc_device_register(&client->dev, client->name, | 930 | ds1307->rtc = devm_rtc_device_register(&client->dev, client->name, |
931 | &ds13xx_rtc_ops, THIS_MODULE); | 931 | &ds13xx_rtc_ops, THIS_MODULE); |
932 | if (IS_ERR(ds1307->rtc)) { | 932 | if (IS_ERR(ds1307->rtc)) { |
933 | err = PTR_ERR(ds1307->rtc); | 933 | return PTR_ERR(ds1307->rtc); |
934 | dev_err(&client->dev, | ||
935 | "unable to register the class device\n"); | ||
936 | goto exit; | ||
937 | } | 934 | } |
938 | 935 | ||
939 | if (want_irq) { | 936 | if (want_irq) { |
940 | err = request_irq(client->irq, ds1307_irq, IRQF_SHARED, | 937 | err = request_irq(client->irq, ds1307_irq, IRQF_SHARED, |
941 | ds1307->rtc->name, client); | 938 | ds1307->rtc->name, client); |
942 | if (err) { | 939 | if (err) { |
943 | dev_err(&client->dev, | 940 | client->irq = 0; |
944 | "unable to request IRQ!\n"); | 941 | dev_err(&client->dev, "unable to request IRQ!\n"); |
945 | goto exit; | 942 | } else { |
946 | } | ||
947 | 943 | ||
948 | device_set_wakeup_capable(&client->dev, 1); | 944 | device_set_wakeup_capable(&client->dev, 1); |
949 | set_bit(HAS_ALARM, &ds1307->flags); | 945 | set_bit(HAS_ALARM, &ds1307->flags); |
950 | dev_dbg(&client->dev, "got IRQ %d\n", client->irq); | 946 | dev_dbg(&client->dev, "got IRQ %d\n", client->irq); |
947 | } | ||
951 | } | 948 | } |
952 | 949 | ||
953 | if (chip->nvram_size) { | 950 | if (chip->nvram_size) { |
951 | |||
954 | ds1307->nvram = devm_kzalloc(&client->dev, | 952 | ds1307->nvram = devm_kzalloc(&client->dev, |
955 | sizeof(struct bin_attribute), | 953 | sizeof(struct bin_attribute), |
956 | GFP_KERNEL); | 954 | GFP_KERNEL); |
957 | if (!ds1307->nvram) { | 955 | if (!ds1307->nvram) { |
958 | err = -ENOMEM; | 956 | dev_err(&client->dev, "cannot allocate memory for nvram sysfs\n"); |
959 | goto err_irq; | 957 | } else { |
958 | |||
959 | ds1307->nvram->attr.name = "nvram"; | ||
960 | ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; | ||
961 | |||
962 | sysfs_bin_attr_init(ds1307->nvram); | ||
963 | |||
964 | ds1307->nvram->read = ds1307_nvram_read; | ||
965 | ds1307->nvram->write = ds1307_nvram_write; | ||
966 | ds1307->nvram->size = chip->nvram_size; | ||
967 | ds1307->nvram_offset = chip->nvram_offset; | ||
968 | |||
969 | err = sysfs_create_bin_file(&client->dev.kobj, | ||
970 | ds1307->nvram); | ||
971 | if (err) { | ||
972 | dev_err(&client->dev, | ||
973 | "unable to create sysfs file: %s\n", | ||
974 | ds1307->nvram->attr.name); | ||
975 | } else { | ||
976 | set_bit(HAS_NVRAM, &ds1307->flags); | ||
977 | dev_info(&client->dev, "%zu bytes nvram\n", | ||
978 | ds1307->nvram->size); | ||
979 | } | ||
960 | } | 980 | } |
961 | ds1307->nvram->attr.name = "nvram"; | ||
962 | ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; | ||
963 | sysfs_bin_attr_init(ds1307->nvram); | ||
964 | ds1307->nvram->read = ds1307_nvram_read; | ||
965 | ds1307->nvram->write = ds1307_nvram_write; | ||
966 | ds1307->nvram->size = chip->nvram_size; | ||
967 | ds1307->nvram_offset = chip->nvram_offset; | ||
968 | err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram); | ||
969 | if (err) | ||
970 | goto err_irq; | ||
971 | set_bit(HAS_NVRAM, &ds1307->flags); | ||
972 | dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size); | ||
973 | } | 981 | } |
974 | 982 | ||
975 | return 0; | 983 | return 0; |
976 | 984 | ||
977 | err_irq: | ||
978 | free_irq(client->irq, client); | ||
979 | exit: | 985 | exit: |
980 | return err; | 986 | return err; |
981 | } | 987 | } |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index bc7b4fcf603c..4ff20f9dc212 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -473,7 +473,6 @@ static struct bin_attribute ds1511_nvram_attr = { | |||
473 | 473 | ||
474 | static int ds1511_rtc_probe(struct platform_device *pdev) | 474 | static int ds1511_rtc_probe(struct platform_device *pdev) |
475 | { | 475 | { |
476 | struct rtc_device *rtc; | ||
477 | struct resource *res; | 476 | struct resource *res; |
478 | struct rtc_plat_data *pdata; | 477 | struct rtc_plat_data *pdata; |
479 | int ret = 0; | 478 | int ret = 0; |
@@ -512,6 +511,12 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
512 | 511 | ||
513 | spin_lock_init(&pdata->lock); | 512 | spin_lock_init(&pdata->lock); |
514 | platform_set_drvdata(pdev, pdata); | 513 | platform_set_drvdata(pdev, pdata); |
514 | |||
515 | pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | ||
516 | &ds1511_rtc_ops, THIS_MODULE); | ||
517 | if (IS_ERR(pdata->rtc)) | ||
518 | return PTR_ERR(pdata->rtc); | ||
519 | |||
515 | /* | 520 | /* |
516 | * if the platform has an interrupt in mind for this device, | 521 | * if the platform has an interrupt in mind for this device, |
517 | * then by all means, set it | 522 | * then by all means, set it |
@@ -526,15 +531,12 @@ static int ds1511_rtc_probe(struct platform_device *pdev) | |||
526 | } | 531 | } |
527 | } | 532 | } |
528 | 533 | ||
529 | rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &ds1511_rtc_ops, | ||
530 | THIS_MODULE); | ||
531 | if (IS_ERR(rtc)) | ||
532 | return PTR_ERR(rtc); | ||
533 | pdata->rtc = rtc; | ||
534 | |||
535 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | 534 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); |
535 | if (ret) | ||
536 | dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", | ||
537 | ds1511_nvram_attr.attr.name); | ||
536 | 538 | ||
537 | return ret; | 539 | return 0; |
538 | } | 540 | } |
539 | 541 | ||
540 | static int ds1511_rtc_remove(struct platform_device *pdev) | 542 | static int ds1511_rtc_remove(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index fd31571941f5..9ac2fa07dffa 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -278,7 +278,6 @@ static struct bin_attribute ds1553_nvram_attr = { | |||
278 | 278 | ||
279 | static int ds1553_rtc_probe(struct platform_device *pdev) | 279 | static int ds1553_rtc_probe(struct platform_device *pdev) |
280 | { | 280 | { |
281 | struct rtc_device *rtc; | ||
282 | struct resource *res; | 281 | struct resource *res; |
283 | unsigned int cen, sec; | 282 | unsigned int cen, sec; |
284 | struct rtc_plat_data *pdata; | 283 | struct rtc_plat_data *pdata; |
@@ -311,6 +310,12 @@ static int ds1553_rtc_probe(struct platform_device *pdev) | |||
311 | spin_lock_init(&pdata->lock); | 310 | spin_lock_init(&pdata->lock); |
312 | pdata->last_jiffies = jiffies; | 311 | pdata->last_jiffies = jiffies; |
313 | platform_set_drvdata(pdev, pdata); | 312 | platform_set_drvdata(pdev, pdata); |
313 | |||
314 | pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | ||
315 | &ds1553_rtc_ops, THIS_MODULE); | ||
316 | if (IS_ERR(pdata->rtc)) | ||
317 | return PTR_ERR(pdata->rtc); | ||
318 | |||
314 | if (pdata->irq > 0) { | 319 | if (pdata->irq > 0) { |
315 | writeb(0, ioaddr + RTC_INTERRUPTS); | 320 | writeb(0, ioaddr + RTC_INTERRUPTS); |
316 | if (devm_request_irq(&pdev->dev, pdata->irq, | 321 | if (devm_request_irq(&pdev->dev, pdata->irq, |
@@ -321,15 +326,12 @@ static int ds1553_rtc_probe(struct platform_device *pdev) | |||
321 | } | 326 | } |
322 | } | 327 | } |
323 | 328 | ||
324 | rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | ||
325 | &ds1553_rtc_ops, THIS_MODULE); | ||
326 | if (IS_ERR(rtc)) | ||
327 | return PTR_ERR(rtc); | ||
328 | pdata->rtc = rtc; | ||
329 | |||
330 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); | 329 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); |
330 | if (ret) | ||
331 | dev_err(&pdev->dev, "unable to create sysfs file: %s\n", | ||
332 | ds1553_nvram_attr.attr.name); | ||
331 | 333 | ||
332 | return ret; | 334 | return 0; |
333 | } | 335 | } |
334 | 336 | ||
335 | static int ds1553_rtc_remove(struct platform_device *pdev) | 337 | static int ds1553_rtc_remove(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 18e2d8471472..a4888dbca2e1 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -177,8 +177,9 @@ static int ds1672_probe(struct i2c_client *client, | |||
177 | 177 | ||
178 | /* read control register */ | 178 | /* read control register */ |
179 | err = ds1672_get_control(client, &control); | 179 | err = ds1672_get_control(client, &control); |
180 | if (err) | 180 | if (err) { |
181 | goto exit_devreg; | 181 | dev_warn(&client->dev, "Unable to read the control register\n"); |
182 | } | ||
182 | 183 | ||
183 | if (control & DS1672_REG_CONTROL_EOSC) | 184 | if (control & DS1672_REG_CONTROL_EOSC) |
184 | dev_warn(&client->dev, "Oscillator not enabled. " | 185 | dev_warn(&client->dev, "Oscillator not enabled. " |
@@ -187,12 +188,10 @@ static int ds1672_probe(struct i2c_client *client, | |||
187 | /* Register sysfs hooks */ | 188 | /* Register sysfs hooks */ |
188 | err = device_create_file(&client->dev, &dev_attr_control); | 189 | err = device_create_file(&client->dev, &dev_attr_control); |
189 | if (err) | 190 | if (err) |
190 | goto exit_devreg; | 191 | dev_err(&client->dev, "Unable to create sysfs entry: %s\n", |
192 | dev_attr_control.attr.name); | ||
191 | 193 | ||
192 | return 0; | 194 | return 0; |
193 | |||
194 | exit_devreg: | ||
195 | return err; | ||
196 | } | 195 | } |
197 | 196 | ||
198 | static struct i2c_device_id ds1672_id[] = { | 197 | static struct i2c_device_id ds1672_id[] = { |
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 5a1f3b2a8f1e..942103dac30f 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -204,8 +204,11 @@ static int ds1742_rtc_probe(struct platform_device *pdev) | |||
204 | return PTR_ERR(rtc); | 204 | return PTR_ERR(rtc); |
205 | 205 | ||
206 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); | 206 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); |
207 | if (ret) | ||
208 | dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", | ||
209 | pdata->nvram_attr.attr.name); | ||
207 | 210 | ||
208 | return ret; | 211 | return 0; |
209 | } | 212 | } |
210 | 213 | ||
211 | static int ds1742_rtc_remove(struct platform_device *pdev) | 214 | static int ds1742_rtc_remove(struct platform_device *pdev) |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index b83bb5a527f8..15497c578af5 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -414,7 +414,6 @@ static int ds3232_probe(struct i2c_client *client, | |||
414 | ds3232->rtc = devm_rtc_device_register(&client->dev, client->name, | 414 | ds3232->rtc = devm_rtc_device_register(&client->dev, client->name, |
415 | &ds3232_rtc_ops, THIS_MODULE); | 415 | &ds3232_rtc_ops, THIS_MODULE); |
416 | if (IS_ERR(ds3232->rtc)) { | 416 | if (IS_ERR(ds3232->rtc)) { |
417 | dev_err(&client->dev, "unable to register the class device\n"); | ||
418 | return PTR_ERR(ds3232->rtc); | 417 | return PTR_ERR(ds3232->rtc); |
419 | } | 418 | } |
420 | 419 | ||
@@ -423,7 +422,6 @@ static int ds3232_probe(struct i2c_client *client, | |||
423 | "ds3232", client); | 422 | "ds3232", client); |
424 | if (ret) { | 423 | if (ret) { |
425 | dev_err(&client->dev, "unable to request IRQ\n"); | 424 | dev_err(&client->dev, "unable to request IRQ\n"); |
426 | return ret; | ||
427 | } | 425 | } |
428 | } | 426 | } |
429 | 427 | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 7746e65b93f2..6599c20bc454 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -104,20 +104,17 @@ static int test_probe(struct platform_device *plat_dev) | |||
104 | rtc = devm_rtc_device_register(&plat_dev->dev, "test", | 104 | rtc = devm_rtc_device_register(&plat_dev->dev, "test", |
105 | &test_rtc_ops, THIS_MODULE); | 105 | &test_rtc_ops, THIS_MODULE); |
106 | if (IS_ERR(rtc)) { | 106 | if (IS_ERR(rtc)) { |
107 | err = PTR_ERR(rtc); | 107 | return PTR_ERR(rtc); |
108 | return err; | ||
109 | } | 108 | } |
110 | 109 | ||
111 | err = device_create_file(&plat_dev->dev, &dev_attr_irq); | 110 | err = device_create_file(&plat_dev->dev, &dev_attr_irq); |
112 | if (err) | 111 | if (err) |
113 | goto err; | 112 | dev_err(&plat_dev->dev, "Unable to create sysfs entry: %s\n", |
113 | dev_attr_irq.attr.name); | ||
114 | 114 | ||
115 | platform_set_drvdata(plat_dev, rtc); | 115 | platform_set_drvdata(plat_dev, rtc); |
116 | 116 | ||
117 | return 0; | 117 | return 0; |
118 | |||
119 | err: | ||
120 | return err; | ||
121 | } | 118 | } |
122 | 119 | ||
123 | static int test_remove(struct platform_device *plat_dev) | 120 | static int test_remove(struct platform_device *plat_dev) |
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 365dc6505148..b1de58e0b3d0 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -660,7 +660,7 @@ static int x1205_probe(struct i2c_client *client, | |||
660 | 660 | ||
661 | err = x1205_sysfs_register(&client->dev); | 661 | err = x1205_sysfs_register(&client->dev); |
662 | if (err) | 662 | if (err) |
663 | return err; | 663 | dev_err(&client->dev, "Unable to create sysfs entries\n"); |
664 | 664 | ||
665 | return 0; | 665 | return 0; |
666 | } | 666 | } |