Merge tag 'rtc-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 3 Jul 2023 17:43:10 +0000 (10:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 3 Jul 2023 17:43:10 +0000 (10:43 -0700)
Pull RTC updates from Alexandre Belloni:
 "The isl1208 dirver was reworked tobe able to work as part of an MFD.

  All the Loongson chips are now supported through a new driver, the old
  one is removed.

  Summary:

  Subsystem:
   - Switch i2c drivers back to use .probe()
   - Constify pointers to hwmon_channel_info

  New driver:
   - Loongson on chip RTC, replacing the Loongson 1 only driver

  Drivers:
   - isl1208: cleanup and support for RAA215300
   - st-lpc: cleanups
   - stm32: fix wakeup"

* tag 'rtc-6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (21 commits)
  rtc: Add rtc driver for the Loongson family chips
  rtc: Remove the Loongson-1 RTC driver
  dt-bindings: rtc: Split loongson,ls2x-rtc into SoC-based compatibles
  rtc: rv3028: make rv3028 probeable from userspace
  rtc: isl1208: Add support for the built-in RTC on the PMIC RAA215300
  rtc: isl1208: Add isl1208_set_xtoscb()
  rtc: isl1208: Drop enum isl1208_id and split isl1208_configs[]
  rtc: isl1208: Make similar I2C and DT-based matching table
  rtc: isl1208: Drop name variable
  dt-bindings: rtc: isil,isl1208: Document clock and clock-names properties
  dt-bindings: rtc: isl1208: Convert to json-schema
  rtc: st-lpc: Simplify clk handling in st_rtc_probe()
  rtc: st-lpc: Release some resources in st_rtc_probe() in case of error
  rtc: stm32: remove dedicated wakeup management
  dt-bindings: rtc: restrict node name suffixes
  rtc: add HAS_IOPORT dependencies
  rtc: Switch i2c drivers back to use .probe()
  rtc: rv3032: constify pointers to hwmon_channel_info
  rtc: isl12022: constify pointers to hwmon_channel_info
  rtc: ds3232: constify pointers to hwmon_channel_info
  ...

46 files changed:
Documentation/devicetree/bindings/rtc/isil,isl1208.txt [deleted file]
Documentation/devicetree/bindings/rtc/isil,isl1208.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/loongson,rtc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/rtc.yaml
Documentation/devicetree/bindings/rtc/trivial-rtc.yaml
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-ab-b5ze-s3.c
drivers/rtc/rtc-ab-eoz9.c
drivers/rtc/rtc-abx80x.c
drivers/rtc/rtc-bq32k.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-ds3232.c
drivers/rtc/rtc-em3027.c
drivers/rtc/rtc-fm3130.c
drivers/rtc/rtc-hym8563.c
drivers/rtc/rtc-isl12022.c
drivers/rtc/rtc-isl12026.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-loongson.c [new file with mode: 0644]
drivers/rtc/rtc-ls1x.c [deleted file]
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-max6900.c
drivers/rtc/rtc-nct3018y.c
drivers/rtc/rtc-pcf2127.c
drivers/rtc/rtc-pcf85063.c
drivers/rtc/rtc-pcf8523.c
drivers/rtc/rtc-pcf85363.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-pcf8583.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-rv3028.c
drivers/rtc/rtc-rv3029c2.c
drivers/rtc/rtc-rv3032.c
drivers/rtc/rtc-rv8803.c
drivers/rtc/rtc-rx6110.c
drivers/rtc/rtc-rx8010.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-rx8581.c
drivers/rtc/rtc-s35390a.c
drivers/rtc/rtc-sd3078.c
drivers/rtc/rtc-st-lpc.c
drivers/rtc/rtc-stm32.c
drivers/rtc/rtc-x1205.c

diff --git a/Documentation/devicetree/bindings/rtc/isil,isl1208.txt b/Documentation/devicetree/bindings/rtc/isil,isl1208.txt
deleted file mode 100644 (file)
index 51f0030..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-Intersil ISL1209/19 I2C RTC/Alarm chip with event in
-
-ISL12X9 have additional pins EVIN and #EVDET for tamper detection, while the
-ISL1208 and ISL1218 do not.  They are all use the same driver with the bindings
-described here, with chip specific properties as noted.
-
-Required properties supported by the device:
- - "compatible": Should be one of the following:
-               - "isil,isl1208"
-               - "isil,isl1209"
-               - "isil,isl1218"
-               - "isil,isl1219"
- - "reg": I2C bus address of the device
-
-Optional properties:
- - "interrupt-names": list which may contains "irq" and "evdet"
-       evdet applies to isl1209 and isl1219 only
- - "interrupts": list of interrupts for "irq" and "evdet"
-       evdet applies to isl1209 and isl1219 only
- - "isil,ev-evienb": Enable or disable internal pull on EVIN pin
-       Applies to isl1209 and isl1219 only
-       Possible values are 0 and 1
-       Value 0 enables internal pull-up on evin pin, 1 disables it.
-       Default will leave the non-volatile configuration of the pullup
-       as is.
-
-Example isl1219 node with #IRQ pin connected to SoC gpio1 pin12 and #EVDET pin
-connected to SoC gpio2 pin 24 and internal pull-up enabled in EVIN pin.
-
-       isl1219: rtc@68 {
-               compatible = "isil,isl1219";
-               reg = <0x68>;
-               interrupt-names = "irq", "evdet";
-               interrupts-extended = <&gpio1 12 IRQ_TYPE_EDGE_FALLING>,
-                       <&gpio2 24 IRQ_TYPE_EDGE_FALLING>;
-               isil,ev-evienb = <1>;
-       };
-
diff --git a/Documentation/devicetree/bindings/rtc/isil,isl1208.yaml b/Documentation/devicetree/bindings/rtc/isil,isl1208.yaml
new file mode 100644 (file)
index 0000000..11f7378
--- /dev/null
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/isil,isl1208.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intersil ISL1209/19 I2C RTC/Alarm chip with event in
+
+maintainers:
+  - Biju Das <biju.das.jz@bp.renesas.com>
+  - Trent Piepho <tpiepho@gmail.com>
+
+description:
+  ISL12X9 have additional pins EVIN and EVDET for tamper detection, while the
+  ISL1208 and ISL1218 do not.
+
+properties:
+  compatible:
+    enum:
+      - isil,isl1208
+      - isil,isl1209
+      - isil,isl1218
+      - isil,isl1219
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    description: |
+      Use xin, if connected to an external crystal.
+      Use clkin, if connected to an external clock signal.
+    enum:
+      - xin
+      - clkin
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
+    minItems: 1
+    items:
+      - const: irq
+      - const: evdet
+
+  isil,ev-evienb:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [ 0, 1 ]
+    description: |
+      Enable or disable internal pull on EVIN pin
+      Default will leave the non-volatile configuration of the pullup
+      as is.
+        <0> : Enables internal pull-up on evin pin
+        <1> : Disables internal pull-up on evin pin
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  - $ref: rtc.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - isil,isl1209
+              - isil,isl1219
+    then:
+      properties:
+        interrupts:
+          maxItems: 2
+        interrupt-names:
+          items:
+            - const: irq
+            - const: evdet
+    else:
+      properties:
+        interrupts:
+          maxItems: 1
+        interrupt-names:
+          items:
+            - const: irq
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        rtc_twi: rtc@6f {
+            compatible = "isil,isl1208";
+            reg = <0x6f>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml
new file mode 100644 (file)
index 0000000..f89c1f6
--- /dev/null
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/loongson,rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Loongson Real-Time Clock
+
+description:
+  The Loongson family chips use an on-chip counter 0 (Time Of Year
+  counter) as the RTC.
+
+maintainers:
+  - Binbin Zhou <zhoubinbin@loongson.cn>
+
+allOf:
+  - $ref: rtc.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - loongson,ls1b-rtc
+          - loongson,ls1c-rtc
+          - loongson,ls7a-rtc
+          - loongson,ls2k1000-rtc
+      - items:
+          - enum:
+              - loongson,ls2k2000-rtc
+              - loongson,ls2k0500-rtc
+          - const: loongson,ls7a-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    rtc@1fe27800 {
+        compatible = "loongson,ls2k1000-rtc";
+        reg = <0x1fe27800 0x100>;
+
+        interrupt-parent = <&liointc1>;
+        interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+    };
+
+...
index c6fff5486fe67b398d928b8c67b81a80295d4117..efb66df82782f6b21a01fdd0e1c8a90d75032edb 100644 (file)
@@ -15,7 +15,7 @@ description: |
 
 properties:
   $nodename:
-    pattern: "^rtc(@.*|-[0-9a-f])*$"
+    pattern: "^rtc(@.*|-([0-9]|[1-9][0-9]+))?$"
 
   aux-voltage-chargeable:
     $ref: /schemas/types.yaml#/definitions/uint32
index a3603e638c3739dd9d365a6809c4b27aa711c4c9..9af77f21bb7f487b30233bdb4369f3bd96ca62ca 100644 (file)
@@ -47,8 +47,6 @@ properties:
       - isil,isl1218
       # Intersil ISL12022 Real-time Clock
       - isil,isl12022
-      # Loongson-2K Socs/LS7A bridge Real-time Clock
-      - loongson,ls2x-rtc
       # Real Time Clock Module with I2C-Bus
       - microcrystal,rv3029
       # Real Time Clock
index ffca9a8bb878f221d513d8be02c063e0c8dc489f..05f4b2d66290dc17be553bfb647568e87bbaa0a3 100644 (file)
@@ -956,6 +956,7 @@ comment "Platform RTC drivers"
 config RTC_DRV_CMOS
        tristate "PC-style 'CMOS'"
        depends on X86 || ARM || PPC || MIPS || SPARC64
+       depends on HAS_IOPORT || MACH_DECSTATION
        default y if X86
        select RTC_MC146818_LIB
        help
@@ -976,6 +977,7 @@ config RTC_DRV_CMOS
 config RTC_DRV_ALPHA
        bool "Alpha PC-style CMOS"
        depends on ALPHA
+       depends on HAS_IOPORT
        select RTC_MC146818_LIB
        default y
        help
@@ -1193,7 +1195,7 @@ config RTC_DRV_MSM6242
 
 config RTC_DRV_BQ4802
        tristate "TI BQ4802"
-       depends on HAS_IOMEM
+       depends on HAS_IOMEM && HAS_IOPORT
        help
          If you say Y here you will get support for the TI
          BQ4802 RTC chip.
@@ -1685,6 +1687,19 @@ config RTC_DRV_JZ4740
          This driver can also be built as a module. If so, the module
          will be called rtc-jz4740.
 
+config RTC_DRV_LOONGSON
+       tristate "Loongson On-chip RTC"
+       depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST
+       select REGMAP_MMIO
+       help
+         This is a driver for the Loongson on-chip Counter0 (Time-Of-Year
+         counter) to be used as a RTC.
+         It can be found on Loongson-1 series cpu, Loongson-2K series cpu
+         and Loongson LS7A bridge chips.
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-loongson.
+
 config RTC_DRV_LPC24XX
        tristate "NXP RTC for LPC178x/18xx/408x/43xx"
        depends on ARCH_LPC18XX || COMPILE_TEST
@@ -1726,16 +1741,6 @@ config RTC_DRV_TEGRA
          This drive can also be built as a module. If so, the module
          will be called rtc-tegra.
 
-config RTC_DRV_LOONGSON1
-       tristate "loongson1 RTC support"
-       depends on MACH_LOONGSON32
-       help
-         This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year
-         counter) to be used as a RTC.
-
-         This driver can also be built as a module. If so, the module
-         will be called rtc-ls1x.
-
 config RTC_DRV_MXC
        tristate "Freescale MXC Real Time Clock"
        depends on ARCH_MXC || COMPILE_TEST
index ea445d1ebb172898dc71fd7a097e81385e610dc5..fd209883ee2efd118c992f010fde9935c186c816 100644 (file)
@@ -78,7 +78,7 @@ obj-$(CONFIG_RTC_DRV_ISL12022)        += rtc-isl12022.o
 obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
 obj-$(CONFIG_RTC_DRV_ISL1208)  += rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_JZ4740)   += rtc-jz4740.o
-obj-$(CONFIG_RTC_DRV_LOONGSON1)        += rtc-ls1x.o
+obj-$(CONFIG_RTC_DRV_LOONGSON) += rtc-loongson.o
 obj-$(CONFIG_RTC_DRV_LP8788)   += rtc-lp8788.o
 obj-$(CONFIG_RTC_DRV_LPC24XX)  += rtc-lpc24xx.o
 obj-$(CONFIG_RTC_DRV_LPC32XX)  += rtc-lpc32xx.o
index f2b0971d2c65db64e32253a6feef866c03dc015a..100062001831462a5f6f652414333197042c4fc2 100644 (file)
@@ -944,7 +944,7 @@ static struct i2c_driver abb5zes3_driver = {
                .pm = &abb5zes3_rtc_pm_ops,
                .of_match_table = of_match_ptr(abb5zes3_dt_match),
        },
-       .probe_new = abb5zes3_probe,
+       .probe = abb5zes3_probe,
        .id_table = abb5zes3_id,
 };
 module_i2c_driver(abb5zes3_driver);
index 34611f6dedcba8a7660821f13f3b6b333ed81dff..04e1b8e93bc1cb6d9fde062a1cfe5f979e19048d 100644 (file)
@@ -455,7 +455,7 @@ static const struct hwmon_channel_info abeoz9_temp = {
        .config = abeoz9_temp_config,
 };
 
-static const struct hwmon_channel_info *abeoz9_info[] = {
+static const struct hwmon_channel_info * const abeoz9_info[] = {
        &abeoz9_chip,
        &abeoz9_temp,
        NULL
@@ -584,7 +584,7 @@ static struct i2c_driver abeoz9_driver = {
                .name = "rtc-ab-eoz9",
                .of_match_table = of_match_ptr(abeoz9_dt_match),
        },
-       .probe_new = abeoz9_probe,
+       .probe = abeoz9_probe,
        .id_table = abeoz9_id,
 };
 
index f34a2e59cac765380d50a93f7892690cd72afa41..e08d3181bd2a66211d3de01d64983000da3f540b 100644 (file)
@@ -992,7 +992,7 @@ static struct i2c_driver abx80x_driver = {
                .name   = "rtc-abx80x",
                .of_match_table = of_match_ptr(abx80x_of_match),
        },
-       .probe_new      = abx80x_probe,
+       .probe          = abx80x_probe,
        .id_table       = abx80x_id,
 };
 
index 967ddc6bf76d68697d304c3b511d0f224d8056da..591e42391747bacd4e7ac03fabc737c57fd27295 100644 (file)
@@ -320,7 +320,7 @@ static struct i2c_driver bq32k_driver = {
                .name   = "bq32k",
                .of_match_table = of_match_ptr(bq32k_of_match),
        },
-       .probe_new      = bq32k_probe,
+       .probe          = bq32k_probe,
        .remove         = bq32k_remove,
        .id_table       = bq32k_id,
 };
index e86ba84df6cbedd1f14f02410dedeb15f9aa3c06..cb5acecc11aa4e0700a7e0b537493cac0357c061 100644 (file)
@@ -2011,7 +2011,7 @@ static struct i2c_driver ds1307_driver = {
                .name   = "rtc-ds1307",
                .of_match_table = ds1307_of_match,
        },
-       .probe_new      = ds1307_probe,
+       .probe          = ds1307_probe,
        .id_table       = ds1307_id,
 };
 
index 7f089f0661634624ba4958c82aa0eed92338a712..4a5005cb23f5930139b91c20b7cb5ca904b01dd5 100644 (file)
@@ -572,7 +572,7 @@ static struct i2c_driver ds1374_driver = {
                .of_match_table = of_match_ptr(ds1374_of_match),
                .pm = &ds1374_pm,
        },
-       .probe_new = ds1374_probe,
+       .probe = ds1374_probe,
        .remove = ds1374_remove,
        .id_table = ds1374_id,
 };
index a3bb2cd9c881b2fc4f2f7e771cebe521a3f94739..641799f30baa995278227fe3751f2adc2c106b9a 100644 (file)
@@ -149,7 +149,7 @@ static struct i2c_driver ds1672_driver = {
                   .name = "rtc-ds1672",
                   .of_match_table = of_match_ptr(ds1672_of_match),
        },
-       .probe_new = ds1672_probe,
+       .probe = ds1672_probe,
        .id_table = ds1672_id,
 };
 
index dd31a60c1fc69800813f0eeaf99d8883c5be5152..89d7b085f7219954b1a154ef41245e76251e9336 100644 (file)
@@ -359,7 +359,7 @@ static const struct hwmon_channel_info ds3232_hwmon_temp = {
        .config = ds3232_hwmon_temp_config,
 };
 
-static const struct hwmon_channel_info *ds3232_hwmon_info[] = {
+static const struct hwmon_channel_info * const ds3232_hwmon_info[] = {
        &ds3232_hwmon_chip,
        &ds3232_hwmon_temp,
        NULL
@@ -603,7 +603,7 @@ static struct i2c_driver ds3232_driver = {
                .of_match_table = of_match_ptr(ds3232_of_match),
                .pm     = &ds3232_pm_ops,
        },
-       .probe_new = ds3232_i2c_probe,
+       .probe = ds3232_i2c_probe,
        .id_table = ds3232_id,
 };
 
index 53f9f9391a5f15452f07dccad6102dc437b325ab..fc772eae5da5f25a4ea1d0a13f56b787ece594e7 100644 (file)
@@ -147,7 +147,7 @@ static struct i2c_driver em3027_driver = {
                   .name = "rtc-em3027",
                   .of_match_table = of_match_ptr(em3027_of_match),
        },
-       .probe_new = em3027_probe,
+       .probe = em3027_probe,
        .id_table = em3027_id,
 };
 
index f59bb81f23c0421877c4e60facd26f1cfa7da552..400ce4ad0c49905d003cbad94234be6cc0a1dde3 100644 (file)
@@ -517,7 +517,7 @@ static struct i2c_driver fm3130_driver = {
        .driver = {
                .name   = "rtc-fm3130",
        },
-       .probe_new      = fm3130_probe,
+       .probe          = fm3130_probe,
        .id_table       = fm3130_id,
 };
 
index 7d5a298a9a3bc678c671ede56880e8f82c2f8e98..b018535c842b376adce85d2f584a8c85b0286e5c 100644 (file)
@@ -576,7 +576,7 @@ static struct i2c_driver hym8563_driver = {
                .pm     = &hym8563_pm_ops,
                .of_match_table = hym8563_dt_idtable,
        },
-       .probe_new      = hym8563_probe,
+       .probe          = hym8563_probe,
        .id_table       = hym8563_id,
 };
 
index e68a79b5e00e586ac2a72b4ea2b0171d21129ebb..a613257d1574d387e80208e092a65e764a3e84c1 100644 (file)
@@ -89,7 +89,7 @@ static int isl12022_hwmon_read(struct device *dev,
        return -EOPNOTSUPP;
 }
 
-static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
+static const struct hwmon_channel_info * const isl12022_hwmon_info[] = {
        HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
        NULL
 };
@@ -262,7 +262,7 @@ static struct i2c_driver isl12022_driver = {
                .name   = "rtc-isl12022",
                .of_match_table = isl12022_dt_match,
        },
-       .probe_new      = isl12022_probe,
+       .probe          = isl12022_probe,
        .id_table       = isl12022_id,
 };
 
index 1bfca39079d40efbe71b60cb7da3cfa2424589d5..5abff5d348acdb6333e3bf1454da6292e2b0466b 100644 (file)
@@ -490,7 +490,7 @@ static struct i2c_driver isl12026_driver = {
                .name   = "rtc-isl12026",
                .of_match_table = isl12026_dt_match,
        },
-       .probe_new      = isl12026_probe_new,
+       .probe          = isl12026_probe_new,
        .remove         = isl12026_remove,
 };
 
index 73cc6aaf9b8b72f84d51a54d42bcf1d0528dbdf2..b0712b4e364891656598d0d764c92398057f346d 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/bcd.h>
+#include <linux/clk.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 
 static struct i2c_driver isl1208_driver;
 
-/* ISL1208 various variants */
-enum isl1208_id {
-       TYPE_ISL1208 = 0,
-       TYPE_ISL1209,
-       TYPE_ISL1218,
-       TYPE_ISL1219,
-       ISL_LAST_ID
-};
-
 /* Chip capabilities table */
-static const struct isl1208_config {
-       const char      name[8];
+struct isl1208_config {
        unsigned int    nvmem_length;
        unsigned        has_tamper:1;
        unsigned        has_timestamp:1;
-} isl1208_configs[] = {
-       [TYPE_ISL1208] = { "isl1208", 2, false, false },
-       [TYPE_ISL1209] = { "isl1209", 2, true,  false },
-       [TYPE_ISL1218] = { "isl1218", 8, false, false },
-       [TYPE_ISL1219] = { "isl1219", 2, true,  true },
+       unsigned        has_inverted_osc_bit:1;
+};
+
+static const struct isl1208_config config_isl1208 = {
+       .nvmem_length = 2,
+       .has_tamper = false,
+       .has_timestamp = false
+};
+
+static const struct isl1208_config config_isl1209 = {
+       .nvmem_length = 2,
+       .has_tamper = true,
+       .has_timestamp = false
+};
+
+static const struct isl1208_config config_isl1218 = {
+       .nvmem_length = 8,
+       .has_tamper = false,
+       .has_timestamp = false
+};
+
+static const struct isl1208_config config_isl1219 = {
+       .nvmem_length = 2,
+       .has_tamper = true,
+       .has_timestamp = true
+};
+
+static const struct isl1208_config config_raa215300_a0 = {
+       .nvmem_length = 2,
+       .has_tamper = false,
+       .has_timestamp = false,
+       .has_inverted_osc_bit = true
 };
 
 static const struct i2c_device_id isl1208_id[] = {
-       { "isl1208", TYPE_ISL1208 },
-       { "isl1209", TYPE_ISL1209 },
-       { "isl1218", TYPE_ISL1218 },
-       { "isl1219", TYPE_ISL1219 },
+       { "isl1208", .driver_data = (kernel_ulong_t)&config_isl1208 },
+       { "isl1209", .driver_data = (kernel_ulong_t)&config_isl1209 },
+       { "isl1218", .driver_data = (kernel_ulong_t)&config_isl1218 },
+       { "isl1219", .driver_data = (kernel_ulong_t)&config_isl1219 },
+       { "raa215300_a0", .driver_data = (kernel_ulong_t)&config_raa215300_a0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, isl1208_id);
 
 static const __maybe_unused struct of_device_id isl1208_of_match[] = {
-       { .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] },
-       { .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] },
-       { .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] },
-       { .compatible = "isil,isl1219", .data = &isl1208_configs[TYPE_ISL1219] },
+       { .compatible = "isil,isl1208", .data = &config_isl1208 },
+       { .compatible = "isil,isl1209", .data = &config_isl1209 },
+       { .compatible = "isil,isl1218", .data = &config_isl1218 },
+       { .compatible = "isil,isl1219", .data = &config_isl1219 },
        { }
 };
 MODULE_DEVICE_TABLE(of, isl1208_of_match);
@@ -166,6 +185,20 @@ isl1208_i2c_validate_client(struct i2c_client *client)
        return 0;
 }
 
+static int isl1208_set_xtoscb(struct i2c_client *client, int sr, int xtosb_val)
+{
+       /* Do nothing if bit is already set to desired value */
+       if ((sr & ISL1208_REG_SR_XTOSCB) == xtosb_val)
+               return 0;
+
+       if (xtosb_val)
+               sr |= ISL1208_REG_SR_XTOSCB;
+       else
+               sr &= ~ISL1208_REG_SR_XTOSCB;
+
+       return i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr);
+}
+
 static int
 isl1208_i2c_get_sr(struct i2c_client *client)
 {
@@ -502,7 +535,6 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
        return 0;
 }
 
-
 static int
 isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
@@ -796,12 +828,26 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq)
        return rc;
 }
 
+static int
+isl1208_clk_present(struct i2c_client *client, const char *name)
+{
+       struct clk *clk;
+
+       clk = devm_clk_get_optional(&client->dev, name);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       return !!clk;
+}
+
 static int
 isl1208_probe(struct i2c_client *client)
 {
-       int rc = 0;
        struct isl1208_state *isl1208;
        int evdet_irq = -1;
+       int xtosb_val = 0;
+       int rc = 0;
+       int sr;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
                return -ENODEV;
@@ -823,9 +869,22 @@ isl1208_probe(struct i2c_client *client)
        } else {
                const struct i2c_device_id *id = i2c_match_id(isl1208_id, client);
 
-               if (id->driver_data >= ISL_LAST_ID)
+               if (!id)
                        return -ENODEV;
-               isl1208->config = &isl1208_configs[id->driver_data];
+               isl1208->config = (struct isl1208_config *)id->driver_data;
+       }
+
+       rc = isl1208_clk_present(client, "xin");
+       if (rc < 0)
+               return rc;
+
+       if (!rc) {
+               rc = isl1208_clk_present(client, "clkin");
+               if (rc < 0)
+                       return rc;
+
+               if (rc)
+                       xtosb_val = 1;
        }
 
        isl1208->rtc = devm_rtc_allocate_device(&client->dev);
@@ -839,13 +898,20 @@ isl1208_probe(struct i2c_client *client)
        isl1208->nvmem_config.size = isl1208->config->nvmem_length;
        isl1208->nvmem_config.priv = isl1208;
 
-       rc = isl1208_i2c_get_sr(client);
-       if (rc < 0) {
+       sr = isl1208_i2c_get_sr(client);
+       if (sr < 0) {
                dev_err(&client->dev, "reading status failed\n");
-               return rc;
+               return sr;
        }
 
-       if (rc & ISL1208_REG_SR_RTCF)
+       if (isl1208->config->has_inverted_osc_bit)
+               xtosb_val = !xtosb_val;
+
+       rc = isl1208_set_xtoscb(client, sr, xtosb_val);
+       if (rc)
+               return rc;
+
+       if (sr & ISL1208_REG_SR_RTCF)
                dev_warn(&client->dev, "rtc power failure detected, "
                         "please set clock.\n");
 
@@ -908,7 +974,7 @@ static struct i2c_driver isl1208_driver = {
                .name = "rtc-isl1208",
                .of_match_table = of_match_ptr(isl1208_of_match),
        },
-       .probe_new = isl1208_probe,
+       .probe = isl1208_probe,
        .id_table = isl1208_id,
 };
 
diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c
new file mode 100644 (file)
index 0000000..e8ffc1a
--- /dev/null
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Loongson RTC driver
+ *
+ * Maintained out-of-tree by Huacai Chen <chenhuacai@kernel.org>.
+ * Rewritten for mainline by WANG Xuerui <git@xen0n.name>.
+ *                           Binbin Zhou <zhoubinbin@loongson.cn>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+#include <linux/acpi.h>
+
+/* Time Of Year(TOY) counters registers */
+#define TOY_TRIM_REG           0x20 /* Must be initialized to 0 */
+#define TOY_WRITE0_REG         0x24 /* TOY low 32-bits value (write-only) */
+#define TOY_WRITE1_REG         0x28 /* TOY high 32-bits value (write-only) */
+#define TOY_READ0_REG          0x2c /* TOY low 32-bits value (read-only) */
+#define TOY_READ1_REG          0x30 /* TOY high 32-bits value (read-only) */
+#define TOY_MATCH0_REG         0x34 /* TOY timing interrupt 0 */
+#define TOY_MATCH1_REG         0x38 /* TOY timing interrupt 1 */
+#define TOY_MATCH2_REG         0x3c /* TOY timing interrupt 2 */
+
+/* RTC counters registers */
+#define RTC_CTRL_REG           0x40 /* TOY and RTC control register */
+#define RTC_TRIM_REG           0x60 /* Must be initialized to 0 */
+#define RTC_WRITE0_REG         0x64 /* RTC counters value (write-only) */
+#define RTC_READ0_REG          0x68 /* RTC counters value (read-only) */
+#define RTC_MATCH0_REG         0x6c /* RTC timing interrupt 0 */
+#define RTC_MATCH1_REG         0x70 /* RTC timing interrupt 1 */
+#define RTC_MATCH2_REG         0x74 /* RTC timing interrupt 2 */
+
+/* bitmask of TOY_WRITE0_REG */
+#define TOY_MON                        GENMASK(31, 26)
+#define TOY_DAY                        GENMASK(25, 21)
+#define TOY_HOUR               GENMASK(20, 16)
+#define TOY_MIN                        GENMASK(15, 10)
+#define TOY_SEC                        GENMASK(9, 4)
+#define TOY_MSEC               GENMASK(3, 0)
+
+/* bitmask of TOY_MATCH0/1/2_REG */
+#define TOY_MATCH_YEAR         GENMASK(31, 26)
+#define TOY_MATCH_MON          GENMASK(25, 22)
+#define TOY_MATCH_DAY          GENMASK(21, 17)
+#define TOY_MATCH_HOUR         GENMASK(16, 12)
+#define TOY_MATCH_MIN          GENMASK(11, 6)
+#define TOY_MATCH_SEC          GENMASK(5, 0)
+
+/* bitmask of RTC_CTRL_REG */
+#define RTC_ENABLE             BIT(13) /* 1: RTC counters enable */
+#define TOY_ENABLE             BIT(11) /* 1: TOY counters enable */
+#define OSC_ENABLE             BIT(8) /* 1: 32.768k crystal enable */
+#define TOY_ENABLE_MASK                (TOY_ENABLE | OSC_ENABLE)
+
+/* PM domain registers */
+#define PM1_STS_REG            0x0c    /* Power management 1 status register */
+#define RTC_STS                        BIT(10) /* RTC status */
+#define PM1_EN_REG             0x10    /* Power management 1 enable register */
+#define RTC_EN                 BIT(10) /* RTC event enable */
+
+/*
+ * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined.
+ * Accessing the relevant registers will cause the system to hang.
+ */
+#define LS1C_RTC_CTRL_WORKAROUND       BIT(0)
+
+struct loongson_rtc_config {
+       u32 pm_offset;  /* Offset of PM domain, for RTC alarm wakeup */
+       u32 flags;      /* Workaround bits */
+};
+
+struct loongson_rtc_priv {
+       spinlock_t lock;        /* protects PM registers access */
+       u32 fix_year;           /* RTC alarm year compensation value */
+       struct rtc_device *rtcdev;
+       struct regmap *regmap;
+       void __iomem *pm_base;  /* PM domain base, for RTC alarm wakeup */
+       const struct loongson_rtc_config *config;
+};
+
+static const struct loongson_rtc_config ls1b_rtc_config = {
+       .pm_offset = 0,
+       .flags = 0,
+};
+
+static const struct loongson_rtc_config ls1c_rtc_config = {
+       .pm_offset = 0,
+       .flags = LS1C_RTC_CTRL_WORKAROUND,
+};
+
+static const struct loongson_rtc_config generic_rtc_config = {
+       .pm_offset = 0x100,
+       .flags = 0,
+};
+
+static const struct loongson_rtc_config ls2k1000_rtc_config = {
+       .pm_offset = 0x800,
+       .flags = 0,
+};
+
+static const struct regmap_config loongson_rtc_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+};
+
+/* RTC alarm irq handler */
+static irqreturn_t loongson_rtc_isr(int irq, void *id)
+{
+       struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id;
+
+       rtc_update_irq(priv->rtcdev, 1, RTC_AF | RTC_IRQF);
+       return IRQ_HANDLED;
+}
+
+/* For ACPI fixed event handler */
+static u32 loongson_rtc_handler(void *id)
+{
+       struct loongson_rtc_priv *priv = (struct loongson_rtc_priv *)id;
+
+       spin_lock(&priv->lock);
+       /* Disable RTC alarm wakeup and interrupt */
+       writel(readl(priv->pm_base + PM1_EN_REG) & ~RTC_EN,
+              priv->pm_base + PM1_EN_REG);
+
+       /* Clear RTC interrupt status */
+       writel(RTC_STS, priv->pm_base + PM1_STS_REG);
+       spin_unlock(&priv->lock);
+
+       /*
+        * The TOY_MATCH0_REG should be cleared 0 here,
+        * otherwise the interrupt cannot be cleared.
+        */
+       return regmap_write(priv->regmap, TOY_MATCH0_REG, 0);
+}
+
+static int loongson_rtc_set_enabled(struct device *dev)
+{
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND)
+               return 0;
+
+       /* Enable RTC TOY counters and crystal */
+       return regmap_update_bits(priv->regmap, RTC_CTRL_REG, TOY_ENABLE_MASK,
+                                 TOY_ENABLE_MASK);
+}
+
+static bool loongson_rtc_get_enabled(struct device *dev)
+{
+       int ret;
+       u32 ctrl_data;
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND)
+               return true;
+
+       ret = regmap_read(priv->regmap, RTC_CTRL_REG, &ctrl_data);
+       if (ret < 0)
+               return false;
+
+       return ctrl_data & TOY_ENABLE_MASK;
+}
+
+static int loongson_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+       int ret;
+       u32 rtc_data[2];
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       if (!loongson_rtc_get_enabled(dev))
+               return -EINVAL;
+
+       ret = regmap_bulk_read(priv->regmap, TOY_READ0_REG, rtc_data,
+                              ARRAY_SIZE(rtc_data));
+       if (ret < 0)
+               return ret;
+
+       tm->tm_sec = FIELD_GET(TOY_SEC, rtc_data[0]);
+       tm->tm_min = FIELD_GET(TOY_MIN, rtc_data[0]);
+       tm->tm_hour = FIELD_GET(TOY_HOUR, rtc_data[0]);
+       tm->tm_mday = FIELD_GET(TOY_DAY, rtc_data[0]);
+       tm->tm_mon = FIELD_GET(TOY_MON, rtc_data[0]) - 1;
+       tm->tm_year = rtc_data[1];
+
+       /* Prepare for RTC alarm year compensation value. */
+       priv->fix_year = tm->tm_year / 64 * 64;
+       return 0;
+}
+
+static int loongson_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       int ret;
+       u32 rtc_data[2];
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       rtc_data[0] = FIELD_PREP(TOY_SEC, tm->tm_sec)
+                   | FIELD_PREP(TOY_MIN, tm->tm_min)
+                   | FIELD_PREP(TOY_HOUR, tm->tm_hour)
+                   | FIELD_PREP(TOY_DAY, tm->tm_mday)
+                   | FIELD_PREP(TOY_MON, tm->tm_mon + 1);
+       rtc_data[1] = tm->tm_year;
+
+       ret = regmap_bulk_write(priv->regmap, TOY_WRITE0_REG, rtc_data,
+                               ARRAY_SIZE(rtc_data));
+       if (ret < 0)
+               return ret;
+
+       return loongson_rtc_set_enabled(dev);
+}
+
+static int loongson_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       int ret;
+       u32 alarm_data;
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       ret = regmap_read(priv->regmap, TOY_MATCH0_REG, &alarm_data);
+       if (ret < 0)
+               return ret;
+
+       alrm->time.tm_sec = FIELD_GET(TOY_MATCH_SEC, alarm_data);
+       alrm->time.tm_min = FIELD_GET(TOY_MATCH_MIN, alarm_data);
+       alrm->time.tm_hour = FIELD_GET(TOY_MATCH_HOUR, alarm_data);
+       alrm->time.tm_mday = FIELD_GET(TOY_MATCH_DAY, alarm_data);
+       alrm->time.tm_mon = FIELD_GET(TOY_MATCH_MON, alarm_data) - 1;
+       /*
+        * This is a hardware bug: the year field of SYS_TOYMATCH is only 6 bits,
+        * making it impossible to save year values larger than 64.
+        *
+        * SYS_TOYMATCH is used to match the alarm time value and determine if
+        * an alarm is triggered, so we must keep the lower 6 bits of the year
+        * value constant during the value conversion.
+        *
+        * In summary, we need to manually add 64(or a multiple of 64) to the
+        * year value to avoid the invalid alarm prompt at startup.
+        */
+       alrm->time.tm_year = FIELD_GET(TOY_MATCH_YEAR, alarm_data) + priv->fix_year;
+
+       alrm->enabled = !!(readl(priv->pm_base + PM1_EN_REG) & RTC_EN);
+       return 0;
+}
+
+static int loongson_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       u32 val;
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       spin_lock(&priv->lock);
+       val = readl(priv->pm_base + PM1_EN_REG);
+       /* Enable RTC alarm wakeup */
+       writel(enabled ? val | RTC_EN : val & ~RTC_EN,
+              priv->pm_base + PM1_EN_REG);
+       spin_unlock(&priv->lock);
+
+       return 0;
+}
+
+static int loongson_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       int ret;
+       u32 alarm_data;
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       alarm_data = FIELD_PREP(TOY_MATCH_SEC, alrm->time.tm_sec)
+                  | FIELD_PREP(TOY_MATCH_MIN, alrm->time.tm_min)
+                  | FIELD_PREP(TOY_MATCH_HOUR, alrm->time.tm_hour)
+                  | FIELD_PREP(TOY_MATCH_DAY, alrm->time.tm_mday)
+                  | FIELD_PREP(TOY_MATCH_MON, alrm->time.tm_mon + 1)
+                  | FIELD_PREP(TOY_MATCH_YEAR, alrm->time.tm_year - priv->fix_year);
+
+       ret = regmap_write(priv->regmap, TOY_MATCH0_REG, alarm_data);
+       if (ret < 0)
+               return ret;
+
+       return loongson_rtc_alarm_irq_enable(dev, alrm->enabled);
+}
+
+static const struct rtc_class_ops loongson_rtc_ops = {
+       .read_time = loongson_rtc_read_time,
+       .set_time = loongson_rtc_set_time,
+       .read_alarm = loongson_rtc_read_alarm,
+       .set_alarm = loongson_rtc_set_alarm,
+       .alarm_irq_enable = loongson_rtc_alarm_irq_enable,
+};
+
+static int loongson_rtc_probe(struct platform_device *pdev)
+{
+       int ret, alarm_irq;
+       void __iomem *regs;
+       struct loongson_rtc_priv *priv;
+       struct device *dev = &pdev->dev;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(regs))
+               return dev_err_probe(dev, PTR_ERR(regs),
+                                    "devm_platform_ioremap_resource failed\n");
+
+       priv->regmap = devm_regmap_init_mmio(dev, regs,
+                                            &loongson_rtc_regmap_config);
+       if (IS_ERR(priv->regmap))
+               return dev_err_probe(dev, PTR_ERR(priv->regmap),
+                                    "devm_regmap_init_mmio failed\n");
+
+       priv->config = device_get_match_data(dev);
+       spin_lock_init(&priv->lock);
+       platform_set_drvdata(pdev, priv);
+
+       priv->rtcdev = devm_rtc_allocate_device(dev);
+       if (IS_ERR(priv->rtcdev))
+               return dev_err_probe(dev, PTR_ERR(priv->rtcdev),
+                                    "devm_rtc_allocate_device failed\n");
+
+       /* Get RTC alarm irq */
+       alarm_irq = platform_get_irq(pdev, 0);
+       if (alarm_irq > 0) {
+               ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr,
+                                      0, "loongson-alarm", priv);
+               if (ret < 0)
+                       return dev_err_probe(dev, ret, "Unable to request irq %d\n",
+                                            alarm_irq);
+
+               priv->pm_base = regs - priv->config->pm_offset;
+               device_init_wakeup(dev, 1);
+
+               if (has_acpi_companion(dev))
+                       acpi_install_fixed_event_handler(ACPI_EVENT_RTC,
+                                                        loongson_rtc_handler, priv);
+       } else {
+               /* Loongson-1C RTC does not support alarm */
+               clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features);
+       }
+
+       /* Loongson RTC does not support UIE */
+       clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features);
+       priv->rtcdev->ops = &loongson_rtc_ops;
+       priv->rtcdev->range_min = RTC_TIMESTAMP_BEGIN_2000;
+       priv->rtcdev->range_max = RTC_TIMESTAMP_END_2099;
+
+       return devm_rtc_register_device(priv->rtcdev);
+}
+
+static void loongson_rtc_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct loongson_rtc_priv *priv = dev_get_drvdata(dev);
+
+       if (!test_bit(RTC_FEATURE_ALARM, priv->rtcdev->features))
+               return;
+
+       if (has_acpi_companion(dev))
+               acpi_remove_fixed_event_handler(ACPI_EVENT_RTC,
+                                               loongson_rtc_handler);
+
+       device_init_wakeup(dev, 0);
+       loongson_rtc_alarm_irq_enable(dev, 0);
+}
+
+static const struct of_device_id loongson_rtc_of_match[] = {
+       { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config },
+       { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config },
+       { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config },
+       { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, loongson_rtc_of_match);
+
+static const struct acpi_device_id loongson_rtc_acpi_match[] = {
+       { "LOON0001", .driver_data = (kernel_ulong_t)&generic_rtc_config },
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, loongson_rtc_acpi_match);
+
+static struct platform_driver loongson_rtc_driver = {
+       .probe          = loongson_rtc_probe,
+       .remove_new     = loongson_rtc_remove,
+       .driver         = {
+               .name   = "loongson-rtc",
+               .of_match_table = loongson_rtc_of_match,
+               .acpi_match_table = loongson_rtc_acpi_match,
+       },
+};
+module_platform_driver(loongson_rtc_driver);
+
+MODULE_DESCRIPTION("Loongson RTC driver");
+MODULE_AUTHOR("Binbin Zhou <zhoubinbin@loongson.cn>");
+MODULE_AUTHOR("WANG Xuerui <git@xen0n.name>");
+MODULE_AUTHOR("Huacai Chen <chenhuacai@kernel.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
deleted file mode 100644 (file)
index 5af26dc..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) 2011 Zhao Zhang <zhzhl555@gmail.com>
- *
- * Derived from driver/rtc/rtc-au1xxx.c
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/rtc.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/io.h>
-#include <loongson1.h>
-
-#define LS1X_RTC_REG_OFFSET    (LS1X_RTC_BASE + 0x20)
-#define LS1X_RTC_REGS(x) \
-               ((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x)))
-
-/*RTC programmable counters 0 and 1*/
-#define SYS_COUNTER_CNTRL              (LS1X_RTC_REGS(0x20))
-#define SYS_CNTRL_ERS                  (1 << 23)
-#define SYS_CNTRL_RTS                  (1 << 20)
-#define SYS_CNTRL_RM2                  (1 << 19)
-#define SYS_CNTRL_RM1                  (1 << 18)
-#define SYS_CNTRL_RM0                  (1 << 17)
-#define SYS_CNTRL_RS                   (1 << 16)
-#define SYS_CNTRL_BP                   (1 << 14)
-#define SYS_CNTRL_REN                  (1 << 13)
-#define SYS_CNTRL_BRT                  (1 << 12)
-#define SYS_CNTRL_TEN                  (1 << 11)
-#define SYS_CNTRL_BTT                  (1 << 10)
-#define SYS_CNTRL_E0                   (1 << 8)
-#define SYS_CNTRL_ETS                  (1 << 7)
-#define SYS_CNTRL_32S                  (1 << 5)
-#define SYS_CNTRL_TTS                  (1 << 4)
-#define SYS_CNTRL_TM2                  (1 << 3)
-#define SYS_CNTRL_TM1                  (1 << 2)
-#define SYS_CNTRL_TM0                  (1 << 1)
-#define SYS_CNTRL_TS                   (1 << 0)
-
-/* Programmable Counter 0 Registers */
-#define SYS_TOYTRIM            (LS1X_RTC_REGS(0))
-#define SYS_TOYWRITE0          (LS1X_RTC_REGS(4))
-#define SYS_TOYWRITE1          (LS1X_RTC_REGS(8))
-#define SYS_TOYREAD0           (LS1X_RTC_REGS(0xC))
-#define SYS_TOYREAD1           (LS1X_RTC_REGS(0x10))
-#define SYS_TOYMATCH0          (LS1X_RTC_REGS(0x14))
-#define SYS_TOYMATCH1          (LS1X_RTC_REGS(0x18))
-#define SYS_TOYMATCH2          (LS1X_RTC_REGS(0x1C))
-
-/* Programmable Counter 1 Registers */
-#define SYS_RTCTRIM            (LS1X_RTC_REGS(0x40))
-#define SYS_RTCWRITE0          (LS1X_RTC_REGS(0x44))
-#define SYS_RTCREAD0           (LS1X_RTC_REGS(0x48))
-#define SYS_RTCMATCH0          (LS1X_RTC_REGS(0x4C))
-#define SYS_RTCMATCH1          (LS1X_RTC_REGS(0x50))
-#define SYS_RTCMATCH2          (LS1X_RTC_REGS(0x54))
-
-#define LS1X_SEC_OFFSET                (4)
-#define LS1X_MIN_OFFSET                (10)
-#define LS1X_HOUR_OFFSET       (16)
-#define LS1X_DAY_OFFSET                (21)
-#define LS1X_MONTH_OFFSET      (26)
-
-
-#define LS1X_SEC_MASK          (0x3f)
-#define LS1X_MIN_MASK          (0x3f)
-#define LS1X_HOUR_MASK         (0x1f)
-#define LS1X_DAY_MASK          (0x1f)
-#define LS1X_MONTH_MASK                (0x3f)
-#define LS1X_YEAR_MASK         (0xffffffff)
-
-#define ls1x_get_sec(t)                (((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK)
-#define ls1x_get_min(t)                (((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK)
-#define ls1x_get_hour(t)       (((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK)
-#define ls1x_get_day(t)                (((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK)
-#define ls1x_get_month(t)      (((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK)
-
-#define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
-
-static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm)
-{
-       unsigned long v;
-       time64_t t;
-
-       v = readl(SYS_TOYREAD0);
-       t = readl(SYS_TOYREAD1);
-
-       memset(rtm, 0, sizeof(struct rtc_time));
-       t  = mktime64((t & LS1X_YEAR_MASK), ls1x_get_month(v),
-                       ls1x_get_day(v), ls1x_get_hour(v),
-                       ls1x_get_min(v), ls1x_get_sec(v));
-       rtc_time64_to_tm(t, rtm);
-
-       return 0;
-}
-
-static int ls1x_rtc_set_time(struct device *dev, struct  rtc_time *rtm)
-{
-       unsigned long v, t, c;
-       int ret = -ETIMEDOUT;
-
-       v = ((rtm->tm_mon + 1)  << LS1X_MONTH_OFFSET)
-               | (rtm->tm_mday << LS1X_DAY_OFFSET)
-               | (rtm->tm_hour << LS1X_HOUR_OFFSET)
-               | (rtm->tm_min  << LS1X_MIN_OFFSET)
-               | (rtm->tm_sec  << LS1X_SEC_OFFSET);
-
-       writel(v, SYS_TOYWRITE0);
-       c = 0x10000;
-       /* add timeout check counter, for more safe */
-       while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c)
-               usleep_range(1000, 3000);
-
-       if (!c) {
-               dev_err(dev, "set time timeout!\n");
-               goto err;
-       }
-
-       t = rtm->tm_year + 1900;
-       writel(t, SYS_TOYWRITE1);
-       c = 0x10000;
-       while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c)
-               usleep_range(1000, 3000);
-
-       if (!c) {
-               dev_err(dev, "set time timeout!\n");
-               goto err;
-       }
-       return 0;
-err:
-       return ret;
-}
-
-static const struct rtc_class_ops  ls1x_rtc_ops = {
-       .read_time      = ls1x_rtc_read_time,
-       .set_time       = ls1x_rtc_set_time,
-};
-
-static int ls1x_rtc_probe(struct platform_device *pdev)
-{
-       struct rtc_device *rtcdev;
-       unsigned long v;
-
-       v = readl(SYS_COUNTER_CNTRL);
-       if (!(v & RTC_CNTR_OK)) {
-               dev_err(&pdev->dev, "rtc counters not working\n");
-               return -ENODEV;
-       }
-
-       /* set to 1 HZ if needed */
-       if (readl(SYS_TOYTRIM) != 32767) {
-               v = 0x100000;
-               while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v)
-                       usleep_range(1000, 3000);
-
-               if (!v) {
-                       dev_err(&pdev->dev, "time out\n");
-                       return -ETIMEDOUT;
-               }
-               writel(32767, SYS_TOYTRIM);
-       }
-       /* this loop coundn't be endless */
-       while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS)
-               usleep_range(1000, 3000);
-
-       rtcdev = devm_rtc_allocate_device(&pdev->dev);
-       if (IS_ERR(rtcdev))
-               return PTR_ERR(rtcdev);
-
-       platform_set_drvdata(pdev, rtcdev);
-       rtcdev->ops = &ls1x_rtc_ops;
-       rtcdev->range_min = RTC_TIMESTAMP_BEGIN_1900;
-       rtcdev->range_max = RTC_TIMESTAMP_END_2099;
-
-       return devm_rtc_register_device(rtcdev);
-}
-
-static struct platform_driver  ls1x_rtc_driver = {
-       .driver         = {
-               .name   = "ls1x-rtc",
-       },
-       .probe          = ls1x_rtc_probe,
-};
-
-module_platform_driver(ls1x_rtc_driver);
-
-MODULE_AUTHOR("zhao zhang <zhzhl555@gmail.com>");
-MODULE_LICENSE("GPL");
index c1963f7c424d7032bb13fccc9cf158c7f7e6f2d0..3cc5151e098644aaf4abdfa22c66f2eda14a8c53 100644 (file)
@@ -1013,7 +1013,7 @@ static struct i2c_driver m41t80_driver = {
                .of_match_table = of_match_ptr(m41t80_of_match),
                .pm = &m41t80_pm,
        },
-       .probe_new = m41t80_probe,
+       .probe = m41t80_probe,
        .remove = m41t80_remove,
        .id_table = m41t80_id,
 };
index 0a33851cc51f4f60236fec567f84404db4634384..31b910e4d91a89c530dc8abfaab2b5bf11189949 100644 (file)
@@ -224,7 +224,7 @@ static struct i2c_driver max6900_driver = {
        .driver = {
                   .name = "rtc-max6900",
                   },
-       .probe_new = max6900_probe,
+       .probe = max6900_probe,
        .id_table = max6900_id,
 };
 
index 0a3b14c95d9027ce770e5a30c2f467655519215a..a4e3f924837e0cf904a8c098ccdff895ae1e3fed 100644 (file)
@@ -540,7 +540,7 @@ static struct i2c_driver nct3018y_driver = {
                .name   = "rtc-nct3018y",
                .of_match_table = of_match_ptr(nct3018y_of_match),
        },
-       .probe_new      = nct3018y_probe,
+       .probe          = nct3018y_probe,
        .id_table       = nct3018y_id,
 };
 
index 87f4fc9df68b4a66de70c8768611511828780bb4..ee03b04b74baa7c2740e15f672eb90bbb0a8602e 100644 (file)
@@ -923,7 +923,7 @@ static struct i2c_driver pcf2127_i2c_driver = {
                .name   = "rtc-pcf2127-i2c",
                .of_match_table = of_match_ptr(pcf2127_of_match),
        },
-       .probe_new      = pcf2127_i2c_probe,
+       .probe          = pcf2127_i2c_probe,
        .id_table       = pcf2127_i2c_id,
 };
 
index 71a4563559819473ebd7a5cf430edf90f2ef60ee..e517abfaee2a03d64882add2177e736952b42cfa 100644 (file)
@@ -681,7 +681,7 @@ static struct i2c_driver pcf85063_driver = {
                .name   = "rtc-pcf85063",
                .of_match_table = of_match_ptr(pcf85063_of_match),
        },
-       .probe_new      = pcf85063_probe,
+       .probe          = pcf85063_probe,
        .id_table       = pcf85063_ids,
 };
 
index e7115ebef70771e2ae8db1641b72e90320e0bd1f..d1efde3e7a8094e01b4f34b66f2f5990258ca3cb 100644 (file)
@@ -488,7 +488,7 @@ static struct i2c_driver pcf8523_driver = {
                .name = "rtc-pcf8523",
                .of_match_table = pcf8523_of_match,
        },
-       .probe_new = pcf8523_probe,
+       .probe = pcf8523_probe,
        .id_table = pcf8523_id,
 };
 module_i2c_driver(pcf8523_driver);
index 8958eadf1c3efb0e0281cc910df3bd5ed0c934ed..65b8b1338dbb0b607d651df507bf43097d3debee 100644 (file)
@@ -475,7 +475,7 @@ static struct i2c_driver pcf85363_driver = {
                .name   = "pcf85363",
                .of_match_table = of_match_ptr(dev_ids),
        },
-       .probe_new = pcf85363_probe,
+       .probe = pcf85363_probe,
 };
 
 module_i2c_driver(pcf85363_driver);
index 7e720472213c7c76e2971880d92d68550875e127..ea82b89d8929f95fb26e1f3e77794d75a094a429 100644 (file)
@@ -612,7 +612,7 @@ static struct i2c_driver pcf8563_driver = {
                .name   = "rtc-pcf8563",
                .of_match_table = of_match_ptr(pcf8563_of_match),
        },
-       .probe_new      = pcf8563_probe,
+       .probe          = pcf8563_probe,
        .id_table       = pcf8563_id,
 };
 
index 87074d178274e92576fea2dbd94979848672a2dd..a7e0fc360b6a10703d8c4c00073df6a794ac61fb 100644 (file)
@@ -306,7 +306,7 @@ static struct i2c_driver pcf8583_driver = {
        .driver = {
                .name   = "pcf8583",
        },
-       .probe_new      = pcf8583_probe,
+       .probe          = pcf8583_probe,
        .id_table       = pcf8583_id,
 };
 
index b4c5d016eca32c10838c352859ff1b73fbcb4556..a5a6c8772ecd4beeb57498bf998c3460d13d3ba9 100644 (file)
@@ -921,7 +921,7 @@ static struct i2c_driver rs5c372_driver = {
                .name   = "rtc-rs5c372",
                .of_match_table = of_match_ptr(rs5c372_of_match),
        },
-       .probe_new      = rs5c372_probe,
+       .probe          = rs5c372_probe,
        .remove         = rs5c372_remove,
        .id_table       = rs5c372_id,
 };
index ec5d7a614e2dd25ba5b5a5e3e76e558ca3fbcf33..076e56f4e01a524e56c34a54f0fd8e7a7d8d5e6c 100644 (file)
@@ -994,13 +994,20 @@ static const __maybe_unused struct of_device_id rv3028_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, rv3028_of_match);
 
+static const struct i2c_device_id rv3028_id_table[] = {
+       { .name = "rv3028", },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, rv3028_id_table);
+
 static struct i2c_driver rv3028_driver = {
        .driver = {
                .name = "rtc-rv3028",
                .acpi_match_table = rv3028_i2c_acpi_match,
                .of_match_table = of_match_ptr(rv3028_of_match),
        },
-       .probe_new      = rv3028_probe,
+       .id_table       = rv3028_id_table,
+       .probe          = rv3028_probe,
 };
 module_i2c_driver(rv3028_driver);
 
index 0852f6709a8591cf374056f932ff99aed9c2e769..4a81feeb00ffde03de8d37a2544541b4fde97850 100644 (file)
@@ -824,7 +824,7 @@ static struct i2c_driver rv3029_driver = {
                .name = "rv3029",
                .of_match_table = of_match_ptr(rv3029_of_match),
        },
-       .probe_new      = rv3029_i2c_probe,
+       .probe          = rv3029_i2c_probe,
        .id_table       = rv3029_id,
 };
 
index 1ff4f2e6fa77e78c3f6368ee09e9d9fb2378fbe9..6b8eb2039a33368b3d203e20e1139953fadb250c 100644 (file)
@@ -842,7 +842,7 @@ static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
        return err;
 }
 
-static const struct hwmon_channel_info *rv3032_hwmon_info[] = {
+static const struct hwmon_channel_info * const rv3032_hwmon_info[] = {
        HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
        HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST),
        NULL
@@ -998,7 +998,7 @@ static struct i2c_driver rv3032_driver = {
                .acpi_match_table = rv3032_i2c_acpi_match,
                .of_match_table = of_match_ptr(rv3032_of_match),
        },
-       .probe_new      = rv3032_probe,
+       .probe          = rv3032_probe,
 };
 module_i2c_driver(rv3032_driver);
 
index 25c3b9e4f515af3dcf6c68d7f689036203935264..98679cae13e8409ae0d080e2e42fa886c3d8e1a1 100644 (file)
@@ -739,7 +739,7 @@ static struct i2c_driver rv8803_driver = {
                .name = "rtc-rv8803",
                .of_match_table = of_match_ptr(rv8803_of_match),
        },
-       .probe_new      = rv8803_probe,
+       .probe          = rv8803_probe,
        .id_table       = rv8803_id,
 };
 module_i2c_driver(rv8803_driver);
index 37608883a796d5be0349ce6d7675f84f3f5f227a..8702db6096ba4e7cb6c6a5f7a30233bc7395250e 100644 (file)
@@ -462,7 +462,7 @@ static struct i2c_driver rx6110_i2c_driver = {
                .name = RX6110_DRIVER_NAME,
                .acpi_match_table = rx6110_i2c_acpi_match,
        },
-       .probe_new      = rx6110_i2c_probe,
+       .probe          = rx6110_i2c_probe,
        .id_table       = rx6110_i2c_id,
 };
 
index b9c8dad2620853ff0398f477d02bad2a96bc5426..f44e212c07ded4ff1f8813eab9a7dc207b1df342 100644 (file)
@@ -424,7 +424,7 @@ static struct i2c_driver rx8010_driver = {
                .name = "rtc-rx8010",
                .of_match_table = of_match_ptr(rx8010_of_match),
        },
-       .probe_new      = rx8010_probe,
+       .probe          = rx8010_probe,
        .id_table       = rx8010_id,
 };
 
index 331c20d4d843c1a3aa234c0083763b1151b8eb59..aabe62c283a150f18810545a05827f54b8ed468f 100644 (file)
@@ -581,7 +581,7 @@ static struct i2c_driver rx8025_driver = {
        .driver = {
                .name = "rtc-rx8025",
        },
-       .probe_new      = rx8025_probe,
+       .probe          = rx8025_probe,
        .id_table       = rx8025_id,
 };
 
index 14edb7534c97164853dfe970ce79b811341980c8..82881fd2e14a1aa844182ac9cd5d05e481d5f192 100644 (file)
@@ -325,7 +325,7 @@ static struct i2c_driver rx8581_driver = {
                .name   = "rtc-rx8581",
                .of_match_table = of_match_ptr(rx8581_of_match),
        },
-       .probe_new      = rx8581_probe,
+       .probe          = rx8581_probe,
        .id_table       = rx8581_id,
 };
 
index b18daaf72b17dbd87e982362985ea584c454e2c8..90a3028ac57433444ab8d3b091d35c264aceaefa 100644 (file)
@@ -499,7 +499,7 @@ static struct i2c_driver s35390a_driver = {
                .name   = "rtc-s35390a",
                .of_match_table = of_match_ptr(s35390a_of_match),
        },
-       .probe_new      = s35390a_probe,
+       .probe          = s35390a_probe,
        .id_table       = s35390a_id,
 };
 
index e2f90d768ca80dd19f602226aac49e1d10c3ea74..7760394ccd2dfbaac41ac0ccd70180282886bbc2 100644 (file)
@@ -217,7 +217,7 @@ static struct i2c_driver sd3078_driver = {
                .name   = "sd3078",
                .of_match_table = of_match_ptr(rtc_dt_match),
        },
-       .probe_new  = sd3078_probe,
+       .probe      = sd3078_probe,
        .id_table   = sd3078_id,
 };
 
index 0f8e4231098ef1b856906a484a17585f8be94e2a..d492a2d26600c1bd64f23738b04ad7cad24409e1 100644 (file)
@@ -228,17 +228,13 @@ static int st_rtc_probe(struct platform_device *pdev)
        enable_irq_wake(rtc->irq);
        disable_irq(rtc->irq);
 
-       rtc->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(rtc->clk)) {
-               dev_err(&pdev->dev, "Unable to request clock\n");
-               return PTR_ERR(rtc->clk);
-       }
-
-       clk_prepare_enable(rtc->clk);
+       rtc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(rtc->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(rtc->clk),
+                                    "Unable to request clock\n");
 
        rtc->clkrate = clk_get_rate(rtc->clk);
        if (!rtc->clkrate) {
-               clk_disable_unprepare(rtc->clk);
                dev_err(&pdev->dev, "Unable to fetch clock rate\n");
                return -EINVAL;
        }
@@ -252,10 +248,8 @@ static int st_rtc_probe(struct platform_device *pdev)
        do_div(rtc->rtc_dev->range_max, rtc->clkrate);
 
        ret = devm_rtc_register_device(rtc->rtc_dev);
-       if (ret) {
-               clk_disable_unprepare(rtc->clk);
+       if (ret)
                return ret;
-       }
 
        return 0;
 }
index 229cb2847cc4887a11dfcd5d4e476da4d110ae79..3d36e11cff80c291fc8197612ab4e0f672c59a2f 100644 (file)
@@ -114,7 +114,6 @@ struct stm32_rtc_data {
        void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
        bool has_pclk;
        bool need_dbp;
-       bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -127,7 +126,6 @@ struct stm32_rtc {
        struct clk *rtc_ck;
        const struct stm32_rtc_data *data;
        int irq_alarm;
-       int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -547,7 +545,6 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
        .has_pclk = false,
        .need_dbp = true,
-       .has_wakeirq = false,
        .regs = {
                .tr = 0x00,
                .dr = 0x04,
@@ -569,7 +566,6 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
        .has_pclk = true,
        .need_dbp = true,
-       .has_wakeirq = false,
        .regs = {
                .tr = 0x00,
                .dr = 0x04,
@@ -600,7 +596,6 @@ static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32mp1_data = {
        .has_pclk = true,
        .need_dbp = false,
-       .has_wakeirq = true,
        .regs = {
                .tr = 0x00,
                .dr = 0x04,
@@ -779,19 +774,12 @@ static int stm32_rtc_probe(struct platform_device *pdev)
        }
 
        ret = device_init_wakeup(&pdev->dev, true);
-       if (rtc->data->has_wakeirq) {
-               rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
-               if (rtc->wakeirq_alarm > 0) {
-                       ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
-                                                           rtc->wakeirq_alarm);
-               } else {
-                       ret = rtc->wakeirq_alarm;
-                       if (rtc->wakeirq_alarm == -EPROBE_DEFER)
-                               goto err;
-               }
-       }
        if (ret)
-               dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+               goto err;
+
+       ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm);
+       if (ret)
+               goto err;
 
        platform_set_drvdata(pdev, rtc);
 
@@ -879,9 +867,6 @@ static int stm32_rtc_suspend(struct device *dev)
        if (rtc->data->has_pclk)
                clk_disable_unprepare(rtc->pclk);
 
-       if (device_may_wakeup(dev))
-               return enable_irq_wake(rtc->irq_alarm);
-
        return 0;
 }
 
@@ -903,9 +888,6 @@ static int stm32_rtc_resume(struct device *dev)
                return ret;
        }
 
-       if (device_may_wakeup(dev))
-               return disable_irq_wake(rtc->irq_alarm);
-
        return ret;
 }
 #endif
index f587afa843573d2c7fa69a035f5b5886337c4544..807f953ae0aedc2541bdf58fe0e7bf8eaaa54f5b 100644 (file)
@@ -679,7 +679,7 @@ static struct i2c_driver x1205_driver = {
                .name   = "rtc-x1205",
                .of_match_table = x1205_dt_ids,
        },
-       .probe_new      = x1205_probe,
+       .probe          = x1205_probe,
        .remove         = x1205_remove,
        .id_table       = x1205_id,
 };