aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorRaghavendra Ganiga <ravi23ganiga@gmail.com>2014-06-06 17:36:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-06 19:08:08 -0400
commit10b06b87b77e9fcd7d1282f8cacf9736fb5143b3 (patch)
treedce63ae7ddb4aa4439c64e5c82f6403ba082d39d /drivers/rtc
parent0dd449b1626c3db6b40fc2c7685bf9b0ac79ce00 (diff)
drivers/rtc/rtc-ds1343.c: fix potential race condition
Avoid the potential race condition by avoiding bailing out of driver in probe after registering with rtc subsystem Also the set_alarm , read_alarm and alarm_irq_enable returns error if irq registration fails in probe. Also the sysfs will not create entry for alarm if irq registration fails in probe. Signed-off-by: Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com> Acked-by: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ds1343.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 8ccc75021175..c3719189dd96 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -80,6 +80,7 @@ struct ds1343_priv {
80 struct regmap *map; 80 struct regmap *map;
81 struct mutex mutex; 81 struct mutex mutex;
82 unsigned int irqen; 82 unsigned int irqen;
83 int irq;
83 int alarm_sec; 84 int alarm_sec;
84 int alarm_min; 85 int alarm_min;
85 int alarm_hour; 86 int alarm_hour;
@@ -262,28 +263,32 @@ static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
262 263
263static int ds1343_sysfs_register(struct device *dev) 264static int ds1343_sysfs_register(struct device *dev)
264{ 265{
266 struct ds1343_priv *priv = dev_get_drvdata(dev);
265 int err; 267 int err;
266 268
267 err = device_create_file(dev, &dev_attr_glitch_filter); 269 err = device_create_file(dev, &dev_attr_glitch_filter);
268 if (err) 270 if (err)
269 return err; 271 return err;
270 272
271 err = device_create_file(dev, &dev_attr_alarm_status); 273 err = device_create_file(dev, &dev_attr_trickle_charger);
272 if (err) 274 if (err)
273 goto error1; 275 goto error1;
274 276
277 if (priv->irq <= 0)
278 return err;
279
275 err = device_create_file(dev, &dev_attr_alarm_mode); 280 err = device_create_file(dev, &dev_attr_alarm_mode);
276 if (err) 281 if (err)
277 goto error2; 282 goto error2;
278 283
279 err = device_create_file(dev, &dev_attr_trickle_charger); 284 err = device_create_file(dev, &dev_attr_alarm_status);
280 if (!err) 285 if (!err)
281 return err; 286 return err;
282 287
283 device_remove_file(dev, &dev_attr_alarm_mode); 288 device_remove_file(dev, &dev_attr_alarm_mode);
284 289
285error2: 290error2:
286 device_remove_file(dev, &dev_attr_alarm_status); 291 device_remove_file(dev, &dev_attr_trickle_charger);
287 292
288error1: 293error1:
289 device_remove_file(dev, &dev_attr_glitch_filter); 294 device_remove_file(dev, &dev_attr_glitch_filter);
@@ -293,10 +298,16 @@ error1:
293 298
294static void ds1343_sysfs_unregister(struct device *dev) 299static void ds1343_sysfs_unregister(struct device *dev)
295{ 300{
301 struct ds1343_priv *priv = dev_get_drvdata(dev);
302
296 device_remove_file(dev, &dev_attr_glitch_filter); 303 device_remove_file(dev, &dev_attr_glitch_filter);
304 device_remove_file(dev, &dev_attr_trickle_charger);
305
306 if (priv->irq <= 0)
307 return;
308
297 device_remove_file(dev, &dev_attr_alarm_status); 309 device_remove_file(dev, &dev_attr_alarm_status);
298 device_remove_file(dev, &dev_attr_alarm_mode); 310 device_remove_file(dev, &dev_attr_alarm_mode);
299 device_remove_file(dev, &dev_attr_trickle_charger);
300} 311}
301 312
302static int ds1343_read_time(struct device *dev, struct rtc_time *dt) 313static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
@@ -415,11 +426,10 @@ static int ds1343_update_alarm(struct device *dev)
415static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 426static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
416{ 427{
417 struct ds1343_priv *priv = dev_get_drvdata(dev); 428 struct ds1343_priv *priv = dev_get_drvdata(dev);
418 struct spi_device *spi = priv->spi;
419 int res = 0; 429 int res = 0;
420 unsigned int stat; 430 unsigned int stat;
421 431
422 if (spi->irq <= 0) 432 if (priv->irq <= 0)
423 return -EINVAL; 433 return -EINVAL;
424 434
425 mutex_lock(&priv->mutex); 435 mutex_lock(&priv->mutex);
@@ -450,10 +460,9 @@ out:
450static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 460static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
451{ 461{
452 struct ds1343_priv *priv = dev_get_drvdata(dev); 462 struct ds1343_priv *priv = dev_get_drvdata(dev);
453 struct spi_device *spi = priv->spi;
454 int res = 0; 463 int res = 0;
455 464
456 if (spi->irq <= 0) 465 if (priv->irq <= 0)
457 return -EINVAL; 466 return -EINVAL;
458 467
459 mutex_lock(&priv->mutex); 468 mutex_lock(&priv->mutex);
@@ -476,10 +485,9 @@ static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
476static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled) 485static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled)
477{ 486{
478 struct ds1343_priv *priv = dev_get_drvdata(dev); 487 struct ds1343_priv *priv = dev_get_drvdata(dev);
479 struct spi_device *spi = priv->spi;
480 int res = 0; 488 int res = 0;
481 489
482 if (spi->irq <= 0) 490 if (priv->irq <= 0)
483 return -EINVAL; 491 return -EINVAL;
484 492
485 mutex_lock(&priv->mutex); 493 mutex_lock(&priv->mutex);
@@ -593,18 +601,20 @@ static int ds1343_probe(struct spi_device *spi)
593 return PTR_ERR(priv->rtc); 601 return PTR_ERR(priv->rtc);
594 } 602 }
595 603
596 if (spi->irq >= 0) { 604 priv->irq = spi->irq;
605
606 if (priv->irq >= 0) {
597 res = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, 607 res = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
598 ds1343_thread, 608 ds1343_thread,
599 IRQF_NO_SUSPEND | IRQF_ONESHOT, 609 IRQF_NO_SUSPEND | IRQF_ONESHOT,
600 "ds1343", priv); 610 "ds1343", priv);
601 if (res) { 611 if (res) {
612 priv->irq = -1;
602 dev_err(&spi->dev, 613 dev_err(&spi->dev,
603 "unable to request irq for rtc ds1343\n"); 614 "unable to request irq for rtc ds1343\n");
604 return res; 615 } else {
616 device_set_wakeup_capable(&spi->dev, 1);
605 } 617 }
606
607 device_set_wakeup_capable(&spi->dev, 1);
608 } 618 }
609 619
610 res = ds1343_sysfs_register(&spi->dev); 620 res = ds1343_sysfs_register(&spi->dev);