Message ID | 20240821105943.230281-13-ada@thorsis.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Microchip OTPC driver on SAM9X60 exposing UIDxR as additional nvmem device | expand |
On 21.08.2024 13:59, Alexander Dahl wrote: > For SAM9X60 the Product UID x Register containing the Unique Product ID > is part of the OTPC registers. We have everything at hand here to just > create a trivial nvmem device for those. I'm not sure what is the best option to expose this. I let it to NVMEM maintainers. > > Signed-off-by: Alexander Dahl <ada@thorsis.com> > --- > drivers/nvmem/microchip-otpc.c | 41 +++++++++++++++++++++++++++++++++- > 1 file changed, 40 insertions(+), 1 deletion(-) > > diff --git a/drivers/nvmem/microchip-otpc.c b/drivers/nvmem/microchip-otpc.c > index 047ca5ac6407..52af4c137204 100644 > --- a/drivers/nvmem/microchip-otpc.c > +++ b/drivers/nvmem/microchip-otpc.c > @@ -45,6 +45,9 @@ > #define MCHP_OTPC_NAME "mchp-otpc" > #define MCHP_OTPC_SIZE (11 * 1024) > > +#define MCHP_OTPC_UID_NAME "mchp-uid" > +#define MCHP_OTPC_UID_SIZE 16 > + > /** > * struct mchp_otpc - OTPC private data structure > * @base: base address > @@ -249,6 +252,16 @@ static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size) > return 0; > } > > +static int mchp_otpc_uid_read(void *priv, unsigned int offset, > + void *val, size_t bytes) > +{ > + struct mchp_otpc *otpc = priv; > + > + memcpy_fromio(val, otpc->base + MCHP_OTPC_UID0R + offset, bytes); > + > + return 0; > +} > + > static struct nvmem_config mchp_nvmem_config = { > .name = MCHP_OTPC_NAME, > .type = NVMEM_TYPE_OTP, > @@ -258,6 +271,15 @@ static struct nvmem_config mchp_nvmem_config = { > .reg_read = mchp_otpc_read, > }; > > +static struct nvmem_config mchp_otpc_uid_nvmem_config = { > + .name = MCHP_OTPC_UID_NAME, > + .read_only = true, > + .word_size = 4, > + .stride = 4, > + .size = MCHP_OTPC_UID_SIZE, > + .reg_read = mchp_otpc_uid_read, > +}; > + > static int mchp_otpc_probe(struct platform_device *pdev) > { > struct nvmem_device *nvmem; > @@ -303,8 +325,25 @@ static int mchp_otpc_probe(struct platform_device *pdev) > mchp_nvmem_config.size = size; > mchp_nvmem_config.priv = otpc; > nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); > + if (IS_ERR(nvmem)) { > + dev_err(&pdev->dev, > + "Error (%ld) registering OTP as nvmem device\n", > + PTR_ERR(nvmem)); > + return PTR_ERR(nvmem); return dev_err_probe(); > + } > > - return PTR_ERR_OR_ZERO(nvmem); > + mchp_otpc_uid_nvmem_config.dev = otpc->dev; > + mchp_otpc_uid_nvmem_config.priv = otpc; > + > + nvmem = devm_nvmem_register(&pdev->dev, &mchp_otpc_uid_nvmem_config); > + if (IS_ERR(nvmem)) { > + dev_err(&pdev->dev, > + "Error (%ld) registering UIDxR as nvmem device\n", > + PTR_ERR(nvmem)); > + return PTR_ERR(nvmem); return dev_err_probe(); > + } > + > + return 0; > } > > static const struct of_device_id __maybe_unused mchp_otpc_ids[] = {
diff --git a/drivers/nvmem/microchip-otpc.c b/drivers/nvmem/microchip-otpc.c index 047ca5ac6407..52af4c137204 100644 --- a/drivers/nvmem/microchip-otpc.c +++ b/drivers/nvmem/microchip-otpc.c @@ -45,6 +45,9 @@ #define MCHP_OTPC_NAME "mchp-otpc" #define MCHP_OTPC_SIZE (11 * 1024) +#define MCHP_OTPC_UID_NAME "mchp-uid" +#define MCHP_OTPC_UID_SIZE 16 + /** * struct mchp_otpc - OTPC private data structure * @base: base address @@ -249,6 +252,16 @@ static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size) return 0; } +static int mchp_otpc_uid_read(void *priv, unsigned int offset, + void *val, size_t bytes) +{ + struct mchp_otpc *otpc = priv; + + memcpy_fromio(val, otpc->base + MCHP_OTPC_UID0R + offset, bytes); + + return 0; +} + static struct nvmem_config mchp_nvmem_config = { .name = MCHP_OTPC_NAME, .type = NVMEM_TYPE_OTP, @@ -258,6 +271,15 @@ static struct nvmem_config mchp_nvmem_config = { .reg_read = mchp_otpc_read, }; +static struct nvmem_config mchp_otpc_uid_nvmem_config = { + .name = MCHP_OTPC_UID_NAME, + .read_only = true, + .word_size = 4, + .stride = 4, + .size = MCHP_OTPC_UID_SIZE, + .reg_read = mchp_otpc_uid_read, +}; + static int mchp_otpc_probe(struct platform_device *pdev) { struct nvmem_device *nvmem; @@ -303,8 +325,25 @@ static int mchp_otpc_probe(struct platform_device *pdev) mchp_nvmem_config.size = size; mchp_nvmem_config.priv = otpc; nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); + if (IS_ERR(nvmem)) { + dev_err(&pdev->dev, + "Error (%ld) registering OTP as nvmem device\n", + PTR_ERR(nvmem)); + return PTR_ERR(nvmem); + } - return PTR_ERR_OR_ZERO(nvmem); + mchp_otpc_uid_nvmem_config.dev = otpc->dev; + mchp_otpc_uid_nvmem_config.priv = otpc; + + nvmem = devm_nvmem_register(&pdev->dev, &mchp_otpc_uid_nvmem_config); + if (IS_ERR(nvmem)) { + dev_err(&pdev->dev, + "Error (%ld) registering UIDxR as nvmem device\n", + PTR_ERR(nvmem)); + return PTR_ERR(nvmem); + } + + return 0; } static const struct of_device_id __maybe_unused mchp_otpc_ids[] = {
For SAM9X60 the Product UID x Register containing the Unique Product ID is part of the OTPC registers. We have everything at hand here to just create a trivial nvmem device for those. Signed-off-by: Alexander Dahl <ada@thorsis.com> --- drivers/nvmem/microchip-otpc.c | 41 +++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-)