X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Frtc%2Frtc-at91.c;h=bd61e99540a330450478a5c45832adda143fdc00;hb=6c50444723f2e6487b3377450f90d813a88e6c31;hp=dfd0ce86f6a0d82e445752653e667899959d22cd;hpb=ca78f6baca863afe2e6a244a0fe94b3a70211d46;p=powerpc.git diff --git a/drivers/rtc/rtc-at91.c b/drivers/rtc/rtc-at91.c index dfd0ce86f6..bd61e99540 100644 --- a/drivers/rtc/rtc-at91.c +++ b/drivers/rtc/rtc-at91.c @@ -238,8 +238,7 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) /* * IRQ handler for the RTC */ -static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct rtc_device *rtc = platform_get_drvdata(pdev); @@ -267,7 +266,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id, return IRQ_NONE; /* not handled */ } -static struct rtc_class_ops at91_rtc_ops = { +static const struct rtc_class_ops at91_rtc_ops = { .ioctl = at91_rtc_ioctl, .read_time = at91_rtc_readtime, .set_time = at91_rtc_settime, @@ -307,6 +306,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc); } platform_set_drvdata(pdev, rtc); + device_init_wakeup(&pdev->dev, 1); printk(KERN_INFO "AT91 Real Time Clock driver.\n"); return 0; @@ -327,6 +327,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev) rtc_device_unregister(rtc); platform_set_drvdata(pdev, NULL); + device_init_wakeup(&pdev->dev, 0); return 0; } @@ -336,6 +337,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev) /* AT91RM9200 RTC Power management control */ static struct timespec at91_rtc_delta; +static u32 at91_rtc_imr; static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) { @@ -349,6 +351,18 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) rtc_tm_to_time(&tm, &time.tv_sec); save_time_delta(&at91_rtc_delta, &time); + /* this IRQ is shared with DBGU and other hardware which isn't + * necessarily doing PM like we are... + */ + at91_rtc_imr = at91_sys_read(AT91_RTC_IMR) + & (AT91_RTC_ALARM|AT91_RTC_SECEV); + if (at91_rtc_imr) { + if (device_may_wakeup(&pdev->dev)) + enable_irq_wake(AT91_ID_SYS); + else + at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); + } + pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); @@ -367,6 +381,13 @@ static int at91_rtc_resume(struct platform_device *pdev) rtc_tm_to_time(&tm, &time.tv_sec); restore_time_delta(&at91_rtc_delta, &time); + if (at91_rtc_imr) { + if (device_may_wakeup(&pdev->dev)) + disable_irq_wake(AT91_ID_SYS); + else + at91_sys_write(AT91_RTC_IER, at91_rtc_imr); + } + pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);