Add rtc driver for the Loongson family chips
Subsystems (4)
v5 cover Add rtc driver for the Loongson family chips
Hi all:
The initial DT-base ls2x rtc driver was written by Wang Xuerui, He has released five versions of patchset before, and all related mail records are shown below if you are interested:
https://lore.kernel.org/all/?q=ls2x-rtc
In this series of patches, based on the code above, I have added the following support:
1. Add ACPI-related support, as Loongson-3A5000 + LS7A is now ACPI-base by default under LoongArch architecture;
2. Add rtc alarm/walarm related functions;
3. Merge LS1X rtc and LS2X rtc into a unified rtc-loongson driver.
I have tested on Loongson-3A5000LA+LS7A1000/LS7A2000, Loongson-2K1000LA, Loongson-2K0500 and Loongson-2K2000(ACPI/DT).
Thanks to everyone for reviewing and testing the code.
-------
v5:
patch(1/5)
- The reason why ls2x can be removed directly is explained in the
commit message;
- Use fallback compatible;
Thanks to all who participated in the fallback compatible discussion.
patch(3/5)
- Since ls1b and ls1c have different register definitions, we'd better distinguish them with different configurations(ls1b_rtc_config/ls1c_rtc_config);
- Due to the use of fallback compatible, the redundant compatible is removed. We can see the full list of supported chips in dt-binding..
v4:
https://lore.kernel.org/linux-rtc/[email protected]/
- Rebase on the top of rtc-next;
- Drop defconfig-related patches;
patch(1/5)
- New patch, Loongson RTC bindings have been rewritten and we have dropped the wildcard (ls2x) in compatible.
Thanks to Krzysztof for your comments;
patch(2/5)
- New patch, drop the ls1x rtc driver;
patch(3/5)
- Clear RTC_FEATURE_UPDATE_INTERRUPT bit, for the rtc does not support
UIE;
- Add LS2K2000 support(DT/ACPI);
- Merge ls1x support and name the driver rtc-loongson; Thanks to Jiaxun for his comments and Keguang for his assistance in
testing.
v3:
https://lore.kernel.org/linux-rtc/[email protected]/
patch(2/7):
- Check patchset with "checkpatch.pl --strict";
- Drop static inline functions which are used only once, such as ls2x_rtc_regs_to_time;
- Remove the suruct ls2x_rtc_regs and regmap_bulk_xxx() is used to read and write rtc registers;
- Clear the RTC wakeup interrupt manually;
- Enable the RTC in set_time() and check in read_time();
- device_get_match_data() is used to get ls2x_pm_offset, for LS2k1000 has the different value;
- Remove some inexact CONFIG_ACPI.
v2:
1. Rebased on top of latest loongarch-next;
2. Add interrupt descriptions to the ls2k and ls7a DTS files to avoid errors when the driver gets the IRQ number, Thanks to Qing Zhang for testing;
3. Remove some inexact CONFIG_ACPI.
Thanks.
Binbin Zhou (5):
dt-bindings: rtc: Remove the LS2X from the trivial RTCs
rtc: Remove the Loongson-1 RTC driver
rtc: Add rtc driver for the Loongson family chips
MIPS: Loongson64: DTS: Add RTC support to LS7A PCH
MIPS: Loongson64: DTS: Add RTC support to Loongson-2K1000
.../devicetree/bindings/rtc/loongson,rtc.yaml | 57 +++ .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 - .../boot/dts/loongson/loongson64-2k1000.dtsi | 7 + arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 + drivers/rtc/Kconfig | 23 +- drivers/rtc/Makefile | 2 +- drivers/rtc/rtc-loongson.c | 397 ++++++++++++++++++ drivers/rtc/rtc-ls1x.c | 192 --------- 8 files changed, 482 insertions(+), 205 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/loongson,rtc.yaml create mode 100644 drivers/rtc/rtc-loongson.c delete mode 100644 drivers/rtc/rtc-ls1x.c
Signature · 1 line
2.39.1
PATCH v5 1/5 dt-bindings: rtc: Remove the LS2X from the trivial RTCs
Move Loongson RTC bindings from trivial-rtc.yaml into loongson,rtc.yaml.
The architectures associated with this driver use the built-in DTB, so we can just drop the compatible(rtc-ls2x) with wildcards. Also, soc-based compatible is more accurate for hardware differences between chips.
--- .../devicetree/bindings/rtc/loongson,rtc.yaml | 57 +++++++++++++++++++ .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 - 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/loongson,rtc.yaml
Documentation/devicetree/bindings/rtc/loongson,rtc.yaml new file +57 -0
@@ -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 <[email protected]> + +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>; + }; + +...
Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +0 -2
@@ -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
Signature · 1 line
2.39.1
Re: [PATCH V5 1/5] dt-bindings: rtc: Remove the LS2X from the trivial RTCs
Quoted 1 line · Binbin Zhou
Move Loongson RTC bindings from
trivial-rtc.yamlinto loongson,rtc.yaml.
$subject: dt-bindings: rtc: Remove the LS2X from the trivial RTCs
If you end up resubmitting, could you use a subject like that better describes the changes?
Say "dt-bindings: rtc: Split loongson,ls2x-rtc into SoC-based compatibles"? Otherwise,
Thanks,
Conor.
Quoted 92 lines
The architectures associated with this driver use the built-in DTB, so we can just drop the compatible(rtc-ls2x) with wildcards. Also, soc-based compatible is more accurate for hardware differences between chips.
Signed-off-by Binbin Zhou <[email protected]>--- .../devicetree/bindings/rtc/loongson,rtc.yaml | 57 +++++++++++++++++++ .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 - 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/loongson,rtc.yamlDocumentation/devicetree/bindings/rtc/loongson,rtc.yaml new file +57
-0@@ -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 <[email protected]> + +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>; + }; + +...Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +0
-2@@ -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 ClockSignature · 1 line
2.39.1
Re: [PATCH V5 1/5] dt-bindings: rtc: Remove the LS2X from the trivial RTCs
Quoted 9 lines · Conor Dooley
Quoted 1 line · Binbin Zhou
Move Loongson RTC bindings from
trivial-rtc.yamlinto loongson,rtc.yaml.$subject: dt-bindings: rtc: Remove the LS2X from the trivial RTCs
If you end up resubmitting, could you use a subject like that better describes the changes?
Say "dt-bindings: rtc: Split loongson,ls2x-rtc into SoC-based compatibles"?
OK, I got it.
Thanks.
Binbin
Quoted 97 lines
Otherwise,
Reviewed-by Conor Dooley <[email protected]>Thanks,
Conor.Quoted 92 lines
The architectures associated with this driver use the built-in DTB, so we can just drop the compatible(rtc-ls2x) with wildcards. Also, soc-based compatible is more accurate for hardware differences between chips.
Signed-off-by Binbin Zhou <[email protected]>--- .../devicetree/bindings/rtc/loongson,rtc.yaml | 57 +++++++++++++++++++ .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 - 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/loongson,rtc.yamlDocumentation/devicetree/bindings/rtc/loongson,rtc.yaml new file +57
-0@@ -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 <[email protected]> + +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>; + }; + +...Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +0
-3@@ -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 --2.39.1
PATCH v5 2/5 rtc: Remove the Loongson-1 RTC driver
In reply to Binbin ZhouRemove the ls1x-rtc driver as it is obsolete. We will continue to support the ls1x RTC in the upcoming Loongson unified RTC driver rtc-loongson.
--- drivers/rtc/Kconfig | 10 --- drivers/rtc/Makefile | 1 - drivers/rtc/rtc-ls1x.c | 192 ----------------------------------------- 3 files changed, 203 deletions(-) delete mode 100644 drivers/rtc/rtc-ls1x.c
drivers/rtc/Kconfig +0 -10
@@ -1726,16 +1726,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
drivers/rtc/Makefile +0 -1
@@ -78,7 +78,6 @@ 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_LP8788) += rtc-lp8788.o obj-$(CONFIG_RTC_DRV_LPC24XX) += rtc-lpc24xx.o obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o
drivers/rtc/rtc-ls1x.c deleted +0 -192
192 lines not on this page · raw message
Signature · 1 line
2.39.1
Re: [PATCH V5 2/5] rtc: Remove the Loongson-1 RTC driver
Quoted 9 lines · Binbin Zhou
Remove the ls1x-rtc driver as it is obsolete. We will continue to support the ls1x RTC in the upcoming Loongson unified RTC driver rtc-loongson.
Cc Keguang Zhang <[email protected]>Cc zhao zhang <[email protected]>Cc Yang Ling <[email protected]>Signed-off-by Binbin Zhou <[email protected]>
Quoted 241 lines
--- drivers/rtc/Kconfig | 10 --- drivers/rtc/Makefile | 1 - drivers/rtc/rtc-ls1x.c | 192 ----------------------------------------- 3 files changed, 203 deletions(-) delete mode 100644 drivers/rtc/rtc-ls1x.cdrivers/rtc/Kconfig +0
-10@@ -1726,16 +1726,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_TESTdrivers/rtc/Makefile +0
-1@@ -78,7 +78,6 @@ 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_LP8788) += rtc-lp8788.o obj-$(CONFIG_RTC_DRV_LPC24XX) += rtc-lpc24xx.o obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.odrivers/rtc/rtc-ls1x.c deleted +0
-193@@ -1,192 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* -* Copyright (c) 2011 Zhao Zhang <[email protected]> -* -* 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 <[email protected]>" ); -MODULE_LICENSE ("GPL" ); --2.39.1
Signature · 3 lines
Best regards, Keguang Zhang
PATCH v5 3/5 rtc: Add rtc driver for the Loongson family chips
In reply to Binbin ZhouThe Loongson family chips use an on-chip counter 0 (Time Of Year counter) as the RTC. We will refer to them as rtc-loongson.
--- drivers/rtc/Kconfig | 13 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-loongson.c | 397 +++++++++++++++++++++++++++++++++++++ 3 files changed, 411 insertions(+) create mode 100644 drivers/rtc/rtc-loongson.c
drivers/rtc/Kconfig +13 -0
@@ -1685,6 +1685,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
drivers/rtc/Makefile +1 -0
@@ -78,6 +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_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
drivers/rtc/rtc-loongson.c new file +397 -0
397 lines not on this page · raw message
Signature · 1 line
2.39.1
Re: [PATCH V5 3/5] rtc: Add rtc driver for the Loongson family chips
Quoted 10 lines · Binbin Zhou
The Loongson family chips use an on-chip counter 0 (Time Of Year counter) as the RTC. We will refer to them as rtc-loongson.
Cc Keguang Zhang <[email protected]>Cc Yang Ling <[email protected]>Cc Jiaxun Yang <[email protected]>Signed-off-by Binbin Zhou <[email protected]>Signed-off-by Huacai Chen <[email protected]>Signed-off-by WANG Xuerui <[email protected]>
Quoted 447 lines
--- drivers/rtc/Kconfig | 13 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-loongson.c | 397 +++++++++++++++++++++++++++++++++++++ 3 files changed, 411 insertions(+) create mode 100644 drivers/rtc/rtc-loongson.cdrivers/rtc/Kconfig +13
-0@@ -1685,6 +1685,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_TESTdrivers/rtc/Makefile +1
-0@@ -78,6 +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_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.odrivers/rtc/rtc-loongson.c new file +397
-1@@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Loongson RTC driver +* +* Maintained out-of-tree by Huacai Chen <[email protected]>. +* Rewritten for mainline by WANG Xuerui <[email protected]>. +* Binbin Zhou <[email protected]> +*/ + +#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 <[email protected]>" ); +MODULE_AUTHOR ("WANG Xuerui <[email protected]>" ); +MODULE_AUTHOR ("Huacai Chen <[email protected]>" ); +MODULE_LICENSE ("GPL" ); --
Quoted 2 lines
2.39.1
--
Best regards,
Keguang Zhang
Re: [PATCH V5 3/5] rtc: Add rtc driver for the Loongson family chips
In reply to Binbin ZhouQuoted 9 lines · 在2023年6月2日六月 下午5:50,Binbin Zhou写道:
The Loongson family chips use an on-chip counter 0 (Time Of Year counter) as the RTC. We will refer to them as rtc-loongson.
Cc Keguang Zhang <[email protected]>Cc Yang Ling <[email protected]>Cc Jiaxun Yang <[email protected]>Signed-off-by Binbin Zhou <[email protected]>Signed-off-by Huacai Chen <[email protected]>Signed-off-by WANG Xuerui <[email protected]>
Quoted 457 lines
--- drivers/rtc/Kconfig | 13 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-loongson.c | 397 +++++++++++++++++++++++++++++++++++++ 3 files changed, 411 insertions(+) create mode 100644 drivers/rtc/rtc-loongson.cdrivers/rtc/Kconfig +13
-0@@ -1685,6 +1685,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_TESTdrivers/rtc/Makefile +1
-0@@ -78,6 +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_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.odrivers/rtc/rtc-loongson.c new file +66
-0@@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Loongson RTC driver +* +* Maintained out-of-tree by Huacai Chen <[email protected]>. +* Rewritten for mainline by WANG Xuerui <[email protected]>. +* Binbin Zhou <[email protected]> +*/ + +#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.
+ */drivers/rtc/rtc-loongson.c new file +101
-0+#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)
drivers/rtc/rtc-loongson.c new file +26
-0+{ +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)
drivers/rtc/rtc-loongson.c new file +21
-0+{ +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)drivers/rtc/rtc-loongson.c new file +16
-0+{ +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,
drivers/rtc/rtc-loongson.c new file +10
-0+* 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;drivers/rtc/rtc-loongson.c new file +6
-0+ + alrm->enabled = !!(readl (priv->pm_base +PM1_EN_REG ) &RTC_EN ); +return 0 ; +} + +static int loongson_rtc_alarm_irq_enable(struct device *dev, unsignedint enabled)
drivers/rtc/rtc-loongson.c new file +15
-0+{ +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)drivers/rtc/rtc-loongson.c new file +108
-0+{ +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},
drivers/rtc/rtc-loongson.c new file +26
-0+ {/* 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 <[email protected]>" ); +MODULE_AUTHOR ("WANG Xuerui <[email protected]>" ); +MODULE_AUTHOR ("Huacai Chen <[email protected]>" ); +MODULE_LICENSE ("GPL" );Signature · 1 line
2.39.1
Signature · 1 line
- Jiaxun
PATCH v5 4/5 MIPS: Loongson64: DTS: Add RTC support to LS7A PCH
In reply to Binbin ZhouThe RTC module is now supported, enable it.
--- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)
arch/mips/boot/dts/loongson/ls7a-pch.dtsi +7 -0
@@ -19,6 +19,13 @@ pic: interrupt-controller@10000000 { #interrupt-cells = <2>; }; + rtc0: rtc@100d0100 { + compatible = "loongson,ls7a-rtc"; + reg = <0 0x100d0100 0 0x78>; + interrupt-parent = <&pic>; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH>; + }; + ls7a_uart0: serial@10080000 { compatible = "ns16550a"; reg = <0 0x10080000 0 0x100>;
Signature · 1 line
2.39.1
Re: [PATCH V5 4/5] MIPS: Loongson64: DTS: Add RTC support to LS7A PCH
Quoted 29 lines · Binbin Zhou
The RTC module is now supported, enable it.
Acked-by Jiaxun Yang <[email protected]>Signed-off-by Binbin Zhou <[email protected]>Signed-off-by WANG Xuerui <[email protected]>--- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)arch/mips/boot/dts/loongson/ls7a-pch.dtsi +7
-0@@ -19,6 +19,13 @@ pic: interrupt-controller@10000000 { #interrupt-cells = <2>; }; + rtc0: rtc@100d0100 { + compatible = "loongson,ls7a-rtc"; + reg = <0 0x100d0100 0 0x78>; + interrupt-parent = <&pic>; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH>; + }; + ls7a_uart0: serial@10080000 { compatible = "ns16550a"; reg = <0 0x10080000 0 0x100>;Signature · 1 line
2.39.1
applied to mips-next.
Thomas.
Signature · 2 lines
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a good idea. [ RFC1925, 2.3 ]
PATCH v5 5/5 MIPS: Loongson64: DTS: Add RTC support to Loongson-2K1000
In reply to Binbin ZhouThe module is now supported, enable it.
--- arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)
arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi +7 -0
@@ -97,6 +97,13 @@ liointc1: interrupt-controller@1fe11440 { <0x00000000>; /* int3 */ }; + rtc0: rtc@1fe07800 { + compatible = "loongson,ls2k1000-rtc"; + reg = <0 0x1fe07800 0 0x78>; + interrupt-parent = <&liointc0>; + interrupts = <60 IRQ_TYPE_LEVEL_LOW>; + }; + uart0: serial@1fe00000 { compatible = "ns16550a"; reg = <0 0x1fe00000 0 0x8>;
Signature · 1 line
2.39.1
Re: [PATCH V5 5/5] MIPS: Loongson64: DTS: Add RTC support to Loongson-2K1000
Quoted 29 lines · Binbin Zhou
The module is now supported, enable it.
Acked-by Jiaxun Yang <[email protected]>Signed-off-by Binbin Zhou <[email protected]>Signed-off-by WANG Xuerui <[email protected]>--- arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi | 7 +++++++ 1 file changed, 7 insertions(+)arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi +7
-0@@ -97,6 +97,13 @@ liointc1: interrupt-controller@1fe11440 { <0x00000000>; /* int3 */ }; + rtc0: rtc@1fe07800 { + compatible = "loongson,ls2k1000-rtc"; + reg = <0 0x1fe07800 0 0x78>; + interrupt-parent = <&liointc0>; + interrupts = <60 IRQ_TYPE_LEVEL_LOW>; + }; + uart0: serial@1fe00000 { compatible = "ns16550a"; reg = <0 0x1fe00000 0 0x8>;Signature · 1 line
2.39.1
applied to mips-next.
Thomas.
Signature · 2 lines
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a good idea. [ RFC1925, 2.3 ]
Hi Alexandre:
Gentle ping.
The dt-binding part of the patchset looks good now, do you have any more comments on the driver part?
Thanks.
Binbin
Quoted 103 lines · Binbin Zhou
Hi all:
The initial DT-base ls2x rtc driver was written by Wang Xuerui, He has released five versions of patchset before, and all related mail records are shown below if you are interested:
https://lore.kernel.org/all/?q=ls2x-rtc
In this series of patches, based on the code above, I have added the following support:
1. Add ACPI-related support, as Loongson-3A5000 + LS7A is now ACPI-base by default under LoongArch architecture;
2. Add rtc alarm/walarm related functions;
3. Merge LS1X rtc and LS2X rtc into a unified rtc-loongson driver.I have tested on Loongson-3A5000LA+LS7A1000/LS7A2000, Loongson-2K1000LA, Loongson-2K0500 and Loongson-2K2000(ACPI/DT).
Thanks to everyone for reviewing and testing the code.
-------
v5:
patch(1/5)
- The reason why ls2x can be removed directly is explained in thecommit message;- Use fallback compatible;
Thanks to all who participated in the fallback compatible discussion.
patch(3/5)
- Since ls1b and ls1c have different register definitions, we'd better distinguish them with differentconfigurations(ls1b_rtc_config/ls1c_rtc_config);
- Due to the use of fallback compatible, the redundant compatible is removed. We can see the full list of supported chips in dt-binding..v4:
https://lore.kernel.org/linux-rtc/[email protected]/- Rebase on the top of rtc-next;
- Drop defconfig-related patches;
patch(1/5)
- New patch, Loongson RTC bindings have been rewritten and we have dropped the wildcard (ls2x) in compatible.
Thanks to Krzysztof for your comments;
patch(2/5)
- New patch, drop the ls1x rtc driver;
patch(3/5)
- ClearRTC_FEATURE_UPDATE_INTERRUPTbit, for the rtc does not supportUIE;- Add LS2K2000 support(DT/ACPI);
- Merge ls1x support and name the driver rtc-loongson; Thanks to Jiaxun for his comments and Keguang for his assistance in
testing.v3:
https://lore.kernel.org/linux-rtc/[email protected]/patch(2/7):
- Check patchset with "checkpatch.pl --strict";
- Drop static inline functions which are used only once, such asls2x_rtc_regs_to_time;
- Remove the suructls2x_rtc_regsandregmap_bulk_xxx()is used to read and write rtc registers;
- Clear the RTC wakeup interrupt manually;
- Enable the RTC inset_time()and check inread_time();
-device_get_match_data()is used to getls2x_pm_offset, for LS2k1000 has the different value;
- Remove some inexactCONFIG_ACPI.v2:
1. Rebased on top of latest loongarch-next;
2. Add interrupt descriptions to the ls2k and ls7a DTS files to avoid errors when the driver gets the IRQ number, Thanks to Qing Zhang for testing;
3. Remove some inexactCONFIG_ACPI.Thanks.
Binbin Zhou (5):
dt-bindings: rtc: Remove the LS2X from the trivial RTCs
rtc: Remove the Loongson-1 RTC driver
rtc: Add rtc driver for the Loongson family chips
MIPS: Loongson64: DTS: Add RTC support to LS7A PCH
MIPS: Loongson64: DTS: Add RTC support to Loongson-2K1000.../devicetree/bindings/rtc/loongson,rtc.yaml | 57 +++ .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 - .../boot/dts/loongson/loongson64-2k1000.dtsi | 7 + arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 + drivers/rtc/Kconfig | 23 +- drivers/rtc/Makefile | 2 +- drivers/rtc/rtc-loongson.c | 397 ++++++++++++++++++ drivers/rtc/rtc-ls1x.c | 192 --------- 8 files changed, 482 insertions(+), 205 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/loongson,rtc.yaml create mode 100644 drivers/rtc/rtc-loongson.c delete mode 100644 drivers/rtc/rtc-ls1x.c--
2.39.1
Re: (subset) [PATCH V5 0/5] Add rtc driver for the Loongson family chips
In reply to Binbin ZhouQuoted 10 lines · Binbin Zhou
The initial DT-base ls2x rtc driver was written by Wang Xuerui, He has released five versions of patchset before, and all related mail records are shown below if you are interested:
https://lore.kernel.org/all/?q=ls2x-rtc
In this series of patches, based on the code above, I have added the following support:
[...]
Applied, thanks!
[1/5] dt-bindings: rtc: Remove the LS2X from the trivial RTCs
commit: 487ef32caebe010f0ff0f17267230ebaf2177e67
[2/5] rtc: Remove the Loongson-1 RTC driver
commit: 9fb23090658adbd7f8f44bf5c38aa3fc4b1699bd
[3/5] rtc: Add rtc driver for the Loongson family chips
commit: 1b733a9ebc3d8011ca66ec6ff17f55a440358794Best regards,
Signature · 3 lines
Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com