From 7c1d23c3df067ab45bb48c71f3573a92f7f87639 Mon Sep 17 00:00:00 2001 From: Anish Trivedi Date: Mon, 18 Apr 2011 14:38:48 -0500 Subject: [PATCH] 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 --- drivers/rtc/rtc-mxc_v2.c | 64 ++++++++++++++++++++++------------------ 1 file 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 */ -- 2.39.5