Dne četrtek, 14. april 2022 ob 01:17:30 CEST je Samuel Holland napisal(a): > The sun6i RTC provides 32 bytes of general-purpose data registers. > They can be used to save data in the always-on RTC power domain. > The registers are writable via 32-bit MMIO accesses only. > > Expose them with a NVMEM provider so they can be used by other drivers. > > Signed-off-by: Samuel Holland <samuel@xxxxxxxxxxxx> Acked-by: Jernej Skrabec <jernej.skrabec@xxxxxxxxx> Best regards, Jernej > --- > > drivers/rtc/rtc-sun6i.c | 42 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c > index 5b3e4da63406..755aeb82a285 100644 > --- a/drivers/rtc/rtc-sun6i.c > +++ b/drivers/rtc/rtc-sun6i.c > @@ -71,6 +71,10 @@ > #define SUN6I_LOSC_OUT_GATING 0x0060 > #define SUN6I_LOSC_OUT_GATING_EN_OFFSET 0 > > +/* General-purpose data */ > +#define SUN6I_GP_DATA 0x0100 > +#define SUN6I_GP_DATA_SIZE 0x20 > + > /* > * Get date values > */ > @@ -662,6 +666,39 @@ static const struct rtc_class_ops sun6i_rtc_ops = { > .alarm_irq_enable = sun6i_rtc_alarm_irq_enable > }; > > +static int sun6i_rtc_nvmem_read(void *priv, unsigned int offset, void > *_val, size_t bytes) +{ > + struct sun6i_rtc_dev *chip = priv; > + u32 *val = _val; > + int i; > + > + for (i = 0; i < bytes / 4; ++i) > + val[i] = readl(chip->base + SUN6I_GP_DATA + offset + 4 * i); > + > + return 0; > +} > + > +static int sun6i_rtc_nvmem_write(void *priv, unsigned int offset, void > *_val, size_t bytes) +{ > + struct sun6i_rtc_dev *chip = priv; > + u32 *val = _val; > + int i; > + > + for (i = 0; i < bytes / 4; ++i) > + writel(val[i], chip->base + SUN6I_GP_DATA + offset + 4 * i); > + > + return 0; > +} > + > +static struct nvmem_config sun6i_rtc_nvmem_cfg = { > + .type = NVMEM_TYPE_BATTERY_BACKED, > + .reg_read = sun6i_rtc_nvmem_read, > + .reg_write = sun6i_rtc_nvmem_write, > + .size = SUN6I_GP_DATA_SIZE, > + .word_size = 4, > + .stride = 4, > +}; > + > #ifdef CONFIG_PM_SLEEP > /* Enable IRQ wake on suspend, to wake up from RTC. */ > static int sun6i_rtc_suspend(struct device *dev) > @@ -795,6 +832,11 @@ static int sun6i_rtc_probe(struct platform_device > *pdev) if (ret) > return ret; > > + sun6i_rtc_nvmem_cfg.priv = chip; > + ret = devm_rtc_nvmem_register(chip->rtc, &sun6i_rtc_nvmem_cfg); > + if (ret) > + return ret; > + > dev_info(&pdev->dev, "RTC enabled\n"); > > return 0;