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.
The rtctest (from selftests) has been passed on this driver, with the
following output:
$ rtctest
TAP version 13
1..7
# Starting 7 tests from 2 test cases.
# RUN rtc.date_read ...
# rtctest.c:47:date_read:Current RTC date/time is 01/01/1970 00:02:03.
# OK rtc.date_read
ok 1 rtc.date_read
# RUN rtc.uie_read ...
# OK rtc.uie_read
ok 2 rtc.uie_read
# RUN rtc.uie_select ...
# OK rtc.uie_select
ok 3 rtc.uie_select
# RUN rtc.alarm_alm_set ...
# rtctest.c:136:alarm_alm_set:Alarm time now set to 00:02:12.
# rtctest.c:156:alarm_alm_set:data: 1a0
# OK rtc.alarm_alm_set
ok 4 rtc.alarm_alm_set
# RUN rtc.alarm_wkalm_set ...
# rtctest.c:192:alarm_wkalm_set:Alarm time now set to 01/01/1970 00:02:15.
# OK rtc.alarm_wkalm_set
ok 5 rtc.alarm_wkalm_set
# RUN rtc.alarm_alm_set_minute ...
# rtctest.c:238:alarm_alm_set_minute:Alarm time now set to 00:03:00.
# rtctest.c:258:alarm_alm_set_minute:data: 1a0
# OK rtc.alarm_alm_set_minute
ok 6 [ 180.545015] random: fast init done
rtc.alarm_alm_set_minute
# RUN rtc.alarm_wkalm_set_minute ...
# rtctest.c:294:alarm_wkalm_set_minute:Alarm time now set to 01/01/1970 00:04:00.
# OK rtc.alarm_wkalm_set_minute
ok 7 rtc.alarm_wkalm_set_minute
# PASSED: 7 / 7 tests passed.
# Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0
Changes since v1:
- Fixed the DT bindings documentation and fixed dt_binding_check (an
include was missing)
- Added || COMPILE_TEST to kconfig
- Removed rtc_valid_tm from msc313_rtc_read_time()
- Removed the last write of the msc313_rtc_set_time() function (not
required) and improved comments
- Replaced the relaxed io by normal io in msc313_rtc_interrupt()
- Added checks to be sure that the alarm fired in msc313_rtc_interrupt()
- Removed msc313_rtc_remove() (replaced by devm_add_action_or_reset)
- Removed unnecessary software reset of the IP in the probe function
(the soft reset is never executed, it is a mistake from the initial
refactoring)
- Switched to devm_rtc_allocate_device() and devm_rtc_register_device(),
and dropped the error message related to the rtc device allocation
- Added an RTC range by setting .range_min and .range_max
- Added the "start-year" property to the DT bindings 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 | 49 ++++
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, 314 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
create mode 100644 drivers/rtc/rtc-msc313.c
--
2.30.2
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 <[email protected]>
---
.../bindings/rtc/mstar,msc313-rtc.yaml | 49 +++++++++++++++++++
1 file changed, 49 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..62bc12b1feb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
@@ -0,0 +1,49 @@
+# 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 <[email protected]>
+ - Romain Perier <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - mstar,msc313-rtc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ start-year: true
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ 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
From: Daniel Palmer <[email protected]>
This adds support for the RTC block on the Mstar MSC313e SoCs and newer.
Signed-off-by: Daniel Palmer <[email protected]>
Co-developed-by: Romain Perier <[email protected]>
Signed-off-by: Romain Perier <[email protected]>
---
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 c9467d2839f5..bff16c7bafb8 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..9ce4baab5fcf 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
+ 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..f7b9fd2807cb
--- /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_STATUS_INT 0x1C
+#define REG_RTC_CNT_VAL_L 0x20
+#define REG_RTC_CNT_VAL_H 0x24
+
+/* Control bits for REG_RTC_CTRL */
+#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)
+
+/* Control bits for REG_RTC_STATUS_INT */
+#define RAW_INT_BIT BIT(0)
+#define ALM_INT_BIT BIT(1)
+
+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 0;
+}
+
+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);
+
+ /* Enable load for loading value into internal RTC counter */
+ reg = readw(priv->rtc_base + REG_RTC_CTRL);
+ writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+ /* Wait for HW latch done */
+ while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
+ udelay(1);
+ 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(priv->rtc_base + REG_RTC_STATUS_INT);
+ if (!(reg & ALM_INT_BIT))
+ return IRQ_NONE;
+
+ reg = readw(priv->rtc_base + REG_RTC_CTRL);
+ reg |= INT_CLEAR_BIT;
+ reg &= ~INT_FORCE_BIT;
+ writew(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_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;
+
+ priv->rtc_dev = devm_rtc_allocate_device(dev);
+ if (IS_ERR(priv->rtc_dev))
+ return PTR_ERR(priv->rtc_dev);
+
+ priv->rtc_dev->ops = &msc313_rtc_ops;
+ priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;
+ priv->rtc_dev->range_max = U32_MAX - 1; /* 2106-02-07 06:28:14 */
+
+ ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
+ dev_name(&pdev->dev), &pdev->dev);
+ if (ret) {
+ dev_err(dev, "Could not 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;
+ }
+
+ ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
+ if (ret)
+ return ret;
+
+ rate = clk_get_rate(priv->clk);
+ writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
+ writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
+
+ reg = readw(priv->rtc_base + REG_RTC_CTRL);
+ reg |= CNT_EN_BIT;
+ writew(reg, priv->rtc_base + REG_RTC_CTRL);
+
+ platform_set_drvdata(pdev, priv);
+
+ return devm_rtc_register_device(priv->rtc_dev);
+}
+
+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 = {
+ .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 <[email protected]>");
+MODULE_AUTHOR("Romain Perier <[email protected]>");
+MODULE_DESCRIPTION("MStar RTC Driver");
+MODULE_LICENSE("GPL v2");
--
2.30.2
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 <[email protected]>
---
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
Hi Romain,
On Mon, 2 Aug 2021 at 01:09, Romain Perier <[email protected]> wrote:
> +++ b/arch/arm/boot/dts/mstar-v7.dtsi
> @@ -116,6 +116,13 @@ watchdog@6000 {
> clocks = <&xtal_div2>;
> };
>
> + rtc@2400 {
I think the rtc should be before the watchdog as the address is lower.
I think maybe this got flipped around during cherry-picking.
I can flip it around when I pull this into an mstar dts for 5.15
branch so you don't need to fix it and send a v3 assuming everything
else is ok.
Thanks,
Daniel
Hello,
On 01/08/2021 18:09:20+0200, Romain Perier wrote:
> +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;
> +
> + priv->rtc_dev = devm_rtc_allocate_device(dev);
> + if (IS_ERR(priv->rtc_dev))
> + return PTR_ERR(priv->rtc_dev);
> +
> + priv->rtc_dev->ops = &msc313_rtc_ops;
> + priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;
I'm pretty sure this doesn't fit in this RTC registers, you should
probably leave range_min to 0 (i.e. not set it at all).
> + priv->rtc_dev->range_max = U32_MAX - 1; /* 2106-02-07 06:28:14 */
I guess this one should be U32_MAX
> +
> + ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
> + dev_name(&pdev->dev), &pdev->dev);
> + if (ret) {
> + dev_err(dev, "Could not 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;
> + }
> +
> + ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
> + if (ret)
> + return ret;
> +
> + rate = clk_get_rate(priv->clk);
> + writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
> + writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
> +
> + reg = readw(priv->rtc_base + REG_RTC_CTRL);
> + reg |= CNT_EN_BIT;
> + writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +
If on POR, CNT_EN_BIT is not set, then it would be nice to use that to
know whether the RTC is properly set. You can then check CNT_EN_BIT in
.read_time and return -EINVAL if it is not set. Then you can set the bit
in .set_time. It is anyway useless to let the RTC running if it is not
set.
> + platform_set_drvdata(pdev, priv);
> +
> + return devm_rtc_register_device(priv->rtc_dev);
> +}
> +
> +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 = {
> + .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 <[email protected]>");
> +MODULE_AUTHOR("Romain Perier <[email protected]>");
> +MODULE_DESCRIPTION("MStar RTC Driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.30.2
>
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Sun, Aug 01, 2021 at 06:09:19PM +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 <[email protected]>
> ---
> .../bindings/rtc/mstar,msc313-rtc.yaml | 49 +++++++++++++++++++
> 1 file changed, 49 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..62bc12b1feb6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> @@ -0,0 +1,49 @@
> +# SPDX-License-Identifier: GPL-2.0
As checkpatch.pl will tell you, should be dual licensed.
> +%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 <[email protected]>
> + - Romain Perier <[email protected]>
> +
> +properties:
> + compatible:
> + enum:
> + - mstar,msc313-rtc
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + start-year: true
> +
> + clocks:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - clocks
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + 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
>
>
Hi,
As I need to send a v3, I can fix it, no worries.
Cheers,
Romain
Le lun. 2 août 2021 à 12:40, Daniel Palmer <[email protected]> a écrit :
>
> Hi Romain,
>
> On Mon, 2 Aug 2021 at 01:09, Romain Perier <[email protected]> wrote:
> > +++ b/arch/arm/boot/dts/mstar-v7.dtsi
> > @@ -116,6 +116,13 @@ watchdog@6000 {
> > clocks = <&xtal_div2>;
> > };
> >
> > + rtc@2400 {
>
> I think the rtc should be before the watchdog as the address is lower.
> I think maybe this got flipped around during cherry-picking.
> I can flip it around when I pull this into an mstar dts for 5.15
> branch so you don't need to fix it and send a v3 assuming everything
> else is ok.
>
> Thanks,
>
> Daniel
Hi,
Le ven. 6 août 2021 à 23:37, Rob Herring <[email protected]> a écrit :
>
> On Sun, Aug 01, 2021 at 06:09:19PM +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 <[email protected]>
> > ---
> > .../bindings/rtc/mstar,msc313-rtc.yaml | 49 +++++++++++++++++++
> > 1 file changed, 49 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..62bc12b1feb6
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> > @@ -0,0 +1,49 @@
> > +# SPDX-License-Identifier: GPL-2.0
>
> As checkpatch.pl will tell you, should be dual licensed.
Arf, sorry for this, I have completely missed it (it will be fixed in v3).
Romain
Hello,
Le ven. 6 août 2021 à 21:38, Alexandre Belloni
<[email protected]> a écrit :
>
> Hello,
>
> On 01/08/2021 18:09:20+0200, Romain Perier wrote:
> > +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;
> > +
> > + priv->rtc_dev = devm_rtc_allocate_device(dev);
> > + if (IS_ERR(priv->rtc_dev))
> > + return PTR_ERR(priv->rtc_dev);
> > +
> > + priv->rtc_dev->ops = &msc313_rtc_ops;
> > + priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;
>
> I'm pretty sure this doesn't fit in this RTC registers, you should
> probably leave range_min to 0 (i.e. not set it at all).
ack
>
> > + priv->rtc_dev->range_max = U32_MAX - 1; /* 2106-02-07 06:28:14 */
>
> I guess this one should be U32_MAX
ack
> > +
> > + ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
> > + dev_name(&pdev->dev), &pdev->dev);
> > + if (ret) {
> > + dev_err(dev, "Could not 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;
> > + }
> > +
> > + ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
> > + if (ret)
> > + return ret;
> > +
> > + rate = clk_get_rate(priv->clk);
> > + writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
> > + writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
> > +
> > + reg = readw(priv->rtc_base + REG_RTC_CTRL);
> > + reg |= CNT_EN_BIT;
> > + writew(reg, priv->rtc_base + REG_RTC_CTRL);
> > +
>
> If on POR, CNT_EN_BIT is not set, then it would be nice to use that to
> know whether the RTC is properly set. You can then check CNT_EN_BIT in
> .read_time and return -EINVAL if it is not set. Then you can set the bit
> in .set_time. It is anyway useless to let the RTC running if it is not
> set.
Yeah, this is to be sure that the RTC is alive with a valid value
(which makes sense).
Ok I will fix everything in v3, then.
Romain