* [PATCH 0/3] Add RTC for MStar SoCs @ 2021-07-20 17:22 Romain Perier 2021-07-20 17:22 ` [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation Romain Perier ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Romain Perier @ 2021-07-20 17:22 UTC (permalink / raw) To: Alessandro Zummo, Alexandre Belloni, Daniel Palmer, Rob Herring Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel This patches series adds a new driver for the RTC found in the Mstar MSC313e SoCs and newer. It adds a basic rtc driver, the corresponding devicetree bindings and its documentation. Daniel Palmer (1): rtc: Add support for the MSTAR MSC313 RTC Romain Perier (2): dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation ARM: dts: mstar: Add rtc device node .../bindings/rtc/mstar,msc313-rtc.yaml | 46 ++++ MAINTAINERS | 1 + arch/arm/boot/dts/mstar-v7.dtsi | 7 + drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-msc313.c | 246 ++++++++++++++++++ 6 files changed, 311 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml create mode 100644 drivers/rtc/rtc-msc313.c -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation 2021-07-20 17:22 [PATCH 0/3] Add RTC for MStar SoCs Romain Perier @ 2021-07-20 17:22 ` Romain Perier 2021-07-21 13:41 ` Rob Herring 2021-07-20 17:22 ` [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC Romain Perier 2021-07-20 17:22 ` [PATCH 3/3] ARM: dts: mstar: Add rtc device node Romain Perier 2 siblings, 1 reply; 7+ messages in thread From: Romain Perier @ 2021-07-20 17:22 UTC (permalink / raw) To: Alessandro Zummo, Alexandre Belloni, Daniel Palmer, Rob Herring Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel This adds the documentation for the devicetree bindings of the Mstar MSC313e RTC driver, found from MSC313e SoCs and newer. Signed-off-by: Romain Perier <romain.perier@gmail.com> --- .../bindings/rtc/mstar,msc313-rtc.yaml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml diff --git a/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml new file mode 100644 index 000000000000..978c28bc3da5 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/mstar,msc313-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mstar MSC313e RTC Device Tree Bindings + +allOf: + - $ref: "rtc.yaml#" + +maintainers: + - Daniel Palmer <daniel@0x0f.com> + - Romain Perier <romain.perier@gmail.com> + +properties: + compatible: + enum: + - mstar,msc313-rtc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +additionalProperties: false + +examples: + - | + rtc@2400 { + compatible = "mstar,msc313-rtc"; + reg = <0x2400 0x40>; + clocks = <&xtal_div2>; + interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + }; +... -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation 2021-07-20 17:22 ` [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation Romain Perier @ 2021-07-21 13:41 ` Rob Herring 0 siblings, 0 replies; 7+ messages in thread From: Rob Herring @ 2021-07-21 13:41 UTC (permalink / raw) To: Romain Perier Cc: devicetree, Daniel Palmer, linux-kernel, linux-rtc, Alexandre Belloni, Rob Herring, Alessandro Zummo, linux-arm-kernel On Tue, 20 Jul 2021 19:22:49 +0200, Romain Perier wrote: > This adds the documentation for the devicetree bindings of the Mstar > MSC313e RTC driver, found from MSC313e SoCs and newer. > > Signed-off-by: Romain Perier <romain.perier@gmail.com> > --- > .../bindings/rtc/mstar,msc313-rtc.yaml | 46 +++++++++++++++++++ > 1 file changed, 46 insertions(+) > create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13): yamllint warnings/errors: dtschema/dtc warnings/errors: Error: Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.example.dts:23.46-47 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.example.dt.yaml] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:1418: dt_binding_check] Error 2 \ndoc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/patch/1507685 This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC 2021-07-20 17:22 [PATCH 0/3] Add RTC for MStar SoCs Romain Perier 2021-07-20 17:22 ` [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation Romain Perier @ 2021-07-20 17:22 ` Romain Perier 2021-07-20 20:01 ` Alexandre Belloni 2021-07-20 17:22 ` [PATCH 3/3] ARM: dts: mstar: Add rtc device node Romain Perier 2 siblings, 1 reply; 7+ messages in thread From: Romain Perier @ 2021-07-20 17:22 UTC (permalink / raw) To: Alessandro Zummo, Alexandre Belloni, Daniel Palmer, Rob Herring Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel From: Daniel Palmer <daniel@0x0f.com> This adds support for the RTC block on the Mstar MSC313e SoCs and newer. Signed-off-by: Daniel Palmer <daniel@0x0f.com> Co-developed-by: Romain Perier <romain.perier@gmail.com> Signed-off-by: Romain Perier <romain.perier@gmail.com> --- MAINTAINERS | 1 + drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-msc313.c | 246 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 drivers/rtc/rtc-msc313.c diff --git a/MAINTAINERS b/MAINTAINERS index 6c8be735cc91..7e8d1a375e0d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2220,6 +2220,7 @@ F: arch/arm/boot/dts/mstar-* F: arch/arm/mach-mstar/ F: drivers/clk/mstar/ F: drivers/gpio/gpio-msc313.c +F: drivers/rtc/rtc-msc313.c F: drivers/watchdog/msc313e_wdt.c F: include/dt-bindings/clock/mstar-* F: include/dt-bindings/gpio/msc313-gpio.h diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 12153d5801ce..67870b422bc5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC This can also be built as a module. If so, the module will be named "rtc_wilco_ec". +config RTC_DRV_MSC313 + tristate "MStar MSC313 RTC" + depends on ARCH_MSTARV7 + help + If you say yes here you get support for the Mstar MSC313e On-Chip + Real Time Clock. + + This driver can also be built as a module, if so, the module + will be called "rtc-msc313". + endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2dd0dd956b0e..5efda8a60cee 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -101,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o obj-$(CONFIG_RTC_DRV_MESON) += rtc-meson.o obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o +obj-$(CONFIG_RTC_DRV_MSC313) += rtc-msc313.o obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o obj-$(CONFIG_RTC_DRV_MT2712) += rtc-mt2712.o obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c new file mode 100644 index 000000000000..b1102e3c93ba --- /dev/null +++ b/drivers/rtc/rtc-msc313.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs. + * Based on "Real Time Clock driver for msb252x." that was contained + * in various MStar kernels. + * + * (C) 2019 Daniel Palmer + * (C) 2021 Romain Perier + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> + +/* Registers */ +#define REG_RTC_CTRL 0x00 +#define REG_RTC_FREQ_CW_L 0x04 +#define REG_RTC_FREQ_CW_H 0x08 +#define REG_RTC_LOAD_VAL_L 0x0C +#define REG_RTC_LOAD_VAL_H 0x10 +#define REG_RTC_MATCH_VAL_L 0x14 +#define REG_RTC_MATCH_VAL_H 0x18 +#define REG_RTC_CNT_VAL_L 0x20 +#define REG_RTC_CNT_VAL_H 0x24 + +#define SOFT_RSTZ_BIT BIT(0) +#define CNT_EN_BIT BIT(1) +#define WRAP_EN_BIT BIT(2) +#define LOAD_EN_BIT BIT(3) +#define READ_EN_BIT BIT(4) +#define INT_MASK_BIT BIT(5) +#define INT_FORCE_BIT BIT(6) +#define INT_CLEAR_BIT BIT(7) + +struct msc313_rtc { + struct rtc_device *rtc_dev; + void __iomem *rtc_base; + struct clk *clk; +}; + +static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct msc313_rtc *priv = dev_get_drvdata(dev); + unsigned long seconds; + + seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L) + | (readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16); + + rtc_time64_to_tm(seconds, &alarm->time); + + if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT)) + alarm->enabled = 1; + + return 0; +} + +static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct msc313_rtc *priv = dev_get_drvdata(dev); + u16 reg; + + reg = readw(priv->rtc_base + REG_RTC_CTRL); + if (enabled) + reg &= ~INT_MASK_BIT; + else + reg |= INT_MASK_BIT; + writew(reg, priv->rtc_base + REG_RTC_CTRL); + return 0; +} + +static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct msc313_rtc *priv = dev_get_drvdata(dev); + unsigned long seconds; + + seconds = rtc_tm_to_time64(&alarm->time); + writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L); + writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H); + + msc313_rtc_alarm_irq_enable(dev, alarm->enabled); + + return 0; +} + +static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct msc313_rtc *priv = dev_get_drvdata(dev); + u32 seconds; + u16 reg; + + reg = readw(priv->rtc_base + REG_RTC_CTRL); + writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL); + + /* Wait for HW latch done */ + while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT) + udelay(1); + + seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L) + | (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16); + + rtc_time64_to_tm(seconds, tm); + + return rtc_valid_tm(tm); +} + +static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct msc313_rtc *priv = dev_get_drvdata(dev); + unsigned long seconds; + u16 reg; + + seconds = rtc_tm_to_time64(tm); + writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L); + writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H); + reg = readw(priv->rtc_base + REG_RTC_CTRL); + writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL); + + /* need to check carefully if we want to clear REG_RTC_LOAD_VAL_H for customer*/ + while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT) + udelay(1); + writew(0, priv->rtc_base + REG_RTC_LOAD_VAL_H); + + return 0; +} + +static const struct rtc_class_ops msc313_rtc_ops = { + .read_time = msc313_rtc_read_time, + .set_time = msc313_rtc_set_time, + .read_alarm = msc313_rtc_read_alarm, + .set_alarm = msc313_rtc_set_alarm, + .alarm_irq_enable = msc313_rtc_alarm_irq_enable, +}; + +static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id) +{ + struct msc313_rtc *priv = dev_get_drvdata(dev_id); + u16 reg; + + reg = readw_relaxed(priv->rtc_base + REG_RTC_CTRL); + reg |= INT_CLEAR_BIT; + reg &= ~INT_FORCE_BIT; + writew_relaxed(reg, priv->rtc_base + REG_RTC_CTRL); + + rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF); + + return IRQ_HANDLED; +} + +static int msc313_rtc_remove(struct platform_device *pdev) +{ + struct msc313_rtc *priv = platform_get_drvdata(pdev); + + clk_disable_unprepare(priv->clk); + + return 0; +} + +static int msc313_rtc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct msc313_rtc *priv; + int ret; + int irq; + unsigned long rate; + u16 reg; + + priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->rtc_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->rtc_base)) + return PTR_ERR(priv->rtc_base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -EINVAL; + + ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED, + dev_name(&pdev->dev), &pdev->dev); + if (ret) { + dev_err(dev, "Unable to request irq\n"); + return ret; + } + + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(dev, "No input reference clock\n"); + return PTR_ERR(priv->clk); + } + + ret = clk_prepare_enable(priv->clk); + if (ret) { + dev_err(dev, "Failed to enable the reference clock, %d\n", ret); + return ret; + } + + rate = clk_get_rate(priv->clk); + + reg = readw(priv->rtc_base + REG_RTC_CTRL); + if (!(reg & SOFT_RSTZ_BIT)) { + reg |= SOFT_RSTZ_BIT; + writew(reg, priv->rtc_base + REG_RTC_CTRL); + } + + writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L); + writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H); + + reg |= CNT_EN_BIT; + writew(reg, priv->rtc_base + REG_RTC_CTRL); + + platform_set_drvdata(pdev, priv); + + priv->rtc_dev = devm_rtc_device_register(dev, dev_name(dev), &msc313_rtc_ops, THIS_MODULE); + if (IS_ERR(priv->rtc_dev)) { + dev_err(dev, "Failed to register rtc device\n"); + return PTR_ERR(priv->rtc_dev); + } + + return 0; +} + +static const struct of_device_id msc313_rtc_of_match_table[] = { + { .compatible = "mstar,msc313-rtc" }, + { } +}; +MODULE_DEVICE_TABLE(of, ms_rtc_of_match_table); + +static struct platform_driver msc313_rtc_driver = { + .remove = msc313_rtc_remove, + .probe = msc313_rtc_probe, + .driver = { + .name = "msc313-rtc", + .of_match_table = msc313_rtc_of_match_table, + }, +}; + +module_platform_driver(msc313_rtc_driver); + +MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>"); +MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>"); +MODULE_DESCRIPTION("MStar RTC Driver"); +MODULE_LICENSE("GPL v2"); -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC 2021-07-20 17:22 ` [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC Romain Perier @ 2021-07-20 20:01 ` Alexandre Belloni 2021-07-21 16:56 ` Romain Perier 0 siblings, 1 reply; 7+ messages in thread From: Alexandre Belloni @ 2021-07-20 20:01 UTC (permalink / raw) To: Romain Perier Cc: Alessandro Zummo, Daniel Palmer, Rob Herring, linux-rtc, devicetree, linux-kernel, linux-arm-kernel Hello Romain, On 20/07/2021 19:22:50+0200, Romain Perier wrote: > From: Daniel Palmer <daniel@0x0f.com> > > This adds support for the RTC block on the Mstar MSC313e SoCs and newer. > > Signed-off-by: Daniel Palmer <daniel@0x0f.com> > Co-developed-by: Romain Perier <romain.perier@gmail.com> > Signed-off-by: Romain Perier <romain.perier@gmail.com> > --- > MAINTAINERS | 1 + > drivers/rtc/Kconfig | 10 ++ > drivers/rtc/Makefile | 1 + > drivers/rtc/rtc-msc313.c | 246 +++++++++++++++++++++++++++++++++++++++ > 4 files changed, 258 insertions(+) > create mode 100644 drivers/rtc/rtc-msc313.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 6c8be735cc91..7e8d1a375e0d 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2220,6 +2220,7 @@ F: arch/arm/boot/dts/mstar-* > F: arch/arm/mach-mstar/ > F: drivers/clk/mstar/ > F: drivers/gpio/gpio-msc313.c > +F: drivers/rtc/rtc-msc313.c > F: drivers/watchdog/msc313e_wdt.c > F: include/dt-bindings/clock/mstar-* > F: include/dt-bindings/gpio/msc313-gpio.h > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig > index 12153d5801ce..67870b422bc5 100644 > --- a/drivers/rtc/Kconfig > +++ b/drivers/rtc/Kconfig > @@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC > This can also be built as a module. If so, the module will > be named "rtc_wilco_ec". > > +config RTC_DRV_MSC313 > + tristate "MStar MSC313 RTC" > + depends on ARCH_MSTARV7 || COMPILE_TEST maybe ? > + help > + If you say yes here you get support for the Mstar MSC313e On-Chip > + Real Time Clock. > + > + This driver can also be built as a module, if so, the module > + will be called "rtc-msc313". > + > endif # RTC_CLASS > +static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm) > +{ > + struct msc313_rtc *priv = dev_get_drvdata(dev); > + u32 seconds; > + u16 reg; > + > + reg = readw(priv->rtc_base + REG_RTC_CTRL); > + writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL); > + > + /* Wait for HW latch done */ > + while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT) > + udelay(1); > + > + seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L) > + | (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16); > + > + rtc_time64_to_tm(seconds, tm); > + > + return rtc_valid_tm(tm); This is not necessary, tm is valid at that point (and the core will check anyway). > +} > + > +static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm) > +{ > + struct msc313_rtc *priv = dev_get_drvdata(dev); > + unsigned long seconds; > + u16 reg; > + > + seconds = rtc_tm_to_time64(tm); > + writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L); > + writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H); > + reg = readw(priv->rtc_base + REG_RTC_CTRL); > + writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL); > + > + /* need to check carefully if we want to clear REG_RTC_LOAD_VAL_H for customer*/ > + while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT) > + udelay(1); > + writew(0, priv->rtc_base + REG_RTC_LOAD_VAL_H); Why is that necessary? The comment is not super useful here. > + > + return 0; > +} > + > +static const struct rtc_class_ops msc313_rtc_ops = { > + .read_time = msc313_rtc_read_time, > + .set_time = msc313_rtc_set_time, > + .read_alarm = msc313_rtc_read_alarm, > + .set_alarm = msc313_rtc_set_alarm, > + .alarm_irq_enable = msc313_rtc_alarm_irq_enable, > +}; > + > +static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id) > +{ > + struct msc313_rtc *priv = dev_get_drvdata(dev_id); > + u16 reg; > + > + reg = readw_relaxed(priv->rtc_base + REG_RTC_CTRL); > + reg |= INT_CLEAR_BIT; > + reg &= ~INT_FORCE_BIT; > + writew_relaxed(reg, priv->rtc_base + REG_RTC_CTRL); > + I'm not convinced the _relaxed functions are doing the right thing here. Also, shouldn't you check the alarm actually fired? > + rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF); > + > + return IRQ_HANDLED; > +} > + > +static int msc313_rtc_remove(struct platform_device *pdev) > +{ > + struct msc313_rtc *priv = platform_get_drvdata(pdev); > + > + clk_disable_unprepare(priv->clk); With a nice devm_add_action_or_reset() in the probe, you can remove the need for msc313_rtc_remove(). > + > + return 0; > +} > + > +static int msc313_rtc_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct msc313_rtc *priv; > + int ret; > + int irq; > + unsigned long rate; > + u16 reg; > + > + priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + priv->rtc_base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(priv->rtc_base)) > + return PTR_ERR(priv->rtc_base); > + > + irq = platform_get_irq(pdev, 0); > + if (irq < 0) > + return -EINVAL; > + > + ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED, > + dev_name(&pdev->dev), &pdev->dev); > + if (ret) { > + dev_err(dev, "Unable to request irq\n"); > + return ret; > + } > + > + priv->clk = devm_clk_get(dev, NULL); > + if (IS_ERR(priv->clk)) { > + dev_err(dev, "No input reference clock\n"); > + return PTR_ERR(priv->clk); > + } > + > + ret = clk_prepare_enable(priv->clk); > + if (ret) { > + dev_err(dev, "Failed to enable the reference clock, %d\n", ret); > + return ret; > + } > + > + rate = clk_get_rate(priv->clk); > + > + reg = readw(priv->rtc_base + REG_RTC_CTRL); > + if (!(reg & SOFT_RSTZ_BIT)) { > + reg |= SOFT_RSTZ_BIT; > + writew(reg, priv->rtc_base + REG_RTC_CTRL); > + } What is the meaning of this bit? I would think it is better to use that to know whether the RTC holds the correct time instead of killing the info here. > + > + writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L); > + writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H); > + > + reg |= CNT_EN_BIT; > + writew(reg, priv->rtc_base + REG_RTC_CTRL); > + > + platform_set_drvdata(pdev, priv); > + > + priv->rtc_dev = devm_rtc_device_register(dev, dev_name(dev), &msc313_rtc_ops, THIS_MODULE); > + if (IS_ERR(priv->rtc_dev)) { > + dev_err(dev, "Failed to register rtc device\n"); > + return PTR_ERR(priv->rtc_dev); > + } Please switch to devm_rtc_allocate_device and devm_rtc_register_device. Also drop the error message, it is not necessary. You must also set the RTC range. To help you, you can use: https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/rtc-tools.git/tree/rtc-range.c then you must update the DT bindings as the RTC will support the start-year property You must also run rtctest and should include the results. -- Alexandre Belloni, co-owner and COO, Bootlin Embedded Linux and Kernel engineering https://bootlin.com _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC 2021-07-20 20:01 ` Alexandre Belloni @ 2021-07-21 16:56 ` Romain Perier 0 siblings, 0 replies; 7+ messages in thread From: Romain Perier @ 2021-07-21 16:56 UTC (permalink / raw) To: Alexandre Belloni Cc: Alessandro Zummo, Daniel Palmer, Rob Herring, linux-rtc, devicetree, Linux Kernel Mailing List, linux-arm-kernel Hello Alexandre, Le mar. 20 juil. 2021 à 22:01, Alexandre Belloni <alexandre.belloni@bootlin.com> a écrit : > > Hello Romain, > > On 20/07/2021 19:22:50+0200, Romain Perier wrote: > > From: Daniel Palmer <daniel@0x0f.com> > > > > This adds support for the RTC block on the Mstar MSC313e SoCs and newer. > > > > Signed-off-by: Daniel Palmer <daniel@0x0f.com> > > Co-developed-by: Romain Perier <romain.perier@gmail.com> > > Signed-off-by: Romain Perier <romain.perier@gmail.com> > > --- > > MAINTAINERS | 1 + > > drivers/rtc/Kconfig | 10 ++ > > drivers/rtc/Makefile | 1 + > > drivers/rtc/rtc-msc313.c | 246 +++++++++++++++++++++++++++++++++++++++ > > 4 files changed, 258 insertions(+) > > create mode 100644 drivers/rtc/rtc-msc313.c > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 6c8be735cc91..7e8d1a375e0d 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -2220,6 +2220,7 @@ F: arch/arm/boot/dts/mstar-* > > F: arch/arm/mach-mstar/ > > F: drivers/clk/mstar/ > > F: drivers/gpio/gpio-msc313.c > > +F: drivers/rtc/rtc-msc313.c > > F: drivers/watchdog/msc313e_wdt.c > > F: include/dt-bindings/clock/mstar-* > > F: include/dt-bindings/gpio/msc313-gpio.h > > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig > > index 12153d5801ce..67870b422bc5 100644 > > --- a/drivers/rtc/Kconfig > > +++ b/drivers/rtc/Kconfig > > @@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC > > This can also be built as a module. If so, the module will > > be named "rtc_wilco_ec". > > > > +config RTC_DRV_MSC313 > > + tristate "MStar MSC313 RTC" > > + depends on ARCH_MSTARV7 > > || COMPILE_TEST maybe ? Arf, I always forget this option. Ack, I will add it in v2. > > > + help > > + If you say yes here you get support for the Mstar MSC313e On-Chip > > + Real Time Clock. > > + > > + This driver can also be built as a module, if so, the module > > + will be called "rtc-msc313". > > + > > endif # RTC_CLASS > > > > +static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm) > > +{ > > + struct msc313_rtc *priv = dev_get_drvdata(dev); > > + u32 seconds; > > + u16 reg; > > + > > + reg = readw(priv->rtc_base + REG_RTC_CTRL); > > + writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL); > > + > > + /* Wait for HW latch done */ > > + while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT) > > + udelay(1); > > + > > + seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L) > > + | (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16); > > + > > + rtc_time64_to_tm(seconds, tm); > > + > > + return rtc_valid_tm(tm); > > This is not necessary, tm is valid at that point (and the core will > check anyway). ack. > > > +} > > + > > +static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm) > > +{ > > + struct msc313_rtc *priv = dev_get_drvdata(dev); > > + unsigned long seconds; > > + u16 reg; > > + > > + seconds = rtc_tm_to_time64(tm); > > + writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L); > > + writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H); > > + reg = readw(priv->rtc_base + REG_RTC_CTRL); > > + writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL); > > + > > + /* need to check carefully if we want to clear REG_RTC_LOAD_VAL_H for customer*/ > > + while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT) > > + udelay(1); > > + writew(0, priv->rtc_base + REG_RTC_LOAD_VAL_H); > > Why is that necessary? The comment is not super useful here. > > > + > > + return 0; > > +} > > + > > +static const struct rtc_class_ops msc313_rtc_ops = { > > + .read_time = msc313_rtc_read_time, > > + .set_time = msc313_rtc_set_time, > > + .read_alarm = msc313_rtc_read_alarm, > > + .set_alarm = msc313_rtc_set_alarm, > > + .alarm_irq_enable = msc313_rtc_alarm_irq_enable, > > +}; > > + > > +static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id) > > +{ > > + struct msc313_rtc *priv = dev_get_drvdata(dev_id); > > + u16 reg; > > + > > + reg = readw_relaxed(priv->rtc_base + REG_RTC_CTRL); > > + reg |= INT_CLEAR_BIT; > > + reg &= ~INT_FORCE_BIT; > > + writew_relaxed(reg, priv->rtc_base + REG_RTC_CTRL); > > + > > I'm not convinced the _relaxed functions are doing the right thing here. Good catch for the _relaxed, I did not pay attention during refactoring. > Also, shouldn't you check the alarm actually fired? You mean before set the flag "RTC_AF" ? This driver is mostly based on reverse engineering, even if we have some hardware info. I will try to find if it is possible (I mean, from the info I have). > > > + rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static int msc313_rtc_remove(struct platform_device *pdev) > > +{ > > + struct msc313_rtc *priv = platform_get_drvdata(pdev); > > + > > + clk_disable_unprepare(priv->clk); > > With a nice devm_add_action_or_reset() in the probe, you can remove the > need for msc313_rtc_remove(). devm_add_action_or_reset() you said, interesting I did not know this function. > > > + > > + return 0; > > +} > > + > > +static int msc313_rtc_probe(struct platform_device *pdev) > > +{ > > + struct device *dev = &pdev->dev; > > + struct msc313_rtc *priv; > > + int ret; > > + int irq; > > + unsigned long rate; > > + u16 reg; > > + > > + priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL); > > + if (!priv) > > + return -ENOMEM; > > + > > + priv->rtc_base = devm_platform_ioremap_resource(pdev, 0); > > + if (IS_ERR(priv->rtc_base)) > > + return PTR_ERR(priv->rtc_base); > > + > > + irq = platform_get_irq(pdev, 0); > > + if (irq < 0) > > + return -EINVAL; > > + > > + ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED, > > + dev_name(&pdev->dev), &pdev->dev); > > + if (ret) { > > + dev_err(dev, "Unable to request irq\n"); > > + return ret; > > + } > > + > > + priv->clk = devm_clk_get(dev, NULL); > > + if (IS_ERR(priv->clk)) { > > + dev_err(dev, "No input reference clock\n"); > > + return PTR_ERR(priv->clk); > > + } > > + > > + ret = clk_prepare_enable(priv->clk); > > + if (ret) { > > + dev_err(dev, "Failed to enable the reference clock, %d\n", ret); > > + return ret; > > + } > > + > > + rate = clk_get_rate(priv->clk); > > + > > + reg = readw(priv->rtc_base + REG_RTC_CTRL); > > + if (!(reg & SOFT_RSTZ_BIT)) { > > + reg |= SOFT_RSTZ_BIT; > > + writew(reg, priv->rtc_base + REG_RTC_CTRL); > > + } > > What is the meaning of this bit? I would think it is better to use that > to know whether the RTC holds the correct time instead of killing the > info here. > > > + > > + writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L); > > + writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H); > > + > > + reg |= CNT_EN_BIT; > > + writew(reg, priv->rtc_base + REG_RTC_CTRL); > > + > > + platform_set_drvdata(pdev, priv); > > + > > + priv->rtc_dev = devm_rtc_device_register(dev, dev_name(dev), &msc313_rtc_ops, THIS_MODULE); > > + if (IS_ERR(priv->rtc_dev)) { > > + dev_err(dev, "Failed to register rtc device\n"); > > + return PTR_ERR(priv->rtc_dev); > > + } > > Please switch to devm_rtc_allocate_device and devm_rtc_register_device. > Also drop the error message, it is not necessary. > > You must also set the RTC range. To help you, you can use: > https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/rtc-tools.git/tree/rtc-range.c > then you must update the DT bindings as the RTC will support the > start-year property > > You must also run rtctest and should include the results. Ack, I will do this in v2. Thanks! _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] ARM: dts: mstar: Add rtc device node 2021-07-20 17:22 [PATCH 0/3] Add RTC for MStar SoCs Romain Perier 2021-07-20 17:22 ` [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation Romain Perier 2021-07-20 17:22 ` [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC Romain Perier @ 2021-07-20 17:22 ` Romain Perier 2 siblings, 0 replies; 7+ messages in thread From: Romain Perier @ 2021-07-20 17:22 UTC (permalink / raw) To: Alessandro Zummo, Alexandre Belloni, Daniel Palmer, Rob Herring Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel This adds the definition of the rtc device node. The RTC being able to work with the oscillator at 12Mhz for now, it shares the same xtal than the watchdog. Signed-off-by: Romain Perier <romain.perier@gmail.com> --- arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi index 982dba9d28eb..1d4419aee67d 100644 --- a/arch/arm/boot/dts/mstar-v7.dtsi +++ b/arch/arm/boot/dts/mstar-v7.dtsi @@ -116,6 +116,13 @@ watchdog@6000 { clocks = <&xtal_div2>; }; + rtc@2400 { + compatible = "mstar,msc313-rtc"; + reg = <0x2400 0x40>; + clocks = <&xtal_div2>; + interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + }; + intc_fiq: interrupt-controller@201310 { compatible = "mstar,mst-intc"; reg = <0x201310 0x40>; -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-07-21 16:58 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-07-20 17:22 [PATCH 0/3] Add RTC for MStar SoCs Romain Perier 2021-07-20 17:22 ` [PATCH 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings documentation Romain Perier 2021-07-21 13:41 ` Rob Herring 2021-07-20 17:22 ` [PATCH 2/3] rtc: Add support for the MSTAR MSC313 RTC Romain Perier 2021-07-20 20:01 ` Alexandre Belloni 2021-07-21 16:56 ` Romain Perier 2021-07-20 17:22 ` [PATCH 3/3] ARM: dts: mstar: Add rtc device node Romain Perier
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).