aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-spear.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2012-03-23 18:02:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 19:58:39 -0400
commitee6c54ca64416c75aa6f5021e139f270192bae49 (patch)
tree32c16e2747c4414bdb52939909e071fa07ba7fae /drivers/rtc/rtc-spear.c
parent131f8b75f1c00a5a822ff2103db588466e942490 (diff)
rtc/rtc-spear: call platform_set_drvdata() before registering rtc device
rtc_device_register() calls rtc-spear routines internally. These routines call dev_get_drvdata() to get struct spear_rtc_config. Currently, platform_set_drvdata is called after rtc device is registered. This causes system to crash, as dev_get_drvdata returns NULL. For this we need to call platform_set_drvdata() before registering rtc device. This requires further cleanup, that leads to removal of dev_set_drvdata on rtc->dev, which was just not required at all. Also, we change the parameter to request_irq and pass pointer to config instead of pointer to rtc struct. This patch brings all above changes. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Cc: Shiraz Hashim <shiraz.hashim@st.com> Cc: Deepak Sikri <deepak.sikri@st.com> Acked-by: Rajeev Kumar <rajeev-dlh.kumar@st.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-spear.c')
-rw-r--r--drivers/rtc/rtc-spear.c61
1 files changed, 21 insertions, 40 deletions
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index 646937473515..e38da0dc4187 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -77,6 +77,7 @@
77#define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE) 77#define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE)
78 78
79struct spear_rtc_config { 79struct spear_rtc_config {
80 struct rtc_device *rtc;
80 struct clk *clk; 81 struct clk *clk;
81 spinlock_t lock; 82 spinlock_t lock;
82 void __iomem *ioaddr; 83 void __iomem *ioaddr;
@@ -150,8 +151,7 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config)
150 151
151static irqreturn_t spear_rtc_irq(int irq, void *dev_id) 152static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
152{ 153{
153 struct rtc_device *rtc = (struct rtc_device *)dev_id; 154 struct spear_rtc_config *config = dev_id;
154 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
155 unsigned long flags, events = 0; 155 unsigned long flags, events = 0;
156 unsigned int irq_data; 156 unsigned int irq_data;
157 157
@@ -162,7 +162,7 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
162 if ((irq_data & RTC_INT_MASK)) { 162 if ((irq_data & RTC_INT_MASK)) {
163 spear_rtc_clear_interrupt(config); 163 spear_rtc_clear_interrupt(config);
164 events = RTC_IRQF | RTC_AF; 164 events = RTC_IRQF | RTC_AF;
165 rtc_update_irq(rtc, 1, events); 165 rtc_update_irq(config->rtc, 1, events);
166 return IRQ_HANDLED; 166 return IRQ_HANDLED;
167 } else 167 } else
168 return IRQ_NONE; 168 return IRQ_NONE;
@@ -204,9 +204,7 @@ static void bcd2tm(struct rtc_time *tm)
204 */ 204 */
205static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) 205static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
206{ 206{
207 struct platform_device *pdev = to_platform_device(dev); 207 struct spear_rtc_config *config = dev_get_drvdata(dev);
208 struct rtc_device *rtc = platform_get_drvdata(pdev);
209 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
210 unsigned int time, date; 208 unsigned int time, date;
211 209
212 /* we don't report wday/yday/isdst ... */ 210 /* we don't report wday/yday/isdst ... */
@@ -235,9 +233,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
235 */ 233 */
236static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) 234static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
237{ 235{
238 struct platform_device *pdev = to_platform_device(dev); 236 struct spear_rtc_config *config = dev_get_drvdata(dev);
239 struct rtc_device *rtc = platform_get_drvdata(pdev);
240 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
241 unsigned int time, date, err = 0; 237 unsigned int time, date, err = 0;
242 238
243 if (tm2bcd(tm) < 0) 239 if (tm2bcd(tm) < 0)
@@ -267,9 +263,7 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
267 */ 263 */
268static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 264static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
269{ 265{
270 struct platform_device *pdev = to_platform_device(dev); 266 struct spear_rtc_config *config = dev_get_drvdata(dev);
271 struct rtc_device *rtc = platform_get_drvdata(pdev);
272 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
273 unsigned int time, date; 267 unsigned int time, date;
274 268
275 rtc_wait_not_busy(config); 269 rtc_wait_not_busy(config);
@@ -299,9 +293,7 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
299 */ 293 */
300static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 294static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
301{ 295{
302 struct platform_device *pdev = to_platform_device(dev); 296 struct spear_rtc_config *config = dev_get_drvdata(dev);
303 struct rtc_device *rtc = platform_get_drvdata(pdev);
304 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
305 unsigned int time, date, err = 0; 297 unsigned int time, date, err = 0;
306 298
307 if (tm2bcd(&alm->time) < 0) 299 if (tm2bcd(&alm->time) < 0)
@@ -330,9 +322,7 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
330 322
331static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled) 323static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled)
332{ 324{
333 struct platform_device *pdev = to_platform_device(dev); 325 struct spear_rtc_config *config = dev_get_drvdata(dev);
334 struct rtc_device *rtc = platform_get_drvdata(pdev);
335 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
336 int ret = 0; 326 int ret = 0;
337 327
338 spear_rtc_clear_interrupt(config); 328 spear_rtc_clear_interrupt(config);
@@ -365,7 +355,6 @@ static struct rtc_class_ops spear_rtc_ops = {
365static int __devinit spear_rtc_probe(struct platform_device *pdev) 355static int __devinit spear_rtc_probe(struct platform_device *pdev)
366{ 356{
367 struct resource *res; 357 struct resource *res;
368 struct rtc_device *rtc;
369 struct spear_rtc_config *config; 358 struct spear_rtc_config *config;
370 unsigned int status = 0; 359 unsigned int status = 0;
371 int irq; 360 int irq;
@@ -405,19 +394,17 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
405 } 394 }
406 395
407 spin_lock_init(&config->lock); 396 spin_lock_init(&config->lock);
397 platform_set_drvdata(pdev, config);
408 398
409 rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops, 399 config->rtc = rtc_device_register(pdev->name, &pdev->dev,
410 THIS_MODULE); 400 &spear_rtc_ops, THIS_MODULE);
411 if (IS_ERR(rtc)) { 401 if (IS_ERR(config->rtc)) {
412 dev_err(&pdev->dev, "can't register RTC device, err %ld\n", 402 dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
413 PTR_ERR(rtc)); 403 PTR_ERR(config->rtc));
414 status = PTR_ERR(rtc); 404 status = PTR_ERR(config->rtc);
415 goto err_iounmap; 405 goto err_iounmap;
416 } 406 }
417 407
418 platform_set_drvdata(pdev, rtc);
419 dev_set_drvdata(&rtc->dev, config);
420
421 /* alarm irqs */ 408 /* alarm irqs */
422 irq = platform_get_irq(pdev, 0); 409 irq = platform_get_irq(pdev, 0);
423 if (irq < 0) { 410 if (irq < 0) {
@@ -426,7 +413,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
426 goto err_clear_platdata; 413 goto err_clear_platdata;
427 } 414 }
428 415
429 status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc); 416 status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config);
430 if (status) { 417 if (status) {
431 dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \ 418 dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
432 claimed\n", irq); 419 claimed\n", irq);
@@ -440,8 +427,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
440 427
441err_clear_platdata: 428err_clear_platdata:
442 platform_set_drvdata(pdev, NULL); 429 platform_set_drvdata(pdev, NULL);
443 dev_set_drvdata(&rtc->dev, NULL); 430 rtc_device_unregister(config->rtc);
444 rtc_device_unregister(rtc);
445err_iounmap: 431err_iounmap:
446 iounmap(config->ioaddr); 432 iounmap(config->ioaddr);
447err_disable_clock: 433err_disable_clock:
@@ -458,8 +444,7 @@ err_release_region:
458 444
459static int __devexit spear_rtc_remove(struct platform_device *pdev) 445static int __devexit spear_rtc_remove(struct platform_device *pdev)
460{ 446{
461 struct rtc_device *rtc = platform_get_drvdata(pdev); 447 struct spear_rtc_config *config = platform_get_drvdata(pdev);
462 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
463 int irq; 448 int irq;
464 struct resource *res; 449 struct resource *res;
465 450
@@ -477,8 +462,7 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
477 if (res) 462 if (res)
478 release_mem_region(res->start, resource_size(res)); 463 release_mem_region(res->start, resource_size(res));
479 platform_set_drvdata(pdev, NULL); 464 platform_set_drvdata(pdev, NULL);
480 dev_set_drvdata(&rtc->dev, NULL); 465 rtc_device_unregister(config->rtc);
481 rtc_device_unregister(rtc);
482 466
483 return 0; 467 return 0;
484} 468}
@@ -487,8 +471,7 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
487 471
488static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state) 472static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
489{ 473{
490 struct rtc_device *rtc = platform_get_drvdata(pdev); 474 struct spear_rtc_config *config = platform_get_drvdata(pdev);
491 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
492 int irq; 475 int irq;
493 476
494 irq = platform_get_irq(pdev, 0); 477 irq = platform_get_irq(pdev, 0);
@@ -505,8 +488,7 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
505 488
506static int spear_rtc_resume(struct platform_device *pdev) 489static int spear_rtc_resume(struct platform_device *pdev)
507{ 490{
508 struct rtc_device *rtc = platform_get_drvdata(pdev); 491 struct spear_rtc_config *config = platform_get_drvdata(pdev);
509 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
510 int irq; 492 int irq;
511 493
512 irq = platform_get_irq(pdev, 0); 494 irq = platform_get_irq(pdev, 0);
@@ -531,8 +513,7 @@ static int spear_rtc_resume(struct platform_device *pdev)
531 513
532static void spear_rtc_shutdown(struct platform_device *pdev) 514static void spear_rtc_shutdown(struct platform_device *pdev)
533{ 515{
534 struct rtc_device *rtc = platform_get_drvdata(pdev); 516 struct spear_rtc_config *config = platform_get_drvdata(pdev);
535 struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
536 517
537 spear_rtc_disable_interrupt(config); 518 spear_rtc_disable_interrupt(config);
538 clk_disable(config->clk); 519 clk_disable(config->clk);