Skip to content

Commit

Permalink
drivers/rtc/rtc-mc13xxx.c: fix potential race condition
Browse files Browse the repository at this point in the history
RTC drivers must not return an error after device registration.  This
patch makes RTC registration as the last action.

Signed-off-by: Alexander Shiyan <[email protected]>
Acked-by: Alessandro Zummo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
shcgit authored and torvalds committed Apr 3, 2014
1 parent fda9909 commit 5ab9a52
Showing 1 changed file with 13 additions and 17 deletions.
30 changes: 13 additions & 17 deletions drivers/rtc/rtc-mc13xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,6 @@ static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev)
struct mc13xxx_rtc *priv = dev;
struct mc13xxx *mc13xxx = priv->mc13xxx;

dev_dbg(&priv->rtc->dev, "Alarm\n");

rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);

mc13xxx_irq_ack(mc13xxx, irq);
Expand All @@ -261,8 +259,6 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
struct mc13xxx_rtc *priv = dev;
struct mc13xxx *mc13xxx = priv->mc13xxx;

dev_dbg(&priv->rtc->dev, "1HZ\n");

rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);

mc13xxx_irq_ack(mc13xxx, irq);
Expand All @@ -283,7 +279,6 @@ static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev)
struct mc13xxx_rtc *priv = dev;
struct mc13xxx *mc13xxx = priv->mc13xxx;

dev_warn(&priv->rtc->dev, "Contents of the RTC are no longer valid\n");
priv->valid = 0;

mc13xxx_irq_mask(mc13xxx, irq);
Expand All @@ -307,36 +302,37 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, priv);

priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&mc13xxx_rtc_ops, THIS_MODULE);
if (IS_ERR(priv->rtc))
return PTR_ERR(priv->rtc);

mc13xxx_lock(mc13xxx);

mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST);

ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST,
mc13xxx_rtc_reset_handler, DRIVER_NAME, priv);
if (ret)
goto err_reset_irq_request;
goto err_irq_request;

ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ,
mc13xxx_rtc_update_handler, DRIVER_NAME, priv);
if (ret)
goto err_reset_irq_status;
goto err_irq_request;

ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
if (!ret)
goto err_reset_irq_request;
if (ret)
goto err_irq_request;

mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
mc13xxx_unlock(mc13xxx);

priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&mc13xxx_rtc_ops, THIS_MODULE);

err_reset_irq_status:
return 0;

err_irq_request:
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);

err_reset_irq_request:
mc13xxx_unlock(mc13xxx);

return ret;
Expand Down

0 comments on commit 5ab9a52

Please sign in to comment.