Re: [PATCH stblinux.git 2/2] firmware: bcm47xx_nvram: support platform device "brcm,nvram"
On 02.03.2021 17:59, Florian Fainelli wrote: On 3/1/21 11:44 PM, Rafał Miłecki wrote: From: Rafał Miłecki Add support for platform device providing mapping resource. This allows reading NVRAM based on DT mapping binding. It's required for devices that boot depending on NVRAM stored setup and provides early access to NVRAM data. Signed-off-by: Rafał Miłecki --- bcm47xx_nvram driver was originally added through MIPS tree, but this change doesn't affect BCM47XX (MIPS) as it doesn't use DT. It targets ARCH_BCM_5301X so I suggest this goes through the stblinux.git tree. Can you see if this change can be replaced by the nvmem-rmem work that Nicolas recently did to support something similar for the Raspberry Pi 4: https://lkml.org/lkml/2021/1/29/235 I don't think it fits my case. It's a reserved memory binding/driver which refers to the system memory. In NVRAM case we need to do a mapping. I think it's different? nvmem-rmem registers NVMEM device without providing any cells. It also doesn't understand NVRAM data structure. I guess nvmem-rmem only exposes NVMEM for user-space access. I need to access NVRAM to e.g. detect boot parameters in kernel code. I was thinking for a moment about treating NVRAM like a NVMEM but NVRAM doesn't seem to fit current design and kernel API. NVMEM assumes that every cell has a specific offset and size. Reading NVRAM should be based on string keys (nof offsets). See nvmem_reg_read_t for details. This won't make a huge difference I think, but for a slightly cleaner design I could probably have NVRAM devices without cells and make it setup NVRAM. Let me see if I can code that.
Re: [PATCH stblinux.git 2/2] firmware: bcm47xx_nvram: support platform device "brcm,nvram"
On 3/1/21 11:44 PM, Rafał Miłecki wrote: > From: Rafał Miłecki > > Add support for platform device providing mapping resource. This allows > reading NVRAM based on DT mapping binding. It's required for devices > that boot depending on NVRAM stored setup and provides early access to > NVRAM data. > > Signed-off-by: Rafał Miłecki > --- > bcm47xx_nvram driver was originally added through MIPS tree, but this > change doesn't affect BCM47XX (MIPS) as it doesn't use DT. It targets > ARCH_BCM_5301X so I suggest this goes through the stblinux.git tree. Can you see if this change can be replaced by the nvmem-rmem work that Nicolas recently did to support something similar for the Raspberry Pi 4: https://lkml.org/lkml/2021/1/29/235 > --- > drivers/firmware/broadcom/bcm47xx_nvram.c | 55 +++ > 1 file changed, 55 insertions(+) > > diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c > b/drivers/firmware/broadcom/bcm47xx_nvram.c > index 835ece9c00f1..d5d19dd1b9e1 100644 > --- a/drivers/firmware/broadcom/bcm47xx_nvram.c > +++ b/drivers/firmware/broadcom/bcm47xx_nvram.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > #include > > #define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ > @@ -162,6 +163,60 @@ static int nvram_init(void) > return -ENXIO; > } > > +static int brcm_nvram_probe(struct platform_device *pdev) > +{ > + struct nvram_header __iomem *header; > + struct device *dev = &pdev->dev; > + struct resource *res; > + void __iomem *mmio; > + size_t copy_len; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) { > + dev_err(dev, "Failed to get resource\n"); > + return -ENODEV; > + } > + > + mmio = ioremap(res->start, resource_size(res)); > + if (!mmio) > + return -ENOMEM; > + > + header = (struct nvram_header *)mmio; > + copy_len = DIV_ROUND_UP(sizeof(*header) + header->len, 4); > + if (header->magic != NVRAM_MAGIC) { > + dev_err(dev, "No NVRAM found at %pR\n", res); > + return -EPROTO; > + } else if (copy_len > resource_size(res)) { > + dev_err(dev, "NVRAM size exceeds %pR\n", res); > + return -ERANGE; > + } else if (copy_len >= NVRAM_SPACE) { > + dev_err(dev, "NVRAM size exceeds buffer size %d\n", > NVRAM_SPACE); > + return -ENOMEM; > + } > + > + __ioread32_copy(nvram_buf, mmio, copy_len); > + nvram_buf[NVRAM_SPACE - 1] = '\0'; > + > + iounmap(mmio); > + > + return 0; > +} > + > +static const struct of_device_id brcm_nvram_of_match[] = { > + { .compatible = "brcm,nvram "}, > + {}, > +}; > + > +static struct platform_driver brcm_nvram_driver = { > + .driver = { > + .name = "brcm_nvram", > + .of_match_table = brcm_nvram_of_match, > + }, > + .probe = brcm_nvram_probe, > +}; > + > +module_platform_driver(brcm_nvram_driver); > + > int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) > { > char *var, *value, *end, *eq; > -- Florian
[PATCH stblinux.git 2/2] firmware: bcm47xx_nvram: support platform device "brcm,nvram"
From: Rafał Miłecki Add support for platform device providing mapping resource. This allows reading NVRAM based on DT mapping binding. It's required for devices that boot depending on NVRAM stored setup and provides early access to NVRAM data. Signed-off-by: Rafał Miłecki --- bcm47xx_nvram driver was originally added through MIPS tree, but this change doesn't affect BCM47XX (MIPS) as it doesn't use DT. It targets ARCH_BCM_5301X so I suggest this goes through the stblinux.git tree. --- drivers/firmware/broadcom/bcm47xx_nvram.c | 55 +++ 1 file changed, 55 insertions(+) diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c index 835ece9c00f1..d5d19dd1b9e1 100644 --- a/drivers/firmware/broadcom/bcm47xx_nvram.c +++ b/drivers/firmware/broadcom/bcm47xx_nvram.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define NVRAM_MAGIC0x48534C46 /* 'FLSH' */ @@ -162,6 +163,60 @@ static int nvram_init(void) return -ENXIO; } +static int brcm_nvram_probe(struct platform_device *pdev) +{ + struct nvram_header __iomem *header; + struct device *dev = &pdev->dev; + struct resource *res; + void __iomem *mmio; + size_t copy_len; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "Failed to get resource\n"); + return -ENODEV; + } + + mmio = ioremap(res->start, resource_size(res)); + if (!mmio) + return -ENOMEM; + + header = (struct nvram_header *)mmio; + copy_len = DIV_ROUND_UP(sizeof(*header) + header->len, 4); + if (header->magic != NVRAM_MAGIC) { + dev_err(dev, "No NVRAM found at %pR\n", res); + return -EPROTO; + } else if (copy_len > resource_size(res)) { + dev_err(dev, "NVRAM size exceeds %pR\n", res); + return -ERANGE; + } else if (copy_len >= NVRAM_SPACE) { + dev_err(dev, "NVRAM size exceeds buffer size %d\n", NVRAM_SPACE); + return -ENOMEM; + } + + __ioread32_copy(nvram_buf, mmio, copy_len); + nvram_buf[NVRAM_SPACE - 1] = '\0'; + + iounmap(mmio); + + return 0; +} + +static const struct of_device_id brcm_nvram_of_match[] = { + { .compatible = "brcm,nvram "}, + {}, +}; + +static struct platform_driver brcm_nvram_driver = { + .driver = { + .name = "brcm_nvram", + .of_match_table = brcm_nvram_of_match, + }, + .probe = brcm_nvram_probe, +}; + +module_platform_driver(brcm_nvram_driver); + int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) { char *var, *value, *end, *eq; -- 2.26.2