int pcf50633_irq_suspend(struct pcf50633 *pcf) { int ret; int i; u8 res[5]; /* Make sure our interrupt handlers are not called * henceforth */ disable_irq(pcf->irq); /* Save the masks */ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(pcf->suspend_irq_masks), pcf->suspend_irq_masks); if (ret < 0) { dev_err(pcf->dev, "error saving irq masks\n"); goto out; } /* Write wakeup irq masks */ for (i = 0; i < ARRAY_SIZE(res); i++) res[i] = ~pcf->pdata->resumers[i]; ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(res), &res[0]); if (ret < 0) { dev_err(pcf->dev, "error writing wakeup irq masks\n"); goto out; } pcf->is_suspended = 1; out: return ret; }
static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pcf50633_rtc *rtc; struct pcf50633_time pcf_tm; int alarm_masked, ret = 0; rtc = dev_get_drvdata(dev); rtc2pcf_time(&pcf_tm, &alrm->time); /* do like mktime does and ignore tm_wday */ pcf_tm.time[PCF50633_TI_WKDAY] = 7; alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM); /* disable alarm interrupt */ if (!alarm_masked) pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); /* Returns 0 on success */ ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA, PCF50633_TI_EXTENT, &pcf_tm.time[0]); if (!alrm->enabled) rtc->alarm_pending = 0; if (!alarm_masked || alrm->enabled) pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); rtc->alarm_enabled = alrm->enabled; return ret; }
static int pcf50633_resume(struct device *dev) { struct pcf50633 *pcf; int ret; pcf = dev_get_drvdata(dev); /* Write the saved mask registers */ ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(pcf->suspend_irq_masks), pcf->suspend_irq_masks); if (ret < 0) dev_err(pcf->dev, "Error restoring saved suspend masks\n"); /* Restore regulators' state */ get_device(pcf->dev); /* * Clear any pending interrupts and set resume reason if any. * This will leave with enable_irq() */ pcf50633_irq_worker(&pcf->irq_work); return 0; }
int pcf50633_irq_resume(struct pcf50633 *pcf) { int ret; /* Write the saved mask registers */ ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(pcf->suspend_irq_masks), pcf->suspend_irq_masks); if (ret < 0) dev_err(pcf->dev, "Error restoring saved suspend masks\n"); enable_irq(pcf->irq); return ret; }
static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct pcf50633_rtc *rtc; struct pcf50633_time pcf_tm; int second_masked, alarm_masked, ret = 0; rtc = dev_get_drvdata(dev); dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); rtc2pcf_time(&pcf_tm, tm); dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", pcf_tm.time[PCF50633_TI_DAY], pcf_tm.time[PCF50633_TI_MONTH], pcf_tm.time[PCF50633_TI_YEAR], pcf_tm.time[PCF50633_TI_HOUR], pcf_tm.time[PCF50633_TI_MIN], pcf_tm.time[PCF50633_TI_SEC]); second_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_SECOND); alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM); if (!second_masked) pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND); if (!alarm_masked) pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM); /* Returns 0 on success */ ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSC, PCF50633_TI_EXTENT, &pcf_tm.time[0]); if (!second_masked) pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND); if (!alarm_masked) pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM); return ret; }
static int pcf50633_suspend(struct device *dev, pm_message_t state) { struct pcf50633 *pcf; int ret = 0, i; u8 res[5]; pcf = dev_get_drvdata(dev); /* Make sure our interrupt handlers are not called * henceforth */ disable_irq(pcf->irq); /* Make sure that any running IRQ worker has quit */ cancel_work_sync(&pcf->irq_work); /* Save the masks */ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(pcf->suspend_irq_masks), pcf->suspend_irq_masks); if (ret < 0) { dev_err(pcf->dev, "error saving irq masks\n"); goto out; } /* Write wakeup irq masks */ for (i = 0; i < ARRAY_SIZE(res); i++) res[i] = ~pcf->pdata->resumers[i]; ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(res), &res[0]); if (ret < 0) { dev_err(pcf->dev, "error writing wakeup irq masks\n"); goto out; } pcf->is_suspended = 1; out: return ret; }