diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12026.txt b/Documentation/devicetree/bindings/rtc/isil,isl12026.txt deleted file mode 100644 index 2e0be45193bb..000000000000 --- a/Documentation/devicetree/bindings/rtc/isil,isl12026.txt +++ /dev/null @@ -1,28 +0,0 @@ -ISL12026 I2C RTC/EEPROM - -ISL12026 is an I2C RTC/EEPROM combination device. The RTC and control -registers respond at bus address 0x6f, and the EEPROM array responds -at bus address 0x57. The canonical "reg" value will be for the RTC portion. - -Required properties supported by the device: - - - "compatible": must be "isil,isl12026" - - "reg": I2C bus address of the device (always 0x6f) - -Optional properties: - - - "isil,pwr-bsw": If present PWR.BSW bit must be set to the specified - value for proper operation. - - - "isil,pwr-sbib": If present PWR.SBIB bit must be set to the specified - value for proper operation. - - -Example: - - rtc@6f { - compatible = "isil,isl12026"; - reg = <0x6f>; - isil,pwr-bsw = <0>; - isil,pwr-sbib = <1>; - } diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12026.yaml b/Documentation/devicetree/bindings/rtc/isil,isl12026.yaml new file mode 100644 index 000000000000..152edce2ab41 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/isil,isl12026.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/isil,isl12026.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intersil ISL12026 I2C RTC/EEPROM + +maintainers: + - Piyush Patle + +description: + The ISL12026 is a combination RTC and EEPROM device connected via I2C. + The RTC and control registers respond at address 0x6f, while the EEPROM + array responds at address 0x57. The "reg" property refers to the RTC + portion of the device. + +allOf: + - $ref: rtc.yaml# + +properties: + compatible: + const: isil,isl12026 + + reg: + maxItems: 1 + description: I2C address of the RTC portion (must be 0x6f) + + isil,pwr-bsw: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Value written to the PWR.BSW bit for proper device operation. + + isil,pwr-sbib: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + description: + Value written to the PWR.SBIB bit for proper device operation. + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + rtc@6f { + compatible = "isil,isl12026"; + reg = <0x6f>; + isil,pwr-bsw = <0>; + isil,pwr-sbib = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml b/Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml index a3e60d9f8399..e26e92b1af03 100644 --- a/Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/microchip,mpfs-rtc.yaml @@ -47,6 +47,9 @@ properties: - const: rtc - const: rtcref + resets: + maxItems: 1 + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml b/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml index cda8ad7c1203..2ea3b4041953 100644 --- a/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml +++ b/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml @@ -32,6 +32,8 @@ properties: - 9000 - 15000 + vdd-supply: true + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/rtc/olpc-xo1-rtc.txt b/Documentation/devicetree/bindings/rtc/olpc-xo1-rtc.txt deleted file mode 100644 index a2891ceb6344..000000000000 --- a/Documentation/devicetree/bindings/rtc/olpc-xo1-rtc.txt +++ /dev/null @@ -1,5 +0,0 @@ -OLPC XO-1 RTC -~~~~~~~~~~~~~ - -Required properties: - - compatible : "olpc,xo1-rtc" diff --git a/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml b/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml index 5756f617df36..1deae2f4f09d 100644 --- a/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml @@ -13,7 +13,12 @@ maintainers: properties: compatible: - const: sprd,sc2731-rtc + oneOf: + - items: + - enum: + - sprd,sc2730-rtc + - const: sprd,sc2731-rtc + - const: sprd,sc2731-rtc reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index b47822370d6f..722176c831aa 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -65,6 +65,8 @@ properties: - microcrystal,rv3029 # Real Time Clock - microcrystal,rv8523 + # OLPC XO-1 RTC + - olpc,xo1-rtc # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC - ricoh,r2025sd # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b46ac73a2124..364afc73f8ab 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1986,7 +1986,7 @@ config RTC_DRV_XGENE config RTC_DRV_PIC32 tristate "Microchip PIC32 RTC" - depends on MACH_PIC32 + depends on MACH_PIC32 || COMPILE_TEST default y help If you say yes here you get support for the PIC32 RTC module. diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c index baf1a8ca8b2b..8ba7c25d2565 100644 --- a/drivers/rtc/dev.c +++ b/drivers/rtc/dev.c @@ -195,7 +195,16 @@ static __poll_t rtc_dev_poll(struct file *file, poll_table *wait) poll_wait(file, &rtc->irq_queue, wait); - data = rtc->irq_data; + /* + * This read can race with the write in rtc_handle_legacy_irq(). + * + * - If this check misses a zero to non-zero transition the next check + * will pick it up (rtc_handle_legacy_irq() wakes up rtc->irq_queue). + * - Non-zero to non-zero transition misses do not change return value. + * - And a non-zero to zero transition is unlikely to be missed, since + * it occurs on rtc_dev_read(), during which polling is not expected. + */ + data = data_race(rtc->irq_data); return (data != 0) ? (EPOLLIN | EPOLLRDNORM) : 0; } diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index 3fee27914ba8..00d7de64ed3e 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -772,8 +772,7 @@ static int abx80x_probe(struct i2c_client *client) 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 part = (uintptr_t)i2c_get_match_data(client); unsigned int partnumber; unsigned int majrev, minrev; unsigned int lot; @@ -933,6 +932,8 @@ static int abx80x_probe(struct i2c_client *client) client->irq = 0; } } + if (client->irq <= 0) + clear_bit(RTC_FEATURE_ALARM, priv->rtc->features); err = rtc_add_group(priv->rtc, &rtc_calib_attr_group); if (err) { diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 713fa0d077cd..245290ae1a8d 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c @@ -72,8 +72,8 @@ struct armada38x_rtc { spinlock_t lock; int irq; bool initialized; - struct value_to_freq *val_to_freq; const struct armada38x_rtc_data *data; + struct value_to_freq val_to_freq[]; }; #define ALARM1 0 @@ -490,18 +490,13 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev) { struct armada38x_rtc *rtc; - rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc), + rtc = devm_kzalloc(&pdev->dev, struct_size(rtc, val_to_freq, SAMPLE_NR), GFP_KERNEL); if (!rtc) return -ENOMEM; rtc->data = of_device_get_match_data(&pdev->dev); - rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR, - sizeof(struct value_to_freq), GFP_KERNEL); - if (!rtc->val_to_freq) - return -ENOMEM; - spin_lock_init(&rtc->lock); rtc->regs = devm_platform_ioremap_resource_byname(pdev, "rtc"); diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index acc064baefcd..f89ab58f5048 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -1429,9 +1429,18 @@ static int __init cmos_platform_probe(struct platform_device *pdev) resource = platform_get_resource(pdev, IORESOURCE_IO, 0); else resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (irq < 0) + irq = platform_get_irq_optional(pdev, 0); + if (irq < 0) { irq = -1; +#ifdef CONFIG_X86 + /* + * On some x86 systems, the IRQ is not defined, but it should + * always be safe to hardcode it on systems with a legacy PIC. + */ + if (nr_legacy_irqs()) + irq = RTC_IRQ; +#endif + } return cmos_do_probe(&pdev->dev, resource, irq); } diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 740cab013f59..b26afef37d9c 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -924,13 +924,7 @@ static int m41t80_probe(struct i2c_client *client) return -ENOMEM; m41t80_data->client = client; - if (client->dev.of_node) { - m41t80_data->features = (unsigned long) - of_device_get_match_data(&client->dev); - } else { - const struct i2c_device_id *id = i2c_match_id(m41t80_id, client); - m41t80_data->features = id->driver_data; - } + m41t80_data->features = (unsigned long)i2c_get_match_data(client); i2c_set_clientdata(client, m41t80_data); m41t80_data->rtc = devm_rtc_allocate_device(&client->dev); diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 69ea3ce75b5a..3cdfd78a07cc 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -686,6 +686,11 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info) return ret; } +static void max77686_rtc_release_dev(void *client) +{ + i2c_unregister_device(client); +} + static int max77686_init_rtc_regmap(struct max77686_rtc_info *info) { struct device *parent = info->dev->parent; @@ -713,12 +718,17 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info) goto add_rtc_irq; } - client = devm_i2c_new_dummy_device(info->dev, parent_i2c->adapter, - info->drv_data->rtc_i2c_addr); + client = i2c_new_ancillary_device(parent_i2c, "rtc", + info->drv_data->rtc_i2c_addr); if (IS_ERR(client)) return dev_err_probe(info->dev, PTR_ERR(client), "Failed to allocate I2C device for RTC\n"); + ret = devm_add_action_or_reset(info->dev, max77686_rtc_release_dev, + client); + if (ret) + return ret; + info->rtc_regmap = devm_regmap_init_i2c(client, info->drv_data->regmap_config); if (IS_ERR(info->rtc_regmap)) diff --git a/drivers/rtc/rtc-ntxec.c b/drivers/rtc/rtc-ntxec.c index 850ca49186fd..d28ddb34e19e 100644 --- a/drivers/rtc/rtc-ntxec.c +++ b/drivers/rtc/rtc-ntxec.c @@ -110,7 +110,7 @@ static int ntxec_rtc_probe(struct platform_device *pdev) struct rtc_device *dev; struct ntxec_rtc *rtc; - pdev->dev.of_node = pdev->dev.parent->of_node; + device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (!rtc) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index bb4fe81d3d62..e4785c5a55d0 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -1449,10 +1449,10 @@ static const struct regmap_bus pcf2127_i2c_regmap = { static struct i2c_driver pcf2127_i2c_driver; static const struct i2c_device_id pcf2127_i2c_id[] = { - { "pcf2127", PCF2127 }, - { "pcf2129", PCF2129 }, - { "pca2129", PCF2129 }, - { "pcf2131", PCF2131 }, + { "pcf2127", (kernel_ulong_t)&pcf21xx_cfg[PCF2127] }, + { "pcf2129", (kernel_ulong_t)&pcf21xx_cfg[PCF2129] }, + { "pca2129", (kernel_ulong_t)&pcf21xx_cfg[PCF2129] }, + { "pcf2131", (kernel_ulong_t)&pcf21xx_cfg[PCF2131] }, { } }; MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id); @@ -1469,18 +1469,9 @@ static int pcf2127_i2c_probe(struct i2c_client *client) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - if (client->dev.of_node) { - variant = of_device_get_match_data(&client->dev); - if (!variant) - return -ENODEV; - } else { - enum pcf21xx_type type = - i2c_match_id(pcf2127_i2c_id, client)->driver_data; - - if (type >= PCF21XX_LAST_ID) - return -ENODEV; - variant = &pcf21xx_cfg[type]; - } + variant = i2c_get_match_data(client); + if (!variant) + return -ENODEV; config.max_register = variant->max_register, diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index f8fab0205f8c..936f4f05c8c7 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -825,12 +825,7 @@ static int rs5c372_probe(struct i2c_client *client) rs5c372->client = client; i2c_set_clientdata(client, rs5c372); - if (client->dev.of_node) { - rs5c372->type = (uintptr_t)of_device_get_match_data(&client->dev); - } else { - const struct i2c_device_id *id = i2c_match_id(rs5c372_id, client); - rs5c372->type = id->driver_data; - } + rs5c372->type = (uintptr_t)i2c_get_match_data(client); /* we read registers 0x0f then 0x00-0x0f; skip the first one */ rs5c372->regs = &rs5c372->buf[1]; diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 4e9e04cbec89..2bf988a89fd7 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -667,13 +667,7 @@ static int rv8803_probe(struct i2c_client *client) mutex_init(&rv8803->flags_lock); rv8803->client = client; - if (client->dev.of_node) { - rv8803->type = (uintptr_t)of_device_get_match_data(&client->dev); - } else { - const struct i2c_device_id *id = i2c_match_id(rv8803_id, client); - - rv8803->type = id->driver_data; - } + rv8803->type = (uintptr_t)i2c_get_match_data(client); i2c_set_clientdata(client, rv8803); flags = rv8803_read_reg(client, RV8803_FLAG); diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index ced6e7adfe8d..c57081f9e02b 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -522,7 +522,6 @@ static const struct attribute_group rx8025_attr_group = { 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; @@ -540,8 +539,7 @@ static int rx8025_probe(struct i2c_client *client) i2c_set_clientdata(client, rx8025); - if (id) - rx8025->model = id->driver_data; + rx8025->model = (uintptr_t)i2c_get_match_data(client); err = rx8025_init_client(client); if (err) diff --git a/drivers/rtc/rtc-ti-k3.c b/drivers/rtc/rtc-ti-k3.c index ec759d8f7023..e801f5b9d757 100644 --- a/drivers/rtc/rtc-ti-k3.c +++ b/drivers/rtc/rtc-ti-k3.c @@ -640,10 +640,18 @@ static int __maybe_unused ti_k3_rtc_suspend(struct device *dev) static int __maybe_unused ti_k3_rtc_resume(struct device *dev) { struct ti_k3_rtc *priv = dev_get_drvdata(dev); + int ret = 0; + + if (k3rtc_check_unlocked(priv)) { + /* RTC locked implies low power mode exit where RTC loses context */ + ret = k3rtc_configure(dev); + if (ret) + return ret; + } if (device_may_wakeup(dev)) disable_irq_wake(priv->irq); - return 0; + return ret; } static SIMPLE_DEV_PM_OPS(ti_k3_rtc_pm_ops, ti_k3_rtc_suspend, ti_k3_rtc_resume);