Commit a91d2bab355f3a5caa767d7316f80422bfcd2ad6

Authored by Wolfram Sang
Committed by John Stultz
1 parent 46b2121814

rtc: stmp3xxx: Initialize drvdata before registering device

Commit f44f7f96a20 ("RTC: Initialize kernel state from RTC") uncovered
an issue in a number of RTC drivers, where the drivers call
rtc_device_register before initializing the device or platform drvdata.

This frequently results in null pointer dereferences when the
rtc_device_register immediately makes use of the rtc device, calling
rtc_read_alarm.

The solution is to ensure the drvdata is initialized prior to registering
the rtc device.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>

Showing 1 changed file with 5 additions and 2 deletions Side-by-side Diff

drivers/rtc/rtc-stmp3xxx.c
... ... @@ -176,6 +176,7 @@
176 176 free_irq(rtc_data->irq_alarm, &pdev->dev);
177 177 free_irq(rtc_data->irq_1msec, &pdev->dev);
178 178 rtc_device_unregister(rtc_data->rtc);
  179 + platform_set_drvdata(pdev, NULL);
179 180 iounmap(rtc_data->io);
180 181 kfree(rtc_data);
181 182  
182 183  
... ... @@ -216,11 +217,14 @@
216 217 goto out_remap;
217 218 }
218 219  
  220 + platform_set_drvdata(pdev, rtc_data);
  221 +
219 222 mxs_reset_block(rtc_data->io);
220 223 __mxs_clrl(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
221 224 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
222 225 STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
223 226 rtc_data->io + STMP3XXX_RTC_PERSISTENT0);
  227 +
224 228 rtc_data->rtc = rtc_device_register(pdev->name, &pdev->dev,
225 229 &stmp3xxx_rtc_ops, THIS_MODULE);
226 230 if (IS_ERR(rtc_data->rtc)) {
... ... @@ -244,8 +248,6 @@
244 248 goto out_irq1;
245 249 }
246 250  
247   - platform_set_drvdata(pdev, rtc_data);
248   -
249 251 return 0;
250 252  
251 253 out_irq1:
... ... @@ -256,6 +258,7 @@
256 258 rtc_data->io + STMP3XXX_RTC_CTRL);
257 259 rtc_device_unregister(rtc_data->rtc);
258 260 out_remap:
  261 + platform_set_drvdata(pdev, NULL);
259 262 iounmap(rtc_data->io);
260 263 out_free:
261 264 kfree(rtc_data);