diff options
Diffstat (limited to 'drivers/rtc/rtc-pcf50633.c')
| -rw-r--r-- | drivers/rtc/rtc-pcf50633.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index f4dd87e29075..854c3cb365a1 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c | |||
| @@ -58,6 +58,7 @@ struct pcf50633_time { | |||
| 58 | struct pcf50633_rtc { | 58 | struct pcf50633_rtc { |
| 59 | int alarm_enabled; | 59 | int alarm_enabled; |
| 60 | int second_enabled; | 60 | int second_enabled; |
| 61 | int alarm_pending; | ||
| 61 | 62 | ||
| 62 | struct pcf50633 *pcf; | 63 | struct pcf50633 *pcf; |
| 63 | struct rtc_device *rtc_dev; | 64 | struct rtc_device *rtc_dev; |
| @@ -70,7 +71,7 @@ static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf) | |||
| 70 | rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]); | 71 | rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]); |
| 71 | rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]); | 72 | rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]); |
| 72 | rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]); | 73 | rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]); |
| 73 | rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]); | 74 | rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]) - 1; |
| 74 | rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100; | 75 | rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| @@ -81,7 +82,7 @@ static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc) | |||
| 81 | pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour); | 82 | pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour); |
| 82 | pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday); | 83 | pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday); |
| 83 | pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday); | 84 | pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday); |
| 84 | pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon); | 85 | pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon + 1); |
| 85 | pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100); | 86 | pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100); |
| 86 | } | 87 | } |
| 87 | 88 | ||
| @@ -209,6 +210,7 @@ static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 209 | rtc = dev_get_drvdata(dev); | 210 | rtc = dev_get_drvdata(dev); |
| 210 | 211 | ||
| 211 | alrm->enabled = rtc->alarm_enabled; | 212 | alrm->enabled = rtc->alarm_enabled; |
| 213 | alrm->pending = rtc->alarm_pending; | ||
| 212 | 214 | ||
| 213 | ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA, | 215 | ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA, |
| 214 | PCF50633_TI_EXTENT, &pcf_tm.time[0]); | 216 | PCF50633_TI_EXTENT, &pcf_tm.time[0]); |
| @@ -244,9 +246,12 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 244 | /* Returns 0 on success */ | 246 | /* Returns 0 on success */ |
| 245 | ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA, | 247 | ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA, |
| 246 | PCF50633_TI_EXTENT, &pcf_tm.time[0]); | 248 | PCF50633_TI_EXTENT, &pcf_tm.time[0]); |
| 249 | if (!alrm->enabled) | ||
| 250 | rtc->alarm_pending = 0; | ||
| 247 | 251 | ||
| 248 | if (!alarm_masked) | 252 | if (!alarm_masked || alrm->enabled) |
| 249 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); | 253 | pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); |
| 254 | rtc->alarm_enabled = alrm->enabled; | ||
| 250 | 255 | ||
| 251 | return ret; | 256 | return ret; |
| 252 | } | 257 | } |
| @@ -267,6 +272,7 @@ static void pcf50633_rtc_irq(int irq, void *data) | |||
| 267 | switch (irq) { | 272 | switch (irq) { |
| 268 | case PCF50633_IRQ_ALARM: | 273 | case PCF50633_IRQ_ALARM: |
| 269 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | 274 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); |
| 275 | rtc->alarm_pending = 1; | ||
| 270 | break; | 276 | break; |
| 271 | case PCF50633_IRQ_SECOND: | 277 | case PCF50633_IRQ_SECOND: |
| 272 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | 278 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); |
| @@ -276,23 +282,21 @@ static void pcf50633_rtc_irq(int irq, void *data) | |||
| 276 | 282 | ||
| 277 | static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) | 283 | static int __devinit pcf50633_rtc_probe(struct platform_device *pdev) |
| 278 | { | 284 | { |
| 279 | struct pcf50633_subdev_pdata *pdata; | ||
| 280 | struct pcf50633_rtc *rtc; | 285 | struct pcf50633_rtc *rtc; |
| 281 | 286 | ||
| 282 | |||
| 283 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | 287 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); |
| 284 | if (!rtc) | 288 | if (!rtc) |
| 285 | return -ENOMEM; | 289 | return -ENOMEM; |
| 286 | 290 | ||
| 287 | pdata = pdev->dev.platform_data; | 291 | rtc->pcf = dev_to_pcf50633(pdev->dev.parent); |
| 288 | rtc->pcf = pdata->pcf; | ||
| 289 | platform_set_drvdata(pdev, rtc); | 292 | platform_set_drvdata(pdev, rtc); |
| 290 | rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev, | 293 | rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev, |
| 291 | &pcf50633_rtc_ops, THIS_MODULE); | 294 | &pcf50633_rtc_ops, THIS_MODULE); |
| 292 | 295 | ||
| 293 | if (IS_ERR(rtc->rtc_dev)) { | 296 | if (IS_ERR(rtc->rtc_dev)) { |
| 297 | int ret = PTR_ERR(rtc->rtc_dev); | ||
| 294 | kfree(rtc); | 298 | kfree(rtc); |
| 295 | return PTR_ERR(rtc->rtc_dev); | 299 | return ret; |
| 296 | } | 300 | } |
| 297 | 301 | ||
| 298 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM, | 302 | pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM, |
