diff options
Diffstat (limited to 'drivers/rtc')
| -rw-r--r-- | drivers/rtc/rtc-stmp3xxx.c | 35 | ||||
| -rw-r--r-- | drivers/rtc/rtc-twl.c | 3 | 
2 files changed, 27 insertions, 11 deletions
| diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 767fee2ab340..26019531db15 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -23,6 +23,7 @@  #include <linux/init.h>  #include <linux/platform_device.h>  #include <linux/interrupt.h> +#include <linux/delay.h>  #include <linux/rtc.h>  #include <linux/slab.h>  #include <linux/of_device.h> @@ -119,24 +120,39 @@ static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)  }  #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */ -static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) +static int stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data)  { +	int timeout = 5000; /* 3ms according to i.MX28 Ref Manual */  	/* -	 * The datasheet doesn't say which way round the -	 * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0, -	 * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS +	 * The i.MX28 Applications Processor Reference Manual, Rev. 1, 2010 +	 * states: +	 * | The order in which registers are updated is +	 * | Persistent 0, 1, 2, 3, 4, 5, Alarm, Seconds. +	 * | (This list is in bitfield order, from LSB to MSB, as they would +	 * | appear in the STALE_REGS and NEW_REGS bitfields of the HW_RTC_STAT +	 * | register. For example, the Seconds register corresponds to +	 * | STALE_REGS or NEW_REGS containing 0x80.)  	 */ -	while (readl(rtc_data->io + STMP3XXX_RTC_STAT) & -			(0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) -		cpu_relax(); +	do { +		if (!(readl(rtc_data->io + STMP3XXX_RTC_STAT) & +				(0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT))) +			return 0; +		udelay(1); +	} while (--timeout > 0); +	return (readl(rtc_data->io + STMP3XXX_RTC_STAT) & +		(0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) ? -ETIME : 0;  }  /* Time read/write */  static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)  { +	int ret;  	struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); -	stmp3xxx_wait_time(rtc_data); +	ret = stmp3xxx_wait_time(rtc_data); +	if (ret) +		return ret; +  	rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm);  	return 0;  } @@ -146,8 +162,7 @@ static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t)  	struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);  	writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); -	stmp3xxx_wait_time(rtc_data); -	return 0; +	return stmp3xxx_wait_time(rtc_data);  }  /* interrupt(s) handler */ diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 02faf3c4e0d5..c2e80d7ca5e2 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -524,6 +524,8 @@ static int twl_rtc_probe(struct platform_device *pdev)  	if (ret < 0)  		goto out1; +	device_init_wakeup(&pdev->dev, 1); +  	rtc = rtc_device_register(pdev->name,  				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);  	if (IS_ERR(rtc)) { @@ -542,7 +544,6 @@ static int twl_rtc_probe(struct platform_device *pdev)  	}  	platform_set_drvdata(pdev, rtc); -	device_init_wakeup(&pdev->dev, 1);  	return 0;  out2: |