rtc: st-lpc: 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 before requesting the IRQ. Acked-by: Patrice Chotard <patrice.chotard@st.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
b72252b658
commit
d482510fee
1 changed files with 9 additions and 15 deletions
|
@ -212,6 +212,10 @@ static int st_rtc_probe(struct platform_device *pdev)
|
||||||
if (!rtc)
|
if (!rtc)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
|
||||||
|
if (IS_ERR(rtc->rtc_dev))
|
||||||
|
return PTR_ERR(rtc->rtc_dev);
|
||||||
|
|
||||||
spin_lock_init(&rtc->lock);
|
spin_lock_init(&rtc->lock);
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
@ -253,26 +257,17 @@ static int st_rtc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
|
||||||
rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev,
|
rtc->rtc_dev->ops = &st_rtc_ops;
|
||||||
&st_rtc_ops, THIS_MODULE);
|
|
||||||
if (IS_ERR(rtc->rtc_dev)) {
|
ret = rtc_register_device(rtc->rtc_dev);
|
||||||
|
if (ret) {
|
||||||
clk_disable_unprepare(rtc->clk);
|
clk_disable_unprepare(rtc->clk);
|
||||||
return PTR_ERR(rtc->rtc_dev);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int st_rtc_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct st_rtc *rtc = platform_get_drvdata(pdev);
|
|
||||||
|
|
||||||
if (likely(rtc->rtc_dev))
|
|
||||||
rtc_device_unregister(rtc->rtc_dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
static int st_rtc_suspend(struct device *dev)
|
static int st_rtc_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -325,7 +320,6 @@ static struct platform_driver st_rtc_platform_driver = {
|
||||||
.of_match_table = st_rtc_match,
|
.of_match_table = st_rtc_match,
|
||||||
},
|
},
|
||||||
.probe = st_rtc_probe,
|
.probe = st_rtc_probe,
|
||||||
.remove = st_rtc_remove,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(st_rtc_platform_driver);
|
module_platform_driver(st_rtc_platform_driver);
|
||||||
|
|
Loading…
Add table
Reference in a new issue