diff options
Diffstat (limited to 'drivers/rtc/rtc-wm8350.c')
-rw-r--r-- | drivers/rtc/rtc-wm8350.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index c91edc572eb6..3d0dc76b38af 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c | |||
@@ -307,17 +307,24 @@ static int wm8350_rtc_update_irq_enable(struct device *dev, | |||
307 | { | 307 | { |
308 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | 308 | struct wm8350 *wm8350 = dev_get_drvdata(dev); |
309 | 309 | ||
310 | /* Suppress duplicate changes since genirq nests enable and | ||
311 | * disable calls. */ | ||
312 | if (enabled == wm8350->rtc.update_enabled) | ||
313 | return 0; | ||
314 | |||
310 | if (enabled) | 315 | if (enabled) |
311 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); | 316 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); |
312 | else | 317 | else |
313 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | 318 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); |
314 | 319 | ||
320 | wm8350->rtc.update_enabled = enabled; | ||
321 | |||
315 | return 0; | 322 | return 0; |
316 | } | 323 | } |
317 | 324 | ||
318 | static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq, | 325 | static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data) |
319 | void *data) | ||
320 | { | 326 | { |
327 | struct wm8350 *wm8350 = data; | ||
321 | struct rtc_device *rtc = wm8350->rtc.rtc; | 328 | struct rtc_device *rtc = wm8350->rtc.rtc; |
322 | int ret; | 329 | int ret; |
323 | 330 | ||
@@ -330,14 +337,18 @@ static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq, | |||
330 | dev_err(&(wm8350->rtc.pdev->dev), | 337 | dev_err(&(wm8350->rtc.pdev->dev), |
331 | "Failed to disable alarm: %d\n", ret); | 338 | "Failed to disable alarm: %d\n", ret); |
332 | } | 339 | } |
340 | |||
341 | return IRQ_HANDLED; | ||
333 | } | 342 | } |
334 | 343 | ||
335 | static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq, | 344 | static irqreturn_t wm8350_rtc_update_handler(int irq, void *data) |
336 | void *data) | ||
337 | { | 345 | { |
346 | struct wm8350 *wm8350 = data; | ||
338 | struct rtc_device *rtc = wm8350->rtc.rtc; | 347 | struct rtc_device *rtc = wm8350->rtc.rtc; |
339 | 348 | ||
340 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF); | 349 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF); |
350 | |||
351 | return IRQ_HANDLED; | ||
341 | } | 352 | } |
342 | 353 | ||
343 | static const struct rtc_class_ops wm8350_rtc_ops = { | 354 | static const struct rtc_class_ops wm8350_rtc_ops = { |
@@ -350,8 +361,9 @@ static const struct rtc_class_ops wm8350_rtc_ops = { | |||
350 | }; | 361 | }; |
351 | 362 | ||
352 | #ifdef CONFIG_PM | 363 | #ifdef CONFIG_PM |
353 | static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 364 | static int wm8350_rtc_suspend(struct device *dev) |
354 | { | 365 | { |
366 | struct platform_device *pdev = to_platform_device(dev); | ||
355 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); | 367 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); |
356 | int ret = 0; | 368 | int ret = 0; |
357 | u16 reg; | 369 | u16 reg; |
@@ -369,8 +381,9 @@ static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
369 | return ret; | 381 | return ret; |
370 | } | 382 | } |
371 | 383 | ||
372 | static int wm8350_rtc_resume(struct platform_device *pdev) | 384 | static int wm8350_rtc_resume(struct device *dev) |
373 | { | 385 | { |
386 | struct platform_device *pdev = to_platform_device(dev); | ||
374 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); | 387 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); |
375 | int ret; | 388 | int ret; |
376 | 389 | ||
@@ -455,15 +468,14 @@ static int wm8350_rtc_probe(struct platform_device *pdev) | |||
455 | return ret; | 468 | return ret; |
456 | } | 469 | } |
457 | 470 | ||
458 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
459 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_PER); | ||
460 | |||
461 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, | 471 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, |
462 | wm8350_rtc_update_handler, NULL); | 472 | wm8350_rtc_update_handler, 0, |
473 | "RTC Seconds", wm8350); | ||
474 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
463 | 475 | ||
464 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, | 476 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, |
465 | wm8350_rtc_alarm_handler, NULL); | 477 | wm8350_rtc_alarm_handler, 0, |
466 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM); | 478 | "RTC Alarm", wm8350); |
467 | 479 | ||
468 | return 0; | 480 | return 0; |
469 | } | 481 | } |
@@ -473,23 +485,25 @@ static int __devexit wm8350_rtc_remove(struct platform_device *pdev) | |||
473 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | 485 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); |
474 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; | 486 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; |
475 | 487 | ||
476 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | 488 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); |
477 | 489 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350); | |
478 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
479 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM); | ||
480 | 490 | ||
481 | rtc_device_unregister(wm_rtc->rtc); | 491 | rtc_device_unregister(wm_rtc->rtc); |
482 | 492 | ||
483 | return 0; | 493 | return 0; |
484 | } | 494 | } |
485 | 495 | ||
496 | static struct dev_pm_ops wm8350_rtc_pm_ops = { | ||
497 | .suspend = wm8350_rtc_suspend, | ||
498 | .resume = wm8350_rtc_resume, | ||
499 | }; | ||
500 | |||
486 | static struct platform_driver wm8350_rtc_driver = { | 501 | static struct platform_driver wm8350_rtc_driver = { |
487 | .probe = wm8350_rtc_probe, | 502 | .probe = wm8350_rtc_probe, |
488 | .remove = __devexit_p(wm8350_rtc_remove), | 503 | .remove = __devexit_p(wm8350_rtc_remove), |
489 | .suspend = wm8350_rtc_suspend, | ||
490 | .resume = wm8350_rtc_resume, | ||
491 | .driver = { | 504 | .driver = { |
492 | .name = "wm8350-rtc", | 505 | .name = "wm8350-rtc", |
506 | .pm = &wm8350_rtc_pm_ops, | ||
493 | }, | 507 | }, |
494 | }; | 508 | }; |
495 | 509 | ||