summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@bootlin.com>2019-03-20 08:32:27 -0400
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2019-04-04 04:07:08 -0400
commita652e00ee1233e251a337c28e18a1da59224e5ce (patch)
tree5d4a8cc07bf9a3e52519cca3d1d4fb23c2c4b708
parent540a11d8bd00a89222220efcaa2f33fcbc68404f (diff)
rtc: xgene: fix possible race condition
The IRQ is requested before the struct rtc is allocated and registered, but this struct is used in the IRQ handler. This may lead to a NULL pointer dereference. Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc struct before requesting the IRQ. Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
-rw-r--r--drivers/rtc/rtc-xgene.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c
index 153820876a82..2f741f455c30 100644
--- a/drivers/rtc/rtc-xgene.c
+++ b/drivers/rtc/rtc-xgene.c
@@ -168,6 +168,10 @@ static int xgene_rtc_probe(struct platform_device *pdev)
168 if (IS_ERR(pdata->csr_base)) 168 if (IS_ERR(pdata->csr_base))
169 return PTR_ERR(pdata->csr_base); 169 return PTR_ERR(pdata->csr_base);
170 170
171 pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
172 if (IS_ERR(pdata->rtc))
173 return PTR_ERR(pdata->rtc);
174
171 irq = platform_get_irq(pdev, 0); 175 irq = platform_get_irq(pdev, 0);
172 if (irq < 0) { 176 if (irq < 0) {
173 dev_err(&pdev->dev, "No IRQ resource\n"); 177 dev_err(&pdev->dev, "No IRQ resource\n");
@@ -198,15 +202,15 @@ static int xgene_rtc_probe(struct platform_device *pdev)
198 return ret; 202 return ret;
199 } 203 }
200 204
201 pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
202 &xgene_rtc_ops, THIS_MODULE);
203 if (IS_ERR(pdata->rtc)) {
204 clk_disable_unprepare(pdata->clk);
205 return PTR_ERR(pdata->rtc);
206 }
207
208 /* HW does not support update faster than 1 seconds */ 205 /* HW does not support update faster than 1 seconds */
209 pdata->rtc->uie_unsupported = 1; 206 pdata->rtc->uie_unsupported = 1;
207 pdata->rtc->ops = &xgene_rtc_ops;
208
209 ret = rtc_register_device(pdata->rtc);
210 if (ret) {
211 clk_disable_unprepare(pdata->clk);
212 return ret;
213 }
210 214
211 return 0; 215 return 0;
212} 216}