diff mbox series

[v2,1/2] dt-bindings: nvmem: Add apple,efuses

Message ID 20220306121816.70537-1-sven@svenpeter.dev
State Not Applicable, archived
Headers show
Series [v2,1/2] dt-bindings: nvmem: Add apple,efuses | expand

Checks

Context Check Description
robh/patch-applied success
robh/checkpatch success
robh/dtbs-check success
robh/dt-meta-schema success

Commit Message

Sven Peter March 6, 2022, 12:18 p.m. UTC
Apple SoCs come with eFuses used to store factory-programmed data
such as calibration settings for the PCIe and Type-C PHY.

Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
v1 -> v2:
  - fixed indentation issue pointed out by Krzysztof Kozlowski

 .../bindings/nvmem/apple,efuses.yaml          | 50 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/apple,efuses.yaml

Comments

Krzysztof Kozlowski March 6, 2022, 12:24 p.m. UTC | #1
On 06/03/2022 13:18, Sven Peter wrote:
> Apple SoCs come with eFuses used to store factory-programmed data
> such as calibration settings for the PCIe and Type-C PHY.
> 
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
> v1 -> v2:
>   - fixed indentation issue pointed out by Krzysztof Kozlowski
> 
>  .../bindings/nvmem/apple,efuses.yaml          | 50 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 51 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>


Best regards,
Krzysztof
Krzysztof Kozlowski March 6, 2022, 12:25 p.m. UTC | #2
On 06/03/2022 13:18, Sven Peter wrote:
> Apple SoCs contain eFuses used to store factory-programmed data such
> as calibration values for the PCIe or the Type-C PHY. They are organized
> as 32bit values exposed as MMIO.
> 
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
> v1 -> v2:
>   - fixed sparse warning about __iomem by introducing
>     struct apple_efuses_priv as done in other nvmem drivers
>   - make sure the driver actually works as a module by
>     setting .owner to THIS_MODULE and adding MODULE_DEVICE_TABLE
>     pointed out by Joey Gouly
> 
>  MAINTAINERS                  |  1 +
>  drivers/nvmem/Kconfig        | 12 ++++++
>  drivers/nvmem/Makefile       |  2 +
>  drivers/nvmem/apple-efuses.c | 82 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 97 insertions(+)
>  create mode 100644 drivers/nvmem/apple-efuses.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f70d8525cbd4..e3e973a3f651 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1781,6 +1781,7 @@ F:	drivers/i2c/busses/i2c-pasemi-core.c
>  F:	drivers/i2c/busses/i2c-pasemi-platform.c
>  F:	drivers/irqchip/irq-apple-aic.c
>  F:	drivers/mailbox/apple-mailbox.c
> +F:	drivers/nvmem/apple-efuses.c
>  F:	drivers/pinctrl/pinctrl-apple-gpio.c
>  F:	drivers/soc/apple/*
>  F:	drivers/watchdog/apple_wdt.c
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index da414617a54d..bba29d1aec96 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -300,4 +300,16 @@ config NVMEM_BRCM_NVRAM
>  	  This driver provides support for Broadcom's NVRAM that can be accessed
>  	  using I/O mapping.
>  
> +config NVMEM_APPLE_EFUSES
> +	tristate "Apple eFuse support"
> +	depends on ARCH_APPLE || COMPILE_TEST
> +	default ARCH_APPLE
> +	help
> +	  Say y here to enable support for reading eFuses on Apple SoCs
> +	  such as the M1. These are e.g. used to store factory programmed
> +	  calibration data required for the PCIe or the USB-C PHY.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called nvmem-apple-efuses.
> +
>  endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index dcbbde35b6a8..1a8e54691d3e 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o
>  nvmem-rmem-y			:= rmem.o
>  obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o
>  nvmem_brcm_nvram-y		:= brcm_nvram.o
> +obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o
> +nvmem-apple-efuses-y 		:= apple-efuses.o
> diff --git a/drivers/nvmem/apple-efuses.c b/drivers/nvmem/apple-efuses.c
> new file mode 100644
> index 000000000000..dd5576ec5408
> --- /dev/null
> +++ b/drivers/nvmem/apple-efuses.c
> @@ -0,0 +1,82 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Apple SoC eFuse driver
> + *
> + * Copyright (C) The Asahi Linux Contributors
> + */
> +
> +#include <linux/io.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/platform_device.h>
> +
> +struct apple_efuses_priv {
> +	void __iomem *fuses;
> +};
> +
> +static int apple_efuses_read(void *context, unsigned int offset, void *val,
> +			     size_t bytes)
> +{
> +	struct apple_efuses_priv *priv = context;
> +	u32 *dst = val;
> +
> +	while (bytes >= sizeof(u32)) {
> +		*dst++ = readl_relaxed(priv->fuses + offset);
> +		bytes -= sizeof(u32);
> +		offset += sizeof(u32);
> +	}
> +
> +	return 0;
> +}
> +
> +static int apple_efuses_probe(struct platform_device *pdev)
> +{
> +	struct apple_efuses_priv *priv;
> +	struct resource *res;
> +	struct nvmem_config config = {
> +		.dev = &pdev->dev,
> +		.read_only = true,
> +		.reg_read = apple_efuses_read,
> +		.stride = sizeof(u32),
> +		.word_size = sizeof(u32),
> +		.name = "apple_efuses_nvmem",
> +		.id = NVMEM_DEVID_AUTO,
> +		.owner = THIS_MODULE,
> +		.root_only = true,
> +	};
> +
> +	priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->fuses = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(priv->fuses))
> +		return PTR_ERR(priv->fuses);
> +
> +	config.priv = priv;
> +	config.size = resource_size(res);
> +
> +	return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config));
> +}
> +
> +static const struct of_device_id apple_efuses_of_match[] = {
> +	{ .compatible = "apple,efuses", },
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(of, apple_efuses_of_match);
> +
> +static struct platform_driver apple_efuses_driver = {
> +	.driver = {
> +		.name = "apple_efuses",
> +		.of_match_table = apple_efuses_of_match,
> +		.owner = THIS_MODULE,

You wrote it also in changelog, but why do you need it? Doesn't core set
it? Coccinelle should complain about this as well.

Best regards,
Krzysztof
Sven Peter March 7, 2022, 9:08 a.m. UTC | #3
On Sun, Mar 6, 2022, at 13:25, Krzysztof Kozlowski wrote:
> On 06/03/2022 13:18, Sven Peter wrote:
>> Apple SoCs contain eFuses used to store factory-programmed data such
>> as calibration values for the PCIe or the Type-C PHY. They are organized
>> as 32bit values exposed as MMIO.
>> 
>> Signed-off-by: Sven Peter <sven@svenpeter.dev>
>> ---
>> v1 -> v2:
>>   - fixed sparse warning about __iomem by introducing
>>     struct apple_efuses_priv as done in other nvmem drivers
>>   - make sure the driver actually works as a module by
>>     setting .owner to THIS_MODULE and adding MODULE_DEVICE_TABLE
>>     pointed out by Joey Gouly
>> 
>>  MAINTAINERS                  |  1 +
>>  drivers/nvmem/Kconfig        | 12 ++++++
>>  drivers/nvmem/Makefile       |  2 +
>>  drivers/nvmem/apple-efuses.c | 82 ++++++++++++++++++++++++++++++++++++
>>  4 files changed, 97 insertions(+)
>>  create mode 100644 drivers/nvmem/apple-efuses.c
>> 
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index f70d8525cbd4..e3e973a3f651 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1781,6 +1781,7 @@ F:	drivers/i2c/busses/i2c-pasemi-core.c
>>  F:	drivers/i2c/busses/i2c-pasemi-platform.c
>>  F:	drivers/irqchip/irq-apple-aic.c
>>  F:	drivers/mailbox/apple-mailbox.c
>> +F:	drivers/nvmem/apple-efuses.c
>>  F:	drivers/pinctrl/pinctrl-apple-gpio.c
>>  F:	drivers/soc/apple/*
>>  F:	drivers/watchdog/apple_wdt.c
>> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
>> index da414617a54d..bba29d1aec96 100644
>> --- a/drivers/nvmem/Kconfig
>> +++ b/drivers/nvmem/Kconfig
>> @@ -300,4 +300,16 @@ config NVMEM_BRCM_NVRAM
>>  	  This driver provides support for Broadcom's NVRAM that can be accessed
>>  	  using I/O mapping.
>>  
>> +config NVMEM_APPLE_EFUSES
>> +	tristate "Apple eFuse support"
>> +	depends on ARCH_APPLE || COMPILE_TEST
>> +	default ARCH_APPLE
>> +	help
>> +	  Say y here to enable support for reading eFuses on Apple SoCs
>> +	  such as the M1. These are e.g. used to store factory programmed
>> +	  calibration data required for the PCIe or the USB-C PHY.
>> +
>> +	  This driver can also be built as a module. If so, the module will
>> +	  be called nvmem-apple-efuses.
>> +
>>  endif
>> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
>> index dcbbde35b6a8..1a8e54691d3e 100644
>> --- a/drivers/nvmem/Makefile
>> +++ b/drivers/nvmem/Makefile
>> @@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o
>>  nvmem-rmem-y			:= rmem.o
>>  obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o
>>  nvmem_brcm_nvram-y		:= brcm_nvram.o
>> +obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o
>> +nvmem-apple-efuses-y 		:= apple-efuses.o
>> diff --git a/drivers/nvmem/apple-efuses.c b/drivers/nvmem/apple-efuses.c
>> new file mode 100644
>> index 000000000000..dd5576ec5408
>> --- /dev/null
>> +++ b/drivers/nvmem/apple-efuses.c
>> @@ -0,0 +1,82 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Apple SoC eFuse driver
>> + *
>> + * Copyright (C) The Asahi Linux Contributors
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/mod_devicetable.h>
>> +#include <linux/module.h>
>> +#include <linux/nvmem-provider.h>
>> +#include <linux/platform_device.h>
>> +
>> +struct apple_efuses_priv {
>> +	void __iomem *fuses;
>> +};
>> +
>> +static int apple_efuses_read(void *context, unsigned int offset, void *val,
>> +			     size_t bytes)
>> +{
>> +	struct apple_efuses_priv *priv = context;
>> +	u32 *dst = val;
>> +
>> +	while (bytes >= sizeof(u32)) {
>> +		*dst++ = readl_relaxed(priv->fuses + offset);
>> +		bytes -= sizeof(u32);
>> +		offset += sizeof(u32);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int apple_efuses_probe(struct platform_device *pdev)
>> +{
>> +	struct apple_efuses_priv *priv;
>> +	struct resource *res;
>> +	struct nvmem_config config = {
>> +		.dev = &pdev->dev,
>> +		.read_only = true,
>> +		.reg_read = apple_efuses_read,
>> +		.stride = sizeof(u32),
>> +		.word_size = sizeof(u32),
>> +		.name = "apple_efuses_nvmem",
>> +		.id = NVMEM_DEVID_AUTO,
>> +		.owner = THIS_MODULE,
>> +		.root_only = true,
>> +	};
>> +
>> +	priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);
>> +	if (!priv)
>> +		return -ENOMEM;
>> +
>> +	priv->fuses = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
>> +	if (IS_ERR(priv->fuses))
>> +		return PTR_ERR(priv->fuses);
>> +
>> +	config.priv = priv;
>> +	config.size = resource_size(res);
>> +
>> +	return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config));
>> +}
>> +
>> +static const struct of_device_id apple_efuses_of_match[] = {
>> +	{ .compatible = "apple,efuses", },
>> +	{}
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, apple_efuses_of_match);
>> +
>> +static struct platform_driver apple_efuses_driver = {
>> +	.driver = {
>> +		.name = "apple_efuses",
>> +		.of_match_table = apple_efuses_of_match,
>> +		.owner = THIS_MODULE,
>
> You wrote it also in changelog, but why do you need it? Doesn't core set
> it? Coccinelle should complain about this as well.
>

yeah, you're right. I shouldn't have just blindly followed what Hector and Joey
had to do for another subsystem to make reference counting work there.

I just checked again and it's neither required here not in struct nvmem_config
because module_platform_driver -> platform_driver_register ->
__platform_driver_register will set it in struct platform_driver and the
nvmem core will take it from there and set it inside nvmem_config.


thanks,


Sven
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/nvmem/apple,efuses.yaml b/Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
new file mode 100644
index 000000000000..5ec8f2bdb3a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
@@ -0,0 +1,50 @@ 
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/apple,efuses.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple SoC eFuse-based NVMEM
+
+description: |
+  Apple SoCs such as the M1 contain factory-programmed eFuses used to e.g. store
+  calibration data for the PCIe and the Type-C PHY or unique chip identifiers
+  such as the ECID.
+
+maintainers:
+  - Sven Peter <sven@svenpeter.dev>
+
+allOf:
+  - $ref: "nvmem.yaml#"
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-efuses
+          - apple,t6000-efuses
+      - const: apple,efuses
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    efuse@3d2bc000 {
+        compatible = "apple,t8103-efuses", "apple,efuses";
+        reg = <0x3d2bc000 0x1000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        ecid: efuse@500 {
+            reg = <0x500 0x8>;
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 05fd080b82f3..f70d8525cbd4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1771,6 +1771,7 @@  F:	Documentation/devicetree/bindings/arm/apple/*
 F:	Documentation/devicetree/bindings/i2c/apple,i2c.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
 F:	Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
+F:	Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
 F:	Documentation/devicetree/bindings/pci/apple,pcie.yaml
 F:	Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
 F:	Documentation/devicetree/bindings/power/apple*