diff options
Diffstat (limited to 'drivers/rtc')
94 files changed, 1595 insertions, 2188 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index bb63edb507da..753872408615 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -433,7 +433,7 @@ config RTC_DRV_ISL12022 config RTC_DRV_ISL12026 tristate "Intersil ISL12026" - depends on OF || COMPILE_TEST + depends on OF help If you say yes here you get support for the Intersil ISL12026 RTC chip. @@ -540,12 +540,6 @@ config RTC_DRV_BQ32K This driver can also be built as a module. If so, the module will be called rtc-bq32k. -config RTC_DRV_DM355EVM - tristate "TI DaVinci DM355 EVM RTC" - depends on MFD_DM355EVM_MSP - help - Supports the RTC firmware in the MSP430 on the DM355 EVM. - config RTC_DRV_TWL92330 bool "TI TWL92330/Menelaus" depends on MENELAUS @@ -1218,15 +1212,6 @@ config RTC_DRV_RP5C01 This driver can also be built as a module. If so, the module will be called rtc-rp5c01. -config RTC_DRV_V3020 - tristate "EM Microelectronic V3020" - help - If you say yes here you will get support for the - EM Microelectronic v3020 RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-v3020. - config RTC_DRV_GAMECUBE tristate "Nintendo GameCube, Wii and Wii U RTC" depends on GAMECUBE || WII || COMPILE_TEST @@ -1351,16 +1336,6 @@ config RTC_DRV_ASM9260 This driver can also be built as a module. If so, the module will be called rtc-asm9260. -config RTC_DRV_DAVINCI - tristate "TI DaVinci RTC" - depends on ARCH_DAVINCI_DM365 || COMPILE_TEST - help - If you say yes here you get support for the RTC on the - DaVinci platforms (DM365). - - This driver can also be built as a module. If so, the module - will be called rtc-davinci. - config RTC_DRV_DIGICOLOR tristate "Conexant Digicolor RTC" depends on ARCH_DIGICOLOR || COMPILE_TEST @@ -1431,18 +1406,14 @@ config RTC_DRV_OMAP config RTC_DRV_S3C tristate "Samsung S3C series SoC RTC" - depends on ARCH_EXYNOS || ARCH_S3C64XX || ARCH_S3C24XX || ARCH_S5PV210 || \ + depends on ARCH_EXYNOS || ARCH_S3C64XX || ARCH_S5PV210 || \ COMPILE_TEST help RTC (Realtime Clock) driver for the clock inbuilt into the - Samsung S3C24XX series of SoCs. This can provide periodic + Samsung S3C64XX series of SoCs. This can provide periodic interrupt rates from 1Hz to 64Hz for user programs, and wakeup from Alarm. - The driver currently supports the common features on all the - S3C24XX range, such as the S3C2410, S3C2412, S3C2413, S3C2440 - and S3C2442. - This driver can also be build as a module. If so, the module will be called rtc-s3c. @@ -1706,7 +1677,7 @@ config RTC_DRV_MPC5121 config RTC_DRV_JZ4740 tristate "Ingenic JZ4740 SoC" depends on MIPS || COMPILE_TEST - depends on OF + depends on OF && COMMON_CLK help If you say yes here you get support for the Ingenic JZ47xx SoCs RTC controllers. @@ -1802,6 +1773,18 @@ config RTC_DRV_SNVS This driver can also be built as a module, if so, the module will be called "rtc-snvs". +config RTC_DRV_BBNSM + tristate "NXP BBNSM RTC support" + select REGMAP_MMIO + depends on ARCH_MXC || COMPILE_TEST + depends on HAS_IOMEM + depends on OF + help + If you say yes here you get support for the NXP BBNSM RTC module. + + This driver can also be built as a module, if so, the module + will be called "rtc-bbnsm". + config RTC_DRV_IMX_SC depends on IMX_SCU depends on HAVE_ARM_SMCCC @@ -1987,7 +1970,7 @@ config RTC_DRV_MSC313 config RTC_DRV_POLARFIRE_SOC tristate "Microchip PolarFire SoC built-in RTC" - depends on SOC_MICROCHIP_POLARFIRE + depends on ARCH_MICROCHIP_POLARFIRE help If you say yes here you will get support for the built-in RTC on Polarfire SoC. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index aab22bc63432..ea445d1ebb17 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_RTC_DRV_ASPEED) += rtc-aspeed.o obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o +obj-$(CONFIG_RTC_DRV_BBNSM) += rtc-nxp-bbnsm.o obj-$(CONFIG_RTC_DRV_BD70528) += rtc-bd70528.o obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o @@ -44,9 +45,7 @@ obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o -obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o -obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o @@ -178,7 +177,6 @@ obj-$(CONFIG_RTC_DRV_TI_K3) += rtc-ti-k3.o obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o -obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o obj-$(CONFIG_RTC_DRV_WILCO_EC) += rtc-wilco-ec.o obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index e48223c00c67..edfd942f8c54 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -374,11 +374,11 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev) rtc->id = id; rtc->dev.parent = dev; - err = dev_set_name(&rtc->dev, "rtc%d", id); + err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc); if (err) return ERR_PTR(err); - err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc); + err = dev_set_name(&rtc->dev, "rtc%d", id); if (err) return ERR_PTR(err); @@ -475,7 +475,7 @@ EXPORT_SYMBOL_GPL(devm_rtc_device_register); static int __init rtc_init(void) { - rtc_class = class_create(THIS_MODULE, "rtc"); + rtc_class = class_create("rtc"); if (IS_ERR(rtc_class)) { pr_err("couldn't create class\n"); return PTR_ERR(rtc_class); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 9edd662c69ac..499d89150afc 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -256,7 +256,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) * * This could all instead be done in the lower level driver, * but since more than one lower level RTC implementation needs it, - * then it's probably best best to do it here instead of there.. + * then it's probably best to do it here instead of there.. */ /* Get the "before" timestamp */ @@ -392,7 +392,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) return err; if (!rtc->ops) { err = -ENODEV; - } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) { + } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features)) { err = -EINVAL; } else { memset(alarm, 0, sizeof(struct rtc_wkalrm)); diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index 6a3f44cf6ebe..f40cc06b0979 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c @@ -317,11 +317,10 @@ out: return ret; } -static int pm80x_rtc_remove(struct platform_device *pdev) +static void pm80x_rtc_remove(struct platform_device *pdev) { struct pm80x_rtc_info *info = platform_get_drvdata(pdev); pm80x_free_irq(info->chip, info->irq, info); - return 0; } static struct platform_driver pm80x_rtc_driver = { @@ -330,7 +329,7 @@ static struct platform_driver pm80x_rtc_driver = { .pm = &pm80x_rtc_pm_ops, }, .probe = pm80x_rtc_probe, - .remove = pm80x_rtc_remove, + .remove_new = pm80x_rtc_remove, }; module_platform_driver(pm80x_rtc_driver); diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 2c809a1a445e..0f124ed5b3e5 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -331,7 +331,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev) return 0; } -static int pm860x_rtc_remove(struct platform_device *pdev) +static void pm860x_rtc_remove(struct platform_device *pdev) { struct pm860x_rtc_info *info = platform_get_drvdata(pdev); @@ -340,8 +340,6 @@ static int pm860x_rtc_remove(struct platform_device *pdev) /* disable measurement */ pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); #endif /* VRTC_CALIBRATION */ - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -373,7 +371,7 @@ static struct platform_driver pm860x_rtc_driver = { .pm = &pm860x_rtc_pm_ops, }, .probe = pm860x_rtc_probe, - .remove = pm860x_rtc_remove, + .remove_new = pm860x_rtc_remove, }; module_platform_driver(pm860x_rtc_driver); diff --git a/drivers/rtc/rtc-ab-eoz9.c b/drivers/rtc/rtc-ab-eoz9.c index 2f8deb8c4cd3..34611f6dedcb 100644 --- a/drivers/rtc/rtc-ab-eoz9.c +++ b/drivers/rtc/rtc-ab-eoz9.c @@ -536,9 +536,14 @@ static int abeoz9_probe(struct i2c_client *client) clear_bit(RTC_FEATURE_ALARM, data->rtc->features); if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + ret = devm_request_threaded_irq(dev, client->irq, NULL, abeoz9_rtc_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, dev_name(dev), dev); if (ret) { dev_err(dev, "failed to request alarm irq\n"); diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index ea33e149d545..75bb2ac9005c 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -392,12 +392,10 @@ static int ab8500_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(rtc); } -static int ab8500_rtc_remove(struct platform_device *pdev) +static void ab8500_rtc_remove(struct platform_device *pdev) { dev_pm_clear_wake_irq(&pdev->dev); device_init_wakeup(&pdev->dev, false); - - return 0; } static struct platform_driver ab8500_rtc_driver = { @@ -405,7 +403,7 @@ static struct platform_driver ab8500_rtc_driver = { .name = "ab8500-rtc", }, .probe = ab8500_rtc_probe, - .remove = ab8500_rtc_remove, + .remove_new = ab8500_rtc_remove, .id_table = ab85xx_rtc_ids, }; diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index 9b0138d07232..f34a2e59cac7 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -11,7 +11,9 @@ */ #include <linux/bcd.h> +#include <linux/bitfield.h> #include <linux/i2c.h> +#include <linux/kstrtox.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/rtc.h> @@ -87,6 +89,16 @@ #define ABX8XX_TRICKLE_STANDARD_DIODE 0x8 #define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4 +#define ABX8XX_REG_EXTRAM 0x3f +#define ABX8XX_EXTRAM_XADS GENMASK(1, 0) + +#define ABX8XX_SRAM_BASE 0x40 +#define ABX8XX_SRAM_WIN_SIZE 0x40 +#define ABX8XX_RAM_SIZE 256 + +#define NVMEM_ADDR_LOWER GENMASK(5, 0) +#define NVMEM_ADDR_UPPER GENMASK(7, 6) + static u8 trickle_resistors[] = {0, 3, 6, 11}; enum abx80x_chip {AB0801, AB0803, AB0804, AB0805, @@ -673,13 +685,90 @@ static int abx80x_setup_watchdog(struct abx80x_priv *priv) } #endif -static int abx80x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int abx80x_nvmem_xfer(struct abx80x_priv *priv, unsigned int offset, + void *val, size_t bytes, bool write) +{ + int ret; + + while (bytes) { + u8 extram, reg, len, lower, upper; + + lower = FIELD_GET(NVMEM_ADDR_LOWER, offset); + upper = FIELD_GET(NVMEM_ADDR_UPPER, offset); + extram = FIELD_PREP(ABX8XX_EXTRAM_XADS, upper); + reg = ABX8XX_SRAM_BASE + lower; + len = min(lower + bytes, (size_t)ABX8XX_SRAM_WIN_SIZE) - lower; + len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX); + + ret = i2c_smbus_write_byte_data(priv->client, ABX8XX_REG_EXTRAM, + extram); + if (ret) + return ret; + + if (write) + ret = i2c_smbus_write_i2c_block_data(priv->client, reg, + len, val); + else + ret = i2c_smbus_read_i2c_block_data(priv->client, reg, + len, val); + if (ret) + return ret; + + offset += len; + val += len; + bytes -= len; + } + + return 0; +} + +static int abx80x_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + return abx80x_nvmem_xfer(priv, offset, val, bytes, false); +} + +static int abx80x_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + return abx80x_nvmem_xfer(priv, offset, val, bytes, true); +} + +static int abx80x_setup_nvmem(struct abx80x_priv *priv) +{ + struct nvmem_config config = { + .type = NVMEM_TYPE_BATTERY_BACKED, + .reg_read = abx80x_nvmem_read, + .reg_write = abx80x_nvmem_write, + .size = ABX8XX_RAM_SIZE, + .priv = priv, + }; + + return devm_rtc_nvmem_register(priv->rtc, &config); +} + +static const struct i2c_device_id abx80x_id[] = { + { "abx80x", ABX80X }, + { "ab0801", AB0801 }, + { "ab0803", AB0803 }, + { "ab0804", AB0804 }, + { "ab0805", AB0805 }, + { "ab1801", AB1801 }, + { "ab1803", AB1803 }, + { "ab1804", AB1804 }, + { "ab1805", AB1805 }, + { "rv1805", RV1805 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, abx80x_id); + +static int abx80x_probe(struct i2c_client *client) { struct device_node *np = client->dev.of_node; struct abx80x_priv *priv; int i, data, err, trickle_cfg = -EINVAL; char buf[7]; + const struct i2c_device_id *id = i2c_match_id(abx80x_id, client); unsigned int part = id->driver_data; unsigned int partnumber; unsigned int majrev, minrev; @@ -824,6 +913,10 @@ static int abx80x_probe(struct i2c_client *client, return err; } + err = abx80x_setup_nvmem(priv); + if (err) + return err; + if (client->irq > 0) { dev_info(&client->dev, "IRQ %d supplied\n", client->irq); err = devm_request_threaded_irq(&client->dev, client->irq, NULL, @@ -847,21 +940,6 @@ static int abx80x_probe(struct i2c_client *client, return devm_rtc_register_device(priv->rtc); } -static const struct i2c_device_id abx80x_id[] = { - { "abx80x", ABX80X }, - { "ab0801", AB0801 }, - { "ab0803", AB0803 }, - { "ab0804", AB0804 }, - { "ab0805", AB0805 }, - { "ab1801", AB1801 }, - { "ab1803", AB1803 }, - { "ab1804", AB1804 }, - { "ab1805", AB1805 }, - { "rv1805", RV1805 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, abx80x_id); - #ifdef CONFIG_OF static const struct of_device_id abx80x_of_match[] = { { @@ -914,7 +992,7 @@ static struct i2c_driver abx80x_driver = { .name = "rtc-abx80x", .of_match_table = of_match_ptr(abx80x_of_match), }, - .probe = abx80x_probe, + .probe_new = abx80x_probe, .id_table = abx80x_id, }; diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 66783cb5e711..eaf2c9ab9661 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c @@ -613,13 +613,11 @@ static int ac100_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(chip->rtc); } -static int ac100_rtc_remove(struct platform_device *pdev) +static void ac100_rtc_remove(struct platform_device *pdev) { struct ac100_rtc_dev *chip = platform_get_drvdata(pdev); ac100_rtc_unregister_clks(chip); - - return 0; } static const struct of_device_id ac100_rtc_match[] = { @@ -630,7 +628,7 @@ MODULE_DEVICE_TABLE(of, ac100_rtc_match); static struct platform_driver ac100_rtc_driver = { .probe = ac100_rtc_probe, - .remove = ac100_rtc_remove, + .remove_new = ac100_rtc_remove, .driver = { .name = "ac100-rtc", .of_match_table = of_match_ptr(ac100_rtc_match), diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index cc542e6b1d5b..b4139c200676 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c @@ -491,7 +491,6 @@ MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table); static __init int armada38x_rtc_probe(struct platform_device *pdev) { - struct resource *res; struct armada38x_rtc *rtc; rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc), @@ -508,12 +507,10 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev) spin_lock_init(&rtc->lock); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); - rtc->regs = devm_ioremap_resource(&pdev->dev, res); + rtc->regs = devm_platform_ioremap_resource_byname(pdev, "rtc"); if (IS_ERR(rtc->regs)) return PTR_ERR(rtc->regs); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc"); - rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res); + rtc->regs_soc = devm_platform_ioremap_resource_byname(pdev, "rtc-soc"); if (IS_ERR(rtc->regs_soc)) return PTR_ERR(rtc->regs_soc); diff --git a/drivers/rtc/rtc-asm9260.c b/drivers/rtc/rtc-asm9260.c index de795e489f71..a83b47e0d8f5 100644 --- a/drivers/rtc/rtc-asm9260.c +++ b/drivers/rtc/rtc-asm9260.c @@ -308,14 +308,13 @@ err_return: return ret; } -static int asm9260_rtc_remove(struct platform_device *pdev) +static void asm9260_rtc_remove(struct platform_device *pdev) { struct asm9260_rtc_priv *priv = platform_get_drvdata(pdev); /* Disable alarm matching */ iowrite32(BM_AMR_OFF, priv->iobase + HW_AMR); clk_disable_unprepare(priv->clk); - return 0; } static const struct of_device_id asm9260_dt_ids[] = { @@ -326,7 +325,7 @@ MODULE_DEVICE_TABLE(of, asm9260_dt_ids); static struct platform_driver asm9260_rtc_driver = { .probe = asm9260_rtc_probe, - .remove = asm9260_rtc_remove, + .remove_new = asm9260_rtc_remove, .driver = { .name = "asm9260-rtc", .of_match_table = asm9260_dt_ids, diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index fe396d27ebb7..e9d17232d0a8 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -130,7 +130,7 @@ static void at91_rtc_write_idr(u32 mask) * * Note that there is still a possibility that the mask is updated * before interrupts have actually been disabled in hardware. The only - * way to be certain would be to poll the IMR-register, which is is + * way to be certain would be to poll the IMR-register, which is * the very register we are trying to emulate. The register read back * is a reasonable heuristic. */ diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index b7b5ea1a4e67..610f27dfc462 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -442,7 +442,7 @@ err_clk: /* * Disable and remove the RTC driver */ -static int at91_rtc_remove(struct platform_device *pdev) +static void at91_rtc_remove(struct platform_device *pdev) { struct sam9_rtc *rtc = platform_get_drvdata(pdev); u32 mr = rtt_readl(rtc, MR); @@ -451,8 +451,6 @@ static int at91_rtc_remove(struct platform_device *pdev) rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); clk_disable_unprepare(rtc->sclk); - - return 0; } static void at91_rtc_shutdown(struct platform_device *pdev) @@ -531,7 +529,7 @@ MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids); static struct platform_driver at91_rtc_driver = { .probe = at91_rtc_probe, - .remove = at91_rtc_remove, + .remove_new = at91_rtc_remove, .shutdown = at91_rtc_shutdown, .driver = { .name = "rtc-at91sam9", diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 6d6a55efb9cc..967ddc6bf76d 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -13,6 +13,7 @@ #include <linux/i2c.h> #include <linux/rtc.h> #include <linux/init.h> +#include <linux/kstrtox.h> #include <linux/errno.h> #include <linux/bcd.h> diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c index c74130e8f496..3cdc015692ca 100644 --- a/drivers/rtc/rtc-brcmstb-waketimer.c +++ b/drivers/rtc/rtc-brcmstb-waketimer.c @@ -27,13 +27,17 @@ struct brcmstb_waketmr { struct rtc_device *rtc; struct device *dev; void __iomem *base; - int irq; + unsigned int wake_irq; + unsigned int alarm_irq; struct notifier_block reboot_notifier; struct clk *clk; u32 rate; + unsigned long rtc_alarm; + bool alarm_en; }; #define BRCMSTB_WKTMR_EVENT 0x00 +#define WKTMR_ALARM_EVENT BIT(0) #define BRCMSTB_WKTMR_COUNTER 0x04 #define BRCMSTB_WKTMR_ALARM 0x08 #define BRCMSTB_WKTMR_PRESCALER 0x0C @@ -41,28 +45,71 @@ struct brcmstb_waketmr { #define BRCMSTB_WKTMR_DEFAULT_FREQ 27000000 +static inline bool brcmstb_waketmr_is_pending(struct brcmstb_waketmr *timer) +{ + u32 reg; + + reg = readl_relaxed(timer->base + BRCMSTB_WKTMR_EVENT); + return !!(reg & WKTMR_ALARM_EVENT); +} + static inline void brcmstb_waketmr_clear_alarm(struct brcmstb_waketmr *timer) { - writel_relaxed(1, timer->base + BRCMSTB_WKTMR_EVENT); + u32 reg; + + if (timer->alarm_en && timer->alarm_irq) + disable_irq(timer->alarm_irq); + timer->alarm_en = false; + reg = readl_relaxed(timer->base + BRCMSTB_WKTMR_COUNTER); + writel_relaxed(reg - 1, timer->base + BRCMSTB_WKTMR_ALARM); + writel_relaxed(WKTMR_ALARM_EVENT, timer->base + BRCMSTB_WKTMR_EVENT); (void)readl_relaxed(timer->base + BRCMSTB_WKTMR_EVENT); } static void brcmstb_waketmr_set_alarm(struct brcmstb_waketmr *timer, unsigned int secs) { + unsigned int now; + brcmstb_waketmr_clear_alarm(timer); /* Make sure we are actually counting in seconds */ writel_relaxed(timer->rate, timer->base + BRCMSTB_WKTMR_PRESCALER); - writel_relaxed(secs + 1, timer->base + BRCMSTB_WKTMR_ALARM); + writel_relaxed(secs, timer->base + BRCMSTB_WKTMR_ALARM); + now = readl_relaxed(timer->base + BRCMSTB_WKTMR_COUNTER); + + while ((int)(secs - now) <= 0 && + !brcmstb_waketmr_is_pending(timer)) { + secs = now + 1; + writel_relaxed(secs, timer->base + BRCMSTB_WKTMR_ALARM); + now = readl_relaxed(timer->base + BRCMSTB_WKTMR_COUNTER); + } } static irqreturn_t brcmstb_waketmr_irq(int irq, void *data) { struct brcmstb_waketmr *timer = data; - pm_wakeup_event(timer->dev, 0); + if (!timer->alarm_irq) + pm_wakeup_event(timer->dev, 0); + return IRQ_HANDLED; +} + +static irqreturn_t brcmstb_alarm_irq(int irq, void *data) +{ + struct brcmstb_waketmr *timer = data; + + /* Ignore spurious interrupts */ + if (!brcmstb_waketmr_is_pending(timer)) + return IRQ_HANDLED; + + if (timer->alarm_en) { + if (!device_may_wakeup(timer->dev)) + writel_relaxed(WKTMR_ALARM_EVENT, + timer->base + BRCMSTB_WKTMR_EVENT); + rtc_update_irq(timer->rtc, 1, RTC_IRQF | RTC_AF); + } return IRQ_HANDLED; } @@ -88,17 +135,25 @@ static void wktmr_read(struct brcmstb_waketmr *timer, static int brcmstb_waketmr_prepare_suspend(struct brcmstb_waketmr *timer) { struct device *dev = timer->dev; - int ret = 0; + int ret; if (device_may_wakeup(dev)) { - ret = enable_irq_wake(timer->irq); + ret = enable_irq_wake(timer->wake_irq); if (ret) { dev_err(dev, "failed to enable wake-up interrupt\n"); return ret; } + if (timer->alarm_en && timer->alarm_irq) { + ret = enable_irq_wake(timer->alarm_irq); + if (ret) { + dev_err(dev, "failed to enable rtc interrupt\n"); + disable_irq_wake(timer->wake_irq); + return ret; + } + } } - return ret; + return 0; } /* If enabled as a wakeup-source, arm the timer when powering off */ @@ -146,46 +201,47 @@ static int brcmstb_waketmr_getalarm(struct device *dev, struct rtc_wkalrm *alarm) { struct brcmstb_waketmr *timer = dev_get_drvdata(dev); - time64_t sec; - u32 reg; - sec = readl_relaxed(timer->base + BRCMSTB_WKTMR_ALARM); - if (sec != 0) { - /* Alarm is enabled */ - alarm->enabled = 1; - rtc_time64_to_tm(sec, &alarm->time); - } + alarm->enabled = timer->alarm_en; + rtc_time64_to_tm(timer->rtc_alarm, &alarm->time); - reg = readl_relaxed(timer->base + BRCMSTB_WKTMR_EVENT); - alarm->pending = !!(reg & 1); + alarm->pending = brcmstb_waketmr_is_pending(timer); return 0; } -static int brcmstb_waketmr_setalarm(struct device *dev, - struct rtc_wkalrm *alarm) +static int brcmstb_waketmr_alarm_enable(struct device *dev, + unsigned int enabled) { struct brcmstb_waketmr *timer = dev_get_drvdata(dev); - time64_t sec; - - if (alarm->enabled) - sec = rtc_tm_to_time64(&alarm->time); - else - sec = 0; - brcmstb_waketmr_set_alarm(timer, sec); + if (enabled && !timer->alarm_en) { + if ((int)(readl_relaxed(timer->base + BRCMSTB_WKTMR_COUNTER) - + readl_relaxed(timer->base + BRCMSTB_WKTMR_ALARM)) >= 0 && + !brcmstb_waketmr_is_pending(timer)) + return -EINVAL; + timer->alarm_en = true; + if (timer->alarm_irq) + enable_irq(timer->alarm_irq); + } else if (!enabled && timer->alarm_en) { + if (timer->alarm_irq) + disable_irq(timer->alarm_irq); + timer->alarm_en = false; + } return 0; } -/* - * Does not do much but keep the RTC class happy. We always support - * alarms. - */ -static int brcmstb_waketmr_alarm_enable(struct device *dev, - unsigned int enabled) +static int brcmstb_waketmr_setalarm(struct device *dev, + struct rtc_wkalrm *alarm) { - return 0; + struct brcmstb_waketmr *timer = dev_get_drvdata(dev); + + timer->rtc_alarm = rtc_tm_to_time64(&alarm->time); + + brcmstb_waketmr_set_alarm(timer, timer->rtc_alarm); + + return brcmstb_waketmr_alarm_enable(dev, alarm->enabled); } static const struct rtc_class_ops brcmstb_waketmr_ops = { @@ -221,12 +277,12 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) * Set wakeup capability before requesting wakeup interrupt, so we can * process boot-time "wakeups" (e.g., from S5 soft-off) */ - device_set_wakeup_capable(dev, true); - device_wakeup_enable(dev); + device_init_wakeup(dev, true); - timer->irq = platform_get_irq(pdev, 0); - if (timer->irq < 0) + ret = platform_get_irq(pdev, 0); + if (ret < 0) return -ENODEV; + timer->wake_irq = (unsigned int)ret; timer->clk = devm_clk_get(dev, NULL); if (!IS_ERR(timer->clk)) { @@ -241,11 +297,24 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) timer->clk = NULL; } - ret = devm_request_irq(dev, timer->irq, brcmstb_waketmr_irq, 0, + ret = devm_request_irq(dev, timer->wake_irq, brcmstb_waketmr_irq, 0, "brcmstb-waketimer", timer); if (ret < 0) goto err_clk; + brcmstb_waketmr_clear_alarm(timer); + + /* Attempt to initialize non-wake irq */ + ret = platform_get_irq(pdev, 1); + if (ret > 0) { + timer->alarm_irq = (unsigned int)ret; + ret = devm_request_irq(dev, timer->alarm_irq, brcmstb_alarm_irq, + IRQF_NO_AUTOEN, "brcmstb-waketimer-rtc", + timer); + if (ret < 0) + timer->alarm_irq = 0; + } + timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot; register_reboot_notifier(&timer->reboot_notifier); @@ -256,8 +325,6 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) if (ret) goto err_notifier; - dev_info(dev, "registered, with irq %d\n", timer->irq); - return 0; err_notifier: @@ -269,14 +336,12 @@ err_clk: return ret; } -static int brcmstb_waketmr_remove(struct platform_device *pdev) +static void brcmstb_waketmr_remove(struct platform_device *pdev) { struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev); unregister_reboot_notifier(&timer->reboot_notifier); clk_disable_unprepare(timer->clk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -295,7 +360,9 @@ static int brcmstb_waketmr_resume(struct device *dev) if (!device_may_wakeup(dev)) return 0; - ret = disable_irq_wake(timer->irq); + ret = disable_irq_wake(timer->wake_irq); + if (timer->alarm_en && timer->alarm_irq) + disable_irq_wake(timer->alarm_irq); brcmstb_waketmr_clear_alarm(timer); @@ -313,7 +380,7 @@ static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = { static struct platform_driver brcmstb_waketmr_driver = { .probe = brcmstb_waketmr_probe, - .remove = brcmstb_waketmr_remove, + .remove_new = brcmstb_waketmr_remove, .driver = { .name = "brcmstb-waketimer", .pm = &brcmstb_waketmr_pm_ops, @@ -325,4 +392,5 @@ module_platform_driver(brcmstb_waketmr_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Brian Norris"); MODULE_AUTHOR("Markus Mayer"); +MODULE_AUTHOR("Doug Berger"); MODULE_DESCRIPTION("Wake-up timer driver for STB chips"); diff --git a/drivers/rtc/rtc-cadence.c b/drivers/rtc/rtc-cadence.c index 1edf7f16d73a..4ca60b519836 100644 --- a/drivers/rtc/rtc-cadence.c +++ b/drivers/rtc/rtc-cadence.c @@ -354,7 +354,7 @@ err_disable_pclk: return ret; } -static int cdns_rtc_remove(struct platform_device *pdev) +static void cdns_rtc_remove(struct platform_device *pdev) { struct cdns_rtc *crtc = platform_get_drvdata(pdev); @@ -363,8 +363,6 @@ static int cdns_rtc_remove(struct platform_device *pdev) clk_disable_unprepare(crtc->pclk); clk_disable_unprepare(crtc->ref_clk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -404,7 +402,7 @@ static struct platform_driver cdns_rtc_driver = { .pm = &cdns_rtc_pm_ops, }, .probe = cdns_rtc_probe, - .remove = cdns_rtc_remove, + .remove_new = cdns_rtc_remove, }; module_platform_driver(cdns_rtc_driver); diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 58cc2bae2f8a..c9416fe8542d 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -744,6 +744,168 @@ static irqreturn_t cmos_interrupt(int irq, void *p) return IRQ_NONE; } +#ifdef CONFIG_ACPI + +#include <linux/acpi.h> + +static u32 rtc_handler(void *context) +{ + struct device *dev = context; + struct cmos_rtc *cmos = dev_get_drvdata(dev); + unsigned char rtc_control = 0; + unsigned char rtc_intr; + unsigned long flags; + + + /* + * Always update rtc irq when ACPI is used as RTC Alarm. + * Or else, ACPI SCI is enabled during suspend/resume only, + * update rtc irq in that case. + */ + if (cmos_use_acpi_alarm()) + cmos_interrupt(0, (void *)cmos->rtc); + else { + /* Fix me: can we use cmos_interrupt() here as well? */ + spin_lock_irqsave(&rtc_lock, flags); + if (cmos_rtc.suspend_ctrl) + rtc_control = CMOS_READ(RTC_CONTROL); + if (rtc_control & RTC_AIE) { + cmos_rtc.suspend_ctrl &= ~RTC_AIE; + CMOS_WRITE(rtc_control, RTC_CONTROL); + rtc_intr = CMOS_READ(RTC_INTR_FLAGS); + rtc_update_irq(cmos->rtc, 1, rtc_intr); + } + spin_unlock_irqrestore(&rtc_lock, flags); + } + + pm_wakeup_hard_event(dev); + acpi_clear_event(ACPI_EVENT_RTC); + acpi_disable_event(ACPI_EVENT_RTC, 0); + return ACPI_INTERRUPT_HANDLED; +} + +static void acpi_rtc_event_setup(struct device *dev) +{ + if (acpi_disabled) + return; + + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev); + /* + * After the RTC handler is installed, the Fixed_RTC event should + * be disabled. Only when the RTC alarm is set will it be enabled. + */ + acpi_clear_event(ACPI_EVENT_RTC); + acpi_disable_event(ACPI_EVENT_RTC, 0); +} + +static void acpi_rtc_event_cleanup(void) +{ + if (acpi_disabled) + return; + + acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler); +} + +static void rtc_wake_on(struct device *dev) +{ + acpi_clear_event(ACPI_EVENT_RTC); + acpi_enable_event(ACPI_EVENT_RTC, 0); +} + +static void rtc_wake_off(struct device *dev) +{ + acpi_disable_event(ACPI_EVENT_RTC, 0); +} + +#ifdef CONFIG_X86 +/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */ +static void use_acpi_alarm_quirks(void) +{ + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return; + + if (!is_hpet_enabled()) + return; + + if (dmi_get_bios_year() < 2015) + return; + + use_acpi_alarm = true; +} +#else +static inline void use_acpi_alarm_quirks(void) { } +#endif + +static void acpi_cmos_wake_setup(struct device *dev) +{ + if (acpi_disabled) + return; + + use_acpi_alarm_quirks(); + + cmos_rtc.wake_on = rtc_wake_on; + cmos_rtc.wake_off = rtc_wake_off; + + /* ACPI tables bug workaround. */ + if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { + dev_dbg(dev, "bogus FADT month_alarm (%d)\n", + acpi_gbl_FADT.month_alarm); + acpi_gbl_FADT.month_alarm = 0; + } + + cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm; + cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm; + cmos_rtc.century = acpi_gbl_FADT.century; + + if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) + dev_info(dev, "RTC can wake from S4\n"); + + /* RTC always wakes from S1/S2/S3, and often S4/STD */ + device_init_wakeup(dev, 1); +} + +static void cmos_check_acpi_rtc_status(struct device *dev, + unsigned char *rtc_control) +{ + struct cmos_rtc *cmos = dev_get_drvdata(dev); + acpi_event_status rtc_status; + acpi_status status; + + if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC) + return; + + status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status); + if (ACPI_FAILURE(status)) { + dev_err(dev, "Could not get RTC status\n"); + } else if (rtc_status & ACPI_EVENT_FLAG_SET) { + unsigned char mask; + *rtc_control &= ~RTC_AIE; + CMOS_WRITE(*rtc_control, RTC_CONTROL); + mask = CMOS_READ(RTC_INTR_FLAGS); + rtc_update_irq(cmos->rtc, 1, mask); + } +} + +#else /* !CONFIG_ACPI */ + +static inline void acpi_rtc_event_setup(struct device *dev) +{ +} + +static inline void acpi_rtc_event_cleanup(void) +{ +} + +static inline void acpi_cmos_wake_setup(struct device *dev) +{ +} + +static inline void cmos_check_acpi_rtc_status(struct device *dev, + unsigned char *rtc_control) +{ +} +#endif /* CONFIG_ACPI */ + #ifdef CONFIG_PNP #define INITSECTION @@ -827,19 +989,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) if (info->address_space) address_space = info->address_space; - if (info->rtc_day_alarm && info->rtc_day_alarm < 128) - cmos_rtc.day_alrm = info->rtc_day_alarm; - if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128) - cmos_rtc.mon_alrm = info->rtc_mon_alarm; - if (info->rtc_century && info->rtc_century < 128) - cmos_rtc.century = info->rtc_century; + cmos_rtc.day_alrm = info->rtc_day_alarm; + cmos_rtc.mon_alrm = info->rtc_mon_alarm; + cmos_rtc.century = info->rtc_century; if (info->wake_on && info->wake_off) { cmos_rtc.wake_on = info->wake_on; cmos_rtc.wake_off = info->wake_off; } + } else { + acpi_cmos_wake_setup(dev); } + if (cmos_rtc.day_alrm >= 128) + cmos_rtc.day_alrm = 0; + + if (cmos_rtc.mon_alrm >= 128) + cmos_rtc.mon_alrm = 0; + + if (cmos_rtc.century >= 128) + cmos_rtc.century = 0; + cmos_rtc.dev = dev; dev_set_drvdata(dev, &cmos_rtc); @@ -928,6 +1098,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) nvmem_cfg.size = address_space - NVRAM_OFFSET; devm_rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg); + /* + * Everything has gone well so far, so by default register a handler for + * the ACPI RTC fixed event. + */ + if (!info) + acpi_rtc_event_setup(dev); + dev_info(dev, "%s%s, %d bytes nvram%s\n", !is_valid_irq(rtc_irq) ? "no alarms" : cmos_rtc.mon_alrm ? "alarms up to one year" : @@ -973,6 +1150,9 @@ static void cmos_do_remove(struct device *dev) hpet_unregister_irq_handler(cmos_interrupt); } + if (!dev_get_platdata(dev)) + acpi_rtc_event_cleanup(); + cmos->rtc = NULL; ports = cmos->iomem; @@ -1122,9 +1302,6 @@ static void cmos_check_wkalrm(struct device *dev) } } -static void cmos_check_acpi_rtc_status(struct device *dev, - unsigned char *rtc_control); - static int __maybe_unused cmos_resume(struct device *dev) { struct cmos_rtc *cmos = dev_get_drvdata(dev); @@ -1191,175 +1368,13 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume); * predate even PNPBIOS should set up platform_bus devices. */ -#ifdef CONFIG_ACPI - -#include <linux/acpi.h> - -static u32 rtc_handler(void *context) -{ - struct device *dev = context; - struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned char rtc_control = 0; - unsigned char rtc_intr; - unsigned long flags; - - - /* - * Always update rtc irq when ACPI is used as RTC Alarm. - * Or else, ACPI SCI is enabled during suspend/resume only, - * update rtc irq in that case. - */ - if (cmos_use_acpi_alarm()) - cmos_interrupt(0, (void *)cmos->rtc); - else { - /* Fix me: can we use cmos_interrupt() here as well? */ - spin_lock_irqsave(&rtc_lock, flags); - if (cmos_rtc.suspend_ctrl) - rtc_control = CMOS_READ(RTC_CONTROL); - if (rtc_control & RTC_AIE) { - cmos_rtc.suspend_ctrl &= ~RTC_AIE; - CMOS_WRITE(rtc_control, RTC_CONTROL); - rtc_intr = CMOS_READ(RTC_INTR_FLAGS); - rtc_update_irq(cmos->rtc, 1, rtc_intr); - } - spin_unlock_irqrestore(&rtc_lock, flags); - } - - pm_wakeup_hard_event(dev); - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); - return ACPI_INTERRUPT_HANDLED; -} - -static inline void rtc_wake_setup(struct device *dev) -{ - if (acpi_disabled) - return; - - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev); - /* - * After the RTC handler is installed, the Fixed_RTC event should - * be disabled. Only when the RTC alarm is set will it be enabled. - */ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); -} - -static void rtc_wake_on(struct device *dev) -{ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_enable_event(ACPI_EVENT_RTC, 0); -} - -static void rtc_wake_off(struct device *dev) -{ - acpi_disable_event(ACPI_EVENT_RTC, 0); -} - -#ifdef CONFIG_X86 -/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */ -static void use_acpi_alarm_quirks(void) -{ - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return; - - if (!is_hpet_enabled()) - return; - - if (dmi_get_bios_year() < 2015) - return; - - use_acpi_alarm = true; -} -#else -static inline void use_acpi_alarm_quirks(void) { } -#endif - -/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find - * its device node and pass extra config data. This helps its driver use - * capabilities that the now-obsolete mc146818 didn't have, and informs it - * that this board's RTC is wakeup-capable (per ACPI spec). - */ -static struct cmos_rtc_board_info acpi_rtc_info; - -static void cmos_wake_setup(struct device *dev) -{ - if (acpi_disabled) - return; - - use_acpi_alarm_quirks(); - - acpi_rtc_info.wake_on = rtc_wake_on; - acpi_rtc_info.wake_off = rtc_wake_off; - - /* workaround bug in some ACPI tables */ - if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { - dev_dbg(dev, "bogus FADT month_alarm (%d)\n", - acpi_gbl_FADT.month_alarm); - acpi_gbl_FADT.month_alarm = 0; - } - - acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; - acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; - acpi_rtc_info.rtc_century = acpi_gbl_FADT.century; - - /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ - if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) - dev_info(dev, "RTC can wake from S4\n"); - - dev->platform_data = &acpi_rtc_info; - - /* RTC always wakes from S1/S2/S3, and often S4/STD */ - device_init_wakeup(dev, 1); -} - -static void cmos_check_acpi_rtc_status(struct device *dev, - unsigned char *rtc_control) -{ - struct cmos_rtc *cmos = dev_get_drvdata(dev); - acpi_event_status rtc_status; - acpi_status status; - - if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC) - return; - - status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status); - if (ACPI_FAILURE(status)) { - dev_err(dev, "Could not get RTC status\n"); - } else if (rtc_status & ACPI_EVENT_FLAG_SET) { - unsigned char mask; - *rtc_control &= ~RTC_AIE; - CMOS_WRITE(*rtc_control, RTC_CONTROL); - mask = CMOS_READ(RTC_INTR_FLAGS); - rtc_update_irq(cmos->rtc, 1, mask); - } -} - -#else - -static void cmos_wake_setup(struct device *dev) -{ -} - -static void cmos_check_acpi_rtc_status(struct device *dev, - unsigned char *rtc_control) -{ -} - -static void rtc_wake_setup(struct device *dev) -{ -} -#endif - #ifdef CONFIG_PNP #include <linux/pnp.h> static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) { - int irq, ret; - - cmos_wake_setup(&pnp->dev); + int irq; if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) { irq = 0; @@ -1375,13 +1390,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) irq = pnp_irq(pnp, 0); } - ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); - if (ret) - return ret; - - rtc_wake_setup(&pnp->dev); - - return 0; + return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); } static void cmos_pnp_remove(struct pnp_dev *pnp) @@ -1465,10 +1474,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {} static int __init cmos_platform_probe(struct platform_device *pdev) { struct resource *resource; - int irq, ret; + int irq; cmos_of_init(pdev); - cmos_wake_setup(&pdev->dev); if (RTC_IOMAPPED) resource = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -1478,19 +1486,12 @@ static int __init cmos_platform_probe(struct platform_device *pdev) if (irq < 0) irq = -1; - ret = cmos_do_probe(&pdev->dev, resource, irq); - if (ret) - return ret; - - rtc_wake_setup(&pdev->dev); - - return 0; + return cmos_do_probe(&pdev->dev, resource, irq); } -static int cmos_platform_remove(struct platform_device *pdev) +static void cmos_platform_remove(struct platform_device *pdev) { cmos_do_remove(&pdev->dev); - return 0; } static void cmos_platform_shutdown(struct platform_device *pdev) @@ -1512,7 +1513,7 @@ static void cmos_platform_shutdown(struct platform_device *pdev) MODULE_ALIAS("platform:rtc_cmos"); static struct platform_driver cmos_platform_driver = { - .remove = cmos_platform_remove, + .remove_new = cmos_platform_remove, .shutdown = cmos_platform_shutdown, .driver = { .name = driver_name, diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c index 887f5193e253..998ab8606f0b 100644 --- a/drivers/rtc/rtc-cros-ec.c +++ b/drivers/rtc/rtc-cros-ec.c @@ -14,6 +14,8 @@ #define DRV_NAME "cros-ec-rtc" +#define SECS_PER_DAY (24 * 60 * 60) + /** * struct cros_ec_rtc - Driver data for EC RTC * @@ -43,13 +45,8 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command, msg.msg.insize = sizeof(msg.data); ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); - if (ret < 0) { - dev_err(cros_ec->dev, - "error getting %s from EC: %d\n", - command == EC_CMD_RTC_GET_VALUE ? "time" : "alarm", - ret); + if (ret < 0) return ret; - } *response = msg.data.time; @@ -59,7 +56,7 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command, static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command, u32 param) { - int ret = 0; + int ret; struct { struct cros_ec_command msg; struct ec_response_rtc data; @@ -71,13 +68,8 @@ static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command, msg.data.time = param; ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); - if (ret < 0) { - dev_err(cros_ec->dev, "error setting %s on EC: %d\n", - command == EC_CMD_RTC_SET_VALUE ? "time" : "alarm", - ret); + if (ret < 0) return ret; - } - return 0; } @@ -190,8 +182,21 @@ static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset); if (ret < 0) { - dev_err(dev, "error setting alarm: %d\n", ret); - return ret; + if (ret == -EINVAL && alarm_offset >= SECS_PER_DAY) { + /* + * RTC chips on some older Chromebooks can only handle + * alarms up to 24h in the future. Try to set an alarm + * below that limit to avoid suspend failures. + */ + ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, + SECS_PER_DAY - 1); + } + + if (ret < 0) { + dev_err(dev, "error setting alarm in %u seconds: %d\n", + alarm_offset, ret); + return ret; + } } return 0; @@ -366,7 +371,7 @@ static int cros_ec_rtc_probe(struct platform_device *pdev) return 0; } -static int cros_ec_rtc_remove(struct platform_device *pdev) +static void cros_ec_rtc_remove(struct platform_device *pdev) { struct cros_ec_rtc *cros_ec_rtc = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; @@ -377,13 +382,11 @@ static int cros_ec_rtc_remove(struct platform_device *pdev) &cros_ec_rtc->notifier); if (ret) dev_err(dev, "failed to unregister notifier\n"); - - return 0; } static struct platform_driver cros_ec_rtc_driver = { .probe = cros_ec_rtc_probe, - .remove = cros_ec_rtc_remove, + .remove_new = cros_ec_rtc_remove, .driver = { .name = DRV_NAME, .pm = &cros_ec_rtc_pm_ops, diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c deleted file mode 100644 index 6bef0f2353da..000000000000 --- a/drivers/rtc/rtc-davinci.c +++ /dev/null @@ -1,512 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * DaVinci Power Management and Real Time Clock Driver for TI platforms - * - * Copyright (C) 2009 Texas Instruments, Inc - * - * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/rtc.h> -#include <linux/bcd.h> -#include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/slab.h> - -/* - * The DaVinci RTC is a simple RTC with the following - * Sec: 0 - 59 : BCD count - * Min: 0 - 59 : BCD count - * Hour: 0 - 23 : BCD count - * Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years ) - */ - -/* PRTC interface registers */ -#define DAVINCI_PRTCIF_PID 0x00 -#define PRTCIF_CTLR 0x04 -#define PRTCIF_LDATA 0x08 -#define PRTCIF_UDATA 0x0C -#define PRTCIF_INTEN 0x10 -#define PRTCIF_INTFLG 0x14 - -/* PRTCIF_CTLR bit fields */ -#define PRTCIF_CTLR_BUSY BIT(31) -#define PRTCIF_CTLR_SIZE BIT(25) -#define PRTCIF_CTLR_DIR BIT(24) -#define PRTCIF_CTLR_BENU_MSB BIT(23) -#define PRTCIF_CTLR_BENU_3RD_BYTE BIT(22) -#define PRTCIF_CTLR_BENU_2ND_BYTE BIT(21) -#define PRTCIF_CTLR_BENU_LSB BIT(20) -#define PRTCIF_CTLR_BENU_MASK (0x00F00000) -#define PRTCIF_CTLR_BENL_MSB BIT(19) -#define PRTCIF_CTLR_BENL_3RD_BYTE BIT(18) -#define PRTCIF_CTLR_BENL_2ND_BYTE BIT(17) -#define PRTCIF_CTLR_BENL_LSB BIT(16) -#define PRTCIF_CTLR_BENL_MASK (0x000F0000) - -/* PRTCIF_INTEN bit fields */ -#define PRTCIF_INTEN_RTCSS BIT(1) -#define PRTCIF_INTEN_RTCIF BIT(0) -#define PRTCIF_INTEN_MASK (PRTCIF_INTEN_RTCSS \ - | PRTCIF_INTEN_RTCIF) - -/* PRTCIF_INTFLG bit fields */ -#define PRTCIF_INTFLG_RTCSS BIT(1) -#define PRTCIF_INTFLG_RTCIF BIT(0) -#define PRTCIF_INTFLG_MASK (PRTCIF_INTFLG_RTCSS \ - | PRTCIF_INTFLG_RTCIF) - -/* PRTC subsystem registers */ -#define PRTCSS_RTC_INTC_EXTENA1 (0x0C) -#define PRTCSS_RTC_CTRL (0x10) -#define PRTCSS_RTC_WDT (0x11) -#define PRTCSS_RTC_TMR0 (0x12) -#define PRTCSS_RTC_TMR1 (0x13) -#define PRTCSS_RTC_CCTRL (0x14) -#define PRTCSS_RTC_SEC (0x15) -#define PRTCSS_RTC_MIN (0x16) -#define PRTCSS_RTC_HOUR (0x17) -#define PRTCSS_RTC_DAY0 (0x18) -#define PRTCSS_RTC_DAY1 (0x19) -#define PRTCSS_RTC_AMIN (0x1A) -#define PRTCSS_RTC_AHOUR (0x1B) -#define PRTCSS_RTC_ADAY0 (0x1C) -#define PRTCSS_RTC_ADAY1 (0x1D) -#define PRTCSS_RTC_CLKC_CNT (0x20) - -/* PRTCSS_RTC_INTC_EXTENA1 */ -#define PRTCSS_RTC_INTC_EXTENA1_MASK (0x07) - -/* PRTCSS_RTC_CTRL bit fields */ -#define PRTCSS_RTC_CTRL_WDTBUS BIT(7) -#define PRTCSS_RTC_CTRL_WEN BIT(6) -#define PRTCSS_RTC_CTRL_WDRT BIT(5) -#define PRTCSS_RTC_CTRL_WDTFLG BIT(4) -#define PRTCSS_RTC_CTRL_TE BIT(3) -#define PRTCSS_RTC_CTRL_TIEN BIT(2) -#define PRTCSS_RTC_CTRL_TMRFLG BIT(1) -#define PRTCSS_RTC_CTRL_TMMD BIT(0) - -/* PRTCSS_RTC_CCTRL bit fields */ -#define PRTCSS_RTC_CCTRL_CALBUSY BIT(7) -#define PRTCSS_RTC_CCTRL_DAEN BIT(5) -#define PRTCSS_RTC_CCTRL_HAEN BIT(4) -#define PRTCSS_RTC_CCTRL_MAEN BIT(3) -#define PRTCSS_RTC_CCTRL_ALMFLG BIT(2) -#define PRTCSS_RTC_CCTRL_AIEN BIT(1) -#define PRTCSS_RTC_CCTRL_CAEN BIT(0) - -static DEFINE_SPINLOCK(davinci_rtc_lock); - -struct davinci_rtc { - struct rtc_device *rtc; - void __iomem *base; - int irq; -}; - -static inline void rtcif_write(struct davinci_rtc *davinci_rtc, - u32 val, u32 addr) -{ - writel(val, davinci_rtc->base + addr); -} - -static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr) -{ - return readl(davinci_rtc->base + addr); -} - -static inline void rtcif_wait(struct davinci_rtc *davinci_rtc) -{ - while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY) - cpu_relax(); -} - -static inline void rtcss_write(struct davinci_rtc *davinci_rtc, - unsigned long val, u8 addr) -{ - rtcif_wait(davinci_rtc); - - rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR); - rtcif_write(davinci_rtc, val, PRTCIF_LDATA); - - rtcif_wait(davinci_rtc); -} - -static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr) -{ - rtcif_wait(davinci_rtc); - - rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr, - PRTCIF_CTLR); - - rtcif_wait(davinci_rtc); - - return rtcif_read(davinci_rtc, PRTCIF_LDATA); -} - -static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc) -{ - while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) & - PRTCSS_RTC_CCTRL_CALBUSY) - cpu_relax(); -} - -static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev) -{ - struct davinci_rtc *davinci_rtc = class_dev; - unsigned long events = 0; - u32 irq_flg; - u8 alm_irq, tmr_irq; - u8 rtc_ctrl, rtc_cctrl; - int ret = IRQ_NONE; - - irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) & - PRTCIF_INTFLG_RTCSS; - - alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) & - PRTCSS_RTC_CCTRL_ALMFLG; - - tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) & - PRTCSS_RTC_CTRL_TMRFLG; - - if (irq_flg) { - if (alm_irq) { - events |= RTC_IRQF | RTC_AF; - rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL); - rtc_cctrl |= PRTCSS_RTC_CCTRL_ALMFLG; - rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL); - } else if (tmr_irq) { - events |= RTC_IRQF | RTC_PF; - rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); - rtc_ctrl |= PRTCSS_RTC_CTRL_TMRFLG; - rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); - } - - rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, - PRTCIF_INTFLG); - rtc_update_irq(davinci_rtc->rtc, 1, events); - - ret = IRQ_HANDLED; - } - - return ret; -} - -static int -davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - u8 rtc_ctrl; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); - - switch (cmd) { - case RTC_WIE_ON: - rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG; - break; - case RTC_WIE_OFF: - rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN; - break; - default: - ret = -ENOIOCTLCMD; - } - - rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - return ret; -} - -static void convertfromdays(u16 days, struct rtc_time *tm) -{ - int tmp_days, year, mon; - - for (year = 2000;; year++) { - tmp_days = rtc_year_days(1, 12, year); - if (days >= tmp_days) - days -= tmp_days; - else { - for (mon = 0;; mon++) { - tmp_days = rtc_month_days(mon, year); - if (days >= tmp_days) { - days -= tmp_days; - } else { - tm->tm_year = year - 1900; - tm->tm_mon = mon; - tm->tm_mday = days + 1; - break; - } - } - break; - } - } -} - -static void convert2days(u16 *days, struct rtc_time *tm) -{ - int i; - *days = 0; - - for (i = 2000; i < 1900 + tm->tm_year; i++) - *days += rtc_year_days(1, 12, i); - - *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year); -} - -static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - u16 days = 0; - u8 day0, day1; - unsigned long flags; - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - davinci_rtcss_calendar_wait(davinci_rtc); - tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC)); - - davinci_rtcss_calendar_wait(davinci_rtc); - tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN)); - - davinci_rtcss_calendar_wait(davinci_rtc); - tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR)); - - davinci_rtcss_calendar_wait(davinci_rtc); - day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0); - - davinci_rtcss_calendar_wait(davinci_rtc); - day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - days |= day1; - days <<= 8; - days |= day0; - - convertfromdays(days, tm); - - return 0; -} - -static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - u16 days; - u8 rtc_cctrl; - unsigned long flags; - - convert2days(&days, tm); - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1); - - rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL); - rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN; - rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - return 0; -} - -static int davinci_rtc_alarm_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - unsigned long flags; - u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL); - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - if (enabled) - rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN | - PRTCSS_RTC_CCTRL_HAEN | - PRTCSS_RTC_CCTRL_MAEN | - PRTCSS_RTC_CCTRL_ALMFLG | - PRTCSS_RTC_CCTRL_AIEN; - else - rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN; - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - return 0; -} - -static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - u16 days = 0; - u8 day0, day1; - unsigned long flags; - - alm->time.tm_sec = 0; - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - davinci_rtcss_calendar_wait(davinci_rtc); - alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN)); - - davinci_rtcss_calendar_wait(davinci_rtc); - alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR)); - - davinci_rtcss_calendar_wait(davinci_rtc); - day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0); - - davinci_rtcss_calendar_wait(davinci_rtc); - day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - days |= day1; - days <<= 8; - days |= day0; - - convertfromdays(days, &alm->time); - - alm->pending = !!(rtcss_read(davinci_rtc, - PRTCSS_RTC_CCTRL) & - PRTCSS_RTC_CCTRL_AIEN); - alm->enabled = alm->pending && device_may_wakeup(dev); - - return 0; -} - -static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - unsigned long flags; - u16 days; - - convert2days(&days, &alm->time); - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0); - - davinci_rtcss_calendar_wait(davinci_rtc); - rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - return 0; -} - -static const struct rtc_class_ops davinci_rtc_ops = { - .ioctl = davinci_rtc_ioctl, - .read_time = davinci_rtc_read_time, - .set_time = davinci_rtc_set_time, - .alarm_irq_enable = davinci_rtc_alarm_irq_enable, - .read_alarm = davinci_rtc_read_alarm, - .set_alarm = davinci_rtc_set_alarm, -}; - -static int __init davinci_rtc_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct davinci_rtc *davinci_rtc; - int ret = 0; - - davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL); - if (!davinci_rtc) - return -ENOMEM; - - davinci_rtc->irq = platform_get_irq(pdev, 0); - if (davinci_rtc->irq < 0) - return davinci_rtc->irq; - - davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(davinci_rtc->base)) - return PTR_ERR(davinci_rtc->base); - - platform_set_drvdata(pdev, davinci_rtc); - - davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(davinci_rtc->rtc)) - return PTR_ERR(davinci_rtc->rtc); - - davinci_rtc->rtc->ops = &davinci_rtc_ops; - davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; - davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1; - - rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); - rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); - rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1); - - rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL); - rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL); - - ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt, - 0, "davinci_rtc", davinci_rtc); - if (ret < 0) { - dev_err(dev, "unable to register davinci RTC interrupt\n"); - return ret; - } - - /* Enable interrupts */ - rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN); - rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK, - PRTCSS_RTC_INTC_EXTENA1); - - rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL); - - device_init_wakeup(&pdev->dev, 0); - - return devm_rtc_register_device(davinci_rtc->rtc); -} - -static int __exit davinci_rtc_remove(struct platform_device *pdev) -{ - struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev); - - device_init_wakeup(&pdev->dev, 0); - - rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); - - return 0; -} - -static struct platform_driver davinci_rtc_driver = { - .remove = __exit_p(davinci_rtc_remove), - .driver = { - .name = "rtc_davinci", - }, -}; - -module_platform_driver_probe(davinci_rtc_driver, davinci_rtc_probe); - -MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>"); -MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c deleted file mode 100644 index 94fb16ac3e0f..000000000000 --- a/drivers/rtc/rtc-dm355evm.c +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware - * - * Copyright (c) 2008 by David Brownell - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/rtc.h> -#include <linux/platform_device.h> - -#include <linux/mfd/dm355evm_msp.h> -#include <linux/module.h> - - -/* - * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed - * a 1 Hz counter. When a backup battery is supplied, that makes a - * reasonable RTC for applications where alarms and non-NTP drift - * compensation aren't important. - * - * The only real glitch is the inability to read or write all four - * counter bytes atomically: the count may increment in the middle - * of an operation, causing trouble when the LSB rolls over. - * - * This driver was tested with firmware revision A4. - */ -union evm_time { - u8 bytes[4]; - u32 value; -}; - -static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - union evm_time time; - int status; - int tries = 0; - - do { - /* - * Read LSB(0) to MSB(3) bytes. Defend against the counter - * rolling over by re-reading until the value is stable, - * and assuming the four reads take at most a few seconds. - */ - status = dm355evm_msp_read(DM355EVM_MSP_RTC_0); - if (status < 0) - return status; - if (tries && time.bytes[0] == status) - break; - time.bytes[0] = status; - - status = dm355evm_msp_read(DM355EVM_MSP_RTC_1); - if (status < 0) - return status; - if (tries && time.bytes[1] == status) - break; - time.bytes[1] = status; - - status = dm355evm_msp_read(DM355EVM_MSP_RTC_2); - if (status < 0) - return status; - if (tries && time.bytes[2] == status) - break; - time.bytes[2] = status; - - status = dm355evm_msp_read(DM355EVM_MSP_RTC_3); - if (status < 0) - return status; - if (tries && time.bytes[3] == status) - break; - time.bytes[3] = status; - - } while (++tries < 5); - - dev_dbg(dev, "read timestamp %08x\n", time.value); - - rtc_time64_to_tm(le32_to_cpu(time.value), tm); - return 0; -} - -static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - union evm_time time; - unsigned long value; - int status; - - value = rtc_tm_to_time64(tm); - time.value = cpu_to_le32(value); - - dev_dbg(dev, "write timestamp %08x\n", time.value); - - /* - * REVISIT handle non-atomic writes ... maybe just retry until - * byte[1] sticks (no rollover)? - */ - status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0); - if (status < 0) - return status; - - status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1); - if (status < 0) - return status; - - status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2); - if (status < 0) - return status; - - status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3); - if (status < 0) - return status; - - return 0; -} - -static const struct rtc_class_ops dm355evm_rtc_ops = { - .read_time = dm355evm_rtc_read_time, - .set_time = dm355evm_rtc_set_time, -}; - -/*----------------------------------------------------------------------*/ - -static int dm355evm_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc; - - rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(pdev, rtc); - - rtc->ops = &dm355evm_rtc_ops; - rtc->range_max = U32_MAX; - - return devm_rtc_register_device(rtc); -} - -/* - * I2C is used to talk to the MSP430, but this platform device is - * exposed by an MFD driver that manages I2C communications. - */ -static struct platform_driver rtc_dm355evm_driver = { - .probe = dm355evm_rtc_probe, - .driver = { - .name = "rtc-dm355evm", - }, -}; - -module_platform_driver(rtc_dm355evm_driver); - -MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 6d66ab5a8b17..ecc7d0307932 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -185,11 +185,6 @@ static int ds1302_probe(struct spi_device *spi) return 0; } -static void ds1302_remove(struct spi_device *spi) -{ - spi_set_drvdata(spi, NULL); -} - #ifdef CONFIG_OF static const struct of_device_id ds1302_dt_ids[] = { { .compatible = "maxim,ds1302", }, @@ -208,7 +203,6 @@ static struct spi_driver ds1302_driver = { .driver.name = "rtc-ds1302", .driver.of_match_table = of_match_ptr(ds1302_dt_ids), .probe = ds1302_probe, - .remove = ds1302_remove, .id_table = ds1302_spi_ids, }; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index d51565bcc189..e86ba84df6cb 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -11,6 +11,7 @@ #include <linux/bcd.h> #include <linux/i2c.h> #include <linux/init.h> +#include <linux/kstrtox.h> #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/property.h> @@ -1218,8 +1219,7 @@ static ssize_t frequency_test_show(struct device *dev, regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg); - return scnprintf(buf, PAGE_SIZE, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" : - "off\n"); + return sysfs_emit(buf, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" : "off\n"); } static DEVICE_ATTR_RW(frequency_test); @@ -1712,9 +1712,9 @@ static const struct regmap_config regmap_config = { .val_bits = 8, }; -static int ds1307_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ds1307_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct ds1307 *ds1307; const void *match; int err = -ENODEV; @@ -2011,7 +2011,7 @@ static struct i2c_driver ds1307_driver = { .name = "rtc-ds1307", .of_match_table = ds1307_of_match, }, - .probe = ds1307_probe, + .probe_new = ds1307_probe, .id_table = ds1307_id, }; diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c index 157bf5209ac4..a40c1a52df65 100644 --- a/drivers/rtc/rtc-ds1347.c +++ b/drivers/rtc/rtc-ds1347.c @@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt) return err; century = (dt->tm_year / 100) + 19; - err = regmap_write(map, DS1347_CENTURY_REG, century); + err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century)); if (err) return err; diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index 93ce72b9ae59..f46428ca77cc 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -213,7 +213,7 @@ static int ds1390_probe(struct spi_device *spi) return res; } -static const struct of_device_id ds1390_of_match[] = { +static const struct of_device_id ds1390_of_match[] __maybe_unused = { { .compatible = "dallas,ds1390" }, {} }; diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 5db9c737c022..0f707be0eb87 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -1322,7 +1322,7 @@ ds1685_rtc_probe(struct platform_device *pdev) * ds1685_rtc_remove - removes rtc driver. * @pdev: pointer to platform_device structure. */ -static int +static void ds1685_rtc_remove(struct platform_device *pdev) { struct ds1685_priv *rtc = platform_get_drvdata(pdev); @@ -1344,8 +1344,6 @@ ds1685_rtc_remove(struct platform_device *pdev) rtc->write(rtc, RTC_EXT_CTRL_4A, (rtc->read(rtc, RTC_EXT_CTRL_4A) & ~(RTC_CTRL_4A_RWK_MASK))); - - return 0; } /* @@ -1356,7 +1354,7 @@ static struct platform_driver ds1685_rtc_driver = { .name = "rtc-ds1685", }, .probe = ds1685_rtc_probe, - .remove = ds1685_rtc_remove, + .remove_new = ds1685_rtc_remove, }; module_platform_driver(ds1685_rtc_driver); /* ----------------------------------------------------------------------- */ diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 13d45c697da6..a5026b0514e7 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -158,8 +158,7 @@ static int ds1742_rtc_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ioaddr = devm_ioremap_resource(&pdev->dev, res); + ioaddr = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(ioaddr)) return PTR_ERR(ioaddr); diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index 11850c2880ad..dc6b0f4a54e2 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -164,7 +164,7 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm) if (status != EFI_SUCCESS) { /* should never happen */ - dev_err(dev, "can't read time\n"); + dev_err_once(dev, "can't read time\n"); return -EINVAL; } @@ -188,9 +188,10 @@ static int efi_set_time(struct device *dev, struct rtc_time *tm) static int efi_procfs(struct device *dev, struct seq_file *seq) { - efi_time_t eft, alm; - efi_time_cap_t cap; - efi_bool_t enabled, pending; + efi_time_t eft, alm; + efi_time_cap_t cap; + efi_bool_t enabled, pending; + struct rtc_device *rtc = dev_get_drvdata(dev); memset(&eft, 0, sizeof(eft)); memset(&alm, 0, sizeof(alm)); @@ -213,23 +214,25 @@ static int efi_procfs(struct device *dev, struct seq_file *seq) /* XXX fixme: convert to string? */ seq_printf(seq, "Timezone\t: %u\n", eft.timezone); - seq_printf(seq, - "Alarm Time\t: %u:%u:%u.%09u\n" - "Alarm Date\t: %u-%u-%u\n" - "Alarm Daylight\t: %u\n" - "Enabled\t\t: %s\n" - "Pending\t\t: %s\n", - alm.hour, alm.minute, alm.second, alm.nanosecond, - alm.year, alm.month, alm.day, - alm.daylight, - enabled == 1 ? "yes" : "no", - pending == 1 ? "yes" : "no"); - - if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) - seq_puts(seq, "Timezone\t: unspecified\n"); - else - /* XXX fixme: convert to string? */ - seq_printf(seq, "Timezone\t: %u\n", alm.timezone); + if (test_bit(RTC_FEATURE_ALARM, rtc->features)) { + seq_printf(seq, + "Alarm Time\t: %u:%u:%u.%09u\n" + "Alarm Date\t: %u-%u-%u\n" + "Alarm Daylight\t: %u\n" + "Enabled\t\t: %s\n" + "Pending\t\t: %s\n", + alm.hour, alm.minute, alm.second, alm.nanosecond, + alm.year, alm.month, alm.day, + alm.daylight, + enabled == 1 ? "yes" : "no", + pending == 1 ? "yes" : "no"); + + if (eft.timezone == EFI_UNSPECIFIED_TIMEZONE) + seq_puts(seq, "Timezone\t: unspecified\n"); + else + /* XXX fixme: convert to string? */ + seq_printf(seq, "Timezone\t: %u\n", alm.timezone); + } /* * now prints the capabilities @@ -269,7 +272,12 @@ static int __init efi_rtc_probe(struct platform_device *dev) rtc->ops = &efi_rtc_ops; clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); - set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); + if (efi_rt_services_supported(EFI_RT_SUPPORTED_WAKEUP_SERVICES)) + set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); + else + clear_bit(RTC_FEATURE_ALARM, rtc->features); + + device_init_wakeup(&dev->dev, true); return devm_rtc_register_device(rtc); } diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c index c0df49fb978c..3d7c4077fe1c 100644 --- a/drivers/rtc/rtc-fsl-ftm-alarm.c +++ b/drivers/rtc/rtc-fsl-ftm-alarm.c @@ -327,12 +327,7 @@ static struct platform_driver ftm_rtc_driver = { }, }; -static int __init ftm_alarm_init(void) -{ - return platform_driver_register(&ftm_rtc_driver); -} - -device_initcall(ftm_alarm_init); +module_platform_driver(ftm_rtc_driver); MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver"); MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>"); diff --git a/drivers/rtc/rtc-ftrtc010.c b/drivers/rtc/rtc-ftrtc010.c index 25c6e7d9570f..8bfe7378f653 100644 --- a/drivers/rtc/rtc-ftrtc010.c +++ b/drivers/rtc/rtc-ftrtc010.c @@ -191,7 +191,7 @@ err_disable_pclk: return ret; } -static int ftrtc010_rtc_remove(struct platform_device *pdev) +static void ftrtc010_rtc_remove(struct platform_device *pdev) { struct ftrtc010_rtc *rtc = platform_get_drvdata(pdev); @@ -199,8 +199,6 @@ static int ftrtc010_rtc_remove(struct platform_device *pdev) clk_disable_unprepare(rtc->extclk); if (!IS_ERR(rtc->pclk)) clk_disable_unprepare(rtc->pclk); - - return 0; } static const struct of_device_id ftrtc010_rtc_dt_match[] = { @@ -216,7 +214,7 @@ static struct platform_driver ftrtc010_rtc_driver = { .of_match_table = ftrtc010_rtc_dt_match, }, .probe = ftrtc010_rtc_probe, - .remove = ftrtc010_rtc_remove, + .remove_new = ftrtc010_rtc_remove, }; module_platform_driver_probe(ftrtc010_rtc_driver, ftrtc010_rtc_probe); diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index 16fdefafec5d..b81cea505ee9 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c @@ -296,14 +296,12 @@ err_open: return ret; } -static int hid_time_remove(struct platform_device *pdev) +static void hid_time_remove(struct platform_device *pdev) { struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); sensor_hub_device_close(hsdev); sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME); - - return 0; } static const struct platform_device_id hid_time_ids[] = { @@ -321,7 +319,7 @@ static struct platform_driver hid_time_platform_driver = { .name = KBUILD_MODNAME, }, .probe = hid_time_probe, - .remove = hid_time_remove, + .remove_new = hid_time_remove, }; module_platform_driver(hid_time_platform_driver); diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index cc710d682121..7d5a298a9a3b 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -518,9 +518,14 @@ static int hym8563_probe(struct i2c_client *client) } if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, hym8563_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, client->name, hym8563); if (ret < 0) { dev_err(&client->dev, "irq %d request failed, %d\n", diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index ca677c4265e6..e68a79b5e00e 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -8,15 +8,16 @@ * by Alessandro Zummo <a.zummo@towertech.it>. */ -#include <linux/i2c.h> #include <linux/bcd.h> -#include <linux/rtc.h> -#include <linux/slab.h> -#include <linux/module.h> #include <linux/err.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/hwmon.h> +#include <linux/i2c.h> +#include <linux/module.h> #include <linux/regmap.h> +#include <linux/rtc.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> /* ISL register offsets */ #define ISL12022_REG_SC 0x00 @@ -30,6 +31,9 @@ #define ISL12022_REG_SR 0x07 #define ISL12022_REG_INT 0x08 +#define ISL12022_REG_BETA 0x0d +#define ISL12022_REG_TEMP_L 0x28 + /* ISL register bits */ #define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */ @@ -38,22 +42,98 @@ #define ISL12022_INT_WRTC (1 << 6) +#define ISL12022_BETA_TSE (1 << 7) -static struct i2c_driver isl12022_driver; +static umode_t isl12022_hwmon_is_visible(const void *data, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + if (type == hwmon_temp && attr == hwmon_temp_input) + return 0444; -struct isl12022 { - struct rtc_device *rtc; - struct regmap *regmap; + return 0; +} + +/* + * A user-initiated temperature conversion is not started by this function, + * so the temperature is updated once every ~60 seconds. + */ +static int isl12022_hwmon_read_temp(struct device *dev, long *mC) +{ + struct regmap *regmap = dev_get_drvdata(dev); + int temp, ret; + __le16 buf; + + ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L, &buf, sizeof(buf)); + if (ret) + return ret; + /* + * Temperature is represented as a 10-bit number, unit half-Kelvins. + */ + temp = le16_to_cpu(buf); + temp *= 500; + temp -= 273000; + + *mC = temp; + + return 0; +} + +static int isl12022_hwmon_read(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + if (type == hwmon_temp && attr == hwmon_temp_input) + return isl12022_hwmon_read_temp(dev, val); + + return -EOPNOTSUPP; +} + +static const struct hwmon_channel_info *isl12022_hwmon_info[] = { + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), + NULL +}; + +static const struct hwmon_ops isl12022_hwmon_ops = { + .is_visible = isl12022_hwmon_is_visible, + .read = isl12022_hwmon_read, }; +static const struct hwmon_chip_info isl12022_hwmon_chip_info = { + .ops = &isl12022_hwmon_ops, + .info = isl12022_hwmon_info, +}; + +static void isl12022_hwmon_register(struct device *dev) +{ + struct regmap *regmap = dev_get_drvdata(dev); + struct device *hwmon; + int ret; + + if (!IS_REACHABLE(CONFIG_HWMON)) + return; + + ret = regmap_update_bits(regmap, ISL12022_REG_BETA, + ISL12022_BETA_TSE, ISL12022_BETA_TSE); + if (ret) { + dev_warn(dev, "unable to enable temperature sensor\n"); + return; + } + + hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", regmap, + &isl12022_hwmon_chip_info, + NULL); + if (IS_ERR(hwmon)) + dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon); +} + /* * In the routines that deal directly with the isl12022 hardware, we use * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. */ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct isl12022 *isl12022 = dev_get_drvdata(dev); - struct regmap *regmap = isl12022->regmap; + struct regmap *regmap = dev_get_drvdata(dev); uint8_t buf[ISL12022_REG_INT + 1]; int ret; @@ -63,16 +143,12 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) if (buf[ISL12022_REG_SR] & (ISL12022_SR_LBAT85 | ISL12022_SR_LBAT75)) { dev_warn(dev, - "voltage dropped below %u%%, " - "date and time is not reliable.\n", + "voltage dropped below %u%%, date and time is not reliable.\n", buf[ISL12022_REG_SR] & ISL12022_SR_LBAT85 ? 85 : 75); } dev_dbg(dev, - "%s: raw data is sec=%02x, min=%02x, hr=%02x, " - "mday=%02x, mon=%02x, year=%02x, wday=%02x, " - "sr=%02x, int=%02x", - __func__, + "raw data is sec=%02x, min=%02x, hr=%02x, mday=%02x, mon=%02x, year=%02x, wday=%02x, sr=%02x, int=%02x", buf[ISL12022_REG_SC], buf[ISL12022_REG_MN], buf[ISL12022_REG_HR], @@ -98,8 +174,7 @@ static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct isl12022 *isl12022 = dev_get_drvdata(dev); - struct regmap *regmap = isl12022->regmap; + struct regmap *regmap = dev_get_drvdata(dev); int ret; uint8_t buf[ISL12022_REG_DW + 1]; @@ -126,8 +201,7 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm) buf[ISL12022_REG_DW] = tm->tm_wday & 0x07; - return regmap_bulk_write(isl12022->regmap, ISL12022_REG_SC, - buf, sizeof(buf)); + return regmap_bulk_write(regmap, ISL12022_REG_SC, buf, sizeof(buf)); } static const struct rtc_class_ops isl12022_rtc_ops = { @@ -143,42 +217,39 @@ static const struct regmap_config regmap_config = { static int isl12022_probe(struct i2c_client *client) { - struct isl12022 *isl12022; + struct rtc_device *rtc; + struct regmap *regmap; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - isl12022 = devm_kzalloc(&client->dev, sizeof(struct isl12022), - GFP_KERNEL); - if (!isl12022) - return -ENOMEM; - dev_set_drvdata(&client->dev, isl12022); - - isl12022->regmap = devm_regmap_init_i2c(client, ®map_config); - if (IS_ERR(isl12022->regmap)) { + regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(regmap)) { dev_err(&client->dev, "regmap allocation failed\n"); - return PTR_ERR(isl12022->regmap); + return PTR_ERR(regmap); } - isl12022->rtc = devm_rtc_allocate_device(&client->dev); - if (IS_ERR(isl12022->rtc)) - return PTR_ERR(isl12022->rtc); + dev_set_drvdata(&client->dev, regmap); + + isl12022_hwmon_register(&client->dev); + + rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); - isl12022->rtc->ops = &isl12022_rtc_ops; - isl12022->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; - isl12022->rtc->range_max = RTC_TIMESTAMP_END_2099; + rtc->ops = &isl12022_rtc_ops; + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->range_max = RTC_TIMESTAMP_END_2099; - return devm_rtc_register_device(isl12022->rtc); + return devm_rtc_register_device(rtc); } -#ifdef CONFIG_OF static const struct of_device_id isl12022_dt_match[] = { { .compatible = "isl,isl12022" }, /* for backward compat., don't use */ { .compatible = "isil,isl12022" }, { }, }; MODULE_DEVICE_TABLE(of, isl12022_dt_match); -#endif static const struct i2c_device_id isl12022_id[] = { { "isl12022", 0 }, @@ -189,9 +260,7 @@ MODULE_DEVICE_TABLE(i2c, isl12022_id); static struct i2c_driver isl12022_driver = { .driver = { .name = "rtc-isl12022", -#ifdef CONFIG_OF - .of_match_table = of_match_ptr(isl12022_dt_match), -#endif + .of_match_table = isl12022_dt_match, }, .probe_new = isl12022_probe, .id_table = isl12022_id, diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index f448a525333e..73cc6aaf9b8b 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -797,7 +797,7 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq) } static int -isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) +isl1208_probe(struct i2c_client *client) { int rc = 0; struct isl1208_state *isl1208; @@ -821,6 +821,8 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!isl1208->config) return -ENODEV; } else { + const struct i2c_device_id *id = i2c_match_id(isl1208_id, client); + if (id->driver_data >= ISL_LAST_ID) return -ENODEV; isl1208->config = &isl1208_configs[id->driver_data]; @@ -906,7 +908,7 @@ static struct i2c_driver isl1208_driver = { .name = "rtc-isl1208", .of_match_table = of_match_ptr(isl1208_of_match), }, - .probe = isl1208_probe, + .probe_new = isl1208_probe, .id_table = isl1208_id, }; diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index c383719292c7..36453b008139 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -6,12 +6,15 @@ */ #include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_wakeirq.h> +#include <linux/property.h> #include <linux/reboot.h> #include <linux/rtc.h> #include <linux/slab.h> @@ -25,6 +28,7 @@ #define JZ_REG_RTC_WAKEUP_FILTER 0x24 #define JZ_REG_RTC_RESET_COUNTER 0x28 #define JZ_REG_RTC_SCRATCHPAD 0x34 +#define JZ_REG_RTC_CKPCR 0x40 /* The following are present on the jz4780 */ #define JZ_REG_RTC_WENR 0x3C @@ -44,6 +48,9 @@ #define JZ_RTC_WAKEUP_FILTER_MASK 0x0000FFE0 #define JZ_RTC_RESET_COUNTER_MASK 0x00000FE0 +#define JZ_RTC_CKPCR_CK32PULL_DIS BIT(4) +#define JZ_RTC_CKPCR_CK32CTL_EN (BIT(2) | BIT(1)) + enum jz4740_rtc_type { ID_JZ4740, ID_JZ4760, @@ -56,6 +63,8 @@ struct jz4740_rtc { struct rtc_device *rtc; + struct clk_hw clk32k; + spinlock_t lock; }; @@ -69,19 +78,15 @@ static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg) static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) { uint32_t ctrl; - int timeout = 10000; - do { - ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); - } while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout); - - return timeout ? 0 : -EIO; + return readl_poll_timeout(rtc->base + JZ_REG_RTC_CTRL, ctrl, + ctrl & JZ_RTC_CTRL_WRDY, 0, 1000); } static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc) { uint32_t ctrl; - int ret, timeout = 10000; + int ret; ret = jz4740_rtc_wait_write_ready(rtc); if (ret != 0) @@ -89,11 +94,8 @@ static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc) writel(JZ_RTC_WENR_MAGIC, rtc->base + JZ_REG_RTC_WENR); - do { - ctrl = readl(rtc->base + JZ_REG_RTC_WENR); - } while (!(ctrl & JZ_RTC_WENR_WEN) && --timeout); - - return timeout ? 0 : -EIO; + return readl_poll_timeout(rtc->base + JZ_REG_RTC_WENR, ctrl, + ctrl & JZ_RTC_WENR_WEN, 0, 1000); } static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg, @@ -260,6 +262,7 @@ static void jz4740_rtc_power_off(void) static const struct of_device_id jz4740_rtc_of_match[] = { { .compatible = "ingenic,jz4740-rtc", .data = (void *)ID_JZ4740 }, { .compatible = "ingenic,jz4760-rtc", .data = (void *)ID_JZ4760 }, + { .compatible = "ingenic,jz4770-rtc", .data = (void *)ID_JZ4780 }, { .compatible = "ingenic,jz4780-rtc", .data = (void *)ID_JZ4780 }, {}, }; @@ -301,6 +304,38 @@ static void jz4740_rtc_set_wakeup_params(struct jz4740_rtc *rtc, jz4740_rtc_reg_write(rtc, JZ_REG_RTC_RESET_COUNTER, reset_ticks); } +static int jz4740_rtc_clk32k_enable(struct clk_hw *hw) +{ + struct jz4740_rtc *rtc = container_of(hw, struct jz4740_rtc, clk32k); + + return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CKPCR, + JZ_RTC_CKPCR_CK32PULL_DIS | + JZ_RTC_CKPCR_CK32CTL_EN); +} + +static void jz4740_rtc_clk32k_disable(struct clk_hw *hw) +{ + struct jz4740_rtc *rtc = container_of(hw, struct jz4740_rtc, clk32k); + + jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CKPCR, 0); +} + +static int jz4740_rtc_clk32k_is_enabled(struct clk_hw *hw) +{ + struct jz4740_rtc *rtc = container_of(hw, struct jz4740_rtc, clk32k); + u32 ckpcr; + + ckpcr = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CKPCR); + + return !!(ckpcr & JZ_RTC_CKPCR_CK32CTL_EN); +} + +static const struct clk_ops jz4740_rtc_clk32k_ops = { + .enable = jz4740_rtc_clk32k_enable, + .disable = jz4740_rtc_clk32k_disable, + .is_enabled = jz4740_rtc_clk32k_is_enabled, +}; + static int jz4740_rtc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -335,17 +370,13 @@ static int jz4740_rtc_probe(struct platform_device *pdev) device_init_wakeup(dev, 1); ret = dev_pm_set_wake_irq(dev, irq); - if (ret) { - dev_err(dev, "Failed to set wake irq: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to set wake irq\n"); rtc->rtc = devm_rtc_allocate_device(dev); - if (IS_ERR(rtc->rtc)) { - ret = PTR_ERR(rtc->rtc); - dev_err(dev, "Failed to allocate rtc device: %d\n", ret); - return ret; - } + if (IS_ERR(rtc->rtc)) + return dev_err_probe(dev, PTR_ERR(rtc->rtc), + "Failed to allocate rtc device\n"); rtc->rtc->ops = &jz4740_rtc_ops; rtc->rtc->range_max = U32_MAX; @@ -362,10 +393,8 @@ static int jz4740_rtc_probe(struct platform_device *pdev) ret = devm_request_irq(dev, irq, jz4740_rtc_irq, 0, pdev->name, rtc); - if (ret) { - dev_err(dev, "Failed to request rtc irq: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to request rtc irq\n"); if (of_device_is_system_power_controller(np)) { dev_for_power_off = dev; @@ -376,6 +405,22 @@ static int jz4740_rtc_probe(struct platform_device *pdev) dev_warn(dev, "Poweroff handler already present!\n"); } + if (device_property_present(dev, "#clock-cells")) { + rtc->clk32k.init = CLK_HW_INIT_HW("clk32k", __clk_get_hw(clk), + &jz4740_rtc_clk32k_ops, 0); + + ret = devm_clk_hw_register(dev, &rtc->clk32k); + if (ret) + return dev_err_probe(dev, ret, + "Unable to register clk32k clock\n"); + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + &rtc->clk32k); + if (ret) + return dev_err_probe(dev, ret, + "Unable to register clk32k clock provider\n"); + } + return 0; } diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c index eec881a81067..a4612e543f35 100644 --- a/drivers/rtc/rtc-lpc24xx.c +++ b/drivers/rtc/rtc-lpc24xx.c @@ -264,7 +264,7 @@ disable_rtc_clk: return ret; } -static int lpc24xx_rtc_remove(struct platform_device *pdev) +static void lpc24xx_rtc_remove(struct platform_device *pdev) { struct lpc24xx_rtc *rtc = platform_get_drvdata(pdev); @@ -276,8 +276,6 @@ static int lpc24xx_rtc_remove(struct platform_device *pdev) clk_disable_unprepare(rtc->clk_rtc); clk_disable_unprepare(rtc->clk_reg); - - return 0; } static const struct of_device_id lpc24xx_rtc_match[] = { @@ -288,7 +286,7 @@ MODULE_DEVICE_TABLE(of, lpc24xx_rtc_match); static struct platform_driver lpc24xx_rtc_driver = { .probe = lpc24xx_rtc_probe, - .remove = lpc24xx_rtc_remove, + .remove_new = lpc24xx_rtc_remove, .driver = { .name = "lpc24xx-rtc", .of_match_table = lpc24xx_rtc_match, diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index e0b4d3794320..c1963f7c424d 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -692,7 +692,7 @@ static void wdt_disable(void) * @ppos: pointer to the position to write. No seeks allowed * * A write to a watchdog device is defined as a keepalive signal. Any - * write of data will do, as we we don't define content meaning. + * write of data will do, as we don't define content meaning. */ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) @@ -876,8 +876,7 @@ static struct notifier_block wdt_notifier = { ***************************************************************************** */ -static int m41t80_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int m41t80_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; int rc = 0; @@ -897,11 +896,13 @@ static int m41t80_probe(struct i2c_client *client, return -ENOMEM; m41t80_data->client = client; - if (client->dev.of_node) + if (client->dev.of_node) { m41t80_data->features = (unsigned long) of_device_get_match_data(&client->dev); - else + } else { + const struct i2c_device_id *id = i2c_match_id(m41t80_id, client); m41t80_data->features = id->driver_data; + } i2c_set_clientdata(client, m41t80_data); m41t80_data->rtc = devm_rtc_allocate_device(&client->dev); @@ -913,9 +914,14 @@ static int m41t80_probe(struct i2c_client *client, "wakeup-source"); #endif if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, m41t80_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "m41t80", client); if (rc) { dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); @@ -1007,7 +1013,7 @@ static struct i2c_driver m41t80_driver = { .of_match_table = of_match_ptr(m41t80_of_match), .pm = &m41t80_pm, }, - .probe = m41t80_probe, + .probe_new = m41t80_probe, .remove = m41t80_remove, .id_table = m41t80_id, }; diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index b0250d91fb00..35a6021d9ba4 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -806,14 +806,12 @@ err_rtc: return ret; } -static int max77686_rtc_remove(struct platform_device *pdev) +static void max77686_rtc_remove(struct platform_device *pdev) { struct max77686_rtc_info *info = platform_get_drvdata(pdev); free_irq(info->virq, info); regmap_del_irq_chip(info->rtc_irq, info->rtc_irq_data); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -877,7 +875,7 @@ static struct platform_driver max77686_rtc_driver = { .pm = &max77686_rtc_pm_ops, }, .probe = max77686_rtc_probe, - .remove = max77686_rtc_remove, + .remove_new = max77686_rtc_remove, .id_table = rtc_id, }; diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c index db3495d10274..af97140dd00a 100644 --- a/drivers/rtc/rtc-max8907.c +++ b/drivers/rtc/rtc-max8907.c @@ -9,7 +9,6 @@ */ #include <linux/bcd.h> -#include <linux/i2c.h> #include <linux/mfd/max8907.h> #include <linux/module.h> #include <linux/platform_device.h> diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index d4234e78497e..763a42f422eb 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -324,7 +324,7 @@ err_irq_request: return ret; } -static int mc13xxx_rtc_remove(struct platform_device *pdev) +static void mc13xxx_rtc_remove(struct platform_device *pdev) { struct mc13xxx_rtc *priv = platform_get_drvdata(pdev); @@ -334,8 +334,6 @@ static int mc13xxx_rtc_remove(struct platform_device *pdev) mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv); mc13xxx_unlock(priv->mc13xxx); - - return 0; } static const struct platform_device_id mc13xxx_rtc_idtable[] = { @@ -352,7 +350,7 @@ MODULE_DEVICE_TABLE(platform, mc13xxx_rtc_idtable); static struct platform_driver mc13xxx_rtc_driver = { .id_table = mc13xxx_rtc_idtable, - .remove = mc13xxx_rtc_remove, + .remove_new = mc13xxx_rtc_remove, .driver = { .name = DRIVER_NAME, }, diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c index 1463c8621561..648fa362ec44 100644 --- a/drivers/rtc/rtc-meson-vrtc.c +++ b/drivers/rtc/rtc-meson-vrtc.c @@ -23,7 +23,7 @@ static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm) struct timespec64 time; dev_dbg(dev, "%s\n", __func__); - ktime_get_raw_ts64(&time); + ktime_get_real_ts64(&time); rtc_time64_to_tm(time.tv_sec, tm); return 0; @@ -96,7 +96,7 @@ static int __maybe_unused meson_vrtc_suspend(struct device *dev) long alarm_secs; struct timespec64 time; - ktime_get_raw_ts64(&time); + ktime_get_real_ts64(&time); local_time = time.tv_sec; dev_dbg(dev, "alarm_time = %lus, local_time=%lus\n", diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c index 6b24ac9e1cfa..2247dd39ee4b 100644 --- a/drivers/rtc/rtc-moxart.c +++ b/drivers/rtc/rtc-moxart.c @@ -10,14 +10,15 @@ * Moxa Technology Co., Ltd. <www.moxa.com> */ +#include <linux/err.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/module.h> -#include <linux/gpio.h> -#include <linux/of_gpio.h> +#include <linux/mod_devicetable.h> +#include <linux/gpio/consumer.h> #define GPIO_RTC_RESERVED 0x0C #define GPIO_RTC_DATA_SET 0x10 @@ -55,7 +56,9 @@ struct moxart_rtc { struct rtc_device *rtc; spinlock_t rtc_lock; - int gpio_data, gpio_sclk, gpio_reset; + struct gpio_desc *gpio_data; + struct gpio_desc *gpio_sclk; + struct gpio_desc *gpio_reset; }; static int day_of_year[12] = { 0, 31, 59, 90, 120, 151, 181, @@ -67,10 +70,10 @@ static void moxart_rtc_write_byte(struct device *dev, u8 data) int i; for (i = 0; i < 8; i++, data >>= 1) { - gpio_set_value(moxart_rtc->gpio_sclk, 0); - gpio_set_value(moxart_rtc->gpio_data, ((data & 1) == 1)); + gpiod_set_value(moxart_rtc->gpio_sclk, 0); + gpiod_set_value(moxart_rtc->gpio_data, ((data & 1) == 1)); udelay(GPIO_RTC_DELAY_TIME); - gpio_set_value(moxart_rtc->gpio_sclk, 1); + gpiod_set_value(moxart_rtc->gpio_sclk, 1); udelay(GPIO_RTC_DELAY_TIME); } } @@ -82,11 +85,11 @@ static u8 moxart_rtc_read_byte(struct device *dev) u8 data = 0; for (i = 0; i < 8; i++) { - gpio_set_value(moxart_rtc->gpio_sclk, 0); + gpiod_set_value(moxart_rtc->gpio_sclk, 0); udelay(GPIO_RTC_DELAY_TIME); - gpio_set_value(moxart_rtc->gpio_sclk, 1); + gpiod_set_value(moxart_rtc->gpio_sclk, 1); udelay(GPIO_RTC_DELAY_TIME); - if (gpio_get_value(moxart_rtc->gpio_data)) + if (gpiod_get_value(moxart_rtc->gpio_data)) data |= (1 << i); udelay(GPIO_RTC_DELAY_TIME); } @@ -101,15 +104,15 @@ static u8 moxart_rtc_read_register(struct device *dev, u8 cmd) local_irq_save(flags); - gpio_direction_output(moxart_rtc->gpio_data, 0); - gpio_set_value(moxart_rtc->gpio_reset, 1); + gpiod_direction_output(moxart_rtc->gpio_data, 0); + gpiod_set_value(moxart_rtc->gpio_reset, 1); udelay(GPIO_RTC_DELAY_TIME); moxart_rtc_write_byte(dev, cmd); - gpio_direction_input(moxart_rtc->gpio_data); + gpiod_direction_input(moxart_rtc->gpio_data); udelay(GPIO_RTC_DELAY_TIME); data = moxart_rtc_read_byte(dev); - gpio_set_value(moxart_rtc->gpio_sclk, 0); - gpio_set_value(moxart_rtc->gpio_reset, 0); + gpiod_set_value(moxart_rtc->gpio_sclk, 0); + gpiod_set_value(moxart_rtc->gpio_reset, 0); udelay(GPIO_RTC_DELAY_TIME); local_irq_restore(flags); @@ -124,13 +127,13 @@ static void moxart_rtc_write_register(struct device *dev, u8 cmd, u8 data) local_irq_save(flags); - gpio_direction_output(moxart_rtc->gpio_data, 0); - gpio_set_value(moxart_rtc->gpio_reset, 1); + gpiod_direction_output(moxart_rtc->gpio_data, 0); + gpiod_set_value(moxart_rtc->gpio_reset, 1); udelay(GPIO_RTC_DELAY_TIME); moxart_rtc_write_byte(dev, cmd); moxart_rtc_write_byte(dev, data); - gpio_set_value(moxart_rtc->gpio_sclk, 0); - gpio_set_value(moxart_rtc->gpio_reset, 0); + gpiod_set_value(moxart_rtc->gpio_sclk, 0); + gpiod_set_value(moxart_rtc->gpio_reset, 0); udelay(GPIO_RTC_DELAY_TIME); local_irq_restore(flags); @@ -247,53 +250,33 @@ static int moxart_rtc_probe(struct platform_device *pdev) if (!moxart_rtc) return -ENOMEM; - moxart_rtc->gpio_data = of_get_named_gpio(pdev->dev.of_node, - "gpio-rtc-data", 0); - if (!gpio_is_valid(moxart_rtc->gpio_data)) { - dev_err(&pdev->dev, "invalid gpio (data): %d\n", - moxart_rtc->gpio_data); - return moxart_rtc->gpio_data; - } - - moxart_rtc->gpio_sclk = of_get_named_gpio(pdev->dev.of_node, - "gpio-rtc-sclk", 0); - if (!gpio_is_valid(moxart_rtc->gpio_sclk)) { - dev_err(&pdev->dev, "invalid gpio (sclk): %d\n", - moxart_rtc->gpio_sclk); - return moxart_rtc->gpio_sclk; - } - - moxart_rtc->gpio_reset = of_get_named_gpio(pdev->dev.of_node, - "gpio-rtc-reset", 0); - if (!gpio_is_valid(moxart_rtc->gpio_reset)) { - dev_err(&pdev->dev, "invalid gpio (reset): %d\n", - moxart_rtc->gpio_reset); - return moxart_rtc->gpio_reset; - } - - spin_lock_init(&moxart_rtc->rtc_lock); - platform_set_drvdata(pdev, moxart_rtc); - - ret = devm_gpio_request(&pdev->dev, moxart_rtc->gpio_data, "rtc_data"); + moxart_rtc->gpio_data = devm_gpiod_get(&pdev->dev, "rtc-data", + GPIOD_IN); + ret = PTR_ERR_OR_ZERO(moxart_rtc->gpio_data); if (ret) { - dev_err(&pdev->dev, "can't get rtc_data gpio\n"); + dev_err(&pdev->dev, "can't get rtc data gpio: %d\n", ret); return ret; } - ret = devm_gpio_request_one(&pdev->dev, moxart_rtc->gpio_sclk, - GPIOF_DIR_OUT, "rtc_sclk"); + moxart_rtc->gpio_sclk = devm_gpiod_get(&pdev->dev, "rtc-sclk", + GPIOD_ASIS); + ret = PTR_ERR_OR_ZERO(moxart_rtc->gpio_sclk); if (ret) { - dev_err(&pdev->dev, "can't get rtc_sclk gpio\n"); + dev_err(&pdev->dev, "can't get rtc sclk gpio: %d\n", ret); return ret; } - ret = devm_gpio_request_one(&pdev->dev, moxart_rtc->gpio_reset, - GPIOF_DIR_OUT, "rtc_reset"); + moxart_rtc->gpio_reset = devm_gpiod_get(&pdev->dev, "rtc-reset", + GPIOD_ASIS); + ret = PTR_ERR_OR_ZERO(moxart_rtc->gpio_reset); if (ret) { - dev_err(&pdev->dev, "can't get rtc_reset gpio\n"); + dev_err(&pdev->dev, "can't get rtc reset gpio: %d\n", ret); return ret; } + spin_lock_init(&moxart_rtc->rtc_lock); + platform_set_drvdata(pdev, moxart_rtc); + moxart_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &moxart_rtc_ops, THIS_MODULE); diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 6d7656a75cae..07df43e4c4d0 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -372,7 +372,7 @@ out_dispose: return err; } -static int mpc5121_rtc_remove(struct platform_device *op) +static void mpc5121_rtc_remove(struct platform_device *op) { struct mpc5121_rtc_data *rtc = platform_get_drvdata(op); struct mpc5121_rtc_regs __iomem *regs = rtc->regs; @@ -383,8 +383,6 @@ static int mpc5121_rtc_remove(struct platform_device *op) irq_dispose_mapping(rtc->irq); irq_dispose_mapping(rtc->irq_periodic); - - return 0; } #ifdef CONFIG_OF @@ -402,7 +400,7 @@ static struct platform_driver mpc5121_rtc_driver = { .of_match_table = of_match_ptr(mpc5121_rtc_match), }, .probe = mpc5121_rtc_probe, - .remove = mpc5121_rtc_remove, + .remove_new = mpc5121_rtc_remove, }; module_platform_driver(mpc5121_rtc_driver); diff --git a/drivers/rtc/rtc-mpfs.c b/drivers/rtc/rtc-mpfs.c index 2a479d44f198..5b96a6d39210 100644 --- a/drivers/rtc/rtc-mpfs.c +++ b/drivers/rtc/rtc-mpfs.c @@ -274,11 +274,9 @@ static int mpfs_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(rtcdev->rtc); } -static int mpfs_rtc_remove(struct platform_device *pdev) +static void mpfs_rtc_remove(struct platform_device *pdev) { dev_pm_clear_wake_irq(&pdev->dev); - - return 0; } static const struct of_device_id mpfs_rtc_of_match[] = { @@ -290,7 +288,7 @@ MODULE_DEVICE_TABLE(of, mpfs_rtc_of_match); static struct platform_driver mpfs_rtc_driver = { .probe = mpfs_rtc_probe, - .remove = mpfs_rtc_remove, + .remove_new = mpfs_rtc_remove, .driver = { .name = "mpfs_rtc", .of_match_table = mpfs_rtc_of_match, diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c index f3fde013c4b8..8d7737e0e2e0 100644 --- a/drivers/rtc/rtc-msc313.c +++ b/drivers/rtc/rtc-msc313.c @@ -212,22 +212,12 @@ static int msc313_rtc_probe(struct platform_device *pdev) return ret; } - clk = devm_clk_get(dev, NULL); + clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(clk)) { dev_err(dev, "No input reference clock\n"); return PTR_ERR(clk); } - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "Failed to enable the reference clock, %d\n", ret); - return ret; - } - - ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk); - if (ret) - return ret; - rate = clk_get_rate(clk); writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L); writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H); diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c index f1e356394814..81857a457c32 100644 --- a/drivers/rtc/rtc-mt7622.c +++ b/drivers/rtc/rtc-mt7622.c @@ -357,13 +357,11 @@ err: return ret; } -static int mtk_rtc_remove(struct platform_device *pdev) +static void mtk_rtc_remove(struct platform_device *pdev) { struct mtk_rtc *hw = platform_get_drvdata(pdev); clk_disable_unprepare(hw->clk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -396,7 +394,7 @@ static SIMPLE_DEV_PM_OPS(mtk_rtc_pm_ops, mtk_rtc_suspend, mtk_rtc_resume); static struct platform_driver mtk_rtc_driver = { .probe = mtk_rtc_probe, - .remove = mtk_rtc_remove, + .remove_new = mtk_rtc_remove, .driver = { .name = MTK_RTC_DEV, .of_match_table = mtk_rtc_match, diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c index 5e0383401629..6934bce4b29f 100644 --- a/drivers/rtc/rtc-mxc_v2.c +++ b/drivers/rtc/rtc-mxc_v2.c @@ -336,8 +336,10 @@ static int mxc_rtc_probe(struct platform_device *pdev) } pdata->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(pdata->rtc)) + if (IS_ERR(pdata->rtc)) { + clk_disable_unprepare(pdata->clk); return PTR_ERR(pdata->rtc); + } pdata->rtc->ops = &mxc_rtc_ops; pdata->rtc->range_max = U32_MAX; @@ -360,12 +362,11 @@ static int mxc_rtc_probe(struct platform_device *pdev) return ret; } -static int mxc_rtc_remove(struct platform_device *pdev) +static void mxc_rtc_remove(struct platform_device *pdev) { struct mxc_rtc_data *pdata = platform_get_drvdata(pdev); clk_disable_unprepare(pdata->clk); - return 0; } static const struct of_device_id mxc_ids[] = { @@ -380,7 +381,7 @@ static struct platform_driver mxc_rtc_driver = { .of_match_table = mxc_ids, }, .probe = mxc_rtc_probe, - .remove = mxc_rtc_remove, + .remove_new = mxc_rtc_remove, }; module_platform_driver(mxc_rtc_driver); diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c index d43acd3920ed..0a3b14c95d90 100644 --- a/drivers/rtc/rtc-nct3018y.c +++ b/drivers/rtc/rtc-nct3018y.c @@ -452,8 +452,7 @@ static const struct rtc_class_ops nct3018y_rtc_ops = { .ioctl = nct3018y_ioctl, }; -static int nct3018y_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int nct3018y_probe(struct i2c_client *client) { struct nct3018y *nct3018y; int err, flags; @@ -541,7 +540,7 @@ static struct i2c_driver nct3018y_driver = { .name = "rtc-nct3018y", .of_match_table = of_match_ptr(nct3018y_of_match), }, - .probe = nct3018y_probe, + .probe_new = nct3018y_probe, .id_table = nct3018y_id, }; diff --git a/drivers/rtc/rtc-nxp-bbnsm.c b/drivers/rtc/rtc-nxp-bbnsm.c new file mode 100644 index 000000000000..acbfbeb8b070 --- /dev/null +++ b/drivers/rtc/rtc-nxp-bbnsm.c @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright 2022 NXP. + +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> +#include <linux/regmap.h> +#include <linux/rtc.h> + +#define BBNSM_CTRL 0x8 +#define BBNSM_INT_EN 0x10 +#define BBNSM_EVENTS 0x14 +#define BBNSM_RTC_LS 0x40 +#define BBNSM_RTC_MS 0x44 +#define BBNSM_TA 0x50 + +#define RTC_EN 0x2 +#define RTC_EN_MSK 0x3 +#define TA_EN (0x2 << 2) +#define TA_DIS (0x1 << 2) +#define TA_EN_MSK (0x3 << 2) +#define RTC_INT_EN 0x2 +#define TA_INT_EN (0x2 << 2) + +#define BBNSM_EVENT_TA (0x2 << 2) + +#define CNTR_TO_SECS_SH 15 + +struct bbnsm_rtc { + struct rtc_device *rtc; + struct regmap *regmap; + int irq; + struct clk *clk; +}; + +static u32 bbnsm_read_counter(struct bbnsm_rtc *bbnsm) +{ + u32 rtc_msb, rtc_lsb; + unsigned int timeout = 100; + u32 time; + u32 tmp = 0; + + do { + time = tmp; + /* read the msb */ + regmap_read(bbnsm->regmap, BBNSM_RTC_MS, &rtc_msb); + /* read the lsb */ + regmap_read(bbnsm->regmap, BBNSM_RTC_LS, &rtc_lsb); + /* convert to seconds */ + tmp = (rtc_msb << 17) | (rtc_lsb >> 15); + } while (tmp != time && --timeout); + + return time; +} + +static int bbnsm_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct bbnsm_rtc *bbnsm = dev_get_drvdata(dev); + unsigned long time; + u32 val; + + regmap_read(bbnsm->regmap, BBNSM_CTRL, &val); + if ((val & RTC_EN_MSK) != RTC_EN) + return -EINVAL; + + time = bbnsm_read_counter(bbnsm); + rtc_time64_to_tm(time, tm); + + return 0; +} + +static int bbnsm_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct bbnsm_rtc *bbnsm = dev_get_drvdata(dev); + unsigned long time = rtc_tm_to_time64(tm); + + /* disable the RTC first */ + regmap_update_bits(bbnsm->regmap, BBNSM_CTRL, RTC_EN_MSK, 0); + + /* write the 32bit sec time to 47 bit timer counter, leaving 15 LSBs blank */ + regmap_write(bbnsm->regmap, BBNSM_RTC_LS, time << CNTR_TO_SECS_SH); + regmap_write(bbnsm->regmap, BBNSM_RTC_MS, time >> (32 - CNTR_TO_SECS_SH)); + + /* Enable the RTC again */ + regmap_update_bits(bbnsm->regmap, BBNSM_CTRL, RTC_EN_MSK, RTC_EN); + + return 0; +} + +static int bbnsm_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct bbnsm_rtc *bbnsm = dev_get_drvdata(dev); + u32 bbnsm_events, bbnsm_ta; + + regmap_read(bbnsm->regmap, BBNSM_TA, &bbnsm_ta); + rtc_time64_to_tm(bbnsm_ta, &alrm->time); + + regmap_read(bbnsm->regmap, BBNSM_EVENTS, &bbnsm_events); + alrm->pending = (bbnsm_events & BBNSM_EVENT_TA) ? 1 : 0; + + return 0; +} + +static int bbnsm_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) +{ + struct bbnsm_rtc *bbnsm = dev_get_drvdata(dev); + + /* enable the alarm event */ + regmap_update_bits(bbnsm->regmap, BBNSM_CTRL, TA_EN_MSK, enable ? TA_EN : TA_DIS); + /* enable the alarm interrupt */ + regmap_update_bits(bbnsm->regmap, BBNSM_INT_EN, TA_EN_MSK, enable ? TA_EN : TA_DIS); + + return 0; +} + +static int bbnsm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct bbnsm_rtc *bbnsm = dev_get_drvdata(dev); + unsigned long time = rtc_tm_to_time64(&alrm->time); + + /* disable the alarm */ + regmap_update_bits(bbnsm->regmap, BBNSM_CTRL, TA_EN, TA_EN); + + /* write the seconds to TA */ + regmap_write(bbnsm->regmap, BBNSM_TA, time); + + return bbnsm_rtc_alarm_irq_enable(dev, alrm->enabled); +} + +static const struct rtc_class_ops bbnsm_rtc_ops = { + .read_time = bbnsm_rtc_read_time, + .set_time = bbnsm_rtc_set_time, + .read_alarm = bbnsm_rtc_read_alarm, + .set_alarm = bbnsm_rtc_set_alarm, + .alarm_irq_enable = bbnsm_rtc_alarm_irq_enable, +}; + +static irqreturn_t bbnsm_rtc_irq_handler(int irq, void *dev_id) +{ + struct device *dev = dev_id; + struct bbnsm_rtc *bbnsm = dev_get_drvdata(dev); + u32 val; + + regmap_read(bbnsm->regmap, BBNSM_EVENTS, &val); + if (val & BBNSM_EVENT_TA) { + bbnsm_rtc_alarm_irq_enable(dev, false); + /* clear the alarm event */ + regmap_write_bits(bbnsm->regmap, BBNSM_EVENTS, TA_EN_MSK, BBNSM_EVENT_TA); + rtc_update_irq(bbnsm->rtc, 1, RTC_AF | RTC_IRQF); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int bbnsm_rtc_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct bbnsm_rtc *bbnsm; + int ret; + + bbnsm = devm_kzalloc(&pdev->dev, sizeof(*bbnsm), GFP_KERNEL); + if (!bbnsm) + return -ENOMEM; + + bbnsm->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(bbnsm->rtc)) + return PTR_ERR(bbnsm->rtc); + + bbnsm->regmap = syscon_node_to_regmap(np->parent); + if (IS_ERR(bbnsm->regmap)) { + dev_dbg(&pdev->dev, "bbnsm get regmap failed\n"); + return PTR_ERR(bbnsm->regmap); + } + + bbnsm->irq = platform_get_irq(pdev, 0); + if (bbnsm->irq < 0) + return bbnsm->irq; + + platform_set_drvdata(pdev, bbnsm); + + /* clear all the pending events */ + regmap_write(bbnsm->regmap, BBNSM_EVENTS, 0x7A); + + device_init_wakeup(&pdev->dev, true); + dev_pm_set_wake_irq(&pdev->dev, bbnsm->irq); + + ret = devm_request_irq(&pdev->dev, bbnsm->irq, bbnsm_rtc_irq_handler, + IRQF_SHARED, "rtc alarm", &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "failed to request irq %d: %d\n", + bbnsm->irq, ret); + return ret; + } + + bbnsm->rtc->ops = &bbnsm_rtc_ops; + bbnsm->rtc->range_max = U32_MAX; + + return devm_rtc_register_device(bbnsm->rtc); +} + +static const struct of_device_id bbnsm_dt_ids[] = { + { .compatible = "nxp,imx93-bbnsm-rtc" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, bbnsm_dt_ids); + +static struct platform_driver bbnsm_rtc_driver = { + .driver = { + .name = "bbnsm_rtc", + .of_match_table = bbnsm_dt_ids, + }, + .probe = bbnsm_rtc_probe, +}; +module_platform_driver(bbnsm_rtc_driver); + +MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>"); +MODULE_DESCRIPTION("NXP BBNSM RTC Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 4d4f3b1a7309..8ae4d7824ec9 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -25,6 +25,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/rtc.h> +#include <linux/rtc/rtc-omap.h> /* * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock @@ -910,7 +911,7 @@ err: return ret; } -static int omap_rtc_remove(struct platform_device *pdev) +static void omap_rtc_remove(struct platform_device *pdev) { struct omap_rtc *rtc = platform_get_drvdata(pdev); u8 reg; @@ -941,8 +942,6 @@ static int omap_rtc_remove(struct platform_device *pdev) /* Disable the clock/module */ pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - - return 0; } static int __maybe_unused omap_rtc_suspend(struct device *dev) @@ -1017,7 +1016,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev) static struct platform_driver omap_rtc_driver = { .probe = omap_rtc_probe, - .remove = omap_rtc_remove, + .remove_new = omap_rtc_remove, .shutdown = omap_rtc_shutdown, .driver = { .name = "omap_rtc", diff --git a/drivers/rtc/rtc-palmas.c b/drivers/rtc/rtc-palmas.c index 67571f7f0bbc..6971e47c6021 100644 --- a/drivers/rtc/rtc-palmas.c +++ b/drivers/rtc/rtc-palmas.c @@ -308,10 +308,9 @@ static int palmas_rtc_probe(struct platform_device *pdev) return 0; } -static int palmas_rtc_remove(struct platform_device *pdev) +static void palmas_rtc_remove(struct platform_device *pdev) { palmas_rtc_alarm_irq_enable(&pdev->dev, 0); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -347,7 +346,7 @@ MODULE_DEVICE_TABLE(of, of_palmas_rtc_match); static struct platform_driver palmas_rtc_driver = { .probe = palmas_rtc_probe, - .remove = palmas_rtc_remove, + .remove_new = palmas_rtc_remove, .driver = { .name = "palmas-rtc", .pm = &palmas_rtc_pm_ops, diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index e13b5e695d06..e714661e61a9 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -413,9 +413,14 @@ static int pcf2123_probe(struct spi_device *spi) /* Register alarm irq */ if (spi->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&spi->dev)) + irqflags = 0; + ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, pcf2123_rtc_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, pcf2123_driver.driver.name, &spi->dev); if (!ret) device_init_wakeup(&spi->dev, true); diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 63b275b014bd..87f4fc9df68b 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -885,9 +885,17 @@ static const struct regmap_bus pcf2127_i2c_regmap = { static struct i2c_driver pcf2127_i2c_driver; -static int pcf2127_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id pcf2127_i2c_id[] = { + { "pcf2127", 1 }, + { "pcf2129", 0 }, + { "pca2129", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id); + +static int pcf2127_i2c_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_match_id(pcf2127_i2c_id, client); struct regmap *regmap; static const struct regmap_config config = { .reg_bits = 8, @@ -910,20 +918,12 @@ static int pcf2127_i2c_probe(struct i2c_client *client, pcf2127_i2c_driver.driver.name, id->driver_data); } -static const struct i2c_device_id pcf2127_i2c_id[] = { - { "pcf2127", 1 }, - { "pcf2129", 0 }, - { "pca2129", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id); - static struct i2c_driver pcf2127_i2c_driver = { .driver = { .name = "rtc-pcf2127-i2c", .of_match_table = of_match_ptr(pcf2127_of_match), }, - .probe = pcf2127_i2c_probe, + .probe_new = pcf2127_i2c_probe, .id_table = pcf2127_i2c_id, }; diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 48951a16d65d..23edd11aa40c 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -260,14 +260,12 @@ static int pcf50633_rtc_probe(struct platform_device *pdev) return 0; } -static int pcf50633_rtc_remove(struct platform_device *pdev) +static void pcf50633_rtc_remove(struct platform_device *pdev) { struct pcf50633_rtc *rtc; rtc = platform_get_drvdata(pdev); pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM); - - return 0; } static struct platform_driver pcf50633_rtc_driver = { @@ -275,7 +273,7 @@ static struct platform_driver pcf50633_rtc_driver = { .name = "pcf50633-rtc", }, .probe = pcf50633_rtc_probe, - .remove = pcf50633_rtc_remove, + .remove_new = pcf50633_rtc_remove, }; module_platform_driver(pcf50633_rtc_driver); diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 095891999da1..71a456355981 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -169,10 +169,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) if (ret) return ret; - alrm->time.tm_sec = bcd2bin(buf[0]); - alrm->time.tm_min = bcd2bin(buf[1]); - alrm->time.tm_hour = bcd2bin(buf[2]); - alrm->time.tm_mday = bcd2bin(buf[3]); + alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f); + alrm->time.tm_min = bcd2bin(buf[1] & 0x7f); + alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f); + alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f); ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val); if (ret) @@ -424,7 +424,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable) unsigned int buf; int ret; - ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf); + ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf); if (ret < 0) return ret; buf &= PCF85063_REG_CLKO_F_MASK; @@ -621,9 +621,14 @@ static int pcf85063_probe(struct i2c_client *client) clear_bit(RTC_FEATURE_ALARM, pcf85063->rtc->features); if (config->has_alarms && client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + err = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf85063_rtc_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "pcf85063", pcf85063); if (err) { dev_warn(&pcf85063->rtc->dev, diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index 6174b3fd4b98..e7115ebef707 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c @@ -21,7 +21,7 @@ #define PCF8523_CONTROL2_AF BIT(3) #define PCF8523_REG_CONTROL3 0x02 -#define PCF8523_CONTROL3_PM GENMASK(7,5) +#define PCF8523_CONTROL3_PM GENMASK(7, 5) #define PCF8523_PM_STANDBY 0x7 #define PCF8523_CONTROL3_BLF BIT(2) /* battery low bit, read-only */ #define PCF8523_CONTROL3_BSF BIT(3) @@ -65,7 +65,7 @@ static int pcf8523_load_capacitance(struct pcf8523 *pcf8523, struct device_node load); fallthrough; case 12500: - value |= PCF8523_CONTROL1_CAP_SEL; + value = PCF8523_CONTROL1_CAP_SEL; break; case 7000: break; @@ -99,24 +99,24 @@ static irqreturn_t pcf8523_irq(int irq, void *dev_id) static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct pcf8523 *pcf8523 = dev_get_drvdata(dev); - u8 regs[7]; + u8 regs[10]; int err; - err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_SECONDS, regs, + err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_CONTROL1, regs, sizeof(regs)); if (err < 0) return err; - if (regs[0] & PCF8523_SECONDS_OS) + if ((regs[0] & PCF8523_CONTROL1_STOP) || (regs[3] & PCF8523_SECONDS_OS)) return -EINVAL; - tm->tm_sec = bcd2bin(regs[0] & 0x7f); - tm->tm_min = bcd2bin(regs[1] & 0x7f); - tm->tm_hour = bcd2bin(regs[2] & 0x3f); - tm->tm_mday = bcd2bin(regs[3] & 0x3f); - tm->tm_wday = regs[4] & 0x7; - tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1; - tm->tm_year = bcd2bin(regs[6]) + 100; + tm->tm_sec = bcd2bin(regs[3] & 0x7f); + tm->tm_min = bcd2bin(regs[4] & 0x7f); + tm->tm_hour = bcd2bin(regs[5] & 0x3f); + tm->tm_mday = bcd2bin(regs[6] & 0x3f); + tm->tm_wday = regs[7] & 0x7; + tm->tm_mon = bcd2bin(regs[8] & 0x1f) - 1; + tm->tm_year = bcd2bin(regs[9]) + 100; return 0; } @@ -234,8 +234,7 @@ static int pcf8523_param_get(struct device *dev, struct rtc_param *param) int ret; u32 value; - switch(param->param) { - + switch (param->param) { case RTC_PARAM_BACKUP_SWITCH_MODE: ret = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL3, &value); if (ret < 0) @@ -243,7 +242,7 @@ static int pcf8523_param_get(struct device *dev, struct rtc_param *param) value = FIELD_GET(PCF8523_CONTROL3_PM, value); - switch(value) { + switch (value) { case 0x0: case 0x4: param->uvalue = RTC_BSM_LEVEL; @@ -273,7 +272,7 @@ static int pcf8523_param_set(struct device *dev, struct rtc_param *param) struct pcf8523 *pcf8523 = dev_get_drvdata(dev); u8 mode; - switch(param->param) { + switch (param->param) { case RTC_PARAM_BACKUP_SWITCH_MODE: switch (param->uvalue) { case RTC_BSM_DISABLED: @@ -385,9 +384,9 @@ static const struct rtc_class_ops pcf8523_rtc_ops = { }; static const struct regmap_config regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = 0x13, + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x13, }; static int pcf8523_probe(struct i2c_client *client) @@ -445,13 +444,18 @@ static int pcf8523_probe(struct i2c_client *client) clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + err = regmap_write(pcf8523->regmap, PCF8523_TMR_CLKOUT_CTRL, 0x38); if (err < 0) return err; err = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf8523_irq, - IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW, + IRQF_SHARED | IRQF_ONESHOT | irqflags, dev_name(&rtc->dev), pcf8523); if (err) return err; diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index c05b722f0060..8958eadf1c3e 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -101,6 +101,10 @@ #define PIN_IO_INTA_OUT 2 #define PIN_IO_INTA_HIZ 3 +#define OSC_CAP_SEL GENMASK(1, 0) +#define OSC_CAP_6000 0x01 +#define OSC_CAP_12500 0x02 + #define STOP_EN_STOP BIT(0) #define RESET_CPR 0xa4 @@ -117,6 +121,32 @@ struct pcf85x63_config { unsigned int num_nvram; }; +static int pcf85363_load_capacitance(struct pcf85363 *pcf85363, struct device_node *node) +{ + u32 load = 7000; + u8 value = 0; + + of_property_read_u32(node, "quartz-load-femtofarads", &load); + + switch (load) { + default: + dev_warn(&pcf85363->rtc->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 7000", + load); + fallthrough; + case 7000: + break; + case 6000: + value = OSC_CAP_6000; + break; + case 12500: + value = OSC_CAP_12500; + break; + } + + return regmap_update_bits(pcf85363->regmap, CTRL_OSCILLATOR, + OSC_CAP_SEL, value); +} + static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct pcf85363 *pcf85363 = dev_get_drvdata(dev); @@ -372,7 +402,7 @@ static int pcf85363_probe(struct i2c_client *client) .reg_write = pcf85363_nvram_write, }, }; - int ret, i; + int ret, i, err; if (data) config = data; @@ -394,18 +424,28 @@ static int pcf85363_probe(struct i2c_client *client) if (IS_ERR(pcf85363->rtc)) return PTR_ERR(pcf85363->rtc); + err = pcf85363_load_capacitance(pcf85363, client->dev.of_node); + if (err < 0) + dev_warn(&client->dev, "failed to set xtal load capacitance: %d", + err); + pcf85363->rtc->ops = &rtc_ops; pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099; clear_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features); if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO, PIN_IO_INTA_OUT, PIN_IO_INTAPM); ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf85363_rtc_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "pcf85363", client); if (ret) dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 11fa9788558b..7e720472213c 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -558,15 +558,22 @@ static int pcf8563_probe(struct i2c_client *client) pcf8563->rtc->set_start_time = true; if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + err = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf8563_irq, - IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW, + IRQF_SHARED | IRQF_ONESHOT | irqflags, pcf8563_driver.driver.name, client); if (err) { dev_err(&client->dev, "unable to request IRQ %d\n", client->irq); return err; } + } else { + clear_bit(RTC_FEATURE_ALARM, pcf8563->rtc->features); } err = devm_rtc_register_device(pcf8563->rtc); diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c index 7fb9145c43bd..4f85e0c3d757 100644 --- a/drivers/rtc/rtc-pic32.c +++ b/drivers/rtc/rtc-pic32.c @@ -284,15 +284,13 @@ static void pic32_rtc_enable(struct pic32_rtc_dev *pdata, int en) clk_disable(pdata->clk); } -static int pic32_rtc_remove(struct platform_device *pdev) +static void pic32_rtc_remove(struct platform_device *pdev) { struct pic32_rtc_dev *pdata = platform_get_drvdata(pdev); pic32_rtc_setaie(&pdev->dev, 0); clk_unprepare(pdata->clk); pdata->clk = NULL; - - return 0; } static int pic32_rtc_probe(struct platform_device *pdev) @@ -324,16 +322,16 @@ static int pic32_rtc_probe(struct platform_device *pdev) spin_lock_init(&pdata->alarm_lock); + pdata->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(pdata->rtc)) + return PTR_ERR(pdata->rtc); + clk_prepare_enable(pdata->clk); pic32_rtc_enable(pdata, 1); device_init_wakeup(&pdev->dev, 1); - pdata->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(pdata->rtc)) - return PTR_ERR(pdata->rtc); - pdata->rtc->ops = &pic32_rtcops; pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pdata->rtc->range_max = RTC_TIMESTAMP_END_2099; @@ -373,7 +371,7 @@ MODULE_DEVICE_TABLE(of, pic32_rtc_dt_ids); static struct platform_driver pic32_rtc_driver = { .probe = pic32_rtc_probe, - .remove = pic32_rtc_remove, + .remove_new = pic32_rtc_remove, .driver = { .name = "pic32-rtc", .of_match_table = of_match_ptr(pic32_rtc_dt_ids), diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index dc6d1476baa5..f6b779c12ca7 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -1,8 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. +/* + * pm8xxx RTC driver + * + * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2023, Linaro Limited */ #include <linux/of.h> #include <linux/module.h> +#include <linux/nvmem-consumer.h> #include <linux/init.h> #include <linux/rtc.h> #include <linux/platform_device.h> @@ -12,11 +17,7 @@ #include <linux/slab.h> #include <linux/spinlock.h> -/* RTC Register offsets from RTC CTRL REG */ -#define PM8XXX_ALARM_CTRL_OFFSET 0x01 -#define PM8XXX_RTC_WRITE_OFFSET 0x02 -#define PM8XXX_RTC_READ_OFFSET 0x06 -#define PM8XXX_ALARM_RW_OFFSET 0x0A +#include <asm/unaligned.h> /* RTC_CTRL register bit fields */ #define PM8xxx_RTC_ENABLE BIT(7) @@ -27,13 +28,13 @@ /** * struct pm8xxx_rtc_regs - describe RTC registers per PMIC versions - * @ctrl: base address of control register - * @write: base address of write register - * @read: base address of read register - * @alarm_ctrl: base address of alarm control register - * @alarm_ctrl2: base address of alarm control2 register - * @alarm_rw: base address of alarm read-write register - * @alarm_en: alarm enable mask + * @ctrl: address of control register + * @write: base address of write registers + * @read: base address of read registers + * @alarm_ctrl: address of alarm control register + * @alarm_ctrl2: address of alarm control2 register + * @alarm_rw: base address of alarm read-write registers + * @alarm_en: alarm enable mask */ struct pm8xxx_rtc_regs { unsigned int ctrl; @@ -46,25 +47,135 @@ struct pm8xxx_rtc_regs { }; /** - * struct pm8xxx_rtc - rtc driver internal structure - * @rtc: rtc device for this driver. - * @regmap: regmap used to access RTC registers - * @allow_set_time: indicates whether writing to the RTC is allowed - * @rtc_alarm_irq: rtc alarm irq number. - * @regs: rtc registers description. - * @rtc_dev: device structure. - * @ctrl_reg_lock: spinlock protecting access to ctrl_reg. + * struct pm8xxx_rtc - RTC driver internal structure + * @rtc: RTC device + * @regmap: regmap used to access registers + * @allow_set_time: whether the time can be set + * @alarm_irq: alarm irq number + * @regs: register description + * @dev: device structure + * @nvmem_cell: nvmem cell for offset + * @offset: offset from epoch in seconds */ struct pm8xxx_rtc { struct rtc_device *rtc; struct regmap *regmap; bool allow_set_time; - int rtc_alarm_irq; + int alarm_irq; const struct pm8xxx_rtc_regs *regs; - struct device *rtc_dev; - spinlock_t ctrl_reg_lock; + struct device *dev; + struct nvmem_cell *nvmem_cell; + u32 offset; }; +static int pm8xxx_rtc_read_nvmem_offset(struct pm8xxx_rtc *rtc_dd) +{ + size_t len; + void *buf; + int rc; + + buf = nvmem_cell_read(rtc_dd->nvmem_cell, &len); + if (IS_ERR(buf)) { + rc = PTR_ERR(buf); + dev_dbg(rtc_dd->dev, "failed to read nvmem offset: %d\n", rc); + return rc; + } + + if (len != sizeof(u32)) { + dev_dbg(rtc_dd->dev, "unexpected nvmem cell size %zu\n", len); + kfree(buf); + return -EINVAL; + } + + rtc_dd->offset = get_unaligned_le32(buf); + + kfree(buf); + + return 0; +} + +static int pm8xxx_rtc_write_nvmem_offset(struct pm8xxx_rtc *rtc_dd, u32 offset) +{ + u8 buf[sizeof(u32)]; + int rc; + + put_unaligned_le32(offset, buf); + + rc = nvmem_cell_write(rtc_dd->nvmem_cell, buf, sizeof(buf)); + if (rc < 0) { + dev_dbg(rtc_dd->dev, "failed to write nvmem offset: %d\n", rc); + return rc; + } + + return 0; +} + +static int pm8xxx_rtc_read_offset(struct pm8xxx_rtc *rtc_dd) +{ + if (!rtc_dd->nvmem_cell) + return 0; + + return pm8xxx_rtc_read_nvmem_offset(rtc_dd); +} + +static int pm8xxx_rtc_read_raw(struct pm8xxx_rtc *rtc_dd, u32 *secs) +{ + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + u8 value[NUM_8_BIT_RTC_REGS]; + unsigned int reg; + int rc; + + rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value)); + if (rc) + return rc; + + /* + * Read the LSB again and check if there has been a carry over. + * If there has, redo the read operation. + */ + rc = regmap_read(rtc_dd->regmap, regs->read, ®); + if (rc < 0) + return rc; + + if (reg < value[0]) { + rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, + sizeof(value)); + if (rc) + return rc; + } + + *secs = get_unaligned_le32(value); + + return 0; +} + +static int pm8xxx_rtc_update_offset(struct pm8xxx_rtc *rtc_dd, u32 secs) +{ + u32 raw_secs; + u32 offset; + int rc; + + if (!rtc_dd->nvmem_cell) + return -ENODEV; + + rc = pm8xxx_rtc_read_raw(rtc_dd, &raw_secs); + if (rc) + return rc; + + offset = secs - raw_secs; + + if (offset == rtc_dd->offset) + return 0; + + rc = pm8xxx_rtc_write_nvmem_offset(rtc_dd, offset); + if (rc) + return rc; + + rtc_dd->offset = offset; + + return 0; +} + /* * Steps to write the RTC registers. * 1. Disable alarm if enabled. @@ -74,269 +185,186 @@ struct pm8xxx_rtc { * 5. Enable rtc if disabled in step 2. * 6. Enable alarm if disabled in step 1. */ -static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) +static int __pm8xxx_rtc_set_time(struct pm8xxx_rtc *rtc_dd, u32 secs) { - int rc, i; - unsigned long secs, irq_flags; - u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, rtc_disabled = 0; - unsigned int ctrl_reg, rtc_ctrl_reg; - struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + u8 value[NUM_8_BIT_RTC_REGS]; + bool alarm_enabled; + int rc; - if (!rtc_dd->allow_set_time) - return -ENODEV; - - secs = rtc_tm_to_time64(tm); - - dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); - - for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { - value[i] = secs & 0xFF; - secs >>= 8; - } - - spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); + put_unaligned_le32(secs, value); - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); + rc = regmap_update_bits_check(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, 0, &alarm_enabled); if (rc) - goto rtc_rw_fail; - - if (ctrl_reg & regs->alarm_en) { - alarm_enabled = 1; - ctrl_reg &= ~regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC Alarm control register failed\n"); - goto rtc_rw_fail; - } - } + return rc; - /* Disable RTC H/w before writing on RTC register */ - rc = regmap_read(rtc_dd->regmap, regs->ctrl, &rtc_ctrl_reg); + /* Disable RTC */ + rc = regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, 0); if (rc) - goto rtc_rw_fail; - - if (rtc_ctrl_reg & PM8xxx_RTC_ENABLE) { - rtc_disabled = 1; - rtc_ctrl_reg &= ~PM8xxx_RTC_ENABLE; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC control register failed\n"); - goto rtc_rw_fail; - } - } + return rc; /* Write 0 to Byte[0] */ rc = regmap_write(rtc_dd->regmap, regs->write, 0); - if (rc) { - dev_err(dev, "Write to RTC write data register failed\n"); - goto rtc_rw_fail; - } + if (rc) + return rc; /* Write Byte[1], Byte[2], Byte[3] */ rc = regmap_bulk_write(rtc_dd->regmap, regs->write + 1, &value[1], sizeof(value) - 1); - if (rc) { - dev_err(dev, "Write to RTC write data register failed\n"); - goto rtc_rw_fail; - } + if (rc) + return rc; /* Write Byte[0] */ rc = regmap_write(rtc_dd->regmap, regs->write, value[0]); - if (rc) { - dev_err(dev, "Write to RTC write data register failed\n"); - goto rtc_rw_fail; - } + if (rc) + return rc; - /* Enable RTC H/w after writing on RTC register */ - if (rtc_disabled) { - rtc_ctrl_reg |= PM8xxx_RTC_ENABLE; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC control register failed\n"); - goto rtc_rw_fail; - } - } + /* Enable RTC */ + rc = regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, + PM8xxx_RTC_ENABLE); + if (rc) + return rc; if (alarm_enabled) { - ctrl_reg |= regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC Alarm control register failed\n"); - goto rtc_rw_fail; - } + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, regs->alarm_en); + if (rc) + return rc; } -rtc_rw_fail: - spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); - - return rc; + return 0; } -static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) +static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) { - int rc; - u8 value[NUM_8_BIT_RTC_REGS]; - unsigned long secs; - unsigned int reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); - const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + u32 secs; + int rc; - rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value)); - if (rc) { - dev_err(dev, "RTC read data register failed\n"); - return rc; - } + secs = rtc_tm_to_time64(tm); - /* - * Read the LSB again and check if there has been a carry over. - * If there is, redo the read operation. - */ - rc = regmap_read(rtc_dd->regmap, regs->read, ®); - if (rc < 0) { - dev_err(dev, "RTC read data register failed\n"); + if (rtc_dd->allow_set_time) + rc = __pm8xxx_rtc_set_time(rtc_dd, secs); + else + rc = pm8xxx_rtc_update_offset(rtc_dd, secs); + + if (rc) return rc; - } - if (unlikely(reg < value[0])) { - rc = regmap_bulk_read(rtc_dd->regmap, regs->read, - value, sizeof(value)); - if (rc) { - dev_err(dev, "RTC read data register failed\n"); - return rc; - } - } + dev_dbg(dev, "set time: %ptRd %ptRt (%u + %u)\n", tm, tm, + secs - rtc_dd->offset, rtc_dd->offset); + return 0; +} - secs = value[0] | (value[1] << 8) | (value[2] << 16) | - ((unsigned long)value[3] << 24); +static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); + u32 secs; + int rc; - rtc_time64_to_tm(secs, tm); + rc = pm8xxx_rtc_read_raw(rtc_dd, &secs); + if (rc) + return rc; - dev_dbg(dev, "secs = %lu, h:m:s == %ptRt, y-m-d = %ptRdr\n", secs, tm, tm); + secs += rtc_dd->offset; + rtc_time64_to_tm(secs, tm); + dev_dbg(dev, "read time: %ptRd %ptRt (%u + %u)\n", tm, tm, + secs - rtc_dd->offset, rtc_dd->offset); return 0; } static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - int rc, i; - u8 value[NUM_8_BIT_RTC_REGS]; - unsigned int ctrl_reg; - unsigned long secs, irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + u8 value[NUM_8_BIT_RTC_REGS]; + u32 secs; + int rc; secs = rtc_tm_to_time64(&alarm->time); + secs -= rtc_dd->offset; + put_unaligned_le32(secs, value); - for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { - value[i] = secs & 0xFF; - secs >>= 8; - } - - spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, 0); + if (rc) + return rc; rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, sizeof(value)); - if (rc) { - dev_err(dev, "Write to RTC ALARM register failed\n"); - goto rtc_rw_fail; - } - - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); if (rc) - goto rtc_rw_fail; - - if (alarm->enabled) - ctrl_reg |= regs->alarm_en; - else - ctrl_reg &= ~regs->alarm_en; + return rc; - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC alarm control register failed\n"); - goto rtc_rw_fail; + if (alarm->enabled) { + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, regs->alarm_en); + if (rc) + return rc; } - dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n", - &alarm->time, &alarm->time); -rtc_rw_fail: - spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); - return rc; + dev_dbg(dev, "set alarm: %ptRd %ptRt\n", &alarm->time, &alarm->time); + + return 0; } static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - int rc; - unsigned int ctrl_reg; - u8 value[NUM_8_BIT_RTC_REGS]; - unsigned long secs; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + u8 value[NUM_8_BIT_RTC_REGS]; + unsigned int ctrl_reg; + u32 secs; + int rc; rc = regmap_bulk_read(rtc_dd->regmap, regs->alarm_rw, value, sizeof(value)); - if (rc) { - dev_err(dev, "RTC alarm time read failed\n"); + if (rc) return rc; - } - - secs = value[0] | (value[1] << 8) | (value[2] << 16) | - ((unsigned long)value[3] << 24); + secs = get_unaligned_le32(value); + secs += rtc_dd->offset; rtc_time64_to_tm(secs, &alarm->time); rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); - if (rc) { - dev_err(dev, "Read from RTC alarm control register failed\n"); + if (rc) return rc; - } + alarm->enabled = !!(ctrl_reg & PM8xxx_RTC_ALARM_ENABLE); - dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n", - &alarm->time, &alarm->time); + dev_dbg(dev, "read alarm: %ptRd %ptRt\n", &alarm->time, &alarm->time); return 0; } static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) { - int rc; - unsigned long irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; - unsigned int ctrl_reg; u8 value[NUM_8_BIT_RTC_REGS] = {0}; - - spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); - - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); - if (rc) - goto rtc_rw_fail; + unsigned int val; + int rc; if (enable) - ctrl_reg |= regs->alarm_en; + val = regs->alarm_en; else - ctrl_reg &= ~regs->alarm_en; + val = 0; - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC control register failed\n"); - goto rtc_rw_fail; - } + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, val); + if (rc) + return rc; - /* Clear Alarm register */ + /* Clear alarm register */ if (!enable) { rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, sizeof(value)); - if (rc) { - dev_err(dev, "Clear RTC ALARM register failed\n"); - goto rtc_rw_fail; - } + if (rc) + return rc; } -rtc_rw_fail: - spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); - return rc; + return 0; } static const struct rtc_class_ops pm8xxx_rtc_ops = { @@ -351,69 +379,31 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) { struct pm8xxx_rtc *rtc_dd = dev_id; const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; - unsigned int ctrl_reg; int rc; rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF); - spin_lock(&rtc_dd->ctrl_reg_lock); - - /* Clear the alarm enable bit */ - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); - if (rc) { - spin_unlock(&rtc_dd->ctrl_reg_lock); - goto rtc_alarm_handled; - } - - ctrl_reg &= ~regs->alarm_en; - - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - spin_unlock(&rtc_dd->ctrl_reg_lock); - dev_err(rtc_dd->rtc_dev, - "Write to alarm control register failed\n"); - goto rtc_alarm_handled; - } - - spin_unlock(&rtc_dd->ctrl_reg_lock); - - /* Clear RTC alarm register */ - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl2, &ctrl_reg); - if (rc) { - dev_err(rtc_dd->rtc_dev, - "RTC Alarm control2 register read failed\n"); - goto rtc_alarm_handled; - } + /* Disable alarm */ + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, 0); + if (rc) + return IRQ_NONE; - ctrl_reg |= PM8xxx_RTC_ALARM_CLEAR; - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl2, ctrl_reg); + /* Clear alarm status */ + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl2, + PM8xxx_RTC_ALARM_CLEAR, 0); if (rc) - dev_err(rtc_dd->rtc_dev, - "Write to RTC Alarm control2 register failed\n"); + return IRQ_NONE; -rtc_alarm_handled: return IRQ_HANDLED; } static int pm8xxx_rtc_enable(struct pm8xxx_rtc *rtc_dd) { const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; - unsigned int ctrl_reg; - int rc; - - /* Check if the RTC is on, else turn it on */ - rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg); - if (rc) - return rc; - - if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) { - ctrl_reg |= PM8xxx_RTC_ENABLE; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); - if (rc) - return rc; - } - return 0; + return regmap_update_bits(rtc_dd->regmap, regs->ctrl, PM8xxx_RTC_ENABLE, + PM8xxx_RTC_ENABLE); } static const struct pm8xxx_rtc_regs pm8921_regs = { @@ -456,12 +446,8 @@ static const struct pm8xxx_rtc_regs pmk8350_regs = { .alarm_en = BIT(7), }; -/* - * Hardcoded RTC bases until IORESOURCE_REG mapping is figured out - */ static const struct of_device_id pm8xxx_id_table[] = { { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs }, - { .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs }, { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs }, { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs }, { .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs }, @@ -471,9 +457,9 @@ MODULE_DEVICE_TABLE(of, pm8xxx_id_table); static int pm8xxx_rtc_probe(struct platform_device *pdev) { - int rc; - struct pm8xxx_rtc *rtc_dd; const struct of_device_id *match; + struct pm8xxx_rtc *rtc_dd; + int rc; match = of_match_node(pm8xxx_id_table, pdev->dev.of_node); if (!match) @@ -483,24 +469,33 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) if (rtc_dd == NULL) return -ENOMEM; - /* Initialise spinlock to protect RTC control register */ - spin_lock_init(&rtc_dd->ctrl_reg_lock); - rtc_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL); - if (!rtc_dd->regmap) { - dev_err(&pdev->dev, "Parent regmap unavailable.\n"); + if (!rtc_dd->regmap) return -ENXIO; - } - rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0); - if (rtc_dd->rtc_alarm_irq < 0) + rtc_dd->alarm_irq = platform_get_irq(pdev, 0); + if (rtc_dd->alarm_irq < 0) return -ENXIO; rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node, "allow-set-time"); + rtc_dd->nvmem_cell = devm_nvmem_cell_get(&pdev->dev, "offset"); + if (IS_ERR(rtc_dd->nvmem_cell)) { + rc = PTR_ERR(rtc_dd->nvmem_cell); + if (rc != -ENOENT) + return rc; + rtc_dd->nvmem_cell = NULL; + } + rtc_dd->regs = match->data; - rtc_dd->rtc_dev = &pdev->dev; + rtc_dd->dev = &pdev->dev; + + if (!rtc_dd->allow_set_time) { + rc = pm8xxx_rtc_read_offset(rtc_dd); + if (rc) + return rc; + } rc = pm8xxx_rtc_enable(rtc_dd); if (rc) @@ -510,7 +505,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - /* Register the RTC device */ rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc_dd->rtc)) return PTR_ERR(rtc_dd->rtc); @@ -518,36 +512,32 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) rtc_dd->rtc->ops = &pm8xxx_rtc_ops; rtc_dd->rtc->range_max = U32_MAX; - /* Request the alarm IRQ */ - rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->rtc_alarm_irq, + rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->alarm_irq, pm8xxx_alarm_trigger, IRQF_TRIGGER_RISING, "pm8xxx_rtc_alarm", rtc_dd); - if (rc < 0) { - dev_err(&pdev->dev, "Request IRQ failed (%d)\n", rc); + if (rc < 0) return rc; - } rc = devm_rtc_register_device(rtc_dd->rtc); if (rc) return rc; - rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->rtc_alarm_irq); + rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->alarm_irq); if (rc) return rc; return 0; } -static int pm8xxx_remove(struct platform_device *pdev) +static void pm8xxx_remove(struct platform_device *pdev) { dev_pm_clear_wake_irq(&pdev->dev); - return 0; } static struct platform_driver pm8xxx_rtc_driver = { .probe = pm8xxx_rtc_probe, - .remove = pm8xxx_remove, + .remove_new = pm8xxx_remove, .driver = { .name = "rtc-pm8xxx", .of_match_table = pm8xxx_id_table, @@ -560,3 +550,4 @@ MODULE_ALIAS("platform:rtc-pm8xxx"); MODULE_DESCRIPTION("PMIC8xxx RTC driver"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Anirudh Ghayal <aghayal@codeaurora.org>"); +MODULE_AUTHOR("Johan Hovold <johan@kernel.org>"); diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c index 18684a7026c4..6f4bf919827a 100644 --- a/drivers/rtc/rtc-rc5t583.c +++ b/drivers/rtc/rtc-rc5t583.c @@ -262,12 +262,11 @@ static int rc5t583_rtc_probe(struct platform_device *pdev) * Disable rc5t583 RTC interrupts. * Sets status flag to free. */ -static int rc5t583_rtc_remove(struct platform_device *pdev) +static void rc5t583_rtc_remove(struct platform_device *pdev) { struct rc5t583_rtc *rc5t583_rtc = platform_get_drvdata(pdev); rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -299,7 +298,7 @@ static SIMPLE_DEV_PM_OPS(rc5t583_rtc_pm_ops, rc5t583_rtc_suspend, static struct platform_driver rc5t583_rtc_driver = { .probe = rc5t583_rtc_probe, - .remove = rc5t583_rtc_remove, + .remove_new = rc5t583_rtc_remove, .driver = { .name = "rtc-rc5t583", .pm = &rc5t583_rtc_pm_ops, diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index e920da8c08da..2d9bcb3ce1e3 100644 --- a/drivers/rtc/rtc-rk808.c +++ b/drivers/rtc/rtc-rk808.c @@ -14,7 +14,6 @@ #include <linux/bcd.h> #include <linux/mfd/rk808.h> #include <linux/platform_device.h> -#include <linux/i2c.h> /* RTC_CTRL_REG bitfields */ #define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0) @@ -51,7 +50,7 @@ struct rk_rtc_compat_reg { }; struct rk808_rtc { - struct rk808 *rk808; + struct regmap *regmap; struct rtc_device *rtc; struct rk_rtc_compat_reg *creg; int irq; @@ -97,12 +96,11 @@ static void gregorian_to_rockchip(struct rtc_time *tm) static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) { struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); - struct rk808 *rk808 = rk808_rtc->rk808; u8 rtc_data[NUM_TIME_REGS]; int ret; /* Force an update of the shadowed registers right now */ - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg, BIT_RTC_CTRL_REG_RTC_GET_TIME, BIT_RTC_CTRL_REG_RTC_GET_TIME); if (ret) { @@ -116,7 +114,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) * 32khz. If we clear the GET_TIME bit here, the time of i2c transfer * certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency. */ - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg, BIT_RTC_CTRL_REG_RTC_GET_TIME, 0); if (ret) { @@ -124,7 +122,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) return ret; } - ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg, + ret = regmap_bulk_read(rk808_rtc->regmap, rk808_rtc->creg->seconds_reg, rtc_data, NUM_TIME_REGS); if (ret) { dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret); @@ -148,7 +146,6 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); - struct rk808 *rk808 = rk808_rtc->rk808; u8 rtc_data[NUM_TIME_REGS]; int ret; @@ -163,7 +160,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) rtc_data[6] = bin2bcd(tm->tm_wday); /* Stop RTC while updating the RTC registers */ - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg, BIT_RTC_CTRL_REG_STOP_RTC_M, BIT_RTC_CTRL_REG_STOP_RTC_M); if (ret) { @@ -171,14 +168,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) return ret; } - ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg, + ret = regmap_bulk_write(rk808_rtc->regmap, rk808_rtc->creg->seconds_reg, rtc_data, NUM_TIME_REGS); if (ret) { dev_err(dev, "Failed to bull write rtc_data: %d\n", ret); return ret; } /* Start RTC again */ - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg, BIT_RTC_CTRL_REG_STOP_RTC_M, 0); if (ret) { dev_err(dev, "Failed to update RTC control: %d\n", ret); @@ -191,12 +188,11 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); - struct rk808 *rk808 = rk808_rtc->rk808; u8 alrm_data[NUM_ALARM_REGS]; uint32_t int_reg; int ret; - ret = regmap_bulk_read(rk808->regmap, + ret = regmap_bulk_read(rk808_rtc->regmap, rk808_rtc->creg->alarm_seconds_reg, alrm_data, NUM_ALARM_REGS); if (ret) { @@ -212,7 +208,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; rockchip_to_gregorian(&alrm->time); - ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg); + ret = regmap_read(rk808_rtc->regmap, rk808_rtc->creg->int_reg, &int_reg); if (ret) { dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); return ret; @@ -228,10 +224,9 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) { - struct rk808 *rk808 = rk808_rtc->rk808; int ret; - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->int_reg, BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0); return ret; @@ -239,10 +234,9 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc) { - struct rk808 *rk808 = rk808_rtc->rk808; int ret; - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->int_reg, BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); @@ -252,7 +246,6 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc) static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); - struct rk808 *rk808 = rk808_rtc->rk808; u8 alrm_data[NUM_ALARM_REGS]; int ret; @@ -272,7 +265,7 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1); alrm_data[5] = bin2bcd(alrm->time.tm_year - 100); - ret = regmap_bulk_write(rk808->regmap, + ret = regmap_bulk_write(rk808_rtc->regmap, rk808_rtc->creg->alarm_seconds_reg, alrm_data, NUM_ALARM_REGS); if (ret) { @@ -313,20 +306,18 @@ static int rk808_rtc_alarm_irq_enable(struct device *dev, static irqreturn_t rk808_alarm_irq(int irq, void *data) { struct rk808_rtc *rk808_rtc = data; - struct rk808 *rk808 = rk808_rtc->rk808; - struct i2c_client *client = rk808->i2c; int ret; - ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg, + ret = regmap_write(rk808_rtc->regmap, rk808_rtc->creg->status_reg, RTC_STATUS_MASK); if (ret) { - dev_err(&client->dev, + dev_err(&rk808_rtc->rtc->dev, "%s:Failed to update RTC status: %d\n", __func__, ret); return ret; } rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF); - dev_dbg(&client->dev, + dev_dbg(&rk808_rtc->rtc->dev, "%s:irq=%d\n", __func__, irq); return IRQ_HANDLED; } @@ -404,10 +395,12 @@ static int rk808_rtc_probe(struct platform_device *pdev) break; } platform_set_drvdata(pdev, rk808_rtc); - rk808_rtc->rk808 = rk808; + rk808_rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!rk808_rtc->regmap) + return -ENODEV; /* start rtc running by default, and use shadowed timer. */ - ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg, + ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg, BIT_RTC_CTRL_REG_STOP_RTC_M | BIT_RTC_CTRL_REG_RTC_READSEL_M, BIT_RTC_CTRL_REG_RTC_READSEL_M); @@ -417,7 +410,7 @@ static int rk808_rtc_probe(struct platform_device *pdev) return ret; } - ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg, + ret = regmap_write(rk808_rtc->regmap, rk808_rtc->creg->status_reg, RTC_STATUS_MASK); if (ret) { dev_err(&pdev->dev, diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index e98f85f34206..712a08e9e52d 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c @@ -2,7 +2,7 @@ * Ricoh RS5C313 RTC device/driver * Copyright (C) 2007 Nobuhiro Iwamatsu * - * 2005-09-19 modifed by kogiidena + * 2005-09-19 modified by kogiidena * * Based on the old drivers/char/rs5c313_rtc.c by: * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> @@ -36,7 +36,7 @@ * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer * CONFIG_HPET_EMULATE_RTC - * 1.13 Nobuhiro Iwamatsu: Updata driver. + * 1.13 Nobuhiro Iwamatsu: Update driver. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -280,7 +280,7 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm) while (1) { RS5C313_CEENABLE; /* CE:H */ - /* Initiatlize control reg. 24 hour */ + /* Initialize control reg. 24 hour */ rs5c313_write_cntreg(0x04); if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)) diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 9562c477e1c9..b4c5d016eca3 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -150,7 +150,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) * least 80219 chips; this works around that bug. * * The third method on the other hand doesn't work for the SMBus-only - * configurations, so we use the the first method there, stripping off + * configurations, so we use the first method there, stripping off * the extra register in the process. */ if (rs5c->smbus) { @@ -791,8 +791,7 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372) return 0; } -static int rs5c372_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rs5c372_probe(struct i2c_client *client) { int err = 0; int smbus_mode = 0; @@ -826,11 +825,13 @@ static int rs5c372_probe(struct i2c_client *client, rs5c372->client = client; i2c_set_clientdata(client, rs5c372); - if (client->dev.of_node) + if (client->dev.of_node) { rs5c372->type = (enum rtc_type) of_device_get_match_data(&client->dev); - else + } else { + const struct i2c_device_id *id = i2c_match_id(rs5c372_id, client); rs5c372->type = id->driver_data; + } /* we read registers 0x0f then 0x00-0x0f; skip the first one */ rs5c372->regs = &rs5c372->buf[1]; @@ -920,7 +921,7 @@ static struct i2c_driver rs5c372_driver = { .name = "rtc-rs5c372", .of_match_table = of_match_ptr(rs5c372_of_match), }, - .probe = rs5c372_probe, + .probe_new = rs5c372_probe, .remove = rs5c372_remove, .id_table = rs5c372_id, }; diff --git a/drivers/rtc/rtc-rtd119x.c b/drivers/rtc/rtc-rtd119x.c index 8f9abd65846c..29662dfd56fe 100644 --- a/drivers/rtc/rtc-rtd119x.c +++ b/drivers/rtc/rtc-rtd119x.c @@ -216,7 +216,7 @@ static int rtd119x_rtc_probe(struct platform_device *pdev) return 0; } -static int rtd119x_rtc_remove(struct platform_device *pdev) +static void rtd119x_rtc_remove(struct platform_device *pdev) { struct rtd119x_rtc *data = platform_get_drvdata(pdev); @@ -224,13 +224,11 @@ static int rtd119x_rtc_remove(struct platform_device *pdev) clk_disable_unprepare(data->clk); clk_put(data->clk); - - return 0; } static struct platform_driver rtd119x_rtc_driver = { .probe = rtd119x_rtc_probe, - .remove = rtd119x_rtc_remove, + .remove_new = rtd119x_rtc_remove, .driver = { .name = "rtd1295-rtc", .of_match_table = rtd119x_rtc_dt_ids, diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index dd170e3efd83..ec5d7a614e2d 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -902,9 +902,20 @@ static int rv3028_probe(struct i2c_client *client) return PTR_ERR(rv3028->rtc); if (client->irq > 0) { + unsigned long flags; + + /* + * If flags = 0, devm_request_threaded_irq() will use IRQ flags + * obtained from device tree. + */ + if (dev_fwnode(&client->dev)) + flags = 0; + else + flags = IRQF_TRIGGER_LOW; + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, rv3028_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + flags | IRQF_ONESHOT, "rv3028", rv3028); if (ret) { dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); @@ -971,6 +982,12 @@ static int rv3028_probe(struct i2c_client *client) return 0; } +static const struct acpi_device_id rv3028_i2c_acpi_match[] = { + { "MCRY3028" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, rv3028_i2c_acpi_match); + static const __maybe_unused struct of_device_id rv3028_of_match[] = { { .compatible = "microcrystal,rv3028", }, { } @@ -980,6 +997,7 @@ MODULE_DEVICE_TABLE(of, rv3028_of_match); 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, diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index eb483a30bd92..0852f6709a85 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -17,6 +17,7 @@ #include <linux/of.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> +#include <linux/kstrtox.h> #include <linux/regmap.h> /* Register map */ @@ -734,9 +735,14 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, return PTR_ERR(rv3029->rtc); if (rv3029->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(dev)) + irqflags = 0; + rc = devm_request_threaded_irq(dev, rv3029->irq, NULL, rv3029_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "rv3029", dev); if (rc) { dev_warn(dev, "unable to request IRQ, alarms disabled\n"); diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c index c3bee305eacc..1ff4f2e6fa77 100644 --- a/drivers/rtc/rtc-rv3032.c +++ b/drivers/rtc/rtc-rv3032.c @@ -930,9 +930,14 @@ static int rv3032_probe(struct i2c_client *client) return PTR_ERR(rv3032->rtc); if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, rv3032_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "rv3032", rv3032); if (ret) { dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); @@ -975,6 +980,12 @@ static int rv3032_probe(struct i2c_client *client) return 0; } +static const struct acpi_device_id rv3032_i2c_acpi_match[] = { + { "MCRY3032" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, rv3032_i2c_acpi_match); + static const __maybe_unused struct of_device_id rv3032_of_match[] = { { .compatible = "microcrystal,rv3032", }, { } @@ -984,6 +995,7 @@ MODULE_DEVICE_TABLE(of, rv3032_of_match); static struct i2c_driver rv3032_driver = { .driver = { .name = "rtc-rv3032", + .acpi_match_table = rv3032_i2c_acpi_match, .of_match_table = of_match_ptr(rv3032_of_match), }, .probe_new = rv3032_probe, diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 3527a0521e9b..25c3b9e4f515 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -70,6 +70,7 @@ struct rv8803_data { struct mutex flags_lock; u8 ctrl; u8 backup; + u8 alarm_invalid:1; enum rv8803_type type; }; @@ -165,13 +166,13 @@ static int rv8803_regs_init(struct rv8803_data *rv8803) static int rv8803_regs_configure(struct rv8803_data *rv8803); -static int rv8803_regs_reset(struct rv8803_data *rv8803) +static int rv8803_regs_reset(struct rv8803_data *rv8803, bool full) { /* * The RV-8803 resets all registers to POR defaults after voltage-loss, * the Epson RTCs don't, so we manually reset the remainder here. */ - if (rv8803->type == rx_8803 || rv8803->type == rx_8900) { + if (full || rv8803->type == rx_8803 || rv8803->type == rx_8900) { int ret = rv8803_regs_init(rv8803); if (ret) return ret; @@ -238,6 +239,11 @@ static int rv8803_get_time(struct device *dev, struct rtc_time *tm) u8 *date = date1; int ret, flags; + if (rv8803->alarm_invalid) { + dev_warn(dev, "Corruption detected, data may be invalid.\n"); + return -EINVAL; + } + flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); if (flags < 0) return flags; @@ -313,12 +319,19 @@ static int rv8803_set_time(struct device *dev, struct rtc_time *tm) return flags; } - if (flags & RV8803_FLAG_V2F) { - ret = rv8803_regs_reset(rv8803); + if ((flags & RV8803_FLAG_V2F) || rv8803->alarm_invalid) { + /* + * If we sense corruption in the alarm registers, but see no + * voltage loss flag, we can't rely on other registers having + * sensible values. Reset them fully. + */ + ret = rv8803_regs_reset(rv8803, rv8803->alarm_invalid); if (ret) { mutex_unlock(&rv8803->flags_lock); return ret; } + + rv8803->alarm_invalid = false; } ret = rv8803_write_reg(rv8803->client, RV8803_FLAG, @@ -344,15 +357,33 @@ static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) if (flags < 0) return flags; + alarmvals[0] &= 0x7f; + alarmvals[1] &= 0x3f; + alarmvals[2] &= 0x3f; + + if (!bcd_is_valid(alarmvals[0]) || + !bcd_is_valid(alarmvals[1]) || + !bcd_is_valid(alarmvals[2])) + goto err_invalid; + alrm->time.tm_sec = 0; - alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); - alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); - alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); + alrm->time.tm_min = bcd2bin(alarmvals[0]); + alrm->time.tm_hour = bcd2bin(alarmvals[1]); + alrm->time.tm_mday = bcd2bin(alarmvals[2]); alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE); alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled; + if ((unsigned int)alrm->time.tm_mday > 31 || + (unsigned int)alrm->time.tm_hour >= 24 || + (unsigned int)alrm->time.tm_min >= 60) + goto err_invalid; + return 0; + +err_invalid: + rv8803->alarm_invalid = true; + return -EINVAL; } static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -576,8 +607,16 @@ static int rv8803_regs_configure(struct rv8803_data *rv8803) return 0; } -static int rv8803_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct i2c_device_id rv8803_id[] = { + { "rv8803", rv_8803 }, + { "rv8804", rx_8804 }, + { "rx8803", rx_8803 }, + { "rx8900", rx_8900 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rv8803_id); + +static int rv8803_probe(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; struct rv8803_data *rv8803; @@ -605,11 +644,14 @@ static int rv8803_probe(struct i2c_client *client, mutex_init(&rv8803->flags_lock); rv8803->client = client; - if (client->dev.of_node) + if (client->dev.of_node) { rv8803->type = (enum rv8803_type) of_device_get_match_data(&client->dev); - else + } else { + const struct i2c_device_id *id = i2c_match_id(rv8803_id, client); + rv8803->type = id->driver_data; + } i2c_set_clientdata(client, rv8803); flags = rv8803_read_reg(client, RV8803_FLAG); @@ -630,9 +672,14 @@ static int rv8803_probe(struct i2c_client *client, return PTR_ERR(rv8803->rtc); if (client->irq > 0) { + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + err = devm_request_threaded_irq(&client->dev, client->irq, NULL, rv8803_handle_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "rv8803", client); if (err) { dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); @@ -666,15 +713,6 @@ static int rv8803_probe(struct i2c_client *client, return 0; } -static const struct i2c_device_id rv8803_id[] = { - { "rv8803", rv_8803 }, - { "rv8804", rx_8804 }, - { "rx8803", rx_8803 }, - { "rx8900", rx_8900 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, rv8803_id); - static const __maybe_unused struct of_device_id rv8803_of_match[] = { { .compatible = "microcrystal,rv8803", @@ -701,7 +739,7 @@ static struct i2c_driver rv8803_driver = { .name = "rtc-rv8803", .of_match_table = of_match_ptr(rv8803_of_match), }, - .probe = rv8803_probe, + .probe_new = 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 cc634558b928..37608883a796 100644 --- a/drivers/rtc/rtc-rx6110.c +++ b/drivers/rtc/rtc-rx6110.c @@ -10,7 +10,6 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_gpio.h> #include <linux/regmap.h> #include <linux/rtc.h> #include <linux/of.h> @@ -376,7 +375,7 @@ static const struct spi_device_id rx6110_spi_id[] = { }; MODULE_DEVICE_TABLE(spi, rx6110_spi_id); -static const struct of_device_id rx6110_spi_of_match[] = { +static const __maybe_unused struct of_device_id rx6110_spi_of_match[] = { { .compatible = "epson,rx6110" }, { }, }; diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index d09056570739..b9c8dad26208 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -394,10 +394,14 @@ static int rx8010_probe(struct i2c_client *client) return PTR_ERR(rx8010->rtc); if (client->irq > 0) { - dev_info(dev, "IRQ %d supplied\n", client->irq); + unsigned long irqflags = IRQF_TRIGGER_LOW; + + if (dev_fwnode(&client->dev)) + irqflags = 0; + err = devm_request_threaded_irq(dev, client->irq, NULL, rx8010_irq_1_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + irqflags | IRQF_ONESHOT, "rx8010", client); if (err) { dev_err(dev, "unable to request IRQ\n"); diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index dde86f3e2a4b..331c20d4d843 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -19,6 +19,7 @@ #include <linux/bitops.h> #include <linux/i2c.h> #include <linux/kernel.h> +#include <linux/kstrtox.h> #include <linux/module.h> #include <linux/rtc.h> @@ -519,9 +520,9 @@ static const struct attribute_group rx8025_attr_group = { .attrs = rx8025_attrs, }; -static int rx8025_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int rx8025_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_match_id(rx8025_id, client); struct i2c_adapter *adapter = client->adapter; struct rx8025_data *rx8025; int err = 0; @@ -580,7 +581,7 @@ static struct i2c_driver rx8025_driver = { .driver = { .name = "rtc-rx8025", }, - .probe = rx8025_probe, + .probe_new = rx8025_probe, .id_table = rx8025_id, }; diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c index ac788799c8e3..dca736caba85 100644 --- a/drivers/rtc/rtc-rzn1.c +++ b/drivers/rtc/rtc-rzn1.c @@ -355,7 +355,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev) set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features); clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features); - devm_pm_runtime_enable(&pdev->dev); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret < 0) + return ret; ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; @@ -389,11 +391,9 @@ dis_runtime_pm: return ret; } -static int rzn1_rtc_remove(struct platform_device *pdev) +static void rzn1_rtc_remove(struct platform_device *pdev) { pm_runtime_put(&pdev->dev); - - return 0; } static const struct of_device_id rzn1_rtc_of_match[] = { @@ -404,7 +404,7 @@ MODULE_DEVICE_TABLE(of, rzn1_rtc_of_match); static struct platform_driver rzn1_rtc_driver = { .probe = rzn1_rtc_probe, - .remove = rzn1_rtc_remove, + .remove_new = rzn1_rtc_remove, .driver = { .name = "rzn1-rtc", .of_match_table = rzn1_rtc_of_match, diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 81d97b1d3159..b18daaf72b17 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -211,7 +211,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct i2c_client *client = to_i2c_client(dev); struct s35390a *s35390a = i2c_get_clientdata(client); - int i, err; + int i; char buf[7], status; dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " @@ -234,9 +234,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) for (i = 0; i < 7; ++i) buf[i] = bitrev8(buf[i]); - err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); - - return err; + return s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); } static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index db529733c9c4..70e1a18e5efd 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -385,7 +385,7 @@ static void s3c6410_rtc_disable(struct s3c_rtc *info) writew(con, info->base + S3C2410_RTCCON); } -static int s3c_rtc_remove(struct platform_device *pdev) +static void s3c_rtc_remove(struct platform_device *pdev) { struct s3c_rtc *info = platform_get_drvdata(pdev); @@ -394,8 +394,6 @@ static int s3c_rtc_remove(struct platform_device *pdev) if (info->data->needs_src_clk) clk_unprepare(info->rtc_src_clk); clk_unprepare(info->rtc_clk); - - return 0; } static int s3c_rtc_probe(struct platform_device *pdev) @@ -429,14 +427,9 @@ static int s3c_rtc_probe(struct platform_device *pdev) return PTR_ERR(info->base); info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); - if (IS_ERR(info->rtc_clk)) { - ret = PTR_ERR(info->rtc_clk); - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to find rtc clock\n"); - else - dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n"); - return ret; - } + if (IS_ERR(info->rtc_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_clk), + "failed to find rtc clock\n"); ret = clk_prepare_enable(info->rtc_clk); if (ret) return ret; @@ -605,7 +598,7 @@ MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); static struct platform_driver s3c_rtc_driver = { .probe = s3c_rtc_probe, - .remove = s3c_rtc_remove, + .remove_new = s3c_rtc_remove, .driver = { .name = "s3c-rtc", .pm = &s3c_rtc_pm_ops, diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 4243fe6d3842..dad294a0ce2a 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -85,7 +85,7 @@ struct s5m_rtc_reg_config { unsigned int write_alarm_udr_mask; }; -/* Register map for S5M8763 and S5M8767 */ +/* Register map for S5M8767 */ static const struct s5m_rtc_reg_config s5m_rtc_regs = { .regs_count = 8, .time = S5M_RTC_SEC, @@ -236,7 +236,6 @@ static int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info, switch (info->device_type) { case S5M8767X: - case S5M8763X: ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val); val &= S5M_ALARM0_STATUS; break; @@ -299,7 +298,6 @@ static int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) data |= info->regs->write_alarm_udr_mask; switch (info->device_type) { - case S5M8763X: case S5M8767X: data &= ~S5M_RTC_TIME_EN_MASK; break; @@ -329,38 +327,6 @@ static int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) return ret; } -static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm) -{ - tm->tm_sec = bcd2bin(data[RTC_SEC]); - tm->tm_min = bcd2bin(data[RTC_MIN]); - - if (data[RTC_HOUR] & HOUR_12) { - tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f); - if (data[RTC_HOUR] & HOUR_PM) - tm->tm_hour += 12; - } else { - tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f); - } - - tm->tm_wday = data[RTC_WEEKDAY] & 0x07; - tm->tm_mday = bcd2bin(data[RTC_DATE]); - tm->tm_mon = bcd2bin(data[RTC_MONTH]); - tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100; - tm->tm_year -= 1900; -} - -static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data) -{ - data[RTC_SEC] = bin2bcd(tm->tm_sec); - data[RTC_MIN] = bin2bcd(tm->tm_min); - data[RTC_HOUR] = bin2bcd(tm->tm_hour); - data[RTC_WEEKDAY] = tm->tm_wday; - data[RTC_DATE] = bin2bcd(tm->tm_mday); - data[RTC_MONTH] = bin2bcd(tm->tm_mon); - data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100); - data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100); -} - static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct s5m_rtc_info *info = dev_get_drvdata(dev); @@ -385,10 +351,6 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) return ret; switch (info->device_type) { - case S5M8763X: - s5m8763_data_to_tm(data, tm); - break; - case S5M8767X: case S2MPS15X: case S2MPS14X: @@ -412,9 +374,6 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) int ret = 0; switch (info->device_type) { - case S5M8763X: - s5m8763_tm_to_data(tm, data); - break; case S5M8767X: case S2MPS15X: case S2MPS14X: @@ -444,7 +403,6 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct s5m_rtc_info *info = dev_get_drvdata(dev); u8 data[RTC_MAX_NUM_TIME_REGS]; - unsigned int val; int ret, i; ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data, @@ -453,15 +411,6 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; switch (info->device_type) { - case S5M8763X: - s5m8763_data_to_tm(data, &alrm->time); - ret = regmap_read(info->regmap, S5M_ALARM0_CONF, &val); - if (ret < 0) - return ret; - - alrm->enabled = !!val; - break; - case S5M8767X: case S2MPS15X: case S2MPS14X: @@ -500,10 +449,6 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday); switch (info->device_type) { - case S5M8763X: - ret = regmap_write(info->regmap, S5M_ALARM0_CONF, 0); - break; - case S5M8767X: case S2MPS15X: case S2MPS14X: @@ -531,7 +476,6 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) { int ret; u8 data[RTC_MAX_NUM_TIME_REGS]; - u8 alarm0_conf; struct rtc_time tm; ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data, @@ -543,11 +487,6 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday); switch (info->device_type) { - case S5M8763X: - alarm0_conf = 0x77; - ret = regmap_write(info->regmap, S5M_ALARM0_CONF, alarm0_conf); - break; - case S5M8767X: case S2MPS15X: case S2MPS14X: @@ -585,10 +524,6 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) int ret; switch (info->device_type) { - case S5M8763X: - s5m8763_tm_to_data(&alrm->time, data); - break; - case S5M8767X: case S2MPS15X: case S2MPS14X: @@ -655,7 +590,6 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) int ret; switch (info->device_type) { - case S5M8763X: case S5M8767X: /* UDR update time. Default of 7.32 ms is too long. */ ret = regmap_update_bits(info->regmap, S5M_RTC_UDR_CON, @@ -729,11 +663,6 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->regs = &s2mps13_rtc_regs; alarm_irq = S2MPS14_IRQ_RTCA0; break; - case S5M8763X: - regmap_cfg = &s5m_rtc_regmap_config; - info->regs = &s5m_rtc_regs; - alarm_irq = S5M8763_IRQ_ALARM0; - break; case S5M8767X: regmap_cfg = &s5m_rtc_regmap_config; info->regs = &s5m_rtc_regs; @@ -786,13 +715,8 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->rtc_dev->ops = &s5m_rtc_ops; - if (info->device_type == S5M8763X) { - info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000; - info->rtc_dev->range_max = RTC_TIMESTAMP_END_9999; - } else { - info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; - info->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; - } + info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; + info->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; if (!info->irq) { clear_bit(RTC_FEATURE_ALARM, info->rtc_dev->features); diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 1250887e4382..0b2cfa8ca05b 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -297,7 +297,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev) return sa1100_rtc_init(pdev, info); } -static int sa1100_rtc_remove(struct platform_device *pdev) +static void sa1100_rtc_remove(struct platform_device *pdev) { struct sa1100_rtc *info = platform_get_drvdata(pdev); @@ -307,8 +307,6 @@ static int sa1100_rtc_remove(struct platform_device *pdev) spin_unlock_irq(&info->lock); clk_disable_unprepare(info->clk); } - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -343,7 +341,7 @@ MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids); static struct platform_driver sa1100_rtc_driver = { .probe = sa1100_rtc_probe, - .remove = sa1100_rtc_remove, + .remove_new = sa1100_rtc_remove, .driver = { .name = "sa1100-rtc", .pm = &sa1100_rtc_pm_ops, diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index bd929b0e7d7d..d82acf1af1fa 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -32,6 +32,14 @@ #define SNVS_LPPGDR_INIT 0x41736166 #define CNTR_TO_SECS_SH 15 +/* The maximum RTC clock cycles that are allowed to pass between two + * consecutive clock counter register reads. If the values are corrupted a + * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles + * we end at 10ms which should be enough for most cases. If it once takes + * longer than expected we do a retry. + */ +#define MAX_RTC_READ_DIFF_CYCLES 320 + struct snvs_rtc_data { struct rtc_device *rtc; struct regmap *regmap; @@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data) static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) { u64 read1, read2; + s64 diff; unsigned int timeout = 100; /* As expected, the registers might update between the read of the LSB @@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) do { read2 = read1; read1 = rtc_read_lpsrt(data); - } while (read1 != read2 && --timeout); + diff = read1 - read2; + } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); if (!timeout) dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); @@ -78,13 +88,15 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb) { u32 count1, count2; + s32 diff; unsigned int timeout = 100; regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); do { count2 = count1; regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); - } while (count1 != count2 && --timeout); + diff = count1 - count2; + } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); if (!timeout) { dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); return -ETIMEDOUT; diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index 736fe535cd45..1df5c7e94198 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -405,15 +405,13 @@ err_disable_clock: return status; } -static int spear_rtc_remove(struct platform_device *pdev) +static void spear_rtc_remove(struct platform_device *pdev) { struct spear_rtc_config *config = platform_get_drvdata(pdev); spear_rtc_disable_interrupt(config); clk_disable_unprepare(config->clk); device_init_wakeup(&pdev->dev, 0); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -477,7 +475,7 @@ MODULE_DEVICE_TABLE(of, spear_rtc_id_table); static struct platform_driver spear_rtc_driver = { .probe = spear_rtc_probe, - .remove = spear_rtc_remove, + .remove_new = spear_rtc_remove, .shutdown = spear_rtc_shutdown, .driver = { .name = "rtc-spear", diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index bdb20f63254e..0f8e4231098e 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev) 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; } diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index ac9e228b56d0..229cb2847cc4 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -846,7 +846,7 @@ err_no_rtc_ck: return ret; } -static int stm32_rtc_remove(struct platform_device *pdev) +static void stm32_rtc_remove(struct platform_device *pdev) { struct stm32_rtc *rtc = platform_get_drvdata(pdev); const struct stm32_rtc_registers *regs = &rtc->data->regs; @@ -869,8 +869,6 @@ static int stm32_rtc_remove(struct platform_device *pdev) dev_pm_clear_wake_irq(&pdev->dev); device_init_wakeup(&pdev->dev, false); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -917,7 +915,7 @@ static SIMPLE_DEV_PM_OPS(stm32_rtc_pm_ops, static struct platform_driver stm32_rtc_driver = { .probe = stm32_rtc_probe, - .remove = stm32_rtc_remove, + .remove_new = stm32_rtc_remove, .driver = { .name = DRIVER_NAME, .pm = &stm32_rtc_pm_ops, diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index aae40d20d086..6f11b745f34d 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -232,17 +232,15 @@ static const struct rtc_class_ops stmp3xxx_rtc_ops = { .set_alarm = stmp3xxx_rtc_set_alarm, }; -static int stmp3xxx_rtc_remove(struct platform_device *pdev) +static void stmp3xxx_rtc_remove(struct platform_device *pdev) { struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(pdev); if (!rtc_data) - return 0; + return; writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR); - - return 0; } static int stmp3xxx_rtc_probe(struct platform_device *pdev) @@ -406,7 +404,7 @@ MODULE_DEVICE_TABLE(of, rtc_dt_ids); static struct platform_driver stmp3xxx_rtcdrv = { .probe = stmp3xxx_rtc_probe, - .remove = stmp3xxx_rtc_remove, + .remove_new = stmp3xxx_rtc_remove, .driver = { .name = "stmp3xxx-rtc", .pm = &stmp3xxx_rtc_pm_ops, diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index ed5516089e9a..dc76537f1b62 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -136,7 +136,6 @@ struct sun6i_rtc_clk_data { unsigned int fixed_prescaler : 16; unsigned int has_prescaler : 1; unsigned int has_out_clk : 1; - unsigned int export_iosc : 1; unsigned int has_losc_en : 1; unsigned int has_auto_swt : 1; }; @@ -261,7 +260,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, } /* Switch to the external, more precise, oscillator, if present */ - if (of_get_property(node, "clocks", NULL)) { + if (of_property_present(node, "clocks")) { reg |= SUN6I_LOSC_CTRL_EXT_OSC; if (rtc->data->has_losc_en) reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; @@ -271,10 +270,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, /* Yes, I know, this is ugly. */ sun6i_rtc = rtc; - /* Only read IOSC name from device tree if it is exported */ - if (rtc->data->export_iosc) - of_property_read_string_index(node, "clock-output-names", 2, - &iosc_name); + of_property_read_string_index(node, "clock-output-names", 2, + &iosc_name); rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL, iosc_name, @@ -315,13 +312,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, goto err_register; } - clk_data->num = 2; + clk_data->num = 3; clk_data->hws[0] = &rtc->hw; clk_data->hws[1] = __clk_get_hw(rtc->ext_losc); - if (rtc->data->export_iosc) { - clk_data->hws[2] = rtc->int_osc; - clk_data->num = 3; - } + clk_data->hws[2] = rtc->int_osc; of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); return; @@ -361,7 +355,6 @@ static const struct sun6i_rtc_clk_data sun8i_h3_rtc_data = { .fixed_prescaler = 32, .has_prescaler = 1, .has_out_clk = 1, - .export_iosc = 1, }; static void __init sun8i_h3_rtc_clk_init(struct device_node *node) @@ -379,7 +372,6 @@ static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = { .fixed_prescaler = 32, .has_prescaler = 1, .has_out_clk = 1, - .export_iosc = 1, .has_losc_en = 1, .has_auto_swt = 1, }; diff --git a/drivers/rtc/rtc-sunplus.c b/drivers/rtc/rtc-sunplus.c index e8e2ab1103fc..f33dc301f301 100644 --- a/drivers/rtc/rtc-sunplus.c +++ b/drivers/rtc/rtc-sunplus.c @@ -235,13 +235,12 @@ static int sp_rtc_probe(struct platform_device *plat_dev) if (!sp_rtc) return -ENOMEM; - sp_rtc->res = platform_get_resource_byname(plat_dev, IORESOURCE_MEM, RTC_REG_NAME); - sp_rtc->reg_base = devm_ioremap_resource(&plat_dev->dev, sp_rtc->res); + sp_rtc->reg_base = devm_platform_ioremap_resource_byname(plat_dev, RTC_REG_NAME); if (IS_ERR(sp_rtc->reg_base)) return dev_err_probe(&plat_dev->dev, PTR_ERR(sp_rtc->reg_base), "%s devm_ioremap_resource fail\n", RTC_REG_NAME); - dev_dbg(&plat_dev->dev, "res = 0x%x, reg_base = 0x%lx\n", - sp_rtc->res->start, (unsigned long)sp_rtc->reg_base); + dev_dbg(&plat_dev->dev, "res = %pR, reg_base = %p\n", + sp_rtc->res, sp_rtc->reg_base); sp_rtc->irq = platform_get_irq(plat_dev, 0); if (sp_rtc->irq < 0) @@ -304,15 +303,13 @@ free_clk: return ret; } -static int sp_rtc_remove(struct platform_device *plat_dev) +static void sp_rtc_remove(struct platform_device *plat_dev) { struct sunplus_rtc *sp_rtc = dev_get_drvdata(&plat_dev->dev); device_init_wakeup(&plat_dev->dev, 0); reset_control_assert(sp_rtc->rstc); clk_disable_unprepare(sp_rtc->rtcclk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -347,7 +344,7 @@ static SIMPLE_DEV_PM_OPS(sp_rtc_pm_ops, sp_rtc_suspend, sp_rtc_resume); static struct platform_driver sp_rtc_driver = { .probe = sp_rtc_probe, - .remove = sp_rtc_remove, + .remove_new = sp_rtc_remove, .driver = { .name = "sp7021-rtc", .of_match_table = sp_rtc_of_match, diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 85f7ad5d5390..441e0a66b215 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -342,13 +342,11 @@ disable_clk: return ret; } -static int tegra_rtc_remove(struct platform_device *pdev) +static void tegra_rtc_remove(struct platform_device *pdev) { struct tegra_rtc_info *info = platform_get_drvdata(pdev); clk_disable_unprepare(info->clk); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -401,7 +399,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) static struct platform_driver tegra_rtc_driver = { .probe = tegra_rtc_probe, - .remove = tegra_rtc_remove, + .remove_new = tegra_rtc_remove, .shutdown = tegra_rtc_shutdown, .driver = { .name = "tegra_rtc", diff --git a/drivers/rtc/rtc-ti-k3.c b/drivers/rtc/rtc-ti-k3.c index ba23163cc042..0d90fe923355 100644 --- a/drivers/rtc/rtc-ti-k3.c +++ b/drivers/rtc/rtc-ti-k3.c @@ -632,7 +632,8 @@ static int __maybe_unused ti_k3_rtc_suspend(struct device *dev) struct ti_k3_rtc *priv = dev_get_drvdata(dev); if (device_may_wakeup(dev)) - enable_irq_wake(priv->irq); + return enable_irq_wake(priv->irq); + return 0; } diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index 52093e7ba22d..9f14e2475747 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -279,13 +279,12 @@ fail_rtc_register: return ret; }; -static int tps6586x_rtc_remove(struct platform_device *pdev) +static void tps6586x_rtc_remove(struct platform_device *pdev) { struct device *tps_dev = to_tps6586x_dev(&pdev->dev); tps6586x_update(tps_dev, RTC_CTRL, 0, RTC_ENABLE | OSC_SRC_SEL | PRE_BYPASS | CL_SEL_MASK); - return 0; } #ifdef CONFIG_PM_SLEEP @@ -317,7 +316,7 @@ static struct platform_driver tps6586x_rtc_driver = { .pm = &tps6586x_pm_ops, }, .probe = tps6586x_rtc_probe, - .remove = tps6586x_rtc_remove, + .remove_new = tps6586x_rtc_remove, }; module_platform_driver(tps6586x_rtc_driver); diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index c24d1e18f56c..81b36948c2fa 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -586,7 +586,7 @@ static int twl_rtc_probe(struct platform_device *pdev) * Disable all TWL RTC module interrupts. * Sets status flag to free. */ -static int twl_rtc_remove(struct platform_device *pdev) +static void twl_rtc_remove(struct platform_device *pdev) { struct twl_rtc *twl_rtc = platform_get_drvdata(pdev); @@ -599,8 +599,6 @@ static int twl_rtc_remove(struct platform_device *pdev) twl6030_interrupt_mask(TWL6030_RTC_INT_MASK, REG_INT_MSK_STS_A); } - - return 0; } static void twl_rtc_shutdown(struct platform_device *pdev) @@ -642,7 +640,7 @@ MODULE_DEVICE_TABLE(of, twl_rtc_of_match); static struct platform_driver twl4030rtc_driver = { .probe = twl_rtc_probe, - .remove = twl_rtc_remove, + .remove_new = twl_rtc_remove, .shutdown = twl_rtc_shutdown, .driver = { .name = "twl_rtc", diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c deleted file mode 100644 index 4e8341c49f51..000000000000 --- a/drivers/rtc/rtc-v3020.c +++ /dev/null @@ -1,369 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* drivers/rtc/rtc-v3020.c - * - * Copyright (C) 2006 8D Technologies inc. - * Copyright (C) 2004 Compulab Ltd. - * - * Driver for the V3020 RTC - * - * Changelog: - * - * 10-May-2006: Raphael Assenat <raph@8d.com> - * - Converted to platform driver - * - Use the generic rtc class - * - * ??-???-2004: Someone at Compulab - * - Initial driver creation. - */ -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/rtc.h> -#include <linux/types.h> -#include <linux/bcd.h> -#include <linux/platform_data/rtc-v3020.h> -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/slab.h> - -#include <linux/io.h> - -#undef DEBUG - -struct v3020; - -struct v3020_chip_ops { - int (*map_io)(struct v3020 *chip, struct platform_device *pdev, - struct v3020_platform_data *pdata); - void (*unmap_io)(struct v3020 *chip); - unsigned char (*read_bit)(struct v3020 *chip); - void (*write_bit)(struct v3020 *chip, unsigned char bit); -}; - -#define V3020_CS 0 -#define V3020_WR 1 -#define V3020_RD 2 -#define V3020_IO 3 - -struct v3020 { - /* MMIO access */ - void __iomem *ioaddress; - int leftshift; - - /* GPIO access */ - struct gpio *gpio; - - const struct v3020_chip_ops *ops; - - struct rtc_device *rtc; -}; - - -static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev, - struct v3020_platform_data *pdata) -{ - if (pdev->num_resources != 1) - return -EBUSY; - - if (pdev->resource[0].flags != IORESOURCE_MEM) - return -EBUSY; - - chip->leftshift = pdata->leftshift; - chip->ioaddress = ioremap(pdev->resource[0].start, 1); - if (chip->ioaddress == NULL) - return -EBUSY; - - return 0; -} - -static void v3020_mmio_unmap(struct v3020 *chip) -{ - iounmap(chip->ioaddress); -} - -static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit) -{ - writel(bit << chip->leftshift, chip->ioaddress); -} - -static unsigned char v3020_mmio_read_bit(struct v3020 *chip) -{ - return !!(readl(chip->ioaddress) & (1 << chip->leftshift)); -} - -static const struct v3020_chip_ops v3020_mmio_ops = { - .map_io = v3020_mmio_map, - .unmap_io = v3020_mmio_unmap, - .read_bit = v3020_mmio_read_bit, - .write_bit = v3020_mmio_write_bit, -}; - -static struct gpio v3020_gpio[] = { - { 0, GPIOF_OUT_INIT_HIGH, "RTC CS"}, - { 0, GPIOF_OUT_INIT_HIGH, "RTC WR"}, - { 0, GPIOF_OUT_INIT_HIGH, "RTC RD"}, - { 0, GPIOF_OUT_INIT_HIGH, "RTC IO"}, -}; - -static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev, - struct v3020_platform_data *pdata) -{ - int err; - - v3020_gpio[V3020_CS].gpio = pdata->gpio_cs; - v3020_gpio[V3020_WR].gpio = pdata->gpio_wr; - v3020_gpio[V3020_RD].gpio = pdata->gpio_rd; - v3020_gpio[V3020_IO].gpio = pdata->gpio_io; - - err = gpio_request_array(v3020_gpio, ARRAY_SIZE(v3020_gpio)); - - if (!err) - chip->gpio = v3020_gpio; - - return err; -} - -static void v3020_gpio_unmap(struct v3020 *chip) -{ - gpio_free_array(v3020_gpio, ARRAY_SIZE(v3020_gpio)); -} - -static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit) -{ - gpio_direction_output(chip->gpio[V3020_IO].gpio, bit); - gpio_set_value(chip->gpio[V3020_CS].gpio, 0); - gpio_set_value(chip->gpio[V3020_WR].gpio, 0); - udelay(1); - gpio_set_value(chip->gpio[V3020_WR].gpio, 1); - gpio_set_value(chip->gpio[V3020_CS].gpio, 1); -} - -static unsigned char v3020_gpio_read_bit(struct v3020 *chip) -{ - int bit; - - gpio_direction_input(chip->gpio[V3020_IO].gpio); - gpio_set_value(chip->gpio[V3020_CS].gpio, 0); - gpio_set_value(chip->gpio[V3020_RD].gpio, 0); - udelay(1); - bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio); - udelay(1); - gpio_set_value(chip->gpio[V3020_RD].gpio, 1); - gpio_set_value(chip->gpio[V3020_CS].gpio, 1); - - return bit; -} - -static const struct v3020_chip_ops v3020_gpio_ops = { - .map_io = v3020_gpio_map, - .unmap_io = v3020_gpio_unmap, - .read_bit = v3020_gpio_read_bit, - .write_bit = v3020_gpio_write_bit, -}; - -static void v3020_set_reg(struct v3020 *chip, unsigned char address, - unsigned char data) -{ - int i; - unsigned char tmp; - - tmp = address; - for (i = 0; i < 4; i++) { - chip->ops->write_bit(chip, (tmp & 1)); - tmp >>= 1; - udelay(1); - } - - /* Commands dont have data */ - if (!V3020_IS_COMMAND(address)) { - for (i = 0; i < 8; i++) { - chip->ops->write_bit(chip, (data & 1)); - data >>= 1; - udelay(1); - } - } -} - -static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address) -{ - unsigned int data = 0; - int i; - - for (i = 0; i < 4; i++) { - chip->ops->write_bit(chip, (address & 1)); - address >>= 1; - udelay(1); - } - - for (i = 0; i < 8; i++) { - data >>= 1; - if (chip->ops->read_bit(chip)) - data |= 0x80; - udelay(1); - } - - return data; -} - -static int v3020_read_time(struct device *dev, struct rtc_time *dt) -{ - struct v3020 *chip = dev_get_drvdata(dev); - int tmp; - - /* Copy the current time to ram... */ - v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0); - - /* ...and then read constant values. */ - tmp = v3020_get_reg(chip, V3020_SECONDS); - dt->tm_sec = bcd2bin(tmp); - tmp = v3020_get_reg(chip, V3020_MINUTES); - dt->tm_min = bcd2bin(tmp); - tmp = v3020_get_reg(chip, V3020_HOURS); - dt->tm_hour = bcd2bin(tmp); - tmp = v3020_get_reg(chip, V3020_MONTH_DAY); - dt->tm_mday = bcd2bin(tmp); - tmp = v3020_get_reg(chip, V3020_MONTH); - dt->tm_mon = bcd2bin(tmp) - 1; - tmp = v3020_get_reg(chip, V3020_WEEK_DAY); - dt->tm_wday = bcd2bin(tmp); - tmp = v3020_get_reg(chip, V3020_YEAR); - dt->tm_year = bcd2bin(tmp)+100; - - dev_dbg(dev, "\n%s : Read RTC values\n", __func__); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); - dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); - - return 0; -} - - -static int v3020_set_time(struct device *dev, struct rtc_time *dt) -{ - struct v3020 *chip = dev_get_drvdata(dev); - - dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); - dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); - dev_dbg(dev, "tm_min : %i\n", dt->tm_min); - dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); - dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); - dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); - dev_dbg(dev, "tm_year: %i\n", dt->tm_year); - - /* Write all the values to ram... */ - v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec)); - v3020_set_reg(chip, V3020_MINUTES, bin2bcd(dt->tm_min)); - v3020_set_reg(chip, V3020_HOURS, bin2bcd(dt->tm_hour)); - v3020_set_reg(chip, V3020_MONTH_DAY, bin2bcd(dt->tm_mday)); - v3020_set_reg(chip, V3020_MONTH, bin2bcd(dt->tm_mon + 1)); - v3020_set_reg(chip, V3020_WEEK_DAY, bin2bcd(dt->tm_wday)); - v3020_set_reg(chip, V3020_YEAR, bin2bcd(dt->tm_year % 100)); - - /* ...and set the clock. */ - v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0); - - /* Compulab used this delay here. I dont know why, - * the datasheet does not specify a delay. */ - /*mdelay(5);*/ - - return 0; -} - -static const struct rtc_class_ops v3020_rtc_ops = { - .read_time = v3020_read_time, - .set_time = v3020_set_time, -}; - -static int rtc_probe(struct platform_device *pdev) -{ - struct v3020_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct v3020 *chip; - int retval; - int i; - - chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - if (pdata->use_gpio) - chip->ops = &v3020_gpio_ops; - else - chip->ops = &v3020_mmio_ops; - - retval = chip->ops->map_io(chip, pdev, pdata); - if (retval) - return retval; - - /* Make sure the v3020 expects a communication cycle - * by reading 8 times */ - for (i = 0; i < 8; i++) - chip->ops->read_bit(chip); - - /* Test chip by doing a write/read sequence - * to the chip ram */ - v3020_set_reg(chip, V3020_SECONDS, 0x33); - if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) { - retval = -ENODEV; - goto err_io; - } - - /* Make sure frequency measurement mode, test modes, and lock - * are all disabled */ - v3020_set_reg(chip, V3020_STATUS_0, 0x0); - - if (pdata->use_gpio) - dev_info(&pdev->dev, "Chip available at GPIOs " - "%d, %d, %d, %d\n", - chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio, - chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio); - else - dev_info(&pdev->dev, "Chip available at " - "physical address 0x%llx," - "data connected to D%d\n", - (unsigned long long)pdev->resource[0].start, - chip->leftshift); - - platform_set_drvdata(pdev, chip); - - chip->rtc = devm_rtc_device_register(&pdev->dev, "v3020", - &v3020_rtc_ops, THIS_MODULE); - if (IS_ERR(chip->rtc)) { - retval = PTR_ERR(chip->rtc); - goto err_io; - } - - return 0; - -err_io: - chip->ops->unmap_io(chip); - - return retval; -} - -static int rtc_remove(struct platform_device *dev) -{ - struct v3020 *chip = platform_get_drvdata(dev); - - chip->ops->unmap_io(chip); - - return 0; -} - -static struct platform_driver rtc_device_driver = { - .probe = rtc_probe, - .remove = rtc_remove, - .driver = { - .name = "v3020", - }, -}; - -module_platform_driver(rtc_device_driver); - -MODULE_DESCRIPTION("V3020 RTC"); -MODULE_AUTHOR("Raphael Assenat"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:v3020"); diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index 197b649cd629..ccfa76513a2c 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -235,14 +235,12 @@ static int vt8500_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(vt8500_rtc->rtc); } -static int vt8500_rtc_remove(struct platform_device *pdev) +static void vt8500_rtc_remove(struct platform_device *pdev) { struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); /* Disable alarm matching */ writel(0, vt8500_rtc->regbase + VT8500_RTC_IS); - - return 0; } static const struct of_device_id wmt_dt_ids[] = { @@ -253,7 +251,7 @@ MODULE_DEVICE_TABLE(of, wmt_dt_ids); static struct platform_driver vt8500_rtc_driver = { .probe = vt8500_rtc_probe, - .remove = vt8500_rtc_remove, + .remove_new = vt8500_rtc_remove, .driver = { .name = "vt8500-rtc", .of_match_table = wmt_dt_ids, diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index 6eaa9321c074..947f8071803f 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c @@ -451,14 +451,12 @@ static int wm8350_rtc_probe(struct platform_device *pdev) return 0; } -static int wm8350_rtc_remove(struct platform_device *pdev) +static void wm8350_rtc_remove(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350); - - return 0; } static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend, @@ -466,7 +464,7 @@ static SIMPLE_DEV_PM_OPS(wm8350_rtc_pm_ops, wm8350_rtc_suspend, static struct platform_driver wm8350_rtc_driver = { .probe = wm8350_rtc_probe, - .remove = wm8350_rtc_remove, + .remove_new = wm8350_rtc_remove, .driver = { .name = "wm8350-rtc", .pm = &wm8350_rtc_pm_ops, diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c index d3d0054e21fd..f78efc9760c0 100644 --- a/drivers/rtc/rtc-xgene.c +++ b/drivers/rtc/rtc-xgene.c @@ -192,14 +192,13 @@ static int xgene_rtc_probe(struct platform_device *pdev) return 0; } -static int xgene_rtc_remove(struct platform_device *pdev) +static void xgene_rtc_remove(struct platform_device *pdev) { struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); xgene_rtc_alarm_irq_enable(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0); clk_disable_unprepare(pdata->clk); - return 0; } static int __maybe_unused xgene_rtc_suspend(struct device *dev) @@ -264,7 +263,7 @@ MODULE_DEVICE_TABLE(of, xgene_rtc_of_match); static struct platform_driver xgene_rtc_driver = { .probe = xgene_rtc_probe, - .remove = xgene_rtc_remove, + .remove_new = xgene_rtc_remove, .driver = { .name = "xgene-rtc", .pm = &xgene_rtc_pm_ops, diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index c9b85c838ebe..08ed171bdab4 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -342,12 +342,10 @@ static int xlnx_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(xrtcdev->rtc); } -static int xlnx_rtc_remove(struct platform_device *pdev) +static void xlnx_rtc_remove(struct platform_device *pdev) { xlnx_rtc_alarm_irq_enable(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0); - - return 0; } static int __maybe_unused xlnx_rtc_suspend(struct device *dev) @@ -384,7 +382,7 @@ MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match); static struct platform_driver xlnx_rtc_driver = { .probe = xlnx_rtc_probe, - .remove = xlnx_rtc_remove, + .remove_new = xlnx_rtc_remove, .driver = { .name = KBUILD_MODNAME, .pm = &xlnx_rtc_pm_ops, diff --git a/drivers/rtc/sysfs.c b/drivers/rtc/sysfs.c index 00f1945bcb7e..e3062c4d3f2c 100644 --- a/drivers/rtc/sysfs.c +++ b/drivers/rtc/sysfs.c @@ -6,6 +6,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> */ +#include <linux/kstrtox.h> #include <linux/module.h> #include <linux/rtc.h> |