diff options
Diffstat (limited to 'drivers/rtc')
41 files changed, 568 insertions, 309 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index ffca9a8bb878..05f4b2d66290 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -956,6 +956,7 @@ comment "Platform RTC drivers"  config RTC_DRV_CMOS  	tristate "PC-style 'CMOS'"  	depends on X86 || ARM || PPC || MIPS || SPARC64 +	depends on HAS_IOPORT || MACH_DECSTATION  	default y if X86  	select RTC_MC146818_LIB  	help @@ -976,6 +977,7 @@ config RTC_DRV_CMOS  config RTC_DRV_ALPHA  	bool "Alpha PC-style CMOS"  	depends on ALPHA +	depends on HAS_IOPORT  	select RTC_MC146818_LIB  	default y  	help @@ -1193,7 +1195,7 @@ config RTC_DRV_MSM6242  config RTC_DRV_BQ4802  	tristate "TI BQ4802" -	depends on HAS_IOMEM +	depends on HAS_IOMEM && HAS_IOPORT  	help  	  If you say Y here you will get support for the TI  	  BQ4802 RTC chip. @@ -1685,6 +1687,19 @@ config RTC_DRV_JZ4740  	  This driver can also be built as a module. If so, the module  	  will be called rtc-jz4740. +config RTC_DRV_LOONGSON +	tristate "Loongson On-chip RTC" +	depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST +	select REGMAP_MMIO +	help +	  This is a driver for the Loongson on-chip Counter0 (Time-Of-Year +	  counter) to be used as a RTC. +	  It can be found on Loongson-1 series cpu, Loongson-2K series cpu +	  and Loongson LS7A bridge chips. + +	  This driver can also be built as a module. If so, the module +	  will be called rtc-loongson. +  config RTC_DRV_LPC24XX  	tristate "NXP RTC for LPC178x/18xx/408x/43xx"  	depends on ARCH_LPC18XX || COMPILE_TEST @@ -1726,16 +1741,6 @@ config RTC_DRV_TEGRA  	  This drive can also be built as a module. If so, the module  	  will be called rtc-tegra. -config RTC_DRV_LOONGSON1 -	tristate "loongson1 RTC support" -	depends on MACH_LOONGSON32 -	help -	  This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year -	  counter) to be used as a RTC. - -	  This driver can also be built as a module. If so, the module -	  will be called rtc-ls1x. -  config RTC_DRV_MXC  	tristate "Freescale MXC Real Time Clock"  	depends on ARCH_MXC || COMPILE_TEST diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ea445d1ebb17..fd209883ee2e 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -78,7 +78,7 @@ obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o  obj-$(CONFIG_RTC_DRV_ISL12026)	+= rtc-isl12026.o  obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o  obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o -obj-$(CONFIG_RTC_DRV_LOONGSON1)	+= rtc-ls1x.o +obj-$(CONFIG_RTC_DRV_LOONGSON)	+= rtc-loongson.o  obj-$(CONFIG_RTC_DRV_LP8788)	+= rtc-lp8788.o  obj-$(CONFIG_RTC_DRV_LPC24XX)	+= rtc-lpc24xx.o  obj-$(CONFIG_RTC_DRV_LPC32XX)	+= rtc-lpc32xx.o diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index f2b0971d2c65..100062001831 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -944,7 +944,7 @@ static struct i2c_driver abb5zes3_driver = {  		.pm = &abb5zes3_rtc_pm_ops,  		.of_match_table = of_match_ptr(abb5zes3_dt_match),  	}, -	.probe_new = abb5zes3_probe, +	.probe = abb5zes3_probe,  	.id_table = abb5zes3_id,  };  module_i2c_driver(abb5zes3_driver); diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c index 34611f6dedcb..04e1b8e93bc1 100644 --- a/drivers/rtc/rtc-ab-eoz9.c +++ b/drivers/rtc/rtc-ab-eoz9.c @@ -455,7 +455,7 @@ static const struct hwmon_channel_info abeoz9_temp = {  	.config = abeoz9_temp_config,  }; -static const struct hwmon_channel_info *abeoz9_info[] = { +static const struct hwmon_channel_info * const abeoz9_info[] = {  	&abeoz9_chip,  	&abeoz9_temp,  	NULL @@ -584,7 +584,7 @@ static struct i2c_driver abeoz9_driver = {  		.name = "rtc-ab-eoz9",  		.of_match_table = of_match_ptr(abeoz9_dt_match),  	}, -	.probe_new = abeoz9_probe, +	.probe = abeoz9_probe,  	.id_table = abeoz9_id,  }; diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index f34a2e59cac7..e08d3181bd2a 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -992,7 +992,7 @@ static struct i2c_driver abx80x_driver = {  		.name	= "rtc-abx80x",  		.of_match_table = of_match_ptr(abx80x_of_match),  	}, -	.probe_new	= abx80x_probe, +	.probe		= abx80x_probe,  	.id_table	= abx80x_id,  }; diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 967ddc6bf76d..591e42391747 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -320,7 +320,7 @@ static struct i2c_driver bq32k_driver = {  		.name	= "bq32k",  		.of_match_table = of_match_ptr(bq32k_of_match),  	}, -	.probe_new	= bq32k_probe, +	.probe		= bq32k_probe,  	.remove		= bq32k_remove,  	.id_table	= bq32k_id,  }; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e86ba84df6cb..cb5acecc11aa 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -2011,7 +2011,7 @@ static struct i2c_driver ds1307_driver = {  		.name	= "rtc-ds1307",  		.of_match_table = ds1307_of_match,  	}, -	.probe_new	= ds1307_probe, +	.probe		= ds1307_probe,  	.id_table	= ds1307_id,  }; diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 7f089f066163..4a5005cb23f5 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -572,7 +572,7 @@ static struct i2c_driver ds1374_driver = {  		.of_match_table = of_match_ptr(ds1374_of_match),  		.pm = &ds1374_pm,  	}, -	.probe_new = ds1374_probe, +	.probe = ds1374_probe,  	.remove = ds1374_remove,  	.id_table = ds1374_id,  }; diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index a3bb2cd9c881..641799f30baa 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -149,7 +149,7 @@ static struct i2c_driver ds1672_driver = {  		   .name = "rtc-ds1672",  		   .of_match_table = of_match_ptr(ds1672_of_match),  	}, -	.probe_new = ds1672_probe, +	.probe = ds1672_probe,  	.id_table = ds1672_id,  }; diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index dd31a60c1fc6..89d7b085f721 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -359,7 +359,7 @@ static const struct hwmon_channel_info ds3232_hwmon_temp = {  	.config = ds3232_hwmon_temp_config,  }; -static const struct hwmon_channel_info *ds3232_hwmon_info[] = { +static const struct hwmon_channel_info * const ds3232_hwmon_info[] = {  	&ds3232_hwmon_chip,  	&ds3232_hwmon_temp,  	NULL @@ -603,7 +603,7 @@ static struct i2c_driver ds3232_driver = {  		.of_match_table = of_match_ptr(ds3232_of_match),  		.pm	= &ds3232_pm_ops,  	}, -	.probe_new = ds3232_i2c_probe, +	.probe = ds3232_i2c_probe,  	.id_table = ds3232_id,  }; diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index 53f9f9391a5f..fc772eae5da5 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -147,7 +147,7 @@ static struct i2c_driver em3027_driver = {  		   .name = "rtc-em3027",  		   .of_match_table = of_match_ptr(em3027_of_match),  	}, -	.probe_new = em3027_probe, +	.probe = em3027_probe,  	.id_table = em3027_id,  }; diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index f59bb81f23c0..400ce4ad0c49 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -517,7 +517,7 @@ static struct i2c_driver fm3130_driver = {  	.driver = {  		.name	= "rtc-fm3130",  	}, -	.probe_new	= fm3130_probe, +	.probe		= fm3130_probe,  	.id_table	= fm3130_id,  }; diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index 7d5a298a9a3b..b018535c842b 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -576,7 +576,7 @@ static struct i2c_driver hym8563_driver = {  		.pm	= &hym8563_pm_ops,  		.of_match_table	= hym8563_dt_idtable,  	}, -	.probe_new	= hym8563_probe, +	.probe		= hym8563_probe,  	.id_table	= hym8563_id,  }; diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index e68a79b5e00e..a613257d1574 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -89,7 +89,7 @@ static int isl12022_hwmon_read(struct device *dev,  	return -EOPNOTSUPP;  } -static const struct hwmon_channel_info *isl12022_hwmon_info[] = { +static const struct hwmon_channel_info * const isl12022_hwmon_info[] = {  	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),  	NULL  }; @@ -262,7 +262,7 @@ static struct i2c_driver isl12022_driver = {  		.name	= "rtc-isl12022",  		.of_match_table = isl12022_dt_match,  	}, -	.probe_new	= isl12022_probe, +	.probe		= isl12022_probe,  	.id_table	= isl12022_id,  }; diff --git a/drivers/rtc/rtc-isl12026.c b/drivers/rtc/rtc-isl12026.c index 1bfca39079d4..5abff5d348ac 100644 --- a/drivers/rtc/rtc-isl12026.c +++ b/drivers/rtc/rtc-isl12026.c @@ -490,7 +490,7 @@ static struct i2c_driver isl12026_driver = {  		.name	= "rtc-isl12026",  		.of_match_table = isl12026_dt_match,  	}, -	.probe_new	= isl12026_probe_new, +	.probe		= isl12026_probe_new,  	.remove		= isl12026_remove,  }; diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 73cc6aaf9b8b..b0712b4e3648 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -6,6 +6,7 @@   */  #include <linux/bcd.h> +#include <linux/clk.h>  #include <linux/i2c.h>  #include <linux/module.h>  #include <linux/of_device.h> @@ -68,42 +69,60 @@  static struct i2c_driver isl1208_driver; -/* ISL1208 various variants */ -enum isl1208_id { -	TYPE_ISL1208 = 0, -	TYPE_ISL1209, -	TYPE_ISL1218, -	TYPE_ISL1219, -	ISL_LAST_ID -}; -  /* Chip capabilities table */ -static const struct isl1208_config { -	const char	name[8]; +struct isl1208_config {  	unsigned int	nvmem_length;  	unsigned	has_tamper:1;  	unsigned	has_timestamp:1; -} isl1208_configs[] = { -	[TYPE_ISL1208] = { "isl1208", 2, false, false }, -	[TYPE_ISL1209] = { "isl1209", 2, true,  false }, -	[TYPE_ISL1218] = { "isl1218", 8, false, false }, -	[TYPE_ISL1219] = { "isl1219", 2, true,  true }, +	unsigned	has_inverted_osc_bit:1; +}; + +static const struct isl1208_config config_isl1208 = { +	.nvmem_length = 2, +	.has_tamper = false, +	.has_timestamp = false +}; + +static const struct isl1208_config config_isl1209 = { +	.nvmem_length = 2, +	.has_tamper = true, +	.has_timestamp = false +}; + +static const struct isl1208_config config_isl1218 = { +	.nvmem_length = 8, +	.has_tamper = false, +	.has_timestamp = false +}; + +static const struct isl1208_config config_isl1219 = { +	.nvmem_length = 2, +	.has_tamper = true, +	.has_timestamp = true +}; + +static const struct isl1208_config config_raa215300_a0 = { +	.nvmem_length = 2, +	.has_tamper = false, +	.has_timestamp = false, +	.has_inverted_osc_bit = true  };  static const struct i2c_device_id isl1208_id[] = { -	{ "isl1208", TYPE_ISL1208 }, -	{ "isl1209", TYPE_ISL1209 }, -	{ "isl1218", TYPE_ISL1218 }, -	{ "isl1219", TYPE_ISL1219 }, +	{ "isl1208", .driver_data = (kernel_ulong_t)&config_isl1208 }, +	{ "isl1209", .driver_data = (kernel_ulong_t)&config_isl1209 }, +	{ "isl1218", .driver_data = (kernel_ulong_t)&config_isl1218 }, +	{ "isl1219", .driver_data = (kernel_ulong_t)&config_isl1219 }, +	{ "raa215300_a0", .driver_data = (kernel_ulong_t)&config_raa215300_a0 },  	{ }  };  MODULE_DEVICE_TABLE(i2c, isl1208_id);  static const __maybe_unused struct of_device_id isl1208_of_match[] = { -	{ .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] }, -	{ .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] }, -	{ .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] }, -	{ .compatible = "isil,isl1219", .data = &isl1208_configs[TYPE_ISL1219] }, +	{ .compatible = "isil,isl1208", .data = &config_isl1208 }, +	{ .compatible = "isil,isl1209", .data = &config_isl1209 }, +	{ .compatible = "isil,isl1218", .data = &config_isl1218 }, +	{ .compatible = "isil,isl1219", .data = &config_isl1219 },  	{ }  };  MODULE_DEVICE_TABLE(of, isl1208_of_match); @@ -166,6 +185,20 @@ isl1208_i2c_validate_client(struct i2c_client *client)  	return 0;  } +static int isl1208_set_xtoscb(struct i2c_client *client, int sr, int xtosb_val) +{ +	/* Do nothing if bit is already set to desired value */ +	if ((sr & ISL1208_REG_SR_XTOSCB) == xtosb_val) +		return 0; + +	if (xtosb_val) +		sr |= ISL1208_REG_SR_XTOSCB; +	else +		sr &= ~ISL1208_REG_SR_XTOSCB; + +	return i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); +} +  static int  isl1208_i2c_get_sr(struct i2c_client *client)  { @@ -502,7 +535,6 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)  	return 0;  } -  static int  isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)  { @@ -797,11 +829,25 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq)  }  static int +isl1208_clk_present(struct i2c_client *client, const char *name) +{ +	struct clk *clk; + +	clk = devm_clk_get_optional(&client->dev, name); +	if (IS_ERR(clk)) +		return PTR_ERR(clk); + +	return !!clk; +} + +static int  isl1208_probe(struct i2c_client *client)  { -	int rc = 0;  	struct isl1208_state *isl1208;  	int evdet_irq = -1; +	int xtosb_val = 0; +	int rc = 0; +	int sr;  	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))  		return -ENODEV; @@ -823,9 +869,22 @@ isl1208_probe(struct i2c_client *client)  	} else {  		const struct i2c_device_id *id = i2c_match_id(isl1208_id, client); -		if (id->driver_data >= ISL_LAST_ID) +		if (!id)  			return -ENODEV; -		isl1208->config = &isl1208_configs[id->driver_data]; +		isl1208->config = (struct isl1208_config *)id->driver_data; +	} + +	rc = isl1208_clk_present(client, "xin"); +	if (rc < 0) +		return rc; + +	if (!rc) { +		rc = isl1208_clk_present(client, "clkin"); +		if (rc < 0) +			return rc; + +		if (rc) +			xtosb_val = 1;  	}  	isl1208->rtc = devm_rtc_allocate_device(&client->dev); @@ -839,13 +898,20 @@ isl1208_probe(struct i2c_client *client)  	isl1208->nvmem_config.size = isl1208->config->nvmem_length;  	isl1208->nvmem_config.priv = isl1208; -	rc = isl1208_i2c_get_sr(client); -	if (rc < 0) { +	sr = isl1208_i2c_get_sr(client); +	if (sr < 0) {  		dev_err(&client->dev, "reading status failed\n"); -		return rc; +		return sr;  	} -	if (rc & ISL1208_REG_SR_RTCF) +	if (isl1208->config->has_inverted_osc_bit) +		xtosb_val = !xtosb_val; + +	rc = isl1208_set_xtoscb(client, sr, xtosb_val); +	if (rc) +		return rc; + +	if (sr & ISL1208_REG_SR_RTCF)  		dev_warn(&client->dev, "rtc power failure detected, "  			 "please set clock.\n"); @@ -908,7 +974,7 @@ static struct i2c_driver isl1208_driver = {  		.name = "rtc-isl1208",  		.of_match_table = of_match_ptr(isl1208_of_match),  	}, -	.probe_new = isl1208_probe, +	.probe = isl1208_probe,  	.id_table = isl1208_id,  }; diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c new file mode 100644 index 000000000000..e8ffc1ab90b0 --- /dev/null +++ b/drivers/rtc/rtc-loongson.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Loongson RTC driver + * + * Maintained out-of-tree by Huacai Chen <chenhuacai@kernel.org>. + * Rewritten for mainline by WANG Xuerui <git@xen0n.name>. + *                           Binbin Zhou <zhoubinbin@loongson.cn> + */ + +#include <linux/bitfield.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/rtc.h> +#include <linux/acpi.h> + +/* Time Of Year(TOY) counters registers */ +#define TOY_TRIM_REG		0x20 /* Must be initialized to 0 */ +#define TOY_WRITE0_REG		0x24 /* TOY low 32-bits value (write-only) */ +#define TOY_WRITE1_REG		0x28 /* TOY high 32-bits value (write-only) */ +#define TOY_READ0_REG		0x2c /* TOY low 32-bits value (read-only) */ +#define TOY_READ1_REG		0x30 /* TOY high 32-bits value (read-only) */ +#define TOY_MATCH0_REG		0x34 /* TOY timing interrupt 0 */ +#define TOY_MATCH1_REG		0x38 /* TOY timing interrupt 1 */ +#define TOY_MATCH2_REG		0x3c /* TOY timing interrupt 2 */ + +/* RTC counters registers */ +#define RTC_CTRL_REG		0x40 /* TOY and RTC control register */ +#define RTC_TRIM_REG		0x60 /* Must be initialized to 0 */ +#define RTC_WRITE0_REG		0x64 /* RTC counters value (write-only) */ +#define RTC_READ0_REG		0x68 /* RTC counters value (read-only) */ +#define RTC_MATCH0_REG		0x6c /* RTC timing interrupt 0 */ +#define RTC_MATCH1_REG		0x70 /* RTC timing interrupt 1 */ +#define RTC_MATCH2_REG		0x74 /* RTC timing interrupt 2 */ + +/* bitmask of TOY_WRITE0_REG */ +#define TOY_MON			GENMASK(31, 26) +#define TOY_DAY			GENMASK(25, 21) +#define TOY_HOUR		GENMASK(20, 16) +#define TOY_MIN			GENMASK(15, 10) +#define TOY_SEC			GENMASK(9, 4) +#define TOY_MSEC		GENMASK(3, 0) + +/* bitmask of TOY_MATCH0/1/2_REG */ +#define TOY_MATCH_YEAR		GENMASK(31, 26) +#define TOY_MATCH_MON		GENMASK(25, 22) +#define TOY_MATCH_DAY		GENMASK(21, 17) +#define TOY_MATCH_HOUR		GENMASK(16, 12) +#define TOY_MATCH_MIN		GENMASK(11, 6) +#define TOY_MATCH_SEC		GENMASK(5, 0) + +/* bitmask of RTC_CTRL_REG */ +#define RTC_ENABLE		BIT(13) /* 1: RTC counters enable */ +#define TOY_ENABLE		BIT(11) /* 1: TOY counters enable */ +#define OSC_ENABLE		BIT(8) /* 1: 32.768k crystal enable */ +#define TOY_ENABLE_MASK		(TOY_ENABLE | OSC_ENABLE) + +/* PM domain registers */ +#define PM1_STS_REG		0x0c	/* Power management 1 status register */ +#define RTC_STS			BIT(10)	/* RTC status */ +#define PM1_EN_REG		0x10	/* Power management 1 enable register */ +#define RTC_EN			BIT(10)	/* RTC event enable */ + +/* + * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined. + * Accessing the relevant registers will cause the system to hang. + */ +#define LS1C_RTC_CTRL_WORKAROUND	BIT(0) + +struct loongson_rtc_config { +	u32 pm_offset;	/* Offset of PM domain, for RTC alarm wakeup */ +	u32 flags;	/* Workaround bits */ +}; + +struct loongson_rtc_priv { +	spinlock_t lock;	/* protects PM registers access */ +	u32 fix_year;		/* RTC alarm year compensation value */ +	struct rtc_device *rtcdev; +	struct regmap *regmap; +	void __iomem *pm_base;	/* PM domain base, for RTC alarm wakeup */ +	const struct loongson_rtc_config *config; +}; + +static const struct loongson_rtc_config ls1b_rtc_config = { +	.pm_offset = 0, +	.flags = 0, +}; + +static const struct loongson_rtc_config ls1c_rtc_config = { +	.pm_offset = 0, +	.flags = LS1C_RTC_CTRL_WORKAROUND, +}; + +static const struct loongson_rtc_config generic_rtc_config = { +	.pm_offset = 0x100, +	.flags = 0, +}; + +static const struct loongson_rtc_config ls2k1000_rtc_config = { +	.pm_offset = 0x800, +	.flags = 0, +}; + +static const struct regmap_config loongson_rtc_regmap_config = { +	.reg_bits = 32, +	.val_bits = 32, +	.reg_stride = 4, +}; + +/* RTC alarm irq handler */ +static irqreturn_t loongson_rtc_isr(int irq, void *id) +{ +	struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id; + +	rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF); +	return IRQ_HANDLED; +} + +/* For ACPI fixed event handler */ +static u32 loongson_rtc_handler(void *id) +{ +	struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id; + +	spin_lock(&priv->lock); +	/* Disable RTC alarm wakeup and interrupt */ +	writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN, +	       priv->pm_base + PM1_EN_REG); + +	/* Clear RTC interrupt status */ +	writel(RTC_STS, priv->pm_base + PM1_STS_REG); +	spin_unlock(&priv->lock); + +	/* +	 * The TOY_MATCH0_REG should be cleared 0 here, +	 * otherwise the interrupt cannot be cleared. +	 */ +	return regmap_write(priv->regmap, TOY_MATCH0_REG, 0); +} + +static int loongson_rtc_set_enabled(struct device *dev) +{ +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) +		return 0; + +	/* Enable RTC TOY counters and crystal */ +	return regmap_update_bits(priv->regmap, RTC_CTRL_REG, TOY_ENABLE_MASK, +				  TOY_ENABLE_MASK); +} + +static bool loongson_rtc_get_enabled(struct device *dev) +{ +	int ret; +	u32 ctrl_data; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) +		return true; + +	ret = regmap_read(priv->regmap, RTC_CTRL_REG, &ctrl_data); +	if (ret < 0) +		return false; + +	return ctrl_data & TOY_ENABLE_MASK; +} + +static int loongson_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ +	int ret; +	u32 rtc_data[2]; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	if (!loongson_rtc_get_enabled(dev)) +		return -EINVAL; + +	ret = regmap_bulk_read(priv->regmap, TOY_READ0_REG, rtc_data, +			       ARRAY_SIZE(rtc_data)); +	if (ret < 0) +		return ret; + +	tm->tm_sec = FIELD_GET(TOY_SEC, rtc_data[0]); +	tm->tm_min = FIELD_GET(TOY_MIN, rtc_data[0]); +	tm->tm_hour = FIELD_GET(TOY_HOUR, rtc_data[0]); +	tm->tm_mday = FIELD_GET(TOY_DAY, rtc_data[0]); +	tm->tm_mon = FIELD_GET(TOY_MON, rtc_data[0]) - 1; +	tm->tm_year = rtc_data[1]; + +	/* Prepare for RTC alarm year compensation value. */ +	priv->fix_year = tm->tm_year / 64 * 64; +	return 0; +} + +static int loongson_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ +	int ret; +	u32 rtc_data[2]; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	rtc_data[0] = FIELD_PREP(TOY_SEC, tm->tm_sec) +		    | FIELD_PREP(TOY_MIN, tm->tm_min) +		    | FIELD_PREP(TOY_HOUR, tm->tm_hour) +		    | FIELD_PREP(TOY_DAY, tm->tm_mday) +		    | FIELD_PREP(TOY_MON, tm->tm_mon + 1); +	rtc_data[1] = tm->tm_year; + +	ret = regmap_bulk_write(priv->regmap, TOY_WRITE0_REG, rtc_data, +				ARRAY_SIZE(rtc_data)); +	if (ret < 0) +		return ret; + +	return loongson_rtc_set_enabled(dev); +} + +static int loongson_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ +	int ret; +	u32 alarm_data; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	ret = regmap_read(priv->regmap, TOY_MATCH0_REG, &alarm_data); +	if (ret < 0) +		return ret; + +	alrm->time.tm_sec = FIELD_GET(TOY_MATCH_SEC, alarm_data); +	alrm->time.tm_min = FIELD_GET(TOY_MATCH_MIN, alarm_data); +	alrm->time.tm_hour = FIELD_GET(TOY_MATCH_HOUR, alarm_data); +	alrm->time.tm_mday = FIELD_GET(TOY_MATCH_DAY, alarm_data); +	alrm->time.tm_mon = FIELD_GET(TOY_MATCH_MON, alarm_data) - 1; +	/* +	 * This is a hardware bug: the year field of SYS_TOYMATCH is only 6 bits, +	 * making it impossible to save year values larger than 64. +	 * +	 * SYS_TOYMATCH is used to match the alarm time value and determine if +	 * an alarm is triggered, so we must keep the lower 6 bits of the year +	 * value constant during the value conversion. +	 * +	 * In summary, we need to manually add 64(or a multiple of 64) to the +	 * year value to avoid the invalid alarm prompt at startup. +	 */ +	alrm->time.tm_year = FIELD_GET(TOY_MATCH_YEAR, alarm_data) + priv->fix_year; + +	alrm->enabled = !!(readl(priv->pm_base + PM1_EN_REG) & RTC_EN); +	return 0; +} + +static int loongson_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ +	u32 val; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	spin_lock(&priv->lock); +	val = readl(priv->pm_base + PM1_EN_REG); +	/* Enable RTC alarm wakeup */ +	writel(enabled ? val | RTC_EN : val & ~RTC_EN, +	       priv->pm_base + PM1_EN_REG); +	spin_unlock(&priv->lock); + +	return 0; +} + +static int loongson_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ +	int ret; +	u32 alarm_data; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	alarm_data = FIELD_PREP(TOY_MATCH_SEC, alrm->time.tm_sec) +		   | FIELD_PREP(TOY_MATCH_MIN, alrm->time.tm_min) +		   | FIELD_PREP(TOY_MATCH_HOUR, alrm->time.tm_hour) +		   | FIELD_PREP(TOY_MATCH_DAY, alrm->time.tm_mday) +		   | FIELD_PREP(TOY_MATCH_MON, alrm->time.tm_mon + 1) +		   | FIELD_PREP(TOY_MATCH_YEAR, alrm->time.tm_year - priv->fix_year); + +	ret = regmap_write(priv->regmap, TOY_MATCH0_REG, alarm_data); +	if (ret < 0) +		return ret; + +	return loongson_rtc_alarm_irq_enable(dev, alrm->enabled); +} + +static const struct rtc_class_ops loongson_rtc_ops = { +	.read_time = loongson_rtc_read_time, +	.set_time = loongson_rtc_set_time, +	.read_alarm = loongson_rtc_read_alarm, +	.set_alarm = loongson_rtc_set_alarm, +	.alarm_irq_enable = loongson_rtc_alarm_irq_enable, +}; + +static int loongson_rtc_probe(struct platform_device *pdev) +{ +	int ret, alarm_irq; +	void __iomem *regs; +	struct loongson_rtc_priv *priv; +	struct device *dev = &pdev->dev; + +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); +	if (!priv) +		return -ENOMEM; + +	regs = devm_platform_ioremap_resource(pdev, 0); +	if (IS_ERR(regs)) +		return dev_err_probe(dev, PTR_ERR(regs), +				     "devm_platform_ioremap_resource failed\n"); + +	priv->regmap = devm_regmap_init_mmio(dev, regs, +					     &loongson_rtc_regmap_config); +	if (IS_ERR(priv->regmap)) +		return dev_err_probe(dev, PTR_ERR(priv->regmap), +				     "devm_regmap_init_mmio failed\n"); + +	priv->config = device_get_match_data(dev); +	spin_lock_init(&priv->lock); +	platform_set_drvdata(pdev, priv); + +	priv->rtcdev = devm_rtc_allocate_device(dev); +	if (IS_ERR(priv->rtcdev)) +		return dev_err_probe(dev, PTR_ERR(priv->rtcdev), +				     "devm_rtc_allocate_device failed\n"); + +	/* Get RTC alarm irq */ +	alarm_irq = platform_get_irq(pdev, 0); +	if (alarm_irq > 0) { +		ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, +				       0, "loongson-alarm", priv); +		if (ret < 0) +			return dev_err_probe(dev, ret, "Unable to request irq %d\n", +					     alarm_irq); + +		priv->pm_base = regs - priv->config->pm_offset; +		device_init_wakeup(dev, 1); + +		if (has_acpi_companion(dev)) +			acpi_install_fixed_event_handler(ACPI_EVENT_RTC, +							 loongson_rtc_handler, priv); +	} else { +		/* Loongson-1C RTC does not support alarm */ +		clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); +	} + +	/* Loongson RTC does not support UIE */ +	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features); +	priv->rtcdev->ops = &loongson_rtc_ops; +	priv->rtcdev->range_min = RTC_TIMESTAMP_BEGIN_2000; +	priv->rtcdev->range_max = RTC_TIMESTAMP_END_2099; + +	return devm_rtc_register_device(priv->rtcdev); +} + +static void loongson_rtc_remove(struct platform_device *pdev) +{ +	struct device *dev = &pdev->dev; +	struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + +	if (!test_bit(RTC_FEATURE_ALARM, priv->rtcdev->features)) +		return; + +	if (has_acpi_companion(dev)) +		acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, +						loongson_rtc_handler); + +	device_init_wakeup(dev, 0); +	loongson_rtc_alarm_irq_enable(dev, 0); +} + +static const struct of_device_id loongson_rtc_of_match[] = { +	{ .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config }, +	{ .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config }, +	{ .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config }, +	{ .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config }, +	{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, loongson_rtc_of_match); + +static const struct acpi_device_id loongson_rtc_acpi_match[] = { +	{ "LOON0001", .driver_data = (kernel_ulong_t)&generic_rtc_config }, +	{ } +}; +MODULE_DEVICE_TABLE(acpi, loongson_rtc_acpi_match); + +static struct platform_driver loongson_rtc_driver = { +	.probe		= loongson_rtc_probe, +	.remove_new	= loongson_rtc_remove, +	.driver		= { +		.name	= "loongson-rtc", +		.of_match_table = loongson_rtc_of_match, +		.acpi_match_table = loongson_rtc_acpi_match, +	}, +}; +module_platform_driver(loongson_rtc_driver); + +MODULE_DESCRIPTION("Loongson RTC driver"); +MODULE_AUTHOR("Binbin Zhou <zhoubinbin@loongson.cn>"); +MODULE_AUTHOR("WANG Xuerui <git@xen0n.name>"); +MODULE_AUTHOR("Huacai Chen <chenhuacai@kernel.org>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c deleted file mode 100644 index 5af26dc5c2a3..000000000000 --- a/drivers/rtc/rtc-ls1x.c +++ /dev/null @@ -1,192 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2011 Zhao Zhang <zhzhl555@gmail.com> - * - * Derived from driver/rtc/rtc-au1xxx.c - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/rtc.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/types.h> -#include <linux/io.h> -#include <loongson1.h> - -#define LS1X_RTC_REG_OFFSET	(LS1X_RTC_BASE + 0x20) -#define LS1X_RTC_REGS(x) \ -		((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x))) - -/*RTC programmable counters 0 and 1*/ -#define SYS_COUNTER_CNTRL		(LS1X_RTC_REGS(0x20)) -#define SYS_CNTRL_ERS			(1 << 23) -#define SYS_CNTRL_RTS			(1 << 20) -#define SYS_CNTRL_RM2			(1 << 19) -#define SYS_CNTRL_RM1			(1 << 18) -#define SYS_CNTRL_RM0			(1 << 17) -#define SYS_CNTRL_RS			(1 << 16) -#define SYS_CNTRL_BP			(1 << 14) -#define SYS_CNTRL_REN			(1 << 13) -#define SYS_CNTRL_BRT			(1 << 12) -#define SYS_CNTRL_TEN			(1 << 11) -#define SYS_CNTRL_BTT			(1 << 10) -#define SYS_CNTRL_E0			(1 << 8) -#define SYS_CNTRL_ETS			(1 << 7) -#define SYS_CNTRL_32S			(1 << 5) -#define SYS_CNTRL_TTS			(1 << 4) -#define SYS_CNTRL_TM2			(1 << 3) -#define SYS_CNTRL_TM1			(1 << 2) -#define SYS_CNTRL_TM0			(1 << 1) -#define SYS_CNTRL_TS			(1 << 0) - -/* Programmable Counter 0 Registers */ -#define SYS_TOYTRIM		(LS1X_RTC_REGS(0)) -#define SYS_TOYWRITE0		(LS1X_RTC_REGS(4)) -#define SYS_TOYWRITE1		(LS1X_RTC_REGS(8)) -#define SYS_TOYREAD0		(LS1X_RTC_REGS(0xC)) -#define SYS_TOYREAD1		(LS1X_RTC_REGS(0x10)) -#define SYS_TOYMATCH0		(LS1X_RTC_REGS(0x14)) -#define SYS_TOYMATCH1		(LS1X_RTC_REGS(0x18)) -#define SYS_TOYMATCH2		(LS1X_RTC_REGS(0x1C)) - -/* Programmable Counter 1 Registers */ -#define SYS_RTCTRIM		(LS1X_RTC_REGS(0x40)) -#define SYS_RTCWRITE0		(LS1X_RTC_REGS(0x44)) -#define SYS_RTCREAD0		(LS1X_RTC_REGS(0x48)) -#define SYS_RTCMATCH0		(LS1X_RTC_REGS(0x4C)) -#define SYS_RTCMATCH1		(LS1X_RTC_REGS(0x50)) -#define SYS_RTCMATCH2		(LS1X_RTC_REGS(0x54)) - -#define LS1X_SEC_OFFSET		(4) -#define LS1X_MIN_OFFSET		(10) -#define LS1X_HOUR_OFFSET	(16) -#define LS1X_DAY_OFFSET		(21) -#define LS1X_MONTH_OFFSET	(26) - - -#define LS1X_SEC_MASK		(0x3f) -#define LS1X_MIN_MASK		(0x3f) -#define LS1X_HOUR_MASK		(0x1f) -#define LS1X_DAY_MASK		(0x1f) -#define LS1X_MONTH_MASK		(0x3f) -#define LS1X_YEAR_MASK		(0xffffffff) - -#define ls1x_get_sec(t)		(((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK) -#define ls1x_get_min(t)		(((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK) -#define ls1x_get_hour(t)	(((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK) -#define ls1x_get_day(t)		(((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK) -#define ls1x_get_month(t)	(((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK) - -#define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) - -static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm) -{ -	unsigned long v; -	time64_t t; - -	v = readl(SYS_TOYREAD0); -	t = readl(SYS_TOYREAD1); - -	memset(rtm, 0, sizeof(struct rtc_time)); -	t  = mktime64((t & LS1X_YEAR_MASK), ls1x_get_month(v), -			ls1x_get_day(v), ls1x_get_hour(v), -			ls1x_get_min(v), ls1x_get_sec(v)); -	rtc_time64_to_tm(t, rtm); - -	return 0; -} - -static int ls1x_rtc_set_time(struct device *dev, struct  rtc_time *rtm) -{ -	unsigned long v, t, c; -	int ret = -ETIMEDOUT; - -	v = ((rtm->tm_mon + 1)  << LS1X_MONTH_OFFSET) -		| (rtm->tm_mday << LS1X_DAY_OFFSET) -		| (rtm->tm_hour << LS1X_HOUR_OFFSET) -		| (rtm->tm_min  << LS1X_MIN_OFFSET) -		| (rtm->tm_sec  << LS1X_SEC_OFFSET); - -	writel(v, SYS_TOYWRITE0); -	c = 0x10000; -	/* add timeout check counter, for more safe */ -	while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) -		usleep_range(1000, 3000); - -	if (!c) { -		dev_err(dev, "set time timeout!\n"); -		goto err; -	} - -	t = rtm->tm_year + 1900; -	writel(t, SYS_TOYWRITE1); -	c = 0x10000; -	while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c) -		usleep_range(1000, 3000); - -	if (!c) { -		dev_err(dev, "set time timeout!\n"); -		goto err; -	} -	return 0; -err: -	return ret; -} - -static const struct rtc_class_ops  ls1x_rtc_ops = { -	.read_time	= ls1x_rtc_read_time, -	.set_time	= ls1x_rtc_set_time, -}; - -static int ls1x_rtc_probe(struct platform_device *pdev) -{ -	struct rtc_device *rtcdev; -	unsigned long v; - -	v = readl(SYS_COUNTER_CNTRL); -	if (!(v & RTC_CNTR_OK)) { -		dev_err(&pdev->dev, "rtc counters not working\n"); -		return -ENODEV; -	} - -	/* set to 1 HZ if needed */ -	if (readl(SYS_TOYTRIM) != 32767) { -		v = 0x100000; -		while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v) -			usleep_range(1000, 3000); - -		if (!v) { -			dev_err(&pdev->dev, "time out\n"); -			return -ETIMEDOUT; -		} -		writel(32767, SYS_TOYTRIM); -	} -	/* this loop coundn't be endless */ -	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) -		usleep_range(1000, 3000); - -	rtcdev = devm_rtc_allocate_device(&pdev->dev); -	if (IS_ERR(rtcdev)) -		return PTR_ERR(rtcdev); - -	platform_set_drvdata(pdev, rtcdev); -	rtcdev->ops = &ls1x_rtc_ops; -	rtcdev->range_min = RTC_TIMESTAMP_BEGIN_1900; -	rtcdev->range_max = RTC_TIMESTAMP_END_2099; - -	return devm_rtc_register_device(rtcdev); -} - -static struct platform_driver  ls1x_rtc_driver = { -	.driver		= { -		.name	= "ls1x-rtc", -	}, -	.probe		= ls1x_rtc_probe, -}; - -module_platform_driver(ls1x_rtc_driver); - -MODULE_AUTHOR("zhao zhang <zhzhl555@gmail.com>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index c1963f7c424d..3cc5151e0986 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -1013,7 +1013,7 @@ static struct i2c_driver m41t80_driver = {  		.of_match_table = of_match_ptr(m41t80_of_match),  		.pm = &m41t80_pm,  	}, -	.probe_new = m41t80_probe, +	.probe = m41t80_probe,  	.remove = m41t80_remove,  	.id_table = m41t80_id,  }; diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 0a33851cc51f..31b910e4d91a 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -224,7 +224,7 @@ static struct i2c_driver max6900_driver = {  	.driver = {  		   .name = "rtc-max6900",  		   }, -	.probe_new = max6900_probe, +	.probe = max6900_probe,  	.id_table = max6900_id,  }; diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c index 0a3b14c95d90..a4e3f924837e 100644 --- a/drivers/rtc/rtc-nct3018y.c +++ b/drivers/rtc/rtc-nct3018y.c @@ -540,7 +540,7 @@ static struct i2c_driver nct3018y_driver = {  		.name	= "rtc-nct3018y",  		.of_match_table = of_match_ptr(nct3018y_of_match),  	}, -	.probe_new	= nct3018y_probe, +	.probe		= nct3018y_probe,  	.id_table	= nct3018y_id,  }; diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 87f4fc9df68b..ee03b04b74ba 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -923,7 +923,7 @@ static struct i2c_driver pcf2127_i2c_driver = {  		.name	= "rtc-pcf2127-i2c",  		.of_match_table = of_match_ptr(pcf2127_of_match),  	}, -	.probe_new	= pcf2127_i2c_probe, +	.probe		= pcf2127_i2c_probe,  	.id_table	= pcf2127_i2c_id,  }; diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 71a456355981..e517abfaee2a 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -681,7 +681,7 @@ static struct i2c_driver pcf85063_driver = {  		.name	= "rtc-pcf85063",  		.of_match_table = of_match_ptr(pcf85063_of_match),  	}, -	.probe_new	= pcf85063_probe, +	.probe		= pcf85063_probe,  	.id_table	= pcf85063_ids,  }; diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index e7115ebef707..d1efde3e7a80 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c @@ -488,7 +488,7 @@ static struct i2c_driver pcf8523_driver = {  		.name = "rtc-pcf8523",  		.of_match_table = pcf8523_of_match,  	}, -	.probe_new = pcf8523_probe, +	.probe = pcf8523_probe,  	.id_table = pcf8523_id,  };  module_i2c_driver(pcf8523_driver); diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index 8958eadf1c3e..65b8b1338dbb 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -475,7 +475,7 @@ static struct i2c_driver pcf85363_driver = {  		.name	= "pcf85363",  		.of_match_table = of_match_ptr(dev_ids),  	}, -	.probe_new = pcf85363_probe, +	.probe = pcf85363_probe,  };  module_i2c_driver(pcf85363_driver); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 7e720472213c..ea82b89d8929 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -612,7 +612,7 @@ static struct i2c_driver pcf8563_driver = {  		.name	= "rtc-pcf8563",  		.of_match_table = of_match_ptr(pcf8563_of_match),  	}, -	.probe_new	= pcf8563_probe, +	.probe		= pcf8563_probe,  	.id_table	= pcf8563_id,  }; diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 87074d178274..a7e0fc360b6a 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -306,7 +306,7 @@ static struct i2c_driver pcf8583_driver = {  	.driver = {  		.name	= "pcf8583",  	}, -	.probe_new	= pcf8583_probe, +	.probe		= pcf8583_probe,  	.id_table	= pcf8583_id,  }; diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index b4c5d016eca3..a5a6c8772ecd 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -921,7 +921,7 @@ static struct i2c_driver rs5c372_driver = {  		.name	= "rtc-rs5c372",  		.of_match_table = of_match_ptr(rs5c372_of_match),  	}, -	.probe_new	= rs5c372_probe, +	.probe		= rs5c372_probe,  	.remove		= rs5c372_remove,  	.id_table	= rs5c372_id,  }; diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index ec5d7a614e2d..076e56f4e01a 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -994,13 +994,20 @@ static const __maybe_unused struct of_device_id rv3028_of_match[] = {  };  MODULE_DEVICE_TABLE(of, rv3028_of_match); +static const struct i2c_device_id rv3028_id_table[] = { +	{ .name = "rv3028", }, +	{ } +}; +MODULE_DEVICE_TABLE(i2c, rv3028_id_table); +  static struct i2c_driver rv3028_driver = {  	.driver = {  		.name = "rtc-rv3028",  		.acpi_match_table = rv3028_i2c_acpi_match,  		.of_match_table = of_match_ptr(rv3028_of_match),  	}, -	.probe_new	= rv3028_probe, +	.id_table	= rv3028_id_table, +	.probe		= rv3028_probe,  };  module_i2c_driver(rv3028_driver); diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 0852f6709a85..4a81feeb00ff 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -824,7 +824,7 @@ static struct i2c_driver rv3029_driver = {  		.name = "rv3029",  		.of_match_table = of_match_ptr(rv3029_of_match),  	}, -	.probe_new	= rv3029_i2c_probe, +	.probe		= rv3029_i2c_probe,  	.id_table	= rv3029_id,  }; diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c index 1ff4f2e6fa77..6b8eb2039a33 100644 --- a/drivers/rtc/rtc-rv3032.c +++ b/drivers/rtc/rtc-rv3032.c @@ -842,7 +842,7 @@ static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type,  	return err;  } -static const struct hwmon_channel_info *rv3032_hwmon_info[] = { +static const struct hwmon_channel_info * const rv3032_hwmon_info[] = {  	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),  	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),  	NULL @@ -998,7 +998,7 @@ static struct i2c_driver rv3032_driver = {  		.acpi_match_table = rv3032_i2c_acpi_match,  		.of_match_table = of_match_ptr(rv3032_of_match),  	}, -	.probe_new	= rv3032_probe, +	.probe		= rv3032_probe,  };  module_i2c_driver(rv3032_driver); diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 25c3b9e4f515..98679cae13e8 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -739,7 +739,7 @@ static struct i2c_driver rv8803_driver = {  		.name = "rtc-rv8803",  		.of_match_table = of_match_ptr(rv8803_of_match),  	}, -	.probe_new	= rv8803_probe, +	.probe		= rv8803_probe,  	.id_table	= rv8803_id,  };  module_i2c_driver(rv8803_driver); diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c index 37608883a796..8702db6096ba 100644 --- a/drivers/rtc/rtc-rx6110.c +++ b/drivers/rtc/rtc-rx6110.c @@ -462,7 +462,7 @@ static struct i2c_driver rx6110_i2c_driver = {  		.name = RX6110_DRIVER_NAME,  		.acpi_match_table = rx6110_i2c_acpi_match,  	}, -	.probe_new	= rx6110_i2c_probe, +	.probe		= rx6110_i2c_probe,  	.id_table	= rx6110_i2c_id,  }; diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index b9c8dad26208..f44e212c07de 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -424,7 +424,7 @@ static struct i2c_driver rx8010_driver = {  		.name = "rtc-rx8010",  		.of_match_table = of_match_ptr(rx8010_of_match),  	}, -	.probe_new	= rx8010_probe, +	.probe		= rx8010_probe,  	.id_table	= rx8010_id,  }; diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 331c20d4d843..aabe62c283a1 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -581,7 +581,7 @@ static struct i2c_driver rx8025_driver = {  	.driver = {  		.name = "rtc-rx8025",  	}, -	.probe_new	= rx8025_probe, +	.probe		= rx8025_probe,  	.id_table	= rx8025_id,  }; diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 14edb7534c97..82881fd2e14a 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -325,7 +325,7 @@ static struct i2c_driver rx8581_driver = {  		.name	= "rtc-rx8581",  		.of_match_table = of_match_ptr(rx8581_of_match),  	}, -	.probe_new	= rx8581_probe, +	.probe		= rx8581_probe,  	.id_table	= rx8581_id,  }; diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index b18daaf72b17..90a3028ac574 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -499,7 +499,7 @@ static struct i2c_driver s35390a_driver = {  		.name	= "rtc-s35390a",  		.of_match_table = of_match_ptr(s35390a_of_match),  	}, -	.probe_new	= s35390a_probe, +	.probe		= s35390a_probe,  	.id_table	= s35390a_id,  }; diff --git a/drivers/rtc/rtc-sd3078.c b/drivers/rtc/rtc-sd3078.c index e2f90d768ca8..7760394ccd2d 100644 --- a/drivers/rtc/rtc-sd3078.c +++ b/drivers/rtc/rtc-sd3078.c @@ -217,7 +217,7 @@ static struct i2c_driver sd3078_driver = {  		.name   = "sd3078",  		.of_match_table = of_match_ptr(rtc_dt_match),  	}, -	.probe_new  = sd3078_probe, +	.probe      = sd3078_probe,  	.id_table   = sd3078_id,  }; diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index 0f8e4231098e..d492a2d26600 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -228,17 +228,13 @@ static int st_rtc_probe(struct platform_device *pdev)  	enable_irq_wake(rtc->irq);  	disable_irq(rtc->irq); -	rtc->clk = clk_get(&pdev->dev, NULL); -	if (IS_ERR(rtc->clk)) { -		dev_err(&pdev->dev, "Unable to request clock\n"); -		return PTR_ERR(rtc->clk); -	} - -	clk_prepare_enable(rtc->clk); +	rtc->clk = devm_clk_get_enabled(&pdev->dev, NULL); +	if (IS_ERR(rtc->clk)) +		return dev_err_probe(&pdev->dev, PTR_ERR(rtc->clk), +				     "Unable to request clock\n");  	rtc->clkrate = clk_get_rate(rtc->clk);  	if (!rtc->clkrate) { -		clk_disable_unprepare(rtc->clk);  		dev_err(&pdev->dev, "Unable to fetch clock rate\n");  		return -EINVAL;  	} @@ -252,10 +248,8 @@ static int st_rtc_probe(struct platform_device *pdev)  	do_div(rtc->rtc_dev->range_max, rtc->clkrate);  	ret = devm_rtc_register_device(rtc->rtc_dev); -	if (ret) { -		clk_disable_unprepare(rtc->clk); +	if (ret)  		return ret; -	}  	return 0;  } diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 229cb2847cc4..3d36e11cff80 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -114,7 +114,6 @@ struct stm32_rtc_data {  	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);  	bool has_pclk;  	bool need_dbp; -	bool has_wakeirq;  };  struct stm32_rtc { @@ -127,7 +126,6 @@ struct stm32_rtc {  	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) @@ -547,7 +545,6 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,  static const struct stm32_rtc_data stm32_rtc_data = {  	.has_pclk = false,  	.need_dbp = true, -	.has_wakeirq = false,  	.regs = {  		.tr = 0x00,  		.dr = 0x04, @@ -569,7 +566,6 @@ static const struct stm32_rtc_data stm32_rtc_data = {  static const struct stm32_rtc_data stm32h7_rtc_data = {  	.has_pclk = true,  	.need_dbp = true, -	.has_wakeirq = false,  	.regs = {  		.tr = 0x00,  		.dr = 0x04, @@ -600,7 +596,6 @@ static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,  static const struct stm32_rtc_data stm32mp1_data = {  	.has_pclk = true,  	.need_dbp = false, -	.has_wakeirq = true,  	.regs = {  		.tr = 0x00,  		.dr = 0x04, @@ -779,19 +774,12 @@ static int stm32_rtc_probe(struct platform_device *pdev)  	}  	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 = dev_pm_set_dedicated_wake_irq(&pdev->dev, -							    rtc->wakeirq_alarm); -		} else { -			ret = rtc->wakeirq_alarm; -			if (rtc->wakeirq_alarm == -EPROBE_DEFER) -				goto err; -		} -	}  	if (ret) -		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret); +		goto err; + +	ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm); +	if (ret) +		goto err;  	platform_set_drvdata(pdev, rtc); @@ -879,9 +867,6 @@ static int stm32_rtc_suspend(struct device *dev)  	if (rtc->data->has_pclk)  		clk_disable_unprepare(rtc->pclk); -	if (device_may_wakeup(dev)) -		return enable_irq_wake(rtc->irq_alarm); -  	return 0;  } @@ -903,9 +888,6 @@ static int stm32_rtc_resume(struct device *dev)  		return ret;  	} -	if (device_may_wakeup(dev)) -		return disable_irq_wake(rtc->irq_alarm); -  	return ret;  }  #endif diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index f587afa84357..807f953ae0ae 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -679,7 +679,7 @@ static struct i2c_driver x1205_driver = {  		.name	= "rtc-x1205",  		.of_match_table = x1205_dt_ids,  	}, -	.probe_new	= x1205_probe, +	.probe		= x1205_probe,  	.remove		= x1205_remove,  	.id_table	= x1205_id,  };  | 
