diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2019-03-20 08:32:27 -0400 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2019-04-04 04:07:08 -0400 |
commit | a652e00ee1233e251a337c28e18a1da59224e5ce (patch) | |
tree | 5d4a8cc07bf9a3e52519cca3d1d4fb23c2c4b708 | |
parent | 540a11d8bd00a89222220efcaa2f33fcbc68404f (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.c | 18 |
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 | } |