linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] rtc: sun6i: Add NVMEM provider
@ 2021-04-19  1:45 Samuel Holland
  2021-04-30  9:02 ` Maxime Ripard
  0 siblings, 1 reply; 10+ messages in thread
From: Samuel Holland @ 2021-04-19  1:45 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Maxime Ripard, Chen-Yu Tsai,
	Jernej Skrabec
  Cc: linux-rtc, linux-arm-kernel, linux-sunxi, linux-kernel, Samuel Holland

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 the region as a NVMEM provider so it can be used by userspace and
other drivers.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 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 e75020ab8024..f4a5e7465148 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -69,6 +69,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
  */
@@ -641,6 +645,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,
+};
+
 /* Enable IRQ wake on suspend, to wake up from RTC. */
 static int sun6i_rtc_suspend(struct device *dev)
 {
@@ -728,6 +765,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;
-- 
2.26.3


_______________________________________________
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2021-04-19  1:45 [PATCH] rtc: sun6i: Add NVMEM provider Samuel Holland
@ 2021-04-30  9:02 ` Maxime Ripard
  2021-05-04 15:33   ` Alexandre Belloni
  2021-05-10  3:39   ` Samuel Holland
  0 siblings, 2 replies; 10+ messages in thread
From: Maxime Ripard @ 2021-04-30  9:02 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Alessandro Zummo, Alexandre Belloni, Chen-Yu Tsai,
	Jernej Skrabec, linux-rtc, linux-arm-kernel, linux-sunxi,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 692 bytes --]

Hi,

On Sun, Apr 18, 2021 at 08:45:49PM -0500, Samuel Holland wrote:
> 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 the region as a NVMEM provider so it can be used by userspace and
> other drivers.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

As far as I understood, you want to use those registers to implement
super-standby? If so, while it makes sense for the kernel to be able to
be able to write to those registers, I guess it would be a bit unwise to
allow the userspace to access it?

Maxime

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2021-04-30  9:02 ` Maxime Ripard
@ 2021-05-04 15:33   ` Alexandre Belloni
  2021-05-10  3:39   ` Samuel Holland
  1 sibling, 0 replies; 10+ messages in thread
From: Alexandre Belloni @ 2021-05-04 15:33 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Samuel Holland, Alessandro Zummo, Chen-Yu Tsai, Jernej Skrabec,
	linux-rtc, linux-arm-kernel, linux-sunxi, linux-kernel

On 30/04/2021 11:02:06+0200, Maxime Ripard wrote:
> Hi,
> 
> On Sun, Apr 18, 2021 at 08:45:49PM -0500, Samuel Holland wrote:
> > 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 the region as a NVMEM provider so it can be used by userspace and
> > other drivers.
> > 
> > Signed-off-by: Samuel Holland <samuel@sholland.org>
> 
> As far as I understood, you want to use those registers to implement
> super-standby? If so, while it makes sense for the kernel to be able to
> be able to write to those registers, I guess it would be a bit unwise to
> allow the userspace to access it?

I would think nvmem is still the proper subsystem. I guess maybe we
should have a version of __nvmem_device_get that would ensure exclusive
access to a cell, thus preventing userspace accessing it as long a the
kernel is using it.

-- 
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2021-04-30  9:02 ` Maxime Ripard
  2021-05-04 15:33   ` Alexandre Belloni
@ 2021-05-10  3:39   ` Samuel Holland
  2021-05-10  8:00     ` Alexandre Belloni
  2021-05-25  8:24     ` Maxime Ripard
  1 sibling, 2 replies; 10+ messages in thread
From: Samuel Holland @ 2021-05-10  3:39 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alessandro Zummo, Alexandre Belloni, Chen-Yu Tsai,
	Jernej Skrabec, linux-rtc, linux-arm-kernel, linux-sunxi,
	linux-kernel

On 4/30/21 4:02 AM, Maxime Ripard wrote:
> Hi,
> 
> On Sun, Apr 18, 2021 at 08:45:49PM -0500, Samuel Holland wrote:
>> 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 the region as a NVMEM provider so it can be used by userspace and
>> other drivers.
>>
>> Signed-off-by: Samuel Holland <samuel@sholland.org>
> 
> As far as I understood, you want to use those registers to implement
> super-standby? If so, while it makes sense for the kernel to be able to
> be able to write to those registers, I guess it would be a bit unwise to
> allow the userspace to access it?

I want the user to be able to pass information to the bootloader (to
select a boot device, e.g. reboot to FEL). I also want the user to be
able to read data stored to these registers by system firmware (e.g.
crust writes exception information there). It's not really related to
standby.

I would want to stack a nvmem-reboot-mode on top to give friendlier
names to some of the numbers, but I don't see a problem with root having
direct access to the registers. It's no different from /dev/nvram
providing access to the PC CMOS RAM.

Regards,
Samuel

_______________________________________________
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2021-05-10  3:39   ` Samuel Holland
@ 2021-05-10  8:00     ` Alexandre Belloni
  2021-05-25  8:24     ` Maxime Ripard
  1 sibling, 0 replies; 10+ messages in thread
From: Alexandre Belloni @ 2021-05-10  8:00 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Maxime Ripard, Alessandro Zummo, Chen-Yu Tsai, Jernej Skrabec,
	linux-rtc, linux-arm-kernel, linux-sunxi, linux-kernel

On 09/05/2021 22:39:30-0500, Samuel Holland wrote:
> On 4/30/21 4:02 AM, Maxime Ripard wrote:
> > Hi,
> > 
> > On Sun, Apr 18, 2021 at 08:45:49PM -0500, Samuel Holland wrote:
> >> 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 the region as a NVMEM provider so it can be used by userspace and
> >> other drivers.
> >>
> >> Signed-off-by: Samuel Holland <samuel@sholland.org>
> > 
> > As far as I understood, you want to use those registers to implement
> > super-standby? If so, while it makes sense for the kernel to be able to
> > be able to write to those registers, I guess it would be a bit unwise to
> > allow the userspace to access it?
> 
> I want the user to be able to pass information to the bootloader (to
> select a boot device, e.g. reboot to FEL). I also want the user to be
> able to read data stored to these registers by system firmware (e.g.
> crust writes exception information there). It's not really related to
> standby.
> 
> I would want to stack a nvmem-reboot-mode on top to give friendlier
> names to some of the numbers, but I don't see a problem with root having
> direct access to the registers. It's no different from /dev/nvram
> providing access to the PC CMOS RAM.
> 

(which is deprecated in favor of nvmem)


-- 
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2021-05-10  3:39   ` Samuel Holland
  2021-05-10  8:00     ` Alexandre Belloni
@ 2021-05-25  8:24     ` Maxime Ripard
  2021-05-27  4:09       ` Samuel Holland
  1 sibling, 1 reply; 10+ messages in thread
From: Maxime Ripard @ 2021-05-25  8:24 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Alessandro Zummo, Alexandre Belloni, Chen-Yu Tsai,
	Jernej Skrabec, linux-rtc, linux-arm-kernel, linux-sunxi,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1972 bytes --]

On Sun, May 09, 2021 at 10:39:30PM -0500, Samuel Holland wrote:
> On 4/30/21 4:02 AM, Maxime Ripard wrote:
> > Hi,
> > 
> > On Sun, Apr 18, 2021 at 08:45:49PM -0500, Samuel Holland wrote:
> >> 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 the region as a NVMEM provider so it can be used by userspace and
> >> other drivers.
> >>
> >> Signed-off-by: Samuel Holland <samuel@sholland.org>
> > 
> > As far as I understood, you want to use those registers to implement
> > super-standby? If so, while it makes sense for the kernel to be able to
> > be able to write to those registers, I guess it would be a bit unwise to
> > allow the userspace to access it?
> 
> I want the user to be able to pass information to the bootloader (to
> select a boot device, e.g. reboot to FEL). I also want the user to be
> able to read data stored to these registers by system firmware (e.g.
> crust writes exception information there). It's not really related to
> standby.

What information do you want to provide? This looks like punching
through the abstraction layer provided by the kernel. This is also an
issue since it ties an ABI to the use of crust: if there's another user
for those RTC registers at some point, the userspace would have no way
to tell whether or not crust is being used and might get complete
garbage (compared to what crust usually provides) instead.

> I would want to stack a nvmem-reboot-mode on top to give friendlier
> names to some of the numbers, but I don't see a problem with root having
> direct access to the registers. It's no different from /dev/nvram
> providing access to the PC CMOS RAM.

And those solutions have issues too. efivarfs for example can totally
brick the system it runs on if the user has an unfortunate rm -rf.

Maxime

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2021-05-25  8:24     ` Maxime Ripard
@ 2021-05-27  4:09       ` Samuel Holland
  0 siblings, 0 replies; 10+ messages in thread
From: Samuel Holland @ 2021-05-27  4:09 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alessandro Zummo, Alexandre Belloni, Chen-Yu Tsai,
	Jernej Skrabec, linux-rtc, linux-arm-kernel, linux-sunxi,
	linux-kernel


On 5/25/21 3:24 AM, Maxime Ripard wrote:
> On Sun, May 09, 2021 at 10:39:30PM -0500, Samuel Holland wrote:
>> On 4/30/21 4:02 AM, Maxime Ripard wrote:
>>> Hi,
>>>
>>> On Sun, Apr 18, 2021 at 08:45:49PM -0500, Samuel Holland wrote:
>>>> 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 the region as a NVMEM provider so it can be used by userspace and
>>>> other drivers.
>>>>
>>>> Signed-off-by: Samuel Holland <samuel@sholland.org>
>>>
>>> As far as I understood, you want to use those registers to implement
>>> super-standby? If so, while it makes sense for the kernel to be able to
>>> be able to write to those registers, I guess it would be a bit unwise to
>>> allow the userspace to access it?
>>
>> I want the user to be able to pass information to the bootloader (to
>> select a boot device, e.g. reboot to FEL). I also want the user to be
>> able to read data stored to these registers by system firmware (e.g.
>> crust writes exception information there). It's not really related to
>> standby.
> 
> What information do you want to provide? This looks like punching
> through the abstraction layer provided by the kernel.

I don't see how registering an NVMEM provider is punching through any
abstraction layer. NVMEM _is_ the relevant abstraction layer provided by
the kernel. What else would you suggest I use?

> This is also an issue since it ties an ABI to the use of crust: if
> there's another user for those RTC registers at some point, the
> userspace would have no way to tell whether or not crust is being
> used and might get complete garbage (compared to what crust usually
> provides) instead.

If the user chooses to interact with the NVMEM via sysfs, then the user
has to deal with the consequences. This is equivalent to the user's
responsibility when using, for example, /dev/mem or libusb.

For the purpose of providing the abstraction, the actual data stored
there is irrelevant. And if you want to partition up the registers to
reserve for different users, that is what NVMEM cells accomplish.

>> I would want to stack a nvmem-reboot-mode on top to give friendlier
>> names to some of the numbers, but I don't see a problem with root having
>> direct access to the registers. It's no different from /dev/nvram
>> providing access to the PC CMOS RAM.
> 
> And those solutions have issues too. efivarfs for example can totally
> brick the system it runs on if the user has an unfortunate rm -rf.

The sun6i RTC, like PC CMOS, is battery-backed RAM. efivarfs writes to
flash. The magnitude of any such "danger" is vastly different between
the two. (And I think we can do better than vendors who release those
brickable EFI implementations.)

Regards,
Samuel

_______________________________________________
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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2022-04-13 23:17 Samuel Holland
  2022-04-15 18:26 ` Jernej Škrabec
@ 2022-05-17 20:49 ` alexandre.belloni
  1 sibling, 0 replies; 10+ messages in thread
From: alexandre.belloni @ 2022-05-17 20:49 UTC (permalink / raw)
  To: Samuel Holland, Alessandro Zummo, Chen-Yu Tsai, Jernej Skrabec
  Cc: Alexandre Belloni, linux-kernel, linux-arm-kernel, linux-sunxi,
	linux-rtc

From: Alexandre Belloni <alexandre.belloni@bootlin.com>

On Wed, 13 Apr 2022 18:17:30 -0500, Samuel Holland wrote:
> 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.
> 
> 
> [...]

Applied, thanks!

[1/1] rtc: sun6i: Add NVMEM provider
      commit: 581d6d8f483696ff164f52a71beb43a87b718592

Best regards,
-- 
Alexandre Belloni <alexandre.belloni@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] 10+ messages in thread

* Re: [PATCH] rtc: sun6i: Add NVMEM provider
  2022-04-13 23:17 Samuel Holland
@ 2022-04-15 18:26 ` Jernej Škrabec
  2022-05-17 20:49 ` alexandre.belloni
  1 sibling, 0 replies; 10+ messages in thread
From: Jernej Škrabec @ 2022-04-15 18:26 UTC (permalink / raw)
  To: Chen-Yu Tsai, Alessandro Zummo, Alexandre Belloni, Samuel Holland
  Cc: Samuel Holland, linux-arm-kernel, linux-kernel, linux-rtc, linux-sunxi

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@sholland.org>

Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>

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;





_______________________________________________
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] 10+ messages in thread

* [PATCH] rtc: sun6i: Add NVMEM provider
@ 2022-04-13 23:17 Samuel Holland
  2022-04-15 18:26 ` Jernej Škrabec
  2022-05-17 20:49 ` alexandre.belloni
  0 siblings, 2 replies; 10+ messages in thread
From: Samuel Holland @ 2022-04-13 23:17 UTC (permalink / raw)
  To: Chen-Yu Tsai, Jernej Skrabec, Alessandro Zummo, Alexandre Belloni
  Cc: Samuel Holland, linux-arm-kernel, linux-kernel, linux-rtc, linux-sunxi

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@sholland.org>
---

 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;
-- 
2.35.1


_______________________________________________
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] 10+ messages in thread

end of thread, other threads:[~2022-05-17 20:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-19  1:45 [PATCH] rtc: sun6i: Add NVMEM provider Samuel Holland
2021-04-30  9:02 ` Maxime Ripard
2021-05-04 15:33   ` Alexandre Belloni
2021-05-10  3:39   ` Samuel Holland
2021-05-10  8:00     ` Alexandre Belloni
2021-05-25  8:24     ` Maxime Ripard
2021-05-27  4:09       ` Samuel Holland
2022-04-13 23:17 Samuel Holland
2022-04-15 18:26 ` Jernej Škrabec
2022-05-17 20:49 ` alexandre.belloni

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).