Commit a748384b authored by Alessandro Zummo's avatar Alessandro Zummo Committed by Linus Torvalds

rtc: tw4030 add alarm/update interfaces

- implement alarm_irq_enable
- return correct error code when registering fails

[dbrownell@users.sourceforge.net: build fixes, force 1/sec irqs]
Signed-off-by: default avatarAlessandro Zummo <a.zummo@towertech.it>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Samuel Ortiz <sameo@openedhand.com>
Cc: rtc-linux@googlegroups.com
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fb144adc
...@@ -120,7 +120,7 @@ static int twl4030_rtc_write_u8(u8 data, u8 reg) ...@@ -120,7 +120,7 @@ static int twl4030_rtc_write_u8(u8 data, u8 reg)
static unsigned char rtc_irq_bits; static unsigned char rtc_irq_bits;
/* /*
* Enable timer and/or alarm interrupts. * Enable 1/second update and/or alarm interrupts.
*/ */
static int set_rtc_irq_bit(unsigned char bit) static int set_rtc_irq_bit(unsigned char bit)
{ {
...@@ -128,6 +128,7 @@ static int set_rtc_irq_bit(unsigned char bit) ...@@ -128,6 +128,7 @@ static int set_rtc_irq_bit(unsigned char bit)
int ret; int ret;
val = rtc_irq_bits | bit; val = rtc_irq_bits | bit;
val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
if (ret == 0) if (ret == 0)
rtc_irq_bits = val; rtc_irq_bits = val;
...@@ -136,7 +137,7 @@ static int set_rtc_irq_bit(unsigned char bit) ...@@ -136,7 +137,7 @@ static int set_rtc_irq_bit(unsigned char bit)
} }
/* /*
* Disable timer and/or alarm interrupts. * Disable update and/or alarm interrupts.
*/ */
static int mask_rtc_irq_bit(unsigned char bit) static int mask_rtc_irq_bit(unsigned char bit)
{ {
...@@ -151,7 +152,7 @@ static int mask_rtc_irq_bit(unsigned char bit) ...@@ -151,7 +152,7 @@ static int mask_rtc_irq_bit(unsigned char bit)
return ret; return ret;
} }
static inline int twl4030_rtc_alarm_irq_set_state(int enabled) static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
{ {
int ret; int ret;
...@@ -163,7 +164,7 @@ static inline int twl4030_rtc_alarm_irq_set_state(int enabled) ...@@ -163,7 +164,7 @@ static inline int twl4030_rtc_alarm_irq_set_state(int enabled)
return ret; return ret;
} }
static inline int twl4030_rtc_irq_set_state(int enabled) static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled)
{ {
int ret; int ret;
...@@ -292,7 +293,7 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -292,7 +293,7 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
unsigned char alarm_data[ALL_TIME_REGS + 1]; unsigned char alarm_data[ALL_TIME_REGS + 1];
int ret; int ret;
ret = twl4030_rtc_alarm_irq_set_state(0); ret = twl4030_rtc_alarm_irq_enable(dev, 0);
if (ret) if (ret)
goto out; goto out;
...@@ -312,35 +313,11 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) ...@@ -312,35 +313,11 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
} }
if (alm->enabled) if (alm->enabled)
ret = twl4030_rtc_alarm_irq_set_state(1); ret = twl4030_rtc_alarm_irq_enable(dev, 1);
out: out:
return ret; return ret;
} }
#ifdef CONFIG_RTC_INTF_DEV
static int twl4030_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
switch (cmd) {
case RTC_AIE_OFF:
return twl4030_rtc_alarm_irq_set_state(0);
case RTC_AIE_ON:
return twl4030_rtc_alarm_irq_set_state(1);
case RTC_UIE_OFF:
return twl4030_rtc_irq_set_state(0);
case RTC_UIE_ON:
return twl4030_rtc_irq_set_state(1);
default:
return -ENOIOCTLCMD;
}
}
#else
#define twl4030_rtc_ioctl NULL
#endif
static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
{ {
unsigned long events = 0; unsigned long events = 0;
...@@ -400,11 +377,12 @@ static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) ...@@ -400,11 +377,12 @@ static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
} }
static struct rtc_class_ops twl4030_rtc_ops = { static struct rtc_class_ops twl4030_rtc_ops = {
.ioctl = twl4030_rtc_ioctl,
.read_time = twl4030_rtc_read_time, .read_time = twl4030_rtc_read_time,
.set_time = twl4030_rtc_set_time, .set_time = twl4030_rtc_set_time,
.read_alarm = twl4030_rtc_read_alarm, .read_alarm = twl4030_rtc_read_alarm,
.set_alarm = twl4030_rtc_set_alarm, .set_alarm = twl4030_rtc_set_alarm,
.alarm_irq_enable = twl4030_rtc_alarm_irq_enable,
.update_irq_enable = twl4030_rtc_update_irq_enable,
}; };
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
...@@ -422,7 +400,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) ...@@ -422,7 +400,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
rtc = rtc_device_register(pdev->name, rtc = rtc_device_register(pdev->name,
&pdev->dev, &twl4030_rtc_ops, THIS_MODULE); &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(rtc)) {
ret = -EINVAL; ret = PTR_ERR(rtc);
dev_err(&pdev->dev, "can't register RTC device, err %ld\n", dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
PTR_ERR(rtc)); PTR_ERR(rtc));
goto out0; goto out0;
...@@ -432,7 +410,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) ...@@ -432,7 +410,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
if (ret < 0) if (ret < 0)
goto out1; goto out1;
...@@ -475,7 +452,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) ...@@ -475,7 +452,6 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
return ret; return ret;
out2: out2:
free_irq(irq, rtc); free_irq(irq, rtc);
out1: out1:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment