* [PATCH v4 0/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC @ 2021-06-28 16:45 WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 1/6] " WANG Xuerui ` (3 more replies) 0 siblings, 4 replies; 8+ messages in thread From: WANG Xuerui @ 2021-06-28 16:45 UTC (permalink / raw) To: linux-rtc; +Cc: WANG Xuerui, linux-mips, devicetree Here is the 4th revision of the series; the review mail got lost in my inbox so this is a bit late, sorry for the delay! The previous revision is tested on Loongson-2K by Jiaxun Yang, and this revision contains no functional changes so should work on 2K too. I compiled and tested this revision on a Loongson-3A4000 & LS7A system. This patch series adds support for the RTC module found on various Loongson systems with the Loongson-2K SoC or the LS7A bridge chip. The driver is rewritten from an out-of-tree version to meet mainline standards. I write kernel code as a hobby, though, so there might still be overlooked issues. Any suggestions are welcome. This series is based on next-20210628, but should apply cleanly on rtc-next too. v4: - Rebased on top of next-20210628 - Added Jiaxun's Tested-by tag for Loongson-2K - Addressed all review comments from v3 - Rewritten field operations with FIELD_GET/FIELD_PREP - Removed all error logs - Removed unnecessary spinlocking (RTC core already protects against concurrent device file operations) v3: - Fixed compile error not discovered after rebase (blame sleep deprivation) - Tested on Loongson-3A4000 (still need testing on Loongson-2K) v2: - Rebased on top of latest linux-next - Updated Huacai's e-mail address to the kernel.org one - Added collected tags - Added adaptation for newly upstreamed Loongson-2K platforms WANG Xuerui (6): rtc: ls2x: Add support for the Loongson-2K/LS7A RTC dt-bindings: rtc: Add bindings for LS2X RTC MIPS: Loongson64: DTS: Add RTC support to LS7A MIPS: Loongson: Enable LS2X RTC in loongson3_defconfig MIPS: Loongson64: DTS: Add RTC support to Loongson-2K MIPS: Loongson: Enable LS2X RTC in loongson2k_defconfig .../devicetree/bindings/rtc/trivial-rtc.yaml | 2 + .../boot/dts/loongson/loongson64-2k1000.dtsi | 5 + arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 5 + arch/mips/configs/loongson2k_defconfig | 1 + arch/mips/configs/loongson3_defconfig | 1 + drivers/rtc/Kconfig | 11 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ls2x.c | 184 ++++++++++++++++++ 8 files changed, 210 insertions(+) create mode 100644 drivers/rtc/rtc-ls2x.c base-commit: 3579aa488520feeda433ceca23ef4704bf8cd280 -- 2.30.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 1/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC 2021-06-28 16:45 [PATCH v4 0/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC WANG Xuerui @ 2021-06-28 16:45 ` WANG Xuerui 2021-07-02 5:52 ` Nobuhiro Iwamatsu 2021-06-28 16:45 ` [PATCH v4 2/6] dt-bindings: rtc: Add bindings for LS2X RTC WANG Xuerui ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: WANG Xuerui @ 2021-06-28 16:45 UTC (permalink / raw) To: linux-rtc; +Cc: WANG Xuerui, Huacai Chen, Jiaxun Yang, devicetree, linux-mips This RTC module is integrated into the Loongson-2K SoC and the LS7A bridge chip. This version is almost entirely rewritten to make use of current kernel API. Signed-off-by: Huacai Chen <chenhuacai@kernel.org> Signed-off-by: WANG Xuerui <git@xen0n.name> Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> # loongson2k Cc: devicetree@vger.kernel.org Cc: linux-mips@vger.kernel.org --- drivers/rtc/Kconfig | 11 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ls2x.c | 184 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 drivers/rtc/rtc-ls2x.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 12153d5801ce..253b9f22a162 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1304,6 +1304,17 @@ config RTC_DRV_NTXEC embedded controller found in certain e-book readers designed by the original design manufacturer Netronix. +config RTC_DRV_LS2X + tristate "Loongson LS2X RTC" + depends on MACH_LOONGSON64 || COMPILE_TEST + select REGMAP_MMIO + help + If you say yes here you get support for the RTC on the Loongson-2K + SoC and LS7A bridge, which first appeared on the Loongson-2H. + + This driver can also be built as a module. If so, the module + will be called rtc-ls2x. + comment "on-CPU RTC drivers" config RTC_DRV_ASM9260 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2dd0dd956b0e..6042ff1e73b7 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -81,6 +81,7 @@ 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 +obj-$(CONFIG_RTC_DRV_LS2X) += rtc-ls2x.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o diff --git a/drivers/rtc/rtc-ls2x.c b/drivers/rtc/rtc-ls2x.c new file mode 100644 index 000000000000..1147a6e1591f --- /dev/null +++ b/drivers/rtc/rtc-ls2x.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Loongson-2K/7A RTC driver + * + * Based on the original out-of-tree Loongson-2H RTC driver for Linux 2.6.32, + * by Shaozong Liu <liushaozong@loongson.cn>. + * + * Maintained out-of-tree by Huacai Chen <chenhuacai@kernel.org>. + * + * Rewritten for mainline by WANG Xuerui <git@xen0n.name>. + */ + +#include <linux/bitfield.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/rtc.h> + +#define TOY_TRIM_REG 0x20 +#define TOY_WRITE0_REG 0x24 +#define TOY_WRITE1_REG 0x28 +#define TOY_READ0_REG 0x2c +#define TOY_READ1_REG 0x30 +#define TOY_MATCH0_REG 0x34 +#define TOY_MATCH1_REG 0x38 +#define TOY_MATCH2_REG 0x3c +#define RTC_CTRL_REG 0x40 +#define RTC_TRIM_REG 0x60 +#define RTC_WRITE0_REG 0x64 +#define RTC_READ0_REG 0x68 +#define RTC_MATCH0_REG 0x6c +#define RTC_MATCH1_REG 0x70 +#define RTC_MATCH2_REG 0x74 + +#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) + +struct ls2x_rtc_priv { + struct regmap *regmap; +}; + +static const struct regmap_config ls2x_rtc_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +struct ls2x_rtc_regs { + u32 reg0; + u32 reg1; +}; + +static inline void ls2x_rtc_regs_to_time(struct ls2x_rtc_regs *regs, + struct rtc_time *tm) +{ + tm->tm_year = regs->reg1; + tm->tm_sec = FIELD_GET(TOY_SEC, regs->reg0); + tm->tm_min = FIELD_GET(TOY_MIN, regs->reg0); + tm->tm_hour = FIELD_GET(TOY_HOUR, regs->reg0); + tm->tm_mday = FIELD_GET(TOY_DAY, regs->reg0); + tm->tm_mon = FIELD_GET(TOY_MON, regs->reg0) - 1; +} + +static inline void ls2x_rtc_time_to_regs(struct rtc_time *tm, + struct ls2x_rtc_regs *regs) +{ + regs->reg0 = FIELD_PREP(TOY_SEC, tm->tm_sec); + regs->reg0 |= FIELD_PREP(TOY_MIN, tm->tm_min); + regs->reg0 |= FIELD_PREP(TOY_HOUR, tm->tm_hour); + regs->reg0 |= FIELD_PREP(TOY_DAY, tm->tm_mday); + regs->reg0 |= FIELD_PREP(TOY_MON, tm->tm_mon + 1); + regs->reg1 = tm->tm_year; +} + +static int ls2x_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct ls2x_rtc_priv *priv = dev_get_drvdata(dev); + struct ls2x_rtc_regs regs; + int ret; + + ret = regmap_read(priv->regmap, TOY_READ1_REG, ®s.reg1); + if (unlikely(ret)) + return ret; + + ret = regmap_read(priv->regmap, TOY_READ0_REG, ®s.reg0); + if (unlikely(ret)) + return ret; + + ls2x_rtc_regs_to_time(®s, tm); + + return 0; +} + +static int ls2x_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct ls2x_rtc_priv *priv = dev_get_drvdata(dev); + struct ls2x_rtc_regs regs; + int ret; + + ls2x_rtc_time_to_regs(tm, ®s); + + ret = regmap_write(priv->regmap, TOY_WRITE0_REG, regs.reg0); + if (unlikely(ret)) + return ret; + + ret = regmap_write(priv->regmap, TOY_WRITE1_REG, regs.reg1); + if (unlikely(ret)) + return ret; + + return 0; +} + +static struct rtc_class_ops ls2x_rtc_ops = { + .read_time = ls2x_rtc_read_time, + .set_time = ls2x_rtc_set_time, +}; + +static int ls2x_rtc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rtc_device *rtc; + struct ls2x_rtc_priv *priv; + void __iomem *regs; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (unlikely(!priv)) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + priv->regmap = devm_regmap_init_mmio(dev, regs, + &ls2x_rtc_regmap_config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + rtc = devm_rtc_allocate_device(dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + rtc->ops = &ls2x_rtc_ops; + + /* Due to hardware erratum, all years multiple of 4 are considered + * leap year, so only years 2000 through 2099 are usable. + * + * Previous out-of-tree versions of this driver wrote tm_year directly + * into the year register, so epoch 2000 must be used to preserve + * semantics on shipped systems. + */ + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->range_max = RTC_TIMESTAMP_END_2099; + + return devm_rtc_register_device(rtc); +} + +static const struct of_device_id ls2x_rtc_of_match[] = { + { .compatible = "loongson,ls2x-rtc" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ls2x_rtc_of_match); + +static struct platform_driver ls2x_rtc_driver = { + .probe = ls2x_rtc_probe, + .driver = { + .name = "ls2x-rtc", + .of_match_table = of_match_ptr(ls2x_rtc_of_match), + }, +}; + +module_platform_driver(ls2x_rtc_driver); + +MODULE_DESCRIPTION("LS2X RTC driver"); +MODULE_AUTHOR("WANG Xuerui"); +MODULE_AUTHOR("Huacai Chen"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ls2x-rtc"); -- 2.30.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC 2021-06-28 16:45 ` [PATCH v4 1/6] " WANG Xuerui @ 2021-07-02 5:52 ` Nobuhiro Iwamatsu 2021-07-02 6:16 ` WANG Xuerui 0 siblings, 1 reply; 8+ messages in thread From: Nobuhiro Iwamatsu @ 2021-07-02 5:52 UTC (permalink / raw) To: WANG Xuerui; +Cc: linux-rtc, Huacai Chen, Jiaxun Yang, devicetree, linux-mips Hi, 2021年6月29日(火) 1:52 WANG Xuerui <git@xen0n.name>: > > This RTC module is integrated into the Loongson-2K SoC and the LS7A > bridge chip. This version is almost entirely rewritten to make use of > current kernel API. > > Signed-off-by: Huacai Chen <chenhuacai@kernel.org> > Signed-off-by: WANG Xuerui <git@xen0n.name> > Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> # loongson2k > Cc: devicetree@vger.kernel.org > Cc: linux-mips@vger.kernel.org > --- > drivers/rtc/Kconfig | 11 +++ > drivers/rtc/Makefile | 1 + > drivers/rtc/rtc-ls2x.c | 184 +++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 196 insertions(+) > create mode 100644 drivers/rtc/rtc-ls2x.c > > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig > index 12153d5801ce..253b9f22a162 100644 > --- a/drivers/rtc/Kconfig > +++ b/drivers/rtc/Kconfig > @@ -1304,6 +1304,17 @@ config RTC_DRV_NTXEC > embedded controller found in certain e-book readers designed by the > original design manufacturer Netronix. > > +config RTC_DRV_LS2X > + tristate "Loongson LS2X RTC" > + depends on MACH_LOONGSON64 || COMPILE_TEST > + select REGMAP_MMIO > + help > + If you say yes here you get support for the RTC on the Loongson-2K > + SoC and LS7A bridge, which first appeared on the Loongson-2H. > + > + This driver can also be built as a module. If so, the module > + will be called rtc-ls2x. > + > comment "on-CPU RTC drivers" > > config RTC_DRV_ASM9260 > diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile > index 2dd0dd956b0e..6042ff1e73b7 100644 > --- a/drivers/rtc/Makefile > +++ b/drivers/rtc/Makefile > @@ -81,6 +81,7 @@ 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 > +obj-$(CONFIG_RTC_DRV_LS2X) += rtc-ls2x.o > obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o > obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o > obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o > diff --git a/drivers/rtc/rtc-ls2x.c b/drivers/rtc/rtc-ls2x.c > new file mode 100644 > index 000000000000..1147a6e1591f > --- /dev/null > +++ b/drivers/rtc/rtc-ls2x.c > @@ -0,0 +1,184 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Loongson-2K/7A RTC driver > + * > + * Based on the original out-of-tree Loongson-2H RTC driver for Linux 2.6.32, > + * by Shaozong Liu <liushaozong@loongson.cn>. > + * > + * Maintained out-of-tree by Huacai Chen <chenhuacai@kernel.org>. > + * > + * Rewritten for mainline by WANG Xuerui <git@xen0n.name>. > + */ > + > +#include <linux/bitfield.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/platform_device.h> > +#include <linux/regmap.h> > +#include <linux/rtc.h> > + > +#define TOY_TRIM_REG 0x20 > +#define TOY_WRITE0_REG 0x24 > +#define TOY_WRITE1_REG 0x28 > +#define TOY_READ0_REG 0x2c > +#define TOY_READ1_REG 0x30 > +#define TOY_MATCH0_REG 0x34 > +#define TOY_MATCH1_REG 0x38 > +#define TOY_MATCH2_REG 0x3c > +#define RTC_CTRL_REG 0x40 > +#define RTC_TRIM_REG 0x60 > +#define RTC_WRITE0_REG 0x64 > +#define RTC_READ0_REG 0x68 > +#define RTC_MATCH0_REG 0x6c > +#define RTC_MATCH1_REG 0x70 > +#define RTC_MATCH2_REG 0x74 > + > +#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) > + > +struct ls2x_rtc_priv { > + struct regmap *regmap; > +}; > + > +static const struct regmap_config ls2x_rtc_regmap_config = { > + .reg_bits = 32, > + .val_bits = 32, > + .reg_stride = 4, > +}; > + > +struct ls2x_rtc_regs { > + u32 reg0; > + u32 reg1; > +}; > + > +static inline void ls2x_rtc_regs_to_time(struct ls2x_rtc_regs *regs, > + struct rtc_time *tm) > +{ > + tm->tm_year = regs->reg1; > + tm->tm_sec = FIELD_GET(TOY_SEC, regs->reg0); > + tm->tm_min = FIELD_GET(TOY_MIN, regs->reg0); > + tm->tm_hour = FIELD_GET(TOY_HOUR, regs->reg0); > + tm->tm_mday = FIELD_GET(TOY_DAY, regs->reg0); > + tm->tm_mon = FIELD_GET(TOY_MON, regs->reg0) - 1; > +} > + > +static inline void ls2x_rtc_time_to_regs(struct rtc_time *tm, > + struct ls2x_rtc_regs *regs) > +{ > + regs->reg0 = FIELD_PREP(TOY_SEC, tm->tm_sec); > + regs->reg0 |= FIELD_PREP(TOY_MIN, tm->tm_min); > + regs->reg0 |= FIELD_PREP(TOY_HOUR, tm->tm_hour); > + regs->reg0 |= FIELD_PREP(TOY_DAY, tm->tm_mday); > + regs->reg0 |= FIELD_PREP(TOY_MON, tm->tm_mon + 1); > + regs->reg1 = tm->tm_year; > +} > + > +static int ls2x_rtc_read_time(struct device *dev, struct rtc_time *tm) > +{ > + struct ls2x_rtc_priv *priv = dev_get_drvdata(dev); > + struct ls2x_rtc_regs regs; > + int ret; > + > + ret = regmap_read(priv->regmap, TOY_READ1_REG, ®s.reg1); > + if (unlikely(ret)) > + return ret; > + > + ret = regmap_read(priv->regmap, TOY_READ0_REG, ®s.reg0); > + if (unlikely(ret)) > + return ret; > + > + ls2x_rtc_regs_to_time(®s, tm); > + > + return 0; > +} > + > +static int ls2x_rtc_set_time(struct device *dev, struct rtc_time *tm) > +{ > + struct ls2x_rtc_priv *priv = dev_get_drvdata(dev); > + struct ls2x_rtc_regs regs; > + int ret; > + > + ls2x_rtc_time_to_regs(tm, ®s); > + > + ret = regmap_write(priv->regmap, TOY_WRITE0_REG, regs.reg0); > + if (unlikely(ret)) > + return ret; > + > + ret = regmap_write(priv->regmap, TOY_WRITE1_REG, regs.reg1); > + if (unlikely(ret)) > + return ret; I think this can be returned directly. > + > + return 0; > +} > + > +static struct rtc_class_ops ls2x_rtc_ops = { > + .read_time = ls2x_rtc_read_time, > + .set_time = ls2x_rtc_set_time, > +}; > + > +static int ls2x_rtc_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct rtc_device *rtc; > + struct ls2x_rtc_priv *priv; > + void __iomem *regs; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (unlikely(!priv)) > + return -ENOMEM; > + > + platform_set_drvdata(pdev, priv); > + > + regs = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(regs)) > + return PTR_ERR(regs); > + > + priv->regmap = devm_regmap_init_mmio(dev, regs, > + &ls2x_rtc_regmap_config); > + if (IS_ERR(priv->regmap)) > + return PTR_ERR(priv->regmap); > + > + rtc = devm_rtc_allocate_device(dev); > + if (IS_ERR(rtc)) > + return PTR_ERR(rtc); > + > + rtc->ops = &ls2x_rtc_ops; > + > + /* Due to hardware erratum, all years multiple of 4 are considered > + * leap year, so only years 2000 through 2099 are usable. > + * > + * Previous out-of-tree versions of this driver wrote tm_year directly > + * into the year register, so epoch 2000 must be used to preserve > + * semantics on shipped systems. > + */ > + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; > + rtc->range_max = RTC_TIMESTAMP_END_2099; > + > + return devm_rtc_register_device(rtc); > +} > + > +static const struct of_device_id ls2x_rtc_of_match[] = { > + { .compatible = "loongson,ls2x-rtc" }, > + { /* sentinel */ }, > +}; > +MODULE_DEVICE_TABLE(of, ls2x_rtc_of_match); > + > +static struct platform_driver ls2x_rtc_driver = { > + .probe = ls2x_rtc_probe, > + .driver = { > + .name = "ls2x-rtc", > + .of_match_table = of_match_ptr(ls2x_rtc_of_match), If my understanding is correct, this architecture is a DT-only platform. Therefore, of_match_ptr() macro is unnecessary. > + }, > +}; > + > +module_platform_driver(ls2x_rtc_driver); > + > +MODULE_DESCRIPTION("LS2X RTC driver"); > +MODULE_AUTHOR("WANG Xuerui"); > +MODULE_AUTHOR("Huacai Chen"); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:ls2x-rtc"); > -- > 2.30.1 > -- Nobuhiro Iwamatsu iwamatsu at {nigauri.org / debian.org / kernel.org} GPG ID: 40AD1FA6 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC 2021-07-02 5:52 ` Nobuhiro Iwamatsu @ 2021-07-02 6:16 ` WANG Xuerui 0 siblings, 0 replies; 8+ messages in thread From: WANG Xuerui @ 2021-07-02 6:16 UTC (permalink / raw) To: Nobuhiro Iwamatsu Cc: linux-rtc, Huacai Chen, Jiaxun Yang, devicetree, linux-mips Hi Nobuhiro-san, (sorry for the duplicated reply on your side; I didn't include all recipients correctly in the first mail, hence the resend.) On 2021/7/2 13:52, Nobuhiro Iwamatsu wrote: > Hi, > > 2021年6月29日(火) 1:52 WANG Xuerui <git@xen0n.name>: >> This RTC module is integrated into the Loongson-2K SoC and the LS7A >> bridge chip. This version is almost entirely rewritten to make use of >> current kernel API. >> >> Signed-off-by: Huacai Chen <chenhuacai@kernel.org> >> Signed-off-by: WANG Xuerui <git@xen0n.name> >> Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> # loongson2k >> Cc: devicetree@vger.kernel.org >> Cc: linux-mips@vger.kernel.org >> --- >> drivers/rtc/Kconfig | 11 +++ >> drivers/rtc/Makefile | 1 + >> drivers/rtc/rtc-ls2x.c | 184 +++++++++++++++++++++++++++++++++++++++++ >> 3 files changed, 196 insertions(+) >> create mode 100644 drivers/rtc/rtc-ls2x.c >> >> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig >> index 12153d5801ce..253b9f22a162 100644 >> --- a/drivers/rtc/Kconfig >> +++ b/drivers/rtc/Kconfig >> @@ -1304,6 +1304,17 @@ config RTC_DRV_NTXEC >> embedded controller found in certain e-book readers designed by the >> original design manufacturer Netronix. >> >> +config RTC_DRV_LS2X >> + tristate "Loongson LS2X RTC" >> + depends on MACH_LOONGSON64 || COMPILE_TEST >> + select REGMAP_MMIO >> + help >> + If you say yes here you get support for the RTC on the Loongson-2K >> + SoC and LS7A bridge, which first appeared on the Loongson-2H. >> + >> + This driver can also be built as a module. If so, the module >> + will be called rtc-ls2x. >> + >> comment "on-CPU RTC drivers" >> >> config RTC_DRV_ASM9260 >> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile >> index 2dd0dd956b0e..6042ff1e73b7 100644 >> --- a/drivers/rtc/Makefile >> +++ b/drivers/rtc/Makefile >> @@ -81,6 +81,7 @@ 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 >> +obj-$(CONFIG_RTC_DRV_LS2X) += rtc-ls2x.o >> obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o >> obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o >> obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o >> diff --git a/drivers/rtc/rtc-ls2x.c b/drivers/rtc/rtc-ls2x.c >> new file mode 100644 >> index 000000000000..1147a6e1591f >> --- /dev/null >> +++ b/drivers/rtc/rtc-ls2x.c >> @@ -0,0 +1,184 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Loongson-2K/7A RTC driver >> + * >> + * Based on the original out-of-tree Loongson-2H RTC driver for Linux 2.6.32, >> + * by Shaozong Liu <liushaozong@loongson.cn>. >> + * >> + * Maintained out-of-tree by Huacai Chen <chenhuacai@kernel.org>. >> + * >> + * Rewritten for mainline by WANG Xuerui <git@xen0n.name>. >> + */ >> + >> +#include <linux/bitfield.h> >> +#include <linux/module.h> >> +#include <linux/of.h> >> +#include <linux/platform_device.h> >> +#include <linux/regmap.h> >> +#include <linux/rtc.h> >> + >> +#define TOY_TRIM_REG 0x20 >> +#define TOY_WRITE0_REG 0x24 >> +#define TOY_WRITE1_REG 0x28 >> +#define TOY_READ0_REG 0x2c >> +#define TOY_READ1_REG 0x30 >> +#define TOY_MATCH0_REG 0x34 >> +#define TOY_MATCH1_REG 0x38 >> +#define TOY_MATCH2_REG 0x3c >> +#define RTC_CTRL_REG 0x40 >> +#define RTC_TRIM_REG 0x60 >> +#define RTC_WRITE0_REG 0x64 >> +#define RTC_READ0_REG 0x68 >> +#define RTC_MATCH0_REG 0x6c >> +#define RTC_MATCH1_REG 0x70 >> +#define RTC_MATCH2_REG 0x74 >> + >> +#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) >> + >> +struct ls2x_rtc_priv { >> + struct regmap *regmap; >> +}; >> + >> +static const struct regmap_config ls2x_rtc_regmap_config = { >> + .reg_bits = 32, >> + .val_bits = 32, >> + .reg_stride = 4, >> +}; >> + >> +struct ls2x_rtc_regs { >> + u32 reg0; >> + u32 reg1; >> +}; >> + >> +static inline void ls2x_rtc_regs_to_time(struct ls2x_rtc_regs *regs, >> + struct rtc_time *tm) >> +{ >> + tm->tm_year = regs->reg1; >> + tm->tm_sec = FIELD_GET(TOY_SEC, regs->reg0); >> + tm->tm_min = FIELD_GET(TOY_MIN, regs->reg0); >> + tm->tm_hour = FIELD_GET(TOY_HOUR, regs->reg0); >> + tm->tm_mday = FIELD_GET(TOY_DAY, regs->reg0); >> + tm->tm_mon = FIELD_GET(TOY_MON, regs->reg0) - 1; >> +} >> + >> +static inline void ls2x_rtc_time_to_regs(struct rtc_time *tm, >> + struct ls2x_rtc_regs *regs) >> +{ >> + regs->reg0 = FIELD_PREP(TOY_SEC, tm->tm_sec); >> + regs->reg0 |= FIELD_PREP(TOY_MIN, tm->tm_min); >> + regs->reg0 |= FIELD_PREP(TOY_HOUR, tm->tm_hour); >> + regs->reg0 |= FIELD_PREP(TOY_DAY, tm->tm_mday); >> + regs->reg0 |= FIELD_PREP(TOY_MON, tm->tm_mon + 1); >> + regs->reg1 = tm->tm_year; >> +} >> + >> +static int ls2x_rtc_read_time(struct device *dev, struct rtc_time *tm) >> +{ >> + struct ls2x_rtc_priv *priv = dev_get_drvdata(dev); >> + struct ls2x_rtc_regs regs; >> + int ret; >> + >> + ret = regmap_read(priv->regmap, TOY_READ1_REG, ®s.reg1); >> + if (unlikely(ret)) >> + return ret; >> + >> + ret = regmap_read(priv->regmap, TOY_READ0_REG, ®s.reg0); >> + if (unlikely(ret)) >> + return ret; >> + >> + ls2x_rtc_regs_to_time(®s, tm); >> + >> + return 0; >> +} >> + >> +static int ls2x_rtc_set_time(struct device *dev, struct rtc_time *tm) >> +{ >> + struct ls2x_rtc_priv *priv = dev_get_drvdata(dev); >> + struct ls2x_rtc_regs regs; >> + int ret; >> + >> + ls2x_rtc_time_to_regs(tm, ®s); >> + >> + ret = regmap_write(priv->regmap, TOY_WRITE0_REG, regs.reg0); >> + if (unlikely(ret)) >> + return ret; >> + >> + ret = regmap_write(priv->regmap, TOY_WRITE1_REG, regs.reg1); >> + if (unlikely(ret)) >> + return ret; > I think this can be returned directly. Fair point; this is done purely for the two writes to be visually symmetrical. I'll send v5. > >> + >> + return 0; >> +} >> + >> +static struct rtc_class_ops ls2x_rtc_ops = { >> + .read_time = ls2x_rtc_read_time, >> + .set_time = ls2x_rtc_set_time, >> +}; >> + >> +static int ls2x_rtc_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct rtc_device *rtc; >> + struct ls2x_rtc_priv *priv; >> + void __iomem *regs; >> + >> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); >> + if (unlikely(!priv)) >> + return -ENOMEM; >> + >> + platform_set_drvdata(pdev, priv); >> + >> + regs = devm_platform_ioremap_resource(pdev, 0); >> + if (IS_ERR(regs)) >> + return PTR_ERR(regs); >> + >> + priv->regmap = devm_regmap_init_mmio(dev, regs, >> + &ls2x_rtc_regmap_config); >> + if (IS_ERR(priv->regmap)) >> + return PTR_ERR(priv->regmap); >> + >> + rtc = devm_rtc_allocate_device(dev); >> + if (IS_ERR(rtc)) >> + return PTR_ERR(rtc); >> + >> + rtc->ops = &ls2x_rtc_ops; >> + >> + /* Due to hardware erratum, all years multiple of 4 are considered >> + * leap year, so only years 2000 through 2099 are usable. >> + * >> + * Previous out-of-tree versions of this driver wrote tm_year directly >> + * into the year register, so epoch 2000 must be used to preserve >> + * semantics on shipped systems. >> + */ >> + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; >> + rtc->range_max = RTC_TIMESTAMP_END_2099; >> + >> + return devm_rtc_register_device(rtc); >> +} >> + >> +static const struct of_device_id ls2x_rtc_of_match[] = { >> + { .compatible = "loongson,ls2x-rtc" }, >> + { /* sentinel */ }, >> +}; >> +MODULE_DEVICE_TABLE(of, ls2x_rtc_of_match); >> + >> +static struct platform_driver ls2x_rtc_driver = { >> + .probe = ls2x_rtc_probe, >> + .driver = { >> + .name = "ls2x-rtc", >> + .of_match_table = of_match_ptr(ls2x_rtc_of_match), > If my understanding is correct, this architecture is a DT-only platform. > Therefore, of_match_ptr() macro is unnecessary. Actually the forthcoming LoongArch platforms have both ACPI and DT, and this RTC block would of course be included in these (inside the LS7A bridge chip). If we remove the of_match_ptr usage now, we would still have to add back later. However I agree about not doing speculations; I'll remove that usage in v5. >> + }, >> +}; >> + >> +module_platform_driver(ls2x_rtc_driver); >> + >> +MODULE_DESCRIPTION("LS2X RTC driver"); >> +MODULE_AUTHOR("WANG Xuerui"); >> +MODULE_AUTHOR("Huacai Chen"); >> +MODULE_LICENSE("GPL"); >> +MODULE_ALIAS("platform:ls2x-rtc"); >> -- >> 2.30.1 >> > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 2/6] dt-bindings: rtc: Add bindings for LS2X RTC 2021-06-28 16:45 [PATCH v4 0/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 1/6] " WANG Xuerui @ 2021-06-28 16:45 ` WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 3/6] MIPS: Loongson64: DTS: Add RTC support to LS7A WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 5/6] MIPS: Loongson64: DTS: Add RTC support to Loongson-2K WANG Xuerui 3 siblings, 0 replies; 8+ messages in thread From: WANG Xuerui @ 2021-06-28 16:45 UTC (permalink / raw) To: linux-rtc; +Cc: WANG Xuerui, Rob Herring, Rob Herring, devicetree Document the binding for the LS2X RTC block found on the Loongson-2K SoC and the LS7A bridge, originally appearing on the Loongson-2H. Signed-off-by: WANG Xuerui <git@xen0n.name> Acked-by: Rob Herring <robh@kernel.org> Cc: Rob Herring <robh+dt@kernel.org> Cc: devicetree@vger.kernel.org --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index 7548d8714871..568aa89989fe 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -42,6 +42,8 @@ properties: - isil,isl1218 # Intersil ISL12022 Real-time Clock - isil,isl12022 + # Loongson LS2X RTC + - loongson,ls2x-rtc # Real Time Clock Module with I2C-Bus - microcrystal,rv3028 # Real Time Clock Module with I2C-Bus -- 2.30.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 3/6] MIPS: Loongson64: DTS: Add RTC support to LS7A 2021-06-28 16:45 [PATCH v4 0/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 1/6] " WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 2/6] dt-bindings: rtc: Add bindings for LS2X RTC WANG Xuerui @ 2021-06-28 16:45 ` WANG Xuerui 2021-06-29 3:25 ` Jiaxun Yang 2021-06-28 16:45 ` [PATCH v4 5/6] MIPS: Loongson64: DTS: Add RTC support to Loongson-2K WANG Xuerui 3 siblings, 1 reply; 8+ messages in thread From: WANG Xuerui @ 2021-06-28 16:45 UTC (permalink / raw) To: linux-rtc; +Cc: WANG Xuerui, Rob Herring, devicetree, linux-mips The LS7A RTC module is now supported, enable it. Signed-off-by: WANG Xuerui <git@xen0n.name> Cc: Rob Herring <robh+dt@kernel.org> Cc: devicetree@vger.kernel.org Cc: linux-mips@vger.kernel.org --- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index 2f45fce2cdc4..82035de4774f 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -19,6 +19,11 @@ pic: interrupt-controller@10000000 { #interrupt-cells = <2>; }; + rtc0: rtc@100d0100 { + compatible = "loongson,ls2x-rtc"; + reg = <0 0x100d0100 0 0x78>; + }; + ls7a_uart0: serial@10080000 { compatible = "ns16550a"; reg = <0 0x10080000 0 0x100>; -- 2.30.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 3/6] MIPS: Loongson64: DTS: Add RTC support to LS7A 2021-06-28 16:45 ` [PATCH v4 3/6] MIPS: Loongson64: DTS: Add RTC support to LS7A WANG Xuerui @ 2021-06-29 3:25 ` Jiaxun Yang 0 siblings, 0 replies; 8+ messages in thread From: Jiaxun Yang @ 2021-06-29 3:25 UTC (permalink / raw) To: WANG Xuerui, linux-rtc; +Cc: Rob Herring, devicetree, linux-mips 在 2021/6/29 上午12:45, WANG Xuerui 写道: > The LS7A RTC module is now supported, enable it. > > Signed-off-by: WANG Xuerui <git@xen0n.name> > Cc: Rob Herring <robh+dt@kernel.org> > Cc: devicetree@vger.kernel.org > Cc: linux-mips@vger.kernel.org Acked-by: Jiaxun Yang <jiaxun.yang@flygoat.com> > --- > arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi > index 2f45fce2cdc4..82035de4774f 100644 > --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi > +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi > @@ -19,6 +19,11 @@ pic: interrupt-controller@10000000 { > #interrupt-cells = <2>; > }; > > + rtc0: rtc@100d0100 { > + compatible = "loongson,ls2x-rtc"; > + reg = <0 0x100d0100 0 0x78>; > + }; > + > ls7a_uart0: serial@10080000 { > compatible = "ns16550a"; > reg = <0 0x10080000 0 0x100>; ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 5/6] MIPS: Loongson64: DTS: Add RTC support to Loongson-2K 2021-06-28 16:45 [PATCH v4 0/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC WANG Xuerui ` (2 preceding siblings ...) 2021-06-28 16:45 ` [PATCH v4 3/6] MIPS: Loongson64: DTS: Add RTC support to LS7A WANG Xuerui @ 2021-06-28 16:45 ` WANG Xuerui 3 siblings, 0 replies; 8+ messages in thread From: WANG Xuerui @ 2021-06-28 16:45 UTC (permalink / raw) To: linux-rtc; +Cc: WANG Xuerui, Jiaxun Yang, Rob Herring, devicetree, linux-mips The Loongson-2K RTC module is now supported, enable it. The MMIO address is unclear from the Loongson 2K1000 user manual, I took it from Loongson's out-of-tree fork of Linux 4.19. Signed-off-by: WANG Xuerui <git@xen0n.name> Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> # loongson2k Cc: Rob Herring <robh+dt@kernel.org> Cc: devicetree@vger.kernel.org Cc: linux-mips@vger.kernel.org --- arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi index bfc3d3243ee7..4a04e1dc5fda 100644 --- a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi +++ b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi @@ -52,6 +52,11 @@ package0: bus@10000000 { 0 0x40000000 0 0x40000000 0 0x40000000 0xfe 0x00000000 0xfe 0x00000000 0 0x40000000>; + rtc0: rtc@1fe07800 { + compatible = "loongson,ls2x-rtc"; + reg = <0 0x1fe07800 0 0x78>; + }; + liointc0: interrupt-controller@1fe11400 { compatible = "loongson,liointc-2.0"; reg = <0 0x1fe11400 0 0x40>, -- 2.30.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-07-02 6:27 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-06-28 16:45 [PATCH v4 0/6] rtc: ls2x: Add support for the Loongson-2K/LS7A RTC WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 1/6] " WANG Xuerui 2021-07-02 5:52 ` Nobuhiro Iwamatsu 2021-07-02 6:16 ` WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 2/6] dt-bindings: rtc: Add bindings for LS2X RTC WANG Xuerui 2021-06-28 16:45 ` [PATCH v4 3/6] MIPS: Loongson64: DTS: Add RTC support to LS7A WANG Xuerui 2021-06-29 3:25 ` Jiaxun Yang 2021-06-28 16:45 ` [PATCH v4 5/6] MIPS: Loongson64: DTS: Add RTC support to Loongson-2K WANG Xuerui
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).