summaryrefslogtreecommitdiff
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAnish Trivedi <anish@freescale.com>2011-04-18 14:38:48 -0500
committerJason Liu <r64343@freescale.com>2012-07-20 13:13:25 +0800
commitf45d48e7516236910ea5cae04ac303b310bcecfc (patch)
tree9a10b8ddb03574ab4af30f01d648b8936b889a5e /drivers/rtc
parentacaf0f448d9d0f43056b00689e9d94ee10707d73 (diff)
ENGR00142296-2 SRTC: Upgrade driver to kernel version 2.6.38
RTC-DEV ioctl interface changed, which required a definition of new callback mxc_rtc_alarm_irq_enable in SRTC driver. Also, added a sync call to mxc_rtc_interrupt after a write to LP domain register to make sure we wait 3 clock cycles in order for the write to complete, as required by the hardware. Signed-off-by: Anish Trivedi <anish@freescale.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-mxc_v2.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
index 7737420cac9b..6b02c92cf6a3 100644
--- a/drivers/rtc/rtc-mxc_v2.c
+++ b/drivers/rtc/rtc-mxc_v2.c
@@ -273,6 +273,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
/* clear interrupt status */
__raw_writel(lp_status, ioaddr + SRTC_LPSR);
+ rtc_write_sync_lp(ioaddr);
rtc_update_irq(pdata->rtc, 1, events);
return IRQ_HANDLED;
}
@@ -312,37 +313,10 @@ static int mxc_rtc_ioctl(struct device *dev, unsigned int cmd,
{
struct rtc_drv_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr;
- unsigned long lock_flags = 0;
- u32 lp_cr;
u64 time_47bit;
int retVal;
switch (cmd) {
- case RTC_AIE_OFF:
- spin_lock_irqsave(&rtc_lock, lock_flags);
- lp_cr = __raw_readl(ioaddr + SRTC_LPCR);
- lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
- if (((lp_cr & SRTC_LPCR_ALL_INT_EN) == 0)
- && (pdata->irq_enable)) {
- disable_irq(pdata->irq);
- pdata->irq_enable = false;
- }
- __raw_writel(lp_cr, ioaddr + SRTC_LPCR);
- spin_unlock_irqrestore(&rtc_lock, lock_flags);
- return 0;
-
- case RTC_AIE_ON:
- spin_lock_irqsave(&rtc_lock, lock_flags);
- if (!pdata->irq_enable) {
- enable_irq(pdata->irq);
- pdata->irq_enable = true;
- }
- lp_cr = __raw_readl(ioaddr + SRTC_LPCR);
- lp_cr |= SRTC_LPCR_ALP | SRTC_LPCR_WAE;
- __raw_writel(lp_cr, ioaddr + SRTC_LPCR);
- spin_unlock_irqrestore(&rtc_lock, lock_flags);
- return 0;
-
case RTC_READ_TIME_47BIT:
time_47bit = (((u64) __raw_readl(ioaddr + SRTC_LPSCMR)) << 32 |
((u64) __raw_readl(ioaddr + SRTC_LPSCLR)));
@@ -508,8 +482,8 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
__raw_writel(lp_cr, ioaddr + SRTC_LPCR);
out:
- spin_unlock_irqrestore(&rtc_lock, lock_flags);
rtc_write_sync_lp(ioaddr);
+ spin_unlock_irqrestore(&rtc_lock, lock_flags);
return ret;
}
@@ -533,6 +507,39 @@ static int mxc_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
+static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+ struct rtc_drv_data *pdata = dev_get_drvdata(dev);
+ void __iomem *ioaddr = pdata->ioaddr;
+ u32 lp_cr;
+ unsigned long lock_flags = 0;
+
+ spin_lock_irqsave(&rtc_lock, lock_flags);
+
+ if (enable) {
+ if (!pdata->irq_enable) {
+ enable_irq(pdata->irq);
+ pdata->irq_enable = true;
+ }
+ lp_cr = __raw_readl(ioaddr + SRTC_LPCR);
+ lp_cr |= SRTC_LPCR_ALP | SRTC_LPCR_WAE;
+ __raw_writel(lp_cr, ioaddr + SRTC_LPCR);
+ } else {
+ lp_cr = __raw_readl(ioaddr + SRTC_LPCR);
+ lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
+ if (((lp_cr & SRTC_LPCR_ALL_INT_EN) == 0)
+ && (pdata->irq_enable)) {
+ disable_irq(pdata->irq);
+ pdata->irq_enable = false;
+ }
+ __raw_writel(lp_cr, ioaddr + SRTC_LPCR);
+ }
+
+ rtc_write_sync_lp(ioaddr);
+ spin_unlock_irqrestore(&rtc_lock, lock_flags);
+ return 0;
+}
+
/*!
* The RTC driver structure
*/
@@ -545,6 +552,7 @@ static struct rtc_class_ops mxc_rtc_ops = {
.read_alarm = mxc_rtc_read_alarm,
.set_alarm = mxc_rtc_set_alarm,
.proc = mxc_rtc_proc,
+ .alarm_irq_enable = mxc_rtc_alarm_irq_enable,
};
/*! MXC RTC Power management control */