summaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-07-03 10:43:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-07-03 10:43:10 -0700
commitb349de4c91e6ad761c2beecc796615bcb64b36e6 (patch)
tree65b9a62b26e2fa9f5a7ce58ac247015e975dd015 /drivers/rtc
parenta74195876b95fce5f1c5b051b8c3b01e1b18a83b (diff)
parent1b733a9ebc3d8011ca66ec6ff17f55a440358794 (diff)
downloadlinux-stable-b349de4c91e6ad761c2beecc796615bcb64b36e6.tar.gz
linux-stable-b349de4c91e6ad761c2beecc796615bcb64b36e6.tar.bz2
linux-stable-b349de4c91e6ad761c2beecc796615bcb64b36e6.zip
Merge tag 'rtc-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "The isl1208 dirver was reworked tobe able to work as part of an MFD. All the Loongson chips are now supported through a new driver, the old one is removed. Summary: Subsystem: - Switch i2c drivers back to use .probe() - Constify pointers to hwmon_channel_info New driver: - Loongson on chip RTC, replacing the Loongson 1 only driver Drivers: - isl1208: cleanup and support for RAA215300 - st-lpc: cleanups - stm32: fix wakeup" * tag 'rtc-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (21 commits) rtc: Add rtc driver for the Loongson family chips rtc: Remove the Loongson-1 RTC driver dt-bindings: rtc: Split loongson,ls2x-rtc into SoC-based compatibles rtc: rv3028: make rv3028 probeable from userspace rtc: isl1208: Add support for the built-in RTC on the PMIC RAA215300 rtc: isl1208: Add isl1208_set_xtoscb() rtc: isl1208: Drop enum isl1208_id and split isl1208_configs[] rtc: isl1208: Make similar I2C and DT-based matching table rtc: isl1208: Drop name variable dt-bindings: rtc: isil,isl1208: Document clock and clock-names properties dt-bindings: rtc: isl1208: Convert to json-schema rtc: st-lpc: Simplify clk handling in st_rtc_probe() rtc: st-lpc: Release some resources in st_rtc_probe() in case of error rtc: stm32: remove dedicated wakeup management dt-bindings: rtc: restrict node name suffixes rtc: add HAS_IOPORT dependencies rtc: Switch i2c drivers back to use .probe() rtc: rv3032: constify pointers to hwmon_channel_info rtc: isl12022: constify pointers to hwmon_channel_info rtc: ds3232: constify pointers to hwmon_channel_info ...
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig27
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-ab-b5ze-s3.c2
-rw-r--r--drivers/rtc/rtc-ab-eoz9.c4
-rw-r--r--drivers/rtc/rtc-abx80x.c2
-rw-r--r--drivers/rtc/rtc-bq32k.c2
-rw-r--r--drivers/rtc/rtc-ds1307.c2
-rw-r--r--drivers/rtc/rtc-ds1374.c2
-rw-r--r--drivers/rtc/rtc-ds1672.c2
-rw-r--r--drivers/rtc/rtc-ds3232.c4
-rw-r--r--drivers/rtc/rtc-em3027.c2
-rw-r--r--drivers/rtc/rtc-fm3130.c2
-rw-r--r--drivers/rtc/rtc-hym8563.c2
-rw-r--r--drivers/rtc/rtc-isl12022.c4
-rw-r--r--drivers/rtc/rtc-isl12026.c2
-rw-r--r--drivers/rtc/rtc-isl1208.c132
-rw-r--r--drivers/rtc/rtc-loongson.c397
-rw-r--r--drivers/rtc/rtc-ls1x.c192
-rw-r--r--drivers/rtc/rtc-m41t80.c2
-rw-r--r--drivers/rtc/rtc-max6900.c2
-rw-r--r--drivers/rtc/rtc-nct3018y.c2
-rw-r--r--drivers/rtc/rtc-pcf2127.c2
-rw-r--r--drivers/rtc/rtc-pcf85063.c2
-rw-r--r--drivers/rtc/rtc-pcf8523.c2
-rw-r--r--drivers/rtc/rtc-pcf85363.c2
-rw-r--r--drivers/rtc/rtc-pcf8563.c2
-rw-r--r--drivers/rtc/rtc-pcf8583.c2
-rw-r--r--drivers/rtc/rtc-rs5c372.c2
-rw-r--r--drivers/rtc/rtc-rv3028.c9
-rw-r--r--drivers/rtc/rtc-rv3029c2.c2
-rw-r--r--drivers/rtc/rtc-rv3032.c4
-rw-r--r--drivers/rtc/rtc-rv8803.c2
-rw-r--r--drivers/rtc/rtc-rx6110.c2
-rw-r--r--drivers/rtc/rtc-rx8010.c2
-rw-r--r--drivers/rtc/rtc-rx8025.c2
-rw-r--r--drivers/rtc/rtc-rx8581.c2
-rw-r--r--drivers/rtc/rtc-s35390a.c2
-rw-r--r--drivers/rtc/rtc-sd3078.c2
-rw-r--r--drivers/rtc/rtc-st-lpc.c16
-rw-r--r--drivers/rtc/rtc-stm32.c28
-rw-r--r--drivers/rtc/rtc-x1205.c2
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,
};