diff options
Diffstat (limited to 'drivers/rtc')
| -rw-r--r-- | drivers/rtc/Kconfig | 21 | ||||
| -rw-r--r-- | drivers/rtc/Makefile | 2 | ||||
| -rw-r--r-- | drivers/rtc/hctosys.c | 18 | ||||
| -rw-r--r-- | drivers/rtc/interface.c | 22 | ||||
| -rw-r--r-- | drivers/rtc/rtc-ab-b5ze-s3.c | 1035 | ||||
| -rw-r--r-- | drivers/rtc/rtc-armada38x.c | 320 | ||||
| -rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 2 | ||||
| -rw-r--r-- | drivers/rtc/rtc-dev.c | 8 | ||||
| -rw-r--r-- | drivers/rtc/rtc-efi.c | 1 | ||||
| -rw-r--r-- | drivers/rtc/rtc-imxdi.c | 50 | ||||
| -rw-r--r-- | drivers/rtc/rtc-isl12057.c | 348 | ||||
| -rw-r--r-- | drivers/rtc/rtc-pcf2123.c | 10 | ||||
| -rw-r--r-- | drivers/rtc/rtc-rk808.c | 10 | ||||
| -rw-r--r-- | drivers/rtc/rtc-s5m.c | 1 | ||||
| -rw-r--r-- | drivers/rtc/systohc.c | 6 | 
15 files changed, 1803 insertions, 51 deletions
| diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f15cddfeb897..3bc9ddbe5cf7 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -153,6 +153,17 @@ config RTC_DRV_88PM80X  	  This driver can also be built as a module. If so, the module  	  will be called rtc-88pm80x. +config RTC_DRV_ABB5ZES3 +       depends on I2C +       select REGMAP_I2C +       tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" +       help +	  If you say yes here you get support for the Abracon +	  AB-RTCMC-32.768kHz-B5ZE-S3 I2C RTC chip. + +	  This driver can also be built as a module. If so, the module +	  will be called rtc-ab-b5ze-s3. +  config RTC_DRV_AS3722  	tristate "ams AS3722 RTC driver"  	depends on MFD_AS3722 @@ -1269,6 +1280,16 @@ config RTC_DRV_MV  	  This driver can also be built as a module. If so, the module  	  will be called rtc-mv. +config RTC_DRV_ARMADA38X +	tristate "Armada 38x Marvell SoC RTC" +	depends on ARCH_MVEBU +	help +	  If you say yes here you will get support for the in-chip RTC +	  that can be found in the Armada 38x Marvell's SoC device + +	  This driver can also be built as a module. If so, the module +	  will be called armada38x-rtc. +  config RTC_DRV_PS3  	tristate "PS3 RTC"  	depends on PPC_PS3 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index c8ef3e1e6ccd..99ded8b75e95 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -24,6 +24,8 @@ obj-$(CONFIG_RTC_DRV_88PM860X)  += rtc-88pm860x.o  obj-$(CONFIG_RTC_DRV_88PM80X)	+= rtc-88pm80x.o  obj-$(CONFIG_RTC_DRV_AB3100)	+= rtc-ab3100.o  obj-$(CONFIG_RTC_DRV_AB8500)	+= rtc-ab8500.o +obj-$(CONFIG_RTC_DRV_ABB5ZES3)	+= rtc-ab-b5ze-s3.o +obj-$(CONFIG_RTC_DRV_ARMADA38X)	+= rtc-armada38x.o  obj-$(CONFIG_RTC_DRV_AS3722)	+= rtc-as3722.o  obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o  obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index 4aa60d74004e..6c719f23520a 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -26,7 +26,7 @@ static int __init rtc_hctosys(void)  {  	int err = -ENODEV;  	struct rtc_time tm; -	struct timespec tv = { +	struct timespec64 tv64 = {  		.tv_nsec = NSEC_PER_SEC >> 1,  	};  	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); @@ -45,25 +45,17 @@ static int __init rtc_hctosys(void)  	} -	err = rtc_valid_tm(&tm); -	if (err) { -		dev_err(rtc->dev.parent, -			"hctosys: invalid date/time\n"); -		goto err_invalid; -	} - -	rtc_tm_to_time(&tm, &tv.tv_sec); +	tv64.tv_sec = rtc_tm_to_time64(&tm); -	err = do_settimeofday(&tv); +	err = do_settimeofday64(&tv64);  	dev_info(rtc->dev.parent,  		"setting system clock to " -		"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", +		"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",  		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,  		tm.tm_hour, tm.tm_min, tm.tm_sec, -		(unsigned int) tv.tv_sec); +		(long long) tv64.tv_sec); -err_invalid:  err_read:  	rtc_class_close(rtc); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 45bfc28ee3aa..37215cf983e9 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -73,10 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)  	else if (rtc->ops->set_time)  		err = rtc->ops->set_time(rtc->dev.parent, tm);  	else if (rtc->ops->set_mmss) { -		unsigned long secs; -		err = rtc_tm_to_time(tm, &secs); -		if (err == 0) -			err = rtc->ops->set_mmss(rtc->dev.parent, secs); +		time64_t secs64 = rtc_tm_to_time64(tm); +		err = rtc->ops->set_mmss(rtc->dev.parent, secs64);  	} else  		err = -EINVAL; @@ -105,7 +103,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)  		err = rtc->ops->read_time(rtc->dev.parent, &old);  		if (err == 0) { -			rtc_time_to_tm(secs, &new); +			rtc_time64_to_tm(secs, &new);  			/*  			 * avoid writing when we're going to change the day of @@ -157,7 +155,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)  	int err;  	struct rtc_time before, now;  	int first_time = 1; -	unsigned long t_now, t_alm; +	time64_t t_now, t_alm;  	enum { none, day, month, year } missing = none;  	unsigned days; @@ -258,8 +256,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)  	}  	/* with luck, no rollover is needed */ -	rtc_tm_to_time(&now, &t_now); -	rtc_tm_to_time(&alarm->time, &t_alm); +	t_now = rtc_tm_to_time64(&now); +	t_alm = rtc_tm_to_time64(&alarm->time);  	if (t_now < t_alm)  		goto done; @@ -273,7 +271,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)  	case day:  		dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day");  		t_alm += 24 * 60 * 60; -		rtc_time_to_tm(t_alm, &alarm->time); +		rtc_time64_to_tm(t_alm, &alarm->time);  		break;  	/* Month rollover ... if it's the 31th, an alarm on the 3rd will @@ -346,19 +344,19 @@ EXPORT_SYMBOL_GPL(rtc_read_alarm);  static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)  {  	struct rtc_time tm; -	long now, scheduled; +	time64_t now, scheduled;  	int err;  	err = rtc_valid_tm(&alarm->time);  	if (err)  		return err; -	rtc_tm_to_time(&alarm->time, &scheduled); +	scheduled = rtc_tm_to_time64(&alarm->time);  	/* Make sure we're not setting alarms in the past */  	err = __rtc_read_time(rtc, &tm);  	if (err)  		return err; -	rtc_tm_to_time(&tm, &now); +	now = rtc_tm_to_time64(&tm);  	if (scheduled <= now)  		return -ETIME;  	/* diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c new file mode 100644 index 000000000000..cfc2ef98d393 --- /dev/null +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -0,0 +1,1035 @@ +/* + * rtc-ab-b5ze-s3 - Driver for Abracon AB-RTCMC-32.768Khz-B5ZE-S3 + *                  I2C RTC / Alarm chip + * + * Copyright (C) 2014, Arnaud EBALARD <[email protected]> + * + * Detailed datasheet of the chip is available here: + * + *  http://www.abracon.com/realtimeclock/AB-RTCMC-32.768kHz-B5ZE-S3-Application-Manual.pdf + * + * This work is based on ISL12057 driver (drivers/rtc/rtc-isl12057.c). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/rtc.h> +#include <linux/i2c.h> +#include <linux/bcd.h> +#include <linux/of.h> +#include <linux/regmap.h> +#include <linux/interrupt.h> + +#define DRV_NAME "rtc-ab-b5ze-s3" + +/* Control section */ +#define ABB5ZES3_REG_CTRL1	   0x00	   /* Control 1 register */ +#define ABB5ZES3_REG_CTRL1_CIE	   BIT(0)  /* Pulse interrupt enable */ +#define ABB5ZES3_REG_CTRL1_AIE	   BIT(1)  /* Alarm interrupt enable */ +#define ABB5ZES3_REG_CTRL1_SIE	   BIT(2)  /* Second interrupt enable */ +#define ABB5ZES3_REG_CTRL1_PM	   BIT(3)  /* 24h/12h mode */ +#define ABB5ZES3_REG_CTRL1_SR	   BIT(4)  /* Software reset */ +#define ABB5ZES3_REG_CTRL1_STOP	   BIT(5)  /* RTC circuit enable */ +#define ABB5ZES3_REG_CTRL1_CAP	   BIT(7) + +#define ABB5ZES3_REG_CTRL2	   0x01	   /* Control 2 register */ +#define ABB5ZES3_REG_CTRL2_CTBIE   BIT(0)  /* Countdown timer B int. enable */ +#define ABB5ZES3_REG_CTRL2_CTAIE   BIT(1)  /* Countdown timer A int. enable */ +#define ABB5ZES3_REG_CTRL2_WTAIE   BIT(2)  /* Watchdog timer A int. enable */ +#define ABB5ZES3_REG_CTRL2_AF	   BIT(3)  /* Alarm interrupt status */ +#define ABB5ZES3_REG_CTRL2_SF	   BIT(4)  /* Second interrupt status */ +#define ABB5ZES3_REG_CTRL2_CTBF	   BIT(5)  /* Countdown timer B int. status */ +#define ABB5ZES3_REG_CTRL2_CTAF	   BIT(6)  /* Countdown timer A int. status */ +#define ABB5ZES3_REG_CTRL2_WTAF	   BIT(7)  /* Watchdog timer A int. status */ + +#define ABB5ZES3_REG_CTRL3	   0x02	   /* Control 3 register */ +#define ABB5ZES3_REG_CTRL3_PM2	   BIT(7)  /* Power Management bit 2 */ +#define ABB5ZES3_REG_CTRL3_PM1	   BIT(6)  /* Power Management bit 1 */ +#define ABB5ZES3_REG_CTRL3_PM0	   BIT(5)  /* Power Management bit 0 */ +#define ABB5ZES3_REG_CTRL3_BSF	   BIT(3)  /* Battery switchover int. status */ +#define ABB5ZES3_REG_CTRL3_BLF	   BIT(2)  /* Battery low int. status */ +#define ABB5ZES3_REG_CTRL3_BSIE	   BIT(1)  /* Battery switchover int. enable */ +#define ABB5ZES3_REG_CTRL3_BLIE	   BIT(0)  /* Battery low int. enable */ + +#define ABB5ZES3_CTRL_SEC_LEN	   3 + +/* RTC section */ +#define ABB5ZES3_REG_RTC_SC	   0x03	   /* RTC Seconds register */ +#define ABB5ZES3_REG_RTC_SC_OSC	   BIT(7)  /* Clock integrity status */ +#define ABB5ZES3_REG_RTC_MN	   0x04	   /* RTC Minutes register */ +#define ABB5ZES3_REG_RTC_HR	   0x05	   /* RTC Hours register */ +#define ABB5ZES3_REG_RTC_HR_PM	   BIT(5)  /* RTC Hours PM bit */ +#define ABB5ZES3_REG_RTC_DT	   0x06	   /* RTC Date register */ +#define ABB5ZES3_REG_RTC_DW	   0x07	   /* RTC Day of the week register */ +#define ABB5ZES3_REG_RTC_MO	   0x08	   /* RTC Month register */ +#define ABB5ZES3_REG_RTC_YR	   0x09	   /* RTC Year register */ + +#define ABB5ZES3_RTC_SEC_LEN	   7 + +/* Alarm section (enable bits are all active low) */ +#define ABB5ZES3_REG_ALRM_MN	   0x0A	   /* Alarm - minute register */ +#define ABB5ZES3_REG_ALRM_MN_AE	   BIT(7)  /* Minute enable */ +#define ABB5ZES3_REG_ALRM_HR	   0x0B	   /* Alarm - hours register */ +#define ABB5ZES3_REG_ALRM_HR_AE	   BIT(7)  /* Hour enable */ +#define ABB5ZES3_REG_ALRM_DT	   0x0C	   /* Alarm - date register */ +#define ABB5ZES3_REG_ALRM_DT_AE	   BIT(7)  /* Date (day of the month) enable */ +#define ABB5ZES3_REG_ALRM_DW	   0x0D	   /* Alarm - day of the week reg. */ +#define ABB5ZES3_REG_ALRM_DW_AE	   BIT(7)  /* Day of the week enable */ + +#define ABB5ZES3_ALRM_SEC_LEN	   4 + +/* Frequency offset section */ +#define ABB5ZES3_REG_FREQ_OF	   0x0E	   /* Frequency offset register */ +#define ABB5ZES3_REG_FREQ_OF_MODE  0x0E	   /* Offset mode: 2 hours / minute */ + +/* CLOCKOUT section */ +#define ABB5ZES3_REG_TIM_CLK	   0x0F	   /* Timer & Clockout register */ +#define ABB5ZES3_REG_TIM_CLK_TAM   BIT(7)  /* Permanent/pulsed timer A/int. 2 */ +#define ABB5ZES3_REG_TIM_CLK_TBM   BIT(6)  /* Permanent/pulsed timer B */ +#define ABB5ZES3_REG_TIM_CLK_COF2  BIT(5)  /* Clkout Freq bit 2 */ +#define ABB5ZES3_REG_TIM_CLK_COF1  BIT(4)  /* Clkout Freq bit 1 */ +#define ABB5ZES3_REG_TIM_CLK_COF0  BIT(3)  /* Clkout Freq bit 0 */ +#define ABB5ZES3_REG_TIM_CLK_TAC1  BIT(2)  /* Timer A: - 01 : countdown */ +#define ABB5ZES3_REG_TIM_CLK_TAC0  BIT(1)  /*	       - 10 : timer	*/ +#define ABB5ZES3_REG_TIM_CLK_TBC   BIT(0)  /* Timer B enable */ + +/* Timer A Section */ +#define ABB5ZES3_REG_TIMA_CLK	   0x10	   /* Timer A clock register */ +#define ABB5ZES3_REG_TIMA_CLK_TAQ2 BIT(2)  /* Freq bit 2 */ +#define ABB5ZES3_REG_TIMA_CLK_TAQ1 BIT(1)  /* Freq bit 1 */ +#define ABB5ZES3_REG_TIMA_CLK_TAQ0 BIT(0)  /* Freq bit 0 */ +#define ABB5ZES3_REG_TIMA	   0x11	   /* Timer A register */ + +#define ABB5ZES3_TIMA_SEC_LEN	   2 + +/* Timer B Section */ +#define ABB5ZES3_REG_TIMB_CLK	   0x12	   /* Timer B clock register */ +#define ABB5ZES3_REG_TIMB_CLK_TBW2 BIT(6) +#define ABB5ZES3_REG_TIMB_CLK_TBW1 BIT(5) +#define ABB5ZES3_REG_TIMB_CLK_TBW0 BIT(4) +#define ABB5ZES3_REG_TIMB_CLK_TAQ2 BIT(2) +#define ABB5ZES3_REG_TIMB_CLK_TAQ1 BIT(1) +#define ABB5ZES3_REG_TIMB_CLK_TAQ0 BIT(0) +#define ABB5ZES3_REG_TIMB	   0x13	   /* Timer B register */ +#define ABB5ZES3_TIMB_SEC_LEN	   2 + +#define ABB5ZES3_MEM_MAP_LEN	   0x14 + +struct abb5zes3_rtc_data { +	struct rtc_device *rtc; +	struct regmap *regmap; +	struct mutex lock; + +	int irq; + +	bool battery_low; +	bool timer_alarm; /* current alarm is via timer A */ +}; + +/* + * Try and match register bits w/ fixed null values to see whether we + * are dealing with an ABB5ZES3. Note: this function is called early + * during init and hence does need mutex protection. + */ +static int abb5zes3_i2c_validate_chip(struct regmap *regmap) +{ +	u8 regs[ABB5ZES3_MEM_MAP_LEN]; +	static const u8 mask[ABB5ZES3_MEM_MAP_LEN] = { 0x00, 0x00, 0x10, 0x00, +						       0x80, 0xc0, 0xc0, 0xf8, +						       0xe0, 0x00, 0x00, 0x40, +						       0x40, 0x78, 0x00, 0x00, +						       0xf8, 0x00, 0x88, 0x00 }; +	int ret, i; + +	ret = regmap_bulk_read(regmap, 0, regs, ABB5ZES3_MEM_MAP_LEN); +	if (ret) +		return ret; + +	for (i = 0; i < ABB5ZES3_MEM_MAP_LEN; ++i) { +		if (regs[i] & mask[i]) /* check if bits are cleared */ +			return -ENODEV; +	} + +	return 0; +} + +/* Clear alarm status bit. */ +static int _abb5zes3_rtc_clear_alarm(struct device *dev) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL2, +				 ABB5ZES3_REG_CTRL2_AF, 0); +	if (ret) +		dev_err(dev, "%s: clearing alarm failed (%d)\n", __func__, ret); + +	return ret; +} + +/* Enable or disable alarm (i.e. alarm interrupt generation) */ +static int _abb5zes3_rtc_update_alarm(struct device *dev, bool enable) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL1, +				 ABB5ZES3_REG_CTRL1_AIE, +				 enable ? ABB5ZES3_REG_CTRL1_AIE : 0); +	if (ret) +		dev_err(dev, "%s: writing alarm INT failed (%d)\n", +			__func__, ret); + +	return ret; +} + +/* Enable or disable timer (watchdog timer A interrupt generation) */ +static int _abb5zes3_rtc_update_timer(struct device *dev, bool enable) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL2, +				 ABB5ZES3_REG_CTRL2_WTAIE, +				 enable ? ABB5ZES3_REG_CTRL2_WTAIE : 0); +	if (ret) +		dev_err(dev, "%s: writing timer INT failed (%d)\n", +			__func__, ret); + +	return ret; +} + +/* + * Note: we only read, so regmap inner lock protection is sufficient, i.e. + * we do not need driver's main lock protection. + */ +static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN]; +	int ret; + +	/* +	 * As we need to read CTRL1 register anyway to access 24/12h +	 * mode bit, we do a single bulk read of both control and RTC +	 * sections (they are consecutive). This also ease indexing +	 * of register values after bulk read. +	 */ +	ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_CTRL1, regs, +			       sizeof(regs)); +	if (ret) { +		dev_err(dev, "%s: reading RTC time failed (%d)\n", +			__func__, ret); +		goto err; +	} + +	/* If clock integrity is not guaranteed, do not return a time value */ +	if (regs[ABB5ZES3_REG_RTC_SC] & ABB5ZES3_REG_RTC_SC_OSC) { +		ret = -ENODATA; +		goto err; +	} + +	tm->tm_sec = bcd2bin(regs[ABB5ZES3_REG_RTC_SC] & 0x7F); +	tm->tm_min = bcd2bin(regs[ABB5ZES3_REG_RTC_MN]); + +	if (regs[ABB5ZES3_REG_CTRL1] & ABB5ZES3_REG_CTRL1_PM) { /* 12hr mode */ +		tm->tm_hour = bcd2bin(regs[ABB5ZES3_REG_RTC_HR] & 0x1f); +		if (regs[ABB5ZES3_REG_RTC_HR] & ABB5ZES3_REG_RTC_HR_PM) /* PM */ +			tm->tm_hour += 12; +	} else {						/* 24hr mode */ +		tm->tm_hour = bcd2bin(regs[ABB5ZES3_REG_RTC_HR]); +	} + +	tm->tm_mday = bcd2bin(regs[ABB5ZES3_REG_RTC_DT]); +	tm->tm_wday = bcd2bin(regs[ABB5ZES3_REG_RTC_DW]); +	tm->tm_mon  = bcd2bin(regs[ABB5ZES3_REG_RTC_MO]) - 1; /* starts at 1 */ +	tm->tm_year = bcd2bin(regs[ABB5ZES3_REG_RTC_YR]) + 100; + +	ret = rtc_valid_tm(tm); + +err: +	return ret; +} + +static int abb5zes3_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN]; +	int ret; + +	/* +	 * Year register is 8-bit wide and bcd-coded, i.e records values +	 * between 0 and 99. tm_year is an offset from 1900 and we are +	 * interested in the 2000-2099 range, so any value less than 100 +	 * is invalid. +	 */ +	if (tm->tm_year < 100) +		return -EINVAL; + +	regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */ +	regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min); +	regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ +	regs[ABB5ZES3_REG_RTC_DT] = bin2bcd(tm->tm_mday); +	regs[ABB5ZES3_REG_RTC_DW] = bin2bcd(tm->tm_wday); +	regs[ABB5ZES3_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1); +	regs[ABB5ZES3_REG_RTC_YR] = bin2bcd(tm->tm_year - 100); + +	mutex_lock(&data->lock); +	ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_RTC_SC, +				regs + ABB5ZES3_REG_RTC_SC, +				ABB5ZES3_RTC_SEC_LEN); +	mutex_unlock(&data->lock); + + +	return ret; +} + +/* + * Set provided TAQ and Timer A registers (TIMA_CLK and TIMA) based on + * given number of seconds. + */ +static inline void sec_to_timer_a(u8 secs, u8 *taq, u8 *timer_a) +{ +	*taq = ABB5ZES3_REG_TIMA_CLK_TAQ1; /* 1Hz */ +	*timer_a = secs; +} + +/* + * Return current number of seconds in Timer A. As we only use + * timer A with a 1Hz freq, this is what we expect to have. + */ +static inline int sec_from_timer_a(u8 *secs, u8 taq, u8 timer_a) +{ +	if (taq != ABB5ZES3_REG_TIMA_CLK_TAQ1) /* 1Hz */ +		return -EINVAL; + +	*secs = timer_a; + +	return 0; +} + +/* + * Read alarm currently configured via a watchdog timer using timer A. This + * is done by reading current RTC time and adding remaining timer time. + */ +static int _abb5zes3_rtc_read_timer(struct device *dev, +				    struct rtc_wkalrm *alarm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	struct rtc_time rtc_tm, *alarm_tm = &alarm->time; +	u8 regs[ABB5ZES3_TIMA_SEC_LEN + 1]; +	unsigned long rtc_secs; +	unsigned int reg; +	u8 timer_secs; +	int ret; + +	/* +	 * Instead of doing two separate calls, because they are consecutive, +	 * we grab both clockout register and Timer A section. The latter is +	 * used to decide if timer A is enabled (as a watchdog timer). +	 */ +	ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_TIM_CLK, regs, +			       ABB5ZES3_TIMA_SEC_LEN + 1); +	if (ret) { +		dev_err(dev, "%s: reading Timer A section failed (%d)\n", +			__func__, ret); +		goto err; +	} + +	/* get current time ... */ +	ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); +	if (ret) +		goto err; + +	/* ... convert to seconds ... */ +	ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +	if (ret) +		goto err; + +	/* ... add remaining timer A time ... */ +	ret = sec_from_timer_a(&timer_secs, regs[1], regs[2]); +	if (ret) +		goto err; + +	/* ... and convert back. */ +	rtc_time_to_tm(rtc_secs + timer_secs, alarm_tm); + +	ret = regmap_read(data->regmap, ABB5ZES3_REG_CTRL2, ®); +	if (ret) { +		dev_err(dev, "%s: reading ctrl reg failed (%d)\n", +			__func__, ret); +		goto err; +	} + +	alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL2_WTAIE); + +err: +	return ret; +} + +/* Read alarm currently configured via a RTC alarm registers. */ +static int _abb5zes3_rtc_read_alarm(struct device *dev, +				    struct rtc_wkalrm *alarm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	struct rtc_time rtc_tm, *alarm_tm = &alarm->time; +	unsigned long rtc_secs, alarm_secs; +	u8 regs[ABB5ZES3_ALRM_SEC_LEN]; +	unsigned int reg; +	int ret; + +	ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_ALRM_MN, regs, +			       ABB5ZES3_ALRM_SEC_LEN); +	if (ret) { +		dev_err(dev, "%s: reading alarm section failed (%d)\n", +			__func__, ret); +		goto err; +	} + +	alarm_tm->tm_sec  = 0; +	alarm_tm->tm_min  = bcd2bin(regs[0] & 0x7f); +	alarm_tm->tm_hour = bcd2bin(regs[1] & 0x3f); +	alarm_tm->tm_mday = bcd2bin(regs[2] & 0x3f); +	alarm_tm->tm_wday = -1; + +	/* +	 * The alarm section does not store year/month. We use the ones in rtc +	 * section as a basis and increment month and then year if needed to get +	 * alarm after current time. +	 */ +	ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); +	if (ret) +		goto err; + +	alarm_tm->tm_year = rtc_tm.tm_year; +	alarm_tm->tm_mon = rtc_tm.tm_mon; + +	ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +	if (ret) +		goto err; + +	ret = rtc_tm_to_time(alarm_tm, &alarm_secs); +	if (ret) +		goto err; + +	if (alarm_secs < rtc_secs) { +		if (alarm_tm->tm_mon == 11) { +			alarm_tm->tm_mon = 0; +			alarm_tm->tm_year += 1; +		} else { +			alarm_tm->tm_mon += 1; +		} +	} + +	ret = regmap_read(data->regmap, ABB5ZES3_REG_CTRL1, ®); +	if (ret) { +		dev_err(dev, "%s: reading ctrl reg failed (%d)\n", +			__func__, ret); +		goto err; +	} + +	alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL1_AIE); + +err: +	return ret; +} + +/* + * As the Alarm mechanism supported by the chip is only accurate to the + * minute, we use the watchdog timer mechanism provided by timer A + * (up to 256 seconds w/ a second accuracy) for low alarm values (below + * 4 minutes). Otherwise, we use the common alarm mechanism provided + * by the chip. In order for that to work, we keep track of currently + * configured timer type via 'timer_alarm' flag in our private data + * structure. + */ +static int abb5zes3_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	mutex_lock(&data->lock); +	if (data->timer_alarm) +		ret = _abb5zes3_rtc_read_timer(dev, alarm); +	else +		ret = _abb5zes3_rtc_read_alarm(dev, alarm); +	mutex_unlock(&data->lock); + +	return ret; +} + +/* + * Set alarm using chip alarm mechanism. It is only accurate to the + * minute (not the second). The function expects alarm interrupt to + * be disabled. + */ +static int _abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	struct rtc_time *alarm_tm = &alarm->time; +	unsigned long rtc_secs, alarm_secs; +	u8 regs[ABB5ZES3_ALRM_SEC_LEN]; +	struct rtc_time rtc_tm; +	int ret, enable = 1; + +	ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); +	if (ret) +		goto err; + +	ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +	if (ret) +		goto err; + +	ret = rtc_tm_to_time(alarm_tm, &alarm_secs); +	if (ret) +		goto err; + +	/* If alarm time is before current time, disable the alarm */ +	if (!alarm->enabled || alarm_secs <= rtc_secs) { +		enable = 0; +	} else { +		/* +		 * Chip only support alarms up to one month in the future. Let's +		 * return an error if we get something after that limit. +		 * Comparison is done by incrementing rtc_tm month field by one +		 * and checking alarm value is still below. +		 */ +		if (rtc_tm.tm_mon == 11) { /* handle year wrapping */ +			rtc_tm.tm_mon = 0; +			rtc_tm.tm_year += 1; +		} else { +			rtc_tm.tm_mon += 1; +		} + +		ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +		if (ret) +			goto err; + +		if (alarm_secs > rtc_secs) { +			dev_err(dev, "%s: alarm maximum is one month in the " +				"future (%d)\n", __func__, ret); +			ret = -EINVAL; +			goto err; +		} +	} + +	/* +	 * Program all alarm registers but DW one. For each register, setting +	 * MSB to 0 enables associated alarm. +	 */ +	regs[0] = bin2bcd(alarm_tm->tm_min) & 0x7f; +	regs[1] = bin2bcd(alarm_tm->tm_hour) & 0x3f; +	regs[2] = bin2bcd(alarm_tm->tm_mday) & 0x3f; +	regs[3] = ABB5ZES3_REG_ALRM_DW_AE; /* do not match day of the week */ + +	ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_ALRM_MN, regs, +				ABB5ZES3_ALRM_SEC_LEN); +	if (ret < 0) { +		dev_err(dev, "%s: writing ALARM section failed (%d)\n", +			__func__, ret); +		goto err; +	} + +	/* Record currently configured alarm is not a timer */ +	data->timer_alarm = 0; + +	/* Enable or disable alarm interrupt generation */ +	ret = _abb5zes3_rtc_update_alarm(dev, enable); + +err: +	return ret; +} + +/* + * Set alarm using timer watchdog (via timer A) mechanism. The function expects + * timer A interrupt to be disabled. + */ +static int _abb5zes3_rtc_set_timer(struct device *dev, struct rtc_wkalrm *alarm, +				   u8 secs) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	u8 regs[ABB5ZES3_TIMA_SEC_LEN]; +	u8 mask = ABB5ZES3_REG_TIM_CLK_TAC0 | ABB5ZES3_REG_TIM_CLK_TAC1; +	int ret = 0; + +	/* Program given number of seconds to Timer A registers */ +	sec_to_timer_a(secs, ®s[0], ®s[1]); +	ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_TIMA_CLK, regs, +				ABB5ZES3_TIMA_SEC_LEN); +	if (ret < 0) { +		dev_err(dev, "%s: writing timer section failed\n", __func__); +		goto err; +	} + +	/* Configure Timer A as a watchdog timer */ +	ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_TIM_CLK, +				 mask, ABB5ZES3_REG_TIM_CLK_TAC1); +	if (ret) +		dev_err(dev, "%s: failed to update timer\n", __func__); + +	/* Record currently configured alarm is a timer */ +	data->timer_alarm = 1; + +	/* Enable or disable timer interrupt generation */ +	ret = _abb5zes3_rtc_update_timer(dev, alarm->enabled); + +err: +	return ret; +} + +/* + * The chip has an alarm which is only accurate to the minute. In order to + * handle alarms below that limit, we use the watchdog timer function of + * timer A. More precisely, the timer method is used for alarms below 240 + * seconds. + */ +static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	struct rtc_time *alarm_tm = &alarm->time; +	unsigned long rtc_secs, alarm_secs; +	struct rtc_time rtc_tm; +	int ret; + +	mutex_lock(&data->lock); +	ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); +	if (ret) +		goto err; + +	ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +	if (ret) +		goto err; + +	ret = rtc_tm_to_time(alarm_tm, &alarm_secs); +	if (ret) +		goto err; + +	/* Let's first disable both the alarm and the timer interrupts */ +	ret = _abb5zes3_rtc_update_alarm(dev, false); +	if (ret < 0) { +		dev_err(dev, "%s: unable to disable alarm (%d)\n", __func__, +			ret); +		goto err; +	} +	ret = _abb5zes3_rtc_update_timer(dev, false); +	if (ret < 0) { +		dev_err(dev, "%s: unable to disable timer (%d)\n", __func__, +			ret); +		goto err; +	} + +	data->timer_alarm = 0; + +	/* +	 * Let's now configure the alarm; if we are expected to ring in +	 * more than 240s, then we setup an alarm. Otherwise, a timer. +	 */ +	if ((alarm_secs > rtc_secs) && ((alarm_secs - rtc_secs) <= 240)) +		ret = _abb5zes3_rtc_set_timer(dev, alarm, +					      alarm_secs - rtc_secs); +	else +		ret = _abb5zes3_rtc_set_alarm(dev, alarm); + + err: +	mutex_unlock(&data->lock); + +	if (ret) +		dev_err(dev, "%s: unable to configure alarm (%d)\n", __func__, +			ret); + +	return ret; + } + +/* Enable or disable battery low irq generation */ +static inline int _abb5zes3_rtc_battery_low_irq_enable(struct regmap *regmap, +						       bool enable) +{ +	return regmap_update_bits(regmap, ABB5ZES3_REG_CTRL3, +				  ABB5ZES3_REG_CTRL3_BLIE, +				  enable ? ABB5ZES3_REG_CTRL3_BLIE : 0); +} + +/* + * Check current RTC status and enable/disable what needs to be. Return 0 if + * everything went ok and a negative value upon error. Note: this function + * is called early during init and hence does need mutex protection. + */ +static int abb5zes3_rtc_check_setup(struct device *dev) +{ +	struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); +	struct regmap *regmap = data->regmap; +	unsigned int reg; +	int ret; +	u8 mask; + +	/* +	 * By default, the devices generates a 32.768KHz signal on IRQ#1 pin. It +	 * is disabled here to prevent polluting the interrupt line and +	 * uselessly triggering the IRQ handler we install for alarm and battery +	 * low events. Note: this is done before clearing int. status below +	 * in this function. +	 * We also disable all timers and set timer interrupt to permanent (not +	 * pulsed). +	 */ +	mask = (ABB5ZES3_REG_TIM_CLK_TBC | ABB5ZES3_REG_TIM_CLK_TAC0 | +		ABB5ZES3_REG_TIM_CLK_TAC1 | ABB5ZES3_REG_TIM_CLK_COF0 | +		ABB5ZES3_REG_TIM_CLK_COF1 | ABB5ZES3_REG_TIM_CLK_COF2 | +		ABB5ZES3_REG_TIM_CLK_TBM | ABB5ZES3_REG_TIM_CLK_TAM); +	ret = regmap_update_bits(regmap, ABB5ZES3_REG_TIM_CLK, mask, +		ABB5ZES3_REG_TIM_CLK_COF0 | ABB5ZES3_REG_TIM_CLK_COF1 | +		ABB5ZES3_REG_TIM_CLK_COF2); +	if (ret < 0) { +		dev_err(dev, "%s: unable to initialize clkout register (%d)\n", +			__func__, ret); +		return ret; +	} + +	/* +	 * Each component of the alarm (MN, HR, DT, DW) can be enabled/disabled +	 * individually by clearing/setting MSB of each associated register. So, +	 * we set all alarm enable bits to disable current alarm setting. +	 */ +	mask = (ABB5ZES3_REG_ALRM_MN_AE | ABB5ZES3_REG_ALRM_HR_AE | +		ABB5ZES3_REG_ALRM_DT_AE | ABB5ZES3_REG_ALRM_DW_AE); +	ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL2, mask, mask); +	if (ret < 0) { +		dev_err(dev, "%s: unable to disable alarm setting (%d)\n", +			__func__, ret); +		return ret; +	} + +	/* Set Control 1 register (RTC enabled, 24hr mode, all int. disabled) */ +	mask = (ABB5ZES3_REG_CTRL1_CIE | ABB5ZES3_REG_CTRL1_AIE | +		ABB5ZES3_REG_CTRL1_SIE | ABB5ZES3_REG_CTRL1_PM | +		ABB5ZES3_REG_CTRL1_CAP | ABB5ZES3_REG_CTRL1_STOP); +	ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL1, mask, 0); +	if (ret < 0) { +		dev_err(dev, "%s: unable to initialize CTRL1 register (%d)\n", +			__func__, ret); +		return ret; +	} + +	/* +	 * Set Control 2 register (timer int. disabled, alarm status cleared). +	 * WTAF is read-only and cleared automatically by reading the register. +	 */ +	mask = (ABB5ZES3_REG_CTRL2_CTBIE | ABB5ZES3_REG_CTRL2_CTAIE | +		ABB5ZES3_REG_CTRL2_WTAIE | ABB5ZES3_REG_CTRL2_AF | +		ABB5ZES3_REG_CTRL2_SF | ABB5ZES3_REG_CTRL2_CTBF | +		ABB5ZES3_REG_CTRL2_CTAF); +	ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL2, mask, 0); +	if (ret < 0) { +		dev_err(dev, "%s: unable to initialize CTRL2 register (%d)\n", +			__func__, ret); +		return ret; +	} + +	/* +	 * Enable battery low detection function and battery switchover function +	 * (standard mode). Disable associated interrupts. Clear battery +	 * switchover flag but not battery low flag. The latter is checked +	 * later below. +	 */ +	mask = (ABB5ZES3_REG_CTRL3_PM0 | ABB5ZES3_REG_CTRL3_PM1 | +		ABB5ZES3_REG_CTRL3_PM2 | ABB5ZES3_REG_CTRL3_BLIE | +		ABB5ZES3_REG_CTRL3_BSIE| ABB5ZES3_REG_CTRL3_BSF); +	ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL3, mask, 0); +	if (ret < 0) { +		dev_err(dev, "%s: unable to initialize CTRL3 register (%d)\n", +			__func__, ret); +		return ret; +	} + +	/* Check oscillator integrity flag */ +	ret = regmap_read(regmap, ABB5ZES3_REG_RTC_SC, ®); +	if (ret < 0) { +		dev_err(dev, "%s: unable to read osc. integrity flag (%d)\n", +			__func__, ret); +		return ret; +	} + +	if (reg & ABB5ZES3_REG_RTC_SC_OSC) { +		dev_err(dev, "clock integrity not guaranteed. Osc. has stopped " +			"or has been interrupted.\n"); +		dev_err(dev, "change battery (if not already done) and  " +			"then set time to reset osc. failure flag.\n"); +	} + +	/* +	 * Check battery low flag at startup: this allows reporting battery +	 * is low at startup when IRQ line is not connected. Note: we record +	 * current status to avoid reenabling this interrupt later in probe +	 * function if battery is low. +	 */ +	ret = regmap_read(regmap, ABB5ZES3_REG_CTRL3, ®); +	if (ret < 0) { +		dev_err(dev, "%s: unable to read battery low flag (%d)\n", +			__func__, ret); +		return ret; +	} + +	data->battery_low = reg & ABB5ZES3_REG_CTRL3_BLF; +	if (data->battery_low) { +		dev_err(dev, "RTC battery is low; please, consider " +			"changing it!\n"); + +		ret = _abb5zes3_rtc_battery_low_irq_enable(regmap, false); +		if (ret) +			dev_err(dev, "%s: disabling battery low interrupt " +				"generation failed (%d)\n", __func__, ret); +	} + +	return ret; +} + +static int abb5zes3_rtc_alarm_irq_enable(struct device *dev, +					 unsigned int enable) +{ +	struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); +	int ret = 0; + +	if (rtc_data->irq) { +		mutex_lock(&rtc_data->lock); +		if (rtc_data->timer_alarm) +			ret = _abb5zes3_rtc_update_timer(dev, enable); +		else +			ret = _abb5zes3_rtc_update_alarm(dev, enable); +		mutex_unlock(&rtc_data->lock); +	} + +	return ret; +} + +static irqreturn_t _abb5zes3_rtc_interrupt(int irq, void *data) +{ +	struct i2c_client *client = data; +	struct device *dev = &client->dev; +	struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); +	struct rtc_device *rtc = rtc_data->rtc; +	u8 regs[ABB5ZES3_CTRL_SEC_LEN]; +	int ret, handled = IRQ_NONE; + +	ret = regmap_bulk_read(rtc_data->regmap, 0, regs, +			       ABB5ZES3_CTRL_SEC_LEN); +	if (ret) { +		dev_err(dev, "%s: unable to read control section (%d)!\n", +			__func__, ret); +		return handled; +	} + +	/* +	 * Check battery low detection flag and disable battery low interrupt +	 * generation if flag is set (interrupt can only be cleared when +	 * battery is replaced). +	 */ +	if (regs[ABB5ZES3_REG_CTRL3] & ABB5ZES3_REG_CTRL3_BLF) { +		dev_err(dev, "RTC battery is low; please change it!\n"); + +		_abb5zes3_rtc_battery_low_irq_enable(rtc_data->regmap, false); + +		handled = IRQ_HANDLED; +	} + +	/* Check alarm flag */ +	if (regs[ABB5ZES3_REG_CTRL2] & ABB5ZES3_REG_CTRL2_AF) { +		dev_dbg(dev, "RTC alarm!\n"); + +		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); + +		/* Acknowledge and disable the alarm */ +		_abb5zes3_rtc_clear_alarm(dev); +		_abb5zes3_rtc_update_alarm(dev, 0); + +		handled = IRQ_HANDLED; +	} + +	/* Check watchdog Timer A flag */ +	if (regs[ABB5ZES3_REG_CTRL2] & ABB5ZES3_REG_CTRL2_WTAF) { +		dev_dbg(dev, "RTC timer!\n"); + +		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); + +		/* +		 * Acknowledge and disable the alarm. Note: WTAF +		 * flag had been cleared when reading CTRL2 +		 */ +		_abb5zes3_rtc_update_timer(dev, 0); + +		rtc_data->timer_alarm = 0; + +		handled = IRQ_HANDLED; +	} + +	return handled; +} + +static const struct rtc_class_ops rtc_ops = { +	.read_time = _abb5zes3_rtc_read_time, +	.set_time = abb5zes3_rtc_set_time, +	.read_alarm = abb5zes3_rtc_read_alarm, +	.set_alarm = abb5zes3_rtc_set_alarm, +	.alarm_irq_enable = abb5zes3_rtc_alarm_irq_enable, +}; + +static struct regmap_config abb5zes3_rtc_regmap_config = { +	.reg_bits = 8, +	.val_bits = 8, +}; + +static int abb5zes3_probe(struct i2c_client *client, +			  const struct i2c_device_id *id) +{ +	struct abb5zes3_rtc_data *data = NULL; +	struct device *dev = &client->dev; +	struct regmap *regmap; +	int ret; + +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | +				     I2C_FUNC_SMBUS_BYTE_DATA | +				     I2C_FUNC_SMBUS_I2C_BLOCK)) { +		ret = -ENODEV; +		goto err; +	} + +	regmap = devm_regmap_init_i2c(client, &abb5zes3_rtc_regmap_config); +	if (IS_ERR(regmap)) { +		ret = PTR_ERR(regmap); +		dev_err(dev, "%s: regmap allocation failed: %d\n", +			__func__, ret); +		goto err; +	} + +	ret = abb5zes3_i2c_validate_chip(regmap); +	if (ret) +		goto err; + +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); +	if (!data) { +		ret = -ENOMEM; +		goto err; +	} + +	mutex_init(&data->lock); +	data->regmap = regmap; +	dev_set_drvdata(dev, data); + +	ret = abb5zes3_rtc_check_setup(dev); +	if (ret) +		goto err; + +	if (client->irq > 0) { +		ret = devm_request_threaded_irq(dev, client->irq, NULL, +						_abb5zes3_rtc_interrupt, +						IRQF_SHARED|IRQF_ONESHOT, +						DRV_NAME, client); +		if (!ret) { +			device_init_wakeup(dev, true); +			data->irq = client->irq; +			dev_dbg(dev, "%s: irq %d used by RTC\n", __func__, +				client->irq); +		} else { +			dev_err(dev, "%s: irq %d unavailable (%d)\n", +				__func__, client->irq, ret); +			goto err; +		} +	} + +	data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, +					     THIS_MODULE); +	ret = PTR_ERR_OR_ZERO(data->rtc); +	if (ret) { +		dev_err(dev, "%s: unable to register RTC device (%d)\n", +			__func__, ret); +		goto err; +	} + +	/* Enable battery low detection interrupt if battery not already low */ +	if (!data->battery_low && data->irq) { +		ret = _abb5zes3_rtc_battery_low_irq_enable(regmap, true); +		if (ret) { +			dev_err(dev, "%s: enabling battery low interrupt " +				"generation failed (%d)\n", __func__, ret); +			goto err; +		} +	} + +err: +	if (ret && data && data->irq) +		device_init_wakeup(dev, false); +	return ret; +} + +static int abb5zes3_remove(struct i2c_client *client) +{ +	struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(&client->dev); + +	if (rtc_data->irq > 0) +		device_init_wakeup(&client->dev, false); + +	return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int abb5zes3_rtc_suspend(struct device *dev) +{ +	struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); + +	if (device_may_wakeup(dev)) +		return enable_irq_wake(rtc_data->irq); + +	return 0; +} + +static int abb5zes3_rtc_resume(struct device *dev) +{ +	struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); + +	if (device_may_wakeup(dev)) +		return disable_irq_wake(rtc_data->irq); + +	return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(abb5zes3_rtc_pm_ops, abb5zes3_rtc_suspend, +			 abb5zes3_rtc_resume); + +#ifdef CONFIG_OF +static const struct of_device_id abb5zes3_dt_match[] = { +	{ .compatible = "abracon,abb5zes3" }, +	{ }, +}; +#endif + +static const struct i2c_device_id abb5zes3_id[] = { +	{ "abb5zes3", 0 }, +	{ } +}; +MODULE_DEVICE_TABLE(i2c, abb5zes3_id); + +static struct i2c_driver abb5zes3_driver = { +	.driver = { +		.name = DRV_NAME, +		.owner = THIS_MODULE, +		.pm = &abb5zes3_rtc_pm_ops, +		.of_match_table = of_match_ptr(abb5zes3_dt_match), +	}, +	.probe	  = abb5zes3_probe, +	.remove	  = abb5zes3_remove, +	.id_table = abb5zes3_id, +}; +module_i2c_driver(abb5zes3_driver); + +MODULE_AUTHOR("Arnaud EBALARD <[email protected]>"); +MODULE_DESCRIPTION("Abracon AB-RTCMC-32.768kHz-B5ZE-S3 RTC/Alarm driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c new file mode 100644 index 000000000000..43e04af39e09 --- /dev/null +++ b/drivers/rtc/rtc-armada38x.c @@ -0,0 +1,320 @@ +/* + * RTC driver for the Armada 38x Marvell SoCs + * + * Copyright (C) 2015 Marvell + * + * Gregory Clement <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + */ + +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> + +#define RTC_STATUS	    0x0 +#define RTC_STATUS_ALARM1	    BIT(0) +#define RTC_STATUS_ALARM2	    BIT(1) +#define RTC_IRQ1_CONF	    0x4 +#define RTC_IRQ1_AL_EN		    BIT(0) +#define RTC_IRQ1_FREQ_EN	    BIT(1) +#define RTC_IRQ1_FREQ_1HZ	    BIT(2) +#define RTC_TIME	    0xC +#define RTC_ALARM1	    0x10 + +#define SOC_RTC_INTERRUPT   0x8 +#define SOC_RTC_ALARM1		BIT(0) +#define SOC_RTC_ALARM2		BIT(1) +#define SOC_RTC_ALARM1_MASK	BIT(2) +#define SOC_RTC_ALARM2_MASK	BIT(3) + +struct armada38x_rtc { +	struct rtc_device   *rtc_dev; +	void __iomem	    *regs; +	void __iomem	    *regs_soc; +	spinlock_t	    lock; +	int		    irq; +}; + +/* + * According to the datasheet, the OS should wait 5us after every + * register write to the RTC hard macro so that the required update + * can occur without holding off the system bus + */ +static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) +{ +	writel(val, rtc->regs + offset); +	udelay(5); +} + +static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ +	struct armada38x_rtc *rtc = dev_get_drvdata(dev); +	unsigned long time, time_check, flags; + +	spin_lock_irqsave(&rtc->lock, flags); + +	time = readl(rtc->regs + RTC_TIME); +	/* +	 * WA for failing time set attempts. As stated in HW ERRATA if +	 * more than one second between two time reads is detected +	 * then read once again. +	 */ +	time_check = readl(rtc->regs + RTC_TIME); +	if ((time_check - time) > 1) +		time_check = readl(rtc->regs + RTC_TIME); + +	spin_unlock_irqrestore(&rtc->lock, flags); + +	rtc_time_to_tm(time_check, tm); + +	return 0; +} + +static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ +	struct armada38x_rtc *rtc = dev_get_drvdata(dev); +	int ret = 0; +	unsigned long time, flags; + +	ret = rtc_tm_to_time(tm, &time); + +	if (ret) +		goto out; +	/* +	 * Setting the RTC time not always succeeds. According to the +	 * errata we need to first write on the status register and +	 * then wait for 100ms before writing to the time register to be +	 * sure that the data will be taken into account. +	 */ +	spin_lock_irqsave(&rtc->lock, flags); + +	rtc_delayed_write(0, rtc, RTC_STATUS); + +	spin_unlock_irqrestore(&rtc->lock, flags); + +	msleep(100); + +	spin_lock_irqsave(&rtc->lock, flags); + +	rtc_delayed_write(time, rtc, RTC_TIME); + +	spin_unlock_irqrestore(&rtc->lock, flags); +out: +	return ret; +} + +static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ +	struct armada38x_rtc *rtc = dev_get_drvdata(dev); +	unsigned long time, flags; +	u32 val; + +	spin_lock_irqsave(&rtc->lock, flags); + +	time = readl(rtc->regs + RTC_ALARM1); +	val = readl(rtc->regs + RTC_IRQ1_CONF) & RTC_IRQ1_AL_EN; + +	spin_unlock_irqrestore(&rtc->lock, flags); + +	alrm->enabled = val ? 1 : 0; +	rtc_time_to_tm(time,  &alrm->time); + +	return 0; +} + +static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ +	struct armada38x_rtc *rtc = dev_get_drvdata(dev); +	unsigned long time, flags; +	int ret = 0; +	u32 val; + +	ret = rtc_tm_to_time(&alrm->time, &time); + +	if (ret) +		goto out; + +	spin_lock_irqsave(&rtc->lock, flags); + +	rtc_delayed_write(time, rtc, RTC_ALARM1); + +	if (alrm->enabled) { +			rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF); +			val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); +			writel(val | SOC_RTC_ALARM1_MASK, +			       rtc->regs_soc + SOC_RTC_INTERRUPT); +	} + +	spin_unlock_irqrestore(&rtc->lock, flags); + +out: +	return ret; +} + +static int armada38x_rtc_alarm_irq_enable(struct device *dev, +					 unsigned int enabled) +{ +	struct armada38x_rtc *rtc = dev_get_drvdata(dev); +	unsigned long flags; + +	spin_lock_irqsave(&rtc->lock, flags); + +	if (enabled) +		rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF); +	else +		rtc_delayed_write(0, rtc, RTC_IRQ1_CONF); + +	spin_unlock_irqrestore(&rtc->lock, flags); + +	return 0; +} + +static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data) +{ +	struct armada38x_rtc *rtc = data; +	u32 val; +	int event = RTC_IRQF | RTC_AF; + +	dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq); + +	spin_lock(&rtc->lock); + +	val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); + +	writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT); +	val = readl(rtc->regs + RTC_IRQ1_CONF); +	/* disable all the interrupts for alarm 1 */ +	rtc_delayed_write(0, rtc, RTC_IRQ1_CONF); +	/* Ack the event */ +	rtc_delayed_write(RTC_STATUS_ALARM1, rtc, RTC_STATUS); + +	spin_unlock(&rtc->lock); + +	if (val & RTC_IRQ1_FREQ_EN) { +		if (val & RTC_IRQ1_FREQ_1HZ) +			event |= RTC_UF; +		else +			event |= RTC_PF; +	} + +	rtc_update_irq(rtc->rtc_dev, 1, event); + +	return IRQ_HANDLED; +} + +static struct rtc_class_ops armada38x_rtc_ops = { +	.read_time = armada38x_rtc_read_time, +	.set_time = armada38x_rtc_set_time, +	.read_alarm = armada38x_rtc_read_alarm, +	.set_alarm = armada38x_rtc_set_alarm, +	.alarm_irq_enable = armada38x_rtc_alarm_irq_enable, +}; + +static __init int armada38x_rtc_probe(struct platform_device *pdev) +{ +	struct resource *res; +	struct armada38x_rtc *rtc; +	int ret; + +	rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc), +			    GFP_KERNEL); +	if (!rtc) +		return -ENOMEM; + +	spin_lock_init(&rtc->lock); + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); +	rtc->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(rtc->regs)) +		return PTR_ERR(rtc->regs); +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc"); +	rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(rtc->regs_soc)) +		return PTR_ERR(rtc->regs_soc); + +	rtc->irq = platform_get_irq(pdev, 0); + +	if (rtc->irq < 0) { +		dev_err(&pdev->dev, "no irq\n"); +		return rtc->irq; +	} +	if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq, +				0, pdev->name, rtc) < 0) { +		dev_warn(&pdev->dev, "Interrupt not available.\n"); +		rtc->irq = -1; +		/* +		 * If there is no interrupt available then we can't +		 * use the alarm +		 */ +		armada38x_rtc_ops.set_alarm = NULL; +		armada38x_rtc_ops.alarm_irq_enable = NULL; +	} +	platform_set_drvdata(pdev, rtc); +	if (rtc->irq != -1) +		device_init_wakeup(&pdev->dev, 1); + +	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, +					&armada38x_rtc_ops, THIS_MODULE); +	if (IS_ERR(rtc->rtc_dev)) { +		ret = PTR_ERR(rtc->rtc_dev); +		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); +		return ret; +	} +	return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int armada38x_rtc_suspend(struct device *dev) +{ +	if (device_may_wakeup(dev)) { +		struct armada38x_rtc *rtc = dev_get_drvdata(dev); + +		return enable_irq_wake(rtc->irq); +	} + +	return 0; +} + +static int armada38x_rtc_resume(struct device *dev) +{ +	if (device_may_wakeup(dev)) { +		struct armada38x_rtc *rtc = dev_get_drvdata(dev); + +		return disable_irq_wake(rtc->irq); +	} + +	return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops, +			 armada38x_rtc_suspend, armada38x_rtc_resume); + +#ifdef CONFIG_OF +static const struct of_device_id armada38x_rtc_of_match_table[] = { +	{ .compatible = "marvell,armada-380-rtc", }, +	{} +}; +#endif + +static struct platform_driver armada38x_rtc_driver = { +	.driver		= { +		.name	= "armada38x-rtc", +		.pm	= &armada38x_rtc_pm_ops, +		.of_match_table = of_match_ptr(armada38x_rtc_of_match_table), +	}, +}; + +module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe); + +MODULE_DESCRIPTION("Marvell Armada 38x RTC driver"); +MODULE_AUTHOR("Gregory CLEMENT <[email protected]>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 6b9aaf1afc72..2183fd2750ab 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -313,7 +313,7 @@ static const struct rtc_class_ops at91_rtc_ops = {  	.alarm_irq_enable = at91_rtc_alarm_irq_enable,  }; -static struct regmap_config gpbr_regmap_config = { +static const struct regmap_config gpbr_regmap_config = {  	.reg_bits = 32,  	.val_bits = 32,  	.reg_stride = 4, diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index d04939369251..799c34bcb26f 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -304,12 +304,12 @@ static long rtc_dev_ioctl(struct file *file,  		 * Not supported here.  		 */  		{ -			unsigned long now, then; +			time64_t now, then;  			err = rtc_read_time(rtc, &tm);  			if (err < 0)  				return err; -			rtc_tm_to_time(&tm, &now); +			now = rtc_tm_to_time64(&tm);  			alarm.time.tm_mday = tm.tm_mday;  			alarm.time.tm_mon = tm.tm_mon; @@ -317,11 +317,11 @@ static long rtc_dev_ioctl(struct file *file,  			err  = rtc_valid_tm(&alarm.time);  			if (err < 0)  				return err; -			rtc_tm_to_time(&alarm.time, &then); +			then = rtc_tm_to_time64(&alarm.time);  			/* alarm may need to wrap into tomorrow */  			if (then < now) { -				rtc_time_to_tm(now + 24 * 60 * 60, &tm); +				rtc_time64_to_tm(now + 24 * 60 * 60, &tm);  				alarm.time.tm_mday = tm.tm_mday;  				alarm.time.tm_mon = tm.tm_mon;  				alarm.time.tm_year = tm.tm_year; diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index b37b0c80bd5a..cb989cd00b14 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -218,6 +218,7 @@ static int __init efi_rtc_probe(struct platform_device *dev)  	if (IS_ERR(rtc))  		return PTR_ERR(rtc); +	rtc->uie_unsupported = 1;  	platform_set_drvdata(dev, rtc);  	return 0; diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 42f5570f42f8..c666eab98273 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -50,22 +50,58 @@  #define DCAMR_UNSET  0xFFFFFFFF  /* doomsday - 1 sec */  #define DCR       0x10           /* Control Reg */ +#define DCR_TDCHL (1 << 30)      /* Tamper-detect configuration hard lock */ +#define DCR_TDCSL (1 << 29)      /* Tamper-detect configuration soft lock */ +#define DCR_KSSL  (1 << 27)      /* Key-select soft lock */ +#define DCR_MCHL  (1 << 20)      /* Monotonic-counter hard lock */ +#define DCR_MCSL  (1 << 19)      /* Monotonic-counter soft lock */ +#define DCR_TCHL  (1 << 18)      /* Timer-counter hard lock */ +#define DCR_TCSL  (1 << 17)      /* Timer-counter soft lock */ +#define DCR_FSHL  (1 << 16)      /* Failure state hard lock */  #define DCR_TCE   (1 << 3)       /* Time Counter Enable */ +#define DCR_MCE   (1 << 2)       /* Monotonic Counter Enable */  #define DSR       0x14           /* Status Reg */ -#define DSR_WBF   (1 << 10)      /* Write Busy Flag */ -#define DSR_WNF   (1 << 9)       /* Write Next Flag */ -#define DSR_WCF   (1 << 8)       /* Write Complete Flag */ +#define DSR_WTD   (1 << 23)      /* Wire-mesh tamper detected */ +#define DSR_ETBD  (1 << 22)      /* External tamper B detected */ +#define DSR_ETAD  (1 << 21)      /* External tamper A detected */ +#define DSR_EBD   (1 << 20)      /* External boot detected */ +#define DSR_SAD   (1 << 19)      /* SCC alarm detected */ +#define DSR_TTD   (1 << 18)      /* Temperatur tamper detected */ +#define DSR_CTD   (1 << 17)      /* Clock tamper detected */ +#define DSR_VTD   (1 << 16)      /* Voltage tamper detected */ +#define DSR_WBF   (1 << 10)      /* Write Busy Flag (synchronous) */ +#define DSR_WNF   (1 << 9)       /* Write Next Flag (synchronous) */ +#define DSR_WCF   (1 << 8)       /* Write Complete Flag (synchronous)*/  #define DSR_WEF   (1 << 7)       /* Write Error Flag */  #define DSR_CAF   (1 << 4)       /* Clock Alarm Flag */ +#define DSR_MCO   (1 << 3)       /* monotonic counter overflow */ +#define DSR_TCO   (1 << 2)       /* time counter overflow */  #define DSR_NVF   (1 << 1)       /* Non-Valid Flag */  #define DSR_SVF   (1 << 0)       /* Security Violation Flag */ -#define DIER      0x18           /* Interrupt Enable Reg */ +#define DIER      0x18           /* Interrupt Enable Reg (synchronous) */  #define DIER_WNIE (1 << 9)       /* Write Next Interrupt Enable */  #define DIER_WCIE (1 << 8)       /* Write Complete Interrupt Enable */  #define DIER_WEIE (1 << 7)       /* Write Error Interrupt Enable */  #define DIER_CAIE (1 << 4)       /* Clock Alarm Interrupt Enable */ +#define DIER_SVIE (1 << 0)       /* Security-violation Interrupt Enable */ + +#define DMCR      0x1c           /* DryIce Monotonic Counter Reg */ + +#define DTCR      0x28           /* DryIce Tamper Configuration Reg */ +#define DTCR_MOE  (1 << 9)       /* monotonic overflow enabled */ +#define DTCR_TOE  (1 << 8)       /* time overflow enabled */ +#define DTCR_WTE  (1 << 7)       /* wire-mesh tamper enabled */ +#define DTCR_ETBE (1 << 6)       /* external B tamper enabled */ +#define DTCR_ETAE (1 << 5)       /* external A tamper enabled */ +#define DTCR_EBE  (1 << 4)       /* external boot tamper enabled */ +#define DTCR_SAIE (1 << 3)       /* SCC enabled */ +#define DTCR_TTE  (1 << 2)       /* temperature tamper enabled */ +#define DTCR_CTE  (1 << 1)       /* clock tamper enabled */ +#define DTCR_VTE  (1 << 0)       /* voltage tamper enabled */ + +#define DGPR      0x3c           /* DryIce General Purpose Reg */  /**   * struct imxdi_dev - private imxdi rtc data @@ -313,7 +349,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)  	dier = __raw_readl(imxdi->ioaddr + DIER);  	/* handle write complete and write error cases */ -	if ((dier & DIER_WCIE)) { +	if (dier & DIER_WCIE) {  		/*If the write wait queue is empty then there is no pending  		  operations. It means the interrupt is for DryIce -Security.  		  IRQ must be returned as none.*/ @@ -322,7 +358,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)  		/* DSR_WCF clears itself on DSR read */  		dsr = __raw_readl(imxdi->ioaddr + DSR); -		if ((dsr & (DSR_WCF | DSR_WEF))) { +		if (dsr & (DSR_WCF | DSR_WEF)) {  			/* mask the interrupt */  			di_int_disable(imxdi, DIER_WCIE); @@ -335,7 +371,7 @@ static irqreturn_t dryice_norm_irq(int irq, void *dev_id)  	}  	/* handle the alarm case */ -	if ((dier & DIER_CAIE)) { +	if (dier & DIER_CAIE) {  		/* DSR_WCF clears itself on DSR read */  		dsr = __raw_readl(imxdi->ioaddr + DSR);  		if (dsr & DSR_CAF) { diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c index 6e1fcfb5d7e6..b8f862953f7f 100644 --- a/drivers/rtc/rtc-isl12057.c +++ b/drivers/rtc/rtc-isl12057.c @@ -79,8 +79,10 @@  #define ISL12057_MEM_MAP_LEN	0x10  struct isl12057_rtc_data { +	struct rtc_device *rtc;  	struct regmap *regmap;  	struct mutex lock; +	int irq;  };  static void isl12057_rtc_regs_to_tm(struct rtc_time *tm, u8 *regs) @@ -160,14 +162,47 @@ static int isl12057_i2c_validate_chip(struct regmap *regmap)  	return 0;  } -static int isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm) +static int _isl12057_rtc_clear_alarm(struct device *dev) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	ret = regmap_update_bits(data->regmap, ISL12057_REG_SR, +				 ISL12057_REG_SR_A1F, 0); +	if (ret) +		dev_err(dev, "%s: clearing alarm failed (%d)\n", __func__, ret); + +	return ret; +} + +static int _isl12057_rtc_update_alarm(struct device *dev, int enable) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	ret = regmap_update_bits(data->regmap, ISL12057_REG_INT, +				 ISL12057_REG_INT_A1IE, +				 enable ? ISL12057_REG_INT_A1IE : 0); +	if (ret) +		dev_err(dev, "%s: changing alarm interrupt flag failed (%d)\n", +			__func__, ret); + +	return ret; +} + +/* + * Note: as we only read from device and do not perform any update, there is + * no need for an equivalent function which would try and get driver's main + * lock. Here, it is safe for everyone if we just use regmap internal lock + * on the device when reading. + */ +static int _isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)  {  	struct isl12057_rtc_data *data = dev_get_drvdata(dev);  	u8 regs[ISL12057_RTC_SEC_LEN];  	unsigned int sr;  	int ret; -	mutex_lock(&data->lock);  	ret = regmap_read(data->regmap, ISL12057_REG_SR, &sr);  	if (ret) {  		dev_err(dev, "%s: unable to read oscillator status flag (%d)\n", @@ -187,8 +222,6 @@ static int isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)  			__func__, ret);  out: -	mutex_unlock(&data->lock); -  	if (ret)  		return ret; @@ -197,6 +230,168 @@ out:  	return rtc_valid_tm(tm);  } +static int isl12057_rtc_update_alarm(struct device *dev, int enable) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); +	int ret; + +	mutex_lock(&data->lock); +	ret = _isl12057_rtc_update_alarm(dev, enable); +	mutex_unlock(&data->lock); + +	return ret; +} + +static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); +	struct rtc_time rtc_tm, *alarm_tm = &alarm->time; +	unsigned long rtc_secs, alarm_secs; +	u8 regs[ISL12057_A1_SEC_LEN]; +	unsigned int ir; +	int ret; + +	mutex_lock(&data->lock); +	ret = regmap_bulk_read(data->regmap, ISL12057_REG_A1_SC, regs, +			       ISL12057_A1_SEC_LEN); +	if (ret) { +		dev_err(dev, "%s: reading alarm section failed (%d)\n", +			__func__, ret); +		goto err_unlock; +	} + +	alarm_tm->tm_sec  = bcd2bin(regs[0] & 0x7f); +	alarm_tm->tm_min  = bcd2bin(regs[1] & 0x7f); +	alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f); +	alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f); +	alarm_tm->tm_wday = -1; + +	/* +	 * The alarm section does not store year/month. We use the ones in rtc +	 * section as a basis and increment month and then year if needed to get +	 * alarm after current time. +	 */ +	ret = _isl12057_rtc_read_time(dev, &rtc_tm); +	if (ret) +		goto err_unlock; + +	alarm_tm->tm_year = rtc_tm.tm_year; +	alarm_tm->tm_mon = rtc_tm.tm_mon; + +	ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +	if (ret) +		goto err_unlock; + +	ret = rtc_tm_to_time(alarm_tm, &alarm_secs); +	if (ret) +		goto err_unlock; + +	if (alarm_secs < rtc_secs) { +		if (alarm_tm->tm_mon == 11) { +			alarm_tm->tm_mon = 0; +			alarm_tm->tm_year += 1; +		} else { +			alarm_tm->tm_mon += 1; +		} +	} + +	ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir); +	if (ret) { +		dev_err(dev, "%s: reading alarm interrupt flag failed (%d)\n", +			__func__, ret); +		goto err_unlock; +	} + +	alarm->enabled = !!(ir & ISL12057_REG_INT_A1IE); + +err_unlock: +	mutex_unlock(&data->lock); + +	return ret; +} + +static int isl12057_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); +	struct rtc_time *alarm_tm = &alarm->time; +	unsigned long rtc_secs, alarm_secs; +	u8 regs[ISL12057_A1_SEC_LEN]; +	struct rtc_time rtc_tm; +	int ret, enable = 1; + +	mutex_lock(&data->lock); +	ret = _isl12057_rtc_read_time(dev, &rtc_tm); +	if (ret) +		goto err_unlock; + +	ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +	if (ret) +		goto err_unlock; + +	ret = rtc_tm_to_time(alarm_tm, &alarm_secs); +	if (ret) +		goto err_unlock; + +	/* If alarm time is before current time, disable the alarm */ +	if (!alarm->enabled || alarm_secs <= rtc_secs) { +		enable = 0; +	} else { +		/* +		 * Chip only support alarms up to one month in the future. Let's +		 * return an error if we get something after that limit. +		 * Comparison is done by incrementing rtc_tm month field by one +		 * and checking alarm value is still below. +		 */ +		if (rtc_tm.tm_mon == 11) { /* handle year wrapping */ +			rtc_tm.tm_mon = 0; +			rtc_tm.tm_year += 1; +		} else { +			rtc_tm.tm_mon += 1; +		} + +		ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); +		if (ret) +			goto err_unlock; + +		if (alarm_secs > rtc_secs) { +			dev_err(dev, "%s: max for alarm is one month (%d)\n", +				__func__, ret); +			ret = -EINVAL; +			goto err_unlock; +		} +	} + +	/* Disable the alarm before modifying it */ +	ret = _isl12057_rtc_update_alarm(dev, 0); +	if (ret < 0) { +		dev_err(dev, "%s: unable to disable the alarm (%d)\n", +			__func__, ret); +		goto err_unlock; +	} + +	/* Program alarm registers */ +	regs[0] = bin2bcd(alarm_tm->tm_sec) & 0x7f; +	regs[1] = bin2bcd(alarm_tm->tm_min) & 0x7f; +	regs[2] = bin2bcd(alarm_tm->tm_hour) & 0x3f; +	regs[3] = bin2bcd(alarm_tm->tm_mday) & 0x3f; + +	ret = regmap_bulk_write(data->regmap, ISL12057_REG_A1_SC, regs, +				ISL12057_A1_SEC_LEN); +	if (ret < 0) { +		dev_err(dev, "%s: writing alarm section failed (%d)\n", +			__func__, ret); +		goto err_unlock; +	} + +	/* Enable or disable alarm */ +	ret = _isl12057_rtc_update_alarm(dev, enable); + +err_unlock: +	mutex_unlock(&data->lock); + +	return ret; +} +  static int isl12057_rtc_set_time(struct device *dev, struct rtc_time *tm)  {  	struct isl12057_rtc_data *data = dev_get_drvdata(dev); @@ -262,12 +457,85 @@ static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)  	return 0;  } +#ifdef CONFIG_OF +/* + * One would expect the device to be marked as a wakeup source only + * when an IRQ pin of the RTC is routed to an interrupt line of the + * CPU. In practice, such an IRQ pin can be connected to a PMIC and + * this allows the device to be powered up when RTC alarm rings. This + * is for instance the case on ReadyNAS 102, 104 and 2120. On those + * devices with no IRQ driectly connected to the SoC, the RTC chip + * can be forced as a wakeup source by stating that explicitly in + * the device's .dts file using the "isil,irq2-can-wakeup-machine" + * boolean property. This will guarantee 'wakealarm' sysfs entry is + * available on the device. + * + * The function below returns 1, i.e. the capability of the chip to + * wakeup the device, based on IRQ availability or if the boolean + * property has been set in the .dts file. Otherwise, it returns 0. + */ + +static bool isl12057_can_wakeup_machine(struct device *dev) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); + +	return (data->irq || of_property_read_bool(dev->of_node, +					      "isil,irq2-can-wakeup-machine")); +} +#else +static bool isl12057_can_wakeup_machine(struct device *dev) +{ +	struct isl12057_rtc_data *data = dev_get_drvdata(dev); + +	return !!data->irq; +} +#endif + +static int isl12057_rtc_alarm_irq_enable(struct device *dev, +					 unsigned int enable) +{ +	struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev); +	int ret = -ENOTTY; + +	if (rtc_data->irq) +		ret = isl12057_rtc_update_alarm(dev, enable); + +	return ret; +} + +static irqreturn_t isl12057_rtc_interrupt(int irq, void *data) +{ +	struct i2c_client *client = data; +	struct isl12057_rtc_data *rtc_data = dev_get_drvdata(&client->dev); +	struct rtc_device *rtc = rtc_data->rtc; +	int ret, handled = IRQ_NONE; +	unsigned int sr; + +	ret = regmap_read(rtc_data->regmap, ISL12057_REG_SR, &sr); +	if (!ret && (sr & ISL12057_REG_SR_A1F)) { +		dev_dbg(&client->dev, "RTC alarm!\n"); + +		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); + +		/* Acknowledge and disable the alarm */ +		_isl12057_rtc_clear_alarm(&client->dev); +		_isl12057_rtc_update_alarm(&client->dev, 0); + +		handled = IRQ_HANDLED; +	} + +	return handled; +} +  static const struct rtc_class_ops rtc_ops = { -	.read_time = isl12057_rtc_read_time, +	.read_time = _isl12057_rtc_read_time,  	.set_time = isl12057_rtc_set_time, +	.read_alarm = isl12057_rtc_read_alarm, +	.set_alarm = isl12057_rtc_set_alarm, +	.alarm_irq_enable = isl12057_rtc_alarm_irq_enable,  }; -static struct regmap_config isl12057_rtc_regmap_config = { +static const struct regmap_config isl12057_rtc_regmap_config = {  	.reg_bits = 8,  	.val_bits = 8,  }; @@ -277,7 +545,6 @@ static int isl12057_probe(struct i2c_client *client,  {  	struct device *dev = &client->dev;  	struct isl12057_rtc_data *data; -	struct rtc_device *rtc;  	struct regmap *regmap;  	int ret; @@ -310,9 +577,70 @@ static int isl12057_probe(struct i2c_client *client,  	data->regmap = regmap;  	dev_set_drvdata(dev, data); -	rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE); -	return PTR_ERR_OR_ZERO(rtc); +	if (client->irq > 0) { +		ret = devm_request_threaded_irq(dev, client->irq, NULL, +						isl12057_rtc_interrupt, +						IRQF_SHARED|IRQF_ONESHOT, +						DRV_NAME, client); +		if (!ret) +			data->irq = client->irq; +		else +			dev_err(dev, "%s: irq %d unavailable (%d)\n", __func__, +				client->irq, ret); +	} + +	if (isl12057_can_wakeup_machine(dev)) +		device_init_wakeup(dev, true); + +	data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, +					     THIS_MODULE); +	ret = PTR_ERR_OR_ZERO(data->rtc); +	if (ret) { +		dev_err(dev, "%s: unable to register RTC device (%d)\n", +			__func__, ret); +		goto err; +	} + +	/* We cannot support UIE mode if we do not have an IRQ line */ +	if (!data->irq) +		data->rtc->uie_unsupported = 1; + +err: +	return ret; +} + +static int isl12057_remove(struct i2c_client *client) +{ +	if (isl12057_can_wakeup_machine(&client->dev)) +		device_init_wakeup(&client->dev, false); + +	return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int isl12057_rtc_suspend(struct device *dev) +{ +	struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev); + +	if (rtc_data->irq && device_may_wakeup(dev)) +		return enable_irq_wake(rtc_data->irq); + +	return 0; +} + +static int isl12057_rtc_resume(struct device *dev) +{ +	struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev); + +	if (rtc_data->irq && device_may_wakeup(dev)) +		return disable_irq_wake(rtc_data->irq); + +	return 0;  } +#endif + +static SIMPLE_DEV_PM_OPS(isl12057_rtc_pm_ops, isl12057_rtc_suspend, +			 isl12057_rtc_resume);  #ifdef CONFIG_OF  static const struct of_device_id isl12057_dt_match[] = { @@ -331,9 +659,11 @@ static struct i2c_driver isl12057_driver = {  	.driver = {  		.name = DRV_NAME,  		.owner = THIS_MODULE, +		.pm = &isl12057_rtc_pm_ops,  		.of_match_table = of_match_ptr(isl12057_dt_match),  	},  	.probe	  = isl12057_probe, +	.remove	  = isl12057_remove,  	.id_table = isl12057_id,  };  module_i2c_driver(isl12057_driver); diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index d1953bb244c5..8a7556cbcb7f 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -38,6 +38,7 @@  #include <linux/errno.h>  #include <linux/init.h>  #include <linux/kernel.h> +#include <linux/of.h>  #include <linux/string.h>  #include <linux/slab.h>  #include <linux/rtc.h> @@ -340,10 +341,19 @@ static int pcf2123_remove(struct spi_device *spi)  	return 0;  } +#ifdef CONFIG_OF +static const struct of_device_id pcf2123_dt_ids[] = { +	{ .compatible = "nxp,rtc-pcf2123", }, +	{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, pcf2123_dt_ids); +#endif +  static struct spi_driver pcf2123_driver = {  	.driver	= {  			.name	= "rtc-pcf2123",  			.owner	= THIS_MODULE, +			.of_match_table = of_match_ptr(pcf2123_dt_ids),  	},  	.probe	= pcf2123_probe,  	.remove	= pcf2123_remove, diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index df42257668ac..91ca0bc1b484 100644 --- a/drivers/rtc/rtc-rk808.c +++ b/drivers/rtc/rtc-rk808.c @@ -67,15 +67,21 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)  	/* Force an update of the shadowed registers right now */  	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,  				 BIT_RTC_CTRL_REG_RTC_GET_TIME, -				 0); +				 BIT_RTC_CTRL_REG_RTC_GET_TIME);  	if (ret) {  		dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);  		return ret;  	} +	/* +	 * After we set the GET_TIME bit, the rtc time can't be read +	 * immediately. So we should wait up to 31.25 us, about one cycle of +	 * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer +	 * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency. +	 */  	ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG,  				 BIT_RTC_CTRL_REG_RTC_GET_TIME, -				 BIT_RTC_CTRL_REG_RTC_GET_TIME); +				 0);  	if (ret) {  		dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret);  		return ret; diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index b5e7c4670205..89ac1d5083c6 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -832,6 +832,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);  static const struct platform_device_id s5m_rtc_id[] = {  	{ "s5m-rtc",		S5M8767X },  	{ "s2mps14-rtc",	S2MPS14X }, +	{ },  };  static struct platform_driver s5m_rtc_driver = { diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index bf3e242ccc5c..eb71872d0361 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -20,16 +20,16 @@   *   * If temporary failure is indicated the caller should try again 'soon'   */ -int rtc_set_ntp_time(struct timespec now) +int rtc_set_ntp_time(struct timespec64 now)  {  	struct rtc_device *rtc;  	struct rtc_time tm;  	int err = -ENODEV;  	if (now.tv_nsec < (NSEC_PER_SEC >> 1)) -		rtc_time_to_tm(now.tv_sec, &tm); +		rtc_time64_to_tm(now.tv_sec, &tm);  	else -		rtc_time_to_tm(now.tv_sec + 1, &tm); +		rtc_time64_to_tm(now.tv_sec + 1, &tm);  	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);  	if (rtc) { |