You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'timers-rtc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-rtc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: RTC: Fix up rtc.txt documentation to reflect changes to generic rtc layer RTC: sa1100: Update the sa1100 RTC driver. RTC: Fix the cross interrupt issue on rtc-test. RTC: Remove UIE and PIE information from the sa1100 driver proc. RTC: Include information about UIE and PIE in RTC driver proc. RTC: Clean out UIE icotl implementations RTC: Cleanup rtc_class_ops->update_irq_enable() RTC: Cleanup rtc_class_ops->irq_set_freq() RTC: Cleanup rtc_class_ops->irq_set_state RTC: Initialize kernel state from RTC
This commit is contained in:
+10
-19
@@ -178,38 +178,29 @@ RTC class framework, but can't be supported by the older driver.
|
||||
setting the longer alarm time and enabling its IRQ using a single
|
||||
request (using the same model as EFI firmware).
|
||||
|
||||
* RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, it probably
|
||||
also offers update IRQs whenever the "seconds" counter changes.
|
||||
If needed, the RTC framework can emulate this mechanism.
|
||||
* RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, the RTC framework
|
||||
will emulate this mechanism.
|
||||
|
||||
* RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... another
|
||||
feature often accessible with an IRQ line is a periodic IRQ, issued
|
||||
at settable frequencies (usually 2^N Hz).
|
||||
* RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... these icotls
|
||||
are emulated via a kernel hrtimer.
|
||||
|
||||
In many cases, the RTC alarm can be a system wake event, used to force
|
||||
Linux out of a low power sleep state (or hibernation) back to a fully
|
||||
operational state. For example, a system could enter a deep power saving
|
||||
state until it's time to execute some scheduled tasks.
|
||||
|
||||
Note that many of these ioctls need not actually be implemented by your
|
||||
driver. The common rtc-dev interface handles many of these nicely if your
|
||||
driver returns ENOIOCTLCMD. Some common examples:
|
||||
Note that many of these ioctls are handled by the common rtc-dev interface.
|
||||
Some common examples:
|
||||
|
||||
* RTC_RD_TIME, RTC_SET_TIME: the read_time/set_time functions will be
|
||||
called with appropriate values.
|
||||
|
||||
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: the
|
||||
set_alarm/read_alarm functions will be called.
|
||||
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: gets or sets
|
||||
the alarm rtc_timer. May call the set_alarm driver function.
|
||||
|
||||
* RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called
|
||||
to set the frequency while the framework will handle the read for you
|
||||
since the frequency is stored in the irq_freq member of the rtc_device
|
||||
structure. Your driver needs to initialize the irq_freq member during
|
||||
init. Make sure you check the requested frequency is in range of your
|
||||
hardware in the irq_set_freq function. If it isn't, return -EINVAL. If
|
||||
you cannot actually change the frequency, do not define irq_set_freq.
|
||||
* RTC_IRQP_SET, RTC_IRQP_READ: These are emulated by the generic code.
|
||||
|
||||
* RTC_PIE_ON, RTC_PIE_OFF: the irq_set_state function will be called.
|
||||
* RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code.
|
||||
|
||||
If all else fails, check out the rtc-test.c driver!
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
|
||||
struct module *owner)
|
||||
{
|
||||
struct rtc_device *rtc;
|
||||
struct rtc_wkalrm alrm;
|
||||
int id, err;
|
||||
|
||||
if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) {
|
||||
@@ -166,6 +167,12 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
|
||||
rtc->pie_timer.function = rtc_pie_update_irq;
|
||||
rtc->pie_enabled = 0;
|
||||
|
||||
/* Check to see if there is an ALARM already set in hw */
|
||||
err = __rtc_read_alarm(rtc, &alrm);
|
||||
|
||||
if (!err && !rtc_valid_tm(&alrm.time))
|
||||
rtc_set_alarm(rtc, &alrm);
|
||||
|
||||
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
|
||||
dev_set_name(&rtc->dev, "rtc%d", id);
|
||||
|
||||
|
||||
@@ -116,6 +116,186 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtc_set_mmss);
|
||||
|
||||
static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mutex_lock_interruptible(&rtc->ops_lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (rtc->ops == NULL)
|
||||
err = -ENODEV;
|
||||
else if (!rtc->ops->read_alarm)
|
||||
err = -EINVAL;
|
||||
else {
|
||||
memset(alarm, 0, sizeof(struct rtc_wkalrm));
|
||||
err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
|
||||
}
|
||||
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
int err;
|
||||
struct rtc_time before, now;
|
||||
int first_time = 1;
|
||||
unsigned long t_now, t_alm;
|
||||
enum { none, day, month, year } missing = none;
|
||||
unsigned days;
|
||||
|
||||
/* The lower level RTC driver may return -1 in some fields,
|
||||
* creating invalid alarm->time values, for reasons like:
|
||||
*
|
||||
* - The hardware may not be capable of filling them in;
|
||||
* many alarms match only on time-of-day fields, not
|
||||
* day/month/year calendar data.
|
||||
*
|
||||
* - Some hardware uses illegal values as "wildcard" match
|
||||
* values, which non-Linux firmware (like a BIOS) may try
|
||||
* to set up as e.g. "alarm 15 minutes after each hour".
|
||||
* Linux uses only oneshot alarms.
|
||||
*
|
||||
* When we see that here, we deal with it by using values from
|
||||
* a current RTC timestamp for any missing (-1) values. The
|
||||
* RTC driver prevents "periodic alarm" modes.
|
||||
*
|
||||
* But this can be racey, because some fields of the RTC timestamp
|
||||
* may have wrapped in the interval since we read the RTC alarm,
|
||||
* which would lead to us inserting inconsistent values in place
|
||||
* of the -1 fields.
|
||||
*
|
||||
* Reading the alarm and timestamp in the reverse sequence
|
||||
* would have the same race condition, and not solve the issue.
|
||||
*
|
||||
* So, we must first read the RTC timestamp,
|
||||
* then read the RTC alarm value,
|
||||
* and then read a second RTC timestamp.
|
||||
*
|
||||
* If any fields of the second timestamp have changed
|
||||
* when compared with the first timestamp, then we know
|
||||
* our timestamp may be inconsistent with that used by
|
||||
* the low-level rtc_read_alarm_internal() function.
|
||||
*
|
||||
* So, when the two timestamps disagree, we just loop and do
|
||||
* the process again to get a fully consistent set of values.
|
||||
*
|
||||
* This could all instead be done in the lower level driver,
|
||||
* but since more than one lower level RTC implementation needs it,
|
||||
* then it's probably best best to do it here instead of there..
|
||||
*/
|
||||
|
||||
/* Get the "before" timestamp */
|
||||
err = rtc_read_time(rtc, &before);
|
||||
if (err < 0)
|
||||
return err;
|
||||
do {
|
||||
if (!first_time)
|
||||
memcpy(&before, &now, sizeof(struct rtc_time));
|
||||
first_time = 0;
|
||||
|
||||
/* get the RTC alarm values, which may be incomplete */
|
||||
err = rtc_read_alarm_internal(rtc, alarm);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* full-function RTCs won't have such missing fields */
|
||||
if (rtc_valid_tm(&alarm->time) == 0)
|
||||
return 0;
|
||||
|
||||
/* get the "after" timestamp, to detect wrapped fields */
|
||||
err = rtc_read_time(rtc, &now);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* note that tm_sec is a "don't care" value here: */
|
||||
} while ( before.tm_min != now.tm_min
|
||||
|| before.tm_hour != now.tm_hour
|
||||
|| before.tm_mon != now.tm_mon
|
||||
|| before.tm_year != now.tm_year);
|
||||
|
||||
/* Fill in the missing alarm fields using the timestamp; we
|
||||
* know there's at least one since alarm->time is invalid.
|
||||
*/
|
||||
if (alarm->time.tm_sec == -1)
|
||||
alarm->time.tm_sec = now.tm_sec;
|
||||
if (alarm->time.tm_min == -1)
|
||||
alarm->time.tm_min = now.tm_min;
|
||||
if (alarm->time.tm_hour == -1)
|
||||
alarm->time.tm_hour = now.tm_hour;
|
||||
|
||||
/* For simplicity, only support date rollover for now */
|
||||
if (alarm->time.tm_mday == -1) {
|
||||
alarm->time.tm_mday = now.tm_mday;
|
||||
missing = day;
|
||||
}
|
||||
if (alarm->time.tm_mon == -1) {
|
||||
alarm->time.tm_mon = now.tm_mon;
|
||||
if (missing == none)
|
||||
missing = month;
|
||||
}
|
||||
if (alarm->time.tm_year == -1) {
|
||||
alarm->time.tm_year = now.tm_year;
|
||||
if (missing == none)
|
||||
missing = year;
|
||||
}
|
||||
|
||||
/* with luck, no rollover is needed */
|
||||
rtc_tm_to_time(&now, &t_now);
|
||||
rtc_tm_to_time(&alarm->time, &t_alm);
|
||||
if (t_now < t_alm)
|
||||
goto done;
|
||||
|
||||
switch (missing) {
|
||||
|
||||
/* 24 hour rollover ... if it's now 10am Monday, an alarm that
|
||||
* that will trigger at 5am will do so at 5am Tuesday, which
|
||||
* could also be in the next month or year. This is a common
|
||||
* case, especially for PCs.
|
||||
*/
|
||||
case day:
|
||||
dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day");
|
||||
t_alm += 24 * 60 * 60;
|
||||
rtc_time_to_tm(t_alm, &alarm->time);
|
||||
break;
|
||||
|
||||
/* Month rollover ... if it's the 31th, an alarm on the 3rd will
|
||||
* be next month. An alarm matching on the 30th, 29th, or 28th
|
||||
* may end up in the month after that! Many newer PCs support
|
||||
* this type of alarm.
|
||||
*/
|
||||
case month:
|
||||
dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month");
|
||||
do {
|
||||
if (alarm->time.tm_mon < 11)
|
||||
alarm->time.tm_mon++;
|
||||
else {
|
||||
alarm->time.tm_mon = 0;
|
||||
alarm->time.tm_year++;
|
||||
}
|
||||
days = rtc_month_days(alarm->time.tm_mon,
|
||||
alarm->time.tm_year);
|
||||
} while (days < alarm->time.tm_mday);
|
||||
break;
|
||||
|
||||
/* Year rollover ... easy except for leap years! */
|
||||
case year:
|
||||
dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year");
|
||||
do {
|
||||
alarm->time.tm_year++;
|
||||
} while (rtc_valid_tm(&alarm->time) != 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_warn(&rtc->dev, "alarm rollover not handled\n");
|
||||
}
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -183,33 +183,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle commands from user-space
|
||||
*/
|
||||
static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg);
|
||||
|
||||
/* important: scrub old status before enabling IRQs */
|
||||
switch (cmd) {
|
||||
case RTC_UIE_OFF: /* update off */
|
||||
at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
|
||||
break;
|
||||
case RTC_UIE_ON: /* update on */
|
||||
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV);
|
||||
at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
pr_debug("%s(): cmd=%08x\n", __func__, enabled);
|
||||
@@ -269,7 +242,6 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops at91_rtc_ops = {
|
||||
.ioctl = at91_rtc_ioctl,
|
||||
.read_time = at91_rtc_readtime,
|
||||
.set_time = at91_rtc_settime,
|
||||
.read_alarm = at91_rtc_readalarm,
|
||||
|
||||
@@ -216,33 +216,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle commands from user-space
|
||||
*/
|
||||
static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct sam9_rtc *rtc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
u32 mr = rtt_readl(rtc, MR);
|
||||
|
||||
dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr);
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_UIE_OFF: /* update off */
|
||||
rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
|
||||
break;
|
||||
case RTC_UIE_ON: /* update on */
|
||||
rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct sam9_rtc *rtc = dev_get_drvdata(dev);
|
||||
@@ -303,7 +276,6 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc)
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops at91_rtc_ops = {
|
||||
.ioctl = at91_rtc_ioctl,
|
||||
.read_time = at91_rtc_readtime,
|
||||
.set_time = at91_rtc_settime,
|
||||
.read_alarm = at91_rtc_readalarm,
|
||||
|
||||
@@ -240,32 +240,6 @@ static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc)
|
||||
*/
|
||||
bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY);
|
||||
}
|
||||
static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct bfin_rtc *rtc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg_stamp(dev);
|
||||
|
||||
bfin_rtc_sync_pending(dev);
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_UIE_ON:
|
||||
dev_dbg_stamp(dev);
|
||||
bfin_rtc_int_set(RTC_ISTAT_SEC);
|
||||
break;
|
||||
case RTC_UIE_OFF:
|
||||
dev_dbg_stamp(dev);
|
||||
bfin_rtc_int_clear(~RTC_ISTAT_SEC);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_dbg_stamp(dev);
|
||||
ret = -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
@@ -358,7 +332,6 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
|
||||
}
|
||||
|
||||
static struct rtc_class_ops bfin_rtc_ops = {
|
||||
.ioctl = bfin_rtc_ioctl,
|
||||
.read_time = bfin_rtc_read_time,
|
||||
.set_time = bfin_rtc_set_time,
|
||||
.read_alarm = bfin_rtc_read_alarm,
|
||||
|
||||
@@ -375,50 +375,6 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmos_irq_set_freq(struct device *dev, int freq)
|
||||
{
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
int f;
|
||||
unsigned long flags;
|
||||
|
||||
if (!is_valid_irq(cmos->irq))
|
||||
return -ENXIO;
|
||||
|
||||
if (!is_power_of_2(freq))
|
||||
return -EINVAL;
|
||||
/* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
|
||||
f = ffs(freq);
|
||||
if (f-- > 16)
|
||||
return -EINVAL;
|
||||
f = 16 - f;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
hpet_set_periodic_freq(freq);
|
||||
CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmos_irq_set_state(struct device *dev, int enabled)
|
||||
{
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (!is_valid_irq(cmos->irq))
|
||||
return -ENXIO;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
|
||||
if (enabled)
|
||||
cmos_irq_enable(cmos, RTC_PIE);
|
||||
else
|
||||
cmos_irq_disable(cmos, RTC_PIE);
|
||||
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
@@ -438,25 +394,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmos_update_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct cmos_rtc *cmos = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (!is_valid_irq(cmos->irq))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
|
||||
if (enabled)
|
||||
cmos_irq_enable(cmos, RTC_UIE);
|
||||
else
|
||||
cmos_irq_disable(cmos, RTC_UIE);
|
||||
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
|
||||
|
||||
static int cmos_procfs(struct device *dev, struct seq_file *seq)
|
||||
@@ -501,10 +438,7 @@ static const struct rtc_class_ops cmos_rtc_ops = {
|
||||
.read_alarm = cmos_read_alarm,
|
||||
.set_alarm = cmos_set_alarm,
|
||||
.proc = cmos_procfs,
|
||||
.irq_set_freq = cmos_irq_set_freq,
|
||||
.irq_set_state = cmos_irq_set_state,
|
||||
.alarm_irq_enable = cmos_alarm_irq_enable,
|
||||
.update_irq_enable = cmos_update_irq_enable,
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
@@ -231,10 +231,6 @@ davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
case RTC_WIE_OFF:
|
||||
rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
|
||||
break;
|
||||
case RTC_UIE_OFF:
|
||||
case RTC_UIE_ON:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
}
|
||||
@@ -473,55 +469,6 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_rtc_irq_set_state(struct device *dev, int enabled)
|
||||
{
|
||||
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
u8 rtc_ctrl;
|
||||
|
||||
spin_lock_irqsave(&davinci_rtc_lock, flags);
|
||||
|
||||
rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
|
||||
|
||||
if (enabled) {
|
||||
while (rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL)
|
||||
& PRTCSS_RTC_CTRL_WDTBUS)
|
||||
cpu_relax();
|
||||
|
||||
rtc_ctrl |= PRTCSS_RTC_CTRL_TE;
|
||||
rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
|
||||
|
||||
rtcss_write(davinci_rtc, 0x0, PRTCSS_RTC_CLKC_CNT);
|
||||
|
||||
rtc_ctrl |= PRTCSS_RTC_CTRL_TIEN |
|
||||
PRTCSS_RTC_CTRL_TMMD |
|
||||
PRTCSS_RTC_CTRL_TMRFLG;
|
||||
} else
|
||||
rtc_ctrl &= ~PRTCSS_RTC_CTRL_TIEN;
|
||||
|
||||
rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
|
||||
|
||||
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_rtc_irq_set_freq(struct device *dev, int freq)
|
||||
{
|
||||
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
u16 tmr_counter = (0x8000 >> (ffs(freq) - 1));
|
||||
|
||||
spin_lock_irqsave(&davinci_rtc_lock, flags);
|
||||
|
||||
rtcss_write(davinci_rtc, tmr_counter & 0xFF, PRTCSS_RTC_TMR0);
|
||||
rtcss_write(davinci_rtc, (tmr_counter & 0xFF00) >> 8, PRTCSS_RTC_TMR1);
|
||||
|
||||
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rtc_class_ops davinci_rtc_ops = {
|
||||
.ioctl = davinci_rtc_ioctl,
|
||||
.read_time = davinci_rtc_read_time,
|
||||
@@ -529,8 +476,6 @@ static struct rtc_class_ops davinci_rtc_ops = {
|
||||
.alarm_irq_enable = davinci_rtc_alarm_irq_enable,
|
||||
.read_alarm = davinci_rtc_read_alarm,
|
||||
.set_alarm = davinci_rtc_set_alarm,
|
||||
.irq_set_state = davinci_rtc_irq_set_state,
|
||||
.irq_set_freq = davinci_rtc_irq_set_freq,
|
||||
};
|
||||
|
||||
static int __init davinci_rtc_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -397,29 +397,12 @@ static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds1511_rtc_update_irq_enable(struct device *dev,
|
||||
unsigned int enabled)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
|
||||
|
||||
if (pdata->irq <= 0)
|
||||
return -EINVAL;
|
||||
if (enabled)
|
||||
pdata->irqen |= RTC_UF;
|
||||
else
|
||||
pdata->irqen &= ~RTC_UF;
|
||||
ds1511_rtc_update_alarm(pdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops ds1511_rtc_ops = {
|
||||
.read_time = ds1511_rtc_read_time,
|
||||
.set_time = ds1511_rtc_set_time,
|
||||
.read_alarm = ds1511_rtc_read_alarm,
|
||||
.set_alarm = ds1511_rtc_set_alarm,
|
||||
.alarm_irq_enable = ds1511_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = ds1511_rtc_update_irq_enable,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
|
||||
@@ -227,29 +227,12 @@ static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds1553_rtc_update_irq_enable(struct device *dev,
|
||||
unsigned int enabled)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
|
||||
|
||||
if (pdata->irq <= 0)
|
||||
return -EINVAL;
|
||||
if (enabled)
|
||||
pdata->irqen |= RTC_UF;
|
||||
else
|
||||
pdata->irqen &= ~RTC_UF;
|
||||
ds1553_rtc_update_alarm(pdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops ds1553_rtc_ops = {
|
||||
.read_time = ds1553_rtc_read_time,
|
||||
.set_time = ds1553_rtc_set_time,
|
||||
.read_alarm = ds1553_rtc_read_alarm,
|
||||
.set_alarm = ds1553_rtc_set_alarm,
|
||||
.alarm_irq_enable = ds1553_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = ds1553_rtc_update_irq_enable,
|
||||
};
|
||||
|
||||
static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj,
|
||||
|
||||
@@ -339,23 +339,6 @@ static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds3232_update_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct ds3232 *ds3232 = i2c_get_clientdata(client);
|
||||
|
||||
if (client->irq <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (enabled)
|
||||
ds3232->rtc->irq_data |= RTC_UF;
|
||||
else
|
||||
ds3232->rtc->irq_data &= ~RTC_UF;
|
||||
|
||||
ds3232_update_alarm(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t ds3232_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct i2c_client *client = dev_id;
|
||||
@@ -406,7 +389,6 @@ static const struct rtc_class_ops ds3232_rtc_ops = {
|
||||
.read_alarm = ds3232_read_alarm,
|
||||
.set_alarm = ds3232_set_alarm,
|
||||
.alarm_irq_enable = ds3232_alarm_irq_enable,
|
||||
.update_irq_enable = ds3232_update_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit ds3232_probe(struct i2c_client *client,
|
||||
|
||||
@@ -168,12 +168,6 @@ static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enable)
|
||||
{
|
||||
struct jz4740_rtc *rtc = dev_get_drvdata(dev);
|
||||
return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, enable);
|
||||
}
|
||||
|
||||
static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
|
||||
{
|
||||
struct jz4740_rtc *rtc = dev_get_drvdata(dev);
|
||||
@@ -185,7 +179,6 @@ static struct rtc_class_ops jz4740_rtc_ops = {
|
||||
.set_mmss = jz4740_rtc_set_mmss,
|
||||
.read_alarm = jz4740_rtc_read_alarm,
|
||||
.set_alarm = jz4740_rtc_set_alarm,
|
||||
.update_irq_enable = jz4740_rtc_update_irq_enable,
|
||||
.alarm_irq_enable = jz4740_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
|
||||
@@ -282,12 +282,6 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mc13xxx_rtc_update_irq_enable(struct device *dev,
|
||||
unsigned int enabled)
|
||||
{
|
||||
return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_1HZ);
|
||||
}
|
||||
|
||||
static int mc13xxx_rtc_alarm_irq_enable(struct device *dev,
|
||||
unsigned int enabled)
|
||||
{
|
||||
@@ -300,7 +294,6 @@ static const struct rtc_class_ops mc13xxx_rtc_ops = {
|
||||
.read_alarm = mc13xxx_rtc_read_alarm,
|
||||
.set_alarm = mc13xxx_rtc_set_alarm,
|
||||
.alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = mc13xxx_rtc_update_irq_enable,
|
||||
};
|
||||
|
||||
static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev)
|
||||
|
||||
@@ -240,32 +240,12 @@ static int mpc5121_rtc_alarm_irq_enable(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc5121_rtc_update_irq_enable(struct device *dev,
|
||||
unsigned int enabled)
|
||||
{
|
||||
struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
|
||||
struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
|
||||
int val;
|
||||
|
||||
val = in_8(®s->int_enable);
|
||||
|
||||
if (enabled)
|
||||
val = (val & ~0x8) | 0x1;
|
||||
else
|
||||
val &= ~0x1;
|
||||
|
||||
out_8(®s->int_enable, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops mpc5121_rtc_ops = {
|
||||
.read_time = mpc5121_rtc_read_time,
|
||||
.set_time = mpc5121_rtc_set_time,
|
||||
.read_alarm = mpc5121_rtc_read_alarm,
|
||||
.set_alarm = mpc5121_rtc_set_alarm,
|
||||
.alarm_irq_enable = mpc5121_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = mpc5121_rtc_update_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit mpc5121_rtc_probe(struct platform_device *op,
|
||||
|
||||
@@ -236,25 +236,6 @@ static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mrst_irq_set_state(struct device *dev, int enabled)
|
||||
{
|
||||
struct mrst_rtc *mrst = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (!mrst->irq)
|
||||
return -ENXIO;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
|
||||
if (enabled)
|
||||
mrst_irq_enable(mrst, RTC_PIE);
|
||||
else
|
||||
mrst_irq_disable(mrst, RTC_PIE);
|
||||
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Currently, the vRTC doesn't support UIE ON/OFF */
|
||||
static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
@@ -301,7 +282,6 @@ static const struct rtc_class_ops mrst_rtc_ops = {
|
||||
.read_alarm = mrst_read_alarm,
|
||||
.set_alarm = mrst_set_alarm,
|
||||
.proc = mrst_procfs,
|
||||
.irq_set_state = mrst_irq_set_state,
|
||||
.alarm_irq_enable = mrst_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
|
||||
@@ -274,12 +274,6 @@ static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_rtc_update_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
mxc_rtc_irq_enable(dev, RTC_1HZ_BIT, enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reads the current RTC time into tm in Gregorian date.
|
||||
*/
|
||||
@@ -368,7 +362,6 @@ static struct rtc_class_ops mxc_rtc_ops = {
|
||||
.read_alarm = mxc_rtc_read_alarm,
|
||||
.set_alarm = mxc_rtc_set_alarm,
|
||||
.alarm_irq_enable = mxc_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = mxc_rtc_update_irq_enable,
|
||||
};
|
||||
|
||||
static int __init mxc_rtc_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -134,20 +134,6 @@ static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm,
|
||||
gettm->bcd_hour = bin2bcd(settm->tm_hour) << 16;
|
||||
}
|
||||
|
||||
static int nuc900_update_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct nuc900_rtc *rtc = dev_get_drvdata(dev);
|
||||
|
||||
if (enabled)
|
||||
__raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)|
|
||||
(TICKINTENB), rtc->rtc_reg + REG_RTC_RIER);
|
||||
else
|
||||
__raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)&
|
||||
(~TICKINTENB), rtc->rtc_reg + REG_RTC_RIER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nuc900_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct nuc900_rtc *rtc = dev_get_drvdata(dev);
|
||||
@@ -234,7 +220,6 @@ static struct rtc_class_ops nuc900_rtc_ops = {
|
||||
.read_alarm = nuc900_rtc_read_alarm,
|
||||
.set_alarm = nuc900_rtc_set_alarm,
|
||||
.alarm_irq_enable = nuc900_alarm_irq_enable,
|
||||
.update_irq_enable = nuc900_update_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -135,44 +135,6 @@ static irqreturn_t rtc_irq(int irq, void *rtc)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_DEV
|
||||
|
||||
static int
|
||||
omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
switch (cmd) {
|
||||
case RTC_UIE_OFF:
|
||||
case RTC_UIE_ON:
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
local_irq_disable();
|
||||
rtc_wait_not_busy();
|
||||
reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
|
||||
switch (cmd) {
|
||||
/* UIE = Update Interrupt Enable (1/second) */
|
||||
case RTC_UIE_OFF:
|
||||
reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER;
|
||||
break;
|
||||
case RTC_UIE_ON:
|
||||
reg |= OMAP_RTC_INTERRUPTS_IT_TIMER;
|
||||
break;
|
||||
}
|
||||
rtc_wait_not_busy();
|
||||
rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
|
||||
local_irq_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define omap_rtc_ioctl NULL
|
||||
#endif
|
||||
|
||||
static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
u8 reg;
|
||||
@@ -313,7 +275,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
|
||||
}
|
||||
|
||||
static struct rtc_class_ops omap_rtc_ops = {
|
||||
.ioctl = omap_rtc_ioctl,
|
||||
.read_time = omap_rtc_read_time,
|
||||
.set_time = omap_rtc_set_time,
|
||||
.read_alarm = omap_rtc_read_alarm,
|
||||
|
||||
@@ -131,18 +131,12 @@ static int pcap_rtc_alarm_irq_enable(struct device *dev, unsigned int en)
|
||||
return pcap_rtc_irq_enable(dev, PCAP_IRQ_TODA, en);
|
||||
}
|
||||
|
||||
static int pcap_rtc_update_irq_enable(struct device *dev, unsigned int en)
|
||||
{
|
||||
return pcap_rtc_irq_enable(dev, PCAP_IRQ_1HZ, en);
|
||||
}
|
||||
|
||||
static const struct rtc_class_ops pcap_rtc_ops = {
|
||||
.read_time = pcap_rtc_read_time,
|
||||
.read_alarm = pcap_rtc_read_alarm,
|
||||
.set_alarm = pcap_rtc_set_alarm,
|
||||
.set_mmss = pcap_rtc_set_mmss,
|
||||
.alarm_irq_enable = pcap_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = pcap_rtc_update_irq_enable,
|
||||
};
|
||||
|
||||
static int __devinit pcap_rtc_probe(struct platform_device *pdev)
|
||||
|
||||
@@ -106,25 +106,6 @@ pcf50633_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pcf50633_rtc_update_irq_enable(struct device *dev, unsigned int enabled)
|
||||
{
|
||||
struct pcf50633_rtc *rtc = dev_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
if (enabled)
|
||||
err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND);
|
||||
else
|
||||
err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
rtc->second_enabled = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct pcf50633_rtc *rtc;
|
||||
@@ -262,8 +243,7 @@ static struct rtc_class_ops pcf50633_rtc_ops = {
|
||||
.set_time = pcf50633_rtc_set_time,
|
||||
.read_alarm = pcf50633_rtc_read_alarm,
|
||||
.set_alarm = pcf50633_rtc_set_alarm,
|
||||
.alarm_irq_enable = pcf50633_rtc_alarm_irq_enable,
|
||||
.update_irq_enable = pcf50633_rtc_update_irq_enable,
|
||||
.alarm_irq_enable = pcf50633_rtc_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static void pcf50633_rtc_irq(int irq, void *data)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user