[PATCH v8 1/9] nvmem: Add a simple NVMEM framework for nvmem providers
Srinivas Kandagatla
srinivas.kandagatla at linaro.org
Tue Jul 21 02:41:44 PDT 2015
Thanks Stephen for review,
On 20/07/15 22:11, Stephen Boyd wrote:
> On 07/20/2015 07:43 AM, Srinivas Kandagatla wrote:
>> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
>> new file mode 100644
>> index 0000000..bde5528
>> --- /dev/null
>> +++ b/drivers/nvmem/core.c
>> @@ -0,0 +1,384 @@
>>
>> +
>> +static int nvmem_add_cells(struct nvmem_device *nvmem,
>> + const struct nvmem_config *cfg)
>> +{
>> + struct nvmem_cell **cells;
>> + const struct nvmem_cell_info *info = cfg->cells;
>> + int i, rval;
>> +
>> + cells = kzalloc(sizeof(*cells) * cfg->ncells, GFP_KERNEL);
>
> kcalloc?
Only reason for using kzalloc is to give the code more flexibility to
free any pointer in the array in case of errors.
>
>> + if (!cells)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < cfg->ncells; i++) {
>> + cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
>> + if (!cells[i]) {
>> + rval = -ENOMEM;
>> + goto err;
>> + }
>> +
>> + rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]);
>> + if (IS_ERR_VALUE(rval)) {
>> + kfree(cells[i]);
>> + goto err;
>> + }
>> +
>> + nvmem_cell_add(cells[i]);
>> + }
>> +
>> + nvmem->ncells = cfg->ncells;
>> + /* remove tmp array */
>> + kfree(cells);
>> +
>> + return 0;
>> +err:
>> + while (--i)
>> + nvmem_cell_drop(cells[i]);
>> +
>> + return rval;
>> +}
>> +
>> +/**
>> + * nvmem_register() - Register a nvmem device for given nvmem_config.
>> + * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
>> + *
>> + * @config: nvmem device configuration with which nvmem device is
>> created.
>> + *
>> + * Return: Will be an ERR_PTR() on error or a valid pointer to
>> nvmem_device
>> + * on success.
>> + */
>> +
>
> Why the newline?
Yep, fixed it now.
>
>> +struct nvmem_device *nvmem_register(const struct nvmem_config *config)
>> +{
>> + struct nvmem_device *nvmem;
>> + struct device_node *np;
>> + struct regmap *rm;
>> + int rval;
>> +
>> + if (!config->dev)
>> + return ERR_PTR(-EINVAL);
>> +
>> + rm = dev_get_regmap(config->dev, NULL);
>> + if (!rm) {
>> + dev_err(config->dev, "Regmap not found\n");
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + nvmem = kzalloc(sizeof(*nvmem), GFP_KERNEL);
>> + if (!nvmem)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + nvmem->id = ida_simple_get(&nvmem_ida, 0, 0, GFP_KERNEL);
>> + if (nvmem->id < 0) {
>> + kfree(nvmem);
>> + return ERR_PTR(nvmem->id);
>
> Oops, we already freed nvmem.
>
Oops, Fixed this one too.
>> + }
>> +
>> + nvmem->regmap = rm;
>> + nvmem->owner = config->owner;
>> + nvmem->stride = regmap_get_reg_stride(rm);
>> + nvmem->word_size = regmap_get_val_bytes(rm);
>> + nvmem->size = regmap_get_max_register(rm) + nvmem->stride;
>> + nvmem->dev.type = &nvmem_provider_type;
>> + nvmem->dev.bus = &nvmem_bus_type;
>> + nvmem->dev.parent = config->dev;
>> + np = config->dev->of_node;
>> + nvmem->dev.of_node = np;
>> + dev_set_name(&nvmem->dev, "%s%d",
>> + config->name ? : "nvmem", config->id);
>> +
>> + nvmem->read_only = np ? of_property_read_bool(np, "read-only") : 0;
>
> of_property_read_bool(NULL, ..) "does the right thing" and returns false
> already.
thanks, that should make this more simple.
>
>> +
>> + nvmem->read_only |= config->read_only;
>> +
>> + device_initialize(&nvmem->dev);
>> +
>> + dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
>> +
>> + rval = device_add(&nvmem->dev);
>> + if (rval) {
>> + ida_simple_remove(&nvmem_ida, nvmem->id);
>> + kfree(nvmem);
>> + return ERR_PTR(rval);
>> + }
>> +
>> + if (device_create_bin_file(&nvmem->dev,
>> + nvmem->read_only ? &bin_attr_ro_nvmem :
>> + &bin_attr_rw_nvmem))
>> + dev_warn(&nvmem->dev, "Failed to create sysfs binary file\n");
>
> Why can't we have device_add() add the binary file attribute too?
>
Yes we can set dev.groups directly before device_add, I did this change too.
>> +
>> + if (config->cells)
>> + nvmem_add_cells(nvmem, config);
>> +
>> + return nvmem;
>> +}
>> +EXPORT_SYMBOL_GPL(nvmem_register);
>> +
>> +/**
>> + * nvmem_unregister() - Unregister previously registered nvmem device
>> + *
>> + * @nvmem: Pointer to previously registered nvmem device.
>> + *
>> + * Return: Will be an negative on error or a zero on success.
>> + */
>> +int nvmem_unregister(struct nvmem_device *nvmem)
>> +{
>> + mutex_lock(&nvmem_mutex);
>> + if (nvmem->users) {
>> + mutex_unlock(&nvmem_mutex);
>> + return -EBUSY;
>> + }
>> + mutex_unlock(&nvmem_mutex);
>
> This lock doesn't seem to be doing anything in this patch? Perhaps it
> should be added in the second patch where consumers start making it useful?
Ok, make sense. I moved this too.
I have v9 ready will send it.
--srini
>
More information about the linux-arm-kernel
mailing list