diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2018-06-22 21:20:35 +0200 | 
| commit | 7731b8bc94e599c9a79e428f3359ff2c34b7576a (patch) | |
| tree | 879f18ccbe274122f2d4f095b43cbc7f953e0ada /drivers/rtc/rtc-stm32.c | |
| parent | 48e315618dc4dc8904182cd221e3d395d5d97005 (diff) | |
| parent | 9ffc59d57228d74809700be6f7ecb1db10292f05 (diff) | |
Merge branch 'linus' into x86/urgent
Required to queue a dependent fix.
Diffstat (limited to 'drivers/rtc/rtc-stm32.c')
| -rw-r--r-- | drivers/rtc/rtc-stm32.c | 339 | 
1 files changed, 249 insertions, 90 deletions
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index f25dabe8fd02..c5908cfea234 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0  /* - * Copyright (C) STMicroelectronics SA 2017 - * Author:  Amelie Delaunay <amelie.delaunay@st.com> for STMicroelectronics. - * License terms:  GNU General Public License (GPL), version 2 + * Copyright (C) STMicroelectronics 2017 + * Author:  Amelie Delaunay <amelie.delaunay@st.com>   */  #include <linux/bcd.h> @@ -11,20 +11,12 @@  #include <linux/mfd/syscon.h>  #include <linux/module.h>  #include <linux/of_device.h> +#include <linux/pm_wakeirq.h>  #include <linux/regmap.h>  #include <linux/rtc.h>  #define DRIVER_NAME "stm32_rtc" -/* STM32 RTC registers */ -#define STM32_RTC_TR		0x00 -#define STM32_RTC_DR		0x04 -#define STM32_RTC_CR		0x08 -#define STM32_RTC_ISR		0x0C -#define STM32_RTC_PRER		0x10 -#define STM32_RTC_ALRMAR	0x1C -#define STM32_RTC_WPR		0x24 -  /* STM32_RTC_TR bit fields  */  #define STM32_RTC_TR_SEC_SHIFT		0  #define STM32_RTC_TR_SEC		GENMASK(6, 0) @@ -48,7 +40,7 @@  #define STM32_RTC_CR_ALRAE		BIT(8)  #define STM32_RTC_CR_ALRAIE		BIT(12) -/* STM32_RTC_ISR bit fields */ +/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */  #define STM32_RTC_ISR_ALRAWF		BIT(0)  #define STM32_RTC_ISR_INITS		BIT(4)  #define STM32_RTC_ISR_RSF		BIT(5) @@ -80,52 +72,87 @@  #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)  #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31) +/* STM32_RTC_SR/_SCR bit fields */ +#define STM32_RTC_SR_ALRA		BIT(0) + +/* STM32_RTC_VERR bit fields */ +#define STM32_RTC_VERR_MINREV_SHIFT	0 +#define STM32_RTC_VERR_MINREV		GENMASK(3, 0) +#define STM32_RTC_VERR_MAJREV_SHIFT	4 +#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4) +  /* STM32_RTC_WPR key constants */  #define RTC_WPR_1ST_KEY			0xCA  #define RTC_WPR_2ND_KEY			0x53  #define RTC_WPR_WRONG_KEY		0xFF -/* - * RTC registers are protected against parasitic write access. - * PWR_CR_DBP bit must be set to enable write access to RTC registers. - */ -/* STM32_PWR_CR */ -#define PWR_CR				0x00 -/* STM32_PWR_CR bit field */ -#define PWR_CR_DBP			BIT(8) +/* Max STM32 RTC register offset is 0x3FC */ +#define UNDEF_REG			0xFFFF + +struct stm32_rtc; + +struct stm32_rtc_registers { +	u16 tr; +	u16 dr; +	u16 cr; +	u16 isr; +	u16 prer; +	u16 alrmar; +	u16 wpr; +	u16 sr; +	u16 scr; +	u16 verr; +}; + +struct stm32_rtc_events { +	u32 alra; +};  struct stm32_rtc_data { +	const struct stm32_rtc_registers regs; +	const struct stm32_rtc_events events; +	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);  	bool has_pclk; +	bool need_dbp; +	bool has_wakeirq;  };  struct stm32_rtc {  	struct rtc_device *rtc_dev;  	void __iomem *base;  	struct regmap *dbp; -	struct stm32_rtc_data *data; +	unsigned int dbp_reg; +	unsigned int dbp_mask;  	struct clk *pclk;  	struct clk *rtc_ck; +	const struct stm32_rtc_data *data;  	int irq_alarm; +	int wakeirq_alarm;  };  static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)  { -	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR); -	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR); +	const struct stm32_rtc_registers *regs = &rtc->data->regs; + +	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs->wpr); +	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs->wpr);  }  static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)  { -	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR); +	const struct stm32_rtc_registers *regs = &rtc->data->regs; + +	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);  }  static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)  { -	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR); +	const struct stm32_rtc_registers *regs = &rtc->data->regs; +	unsigned int isr = readl_relaxed(rtc->base + regs->isr);  	if (!(isr & STM32_RTC_ISR_INITF)) {  		isr |= STM32_RTC_ISR_INIT; -		writel_relaxed(isr, rtc->base + STM32_RTC_ISR); +		writel_relaxed(isr, rtc->base + regs->isr);  		/*  		 * It takes around 2 rtc_ck clock cycles to enter in @@ -134,7 +161,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)  		 * 1MHz, we poll every 10 us with a timeout of 100ms.  		 */  		return readl_relaxed_poll_timeout_atomic( -					rtc->base + STM32_RTC_ISR, +					rtc->base + regs->isr,  					isr, (isr & STM32_RTC_ISR_INITF),  					10, 100000);  	} @@ -144,40 +171,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)  static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)  { -	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR); +	const struct stm32_rtc_registers *regs = &rtc->data->regs; +	unsigned int isr = readl_relaxed(rtc->base + regs->isr);  	isr &= ~STM32_RTC_ISR_INIT; -	writel_relaxed(isr, rtc->base + STM32_RTC_ISR); +	writel_relaxed(isr, rtc->base + regs->isr);  }  static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)  { -	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR); +	const struct stm32_rtc_registers *regs = &rtc->data->regs; +	unsigned int isr = readl_relaxed(rtc->base + regs->isr);  	isr &= ~STM32_RTC_ISR_RSF; -	writel_relaxed(isr, rtc->base + STM32_RTC_ISR); +	writel_relaxed(isr, rtc->base + regs->isr);  	/*  	 * Wait for RSF to be set to ensure the calendar registers are  	 * synchronised, it takes around 2 rtc_ck clock cycles  	 */ -	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR, +	return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,  						 isr,  						 (isr & STM32_RTC_ISR_RSF),  						 10, 100000);  } +static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc, +					unsigned int flags) +{ +	rtc->data->clear_events(rtc, flags); +} +  static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)  {  	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id; -	unsigned int isr, cr; +	const struct stm32_rtc_registers *regs = &rtc->data->regs; +	const struct stm32_rtc_events *evts = &rtc->data->events; +	unsigned int status, cr;  	mutex_lock(&rtc->rtc_dev->ops_lock); -	isr = readl_relaxed(rtc->base + STM32_RTC_ISR); -	cr = readl_relaxed(rtc->base + STM32_RTC_CR); +	status = readl_relaxed(rtc->base + regs->sr); +	cr = readl_relaxed(rtc->base + regs->cr); -	if ((isr & STM32_RTC_ISR_ALRAF) && +	if ((status & evts->alra) &&  	    (cr & STM32_RTC_CR_ALRAIE)) {  		/* Alarm A flag - Alarm interrupt */  		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n"); @@ -185,9 +222,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)  		/* Pass event to the kernel */  		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); -		/* Clear event flag, otherwise new events won't be received */ -		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF, -			       rtc->base + STM32_RTC_ISR); +		/* Clear event flags, otherwise new events won't be received */ +		stm32_rtc_clear_event_flags(rtc, evts->alra);  	}  	mutex_unlock(&rtc->rtc_dev->ops_lock); @@ -234,11 +270,12 @@ static void bcd2tm(struct rtc_time *tm)  static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)  {  	struct stm32_rtc *rtc = dev_get_drvdata(dev); +	const struct stm32_rtc_registers *regs = &rtc->data->regs;  	unsigned int tr, dr;  	/* Time and Date in BCD format */ -	tr = readl_relaxed(rtc->base + STM32_RTC_TR); -	dr = readl_relaxed(rtc->base + STM32_RTC_DR); +	tr = readl_relaxed(rtc->base + regs->tr); +	dr = readl_relaxed(rtc->base + regs->dr);  	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;  	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT; @@ -259,6 +296,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)  static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)  {  	struct stm32_rtc *rtc = dev_get_drvdata(dev); +	const struct stm32_rtc_registers *regs = &rtc->data->regs;  	unsigned int tr, dr;  	int ret = 0; @@ -283,8 +321,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)  		goto end;  	} -	writel_relaxed(tr, rtc->base + STM32_RTC_TR); -	writel_relaxed(dr, rtc->base + STM32_RTC_DR); +	writel_relaxed(tr, rtc->base + regs->tr); +	writel_relaxed(dr, rtc->base + regs->dr);  	stm32_rtc_exit_init_mode(rtc); @@ -298,12 +336,14 @@ end:  static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  {  	struct stm32_rtc *rtc = dev_get_drvdata(dev); +	const struct stm32_rtc_registers *regs = &rtc->data->regs; +	const struct stm32_rtc_events *evts = &rtc->data->events;  	struct rtc_time *tm = &alrm->time; -	unsigned int alrmar, cr, isr; +	unsigned int alrmar, cr, status; -	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR); -	cr = readl_relaxed(rtc->base + STM32_RTC_CR); -	isr = readl_relaxed(rtc->base + STM32_RTC_ISR); +	alrmar = readl_relaxed(rtc->base + regs->alrmar); +	cr = readl_relaxed(rtc->base + regs->cr); +	status = readl_relaxed(rtc->base + regs->sr);  	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {  		/* @@ -356,7 +396,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	bcd2tm(tm);  	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0; -	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0; +	alrm->pending = (status & evts->alra) ? 1 : 0;  	return 0;  } @@ -364,9 +404,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)  {  	struct stm32_rtc *rtc = dev_get_drvdata(dev); -	unsigned int isr, cr; +	const struct stm32_rtc_registers *regs = &rtc->data->regs; +	const struct stm32_rtc_events *evts = &rtc->data->events; +	unsigned int cr; -	cr = readl_relaxed(rtc->base + STM32_RTC_CR); +	cr = readl_relaxed(rtc->base + regs->cr);  	stm32_rtc_wpr_unlock(rtc); @@ -375,12 +417,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)  		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);  	else  		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE); -	writel_relaxed(cr, rtc->base + STM32_RTC_CR); +	writel_relaxed(cr, rtc->base + regs->cr); -	/* Clear event flag, otherwise new events won't be received */ -	isr = readl_relaxed(rtc->base + STM32_RTC_ISR); -	isr &= ~STM32_RTC_ISR_ALRAF; -	writel_relaxed(isr, rtc->base + STM32_RTC_ISR); +	/* Clear event flags, otherwise new events won't be received */ +	stm32_rtc_clear_event_flags(rtc, evts->alra);  	stm32_rtc_wpr_lock(rtc); @@ -389,9 +429,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)  static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)  { +	const struct stm32_rtc_registers *regs = &rtc->data->regs;  	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec; -	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR); -	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR); +	unsigned int dr = readl_relaxed(rtc->base + regs->dr); +	unsigned int tr = readl_relaxed(rtc->base + regs->tr);  	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;  	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT; @@ -425,6 +466,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)  static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  {  	struct stm32_rtc *rtc = dev_get_drvdata(dev); +	const struct stm32_rtc_registers *regs = &rtc->data->regs;  	struct rtc_time *tm = &alrm->time;  	unsigned int cr, isr, alrmar;  	int ret = 0; @@ -456,15 +498,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	stm32_rtc_wpr_unlock(rtc);  	/* Disable Alarm */ -	cr = readl_relaxed(rtc->base + STM32_RTC_CR); +	cr = readl_relaxed(rtc->base + regs->cr);  	cr &= ~STM32_RTC_CR_ALRAE; -	writel_relaxed(cr, rtc->base + STM32_RTC_CR); +	writel_relaxed(cr, rtc->base + regs->cr);  	/*  	 * Poll Alarm write flag to be sure that Alarm update is allowed: it  	 * takes around 2 rtc_ck clock cycles  	 */ -	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR, +	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,  						isr,  						(isr & STM32_RTC_ISR_ALRAWF),  						10, 100000); @@ -475,7 +517,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  	}  	/* Write to Alarm register */ -	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR); +	writel_relaxed(alrmar, rtc->base + regs->alrmar);  	if (alrm->enabled)  		stm32_rtc_alarm_irq_enable(dev, 1); @@ -496,17 +538,95 @@ static const struct rtc_class_ops stm32_rtc_ops = {  	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,  }; +static void stm32_rtc_clear_events(struct stm32_rtc *rtc, +				   unsigned int flags) +{ +	const struct stm32_rtc_registers *regs = &rtc->data->regs; + +	/* Flags are cleared by writing 0 in RTC_ISR */ +	writel_relaxed(readl_relaxed(rtc->base + regs->isr) & ~flags, +		       rtc->base + regs->isr); +} +  static const struct stm32_rtc_data stm32_rtc_data = {  	.has_pclk = false, +	.need_dbp = true, +	.has_wakeirq = false, +	.regs = { +		.tr = 0x00, +		.dr = 0x04, +		.cr = 0x08, +		.isr = 0x0C, +		.prer = 0x10, +		.alrmar = 0x1C, +		.wpr = 0x24, +		.sr = 0x0C, /* set to ISR offset to ease alarm management */ +		.scr = UNDEF_REG, +		.verr = UNDEF_REG, +	}, +	.events = { +		.alra = STM32_RTC_ISR_ALRAF, +	}, +	.clear_events = stm32_rtc_clear_events,  };  static const struct stm32_rtc_data stm32h7_rtc_data = {  	.has_pclk = true, +	.need_dbp = true, +	.has_wakeirq = false, +	.regs = { +		.tr = 0x00, +		.dr = 0x04, +		.cr = 0x08, +		.isr = 0x0C, +		.prer = 0x10, +		.alrmar = 0x1C, +		.wpr = 0x24, +		.sr = 0x0C, /* set to ISR offset to ease alarm management */ +		.scr = UNDEF_REG, +		.verr = UNDEF_REG, +	}, +	.events = { +		.alra = STM32_RTC_ISR_ALRAF, +	}, +	.clear_events = stm32_rtc_clear_events, +}; + +static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc, +				      unsigned int flags) +{ +	struct stm32_rtc_registers regs = rtc->data->regs; + +	/* Flags are cleared by writing 1 in RTC_SCR */ +	writel_relaxed(flags, rtc->base + regs.scr); +} + +static const struct stm32_rtc_data stm32mp1_data = { +	.has_pclk = true, +	.need_dbp = false, +	.has_wakeirq = true, +	.regs = { +		.tr = 0x00, +		.dr = 0x04, +		.cr = 0x18, +		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */ +		.prer = 0x10, +		.alrmar = 0x40, +		.wpr = 0x24, +		.sr = 0x50, +		.scr = 0x5C, +		.verr = 0x3F4, +	}, +	.events = { +		.alra = STM32_RTC_SR_ALRA, +	}, +	.clear_events = stm32mp1_rtc_clear_events,  };  static const struct of_device_id stm32_rtc_of_match[] = {  	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },  	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data }, +	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },  	{}  };  MODULE_DEVICE_TABLE(of, stm32_rtc_of_match); @@ -514,6 +634,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);  static int stm32_rtc_init(struct platform_device *pdev,  			  struct stm32_rtc *rtc)  { +	const struct stm32_rtc_registers *regs = &rtc->data->regs;  	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;  	unsigned int rate;  	int ret = 0; @@ -554,14 +675,14 @@ static int stm32_rtc_init(struct platform_device *pdev,  	}  	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S; -	writel_relaxed(prer, rtc->base + STM32_RTC_PRER); +	writel_relaxed(prer, rtc->base + regs->prer);  	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A; -	writel_relaxed(prer, rtc->base + STM32_RTC_PRER); +	writel_relaxed(prer, rtc->base + regs->prer);  	/* Force 24h time format */ -	cr = readl_relaxed(rtc->base + STM32_RTC_CR); +	cr = readl_relaxed(rtc->base + regs->cr);  	cr &= ~STM32_RTC_CR_FMT; -	writel_relaxed(cr, rtc->base + STM32_RTC_CR); +	writel_relaxed(cr, rtc->base + regs->cr);  	stm32_rtc_exit_init_mode(rtc); @@ -575,8 +696,8 @@ end:  static int stm32_rtc_probe(struct platform_device *pdev)  {  	struct stm32_rtc *rtc; +	const struct stm32_rtc_registers *regs;  	struct resource *res; -	const struct of_device_id *match;  	int ret;  	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); @@ -588,15 +709,32 @@ static int stm32_rtc_probe(struct platform_device *pdev)  	if (IS_ERR(rtc->base))  		return PTR_ERR(rtc->base); -	rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -						   "st,syscfg"); -	if (IS_ERR(rtc->dbp)) { -		dev_err(&pdev->dev, "no st,syscfg\n"); -		return PTR_ERR(rtc->dbp); -	} +	rtc->data = (struct stm32_rtc_data *) +		    of_device_get_match_data(&pdev->dev); +	regs = &rtc->data->regs; + +	if (rtc->data->need_dbp) { +		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, +							   "st,syscfg"); +		if (IS_ERR(rtc->dbp)) { +			dev_err(&pdev->dev, "no st,syscfg\n"); +			return PTR_ERR(rtc->dbp); +		} + +		ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg", +						 1, &rtc->dbp_reg); +		if (ret) { +			dev_err(&pdev->dev, "can't read DBP register offset\n"); +			return ret; +		} -	match = of_match_device(stm32_rtc_of_match, &pdev->dev); -	rtc->data = (struct stm32_rtc_data *)match->data; +		ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg", +						 2, &rtc->dbp_mask); +		if (ret) { +			dev_err(&pdev->dev, "can't read DBP register mask\n"); +			return ret; +		} +	}  	if (!rtc->data->has_pclk) {  		rtc->pclk = NULL; @@ -624,11 +762,13 @@ static int stm32_rtc_probe(struct platform_device *pdev)  	if (ret)  		goto err; -	regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP); +	if (rtc->data->need_dbp) +		regmap_update_bits(rtc->dbp, rtc->dbp_reg, +				   rtc->dbp_mask, rtc->dbp_mask);  	/*  	 * After a system reset, RTC_ISR.INITS flag can be read to check if -	 * the calendar has been initalized or not. INITS flag is reset by a +	 * the calendar has been initialized or not. INITS flag is reset by a  	 * power-on reset (no vbat, no power-supply). It is not reset if  	 * rtc_ck parent clock has changed (so RTC prescalers need to be  	 * changed). That's why we cannot rely on this flag to know if RTC @@ -645,15 +785,22 @@ static int stm32_rtc_probe(struct platform_device *pdev)  		goto err;  	} -	platform_set_drvdata(pdev, rtc); -  	ret = device_init_wakeup(&pdev->dev, true); +	if (rtc->data->has_wakeirq) { +		rtc->wakeirq_alarm = platform_get_irq(pdev, 1); +		if (rtc->wakeirq_alarm <= 0) +			ret = rtc->wakeirq_alarm; +		else +			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, +							    rtc->wakeirq_alarm); +	}  	if (ret) -		dev_warn(&pdev->dev, -			 "alarm won't be able to wake up the system"); +		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret); + +	platform_set_drvdata(pdev, rtc);  	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, -			&stm32_rtc_ops, THIS_MODULE); +						&stm32_rtc_ops, THIS_MODULE);  	if (IS_ERR(rtc->rtc_dev)) {  		ret = PTR_ERR(rtc->rtc_dev);  		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n", @@ -663,8 +810,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)  	/* Handle RTC alarm interrupts */  	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_alarm, NULL, -					stm32_rtc_alarm_irq, -					IRQF_TRIGGER_RISING | IRQF_ONESHOT, +					stm32_rtc_alarm_irq, IRQF_ONESHOT,  					pdev->name, rtc);  	if (ret) {  		dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n", @@ -676,17 +822,27 @@ static int stm32_rtc_probe(struct platform_device *pdev)  	 * If INITS flag is reset (calendar year field set to 0x00), calendar  	 * must be initialized  	 */ -	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS)) +	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))  		dev_warn(&pdev->dev, "Date/Time must be initialized\n"); +	if (regs->verr != UNDEF_REG) { +		u32 ver = readl_relaxed(rtc->base + regs->verr); + +		dev_info(&pdev->dev, "registered rev:%d.%d\n", +			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF, +			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF); +	} +  	return 0;  err:  	if (rtc->data->has_pclk)  		clk_disable_unprepare(rtc->pclk);  	clk_disable_unprepare(rtc->rtc_ck); -	regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0); +	if (rtc->data->need_dbp) +		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); +	dev_pm_clear_wake_irq(&pdev->dev);  	device_init_wakeup(&pdev->dev, false);  	return ret; @@ -695,22 +851,25 @@ err:  static int stm32_rtc_remove(struct platform_device *pdev)  {  	struct stm32_rtc *rtc = platform_get_drvdata(pdev); +	const struct stm32_rtc_registers *regs = &rtc->data->regs;  	unsigned int cr;  	/* Disable interrupts */  	stm32_rtc_wpr_unlock(rtc); -	cr = readl_relaxed(rtc->base + STM32_RTC_CR); +	cr = readl_relaxed(rtc->base + regs->cr);  	cr &= ~STM32_RTC_CR_ALRAIE; -	writel_relaxed(cr, rtc->base + STM32_RTC_CR); +	writel_relaxed(cr, rtc->base + regs->cr);  	stm32_rtc_wpr_lock(rtc);  	clk_disable_unprepare(rtc->rtc_ck);  	if (rtc->data->has_pclk)  		clk_disable_unprepare(rtc->pclk); -	/* Enable backup domain write protection */ -	regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0); +	/* Enable backup domain write protection if needed */ +	if (rtc->data->need_dbp) +		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); +	dev_pm_clear_wake_irq(&pdev->dev);  	device_init_wakeup(&pdev->dev, false);  	return 0;  | 
