diff options
Diffstat (limited to 'drivers/rtc/rtc-m41t93.c')
| -rw-r--r-- | drivers/rtc/rtc-m41t93.c | 46 | 
1 files changed, 27 insertions, 19 deletions
| diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c index 10f1c29436ec..efab3d48cb15 100644 --- a/drivers/rtc/rtc-m41t93.c +++ b/drivers/rtc/rtc-m41t93.c @@ -48,6 +48,7 @@ static inline int m41t93_set_reg(struct spi_device *spi, u8 addr, u8 data)  static int m41t93_set_time(struct device *dev, struct rtc_time *tm)  {  	struct spi_device *spi = to_spi_device(dev); +	int tmp;  	u8 buf[9] = {0x80};        /* write cmd + 8 data bytes */  	u8 * const data = &buf[1]; /* ptr to first data byte */ @@ -62,6 +63,30 @@ static int m41t93_set_time(struct device *dev, struct rtc_time *tm)  		return -EINVAL;  	} +	tmp = spi_w8r8(spi, M41T93_REG_FLAGS); +	if (tmp < 0) +		return tmp; + +	if (tmp & M41T93_FLAG_OF) { +		dev_warn(&spi->dev, "OF bit is set, resetting.\n"); +		m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF); + +		tmp = spi_w8r8(spi, M41T93_REG_FLAGS); +		if (tmp < 0) { +			return tmp; +		} else if (tmp & M41T93_FLAG_OF) { +			/* OF cannot be immediately reset: oscillator has to be +			 * restarted. */ +			u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST; + +			dev_warn(&spi->dev, +				 "OF bit is still set, kickstarting clock.\n"); +			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); +			reset_osc &= ~M41T93_FLAG_ST; +			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); +		} +	} +  	data[M41T93_REG_SSEC]		= 0;  	data[M41T93_REG_ST_SEC]		= bin2bcd(tm->tm_sec);  	data[M41T93_REG_MIN]		= bin2bcd(tm->tm_min); @@ -89,10 +114,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)  	   1. halt bit (HT) is set: the clock is running but update of readout  	      registers has been disabled due to power failure. This is normal  	      case after poweron. Time is valid after resetting HT bit. -	   2. oscillator fail bit (OF) is set. Oscillator has be stopped and -	      time is invalid: -	      a) OF can be immeditely reset. -	      b) OF cannot be immediately reset: oscillator has to be restarted. +	   2. oscillator fail bit (OF) is set: time is invalid.  	*/  	tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT);  	if (tmp < 0) @@ -110,21 +132,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm)  	if (tmp & M41T93_FLAG_OF) {  		ret = -EINVAL; -		dev_warn(&spi->dev, "OF bit is set, resetting.\n"); -		m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF); - -		tmp = spi_w8r8(spi, M41T93_REG_FLAGS); -		if (tmp < 0) -			return tmp; -		else if (tmp & M41T93_FLAG_OF) { -			u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST; - -			dev_warn(&spi->dev, -				 "OF bit is still set, kickstarting clock.\n"); -			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); -			reset_osc &= ~M41T93_FLAG_ST; -			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc); -		} +		dev_warn(&spi->dev, "OF bit is set, write time to restart.\n");  	}  	if (tmp & M41T93_FLAG_BL) |