Skip to content

Commit

Permalink
RTC: Convert rtc drivers to use the alarm_irq_enable method
Browse files Browse the repository at this point in the history
Some rtc drivers use the ioctl method instead of the alarm_irq_enable
method for enabling alarm interupts. With the new virtualized RTC
rework, its important for drivers to use the alarm_irq_enable instead.

This patch converts the drivers that use the AIE ioctl method to
use the alarm_irq_enable method. Other ioctl cmds are left untouched.

I have not been able to test or even compile most of these drivers.
Any help to make sure this change is correct would be appreciated!

CC: Alessandro Zummo <a.zummo@towertech.it>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
Reported-by: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
Tested-by: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
Signed-off-by: John Stultz <john.stultz@linaro.org>
  • Loading branch information
John Stultz committed Feb 3, 2011
1 parent ac54cd2 commit 16380c1
Show file tree
Hide file tree
Showing 18 changed files with 223 additions and 297 deletions.
19 changes: 6 additions & 13 deletions drivers/rtc/rtc-at32ap700x.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,36 +134,29 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}

static int at32_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
int ret = 0;

spin_lock_irq(&rtc->lock);

switch (cmd) {
case RTC_AIE_ON:
if(enabled) {
if (rtc_readl(rtc, VAL) > rtc->alarm_time) {
ret = -EINVAL;
break;
goto out;
}
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
| RTC_BIT(CTRL_TOPEN));
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
rtc_writel(rtc, IER, RTC_BIT(IER_TOPI));
break;
case RTC_AIE_OFF:
} else {
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
& ~RTC_BIT(CTRL_TOPEN));
rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI));
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
break;
default:
ret = -ENOIOCTLCMD;
break;
}

out:
spin_unlock_irq(&rtc->lock);

return ret;
Expand Down Expand Up @@ -195,11 +188,11 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
}

static struct rtc_class_ops at32_rtc_ops = {
.ioctl = at32_rtc_ioctl,
.read_time = at32_rtc_readtime,
.set_time = at32_rtc_settime,
.read_alarm = at32_rtc_readalarm,
.set_alarm = at32_rtc_setalarm,
.alarm_irq_enable = at32_rtc_alarm_irq_enable,
};

static int __init at32_rtc_probe(struct platform_device *pdev)
Expand Down
20 changes: 13 additions & 7 deletions drivers/rtc/rtc-at91rm9200.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,

/* important: scrub old status before enabling IRQs */
switch (cmd) {
case RTC_AIE_OFF: /* alarm off */
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
break;
case RTC_AIE_ON: /* alarm on */
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
break;
case RTC_UIE_OFF: /* update off */
at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
break;
Expand All @@ -217,6 +210,18 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
return ret;
}

static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
pr_debug("%s(): cmd=%08x\n", __func__, enabled);

if (enabled) {
at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
} else
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);

return 0;
}
/*
* Provide additional RTC information in /proc/driver/rtc
*/
Expand Down Expand Up @@ -270,6 +275,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
.read_alarm = at91_rtc_readalarm,
.set_alarm = at91_rtc_setalarm,
.proc = at91_rtc_proc,
.alarm_irq_enable = at91_rtc_alarm_irq_enable,
};

/*
Expand Down
20 changes: 14 additions & 6 deletions drivers/rtc/rtc-at91sam9.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr);

switch (cmd) {
case RTC_AIE_OFF: /* alarm off */
rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
break;
case RTC_AIE_ON: /* alarm on */
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
break;
case RTC_UIE_OFF: /* update off */
rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN);
break;
Expand All @@ -249,6 +243,19 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
return ret;
}

static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct sam9_rtc *rtc = dev_get_drvdata(dev);
u32 mr = rtt_readl(rtc, MR);

dev_dbg(dev, "alarm_irq_enable: enabled=%08x, mr %08x\n", enabled, mr);
if (enabled)
rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN);
else
rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN);
return 0;
}

/*
* Provide additional RTC information in /proc/driver/rtc
*/
Expand Down Expand Up @@ -302,6 +309,7 @@ static const struct rtc_class_ops at91_rtc_ops = {
.read_alarm = at91_rtc_readalarm,
.set_alarm = at91_rtc_setalarm,
.proc = at91_rtc_proc,
.alarm_irq_enabled = at91_rtc_alarm_irq_enable,
};

/*
Expand Down
21 changes: 12 additions & 9 deletions drivers/rtc/rtc-bfin.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,6 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar
bfin_rtc_int_clear(~RTC_ISTAT_SEC);
break;

case RTC_AIE_ON:
dev_dbg_stamp(dev);
bfin_rtc_int_set_alarm(rtc);
break;
case RTC_AIE_OFF:
dev_dbg_stamp(dev);
bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
break;

default:
dev_dbg_stamp(dev);
ret = -ENOIOCTLCMD;
Expand All @@ -276,6 +267,17 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar
return ret;
}

static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct bfin_rtc *rtc = dev_get_drvdata(dev);

dev_dbg_stamp(dev);
if (enabled)
bfin_rtc_int_set_alarm(rtc);
else
bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
}

static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct bfin_rtc *rtc = dev_get_drvdata(dev);
Expand Down Expand Up @@ -362,6 +364,7 @@ static struct rtc_class_ops bfin_rtc_ops = {
.read_alarm = bfin_rtc_read_alarm,
.set_alarm = bfin_rtc_set_alarm,
.proc = bfin_rtc_proc,
.alarm_irq_enable = bfin_rtc_alarm_irq_enable,
};

static int __devinit bfin_rtc_probe(struct platform_device *pdev)
Expand Down
41 changes: 23 additions & 18 deletions drivers/rtc/rtc-ds1286.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg)
__raw_writel(data, &priv->rtcregs[reg]);
}


static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct ds1286_priv *priv = dev_get_drvdata(dev);
unsigned long flags;
unsigned char val;

/* Allow or mask alarm interrupts */
spin_lock_irqsave(&priv->lock, flags);
val = ds1286_rtc_read(priv, RTC_CMD);
if (enabled)
val &= ~RTC_TDM;
else
val |= RTC_TDM;
ds1286_rtc_write(priv, val, RTC_CMD);
spin_unlock_irqrestore(&priv->lock, flags);

return 0;
}

#ifdef CONFIG_RTC_INTF_DEV

static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
Expand All @@ -49,22 +69,6 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
unsigned char val;

switch (cmd) {
case RTC_AIE_OFF:
/* Mask alarm int. enab. bit */
spin_lock_irqsave(&priv->lock, flags);
val = ds1286_rtc_read(priv, RTC_CMD);
val |= RTC_TDM;
ds1286_rtc_write(priv, val, RTC_CMD);
spin_unlock_irqrestore(&priv->lock, flags);
break;
case RTC_AIE_ON:
/* Allow alarm interrupts. */
spin_lock_irqsave(&priv->lock, flags);
val = ds1286_rtc_read(priv, RTC_CMD);
val &= ~RTC_TDM;
ds1286_rtc_write(priv, val, RTC_CMD);
spin_unlock_irqrestore(&priv->lock, flags);
break;
case RTC_WIE_OFF:
/* Mask watchdog int. enab. bit */
spin_lock_irqsave(&priv->lock, flags);
Expand Down Expand Up @@ -316,12 +320,13 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
}

static const struct rtc_class_ops ds1286_ops = {
.ioctl = ds1286_ioctl,
.proc = ds1286_proc,
.ioctl = ds1286_ioctl,
.proc = ds1286_proc,
.read_time = ds1286_read_time,
.set_time = ds1286_set_time,
.read_alarm = ds1286_read_alarm,
.set_alarm = ds1286_set_alarm,
.alarm_irq_enable = ds1286_alarm_irq_enable,
};

static int __devinit ds1286_probe(struct platform_device *pdev)
Expand Down
43 changes: 13 additions & 30 deletions drivers/rtc/rtc-ds1305.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,49 +139,32 @@ static u8 hour2bcd(bool hr12, int hour)
* Interface to RTC framework
*/

#ifdef CONFIG_RTC_INTF_DEV

/*
* Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
*/
static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct ds1305 *ds1305 = dev_get_drvdata(dev);
u8 buf[2];
int status = -ENOIOCTLCMD;
long err = -EINVAL;

buf[0] = DS1305_WRITE | DS1305_CONTROL;
buf[1] = ds1305->ctrl[0];

switch (cmd) {
case RTC_AIE_OFF:
status = 0;
if (!(buf[1] & DS1305_AEI0))
goto done;
buf[1] &= ~DS1305_AEI0;
break;

case RTC_AIE_ON:
status = 0;
if (enabled) {
if (ds1305->ctrl[0] & DS1305_AEI0)
goto done;
buf[1] |= DS1305_AEI0;
break;
}
if (status == 0) {
status = spi_write_then_read(ds1305->spi, buf, sizeof buf,
NULL, 0);
if (status >= 0)
ds1305->ctrl[0] = buf[1];
} else {
if (!(buf[1] & DS1305_AEI0))
goto done;
buf[1] &= ~DS1305_AEI0;
}

err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0);
if (err >= 0)
ds1305->ctrl[0] = buf[1];
done:
return status;
return err;

}

#else
#define ds1305_ioctl NULL
#endif

/*
* Get/set of date and time is pretty normal.
Expand Down Expand Up @@ -460,12 +443,12 @@ static int ds1305_proc(struct device *dev, struct seq_file *seq)
#endif

static const struct rtc_class_ops ds1305_ops = {
.ioctl = ds1305_ioctl,
.read_time = ds1305_get_time,
.set_time = ds1305_set_time,
.read_alarm = ds1305_get_alarm,
.set_alarm = ds1305_set_alarm,
.proc = ds1305_proc,
.alarm_irq_enable = ds1305_alarm_irq_enable,
};

static void ds1305_work(struct work_struct *work)
Expand Down
49 changes: 13 additions & 36 deletions drivers/rtc/rtc-ds1307.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,50 +495,27 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
return 0;
}

static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
struct ds1307 *ds1307 = i2c_get_clientdata(client);
int ret;

switch (cmd) {
case RTC_AIE_OFF:
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -ENOTTY;

ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
if (ret < 0)
return ret;

ret &= ~DS1337_BIT_A1IE;

ret = i2c_smbus_write_byte_data(client,
DS1337_REG_CONTROL, ret);
if (ret < 0)
return ret;

break;

case RTC_AIE_ON:
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -ENOTTY;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -ENOTTY;

ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
if (ret < 0)
return ret;
ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
if (ret < 0)
return ret;

if (enabled)
ret |= DS1337_BIT_A1IE;
else
ret &= ~DS1337_BIT_A1IE;

ret = i2c_smbus_write_byte_data(client,
DS1337_REG_CONTROL, ret);
if (ret < 0)
return ret;

break;

default:
return -ENOIOCTLCMD;
}
ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, ret);
if (ret < 0)
return ret;

return 0;
}
Expand All @@ -548,7 +525,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
.set_time = ds1307_set_time,
.read_alarm = ds1337_read_alarm,
.set_alarm = ds1337_set_alarm,
.ioctl = ds1307_ioctl,
.alarm_irq_enable = ds1307_alarm_irq_enable,
};

/*----------------------------------------------------------------------*/
Expand Down
Loading

0 comments on commit 16380c1

Please sign in to comment.