Instead of adding NVMEM-related code into the generic OF partition parsing, let's instead instantiate a device and bind to it via the driver model. This is also what Linux is currently doing for the u-boot,env driver when not using the layout binding. The nvmem-cells binding itself is using a MTD notifier, but for our purposes just using the driver model is ok. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- drivers/nvmem/partition.c | 23 +++++++++++++++++++++-- drivers/of/partition.c | 8 ++------ include/linux/nvmem-provider.h | 6 ------ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/nvmem/partition.c b/drivers/nvmem/partition.c index 14907e05ba2d..d1127c1401af 100644 --- a/drivers/nvmem/partition.c +++ b/drivers/nvmem/partition.c @@ -18,9 +18,15 @@ static int nvmem_cdev_read(void *ctx, unsigned offset, void *buf, size_t bytes) return cdev_read(ctx, buf, bytes, offset, 0); } -struct nvmem_device *nvmem_partition_register(struct cdev *cdev) +static int nvmem_cells_probe(struct device *dev) { struct nvmem_config config = {}; + struct device_node *node = dev->of_node; + struct cdev *cdev; + + cdev = cdev_by_device_node(node); + if (!cdev) + return -EINVAL; config.name = cdev->name; config.dev = cdev->dev; @@ -32,5 +38,18 @@ struct nvmem_device *nvmem_partition_register(struct cdev *cdev) config.reg_read = nvmem_cdev_read; config.reg_write = nvmem_cdev_write; - return nvmem_register(&config); + return PTR_ERR_OR_ZERO(nvmem_register(&config)); } + +static __maybe_unused struct of_device_id nvmem_cells_dt_ids[] = { + { .compatible = "nvmem-cells", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, nvmem_cells_dt_ids); + +static struct driver nvmem_cells_driver = { + .name = "nvmem_cells", + .probe = nvmem_cells_probe, + .of_compatible = nvmem_cells_dt_ids, +}; +device_platform_driver(nvmem_cells_driver); diff --git a/drivers/of/partition.c b/drivers/of/partition.c index 70297da9d231..56933cc958f7 100644 --- a/drivers/of/partition.c +++ b/drivers/of/partition.c @@ -76,12 +76,6 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node) new->device_node = node; new->flags |= DEVFS_PARTITION_FROM_OF | DEVFS_PARTITION_FOR_FIXUP; - if (IS_ENABLED(CONFIG_NVMEM) && of_device_is_compatible(node, "nvmem-cells")) { - struct nvmem_device *nvmem = nvmem_partition_register(new); - if (IS_ERR(nvmem)) - dev_warn(cdev->dev, "nvmem registeration failed: %pe\n", nvmem); - } - out: free(filename); @@ -108,6 +102,8 @@ int of_parse_partitions(struct cdev *cdev, struct device_node *node) of_parse_partition(cdev, n); } + if (subnode) + of_platform_populate(subnode, NULL, cdev->dev); return 0; } diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h index 41c636b3a4e0..c1765673eb23 100644 --- a/include/linux/nvmem-provider.h +++ b/include/linux/nvmem-provider.h @@ -47,7 +47,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); struct nvmem_device *nvmem_regmap_register(struct regmap *regmap, const char *name); struct nvmem_device *nvmem_regmap_register_with_pp(struct regmap *regmap, const char *name, nvmem_cell_post_process_t cell_post_process); -struct nvmem_device *nvmem_partition_register(struct cdev *cdev); struct device *nvmem_device_get_device(struct nvmem_device *nvmem); #else @@ -69,11 +68,6 @@ nvmem_regmap_register_with_pp(struct regmap *regmap, const char *name, return ERR_PTR(-ENOSYS); } -static inline struct nvmem_device *nvmem_partition_register(struct cdev *cdev) -{ - return ERR_PTR(-ENOSYS); -} - static inline struct device *nvmem_device_get_device(struct nvmem_device *nvmem) { return ERR_PTR(-ENOSYS); -- 2.39.5