/* * Write a dryice register and wait until it completes. * * This function uses interrupts to determine when the * write has completed. */ static int di_write_wait(struct rtc_drv_data *pdata, u32 val, int reg) { int ret; int rc = 0; /* serialize register writes */ mutex_lock(&pdata->write_mutex); /* enable the write-complete interrupt */ di_int_enable(pdata, DIER_WCIE); pdata->dsr = 0; /* do the register write */ di_write(pdata, val, reg); /* wait for the write to finish */ ret = wait_event_interruptible_timeout(pdata->write_wait, pdata->dsr & (DSR_WCF | DSR_WEF), 1 * HZ); if (ret == 0) dev_warn(&pdata->pdev->dev, "Write-wait timeout\n"); /* check for write error */ if (pdata->dsr & DSR_WEF) { clear_write_error(pdata); rc = -EIO; } mutex_unlock(&pdata->write_mutex); return rc; }
/* * set the seconds portion of dryice alarm register */ static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct rtc_drv_data *pdata = dev_get_drvdata(dev); unsigned long now; unsigned long alarm_time; int rc; dev_dbg(dev, "%s\n", __func__); rc = rtc_tm_to_time(&alarm->time, &alarm_time); if (rc) return rc; /* don't allow setting alarm in the past */ now = di_read(pdata, DTCMR); if (alarm_time < now) return -EINVAL; /* write the new alarm time */ di_write_wait_err(pdata, (u32)alarm_time, DCAMR, rc, err); if (alarm->enabled) di_int_enable(pdata, DIER_CAIE); /* enable alarm intr */ else di_int_disable(pdata, DIER_CAIE); /* disable alarm intr */ err: return rc; }
/* * set the seconds portion of dryice alarm register */ static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct imxdi_dev *imxdi = dev_get_drvdata(dev); unsigned long now; unsigned long alarm_time; int rc; rc = rtc_tm_to_time(&alarm->time, &alarm_time); if (rc) return rc; /* don't allow setting alarm in the past */ now = __raw_readl(imxdi->ioaddr + DTCMR); if (alarm_time < now) return -EINVAL; /* write the new alarm time */ rc = di_write_wait(imxdi, (u32)alarm_time, DCAMR); if (rc) return rc; if (alarm->enabled) di_int_enable(imxdi, DIER_CAIE); /* enable alarm intr */ else di_int_disable(imxdi, DIER_CAIE); /* disable alarm intr */ return 0; }
static int dryice_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct imxdi_dev *imxdi = dev_get_drvdata(dev); if (enabled) di_int_enable(imxdi, DIER_CAIE); else di_int_disable(imxdi, DIER_CAIE); return 0; }
/* * rtc device ioctl * * The rtc framework handles the basic rtc ioctls on behalf * of the driver by calling the functions registered in the * rtc_ops structure. */ static int dryice_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct rtc_drv_data *pdata = dev_get_drvdata(dev); dev_dbg(dev, "%s(0x%x)\n", __func__, cmd); switch (cmd) { case RTC_AIE_OFF: /* alarm disable */ di_int_disable(pdata, DIER_CAIE); return 0; case RTC_AIE_ON: /* alarm enable */ di_int_enable(pdata, DIER_CAIE); return 0; } return -ENOIOCTLCMD; }
/* * Write a dryice register and wait until it completes. * * This function uses interrupts to determine when the * write has completed. */ static int di_write_wait(struct imxdi_dev *imxdi, u32 val, int reg) { int ret; int rc = 0; /* serialize register writes */ mutex_lock(&imxdi->write_mutex); /* enable the write-complete interrupt */ di_int_enable(imxdi, DIER_WCIE); imxdi->dsr = 0; /* do the register write */ __raw_writel(val, imxdi->ioaddr + reg); /* wait for the write to finish */ ret = wait_event_interruptible_timeout(imxdi->write_wait, imxdi->dsr & (DSR_WCF | DSR_WEF), msecs_to_jiffies(1)); if (ret < 0) { rc = ret; goto out; } else if (ret == 0) { dev_warn(&imxdi->pdev->dev, "Write-wait timeout " "val = 0x%08x reg = 0x%08x\n", val, reg); } /* check for write error */ if (imxdi->dsr & DSR_WEF) { clear_write_error(imxdi); rc = -EIO; } out: mutex_unlock(&imxdi->write_mutex); return rc; }
static int di_write_wait(struct imxdi_dev *imxdi, u32 val, int reg) { int ret; int rc = 0; mutex_lock(&imxdi->write_mutex); di_int_enable(imxdi, DIER_WCIE); imxdi->dsr = 0; __raw_writel(val, imxdi->ioaddr + reg); ret = wait_event_interruptible_timeout(imxdi->write_wait, imxdi->dsr & (DSR_WCF | DSR_WEF), msecs_to_jiffies(1)); if (ret < 0) { rc = ret; goto out; } else if (ret == 0) { dev_warn(&imxdi->pdev->dev, "Write-wait timeout " "val = 0x%08x reg = 0x%08x\n", val, reg); } if (imxdi->dsr & DSR_WEF) { clear_write_error(imxdi); rc = -EIO; } out: mutex_unlock(&imxdi->write_mutex); return rc; }