kernel: update nvmem subsystem to the latest upstream
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		| @@ -197,6 +197,7 @@ CONFIG_NEED_KUSER_HELPERS=y | ||||
| CONFIG_NEED_PER_CPU_KM=y | ||||
| CONFIG_NLS=y | ||||
| CONFIG_NVMEM=y | ||||
| # CONFIG_NVMEM_MICROCHIP_OTPC is not set | ||||
| CONFIG_NVMEM_SYSFS=y | ||||
| CONFIG_OF=y | ||||
| CONFIG_OF_ADDRESS=y | ||||
|   | ||||
| @@ -303,6 +303,7 @@ CONFIG_NLS_UTF8=y | ||||
| CONFIG_NO_HZ_COMMON=y | ||||
| CONFIG_NO_HZ_IDLE=y | ||||
| CONFIG_NVMEM=y | ||||
| # CONFIG_NVMEM_MICROCHIP_OTPC is not set | ||||
| CONFIG_NVMEM_SYSFS=y | ||||
| CONFIG_OF=y | ||||
| CONFIG_OF_ADDRESS=y | ||||
|   | ||||
| @@ -265,6 +265,7 @@ CONFIG_NLS_UTF8=y | ||||
| CONFIG_NO_HZ_COMMON=y | ||||
| CONFIG_NO_HZ_IDLE=y | ||||
| CONFIG_NVMEM=y | ||||
| # CONFIG_NVMEM_MICROCHIP_OTPC is not set | ||||
| CONFIG_NVMEM_SYSFS=y | ||||
| CONFIG_OF=y | ||||
| CONFIG_OF_ADDRESS=y | ||||
|   | ||||
| @@ -0,0 +1,456 @@ | ||||
| From 7ae6478b304bc004c3139b422665b0e23b57f05c Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Wed, 13 Oct 2021 14:19:55 +0100 | ||||
| Subject: [PATCH] nvmem: core: rework nvmem cell instance creation | ||||
|  | ||||
| In the existing design, we do not create a instance per nvmem cell consumer | ||||
| but we directly refer cell from nvmem cell list that are added to provider. | ||||
|  | ||||
| However this design has some limitations when consumers want to assign name | ||||
| or connection id the nvmem cell instance, ex: via "nvmem-cell-names" or | ||||
| id in nvmem_cell_get(id). | ||||
|  | ||||
| Having a name associated with nvmem cell consumer instance will help | ||||
| provider drivers in performing post processing of nvmem cell data if required | ||||
| before data is seen by the consumers. This is pretty normal with some vendors | ||||
| storing nvmem cells like mac-address in a vendor specific data layouts that | ||||
| are not directly usable by the consumer drivers. | ||||
|  | ||||
| With this patch nvmem cell will be created dynamically during nvmem_cell_get | ||||
| and destroyed in nvmem_cell_put, allowing consumers to associate name with | ||||
| nvmem cell consumer instance. | ||||
|  | ||||
| With this patch a new struct nvmem_cell_entry replaces struct nvmem_cell | ||||
| for storing nvmem cell information within the core. | ||||
| This patch does not change nvmem-consumer interface based on nvmem_cell. | ||||
|  | ||||
| Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211013131957.30271-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 165 +++++++++++++++++++++++++++---------------- | ||||
|  1 file changed, 105 insertions(+), 60 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -45,8 +45,7 @@ struct nvmem_device { | ||||
|  #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) | ||||
|   | ||||
|  #define FLAG_COMPAT		BIT(0) | ||||
| - | ||||
| -struct nvmem_cell { | ||||
| +struct nvmem_cell_entry { | ||||
|  	const char		*name; | ||||
|  	int			offset; | ||||
|  	int			bytes; | ||||
| @@ -57,6 +56,11 @@ struct nvmem_cell { | ||||
|  	struct list_head	node; | ||||
|  }; | ||||
|   | ||||
| +struct nvmem_cell { | ||||
| +	struct nvmem_cell_entry *entry; | ||||
| +	const char		*id; | ||||
| +}; | ||||
| + | ||||
|  static DEFINE_MUTEX(nvmem_mutex); | ||||
|  static DEFINE_IDA(nvmem_ida); | ||||
|   | ||||
| @@ -424,7 +428,7 @@ static struct bus_type nvmem_bus_type = | ||||
|  	.name		= "nvmem", | ||||
|  }; | ||||
|   | ||||
| -static void nvmem_cell_drop(struct nvmem_cell *cell) | ||||
| +static void nvmem_cell_entry_drop(struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell); | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
| @@ -437,13 +441,13 @@ static void nvmem_cell_drop(struct nvmem | ||||
|   | ||||
|  static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem) | ||||
|  { | ||||
| -	struct nvmem_cell *cell, *p; | ||||
| +	struct nvmem_cell_entry *cell, *p; | ||||
|   | ||||
|  	list_for_each_entry_safe(cell, p, &nvmem->cells, node) | ||||
| -		nvmem_cell_drop(cell); | ||||
| +		nvmem_cell_entry_drop(cell); | ||||
|  } | ||||
|   | ||||
| -static void nvmem_cell_add(struct nvmem_cell *cell) | ||||
| +static void nvmem_cell_entry_add(struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
|  	list_add_tail(&cell->node, &cell->nvmem->cells); | ||||
| @@ -451,9 +455,9 @@ static void nvmem_cell_add(struct nvmem_ | ||||
|  	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell); | ||||
|  } | ||||
|   | ||||
| -static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem, | ||||
| -					const struct nvmem_cell_info *info, | ||||
| -					struct nvmem_cell *cell) | ||||
| +static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem, | ||||
| +						     const struct nvmem_cell_info *info, | ||||
| +						     struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	cell->nvmem = nvmem; | ||||
|  	cell->offset = info->offset; | ||||
| @@ -477,13 +481,13 @@ static int nvmem_cell_info_to_nvmem_cell | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| -static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, | ||||
| -				const struct nvmem_cell_info *info, | ||||
| -				struct nvmem_cell *cell) | ||||
| +static int nvmem_cell_info_to_nvmem_cell_entry(struct nvmem_device *nvmem, | ||||
| +					       const struct nvmem_cell_info *info, | ||||
| +					       struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	int err; | ||||
|   | ||||
| -	err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell); | ||||
| +	err = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, cell); | ||||
|  	if (err) | ||||
|  		return err; | ||||
|   | ||||
| @@ -507,7 +511,7 @@ static int nvmem_add_cells(struct nvmem_ | ||||
|  		    const struct nvmem_cell_info *info, | ||||
|  		    int ncells) | ||||
|  { | ||||
| -	struct nvmem_cell **cells; | ||||
| +	struct nvmem_cell_entry **cells; | ||||
|  	int i, rval; | ||||
|   | ||||
|  	cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); | ||||
| @@ -521,13 +525,13 @@ static int nvmem_add_cells(struct nvmem_ | ||||
|  			goto err; | ||||
|  		} | ||||
|   | ||||
| -		rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]); | ||||
| +		rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); | ||||
|  		if (rval) { | ||||
|  			kfree(cells[i]); | ||||
|  			goto err; | ||||
|  		} | ||||
|   | ||||
| -		nvmem_cell_add(cells[i]); | ||||
| +		nvmem_cell_entry_add(cells[i]); | ||||
|  	} | ||||
|   | ||||
|  	/* remove tmp array */ | ||||
| @@ -536,7 +540,7 @@ static int nvmem_add_cells(struct nvmem_ | ||||
|  	return 0; | ||||
|  err: | ||||
|  	while (i--) | ||||
| -		nvmem_cell_drop(cells[i]); | ||||
| +		nvmem_cell_entry_drop(cells[i]); | ||||
|   | ||||
|  	kfree(cells); | ||||
|   | ||||
| @@ -573,7 +577,7 @@ static int nvmem_add_cells_from_table(st | ||||
|  { | ||||
|  	const struct nvmem_cell_info *info; | ||||
|  	struct nvmem_cell_table *table; | ||||
| -	struct nvmem_cell *cell; | ||||
| +	struct nvmem_cell_entry *cell; | ||||
|  	int rval = 0, i; | ||||
|   | ||||
|  	mutex_lock(&nvmem_cell_mutex); | ||||
| @@ -588,15 +592,13 @@ static int nvmem_add_cells_from_table(st | ||||
|  					goto out; | ||||
|  				} | ||||
|   | ||||
| -				rval = nvmem_cell_info_to_nvmem_cell(nvmem, | ||||
| -								     info, | ||||
| -								     cell); | ||||
| +				rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); | ||||
|  				if (rval) { | ||||
|  					kfree(cell); | ||||
|  					goto out; | ||||
|  				} | ||||
|   | ||||
| -				nvmem_cell_add(cell); | ||||
| +				nvmem_cell_entry_add(cell); | ||||
|  			} | ||||
|  		} | ||||
|  	} | ||||
| @@ -606,10 +608,10 @@ out: | ||||
|  	return rval; | ||||
|  } | ||||
|   | ||||
| -static struct nvmem_cell * | ||||
| -nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) | ||||
| +static struct nvmem_cell_entry * | ||||
| +nvmem_find_cell_entry_by_name(struct nvmem_device *nvmem, const char *cell_id) | ||||
|  { | ||||
| -	struct nvmem_cell *iter, *cell = NULL; | ||||
| +	struct nvmem_cell_entry *iter, *cell = NULL; | ||||
|   | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
|  	list_for_each_entry(iter, &nvmem->cells, node) { | ||||
| @@ -680,7 +682,7 @@ static int nvmem_add_cells_from_of(struc | ||||
|  { | ||||
|  	struct device_node *parent, *child; | ||||
|  	struct device *dev = &nvmem->dev; | ||||
| -	struct nvmem_cell *cell; | ||||
| +	struct nvmem_cell_entry *cell; | ||||
|  	const __be32 *addr; | ||||
|  	int len; | ||||
|   | ||||
| @@ -729,7 +731,7 @@ static int nvmem_add_cells_from_of(struc | ||||
|  		} | ||||
|   | ||||
|  		cell->np = of_node_get(child); | ||||
| -		nvmem_cell_add(cell); | ||||
| +		nvmem_cell_entry_add(cell); | ||||
|  	} | ||||
|   | ||||
|  	return 0; | ||||
| @@ -1144,9 +1146,33 @@ struct nvmem_device *devm_nvmem_device_g | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(devm_nvmem_device_get); | ||||
|   | ||||
| +static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) | ||||
| +{ | ||||
| +	struct nvmem_cell *cell; | ||||
| +	const char *name = NULL; | ||||
| + | ||||
| +	cell = kzalloc(sizeof(*cell), GFP_KERNEL); | ||||
| +	if (!cell) | ||||
| +		return ERR_PTR(-ENOMEM); | ||||
| + | ||||
| +	if (id) { | ||||
| +		name = kstrdup_const(id, GFP_KERNEL); | ||||
| +		if (!name) { | ||||
| +			kfree(cell); | ||||
| +			return ERR_PTR(-ENOMEM); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	cell->id = name; | ||||
| +	cell->entry = entry; | ||||
| + | ||||
| +	return cell; | ||||
| +} | ||||
| + | ||||
|  static struct nvmem_cell * | ||||
|  nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) | ||||
|  { | ||||
| +	struct nvmem_cell_entry *cell_entry; | ||||
|  	struct nvmem_cell *cell = ERR_PTR(-ENOENT); | ||||
|  	struct nvmem_cell_lookup *lookup; | ||||
|  	struct nvmem_device *nvmem; | ||||
| @@ -1171,11 +1197,15 @@ nvmem_cell_get_from_lookup(struct device | ||||
|  				break; | ||||
|  			} | ||||
|   | ||||
| -			cell = nvmem_find_cell_by_name(nvmem, | ||||
| -						       lookup->cell_name); | ||||
| -			if (!cell) { | ||||
| +			cell_entry = nvmem_find_cell_entry_by_name(nvmem, | ||||
| +								   lookup->cell_name); | ||||
| +			if (!cell_entry) { | ||||
|  				__nvmem_device_put(nvmem); | ||||
|  				cell = ERR_PTR(-ENOENT); | ||||
| +			} else { | ||||
| +				cell = nvmem_create_cell(cell_entry, con_id); | ||||
| +				if (IS_ERR(cell)) | ||||
| +					__nvmem_device_put(nvmem); | ||||
|  			} | ||||
|  			break; | ||||
|  		} | ||||
| @@ -1186,10 +1216,10 @@ nvmem_cell_get_from_lookup(struct device | ||||
|  } | ||||
|   | ||||
|  #if IS_ENABLED(CONFIG_OF) | ||||
| -static struct nvmem_cell * | ||||
| -nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) | ||||
| +static struct nvmem_cell_entry * | ||||
| +nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np) | ||||
|  { | ||||
| -	struct nvmem_cell *iter, *cell = NULL; | ||||
| +	struct nvmem_cell_entry *iter, *cell = NULL; | ||||
|   | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
|  	list_for_each_entry(iter, &nvmem->cells, node) { | ||||
| @@ -1219,6 +1249,7 @@ struct nvmem_cell *of_nvmem_cell_get(str | ||||
|  { | ||||
|  	struct device_node *cell_np, *nvmem_np; | ||||
|  	struct nvmem_device *nvmem; | ||||
| +	struct nvmem_cell_entry *cell_entry; | ||||
|  	struct nvmem_cell *cell; | ||||
|  	int index = 0; | ||||
|   | ||||
| @@ -1239,12 +1270,16 @@ struct nvmem_cell *of_nvmem_cell_get(str | ||||
|  	if (IS_ERR(nvmem)) | ||||
|  		return ERR_CAST(nvmem); | ||||
|   | ||||
| -	cell = nvmem_find_cell_by_node(nvmem, cell_np); | ||||
| -	if (!cell) { | ||||
| +	cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); | ||||
| +	if (!cell_entry) { | ||||
|  		__nvmem_device_put(nvmem); | ||||
|  		return ERR_PTR(-ENOENT); | ||||
|  	} | ||||
|   | ||||
| +	cell = nvmem_create_cell(cell_entry, id); | ||||
| +	if (IS_ERR(cell)) | ||||
| +		__nvmem_device_put(nvmem); | ||||
| + | ||||
|  	return cell; | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(of_nvmem_cell_get); | ||||
| @@ -1350,13 +1385,17 @@ EXPORT_SYMBOL(devm_nvmem_cell_put); | ||||
|   */ | ||||
|  void nvmem_cell_put(struct nvmem_cell *cell) | ||||
|  { | ||||
| -	struct nvmem_device *nvmem = cell->nvmem; | ||||
| +	struct nvmem_device *nvmem = cell->entry->nvmem; | ||||
| + | ||||
| +	if (cell->id) | ||||
| +		kfree_const(cell->id); | ||||
|   | ||||
| +	kfree(cell); | ||||
|  	__nvmem_device_put(nvmem); | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_cell_put); | ||||
|   | ||||
| -static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf) | ||||
| +static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf) | ||||
|  { | ||||
|  	u8 *p, *b; | ||||
|  	int i, extra, bit_offset = cell->bit_offset; | ||||
| @@ -1390,8 +1429,8 @@ static void nvmem_shift_read_buffer_in_p | ||||
|  } | ||||
|   | ||||
|  static int __nvmem_cell_read(struct nvmem_device *nvmem, | ||||
| -		      struct nvmem_cell *cell, | ||||
| -		      void *buf, size_t *len) | ||||
| +		      struct nvmem_cell_entry *cell, | ||||
| +		      void *buf, size_t *len, const char *id) | ||||
|  { | ||||
|  	int rc; | ||||
|   | ||||
| @@ -1422,18 +1461,18 @@ static int __nvmem_cell_read(struct nvme | ||||
|   */ | ||||
|  void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) | ||||
|  { | ||||
| -	struct nvmem_device *nvmem = cell->nvmem; | ||||
| +	struct nvmem_device *nvmem = cell->entry->nvmem; | ||||
|  	u8 *buf; | ||||
|  	int rc; | ||||
|   | ||||
|  	if (!nvmem) | ||||
|  		return ERR_PTR(-EINVAL); | ||||
|   | ||||
| -	buf = kzalloc(cell->bytes, GFP_KERNEL); | ||||
| +	buf = kzalloc(cell->entry->bytes, GFP_KERNEL); | ||||
|  	if (!buf) | ||||
|  		return ERR_PTR(-ENOMEM); | ||||
|   | ||||
| -	rc = __nvmem_cell_read(nvmem, cell, buf, len); | ||||
| +	rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); | ||||
|  	if (rc) { | ||||
|  		kfree(buf); | ||||
|  		return ERR_PTR(rc); | ||||
| @@ -1443,7 +1482,7 @@ void *nvmem_cell_read(struct nvmem_cell | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_cell_read); | ||||
|   | ||||
| -static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, | ||||
| +static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell, | ||||
|  					     u8 *_buf, int len) | ||||
|  { | ||||
|  	struct nvmem_device *nvmem = cell->nvmem; | ||||
| @@ -1496,16 +1535,7 @@ err: | ||||
|  	return ERR_PTR(rc); | ||||
|  } | ||||
|   | ||||
| -/** | ||||
| - * nvmem_cell_write() - Write to a given nvmem cell | ||||
| - * | ||||
| - * @cell: nvmem cell to be written. | ||||
| - * @buf: Buffer to be written. | ||||
| - * @len: length of buffer to be written to nvmem cell. | ||||
| - * | ||||
| - * Return: length of bytes written or negative on failure. | ||||
| - */ | ||||
| -int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) | ||||
| +static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, size_t len) | ||||
|  { | ||||
|  	struct nvmem_device *nvmem = cell->nvmem; | ||||
|  	int rc; | ||||
| @@ -1531,6 +1561,21 @@ int nvmem_cell_write(struct nvmem_cell * | ||||
|   | ||||
|  	return len; | ||||
|  } | ||||
| + | ||||
| +/** | ||||
| + * nvmem_cell_write() - Write to a given nvmem cell | ||||
| + * | ||||
| + * @cell: nvmem cell to be written. | ||||
| + * @buf: Buffer to be written. | ||||
| + * @len: length of buffer to be written to nvmem cell. | ||||
| + * | ||||
| + * Return: length of bytes written or negative on failure. | ||||
| + */ | ||||
| +int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) | ||||
| +{ | ||||
| +	return __nvmem_cell_entry_write(cell->entry, buf, len); | ||||
| +} | ||||
| + | ||||
|  EXPORT_SYMBOL_GPL(nvmem_cell_write); | ||||
|   | ||||
|  static int nvmem_cell_read_common(struct device *dev, const char *cell_id, | ||||
| @@ -1633,7 +1678,7 @@ static const void *nvmem_cell_read_varia | ||||
|  	if (IS_ERR(cell)) | ||||
|  		return cell; | ||||
|   | ||||
| -	nbits = cell->nbits; | ||||
| +	nbits = cell->entry->nbits; | ||||
|  	buf = nvmem_cell_read(cell, len); | ||||
|  	nvmem_cell_put(cell); | ||||
|  	if (IS_ERR(buf)) | ||||
| @@ -1729,18 +1774,18 @@ EXPORT_SYMBOL_GPL(nvmem_cell_read_variab | ||||
|  ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem, | ||||
|  			   struct nvmem_cell_info *info, void *buf) | ||||
|  { | ||||
| -	struct nvmem_cell cell; | ||||
| +	struct nvmem_cell_entry cell; | ||||
|  	int rc; | ||||
|  	ssize_t len; | ||||
|   | ||||
|  	if (!nvmem) | ||||
|  		return -EINVAL; | ||||
|   | ||||
| -	rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); | ||||
| +	rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); | ||||
|  	if (rc) | ||||
|  		return rc; | ||||
|   | ||||
| -	rc = __nvmem_cell_read(nvmem, &cell, buf, &len); | ||||
| +	rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); | ||||
|  	if (rc) | ||||
|  		return rc; | ||||
|   | ||||
| @@ -1760,17 +1805,17 @@ EXPORT_SYMBOL_GPL(nvmem_device_cell_read | ||||
|  int nvmem_device_cell_write(struct nvmem_device *nvmem, | ||||
|  			    struct nvmem_cell_info *info, void *buf) | ||||
|  { | ||||
| -	struct nvmem_cell cell; | ||||
| +	struct nvmem_cell_entry cell; | ||||
|  	int rc; | ||||
|   | ||||
|  	if (!nvmem) | ||||
|  		return -EINVAL; | ||||
|   | ||||
| -	rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); | ||||
| +	rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); | ||||
|  	if (rc) | ||||
|  		return rc; | ||||
|   | ||||
| -	return nvmem_cell_write(&cell, buf, cell.bytes); | ||||
| +	return __nvmem_cell_entry_write(&cell, buf, cell.bytes); | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_device_cell_write); | ||||
|   | ||||
| @@ -0,0 +1,82 @@ | ||||
| From 5008062f1c3f5af3acf86164aa6fcc77b0c7bdce Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Wed, 13 Oct 2021 14:19:56 +0100 | ||||
| Subject: [PATCH] nvmem: core: add nvmem cell post processing callback | ||||
|  | ||||
| Some NVMEM providers have certain nvmem cells encoded, which requires | ||||
| post processing before actually using it. | ||||
|  | ||||
| For example mac-address is stored in either in ascii or delimited or reverse-order. | ||||
|  | ||||
| Having a post-process callback hook to provider drivers would enable them to | ||||
| do this vendor specific post processing before nvmem consumers see it. | ||||
|  | ||||
| Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211013131957.30271-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c           | 9 +++++++++ | ||||
|  include/linux/nvmem-provider.h | 5 +++++ | ||||
|  2 files changed, 14 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -38,6 +38,7 @@ struct nvmem_device { | ||||
|  	unsigned int		nkeepout; | ||||
|  	nvmem_reg_read_t	reg_read; | ||||
|  	nvmem_reg_write_t	reg_write; | ||||
| +	nvmem_cell_post_process_t cell_post_process; | ||||
|  	struct gpio_desc	*wp_gpio; | ||||
|  	void *priv; | ||||
|  }; | ||||
| @@ -798,6 +799,7 @@ struct nvmem_device *nvmem_register(cons | ||||
|  	nvmem->type = config->type; | ||||
|  	nvmem->reg_read = config->reg_read; | ||||
|  	nvmem->reg_write = config->reg_write; | ||||
| +	nvmem->cell_post_process = config->cell_post_process; | ||||
|  	nvmem->keepout = config->keepout; | ||||
|  	nvmem->nkeepout = config->nkeepout; | ||||
|  	if (config->of_node) | ||||
| @@ -1443,6 +1445,13 @@ static int __nvmem_cell_read(struct nvme | ||||
|  	if (cell->bit_offset || cell->nbits) | ||||
|  		nvmem_shift_read_buffer_in_place(cell, buf); | ||||
|   | ||||
| +	if (nvmem->cell_post_process) { | ||||
| +		rc = nvmem->cell_post_process(nvmem->priv, id, | ||||
| +					      cell->offset, buf, cell->bytes); | ||||
| +		if (rc) | ||||
| +			return rc; | ||||
| +	} | ||||
| + | ||||
|  	if (len) | ||||
|  		*len = cell->bytes; | ||||
|   | ||||
| --- a/include/linux/nvmem-provider.h | ||||
| +++ b/include/linux/nvmem-provider.h | ||||
| @@ -19,6 +19,9 @@ typedef int (*nvmem_reg_read_t)(void *pr | ||||
|  				void *val, size_t bytes); | ||||
|  typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, | ||||
|  				 void *val, size_t bytes); | ||||
| +/* used for vendor specific post processing of cell data */ | ||||
| +typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, | ||||
| +					  void *buf, size_t bytes); | ||||
|   | ||||
|  enum nvmem_type { | ||||
|  	NVMEM_TYPE_UNKNOWN = 0, | ||||
| @@ -62,6 +65,7 @@ struct nvmem_keepout { | ||||
|   * @no_of_node:	Device should not use the parent's of_node even if it's !NULL. | ||||
|   * @reg_read:	Callback to read data. | ||||
|   * @reg_write:	Callback to write data. | ||||
| + * @cell_post_process:	Callback for vendor specific post processing of cell data | ||||
|   * @size:	Device size. | ||||
|   * @word_size:	Minimum read/write access granularity. | ||||
|   * @stride:	Minimum read/write access stride. | ||||
| @@ -92,6 +96,7 @@ struct nvmem_config { | ||||
|  	bool			no_of_node; | ||||
|  	nvmem_reg_read_t	reg_read; | ||||
|  	nvmem_reg_write_t	reg_write; | ||||
| +	nvmem_cell_post_process_t cell_post_process; | ||||
|  	int	size; | ||||
|  	int	word_size; | ||||
|  	int	stride; | ||||
| @@ -0,0 +1,92 @@ | ||||
| From d0221a780cbc99fec6c27a98dba2828dc5735c00 Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Wed, 13 Oct 2021 14:19:57 +0100 | ||||
| Subject: [PATCH] nvmem: imx-ocotp: add support for post processing | ||||
|  | ||||
| Add .cell_post_process callback for imx-ocotp to deal with MAC address, | ||||
| since MAC address need to be reversed byte for some i.MX SoCs. | ||||
|  | ||||
| Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211013131957.30271-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/imx-ocotp.c | 25 +++++++++++++++++++++++++ | ||||
|  1 file changed, 25 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/imx-ocotp.c | ||||
| +++ b/drivers/nvmem/imx-ocotp.c | ||||
| @@ -97,6 +97,7 @@ struct ocotp_params { | ||||
|  	unsigned int bank_address_words; | ||||
|  	void (*set_timing)(struct ocotp_priv *priv); | ||||
|  	struct ocotp_ctrl_reg ctrl; | ||||
| +	bool reverse_mac_address; | ||||
|  }; | ||||
|   | ||||
|  static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) | ||||
| @@ -221,6 +222,25 @@ read_end: | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| +static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, | ||||
| +			     void *data, size_t bytes) | ||||
| +{ | ||||
| +	struct ocotp_priv *priv = context; | ||||
| + | ||||
| +	/* Deal with some post processing of nvmem cell data */ | ||||
| +	if (id && !strcmp(id, "mac-address")) { | ||||
| +		if (priv->params->reverse_mac_address) { | ||||
| +			u8 *buf = data; | ||||
| +			int i; | ||||
| + | ||||
| +			for (i = 0; i < bytes/2; i++) | ||||
| +				swap(buf[i], buf[bytes - i - 1]); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
|  static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv) | ||||
|  { | ||||
|  	unsigned long clk_rate; | ||||
| @@ -468,6 +488,7 @@ static struct nvmem_config imx_ocotp_nvm | ||||
|  	.stride = 1, | ||||
|  	.reg_read = imx_ocotp_read, | ||||
|  	.reg_write = imx_ocotp_write, | ||||
| +	.cell_post_process = imx_ocotp_cell_pp, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx6q_params = { | ||||
| @@ -530,6 +551,7 @@ static const struct ocotp_params imx8mq_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx8mm_params = { | ||||
| @@ -537,6 +559,7 @@ static const struct ocotp_params imx8mm_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx8mn_params = { | ||||
| @@ -544,6 +567,7 @@ static const struct ocotp_params imx8mn_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx8mp_params = { | ||||
| @@ -551,6 +575,7 @@ static const struct ocotp_params imx8mp_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_8MP, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id imx_ocotp_dt_ids[] = { | ||||
| @@ -0,0 +1,68 @@ | ||||
| From f6c052afe6f802d87c74153b7a57c43b2e9faf07 Mon Sep 17 00:00:00 2001 | ||||
| From: Christophe Kerello <christophe.kerello@foss.st.com> | ||||
| Date: Sun, 20 Feb 2022 15:14:31 +0000 | ||||
| Subject: [PATCH] nvmem: core: Fix a conflict between MTD and NVMEM on wp-gpios | ||||
|  property | ||||
|  | ||||
| Wp-gpios property can be used on NVMEM nodes and the same property can | ||||
| be also used on MTD NAND nodes. In case of the wp-gpios property is | ||||
| defined at NAND level node, the GPIO management is done at NAND driver | ||||
| level. Write protect is disabled when the driver is probed or resumed | ||||
| and is enabled when the driver is released or suspended. | ||||
|  | ||||
| When no partitions are defined in the NAND DT node, then the NAND DT node | ||||
| will be passed to NVMEM framework. If wp-gpios property is defined in | ||||
| this node, the GPIO resource is taken twice and the NAND controller | ||||
| driver fails to probe. | ||||
|  | ||||
| It would be possible to set config->wp_gpio at MTD level before calling | ||||
| nvmem_register function but NVMEM framework will toggle this GPIO on | ||||
| each write when this GPIO should only be controlled at NAND level driver | ||||
| to ensure that the Write Protect has not been enabled. | ||||
|  | ||||
| A way to fix this conflict is to add a new boolean flag in nvmem_config | ||||
| named ignore_wp. In case ignore_wp is set, the GPIO resource will | ||||
| be managed by the provider. | ||||
|  | ||||
| Fixes: 2a127da461a9 ("nvmem: add support for the write-protect pin") | ||||
| Cc: stable@vger.kernel.org | ||||
| Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151432.16605-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c           | 2 +- | ||||
|  include/linux/nvmem-provider.h | 4 +++- | ||||
|  2 files changed, 4 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -771,7 +771,7 @@ struct nvmem_device *nvmem_register(cons | ||||
|   | ||||
|  	if (config->wp_gpio) | ||||
|  		nvmem->wp_gpio = config->wp_gpio; | ||||
| -	else | ||||
| +	else if (!config->ignore_wp) | ||||
|  		nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp", | ||||
|  						    GPIOD_OUT_HIGH); | ||||
|  	if (IS_ERR(nvmem->wp_gpio)) { | ||||
| --- a/include/linux/nvmem-provider.h | ||||
| +++ b/include/linux/nvmem-provider.h | ||||
| @@ -70,7 +70,8 @@ struct nvmem_keepout { | ||||
|   * @word_size:	Minimum read/write access granularity. | ||||
|   * @stride:	Minimum read/write access stride. | ||||
|   * @priv:	User context passed to read/write callbacks. | ||||
| - * @wp-gpio:   Write protect pin | ||||
| + * @wp-gpio:	Write protect pin | ||||
| + * @ignore_wp:  Write Protect pin is managed by the provider. | ||||
|   * | ||||
|   * Note: A default "nvmem<id>" name will be assigned to the device if | ||||
|   * no name is specified in its configuration. In such case "<id>" is | ||||
| @@ -92,6 +93,7 @@ struct nvmem_config { | ||||
|  	enum nvmem_type		type; | ||||
|  	bool			read_only; | ||||
|  	bool			root_only; | ||||
| +	bool			ignore_wp; | ||||
|  	struct device_node	*of_node; | ||||
|  	bool			no_of_node; | ||||
|  	nvmem_reg_read_t	reg_read; | ||||
| @@ -0,0 +1,72 @@ | ||||
| From 190fae468592bc2f0efc8b928920f8f712b5831e Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:15 +0000 | ||||
| Subject: [PATCH] nvmem: core: Remove unused devm_nvmem_unregister() | ||||
|  | ||||
| There are no users and seems no will come of the devm_nvmem_unregister(). | ||||
| Remove the function and remove the unused devm_nvmem_match() along with it. | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c           | 22 ---------------------- | ||||
|  include/linux/nvmem-provider.h |  8 -------- | ||||
|  2 files changed, 30 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -945,28 +945,6 @@ struct nvmem_device *devm_nvmem_register | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(devm_nvmem_register); | ||||
|   | ||||
| -static int devm_nvmem_match(struct device *dev, void *res, void *data) | ||||
| -{ | ||||
| -	struct nvmem_device **r = res; | ||||
| - | ||||
| -	return *r == data; | ||||
| -} | ||||
| - | ||||
| -/** | ||||
| - * devm_nvmem_unregister() - Unregister previously registered managed nvmem | ||||
| - * device. | ||||
| - * | ||||
| - * @dev: Device that uses the nvmem device. | ||||
| - * @nvmem: Pointer to previously registered nvmem device. | ||||
| - * | ||||
| - * Return: Will be negative on error or zero on success. | ||||
| - */ | ||||
| -int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) | ||||
| -{ | ||||
| -	return devres_release(dev, devm_nvmem_release, devm_nvmem_match, nvmem); | ||||
| -} | ||||
| -EXPORT_SYMBOL(devm_nvmem_unregister); | ||||
| - | ||||
|  static struct nvmem_device *__nvmem_device_get(void *data, | ||||
|  			int (*match)(struct device *dev, const void *data)) | ||||
|  { | ||||
| --- a/include/linux/nvmem-provider.h | ||||
| +++ b/include/linux/nvmem-provider.h | ||||
| @@ -135,8 +135,6 @@ void nvmem_unregister(struct nvmem_devic | ||||
|  struct nvmem_device *devm_nvmem_register(struct device *dev, | ||||
|  					 const struct nvmem_config *cfg); | ||||
|   | ||||
| -int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem); | ||||
| - | ||||
|  void nvmem_add_cell_table(struct nvmem_cell_table *table); | ||||
|  void nvmem_del_cell_table(struct nvmem_cell_table *table); | ||||
|   | ||||
| @@ -155,12 +153,6 @@ devm_nvmem_register(struct device *dev, | ||||
|  	return nvmem_register(c); | ||||
|  } | ||||
|   | ||||
| -static inline int | ||||
| -devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) | ||||
| -{ | ||||
| -	return -EOPNOTSUPP; | ||||
| -} | ||||
| - | ||||
|  static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} | ||||
|  static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} | ||||
|   | ||||
| @@ -0,0 +1,58 @@ | ||||
| From 5825b2c6762611e67ccaf3ccf64485365a120f0b Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:16 +0000 | ||||
| Subject: [PATCH] nvmem: core: Use devm_add_action_or_reset() | ||||
|  | ||||
| Slightly simplify the devm_nvmem_register() by using the | ||||
| devm_add_action_or_reset(). | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 22 +++++++++------------- | ||||
|  1 file changed, 9 insertions(+), 13 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -907,9 +907,9 @@ void nvmem_unregister(struct nvmem_devic | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_unregister); | ||||
|   | ||||
| -static void devm_nvmem_release(struct device *dev, void *res) | ||||
| +static void devm_nvmem_unregister(void *nvmem) | ||||
|  { | ||||
| -	nvmem_unregister(*(struct nvmem_device **)res); | ||||
| +	nvmem_unregister(nvmem); | ||||
|  } | ||||
|   | ||||
|  /** | ||||
| @@ -926,20 +926,16 @@ static void devm_nvmem_release(struct de | ||||
|  struct nvmem_device *devm_nvmem_register(struct device *dev, | ||||
|  					 const struct nvmem_config *config) | ||||
|  { | ||||
| -	struct nvmem_device **ptr, *nvmem; | ||||
| - | ||||
| -	ptr = devres_alloc(devm_nvmem_release, sizeof(*ptr), GFP_KERNEL); | ||||
| -	if (!ptr) | ||||
| -		return ERR_PTR(-ENOMEM); | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	int ret; | ||||
|   | ||||
|  	nvmem = nvmem_register(config); | ||||
| +	if (IS_ERR(nvmem)) | ||||
| +		return nvmem; | ||||
|   | ||||
| -	if (!IS_ERR(nvmem)) { | ||||
| -		*ptr = nvmem; | ||||
| -		devres_add(dev, ptr); | ||||
| -	} else { | ||||
| -		devres_free(ptr); | ||||
| -	} | ||||
| +	ret = devm_add_action_or_reset(dev, devm_nvmem_unregister, nvmem); | ||||
| +	if (ret) | ||||
| +		return ERR_PTR(ret); | ||||
|   | ||||
|  	return nvmem; | ||||
|  } | ||||
| @@ -0,0 +1,30 @@ | ||||
| From 8c751e0d9a5264376935a84429a2d468c8877d99 Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:17 +0000 | ||||
| Subject: [PATCH] nvmem: core: Check input parameter for NULL in | ||||
|  nvmem_unregister() | ||||
|  | ||||
| nvmem_unregister() frees resources and standard pattern is to allow | ||||
| caller to not care if it's NULL or not. This will reduce burden on | ||||
| the callers to perform this check. | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 3 ++- | ||||
|  1 file changed, 2 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -903,7 +903,8 @@ static void nvmem_device_release(struct | ||||
|   */ | ||||
|  void nvmem_unregister(struct nvmem_device *nvmem) | ||||
|  { | ||||
| -	kref_put(&nvmem->refcnt, nvmem_device_release); | ||||
| +	if (nvmem) | ||||
| +		kref_put(&nvmem->refcnt, nvmem_device_release); | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_unregister); | ||||
|   | ||||
| @@ -0,0 +1,29 @@ | ||||
| From 05196facc052385960028ac634447ecf6c764ec3 Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Sun, 20 Feb 2022 15:15:18 +0000 | ||||
| Subject: [PATCH] nvmem: qfprom: fix kerneldoc warning | ||||
|  | ||||
| This patch fixes below kernel doc warning, | ||||
| warning: expecting prototype for qfprom_efuse_reg_write(). | ||||
| Prototype was for qfprom_reg_write() instead | ||||
|  | ||||
| No code changes. | ||||
|  | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-5-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/qfprom.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/qfprom.c | ||||
| +++ b/drivers/nvmem/qfprom.c | ||||
| @@ -244,7 +244,7 @@ err_clk_prepared: | ||||
|  } | ||||
|   | ||||
|  /** | ||||
| - * qfprom_efuse_reg_write() - Write to fuses. | ||||
| + * qfprom_reg_write() - Write to fuses. | ||||
|   * @context: Our driver data. | ||||
|   * @reg:     The offset to write at. | ||||
|   * @_val:    Pointer to data to write. | ||||
| @@ -0,0 +1,38 @@ | ||||
| From 07ae4fde9efada7878e1383d6ccc7da70315ca23 Mon Sep 17 00:00:00 2001 | ||||
| From: Samuel Holland <samuel@sholland.org> | ||||
| Date: Sun, 20 Feb 2022 15:15:20 +0000 | ||||
| Subject: [PATCH] nvmem: sunxi_sid: Add support for D1 variant | ||||
|  | ||||
| D1 has a smaller eFuse block than some other recent SoCs, and it no | ||||
| longer requires a workaround to read the eFuse data. | ||||
|  | ||||
| Signed-off-by: Samuel Holland <samuel@sholland.org> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-7-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/sunxi_sid.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/sunxi_sid.c | ||||
| +++ b/drivers/nvmem/sunxi_sid.c | ||||
| @@ -184,6 +184,11 @@ static const struct sunxi_sid_cfg sun8i_ | ||||
|  	.need_register_readout = true, | ||||
|  }; | ||||
|   | ||||
| +static const struct sunxi_sid_cfg sun20i_d1_cfg = { | ||||
| +	.value_offset = 0x200, | ||||
| +	.size = 0x100, | ||||
| +}; | ||||
| + | ||||
|  static const struct sunxi_sid_cfg sun50i_a64_cfg = { | ||||
|  	.value_offset = 0x200, | ||||
|  	.size = 0x100, | ||||
| @@ -200,6 +205,7 @@ static const struct of_device_id sunxi_s | ||||
|  	{ .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg }, | ||||
|  	{ .compatible = "allwinner,sun8i-a83t-sid", .data = &sun50i_a64_cfg }, | ||||
|  	{ .compatible = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_cfg }, | ||||
| +	{ .compatible = "allwinner,sun20i-d1-sid", .data = &sun20i_d1_cfg }, | ||||
|  	{ .compatible = "allwinner,sun50i-a64-sid", .data = &sun50i_a64_cfg }, | ||||
|  	{ .compatible = "allwinner,sun50i-h5-sid", .data = &sun50i_a64_cfg }, | ||||
|  	{ .compatible = "allwinner,sun50i-h6-sid", .data = &sun50i_h6_cfg }, | ||||
| @@ -0,0 +1,28 @@ | ||||
| From 4dc8d89faed9bb05f116fa1794fc955b14910386 Mon Sep 17 00:00:00 2001 | ||||
| From: Xiaoke Wang <xkernel.wang@foxmail.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:21 +0000 | ||||
| Subject: [PATCH] nvmem: meson-mx-efuse: replace unnecessary devm_kstrdup() | ||||
|  | ||||
| Replace unnecessary devm_kstrdup() so to avoid redundant memory allocation. | ||||
|  | ||||
| Suggested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> | ||||
| Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/meson-mx-efuse.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/meson-mx-efuse.c | ||||
| +++ b/drivers/nvmem/meson-mx-efuse.c | ||||
| @@ -209,8 +209,7 @@ static int meson_mx_efuse_probe(struct p | ||||
|  	if (IS_ERR(efuse->base)) | ||||
|  		return PTR_ERR(efuse->base); | ||||
|   | ||||
| -	efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name, | ||||
| -					  GFP_KERNEL); | ||||
| +	efuse->config.name = drvdata->name; | ||||
|  	efuse->config.owner = THIS_MODULE; | ||||
|  	efuse->config.dev = &pdev->dev; | ||||
|  	efuse->config.priv = efuse; | ||||
| @@ -0,0 +1,139 @@ | ||||
| From f78451012b9e159afdba31c3eb69f223a9f42adc Mon Sep 17 00:00:00 2001 | ||||
| From: Michael Walle <michael@walle.cc> | ||||
| Date: Sun, 20 Feb 2022 15:15:23 +0000 | ||||
| Subject: [PATCH] nvmem: add driver for Layerscape SFP (Security Fuse | ||||
|  Processor) | ||||
|  | ||||
| Add support for the Security Fuse Processor found on Layerscape SoCs. | ||||
| This driver implements basic read access. | ||||
|  | ||||
| Signed-off-by: Michael Walle <michael@walle.cc> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-10-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig          | 12 +++++ | ||||
|  drivers/nvmem/Makefile         |  2 + | ||||
|  drivers/nvmem/layerscape-sfp.c | 89 ++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 103 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/layerscape-sfp.c | ||||
|  | ||||
| --- 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_LAYERSCAPE_SFP | ||||
| +	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
| +	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver provides support to read the eFuses on Freescale | ||||
| +	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| +	  unique ID there. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called layerscape-sfp. | ||||
| + | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem. | ||||
|  nvmem-rmem-y			:= rmem.o | ||||
|  obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o | ||||
|  nvmem_brcm_nvram-y		:= brcm_nvram.o | ||||
| +obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
| +nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/layerscape-sfp.c | ||||
| @@ -0,0 +1,89 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0-only | ||||
| +/* | ||||
| + * Layerscape SFP driver | ||||
| + * | ||||
| + * Copyright (c) 2022 Michael Walle <michael@walle.cc> | ||||
| + * | ||||
| + */ | ||||
| + | ||||
| +#include <linux/device.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/mod_devicetable.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/property.h> | ||||
| + | ||||
| +#define LAYERSCAPE_SFP_OTP_OFFSET	0x0200 | ||||
| + | ||||
| +struct layerscape_sfp_priv { | ||||
| +	void __iomem *base; | ||||
| +}; | ||||
| + | ||||
| +struct layerscape_sfp_data { | ||||
| +	int size; | ||||
| +}; | ||||
| + | ||||
| +static int layerscape_sfp_read(void *context, unsigned int offset, void *val, | ||||
| +			       size_t bytes) | ||||
| +{ | ||||
| +	struct layerscape_sfp_priv *priv = context; | ||||
| + | ||||
| +	memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, | ||||
| +		      bytes); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config layerscape_sfp_nvmem_config = { | ||||
| +	.name = "fsl-sfp", | ||||
| +	.reg_read = layerscape_sfp_read, | ||||
| +}; | ||||
| + | ||||
| +static int layerscape_sfp_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	const struct layerscape_sfp_data *data; | ||||
| +	struct layerscape_sfp_priv *priv; | ||||
| +	struct nvmem_device *nvmem; | ||||
| + | ||||
| +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||||
| +	if (!priv) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	priv->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(priv->base)) | ||||
| +		return PTR_ERR(priv->base); | ||||
| + | ||||
| +	data = device_get_match_data(&pdev->dev); | ||||
| + | ||||
| +	layerscape_sfp_nvmem_config.size = data->size; | ||||
| +	layerscape_sfp_nvmem_config.dev = &pdev->dev; | ||||
| +	layerscape_sfp_nvmem_config.priv = priv; | ||||
| + | ||||
| +	nvmem = devm_nvmem_register(&pdev->dev, &layerscape_sfp_nvmem_config); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(nvmem); | ||||
| +} | ||||
| + | ||||
| +static const struct layerscape_sfp_data ls1028a_data = { | ||||
| +	.size = 0x88, | ||||
| +}; | ||||
| + | ||||
| +static const struct of_device_id layerscape_sfp_dt_ids[] = { | ||||
| +	{ .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, | ||||
| +	{}, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, layerscape_sfp_dt_ids); | ||||
| + | ||||
| +static struct platform_driver layerscape_sfp_driver = { | ||||
| +	.probe	= layerscape_sfp_probe, | ||||
| +	.driver = { | ||||
| +		.name	= "layerscape_sfp", | ||||
| +		.of_match_table = layerscape_sfp_dt_ids, | ||||
| +	}, | ||||
| +}; | ||||
| +module_platform_driver(layerscape_sfp_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Michael Walle <michael@walle.cc>"); | ||||
| +MODULE_DESCRIPTION("Layerscape Security Fuse Processor driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,32 @@ | ||||
| From bc5c75e0a5a9400f81a987cc720100ac475fa4d8 Mon Sep 17 00:00:00 2001 | ||||
| From: Knox Chiou <knoxchiou@chromium.org> | ||||
| Date: Wed, 23 Feb 2022 22:35:00 +0000 | ||||
| Subject: [PATCH] nvmem: qfprom: Increase fuse blow timeout to prevent write | ||||
|  fail | ||||
|  | ||||
| sc7180 blow fuses got slightly chances to hit qfprom_reg_write timeout. | ||||
| Current timeout is simply too low. Since blowing fuses is a | ||||
| very rare operation, so the risk associated with overestimating this | ||||
| number is low. | ||||
| Increase fuse blow timeout from 1ms to 10ms. | ||||
|  | ||||
| Reviewed-by: Douglas Anderson <dianders@chromium.org> | ||||
| Signed-off-by: Knox Chiou <knoxchiou@chromium.org> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220223223502.29454-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/qfprom.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/qfprom.c | ||||
| +++ b/drivers/nvmem/qfprom.c | ||||
| @@ -22,7 +22,7 @@ | ||||
|   | ||||
|  /* Amount of time required to hold charge to blow fuse in micro-seconds */ | ||||
|  #define QFPROM_FUSE_BLOW_POLL_US	100 | ||||
| -#define QFPROM_FUSE_BLOW_TIMEOUT_US	1000 | ||||
| +#define QFPROM_FUSE_BLOW_TIMEOUT_US	10000 | ||||
|   | ||||
|  #define QFPROM_BLOW_STATUS_OFFSET	0x048 | ||||
|  #define QFPROM_BLOW_STATUS_BUSY		0x1 | ||||
| @@ -0,0 +1,277 @@ | ||||
| From 8747ec2e9762ed9ae53b3a590938f454b6a1abdf Mon Sep 17 00:00:00 2001 | ||||
| From: Vincent Shih <vincent.sunplus@gmail.com> | ||||
| Date: Wed, 23 Feb 2022 22:35:01 +0000 | ||||
| Subject: [PATCH] nvmem: Add driver for OCOTP in Sunplus SP7021 | ||||
|  | ||||
| Add driver for OCOTP in Sunplus SP7021 | ||||
|  | ||||
| Signed-off-by: Vincent Shih <vincent.sunplus@gmail.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220223223502.29454-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  MAINTAINERS                   |   5 + | ||||
|  drivers/nvmem/Kconfig         |  12 ++ | ||||
|  drivers/nvmem/Makefile        |   2 + | ||||
|  drivers/nvmem/sunplus-ocotp.c | 228 ++++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 247 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/sunplus-ocotp.c | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -312,4 +312,16 @@ config NVMEM_LAYERSCAPE_SFP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called layerscape-sfp. | ||||
|   | ||||
| +config NVMEM_SUNPLUS_OCOTP | ||||
| +	tristate "Sunplus SoC OTP support" | ||||
| +	depends on SOC_SP7021 || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This is a driver for the On-chip OTP controller (OCOTP) available | ||||
| +	  on Sunplus SoCs. It provides access to 128 bytes of one-time | ||||
| +	  programmable eFuse. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-sunplus-ocotp. | ||||
| + | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -63,3 +63,5 @@ obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_ | ||||
|  nvmem_brcm_nvram-y		:= brcm_nvram.o | ||||
|  obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
|  nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
| +obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o | ||||
| +nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/sunplus-ocotp.c | ||||
| @@ -0,0 +1,228 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| + | ||||
| +/* | ||||
| + * The OCOTP driver for Sunplus	SP7021 | ||||
| + * | ||||
| + * Copyright (C) 2019 Sunplus Technology Inc., All rights reserved. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitfield.h> | ||||
| +#include <linux/clk.h> | ||||
| +#include <linux/delay.h> | ||||
| +#include <linux/device.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/iopoll.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/of_device.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +/* | ||||
| + * OTP memory | ||||
| + * Each bank contains 4 words (32 bits). | ||||
| + * Bank 0 starts at offset 0 from the base. | ||||
| + */ | ||||
| + | ||||
| +#define OTP_WORDS_PER_BANK		4 | ||||
| +#define OTP_WORD_SIZE			sizeof(u32) | ||||
| +#define OTP_BIT_ADDR_OF_BANK		(8 * OTP_WORD_SIZE * OTP_WORDS_PER_BANK) | ||||
| +#define QAC628_OTP_NUM_BANKS		8 | ||||
| +#define QAC628_OTP_SIZE			(QAC628_OTP_NUM_BANKS * OTP_WORDS_PER_BANK * OTP_WORD_SIZE) | ||||
| +#define OTP_READ_TIMEOUT_US		200000 | ||||
| + | ||||
| +/* HB_GPIO */ | ||||
| +#define ADDRESS_8_DATA			0x20 | ||||
| + | ||||
| +/* OTP_RX */ | ||||
| +#define OTP_CONTROL_2			0x48 | ||||
| +#define OTP_RD_PERIOD			GENMASK(15, 8) | ||||
| +#define OTP_RD_PERIOD_MASK		~GENMASK(15, 8) | ||||
| +#define CPU_CLOCK			FIELD_PREP(OTP_RD_PERIOD, 30) | ||||
| +#define SEL_BAK_KEY2			BIT(5) | ||||
| +#define SEL_BAK_KEY2_MASK		~BIT(5) | ||||
| +#define SW_TRIM_EN			BIT(4) | ||||
| +#define SW_TRIM_EN_MASK			~BIT(4) | ||||
| +#define SEL_BAK_KEY			BIT(3) | ||||
| +#define SEL_BAK_KEY_MASK		~BIT(3) | ||||
| +#define OTP_READ			BIT(2) | ||||
| +#define OTP_LOAD_SECURE_DATA		BIT(1) | ||||
| +#define OTP_LOAD_SECURE_DATA_MASK	~BIT(1) | ||||
| +#define OTP_DO_CRC			BIT(0) | ||||
| +#define OTP_DO_CRC_MASK			~BIT(0) | ||||
| +#define OTP_STATUS			0x4c | ||||
| +#define OTP_READ_DONE			BIT(4) | ||||
| +#define OTP_READ_DONE_MASK		~BIT(4) | ||||
| +#define OTP_LOAD_SECURE_DONE_MASK	~BIT(2) | ||||
| +#define OTP_READ_ADDRESS		0x50 | ||||
| + | ||||
| +enum base_type { | ||||
| +	HB_GPIO, | ||||
| +	OTPRX, | ||||
| +	BASEMAX, | ||||
| +}; | ||||
| + | ||||
| +struct sp_ocotp_priv { | ||||
| +	struct device *dev; | ||||
| +	void __iomem *base[BASEMAX]; | ||||
| +	struct clk *clk; | ||||
| +}; | ||||
| + | ||||
| +struct sp_ocotp_data { | ||||
| +	int size; | ||||
| +}; | ||||
| + | ||||
| +const struct sp_ocotp_data  sp_otp_v0 = { | ||||
| +	.size = QAC628_OTP_SIZE, | ||||
| +}; | ||||
| + | ||||
| +static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value) | ||||
| +{ | ||||
| +	unsigned int addr_data; | ||||
| +	unsigned int byte_shift; | ||||
| +	unsigned int status; | ||||
| +	int ret; | ||||
| + | ||||
| +	addr_data = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); | ||||
| +	addr_data = addr_data / OTP_WORD_SIZE; | ||||
| + | ||||
| +	byte_shift = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); | ||||
| +	byte_shift = byte_shift % OTP_WORD_SIZE; | ||||
| + | ||||
| +	addr = addr / (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); | ||||
| +	addr = addr * OTP_BIT_ADDR_OF_BANK; | ||||
| + | ||||
| +	writel(readl(otp->base[OTPRX] + OTP_STATUS) & OTP_READ_DONE_MASK & | ||||
| +	       OTP_LOAD_SECURE_DONE_MASK, otp->base[OTPRX] + OTP_STATUS); | ||||
| +	writel(addr, otp->base[OTPRX] + OTP_READ_ADDRESS); | ||||
| +	writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) | OTP_READ, | ||||
| +	       otp->base[OTPRX] + OTP_CONTROL_2); | ||||
| +	writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) & SEL_BAK_KEY2_MASK & SW_TRIM_EN_MASK | ||||
| +	       & SEL_BAK_KEY_MASK & OTP_LOAD_SECURE_DATA_MASK & OTP_DO_CRC_MASK, | ||||
| +	       otp->base[OTPRX] + OTP_CONTROL_2); | ||||
| +	writel((readl(otp->base[OTPRX] + OTP_CONTROL_2) & OTP_RD_PERIOD_MASK) | CPU_CLOCK, | ||||
| +	       otp->base[OTPRX] + OTP_CONTROL_2); | ||||
| + | ||||
| +	ret = readl_poll_timeout(otp->base[OTPRX] + OTP_STATUS, status, | ||||
| +				 status & OTP_READ_DONE, 10, OTP_READ_TIMEOUT_US); | ||||
| + | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	*value = (readl(otp->base[HB_GPIO] + ADDRESS_8_DATA + addr_data * OTP_WORD_SIZE) | ||||
| +		  >> (8 * byte_shift)) & 0xff; | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes) | ||||
| +{ | ||||
| +	struct sp_ocotp_priv *otp = priv; | ||||
| +	unsigned int addr; | ||||
| +	char *buf = value; | ||||
| +	char val[4]; | ||||
| +	int ret; | ||||
| + | ||||
| +	ret = clk_enable(otp->clk); | ||||
| +	if (ret) | ||||
| +		return ret; | ||||
| + | ||||
| +	*buf = 0; | ||||
| +	for (addr = offset; addr < (offset + bytes); addr++) { | ||||
| +		ret = sp_otp_read_real(otp, addr, val); | ||||
| +		if (ret < 0) { | ||||
| +			dev_err(otp->dev, "OTP read fail:%d at %d", ret, addr); | ||||
| +			goto disable_clk; | ||||
| +		} | ||||
| + | ||||
| +		*buf++ = *val; | ||||
| +	} | ||||
| + | ||||
| +disable_clk: | ||||
| +	clk_disable(otp->clk); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config sp_ocotp_nvmem_config = { | ||||
| +	.name = "sp-ocotp", | ||||
| +	.read_only = true, | ||||
| +	.word_size = 1, | ||||
| +	.size = QAC628_OTP_SIZE, | ||||
| +	.stride = 1, | ||||
| +	.reg_read = sp_ocotp_read, | ||||
| +	.owner = THIS_MODULE, | ||||
| +}; | ||||
| + | ||||
| +static int sp_ocotp_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct device *dev = &pdev->dev; | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	struct sp_ocotp_priv *otp; | ||||
| +	struct resource *res; | ||||
| +	int ret; | ||||
| + | ||||
| +	otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); | ||||
| +	if (!otp) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	otp->dev = dev; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio"); | ||||
| +	otp->base[HB_GPIO] = devm_ioremap_resource(dev, res); | ||||
| +	if (IS_ERR(otp->base[HB_GPIO])) | ||||
| +		return PTR_ERR(otp->base[HB_GPIO]); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx"); | ||||
| +	otp->base[OTPRX] = devm_ioremap_resource(dev, res); | ||||
| +	if (IS_ERR(otp->base[OTPRX])) | ||||
| +		return PTR_ERR(otp->base[OTPRX]); | ||||
| + | ||||
| +	otp->clk = devm_clk_get(&pdev->dev, NULL); | ||||
| +	if (IS_ERR(otp->clk)) | ||||
| +		return dev_err_probe(&pdev->dev, PTR_ERR(otp->clk), | ||||
| +						"devm_clk_get fail\n"); | ||||
| + | ||||
| +	ret = clk_prepare(otp->clk); | ||||
| +	if (ret < 0) { | ||||
| +		dev_err(dev, "failed to prepare clk: %d\n", ret); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	sp_ocotp_nvmem_config.priv = otp; | ||||
| +	sp_ocotp_nvmem_config.dev = dev; | ||||
| + | ||||
| +	nvmem = devm_nvmem_register(dev, &sp_ocotp_nvmem_config); | ||||
| +	if (IS_ERR(nvmem)) | ||||
| +		return dev_err_probe(&pdev->dev, PTR_ERR(nvmem), | ||||
| +						"register nvmem device fail\n"); | ||||
| + | ||||
| +	platform_set_drvdata(pdev, nvmem); | ||||
| + | ||||
| +	dev_dbg(dev, "banks:%d x wpb:%d x wsize:%d = %d", | ||||
| +		(int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK, | ||||
| +		(int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE); | ||||
| + | ||||
| +	dev_info(dev, "by Sunplus (C) 2020"); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id sp_ocotp_dt_ids[] = { | ||||
| +	{ .compatible = "sunplus,sp7021-ocotp", .data = &sp_otp_v0 }, | ||||
| +	{ } | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, sp_ocotp_dt_ids); | ||||
| + | ||||
| +static struct platform_driver sp_otp_driver = { | ||||
| +	.probe     = sp_ocotp_probe, | ||||
| +	.driver    = { | ||||
| +		.name           = "sunplus,sp7021-ocotp", | ||||
| +		.of_match_table = sp_ocotp_dt_ids, | ||||
| +	} | ||||
| +}; | ||||
| +module_platform_driver(sp_otp_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Vincent Shih <vincent.sunplus@gmail.com>"); | ||||
| +MODULE_DESCRIPTION("Sunplus On-Chip OTP driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| + | ||||
| @@ -0,0 +1,32 @@ | ||||
| From 6bd0ffeaa389866089e9573b2298ae58d6359b75 Mon Sep 17 00:00:00 2001 | ||||
| From: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Date: Mon, 21 Mar 2022 12:03:24 +0100 | ||||
| Subject: [PATCH] nvmem: bcm-ocotp: mark ACPI device ID table as maybe unused | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| "bcm_otpc_acpi_ids" is used with ACPI_PTR, so a build with !CONFIG_ACPI | ||||
| has a warning: | ||||
|  | ||||
|   drivers/nvmem/bcm-ocotp.c:247:36: error: | ||||
|     ‘bcm_otpc_acpi_ids’ defined but not used [-Werror=unused-const-variable=] | ||||
|  | ||||
| Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Link: https://lore.kernel.org/r/20220321110326.44652-1-krzk@kernel.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/bcm-ocotp.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/bcm-ocotp.c | ||||
| +++ b/drivers/nvmem/bcm-ocotp.c | ||||
| @@ -244,7 +244,7 @@ static const struct of_device_id bcm_otp | ||||
|  }; | ||||
|  MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids); | ||||
|   | ||||
| -static const struct acpi_device_id bcm_otpc_acpi_ids[] = { | ||||
| +static const struct acpi_device_id bcm_otpc_acpi_ids[] __maybe_unused = { | ||||
|  	{ .id = "BRCM0700", .driver_data = (kernel_ulong_t)&otp_map }, | ||||
|  	{ .id = "BRCM0701", .driver_data = (kernel_ulong_t)&otp_map_v2 }, | ||||
|  	{ /* sentinel */ } | ||||
| @@ -0,0 +1,30 @@ | ||||
| From 1066f8156351fcd997125257cea47cf805ba4f6d Mon Sep 17 00:00:00 2001 | ||||
| From: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Date: Mon, 21 Mar 2022 12:03:25 +0100 | ||||
| Subject: [PATCH] nvmem: sunplus-ocotp: staticize sp_otp_v0 | ||||
|  | ||||
| The "sp_otp_v0" file scope variable is not used outside, so make it | ||||
| static to fix warning: | ||||
|  | ||||
|   drivers/nvmem/sunplus-ocotp.c:74:29: sparse: | ||||
|     sparse: symbol 'sp_otp_v0' was not declared. Should it be static? | ||||
|  | ||||
| Reported-by: kernel test robot <lkp@intel.com> | ||||
| Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Link: https://lore.kernel.org/r/20220321110326.44652-2-krzk@kernel.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/sunplus-ocotp.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/sunplus-ocotp.c | ||||
| +++ b/drivers/nvmem/sunplus-ocotp.c | ||||
| @@ -71,7 +71,7 @@ struct sp_ocotp_data { | ||||
|  	int size; | ||||
|  }; | ||||
|   | ||||
| -const struct sp_ocotp_data  sp_otp_v0 = { | ||||
| +static const struct sp_ocotp_data sp_otp_v0 = { | ||||
|  	.size = QAC628_OTP_SIZE, | ||||
|  }; | ||||
|   | ||||
| @@ -0,0 +1,27 @@ | ||||
| From 874dfbcf219ccc42a2cbd187d087c7db82c3024b Mon Sep 17 00:00:00 2001 | ||||
| From: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Date: Mon, 21 Mar 2022 12:03:26 +0100 | ||||
| Subject: [PATCH] nvmem: sunplus-ocotp: drop useless probe confirmation | ||||
|  | ||||
| Printing probe success is discouraged, because we can use tracing for | ||||
| this purpose.  Remove useless print message after Sunplus OCOTP driver | ||||
| probe. | ||||
|  | ||||
| Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Link: https://lore.kernel.org/r/20220321110326.44652-3-krzk@kernel.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/sunplus-ocotp.c | 2 -- | ||||
|  1 file changed, 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/sunplus-ocotp.c | ||||
| +++ b/drivers/nvmem/sunplus-ocotp.c | ||||
| @@ -202,8 +202,6 @@ static int sp_ocotp_probe(struct platfor | ||||
|  		(int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK, | ||||
|  		(int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE); | ||||
|   | ||||
| -	dev_info(dev, "by Sunplus (C) 2020"); | ||||
| - | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| 
 | ||||
| --- a/drivers/nvmem/core.c
 | ||||
| +++ b/drivers/nvmem/core.c
 | ||||
| @@ -462,6 +462,7 @@ static int nvmem_cell_info_to_nvmem_cell
 | ||||
| @@ -467,6 +467,7 @@ static int nvmem_cell_info_to_nvmem_cell
 | ||||
|   | ||||
|  	cell->bit_offset = info->bit_offset; | ||||
|  	cell->nbits = info->nbits; | ||||
| @@ -0,0 +1,130 @@ | ||||
| From b6b7ef932ae838209254f016ecf8862d716a5ced Mon Sep 17 00:00:00 2001 | ||||
| From: Sven Peter <sven@svenpeter.dev> | ||||
| Date: Fri, 29 Apr 2022 17:26:50 +0100 | ||||
| Subject: [PATCH] nvmem: Add Apple eFuse driver | ||||
|  | ||||
| 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> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-6-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig        | 12 ++++++ | ||||
|  drivers/nvmem/Makefile       |  2 + | ||||
|  drivers/nvmem/apple-efuses.c | 80 ++++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 94 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/apple-efuses.c | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -324,4 +324,16 @@ config NVMEM_SUNPLUS_OCOTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-sunplus-ocotp. | ||||
|   | ||||
| +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 | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -65,3 +65,5 @@ obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nv | ||||
|  nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
|  obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o | ||||
|  nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
| +nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/apple-efuses.c | ||||
| @@ -0,0 +1,80 @@ | ||||
| +// 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, | ||||
| +		.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, | ||||
| +	}, | ||||
| +	.probe = apple_efuses_probe, | ||||
| +}; | ||||
| + | ||||
| +module_platform_driver(apple_efuses_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,31 @@ | ||||
| From 517f6e2641a2802dce5a5aa0d18c7d37a35678d2 Mon Sep 17 00:00:00 2001 | ||||
| From: Minghao Chi <chi.minghao@zte.com.cn> | ||||
| Date: Fri, 29 Apr 2022 17:26:54 +0100 | ||||
| Subject: [PATCH] nvmem: qfprom: using pm_runtime_resume_and_get instead of | ||||
|  pm_runtime_get_sync | ||||
|  | ||||
| Using pm_runtime_resume_and_get is more appropriate | ||||
| for simplifing code | ||||
|  | ||||
| Reported-by: Zeal Robot <zealci@zte.com.cn> | ||||
| Signed-off-by: Minghao Chi <chi.minghao@zte.com.cn> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-10-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/qfprom.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/qfprom.c | ||||
| +++ b/drivers/nvmem/qfprom.c | ||||
| @@ -217,9 +217,8 @@ static int qfprom_enable_fuse_blowing(co | ||||
|  		goto err_clk_rate_set; | ||||
|  	} | ||||
|   | ||||
| -	ret = pm_runtime_get_sync(priv->dev); | ||||
| +	ret = pm_runtime_resume_and_get(priv->dev); | ||||
|  	if (ret < 0) { | ||||
| -		pm_runtime_put_noidle(priv->dev); | ||||
|  		dev_err(priv->dev, "Failed to enable power-domain\n"); | ||||
|  		goto err_reg_enable; | ||||
|  	} | ||||
| @@ -0,0 +1,109 @@ | ||||
| From 943eadbdb11314b41eacbcc484dfb7f93e271ff4 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Anderson <sean.anderson@seco.com> | ||||
| Date: Fri, 29 Apr 2022 17:27:00 +0100 | ||||
| Subject: [PATCH] nvmem: sfp: Use regmap | ||||
|  | ||||
| This converts the SFP driver to use regmap. This will allow easily | ||||
| supporting devices with different endians. We disallow byte-level | ||||
| access, as regmap_bulk_read doesn't support it (and it's unclear what | ||||
| the correct result would be when we have an endianness difference). | ||||
|  | ||||
| Signed-off-by: Sean Anderson <sean.anderson@seco.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-16-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig          |  1 + | ||||
|  drivers/nvmem/layerscape-sfp.c | 30 ++++++++++++++++++++++-------- | ||||
|  2 files changed, 23 insertions(+), 8 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -304,6 +304,7 @@ config NVMEM_LAYERSCAPE_SFP | ||||
|  	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
|  	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| +	select REGMAP_MMIO | ||||
|  	help | ||||
|  	  This driver provides support to read the eFuses on Freescale | ||||
|  	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| --- a/drivers/nvmem/layerscape-sfp.c | ||||
| +++ b/drivers/nvmem/layerscape-sfp.c | ||||
| @@ -13,15 +13,17 @@ | ||||
|  #include <linux/nvmem-provider.h> | ||||
|  #include <linux/platform_device.h> | ||||
|  #include <linux/property.h> | ||||
| +#include <linux/regmap.h> | ||||
|   | ||||
|  #define LAYERSCAPE_SFP_OTP_OFFSET	0x0200 | ||||
|   | ||||
|  struct layerscape_sfp_priv { | ||||
| -	void __iomem *base; | ||||
| +	struct regmap *regmap; | ||||
|  }; | ||||
|   | ||||
|  struct layerscape_sfp_data { | ||||
|  	int size; | ||||
| +	enum regmap_endian endian; | ||||
|  }; | ||||
|   | ||||
|  static int layerscape_sfp_read(void *context, unsigned int offset, void *val, | ||||
| @@ -29,15 +31,16 @@ static int layerscape_sfp_read(void *con | ||||
|  { | ||||
|  	struct layerscape_sfp_priv *priv = context; | ||||
|   | ||||
| -	memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, | ||||
| -		      bytes); | ||||
| - | ||||
| -	return 0; | ||||
| +	return regmap_bulk_read(priv->regmap, | ||||
| +				LAYERSCAPE_SFP_OTP_OFFSET + offset, val, | ||||
| +				bytes / 4); | ||||
|  } | ||||
|   | ||||
|  static struct nvmem_config layerscape_sfp_nvmem_config = { | ||||
|  	.name = "fsl-sfp", | ||||
|  	.reg_read = layerscape_sfp_read, | ||||
| +	.word_size = 4, | ||||
| +	.stride = 4, | ||||
|  }; | ||||
|   | ||||
|  static int layerscape_sfp_probe(struct platform_device *pdev) | ||||
| @@ -45,16 +48,26 @@ static int layerscape_sfp_probe(struct p | ||||
|  	const struct layerscape_sfp_data *data; | ||||
|  	struct layerscape_sfp_priv *priv; | ||||
|  	struct nvmem_device *nvmem; | ||||
| +	struct regmap_config config = { 0 }; | ||||
| +	void __iomem *base; | ||||
|   | ||||
|  	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||||
|  	if (!priv) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| -	priv->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| -	if (IS_ERR(priv->base)) | ||||
| -		return PTR_ERR(priv->base); | ||||
| +	base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(base)) | ||||
| +		return PTR_ERR(base); | ||||
|   | ||||
|  	data = device_get_match_data(&pdev->dev); | ||||
| +	config.reg_bits = 32; | ||||
| +	config.reg_stride = 4; | ||||
| +	config.val_bits = 32; | ||||
| +	config.val_format_endian = data->endian; | ||||
| +	config.max_register = LAYERSCAPE_SFP_OTP_OFFSET + data->size - 4; | ||||
| +	priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, &config); | ||||
| +	if (IS_ERR(priv->regmap)) | ||||
| +		return PTR_ERR(priv->regmap); | ||||
|   | ||||
|  	layerscape_sfp_nvmem_config.size = data->size; | ||||
|  	layerscape_sfp_nvmem_config.dev = &pdev->dev; | ||||
| @@ -67,6 +80,7 @@ static int layerscape_sfp_probe(struct p | ||||
|   | ||||
|  static const struct layerscape_sfp_data ls1028a_data = { | ||||
|  	.size = 0x88, | ||||
| +	.endian = REGMAP_ENDIAN_LITTLE, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id layerscape_sfp_dt_ids[] = { | ||||
| @@ -0,0 +1,38 @@ | ||||
| From 33a1c6618677fe33f8e84cb7bedc45abbce89a50 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Anderson <sean.anderson@seco.com> | ||||
| Date: Fri, 29 Apr 2022 17:27:01 +0100 | ||||
| Subject: [PATCH] nvmem: sfp: Add support for TA 2.1 devices | ||||
|  | ||||
| This adds support for Trust Architecture (TA) 2.1 devices to the SFP driver. | ||||
| There are few differences between TA 2.1 and TA 3.0, especially for | ||||
| read-only support, so just re-use the existing data. | ||||
|  | ||||
| Signed-off-by: Sean Anderson <sean.anderson@seco.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-17-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/layerscape-sfp.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/layerscape-sfp.c | ||||
| +++ b/drivers/nvmem/layerscape-sfp.c | ||||
| @@ -78,12 +78,18 @@ static int layerscape_sfp_probe(struct p | ||||
|  	return PTR_ERR_OR_ZERO(nvmem); | ||||
|  } | ||||
|   | ||||
| +static const struct layerscape_sfp_data ls1021a_data = { | ||||
| +	.size = 0x88, | ||||
| +	.endian = REGMAP_ENDIAN_BIG, | ||||
| +}; | ||||
| + | ||||
|  static const struct layerscape_sfp_data ls1028a_data = { | ||||
|  	.size = 0x88, | ||||
|  	.endian = REGMAP_ENDIAN_LITTLE, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id layerscape_sfp_dt_ids[] = { | ||||
| +	{ .compatible = "fsl,ls1021a-sfp", .data = &ls1021a_data }, | ||||
|  	{ .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, | ||||
|  	{}, | ||||
|  }; | ||||
| @@ -0,0 +1,389 @@ | ||||
| From 98830350d3fc824c1ff5c338140fe20f041a5916 Mon Sep 17 00:00:00 2001 | ||||
| From: Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| Date: Wed, 6 Jul 2022 11:06:22 +0100 | ||||
| Subject: [PATCH] nvmem: microchip-otpc: add support | ||||
|  | ||||
| Add support for Microchip OTP controller available on SAMA7G5. The OTPC | ||||
| controls the access to a non-volatile memory. The memory behind OTPC is | ||||
| organized into packets, packets are composed by a fixed length header | ||||
| (4 bytes long) and a variable length payload (payload length is available | ||||
| in the header). When software request the data at an offset in memory | ||||
| the OTPC will return (via header + data registers) the whole packet that | ||||
| has a word at that offset. For the OTP memory layout like below: | ||||
|  | ||||
| offset  OTP Memory layout | ||||
|  | ||||
|          .           . | ||||
|          .    ...    . | ||||
|          .           . | ||||
| 0x0E     +-----------+	<--- packet X | ||||
|          | header  X | | ||||
| 0x12     +-----------+ | ||||
|          | payload X | | ||||
| 0x16     |           | | ||||
|          |           | | ||||
| 0x1A     |           | | ||||
|          +-----------+ | ||||
|          .           . | ||||
|          .    ...    . | ||||
|          .           . | ||||
|  | ||||
| if user requests data at address 0x16 the data started at 0x0E will be | ||||
| returned by controller. User will be able to fetch the whole packet | ||||
| starting at 0x0E (or parts of the packet) via proper registers. The same | ||||
| packet will be returned if software request the data at offset 0x0E or | ||||
| 0x12 or 0x1A. | ||||
|  | ||||
| The OTP will be populated by Microchip with at least 2 packets first one | ||||
| being boot configuration packet and the 2nd one being temperature | ||||
| calibration packet. The packet order will be preserved b/w different chip | ||||
| revisions but the packet sizes may change. | ||||
|  | ||||
| For the above reasons and to keep the same software able to work on all | ||||
| chip variants the read function of the driver is working with a packet | ||||
| id instead of an offset in OTP memory. | ||||
|  | ||||
| Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220706100627.6534-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  MAINTAINERS                    |   8 + | ||||
|  drivers/nvmem/Kconfig          |   7 + | ||||
|  drivers/nvmem/Makefile         |   2 + | ||||
|  drivers/nvmem/microchip-otpc.c | 288 +++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 305 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/microchip-otpc.c | ||||
|  | ||||
| --- a/MAINTAINERS | ||||
| +++ b/MAINTAINERS | ||||
| @@ -11565,6 +11565,14 @@ S:	Supported | ||||
|  F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt | ||||
|  F:	drivers/mtd/nand/raw/atmel/* | ||||
|   | ||||
| +MICROCHIP OTPC DRIVER | ||||
| +M:	Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| +L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| +S:	Supported | ||||
| +F:	Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml | ||||
| +F:	drivers/nvmem/microchip-otpc.c | ||||
| +F:	dt-bindings/nvmem/microchip,sama7g5-otpc.h | ||||
| + | ||||
|  MICROCHIP PWM DRIVER | ||||
|  M:	Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
|  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -107,6 +107,13 @@ config MTK_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called efuse-mtk. | ||||
|   | ||||
| +config MICROCHIP_OTPC | ||||
| +	tristate "Microchip OTPC support" | ||||
| +	depends on ARCH_AT91 || COMPILE_TEST | ||||
| +	help | ||||
| +	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| +	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
| + | ||||
|  config NVMEM_NINTENDO_OTP | ||||
|  	tristate "Nintendo Wii and Wii U OTP Support" | ||||
|  	depends on WII || COMPILE_TEST | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -67,3 +67,5 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvm | ||||
|  nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
|  nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| +obj-$(CONFIG_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| +nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/microchip-otpc.c | ||||
| @@ -0,0 +1,288 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| +/* | ||||
| + * OTP Memory controller | ||||
| + * | ||||
| + * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries | ||||
| + * | ||||
| + * Author: Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitfield.h> | ||||
| +#include <linux/iopoll.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#define MCHP_OTPC_CR			(0x0) | ||||
| +#define MCHP_OTPC_CR_READ		BIT(6) | ||||
| +#define MCHP_OTPC_MR			(0x4) | ||||
| +#define MCHP_OTPC_MR_ADDR		GENMASK(31, 16) | ||||
| +#define MCHP_OTPC_AR			(0x8) | ||||
| +#define MCHP_OTPC_SR			(0xc) | ||||
| +#define MCHP_OTPC_SR_READ		BIT(6) | ||||
| +#define MCHP_OTPC_HR			(0x20) | ||||
| +#define MCHP_OTPC_HR_SIZE		GENMASK(15, 8) | ||||
| +#define MCHP_OTPC_DR			(0x24) | ||||
| + | ||||
| +#define MCHP_OTPC_NAME			"mchp-otpc" | ||||
| +#define MCHP_OTPC_SIZE			(11 * 1024) | ||||
| + | ||||
| +/** | ||||
| + * struct mchp_otpc - OTPC private data structure | ||||
| + * @base: base address | ||||
| + * @dev: struct device pointer | ||||
| + * @packets: list of packets in OTP memory | ||||
| + * @npackets: number of packets in OTP memory | ||||
| + */ | ||||
| +struct mchp_otpc { | ||||
| +	void __iomem *base; | ||||
| +	struct device *dev; | ||||
| +	struct list_head packets; | ||||
| +	u32 npackets; | ||||
| +}; | ||||
| + | ||||
| +/** | ||||
| + * struct mchp_otpc_packet - OTPC packet data structure | ||||
| + * @list: list head | ||||
| + * @id: packet ID | ||||
| + * @offset: packet offset (in words) in OTP memory | ||||
| + */ | ||||
| +struct mchp_otpc_packet { | ||||
| +	struct list_head list; | ||||
| +	u32 id; | ||||
| +	u32 offset; | ||||
| +}; | ||||
| + | ||||
| +static struct mchp_otpc_packet *mchp_otpc_id_to_packet(struct mchp_otpc *otpc, | ||||
| +						       u32 id) | ||||
| +{ | ||||
| +	struct mchp_otpc_packet *packet; | ||||
| + | ||||
| +	if (id >= otpc->npackets) | ||||
| +		return NULL; | ||||
| + | ||||
| +	list_for_each_entry(packet, &otpc->packets, list) { | ||||
| +		if (packet->id == id) | ||||
| +			return packet; | ||||
| +	} | ||||
| + | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| +static int mchp_otpc_prepare_read(struct mchp_otpc *otpc, | ||||
| +				  unsigned int offset) | ||||
| +{ | ||||
| +	u32 tmp; | ||||
| + | ||||
| +	/* Set address. */ | ||||
| +	tmp = readl_relaxed(otpc->base + MCHP_OTPC_MR); | ||||
| +	tmp &= ~MCHP_OTPC_MR_ADDR; | ||||
| +	tmp |= FIELD_PREP(MCHP_OTPC_MR_ADDR, offset); | ||||
| +	writel_relaxed(tmp, otpc->base + MCHP_OTPC_MR); | ||||
| + | ||||
| +	/* Set read. */ | ||||
| +	tmp = readl_relaxed(otpc->base + MCHP_OTPC_CR); | ||||
| +	tmp |= MCHP_OTPC_CR_READ; | ||||
| +	writel_relaxed(tmp, otpc->base + MCHP_OTPC_CR); | ||||
| + | ||||
| +	/* Wait for packet to be transferred into temporary buffers. */ | ||||
| +	return read_poll_timeout(readl_relaxed, tmp, !(tmp & MCHP_OTPC_SR_READ), | ||||
| +				 10000, 2000, false, otpc->base + MCHP_OTPC_SR); | ||||
| +} | ||||
| + | ||||
| +/* | ||||
| + * OTPC memory is organized into packets. Each packets contains a header and | ||||
| + * a payload. Header is 4 bytes long and contains the size of the payload. | ||||
| + * Payload size varies. The memory footprint is something as follows: | ||||
| + * | ||||
| + * Memory offset  Memory footprint     Packet ID | ||||
| + * -------------  ----------------     --------- | ||||
| + * | ||||
| + * 0x0            +------------+   <-- packet 0 | ||||
| + *                | header  0  | | ||||
| + * 0x4            +------------+ | ||||
| + *                | payload 0  | | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + * offset1        +------------+   <-- packet 1 | ||||
| + *                | header  1  | | ||||
| + * offset1 + 0x4  +------------+ | ||||
| + *                | payload 1  | | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + * offset2        +------------+   <-- packet 2 | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + * offsetN        +------------+   <-- packet N | ||||
| + *                | header  N  | | ||||
| + * offsetN + 0x4  +------------+ | ||||
| + *                | payload N  | | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + *                +------------+ | ||||
| + * | ||||
| + * where offset1, offset2, offsetN depends on the size of payload 0, payload 1, | ||||
| + * payload N-1. | ||||
| + * | ||||
| + * The access to memory is done on a per packet basis: the control registers | ||||
| + * need to be updated with an offset address (within a packet range) and the | ||||
| + * data registers will be update by controller with information contained by | ||||
| + * that packet. E.g. if control registers are updated with any address within | ||||
| + * the range [offset1, offset2) the data registers are updated by controller | ||||
| + * with packet 1. Header data is accessible though MCHP_OTPC_HR register. | ||||
| + * Payload data is accessible though MCHP_OTPC_DR and MCHP_OTPC_AR registers. | ||||
| + * There is no direct mapping b/w the offset requested by software and the | ||||
| + * offset returned by hardware. | ||||
| + * | ||||
| + * For this, the read function will return the first requested bytes in the | ||||
| + * packet. The user will have to be aware of the memory footprint before doing | ||||
| + * the read request. | ||||
| + */ | ||||
| +static int mchp_otpc_read(void *priv, unsigned int off, void *val, | ||||
| +			  size_t bytes) | ||||
| +{ | ||||
| +	struct mchp_otpc *otpc = priv; | ||||
| +	struct mchp_otpc_packet *packet; | ||||
| +	u32 *buf = val; | ||||
| +	u32 offset; | ||||
| +	size_t len = 0; | ||||
| +	int ret, payload_size; | ||||
| + | ||||
| +	/* | ||||
| +	 * We reach this point with off being multiple of stride = 4 to | ||||
| +	 * be able to cross the subsystem. Inside the driver we use continuous | ||||
| +	 * unsigned integer numbers for packet id, thus devide off by 4 | ||||
| +	 * before passing it to mchp_otpc_id_to_packet(). | ||||
| +	 */ | ||||
| +	packet = mchp_otpc_id_to_packet(otpc, off / 4); | ||||
| +	if (!packet) | ||||
| +		return -EINVAL; | ||||
| +	offset = packet->offset; | ||||
| + | ||||
| +	while (len < bytes) { | ||||
| +		ret = mchp_otpc_prepare_read(otpc, offset); | ||||
| +		if (ret) | ||||
| +			return ret; | ||||
| + | ||||
| +		/* Read and save header content. */ | ||||
| +		*buf++ = readl_relaxed(otpc->base + MCHP_OTPC_HR); | ||||
| +		len += sizeof(*buf); | ||||
| +		offset++; | ||||
| +		if (len >= bytes) | ||||
| +			break; | ||||
| + | ||||
| +		/* Read and save payload content. */ | ||||
| +		payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, *(buf - 1)); | ||||
| +		writel_relaxed(0UL, otpc->base + MCHP_OTPC_AR); | ||||
| +		do { | ||||
| +			*buf++ = readl_relaxed(otpc->base + MCHP_OTPC_DR); | ||||
| +			len += sizeof(*buf); | ||||
| +			offset++; | ||||
| +			payload_size--; | ||||
| +		} while (payload_size >= 0 && len < bytes); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size) | ||||
| +{ | ||||
| +	struct mchp_otpc_packet *packet; | ||||
| +	u32 word, word_pos = 0, id = 0, npackets = 0, payload_size; | ||||
| +	int ret; | ||||
| + | ||||
| +	INIT_LIST_HEAD(&otpc->packets); | ||||
| +	*size = 0; | ||||
| + | ||||
| +	while (*size < MCHP_OTPC_SIZE) { | ||||
| +		ret = mchp_otpc_prepare_read(otpc, word_pos); | ||||
| +		if (ret) | ||||
| +			return ret; | ||||
| + | ||||
| +		word = readl_relaxed(otpc->base + MCHP_OTPC_HR); | ||||
| +		payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, word); | ||||
| +		if (!payload_size) | ||||
| +			break; | ||||
| + | ||||
| +		packet = devm_kzalloc(otpc->dev, sizeof(*packet), GFP_KERNEL); | ||||
| +		if (!packet) | ||||
| +			return -ENOMEM; | ||||
| + | ||||
| +		packet->id = id++; | ||||
| +		packet->offset = word_pos; | ||||
| +		INIT_LIST_HEAD(&packet->list); | ||||
| +		list_add_tail(&packet->list, &otpc->packets); | ||||
| + | ||||
| +		/* Count size by adding header and paload sizes. */ | ||||
| +		*size += 4 * (payload_size + 1); | ||||
| +		/* Next word: this packet (header, payload) position + 1. */ | ||||
| +		word_pos += payload_size + 2; | ||||
| + | ||||
| +		npackets++; | ||||
| +	} | ||||
| + | ||||
| +	otpc->npackets = npackets; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config mchp_nvmem_config = { | ||||
| +	.name = MCHP_OTPC_NAME, | ||||
| +	.type = NVMEM_TYPE_OTP, | ||||
| +	.read_only = true, | ||||
| +	.word_size = 4, | ||||
| +	.stride = 4, | ||||
| +	.reg_read = mchp_otpc_read, | ||||
| +}; | ||||
| + | ||||
| +static int mchp_otpc_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	struct mchp_otpc *otpc; | ||||
| +	u32 size; | ||||
| +	int ret; | ||||
| + | ||||
| +	otpc = devm_kzalloc(&pdev->dev, sizeof(*otpc), GFP_KERNEL); | ||||
| +	if (!otpc) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	otpc->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(otpc->base)) | ||||
| +		return PTR_ERR(otpc->base); | ||||
| + | ||||
| +	otpc->dev = &pdev->dev; | ||||
| +	ret = mchp_otpc_init_packets_list(otpc, &size); | ||||
| +	if (ret) | ||||
| +		return ret; | ||||
| + | ||||
| +	mchp_nvmem_config.dev = otpc->dev; | ||||
| +	mchp_nvmem_config.size = size; | ||||
| +	mchp_nvmem_config.priv = otpc; | ||||
| +	nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(nvmem); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id __maybe_unused mchp_otpc_ids[] = { | ||||
| +	{ .compatible = "microchip,sama7g5-otpc", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, mchp_otpc_ids); | ||||
| + | ||||
| +static struct platform_driver mchp_otpc_driver = { | ||||
| +	.probe = mchp_otpc_probe, | ||||
| +	.driver = { | ||||
| +		.name = MCHP_OTPC_NAME, | ||||
| +		.of_match_table = of_match_ptr(mchp_otpc_ids), | ||||
| +	}, | ||||
| +}; | ||||
| +module_platform_driver(mchp_otpc_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea@microchip.com>"); | ||||
| +MODULE_DESCRIPTION("Microchip SAMA7G5 OTPC driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,32 @@ | ||||
| From f5c97da8037b18d1256a58459fa96ed68e50fb41 Mon Sep 17 00:00:00 2001 | ||||
| From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> | ||||
| Date: Wed, 6 Jul 2022 11:06:27 +0100 | ||||
| Subject: [PATCH] nvmem: mtk-efuse: Simplify with | ||||
|  devm_platform_get_and_ioremap_resource() | ||||
|  | ||||
| Convert platform_get_resource(), devm_ioremap_resource() to a single | ||||
| call to devm_platform_get_and_ioremap_resource(), as this is exactly | ||||
| what this function does. | ||||
|  | ||||
| No functional changes. | ||||
|  | ||||
| Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220706100627.6534-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/mtk-efuse.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/mtk-efuse.c | ||||
| +++ b/drivers/nvmem/mtk-efuse.c | ||||
| @@ -41,8 +41,7 @@ static int mtk_efuse_probe(struct platfo | ||||
|  	if (!priv) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| -	priv->base = devm_ioremap_resource(dev, res); | ||||
| +	priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); | ||||
|  	if (IS_ERR(priv->base)) | ||||
|  		return PTR_ERR(priv->base); | ||||
|   | ||||
| @@ -0,0 +1,52 @@ | ||||
| From bd1244561fa2a4531ded40dbf09c9599084f8b29 Mon Sep 17 00:00:00 2001 | ||||
| From: Gaosheng Cui <cuigaosheng1@huawei.com> | ||||
| Date: Fri, 16 Sep 2022 13:04:02 +0100 | ||||
| Subject: [PATCH] nvmem: core: Fix memleak in nvmem_register() | ||||
|  | ||||
| dev_set_name will alloc memory for nvmem->dev.kobj.name in | ||||
| nvmem_register, when nvmem_validate_keepouts failed, nvmem's | ||||
| memory will be freed and return, but nobody will free memory | ||||
| for nvmem->dev.kobj.name, there will be memleak, so moving | ||||
| nvmem_validate_keepouts() after device_register() and let | ||||
| the device core deal with cleaning name in error cases. | ||||
|  | ||||
| Fixes: de0534df9347 ("nvmem: core: fix error handling while validating keepout regions") | ||||
| Cc: stable@vger.kernel.org | ||||
| Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916120402.38753-1-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 15 ++++++--------- | ||||
|  1 file changed, 6 insertions(+), 9 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -829,21 +829,18 @@ struct nvmem_device *nvmem_register(cons | ||||
|  	nvmem->dev.groups = nvmem_dev_groups; | ||||
|  #endif | ||||
|   | ||||
| -	if (nvmem->nkeepout) { | ||||
| -		rval = nvmem_validate_keepouts(nvmem); | ||||
| -		if (rval) { | ||||
| -			ida_free(&nvmem_ida, nvmem->id); | ||||
| -			kfree(nvmem); | ||||
| -			return ERR_PTR(rval); | ||||
| -		} | ||||
| -	} | ||||
| - | ||||
|  	dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); | ||||
|   | ||||
|  	rval = device_register(&nvmem->dev); | ||||
|  	if (rval) | ||||
|  		goto err_put_device; | ||||
|   | ||||
| +	if (nvmem->nkeepout) { | ||||
| +		rval = nvmem_validate_keepouts(nvmem); | ||||
| +		if (rval) | ||||
| +			goto err_device_del; | ||||
| +	} | ||||
| + | ||||
|  	if (config->compat) { | ||||
|  		rval = nvmem_sysfs_setup_compat(nvmem, config); | ||||
|  		if (rval) | ||||
| @@ -1,6 +1,6 @@ | ||||
| From f955dc14450695564926711cf9fa8e1d5d854302 Mon Sep 17 00:00:00 2001 | ||||
| From d5542923f200f95bddf524f36fd495f78aa28e3c Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 15 Jun 2022 21:43:00 +0200 | ||||
| Date: Fri, 16 Sep 2022 13:20:48 +0100 | ||||
| Subject: [PATCH] nvmem: add driver handling U-Boot environment variables | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -22,16 +22,24 @@ Kernel-parsed NVMEM cells can be read however by Linux drivers. This may | ||||
| be useful for Ethernet drivers for reading device MAC address which is | ||||
| often stored as U-Boot env variable. | ||||
| 
 | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de> | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  MAINTAINERS                |   1 + | ||||
|  drivers/nvmem/Kconfig      |  13 +++ | ||||
|  drivers/nvmem/Makefile     |   2 + | ||||
|  drivers/nvmem/u-boot-env.c | 218 +++++++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 234 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/u-boot-env.c | ||||
| 
 | ||||
| --- a/drivers/nvmem/Kconfig
 | ||||
| +++ b/drivers/nvmem/Kconfig
 | ||||
| @@ -300,4 +300,17 @@ config NVMEM_BRCM_NVRAM
 | ||||
|  	  This driver provides support for Broadcom's NVRAM that can be accessed | ||||
|  	  using I/O mapping. | ||||
| @@ -344,4 +344,17 @@ config NVMEM_APPLE_EFUSES
 | ||||
|  	  This driver can also be built as a module. If so, the module will | ||||
|  	  be called nvmem-apple-efuses. | ||||
|   | ||||
| +config NVMEM_U_BOOT_ENV
 | ||||
| +	tristate "U-Boot environment variables support"
 | ||||
| @@ -49,10 +57,10 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile
 | ||||
| +++ b/drivers/nvmem/Makefile
 | ||||
| @@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.
 | ||||
|  nvmem-rmem-y			:= rmem.o | ||||
|  obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o | ||||
|  nvmem_brcm_nvram-y		:= brcm_nvram.o | ||||
| @@ -69,3 +69,5 @@ obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvme
 | ||||
|  nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
|  obj-$(CONFIG_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
|  nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
| +obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o
 | ||||
| +nvmem_u-boot-env-y		:= u-boot-env.o
 | ||||
| --- /dev/null
 | ||||
| @@ -0,0 +1,47 @@ | ||||
| From 5544e90c81261e82e02bbf7c6015a4b9c8c825ef Mon Sep 17 00:00:00 2001 | ||||
| From: Gaosheng Cui <cuigaosheng1@huawei.com> | ||||
| Date: Fri, 16 Sep 2022 13:20:50 +0100 | ||||
| Subject: [PATCH] nvmem: core: add error handling for dev_set_name | ||||
|  | ||||
| The type of return value of dev_set_name is int, which may return | ||||
| wrong result, so we add error handling for it to reclaim memory | ||||
| of nvmem resource, and return early when an error occurs. | ||||
|  | ||||
| Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 12 +++++++++--- | ||||
|  1 file changed, 9 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -810,18 +810,24 @@ struct nvmem_device *nvmem_register(cons | ||||
|   | ||||
|  	switch (config->id) { | ||||
|  	case NVMEM_DEVID_NONE: | ||||
| -		dev_set_name(&nvmem->dev, "%s", config->name); | ||||
| +		rval = dev_set_name(&nvmem->dev, "%s", config->name); | ||||
|  		break; | ||||
|  	case NVMEM_DEVID_AUTO: | ||||
| -		dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id); | ||||
| +		rval = dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id); | ||||
|  		break; | ||||
|  	default: | ||||
| -		dev_set_name(&nvmem->dev, "%s%d", | ||||
| +		rval = dev_set_name(&nvmem->dev, "%s%d", | ||||
|  			     config->name ? : "nvmem", | ||||
|  			     config->name ? config->id : nvmem->id); | ||||
|  		break; | ||||
|  	} | ||||
|   | ||||
| +	if (rval) { | ||||
| +		ida_free(&nvmem_ida, nvmem->id); | ||||
| +		kfree(nvmem); | ||||
| +		return ERR_PTR(rval); | ||||
| +	} | ||||
| + | ||||
|  	nvmem->read_only = device_property_present(config->dev, "read-only") || | ||||
|  			   config->read_only || !nvmem->reg_write; | ||||
|   | ||||
| @@ -0,0 +1,29 @@ | ||||
| From d3524bb5b9a0c567b853a0024526afe87dde01ed Mon Sep 17 00:00:00 2001 | ||||
| From: Kenneth Lee <klee33@uw.edu> | ||||
| Date: Fri, 16 Sep 2022 13:20:52 +0100 | ||||
| Subject: [PATCH] nvmem: brcm_nvram: Use kzalloc for allocating only one | ||||
|  element | ||||
|  | ||||
| Use kzalloc(...) rather than kcalloc(1, ...) because the number of | ||||
| elements we are specifying in this case is 1, so kzalloc would | ||||
| accomplish the same thing and we can simplify. | ||||
|  | ||||
| Signed-off-by: Kenneth Lee <klee33@uw.edu> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-6-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/brcm_nvram.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/brcm_nvram.c | ||||
| +++ b/drivers/nvmem/brcm_nvram.c | ||||
| @@ -96,7 +96,7 @@ static int brcm_nvram_parse(struct brcm_ | ||||
|   | ||||
|  	len = le32_to_cpu(header.len); | ||||
|   | ||||
| -	data = kcalloc(1, len, GFP_KERNEL); | ||||
| +	data = kzalloc(len, GFP_KERNEL); | ||||
|  	memcpy_fromio(data, priv->base, len); | ||||
|  	data[len - 1] = '\0'; | ||||
|   | ||||
| @@ -0,0 +1,270 @@ | ||||
| From 28fc7c986f01fdcfd28af648be2597624cac0e27 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 16 Sep 2022 13:20:54 +0100 | ||||
| Subject: [PATCH] nvmem: prefix all symbols with NVMEM_ | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This unifies all NVMEM symbols. They follow one style now. | ||||
|  | ||||
| Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> | ||||
| Acked-by: Arnd Bergmann <arnd@arndb.de> | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  arch/arm/configs/multi_v7_defconfig |  6 +++--- | ||||
|  arch/arm/configs/qcom_defconfig     |  2 +- | ||||
|  arch/arm64/configs/defconfig        | 10 +++++----- | ||||
|  arch/mips/configs/ci20_defconfig    |  2 +- | ||||
|  drivers/cpufreq/Kconfig.arm         |  2 +- | ||||
|  drivers/nvmem/Kconfig               | 24 ++++++++++++------------ | ||||
|  drivers/nvmem/Makefile              | 24 ++++++++++++------------ | ||||
|  drivers/soc/mediatek/Kconfig        |  2 +- | ||||
|  drivers/thermal/qcom/Kconfig        |  2 +- | ||||
|  9 files changed, 37 insertions(+), 37 deletions(-) | ||||
|  | ||||
| --- a/arch/arm/configs/multi_v7_defconfig | ||||
| +++ b/arch/arm/configs/multi_v7_defconfig | ||||
| @@ -1085,10 +1085,10 @@ CONFIG_OMAP_USB2=y | ||||
|  CONFIG_TI_PIPE3=y | ||||
|  CONFIG_TWL4030_USB=m | ||||
|  CONFIG_NVMEM_IMX_OCOTP=y | ||||
| -CONFIG_ROCKCHIP_EFUSE=m | ||||
| +CONFIG_NVMEM_ROCKCHIP_EFUSE=m | ||||
|  CONFIG_NVMEM_SUNXI_SID=y | ||||
|  CONFIG_NVMEM_VF610_OCOTP=y | ||||
| -CONFIG_MESON_MX_EFUSE=m | ||||
| +CONFIG_NVMEM_MESON_MX_EFUSE=m | ||||
|  CONFIG_FSI=m | ||||
|  CONFIG_FSI_MASTER_GPIO=m | ||||
|  CONFIG_FSI_MASTER_HUB=m | ||||
| --- a/arch/arm/configs/qcom_defconfig | ||||
| +++ b/arch/arm/configs/qcom_defconfig | ||||
| @@ -257,7 +257,7 @@ CONFIG_PHY_QCOM_APQ8064_SATA=y | ||||
|  CONFIG_PHY_QCOM_IPQ806X_SATA=y | ||||
|  CONFIG_PHY_QCOM_USB_HS=y | ||||
|  CONFIG_PHY_QCOM_USB_HSIC=y | ||||
| -CONFIG_QCOM_QFPROM=y | ||||
| +CONFIG_NVMEM_QCOM_QFPROM=y | ||||
|  CONFIG_INTERCONNECT=y | ||||
|  CONFIG_INTERCONNECT_QCOM=y | ||||
|  CONFIG_INTERCONNECT_QCOM_MSM8974=m | ||||
| --- a/arch/arm64/configs/defconfig | ||||
| +++ b/arch/arm64/configs/defconfig | ||||
| @@ -1022,11 +1022,11 @@ CONFIG_QCOM_L2_PMU=y | ||||
|  CONFIG_QCOM_L3_PMU=y | ||||
|  CONFIG_NVMEM_IMX_OCOTP=y | ||||
|  CONFIG_NVMEM_IMX_OCOTP_SCU=y | ||||
| -CONFIG_QCOM_QFPROM=y | ||||
| -CONFIG_ROCKCHIP_EFUSE=y | ||||
| +CONFIG_NVMEM_QCOM_QFPROM=y | ||||
| +CONFIG_NVMEM_ROCKCHIP_EFUSE=y | ||||
|  CONFIG_NVMEM_SUNXI_SID=y | ||||
| -CONFIG_UNIPHIER_EFUSE=y | ||||
| -CONFIG_MESON_EFUSE=m | ||||
| +CONFIG_NVMEM_UNIPHIER_EFUSE=y | ||||
| +CONFIG_NVMEM_MESON_EFUSE=m | ||||
|  CONFIG_FPGA=y | ||||
|  CONFIG_FPGA_MGR_STRATIX10_SOC=m | ||||
|  CONFIG_FPGA_BRIDGE=m | ||||
| --- a/drivers/cpufreq/Kconfig.arm | ||||
| +++ b/drivers/cpufreq/Kconfig.arm | ||||
| @@ -131,7 +131,7 @@ config ARM_OMAP2PLUS_CPUFREQ | ||||
|  config ARM_QCOM_CPUFREQ_NVMEM | ||||
|  	tristate "Qualcomm nvmem based CPUFreq" | ||||
|  	depends on ARCH_QCOM | ||||
| -	depends on QCOM_QFPROM | ||||
| +	depends on NVMEM_QCOM_QFPROM | ||||
|  	depends on QCOM_SMEM | ||||
|  	select PM_OPP | ||||
|  	help | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -52,7 +52,7 @@ config NVMEM_IMX_OCOTP_SCU | ||||
|  	  This is a driver for the SCU On-Chip OTP Controller (OCOTP) | ||||
|  	  available on i.MX8 SoCs. | ||||
|   | ||||
| -config JZ4780_EFUSE | ||||
| +config NVMEM_JZ4780_EFUSE | ||||
|  	tristate "JZ4780 EFUSE Memory Support" | ||||
|  	depends on MACH_INGENIC || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -96,7 +96,7 @@ config NVMEM_MXS_OCOTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-mxs-ocotp. | ||||
|   | ||||
| -config MTK_EFUSE | ||||
| +config NVMEM_MTK_EFUSE | ||||
|  	tristate "Mediatek SoCs EFUSE support" | ||||
|  	depends on ARCH_MEDIATEK || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -107,7 +107,7 @@ config MTK_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called efuse-mtk. | ||||
|   | ||||
| -config MICROCHIP_OTPC | ||||
| +config NVMEM_MICROCHIP_OTPC | ||||
|  	tristate "Microchip OTPC support" | ||||
|  	depends on ARCH_AT91 || COMPILE_TEST | ||||
|  	help | ||||
| @@ -126,7 +126,7 @@ config NVMEM_NINTENDO_OTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-nintendo-otp. | ||||
|   | ||||
| -config QCOM_QFPROM | ||||
| +config NVMEM_QCOM_QFPROM | ||||
|  	tristate "QCOM QFPROM Support" | ||||
|  	depends on ARCH_QCOM || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -145,7 +145,7 @@ config NVMEM_SPMI_SDAM | ||||
|  	  Qualcomm Technologies, Inc. PMICs. It provides the clients | ||||
|  	  an interface to read/write to the SDAM module's shared memory. | ||||
|   | ||||
| -config ROCKCHIP_EFUSE | ||||
| +config NVMEM_ROCKCHIP_EFUSE | ||||
|  	tristate "Rockchip eFuse Support" | ||||
|  	depends on ARCH_ROCKCHIP || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -156,7 +156,7 @@ config ROCKCHIP_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_rockchip_efuse. | ||||
|   | ||||
| -config ROCKCHIP_OTP | ||||
| +config NVMEM_ROCKCHIP_OTP | ||||
|  	tristate "Rockchip OTP controller support" | ||||
|  	depends on ARCH_ROCKCHIP || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -199,7 +199,7 @@ config NVMEM_SUNXI_SID | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_sunxi_sid. | ||||
|   | ||||
| -config UNIPHIER_EFUSE | ||||
| +config NVMEM_UNIPHIER_EFUSE | ||||
|  	tristate "UniPhier SoCs eFuse support" | ||||
|  	depends on ARCH_UNIPHIER || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -221,7 +221,7 @@ config NVMEM_VF610_OCOTP | ||||
|  	  This driver can also be build as a module. If so, the module will | ||||
|  	  be called nvmem-vf610-ocotp. | ||||
|   | ||||
| -config MESON_EFUSE | ||||
| +config NVMEM_MESON_EFUSE | ||||
|  	tristate "Amlogic Meson GX eFuse Support" | ||||
|  	depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM | ||||
|  	help | ||||
| @@ -231,7 +231,7 @@ config MESON_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_meson_efuse. | ||||
|   | ||||
| -config MESON_MX_EFUSE | ||||
| +config NVMEM_MESON_MX_EFUSE | ||||
|  	tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" | ||||
|  	depends on ARCH_MESON || COMPILE_TEST | ||||
|  	help | ||||
| @@ -251,13 +251,13 @@ config NVMEM_SNVS_LPGPR | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-snvs-lpgpr. | ||||
|   | ||||
| -config RAVE_SP_EEPROM | ||||
| +config NVMEM_RAVE_SP_EEPROM | ||||
|  	tristate "Rave SP EEPROM Support" | ||||
|  	depends on RAVE_SP_CORE | ||||
|  	help | ||||
|  	  Say y here to enable Rave SP EEPROM support. | ||||
|   | ||||
| -config SC27XX_EFUSE | ||||
| +config NVMEM_SC27XX_EFUSE | ||||
|  	tristate "Spreadtrum SC27XX eFuse Support" | ||||
|  	depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -278,7 +278,7 @@ config NVMEM_ZYNQMP | ||||
|   | ||||
|  	  If sure, say yes. If unsure, say no. | ||||
|   | ||||
| -config SPRD_EFUSE | ||||
| +config NVMEM_SPRD_EFUSE | ||||
|  	tristate "Spreadtrum SoC eFuse Support" | ||||
|  	depends on ARCH_SPRD || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -15,7 +15,7 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-i | ||||
|  nvmem-imx-ocotp-y		:= imx-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o | ||||
|  nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o | ||||
| -obj-$(CONFIG_JZ4780_EFUSE)		+= nvmem_jz4780_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_JZ4780_EFUSE)		+= nvmem_jz4780_efuse.o | ||||
|  nvmem_jz4780_efuse-y		:= jz4780-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o | ||||
|  nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o | ||||
| @@ -25,37 +25,37 @@ obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-m | ||||
|  nvmem-mxs-ocotp-y		:= mxs-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_NINTENDO_OTP)	+= nvmem-nintendo-otp.o | ||||
|  nvmem-nintendo-otp-y		:= nintendo-otp.o | ||||
| -obj-$(CONFIG_MTK_EFUSE)		+= nvmem_mtk-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MTK_EFUSE)		+= nvmem_mtk-efuse.o | ||||
|  nvmem_mtk-efuse-y		:= mtk-efuse.o | ||||
| -obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o | ||||
| +obj-$(CONFIG_NVMEM_QCOM_QFPROM)	+= nvmem_qfprom.o | ||||
|  nvmem_qfprom-y			:= qfprom.o | ||||
|  obj-$(CONFIG_NVMEM_SPMI_SDAM)	+= nvmem_qcom-spmi-sdam.o | ||||
|  nvmem_qcom-spmi-sdam-y		+= qcom-spmi-sdam.o | ||||
| -obj-$(CONFIG_ROCKCHIP_EFUSE)	+= nvmem_rockchip_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE)	+= nvmem_rockchip_efuse.o | ||||
|  nvmem_rockchip_efuse-y		:= rockchip-efuse.o | ||||
| -obj-$(CONFIG_ROCKCHIP_OTP)	+= nvmem-rockchip-otp.o | ||||
| +obj-$(CONFIG_NVMEM_ROCKCHIP_OTP)	+= nvmem-rockchip-otp.o | ||||
|  nvmem-rockchip-otp-y		:= rockchip-otp.o | ||||
|  obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o | ||||
|  nvmem_stm32_romem-y 		:= stm32-romem.o | ||||
|  obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o | ||||
|  nvmem_sunxi_sid-y		:= sunxi_sid.o | ||||
| -obj-$(CONFIG_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
|  nvmem-uniphier-efuse-y		:= uniphier-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o | ||||
|  nvmem-vf610-ocotp-y		:= vf610-ocotp.o | ||||
| -obj-$(CONFIG_MESON_EFUSE)	+= nvmem_meson_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_EFUSE)	+= nvmem_meson_efuse.o | ||||
|  nvmem_meson_efuse-y		:= meson-efuse.o | ||||
| -obj-$(CONFIG_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
|  nvmem_meson_mx_efuse-y		:= meson-mx-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_SNVS_LPGPR)	+= nvmem_snvs_lpgpr.o | ||||
|  nvmem_snvs_lpgpr-y		:= snvs_lpgpr.o | ||||
| -obj-$(CONFIG_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
| +obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
|  nvmem-rave-sp-eeprom-y		:= rave-sp-eeprom.o | ||||
| -obj-$(CONFIG_SC27XX_EFUSE)	+= nvmem-sc27xx-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_SC27XX_EFUSE)	+= nvmem-sc27xx-efuse.o | ||||
|  nvmem-sc27xx-efuse-y		:= sc27xx-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_ZYNQMP)	+= nvmem_zynqmp_nvmem.o | ||||
|  nvmem_zynqmp_nvmem-y		:= zynqmp_nvmem.o | ||||
| -obj-$(CONFIG_SPRD_EFUSE)	+= nvmem_sprd_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_SPRD_EFUSE)	+= nvmem_sprd_efuse.o | ||||
|  nvmem_sprd_efuse-y		:= sprd-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o | ||||
|  nvmem-rmem-y			:= rmem.o | ||||
| @@ -67,7 +67,7 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvm | ||||
|  nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
|  nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| -obj-$(CONFIG_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| +obj-$(CONFIG_NVMEM_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
|  nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
|  obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o | ||||
|  nvmem_u-boot-env-y		:= u-boot-env.o | ||||
| --- a/drivers/thermal/qcom/Kconfig | ||||
| +++ b/drivers/thermal/qcom/Kconfig | ||||
| @@ -1,7 +1,7 @@ | ||||
|  # SPDX-License-Identifier: GPL-2.0-only | ||||
|  config QCOM_TSENS | ||||
|  	tristate "Qualcomm TSENS Temperature Alarm" | ||||
| -	depends on QCOM_QFPROM | ||||
| +	depends on NVMEM_QCOM_QFPROM | ||||
|  	depends on ARCH_QCOM || COMPILE_TEST | ||||
|  	help | ||||
|  	  This enables the thermal sysfs driver for the TSENS device. It shows | ||||
| @@ -0,0 +1,535 @@ | ||||
| From a06d9e5a63b7c2f622c908cd9600ce735e70f7c6 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 16 Sep 2022 13:20:55 +0100 | ||||
| Subject: [PATCH] nvmem: sort config symbols alphabetically | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| 1. Match what most subsystems do | ||||
| 2. Simplify maintenance a bit | ||||
| 3. Reduce amount of conflicts for new drivers patches | ||||
|  | ||||
| While at it unify indent level in Makefile. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-9-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig  | 300 +++++++++++++++++++++-------------------- | ||||
|  drivers/nvmem/Makefile | 114 ++++++++-------- | ||||
|  2 files changed, 208 insertions(+), 206 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -21,6 +21,40 @@ config NVMEM_SYSFS | ||||
|  	 This interface is mostly used by userspace applications to | ||||
|  	 read/write directly into nvmem. | ||||
|   | ||||
| +# Devices | ||||
| + | ||||
| +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. | ||||
| + | ||||
| +config NVMEM_BCM_OCOTP | ||||
| +	tristate "Broadcom On-Chip OTP Controller support" | ||||
| +	depends on ARCH_BCM_IPROC || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	default ARCH_BCM_IPROC | ||||
| +	help | ||||
| +	  Say y here to enable read/write access to the Broadcom OTP | ||||
| +	  controller. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-bcm-ocotp. | ||||
| + | ||||
| +config NVMEM_BRCM_NVRAM | ||||
| +	tristate "Broadcom's NVRAM support" | ||||
| +	depends on ARCH_BCM_5301X || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver provides support for Broadcom's NVRAM that can be accessed | ||||
| +	  using I/O mapping. | ||||
| + | ||||
|  config NVMEM_IMX_IIM | ||||
|  	tristate "i.MX IC Identification Module support" | ||||
|  	depends on ARCH_MXC || COMPILE_TEST | ||||
| @@ -64,6 +98,19 @@ config NVMEM_JZ4780_EFUSE | ||||
|  	  To compile this driver as a module, choose M here: the module | ||||
|  	  will be called nvmem_jz4780_efuse. | ||||
|   | ||||
| +config NVMEM_LAYERSCAPE_SFP | ||||
| +	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
| +	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	select REGMAP_MMIO | ||||
| +	help | ||||
| +	  This driver provides support to read the eFuses on Freescale | ||||
| +	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| +	  unique ID there. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called layerscape-sfp. | ||||
| + | ||||
|  config NVMEM_LPC18XX_EEPROM | ||||
|  	tristate "NXP LPC18XX EEPROM Memory Support" | ||||
|  	depends on ARCH_LPC18XX || COMPILE_TEST | ||||
| @@ -84,17 +131,32 @@ config NVMEM_LPC18XX_OTP | ||||
|  	  To compile this driver as a module, choose M here: the module | ||||
|  	  will be called nvmem_lpc18xx_otp. | ||||
|   | ||||
| -config NVMEM_MXS_OCOTP | ||||
| -	tristate "Freescale MXS On-Chip OTP Memory Support" | ||||
| -	depends on ARCH_MXS || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| +config NVMEM_MESON_EFUSE | ||||
| +	tristate "Amlogic Meson GX eFuse Support" | ||||
| +	depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM | ||||
|  	help | ||||
| -	  If you say Y here, you will get readonly access to the | ||||
| -	  One Time Programmable memory pages that are stored | ||||
| -	  on the Freescale i.MX23/i.MX28 processor. | ||||
| +	  This is a driver to retrieve specific values from the eFuse found on | ||||
| +	  the Amlogic Meson GX SoCs. | ||||
|   | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-mxs-ocotp. | ||||
| +	  will be called nvmem_meson_efuse. | ||||
| + | ||||
| +config NVMEM_MESON_MX_EFUSE | ||||
| +	tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" | ||||
| +	depends on ARCH_MESON || COMPILE_TEST | ||||
| +	help | ||||
| +	  This is a driver to retrieve specific values from the eFuse found on | ||||
| +	  the Amlogic Meson6, Meson8 and Meson8b SoCs. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem_meson_mx_efuse. | ||||
| + | ||||
| +config NVMEM_MICROCHIP_OTPC | ||||
| +	tristate "Microchip OTPC support" | ||||
| +	depends on ARCH_AT91 || COMPILE_TEST | ||||
| +	help | ||||
| +	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| +	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
|   | ||||
|  config NVMEM_MTK_EFUSE | ||||
|  	tristate "Mediatek SoCs EFUSE support" | ||||
| @@ -107,12 +169,17 @@ config NVMEM_MTK_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called efuse-mtk. | ||||
|   | ||||
| -config NVMEM_MICROCHIP_OTPC | ||||
| -	tristate "Microchip OTPC support" | ||||
| -	depends on ARCH_AT91 || COMPILE_TEST | ||||
| +config NVMEM_MXS_OCOTP | ||||
| +	tristate "Freescale MXS On-Chip OTP Memory Support" | ||||
| +	depends on ARCH_MXS || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
|  	help | ||||
| -	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| -	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
| +	  If you say Y here, you will get readonly access to the | ||||
| +	  One Time Programmable memory pages that are stored | ||||
| +	  on the Freescale i.MX23/i.MX28 processor. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-mxs-ocotp. | ||||
|   | ||||
|  config NVMEM_NINTENDO_OTP | ||||
|  	tristate "Nintendo Wii and Wii U OTP Support" | ||||
| @@ -137,13 +204,21 @@ config NVMEM_QCOM_QFPROM | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_qfprom. | ||||
|   | ||||
| -config NVMEM_SPMI_SDAM | ||||
| -	tristate "SPMI SDAM Support" | ||||
| -	depends on SPMI | ||||
| +config NVMEM_RAVE_SP_EEPROM | ||||
| +	tristate "Rave SP EEPROM Support" | ||||
| +	depends on RAVE_SP_CORE | ||||
|  	help | ||||
| -	  This driver supports the Shared Direct Access Memory Module on | ||||
| -	  Qualcomm Technologies, Inc. PMICs. It provides the clients | ||||
| -	  an interface to read/write to the SDAM module's shared memory. | ||||
| +	  Say y here to enable Rave SP EEPROM support. | ||||
| + | ||||
| +config NVMEM_RMEM | ||||
| +	tristate "Reserved Memory Based Driver Support" | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver maps reserved memory into an nvmem device. It might be | ||||
| +	  useful to expose information left by firmware in memory. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-rmem. | ||||
|   | ||||
|  config NVMEM_ROCKCHIP_EFUSE | ||||
|  	tristate "Rockchip eFuse Support" | ||||
| @@ -167,79 +242,16 @@ config NVMEM_ROCKCHIP_OTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_rockchip_otp. | ||||
|   | ||||
| -config NVMEM_BCM_OCOTP | ||||
| -	tristate "Broadcom On-Chip OTP Controller support" | ||||
| -	depends on ARCH_BCM_IPROC || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	default ARCH_BCM_IPROC | ||||
| -	help | ||||
| -	  Say y here to enable read/write access to the Broadcom OTP | ||||
| -	  controller. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-bcm-ocotp. | ||||
| - | ||||
| -config NVMEM_STM32_ROMEM | ||||
| -	tristate "STMicroelectronics STM32 factory-programmed memory support" | ||||
| -	depends on ARCH_STM32 || COMPILE_TEST | ||||
| -	help | ||||
| -	  Say y here to enable read-only access for STMicroelectronics STM32 | ||||
| -	  factory-programmed memory area. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-stm32-romem. | ||||
| - | ||||
| -config NVMEM_SUNXI_SID | ||||
| -	tristate "Allwinner SoCs SID support" | ||||
| -	depends on ARCH_SUNXI | ||||
| -	help | ||||
| -	  This is a driver for the 'security ID' available on various Allwinner | ||||
| -	  devices. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem_sunxi_sid. | ||||
| - | ||||
| -config NVMEM_UNIPHIER_EFUSE | ||||
| -	tristate "UniPhier SoCs eFuse support" | ||||
| -	depends on ARCH_UNIPHIER || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This is a simple driver to dump specified values of UniPhier SoC | ||||
| -	  from eFuse. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-uniphier-efuse. | ||||
| - | ||||
| -config NVMEM_VF610_OCOTP | ||||
| -	tristate "VF610 SoC OCOTP support" | ||||
| -	depends on SOC_VF610 || COMPILE_TEST | ||||
| +config NVMEM_SC27XX_EFUSE | ||||
| +	tristate "Spreadtrum SC27XX eFuse Support" | ||||
| +	depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
|  	help | ||||
| -	  This is a driver for the 'OCOTP' peripheral available on Vybrid | ||||
| -	  devices like VF5xx and VF6xx. | ||||
| - | ||||
| -	  This driver can also be build as a module. If so, the module will | ||||
| -	  be called nvmem-vf610-ocotp. | ||||
| - | ||||
| -config NVMEM_MESON_EFUSE | ||||
| -	tristate "Amlogic Meson GX eFuse Support" | ||||
| -	depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM | ||||
| -	help | ||||
| -	  This is a driver to retrieve specific values from the eFuse found on | ||||
| -	  the Amlogic Meson GX SoCs. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem_meson_efuse. | ||||
| - | ||||
| -config NVMEM_MESON_MX_EFUSE | ||||
| -	tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" | ||||
| -	depends on ARCH_MESON || COMPILE_TEST | ||||
| -	help | ||||
| -	  This is a driver to retrieve specific values from the eFuse found on | ||||
| -	  the Amlogic Meson6, Meson8 and Meson8b SoCs. | ||||
| +	  This is a simple driver to dump specified values of Spreadtrum | ||||
| +	  SC27XX PMICs from eFuse. | ||||
|   | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem_meson_mx_efuse. | ||||
| +	  will be called nvmem-sc27xx-efuse. | ||||
|   | ||||
|  config NVMEM_SNVS_LPGPR | ||||
|  	tristate "Support for Low Power General Purpose Register" | ||||
| @@ -251,32 +263,13 @@ config NVMEM_SNVS_LPGPR | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-snvs-lpgpr. | ||||
|   | ||||
| -config NVMEM_RAVE_SP_EEPROM | ||||
| -	tristate "Rave SP EEPROM Support" | ||||
| -	depends on RAVE_SP_CORE | ||||
| -	help | ||||
| -	  Say y here to enable Rave SP EEPROM support. | ||||
| - | ||||
| -config NVMEM_SC27XX_EFUSE | ||||
| -	tristate "Spreadtrum SC27XX eFuse Support" | ||||
| -	depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This is a simple driver to dump specified values of Spreadtrum | ||||
| -	  SC27XX PMICs from eFuse. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-sc27xx-efuse. | ||||
| - | ||||
| -config NVMEM_ZYNQMP | ||||
| -	bool "Xilinx ZYNQMP SoC nvmem firmware support" | ||||
| -	depends on ARCH_ZYNQMP | ||||
| +config NVMEM_SPMI_SDAM | ||||
| +	tristate "SPMI SDAM Support" | ||||
| +	depends on SPMI | ||||
|  	help | ||||
| -	  This is a driver to access hardware related data like | ||||
| -	  soc revision, IDCODE... etc by using the firmware | ||||
| -	  interface. | ||||
| - | ||||
| -	  If sure, say yes. If unsure, say no. | ||||
| +	  This driver supports the Shared Direct Access Memory Module on | ||||
| +	  Qualcomm Technologies, Inc. PMICs. It provides the clients | ||||
| +	  an interface to read/write to the SDAM module's shared memory. | ||||
|   | ||||
|  config NVMEM_SPRD_EFUSE | ||||
|  	tristate "Spreadtrum SoC eFuse Support" | ||||
| @@ -289,36 +282,15 @@ config NVMEM_SPRD_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-sprd-efuse. | ||||
|   | ||||
| -config NVMEM_RMEM | ||||
| -	tristate "Reserved Memory Based Driver Support" | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This driver maps reserved memory into an nvmem device. It might be | ||||
| -	  useful to expose information left by firmware in memory. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-rmem. | ||||
| - | ||||
| -config NVMEM_BRCM_NVRAM | ||||
| -	tristate "Broadcom's NVRAM support" | ||||
| -	depends on ARCH_BCM_5301X || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This driver provides support for Broadcom's NVRAM that can be accessed | ||||
| -	  using I/O mapping. | ||||
| - | ||||
| -config NVMEM_LAYERSCAPE_SFP | ||||
| -	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
| -	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	select REGMAP_MMIO | ||||
| +config NVMEM_STM32_ROMEM | ||||
| +	tristate "STMicroelectronics STM32 factory-programmed memory support" | ||||
| +	depends on ARCH_STM32 || COMPILE_TEST | ||||
|  	help | ||||
| -	  This driver provides support to read the eFuses on Freescale | ||||
| -	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| -	  unique ID there. | ||||
| +	  Say y here to enable read-only access for STMicroelectronics STM32 | ||||
| +	  factory-programmed memory area. | ||||
|   | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called layerscape-sfp. | ||||
| +	  will be called nvmem-stm32-romem. | ||||
|   | ||||
|  config NVMEM_SUNPLUS_OCOTP | ||||
|  	tristate "Sunplus SoC OTP support" | ||||
| @@ -332,17 +304,15 @@ config NVMEM_SUNPLUS_OCOTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-sunplus-ocotp. | ||||
|   | ||||
| -config NVMEM_APPLE_EFUSES | ||||
| -	tristate "Apple eFuse support" | ||||
| -	depends on ARCH_APPLE || COMPILE_TEST | ||||
| -	default ARCH_APPLE | ||||
| +config NVMEM_SUNXI_SID | ||||
| +	tristate "Allwinner SoCs SID support" | ||||
| +	depends on ARCH_SUNXI | ||||
|  	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 is a driver for the 'security ID' available on various Allwinner | ||||
| +	  devices. | ||||
|   | ||||
| -	  This driver can also be built as a module. If so, the module will | ||||
| -	  be called nvmem-apple-efuses. | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem_sunxi_sid. | ||||
|   | ||||
|  config NVMEM_U_BOOT_ENV | ||||
|  	tristate "U-Boot environment variables support" | ||||
| @@ -357,4 +327,36 @@ config NVMEM_U_BOOT_ENV | ||||
|   | ||||
|  	  If compiled as module it will be called nvmem_u-boot-env. | ||||
|   | ||||
| +config NVMEM_UNIPHIER_EFUSE | ||||
| +	tristate "UniPhier SoCs eFuse support" | ||||
| +	depends on ARCH_UNIPHIER || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This is a simple driver to dump specified values of UniPhier SoC | ||||
| +	  from eFuse. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-uniphier-efuse. | ||||
| + | ||||
| +config NVMEM_VF610_OCOTP | ||||
| +	tristate "VF610 SoC OCOTP support" | ||||
| +	depends on SOC_VF610 || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This is a driver for the 'OCOTP' peripheral available on Vybrid | ||||
| +	  devices like VF5xx and VF6xx. | ||||
| + | ||||
| +	  This driver can also be build as a module. If so, the module will | ||||
| +	  be called nvmem-vf610-ocotp. | ||||
| + | ||||
| +config NVMEM_ZYNQMP | ||||
| +	bool "Xilinx ZYNQMP SoC nvmem firmware support" | ||||
| +	depends on ARCH_ZYNQMP | ||||
| +	help | ||||
| +	  This is a driver to access hardware related data like | ||||
| +	  soc revision, IDCODE... etc by using the firmware | ||||
| +	  interface. | ||||
| + | ||||
| +	  If sure, say yes. If unsure, say no. | ||||
| + | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -7,67 +7,67 @@ obj-$(CONFIG_NVMEM)		+= nvmem_core.o | ||||
|  nvmem_core-y			:= core.o | ||||
|   | ||||
|  # Devices | ||||
| -obj-$(CONFIG_NVMEM_BCM_OCOTP)	+= nvmem-bcm-ocotp.o | ||||
| -nvmem-bcm-ocotp-y		:= bcm-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_IMX_IIM)	+= nvmem-imx-iim.o | ||||
| -nvmem-imx-iim-y			:= imx-iim.o | ||||
| -obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o | ||||
| -nvmem-imx-ocotp-y		:= imx-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
| +nvmem-apple-efuses-y 			:= apple-efuses.o | ||||
| +obj-$(CONFIG_NVMEM_BCM_OCOTP)		+= nvmem-bcm-ocotp.o | ||||
| +nvmem-bcm-ocotp-y			:= bcm-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_BRCM_NVRAM)		+= nvmem_brcm_nvram.o | ||||
| +nvmem_brcm_nvram-y			:= brcm_nvram.o | ||||
| +obj-$(CONFIG_NVMEM_IMX_IIM)		+= nvmem-imx-iim.o | ||||
| +nvmem-imx-iim-y				:= imx-iim.o | ||||
| +obj-$(CONFIG_NVMEM_IMX_OCOTP)		+= nvmem-imx-ocotp.o | ||||
| +nvmem-imx-ocotp-y			:= imx-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o | ||||
| -nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o | ||||
| -obj-$(CONFIG_NVMEM_JZ4780_EFUSE)		+= nvmem_jz4780_efuse.o | ||||
| -nvmem_jz4780_efuse-y		:= jz4780-efuse.o | ||||
| +nvmem-imx-ocotp-scu-y			:= imx-ocotp-scu.o | ||||
| +obj-$(CONFIG_NVMEM_JZ4780_EFUSE)	+= nvmem_jz4780_efuse.o | ||||
| +nvmem_jz4780_efuse-y			:= jz4780-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
| +nvmem-layerscape-sfp-y			:= layerscape-sfp.o | ||||
|  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o | ||||
| -nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o | ||||
| -obj-$(CONFIG_NVMEM_LPC18XX_OTP)	+= nvmem_lpc18xx_otp.o | ||||
| -nvmem_lpc18xx_otp-y		:= lpc18xx_otp.o | ||||
| -obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-mxs-ocotp.o | ||||
| -nvmem-mxs-ocotp-y		:= mxs-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_NINTENDO_OTP)	+= nvmem-nintendo-otp.o | ||||
| -nvmem-nintendo-otp-y		:= nintendo-otp.o | ||||
| +nvmem_lpc18xx_eeprom-y			:= lpc18xx_eeprom.o | ||||
| +obj-$(CONFIG_NVMEM_LPC18XX_OTP)		+= nvmem_lpc18xx_otp.o | ||||
| +nvmem_lpc18xx_otp-y			:= lpc18xx_otp.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_EFUSE)		+= nvmem_meson_efuse.o | ||||
| +nvmem_meson_efuse-y			:= meson-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
| +nvmem_meson_mx_efuse-y			:= meson-mx-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| +nvmem-microchip-otpc-y			:= microchip-otpc.o | ||||
|  obj-$(CONFIG_NVMEM_MTK_EFUSE)		+= nvmem_mtk-efuse.o | ||||
| -nvmem_mtk-efuse-y		:= mtk-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_QCOM_QFPROM)	+= nvmem_qfprom.o | ||||
| -nvmem_qfprom-y			:= qfprom.o | ||||
| -obj-$(CONFIG_NVMEM_SPMI_SDAM)	+= nvmem_qcom-spmi-sdam.o | ||||
| -nvmem_qcom-spmi-sdam-y		+= qcom-spmi-sdam.o | ||||
| +nvmem_mtk-efuse-y			:= mtk-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MXS_OCOTP)		+= nvmem-mxs-ocotp.o | ||||
| +nvmem-mxs-ocotp-y			:= mxs-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_NINTENDO_OTP)	+= nvmem-nintendo-otp.o | ||||
| +nvmem-nintendo-otp-y			:= nintendo-otp.o | ||||
| +obj-$(CONFIG_NVMEM_QCOM_QFPROM)		+= nvmem_qfprom.o | ||||
| +nvmem_qfprom-y				:= qfprom.o | ||||
| +obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
| +nvmem-rave-sp-eeprom-y			:= rave-sp-eeprom.o | ||||
| +obj-$(CONFIG_NVMEM_RMEM) 		+= nvmem-rmem.o | ||||
| +nvmem-rmem-y				:= rmem.o | ||||
|  obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE)	+= nvmem_rockchip_efuse.o | ||||
| -nvmem_rockchip_efuse-y		:= rockchip-efuse.o | ||||
| +nvmem_rockchip_efuse-y			:= rockchip-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_ROCKCHIP_OTP)	+= nvmem-rockchip-otp.o | ||||
| -nvmem-rockchip-otp-y		:= rockchip-otp.o | ||||
| -obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o | ||||
| -nvmem_stm32_romem-y 		:= stm32-romem.o | ||||
| -obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o | ||||
| -nvmem_sunxi_sid-y		:= sunxi_sid.o | ||||
| -obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
| -nvmem-uniphier-efuse-y		:= uniphier-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o | ||||
| -nvmem-vf610-ocotp-y		:= vf610-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_MESON_EFUSE)	+= nvmem_meson_efuse.o | ||||
| -nvmem_meson_efuse-y		:= meson-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
| -nvmem_meson_mx_efuse-y		:= meson-mx-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_SNVS_LPGPR)	+= nvmem_snvs_lpgpr.o | ||||
| -nvmem_snvs_lpgpr-y		:= snvs_lpgpr.o | ||||
| -obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
| -nvmem-rave-sp-eeprom-y		:= rave-sp-eeprom.o | ||||
| +nvmem-rockchip-otp-y			:= rockchip-otp.o | ||||
|  obj-$(CONFIG_NVMEM_SC27XX_EFUSE)	+= nvmem-sc27xx-efuse.o | ||||
| -nvmem-sc27xx-efuse-y		:= sc27xx-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_ZYNQMP)	+= nvmem_zynqmp_nvmem.o | ||||
| -nvmem_zynqmp_nvmem-y		:= zynqmp_nvmem.o | ||||
| -obj-$(CONFIG_NVMEM_SPRD_EFUSE)	+= nvmem_sprd_efuse.o | ||||
| -nvmem_sprd_efuse-y		:= sprd-efuse.o | ||||
| -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_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
| -nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
| +nvmem-sc27xx-efuse-y			:= sc27xx-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_SNVS_LPGPR)		+= nvmem_snvs_lpgpr.o | ||||
| +nvmem_snvs_lpgpr-y			:= snvs_lpgpr.o | ||||
| +obj-$(CONFIG_NVMEM_SPMI_SDAM)		+= nvmem_qcom-spmi-sdam.o | ||||
| +nvmem_qcom-spmi-sdam-y			+= qcom-spmi-sdam.o | ||||
| +obj-$(CONFIG_NVMEM_SPRD_EFUSE)		+= nvmem_sprd_efuse.o | ||||
| +nvmem_sprd_efuse-y			:= sprd-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_STM32_ROMEM)		+= nvmem_stm32_romem.o | ||||
| +nvmem_stm32_romem-y 			:= stm32-romem.o | ||||
|  obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o | ||||
| -nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
| -nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| -obj-$(CONFIG_NVMEM_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| -nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
| -obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o | ||||
| -nvmem_u-boot-env-y		:= u-boot-env.o | ||||
| +nvmem_sunplus_ocotp-y			:= sunplus-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_SUNXI_SID)		+= nvmem_sunxi_sid.o | ||||
| +nvmem_sunxi_sid-y			:= sunxi_sid.o | ||||
| +obj-$(CONFIG_NVMEM_U_BOOT_ENV)		+= nvmem_u-boot-env.o | ||||
| +nvmem_u-boot-env-y			:= u-boot-env.o | ||||
| +obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
| +nvmem-uniphier-efuse-y			:= uniphier-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_VF610_OCOTP)		+= nvmem-vf610-ocotp.o | ||||
| +nvmem-vf610-ocotp-y			:= vf610-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_ZYNQMP)		+= nvmem_zynqmp_nvmem.o | ||||
| +nvmem_zynqmp_nvmem-y			:= zynqmp_nvmem.o | ||||
| @@ -1,6 +1,6 @@ | ||||
| From d69efcf951df4dcc74a0e1554969c533aec8aa9b Mon Sep 17 00:00:00 2001 | ||||
| From d4d432670f7dee0a5432fcffcfc8699b25181ace Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 15 Sep 2022 22:06:29 +0200 | ||||
| Date: Fri, 16 Sep 2022 13:20:57 +0100 | ||||
| Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -13,6 +13,8 @@ This allows NVMEM consumers to use U-Boot environment variables. | ||||
| 
 | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-11-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
| @@ -0,0 +1,274 @@ | ||||
| From 9e8f208ad5229ddda97cd4a83ecf89c735d99592 Mon Sep 17 00:00:00 2001 | ||||
| From: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Date: Fri, 16 Sep 2022 13:20:59 +0100 | ||||
| Subject: [PATCH] nvmem: lan9662-otp: add support | ||||
|  | ||||
| Add support for OTP controller available on LAN9662. The OTPC controls | ||||
| the access to a non-volatile memory. The size of the memory is 8KB. | ||||
| The OTPC can access the memory based on an offset. | ||||
| Implement both the read and the write functionality. | ||||
|  | ||||
| Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-13-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig        |   8 ++ | ||||
|  drivers/nvmem/Makefile       |   2 + | ||||
|  drivers/nvmem/lan9662-otpc.c | 222 +++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 232 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/lan9662-otpc.c | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -98,6 +98,14 @@ config NVMEM_JZ4780_EFUSE | ||||
|  	  To compile this driver as a module, choose M here: the module | ||||
|  	  will be called nvmem_jz4780_efuse. | ||||
|   | ||||
| +config NVMEM_LAN9662_OTPC | ||||
| +	tristate "Microchip LAN9662 OTP controller support" | ||||
| +	depends on SOC_LAN966 || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver enables the OTP controller available on Microchip LAN9662 | ||||
| +	  SoCs. It controls the access to the OTP memory connected to it. | ||||
| + | ||||
|  config NVMEM_LAYERSCAPE_SFP | ||||
|  	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
|  	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -21,6 +21,8 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvm | ||||
|  nvmem-imx-ocotp-scu-y			:= imx-ocotp-scu.o | ||||
|  obj-$(CONFIG_NVMEM_JZ4780_EFUSE)	+= nvmem_jz4780_efuse.o | ||||
|  nvmem_jz4780_efuse-y			:= jz4780-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_LAN9662_OTPC)	+= nvmem-lan9662-otpc.o | ||||
| +nvmem-lan9662-otpc-y		:= lan9662-otpc.o | ||||
|  obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
|  nvmem-layerscape-sfp-y			:= layerscape-sfp.o | ||||
|  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/lan9662-otpc.c | ||||
| @@ -0,0 +1,222 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| + | ||||
| +#include <linux/iopoll.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#define OTP_OTP_PWR_DN(t)			(t + 0x00) | ||||
| +#define OTP_OTP_PWR_DN_OTP_PWRDN_N		BIT(0) | ||||
| +#define OTP_OTP_ADDR_HI(t)			(t + 0x04) | ||||
| +#define OTP_OTP_ADDR_LO(t)			(t + 0x08) | ||||
| +#define OTP_OTP_PRGM_DATA(t)			(t + 0x10) | ||||
| +#define OTP_OTP_PRGM_MODE(t)			(t + 0x14) | ||||
| +#define OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE	BIT(0) | ||||
| +#define OTP_OTP_RD_DATA(t)			(t + 0x18) | ||||
| +#define OTP_OTP_FUNC_CMD(t)			(t + 0x20) | ||||
| +#define OTP_OTP_FUNC_CMD_OTP_PROGRAM		BIT(1) | ||||
| +#define OTP_OTP_FUNC_CMD_OTP_READ		BIT(0) | ||||
| +#define OTP_OTP_CMD_GO(t)			(t + 0x28) | ||||
| +#define OTP_OTP_CMD_GO_OTP_GO			BIT(0) | ||||
| +#define OTP_OTP_PASS_FAIL(t)			(t + 0x2c) | ||||
| +#define OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED	BIT(3) | ||||
| +#define OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED	BIT(2) | ||||
| +#define OTP_OTP_PASS_FAIL_OTP_FAIL		BIT(0) | ||||
| +#define OTP_OTP_STATUS(t)			(t + 0x30) | ||||
| +#define OTP_OTP_STATUS_OTP_CPUMPEN		BIT(1) | ||||
| +#define OTP_OTP_STATUS_OTP_BUSY			BIT(0) | ||||
| + | ||||
| +#define OTP_MEM_SIZE 8192 | ||||
| +#define OTP_SLEEP_US 10 | ||||
| +#define OTP_TIMEOUT_US 500000 | ||||
| + | ||||
| +struct lan9662_otp { | ||||
| +	struct device *dev; | ||||
| +	void __iomem *base; | ||||
| +}; | ||||
| + | ||||
| +static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) | ||||
| +{ | ||||
| +	u32 val; | ||||
| + | ||||
| +	return readl_poll_timeout(reg, val, !(val & flag), | ||||
| +				  OTP_SLEEP_US, OTP_TIMEOUT_US); | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_power(struct lan9662_otp *otp, bool up) | ||||
| +{ | ||||
| +	void __iomem *pwrdn = OTP_OTP_PWR_DN(otp->base); | ||||
| + | ||||
| +	if (up) { | ||||
| +		writel(readl(pwrdn) & ~OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); | ||||
| +		if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), | ||||
| +						OTP_OTP_STATUS_OTP_CPUMPEN)) | ||||
| +			return -ETIMEDOUT; | ||||
| +	} else { | ||||
| +		writel(readl(pwrdn) | OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_execute(struct lan9662_otp *otp) | ||||
| +{ | ||||
| +	if (lan9662_otp_wait_flag_clear(OTP_OTP_CMD_GO(otp->base), | ||||
| +					OTP_OTP_CMD_GO_OTP_GO)) | ||||
| +		return -ETIMEDOUT; | ||||
| + | ||||
| +	if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), | ||||
| +					OTP_OTP_STATUS_OTP_BUSY)) | ||||
| +		return -ETIMEDOUT; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void lan9662_otp_set_address(struct lan9662_otp *otp, u32 offset) | ||||
| +{ | ||||
| +	writel(0xff & (offset >> 8), OTP_OTP_ADDR_HI(otp->base)); | ||||
| +	writel(0xff & offset, OTP_OTP_ADDR_LO(otp->base)); | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_read_byte(struct lan9662_otp *otp, u32 offset, u8 *dst) | ||||
| +{ | ||||
| +	u32 pass; | ||||
| +	int rc; | ||||
| + | ||||
| +	lan9662_otp_set_address(otp, offset); | ||||
| +	writel(OTP_OTP_FUNC_CMD_OTP_READ, OTP_OTP_FUNC_CMD(otp->base)); | ||||
| +	writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); | ||||
| +	rc = lan9662_otp_execute(otp); | ||||
| +	if (!rc) { | ||||
| +		pass = readl(OTP_OTP_PASS_FAIL(otp->base)); | ||||
| +		if (pass & OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED) | ||||
| +			return -EACCES; | ||||
| +		*dst = (u8) readl(OTP_OTP_RD_DATA(otp->base)); | ||||
| +	} | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 data) | ||||
| +{ | ||||
| +	u32 pass; | ||||
| +	int rc; | ||||
| + | ||||
| +	lan9662_otp_set_address(otp, offset); | ||||
| +	writel(OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE, OTP_OTP_PRGM_MODE(otp->base)); | ||||
| +	writel(data, OTP_OTP_PRGM_DATA(otp->base)); | ||||
| +	writel(OTP_OTP_FUNC_CMD_OTP_PROGRAM, OTP_OTP_FUNC_CMD(otp->base)); | ||||
| +	writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); | ||||
| + | ||||
| +	rc = lan9662_otp_execute(otp); | ||||
| +	if (!rc) { | ||||
| +		pass = readl(OTP_OTP_PASS_FAIL(otp->base)); | ||||
| +		if (pass & OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED) | ||||
| +			return -EACCES; | ||||
| +		if (pass & OTP_OTP_PASS_FAIL_OTP_FAIL) | ||||
| +			return -EIO; | ||||
| +	} | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_read(void *context, unsigned int offset, | ||||
| +			    void *_val, size_t bytes) | ||||
| +{ | ||||
| +	struct lan9662_otp *otp = context; | ||||
| +	u8 *val = _val; | ||||
| +	uint8_t data; | ||||
| +	int i, rc = 0; | ||||
| + | ||||
| +	lan9662_otp_power(otp, true); | ||||
| +	for (i = 0; i < bytes; i++) { | ||||
| +		rc = lan9662_otp_read_byte(otp, offset + i, &data); | ||||
| +		if (rc < 0) | ||||
| +			break; | ||||
| +		*val++ = data; | ||||
| +	} | ||||
| +	lan9662_otp_power(otp, false); | ||||
| + | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_write(void *context, unsigned int offset, | ||||
| +			     void *_val, size_t bytes) | ||||
| +{ | ||||
| +	struct lan9662_otp *otp = context; | ||||
| +	u8 *val = _val; | ||||
| +	u8 data, newdata; | ||||
| +	int i, rc = 0; | ||||
| + | ||||
| +	lan9662_otp_power(otp, true); | ||||
| +	for (i = 0; i < bytes; i++) { | ||||
| +		/* Skip zero bytes */ | ||||
| +		if (val[i]) { | ||||
| +			rc = lan9662_otp_read_byte(otp, offset + i, &data); | ||||
| +			if (rc < 0) | ||||
| +				break; | ||||
| + | ||||
| +			newdata = data | val[i]; | ||||
| +			if (newdata == data) | ||||
| +				continue; | ||||
| + | ||||
| +			rc = lan9662_otp_write_byte(otp, offset + i, | ||||
| +						      newdata); | ||||
| +			if (rc < 0) | ||||
| +				break; | ||||
| +		} | ||||
| +	} | ||||
| +	lan9662_otp_power(otp, false); | ||||
| + | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config otp_config = { | ||||
| +	.name = "lan9662-otp", | ||||
| +	.stride = 1, | ||||
| +	.word_size = 1, | ||||
| +	.reg_read = lan9662_otp_read, | ||||
| +	.reg_write = lan9662_otp_write, | ||||
| +	.size = OTP_MEM_SIZE, | ||||
| +}; | ||||
| + | ||||
| +static int lan9662_otp_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct device *dev = &pdev->dev; | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	struct lan9662_otp *otp; | ||||
| + | ||||
| +	otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); | ||||
| +	if (!otp) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	otp->dev = dev; | ||||
| +	otp->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(otp->base)) | ||||
| +		return PTR_ERR(otp->base); | ||||
| + | ||||
| +	otp_config.priv = otp; | ||||
| +	otp_config.dev = dev; | ||||
| + | ||||
| +	nvmem = devm_nvmem_register(dev, &otp_config); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(nvmem); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id lan9662_otp_match[] = { | ||||
| +	{ .compatible = "microchip,lan9662-otp", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, lan9662_otp_match); | ||||
| + | ||||
| +static struct platform_driver lan9662_otp_driver = { | ||||
| +	.probe = lan9662_otp_probe, | ||||
| +	.driver = { | ||||
| +		.name = "lan9662-otp", | ||||
| +		.of_match_table = lan9662_otp_match, | ||||
| +	}, | ||||
| +}; | ||||
| +module_platform_driver(lan9662_otp_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Horatiu Vultur <horatiu.vultur@microchip.com>"); | ||||
| +MODULE_DESCRIPTION("lan9662 OTP driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -1,6 +1,6 @@ | ||||
| From 60bbaad38109684b156e21112322e0a922f92cde Mon Sep 17 00:00:00 2001 | ||||
| From 3717ca3e0cc8683f93b41d3f06ca79631eb58715 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 18 Aug 2022 06:38:37 +0200 | ||||
| Date: Fri, 16 Sep 2022 13:21:00 +0100 | ||||
| Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -9,10 +9,12 @@ Content-Transfer-Encoding: 8bit | ||||
| This fixes: | ||||
| drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32 | ||||
| 
 | ||||
| Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") | ||||
| Reported-by: kernel test robot <lkp@intel.com> | ||||
| Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-14-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| @@ -0,0 +1,34 @@ | ||||
| From 1aeb122d214b92474c86fde00a03d6e2d69381b5 Mon Sep 17 00:00:00 2001 | ||||
| From: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Date: Wed, 28 Sep 2022 21:51:12 +0200 | ||||
| Subject: [PATCH] nvmem: lan9662-otp: Fix compatible string | ||||
|  | ||||
| The device tree bindings for lan9662-otp expects the compatible string | ||||
| to be one of following compatible strings: | ||||
| microchip,lan9662-otpc | ||||
| microchip,lan9668-otpc | ||||
|  | ||||
| The problem is that the lan9662-otp driver contains the | ||||
| microchip,lan9662-otp compatible string instead of | ||||
| microchip,lan9662-otpc. | ||||
| Fix this by updating the compatible string in the driver. | ||||
|  | ||||
| Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support") | ||||
| Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Link: https://lore.kernel.org/r/20220928195112.630351-1-horatiu.vultur@microchip.com | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/lan9662-otpc.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/lan9662-otpc.c | ||||
| +++ b/drivers/nvmem/lan9662-otpc.c | ||||
| @@ -203,7 +203,7 @@ static int lan9662_otp_probe(struct plat | ||||
|  } | ||||
|   | ||||
|  static const struct of_device_id lan9662_otp_match[] = { | ||||
| -	{ .compatible = "microchip,lan9662-otp", }, | ||||
| +	{ .compatible = "microchip,lan9662-otpc", }, | ||||
|  	{ }, | ||||
|  }; | ||||
|  MODULE_DEVICE_TABLE(of, lan9662_otp_match); | ||||
| @@ -1,4 +1,4 @@ | ||||
| From 7a69ff9c9bde03a690ea783970f664782fc303d8 Mon Sep 17 00:00:00 2001 | ||||
| From ee424f7d3960152f5f862bbb6943e59828dc7917 Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Lamparter <chunkeey@gmail.com> | ||||
| Date: Fri, 4 Nov 2022 17:52:03 +0100 | ||||
| Subject: [PATCH] nvmem: u-boot-env: fix crc32_data_offset on redundant | ||||
| @@ -37,8 +37,11 @@ crc32 sum... which is unfortunate :( | ||||
| | | ||||
| 
 | ||||
| [0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951 | ||||
| 
 | ||||
| Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") | ||||
| Signed-off-by: Christian Lamparter <chunkeey@gmail.com> | ||||
| Link: https://lore.kernel.org/r/70a16eae113e08db2390b76e174f4837caa135c3.1667580636.git.chunkeey@gmail.com | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| @@ -0,0 +1,36 @@ | ||||
| From 58e92c4a496b27156020a59a98c7f4a92c2b1533 Mon Sep 17 00:00:00 2001 | ||||
| From: Wei Yongjun <weiyongjun1@huawei.com> | ||||
| Date: Fri, 18 Nov 2022 06:38:38 +0000 | ||||
| Subject: [PATCH] nvmem: rmem: Fix return value check in rmem_read() | ||||
|  | ||||
| In case of error, the function memremap() returns NULL pointer | ||||
| not ERR_PTR(). The IS_ERR() test in the return value check | ||||
| should be replaced with NULL test. | ||||
|  | ||||
| Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") | ||||
| Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Cc: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> | ||||
| Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com> | ||||
| Acked-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> | ||||
| Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063840.6357-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/rmem.c | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/rmem.c | ||||
| +++ b/drivers/nvmem/rmem.c | ||||
| @@ -37,9 +37,9 @@ static int rmem_read(void *context, unsi | ||||
|  	 * but as of Dec 2020 this isn't possible on arm64. | ||||
|  	 */ | ||||
|  	addr = memremap(priv->mem->base, available, MEMREMAP_WB); | ||||
| -	if (IS_ERR(addr)) { | ||||
| +	if (!addr) { | ||||
|  		dev_err(priv->dev, "Failed to remap memory region\n"); | ||||
| -		return PTR_ERR(addr); | ||||
| +		return -ENOMEM; | ||||
|  	} | ||||
|   | ||||
|  	count = memory_read_from_buffer(val, bytes, &off, addr, available); | ||||
| @@ -0,0 +1,35 @@ | ||||
| From 022b68f271de0e53024e6d5e96fee8e76d25eb95 Mon Sep 17 00:00:00 2001 | ||||
| From: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Date: Fri, 18 Nov 2022 06:38:40 +0000 | ||||
| Subject: [PATCH] nvmem: lan9662-otp: Change return type of | ||||
|  lan9662_otp_wait_flag_clear() | ||||
|  | ||||
| The blamed commit introduced the following smatch warning in the | ||||
| function lan9662_otp_wait_flag_clear: | ||||
| drivers/nvmem/lan9662-otpc.c:43 lan9662_otp_wait_flag_clear() warn: signedness bug returning '(-110)' | ||||
|  | ||||
| Fix this by changing the return type of the function | ||||
| lan9662_otp_wait_flag_clear() to be int instead of bool. | ||||
|  | ||||
| Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support") | ||||
| Reported-by: kernel test robot <lkp@intel.com> | ||||
| Reported-by: Dan Carpenter <dan.carpenter@oracle.com> | ||||
| Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063840.6357-5-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/lan9662-otpc.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/lan9662-otpc.c | ||||
| +++ b/drivers/nvmem/lan9662-otpc.c | ||||
| @@ -36,7 +36,7 @@ struct lan9662_otp { | ||||
|  	void __iomem *base; | ||||
|  }; | ||||
|   | ||||
| -static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) | ||||
| +static int lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) | ||||
|  { | ||||
|  	u32 val; | ||||
|   | ||||
| @@ -0,0 +1,82 @@ | ||||
| From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001 | ||||
| From: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:20 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config | ||||
|  | ||||
| Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare | ||||
| the next SoC in STM32MP family. | ||||
|  | ||||
| Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++----- | ||||
|  1 file changed, 16 insertions(+), 5 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -22,16 +22,15 @@ | ||||
|  /* shadow registers offest */ | ||||
|  #define STM32MP15_BSEC_DATA0		0x200 | ||||
|   | ||||
| -/* 32 (x 32-bits) lower shadow registers */ | ||||
| -#define STM32MP15_BSEC_NUM_LOWER	32 | ||||
| - | ||||
|  struct stm32_romem_cfg { | ||||
|  	int size; | ||||
| +	u8 lower; | ||||
|  }; | ||||
|   | ||||
|  struct stm32_romem_priv { | ||||
|  	void __iomem *base; | ||||
|  	struct nvmem_config cfg; | ||||
| +	u8 lower; | ||||
|  }; | ||||
|   | ||||
|  static int stm32_romem_read(void *context, unsigned int offset, void *buf, | ||||
| @@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context | ||||
|  	for (i = roffset; (i < roffset + rbytes); i += 4) { | ||||
|  		u32 otp = i >> 2; | ||||
|   | ||||
| -		if (otp < STM32MP15_BSEC_NUM_LOWER) { | ||||
| +		if (otp < priv->lower) { | ||||
|  			/* read lower data from shadow registers */ | ||||
|  			val = readl_relaxed( | ||||
|  				priv->base + STM32MP15_BSEC_DATA0 + i); | ||||
| @@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat | ||||
|  	priv->cfg.priv = priv; | ||||
|  	priv->cfg.owner = THIS_MODULE; | ||||
|   | ||||
| +	priv->lower = 0; | ||||
| + | ||||
|  	cfg = (const struct stm32_romem_cfg *) | ||||
|  		of_match_device(dev->driver->of_match_table, dev)->data; | ||||
|  	if (!cfg) { | ||||
| @@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat | ||||
|  		priv->cfg.reg_read = stm32_romem_read; | ||||
|  	} else { | ||||
|  		priv->cfg.size = cfg->size; | ||||
| +		priv->lower = cfg->lower; | ||||
|  		priv->cfg.reg_read = stm32_bsec_read; | ||||
|  		priv->cfg.reg_write = stm32_bsec_write; | ||||
|  	} | ||||
| @@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat | ||||
|  	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); | ||||
|  } | ||||
|   | ||||
| +/* | ||||
| + * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) | ||||
| + * => 96 x 32-bits data words | ||||
| + * - Lower: 1K bits, 2:1 redundancy, incremental bit programming | ||||
| + *   => 32 (x 32-bits) lower shadow registers = words 0 to 31 | ||||
| + * - Upper: 2K bits, ECC protection, word programming only | ||||
| + *   => 64 (x 32-bits) = words 32 to 95 | ||||
| + */ | ||||
|  static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { | ||||
| -	.size = 384, /* 96 x 32-bits data words */ | ||||
| +	.size = 384, | ||||
| +	.lower = 32, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id stm32_romem_of_match[] = { | ||||
| @@ -0,0 +1,34 @@ | ||||
| From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001 | ||||
| From: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:21 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated | ||||
|  | ||||
| As the upper OTPs are ECC protected, they support only one 32 bits word | ||||
| programming. | ||||
| For a second modification of this word, these ECC become invalid and | ||||
| this OTP will be no more accessible, the shadowed value is invalid. | ||||
|  | ||||
| This patch adds a warning to indicate an upper OTP update, because this | ||||
| operation is dangerous as OTP is not locked by the driver after the first | ||||
| update to avoid a second update. | ||||
|  | ||||
| Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 3 +++ | ||||
|  1 file changed, 3 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| +	if (offset + bytes >= priv->lower * 4) | ||||
| +		dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n"); | ||||
| + | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -0,0 +1,26 @@ | ||||
| From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001 | ||||
| From: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:22 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: add nvmem type attribute | ||||
|  | ||||
| Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP | ||||
| so userspace is able to know how the data is stored in BSEC. | ||||
|  | ||||
| Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat | ||||
|  	priv->cfg.dev = dev; | ||||
|  	priv->cfg.priv = priv; | ||||
|  	priv->cfg.owner = THIS_MODULE; | ||||
| +	priv->cfg.type = NVMEM_TYPE_OTP; | ||||
|   | ||||
|  	priv->lower = 0; | ||||
|   | ||||
| @@ -0,0 +1,27 @@ | ||||
| From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001 | ||||
| From: Jiangshan Yi <yijiangshan@kylinos.cn> | ||||
| Date: Fri, 18 Nov 2022 06:39:24 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: fix spelling typo in comment | ||||
|  | ||||
| Fix spelling typo in comment. | ||||
|  | ||||
| Reported-by: k2ci <kernel-bot@kylinos.cn> | ||||
| Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -19,7 +19,7 @@ | ||||
|  #define STM32_SMC_WRITE_SHADOW		0x03 | ||||
|  #define STM32_SMC_READ_OTP		0x04 | ||||
|   | ||||
| -/* shadow registers offest */ | ||||
| +/* shadow registers offset */ | ||||
|  #define STM32MP15_BSEC_DATA0		0x200 | ||||
|   | ||||
|  struct stm32_romem_cfg { | ||||
| @@ -0,0 +1,27 @@ | ||||
| From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001 | ||||
| From: Colin Ian King <colin.i.king@gmail.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:26 +0000 | ||||
| Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" -> | ||||
|  "controls" | ||||
|  | ||||
| There is a spelling mistake in a Kconfig description. Fix it. | ||||
|  | ||||
| Signed-off-by: Colin Ian King <colin.i.king@gmail.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC | ||||
|  	depends on ARCH_AT91 || COMPILE_TEST | ||||
|  	help | ||||
|  	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| -	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
| +	  SoCs. It controls the access to the OTP memory connected to it. | ||||
|   | ||||
|  config NVMEM_MTK_EFUSE | ||||
|  	tristate "Mediatek SoCs EFUSE support" | ||||
| @@ -1,6 +1,6 @@ | ||||
| From 5b4eaafbeac472fc19049152f18e88aecb2b2829 Mon Sep 17 00:00:00 2001 | ||||
| From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 17 Oct 2022 09:17:22 +0200 | ||||
| Date: Fri, 18 Nov 2022 06:39:27 +0000 | ||||
| Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -15,6 +15,8 @@ Add support for Broadcom's specific binding and their custom format. | ||||
| Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding") | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 14 ++++++++++++++ | ||||
|  1 file changed, 14 insertions(+) | ||||
| @@ -36,7 +36,7 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| 
 | ||||
| --- a/drivers/nvmem/u-boot-env.c
 | ||||
| +++ b/drivers/nvmem/u-boot-env.c
 | ||||
| @@ -143,7 +143,7 @@ static int u_boot_env_parse(struct u_boo
 | ||||
| @@ -156,7 +156,7 @@ static int u_boot_env_parse(struct u_boo
 | ||||
|  	crc32_data_len = priv->mtd->size - crc32_data_offset; | ||||
|  	data_len = priv->mtd->size - data_offset; | ||||
|   | ||||
| @@ -0,0 +1,456 @@ | ||||
| From 7ae6478b304bc004c3139b422665b0e23b57f05c Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Wed, 13 Oct 2021 14:19:55 +0100 | ||||
| Subject: [PATCH] nvmem: core: rework nvmem cell instance creation | ||||
|  | ||||
| In the existing design, we do not create a instance per nvmem cell consumer | ||||
| but we directly refer cell from nvmem cell list that are added to provider. | ||||
|  | ||||
| However this design has some limitations when consumers want to assign name | ||||
| or connection id the nvmem cell instance, ex: via "nvmem-cell-names" or | ||||
| id in nvmem_cell_get(id). | ||||
|  | ||||
| Having a name associated with nvmem cell consumer instance will help | ||||
| provider drivers in performing post processing of nvmem cell data if required | ||||
| before data is seen by the consumers. This is pretty normal with some vendors | ||||
| storing nvmem cells like mac-address in a vendor specific data layouts that | ||||
| are not directly usable by the consumer drivers. | ||||
|  | ||||
| With this patch nvmem cell will be created dynamically during nvmem_cell_get | ||||
| and destroyed in nvmem_cell_put, allowing consumers to associate name with | ||||
| nvmem cell consumer instance. | ||||
|  | ||||
| With this patch a new struct nvmem_cell_entry replaces struct nvmem_cell | ||||
| for storing nvmem cell information within the core. | ||||
| This patch does not change nvmem-consumer interface based on nvmem_cell. | ||||
|  | ||||
| Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211013131957.30271-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 165 +++++++++++++++++++++++++++---------------- | ||||
|  1 file changed, 105 insertions(+), 60 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -45,8 +45,7 @@ struct nvmem_device { | ||||
|  #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) | ||||
|   | ||||
|  #define FLAG_COMPAT		BIT(0) | ||||
| - | ||||
| -struct nvmem_cell { | ||||
| +struct nvmem_cell_entry { | ||||
|  	const char		*name; | ||||
|  	int			offset; | ||||
|  	int			bytes; | ||||
| @@ -57,6 +56,11 @@ struct nvmem_cell { | ||||
|  	struct list_head	node; | ||||
|  }; | ||||
|   | ||||
| +struct nvmem_cell { | ||||
| +	struct nvmem_cell_entry *entry; | ||||
| +	const char		*id; | ||||
| +}; | ||||
| + | ||||
|  static DEFINE_MUTEX(nvmem_mutex); | ||||
|  static DEFINE_IDA(nvmem_ida); | ||||
|   | ||||
| @@ -424,7 +428,7 @@ static struct bus_type nvmem_bus_type = | ||||
|  	.name		= "nvmem", | ||||
|  }; | ||||
|   | ||||
| -static void nvmem_cell_drop(struct nvmem_cell *cell) | ||||
| +static void nvmem_cell_entry_drop(struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell); | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
| @@ -437,13 +441,13 @@ static void nvmem_cell_drop(struct nvmem | ||||
|   | ||||
|  static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem) | ||||
|  { | ||||
| -	struct nvmem_cell *cell, *p; | ||||
| +	struct nvmem_cell_entry *cell, *p; | ||||
|   | ||||
|  	list_for_each_entry_safe(cell, p, &nvmem->cells, node) | ||||
| -		nvmem_cell_drop(cell); | ||||
| +		nvmem_cell_entry_drop(cell); | ||||
|  } | ||||
|   | ||||
| -static void nvmem_cell_add(struct nvmem_cell *cell) | ||||
| +static void nvmem_cell_entry_add(struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
|  	list_add_tail(&cell->node, &cell->nvmem->cells); | ||||
| @@ -451,9 +455,9 @@ static void nvmem_cell_add(struct nvmem_ | ||||
|  	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell); | ||||
|  } | ||||
|   | ||||
| -static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem, | ||||
| -					const struct nvmem_cell_info *info, | ||||
| -					struct nvmem_cell *cell) | ||||
| +static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem, | ||||
| +						     const struct nvmem_cell_info *info, | ||||
| +						     struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	cell->nvmem = nvmem; | ||||
|  	cell->offset = info->offset; | ||||
| @@ -477,13 +481,13 @@ static int nvmem_cell_info_to_nvmem_cell | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| -static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, | ||||
| -				const struct nvmem_cell_info *info, | ||||
| -				struct nvmem_cell *cell) | ||||
| +static int nvmem_cell_info_to_nvmem_cell_entry(struct nvmem_device *nvmem, | ||||
| +					       const struct nvmem_cell_info *info, | ||||
| +					       struct nvmem_cell_entry *cell) | ||||
|  { | ||||
|  	int err; | ||||
|   | ||||
| -	err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell); | ||||
| +	err = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, cell); | ||||
|  	if (err) | ||||
|  		return err; | ||||
|   | ||||
| @@ -507,7 +511,7 @@ static int nvmem_add_cells(struct nvmem_ | ||||
|  		    const struct nvmem_cell_info *info, | ||||
|  		    int ncells) | ||||
|  { | ||||
| -	struct nvmem_cell **cells; | ||||
| +	struct nvmem_cell_entry **cells; | ||||
|  	int i, rval; | ||||
|   | ||||
|  	cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); | ||||
| @@ -521,13 +525,13 @@ static int nvmem_add_cells(struct nvmem_ | ||||
|  			goto err; | ||||
|  		} | ||||
|   | ||||
| -		rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]); | ||||
| +		rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); | ||||
|  		if (rval) { | ||||
|  			kfree(cells[i]); | ||||
|  			goto err; | ||||
|  		} | ||||
|   | ||||
| -		nvmem_cell_add(cells[i]); | ||||
| +		nvmem_cell_entry_add(cells[i]); | ||||
|  	} | ||||
|   | ||||
|  	/* remove tmp array */ | ||||
| @@ -536,7 +540,7 @@ static int nvmem_add_cells(struct nvmem_ | ||||
|  	return 0; | ||||
|  err: | ||||
|  	while (i--) | ||||
| -		nvmem_cell_drop(cells[i]); | ||||
| +		nvmem_cell_entry_drop(cells[i]); | ||||
|   | ||||
|  	kfree(cells); | ||||
|   | ||||
| @@ -573,7 +577,7 @@ static int nvmem_add_cells_from_table(st | ||||
|  { | ||||
|  	const struct nvmem_cell_info *info; | ||||
|  	struct nvmem_cell_table *table; | ||||
| -	struct nvmem_cell *cell; | ||||
| +	struct nvmem_cell_entry *cell; | ||||
|  	int rval = 0, i; | ||||
|   | ||||
|  	mutex_lock(&nvmem_cell_mutex); | ||||
| @@ -588,15 +592,13 @@ static int nvmem_add_cells_from_table(st | ||||
|  					goto out; | ||||
|  				} | ||||
|   | ||||
| -				rval = nvmem_cell_info_to_nvmem_cell(nvmem, | ||||
| -								     info, | ||||
| -								     cell); | ||||
| +				rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); | ||||
|  				if (rval) { | ||||
|  					kfree(cell); | ||||
|  					goto out; | ||||
|  				} | ||||
|   | ||||
| -				nvmem_cell_add(cell); | ||||
| +				nvmem_cell_entry_add(cell); | ||||
|  			} | ||||
|  		} | ||||
|  	} | ||||
| @@ -606,10 +608,10 @@ out: | ||||
|  	return rval; | ||||
|  } | ||||
|   | ||||
| -static struct nvmem_cell * | ||||
| -nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) | ||||
| +static struct nvmem_cell_entry * | ||||
| +nvmem_find_cell_entry_by_name(struct nvmem_device *nvmem, const char *cell_id) | ||||
|  { | ||||
| -	struct nvmem_cell *iter, *cell = NULL; | ||||
| +	struct nvmem_cell_entry *iter, *cell = NULL; | ||||
|   | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
|  	list_for_each_entry(iter, &nvmem->cells, node) { | ||||
| @@ -680,7 +682,7 @@ static int nvmem_add_cells_from_of(struc | ||||
|  { | ||||
|  	struct device_node *parent, *child; | ||||
|  	struct device *dev = &nvmem->dev; | ||||
| -	struct nvmem_cell *cell; | ||||
| +	struct nvmem_cell_entry *cell; | ||||
|  	const __be32 *addr; | ||||
|  	int len; | ||||
|   | ||||
| @@ -729,7 +731,7 @@ static int nvmem_add_cells_from_of(struc | ||||
|  		} | ||||
|   | ||||
|  		cell->np = of_node_get(child); | ||||
| -		nvmem_cell_add(cell); | ||||
| +		nvmem_cell_entry_add(cell); | ||||
|  	} | ||||
|   | ||||
|  	return 0; | ||||
| @@ -1141,9 +1143,33 @@ struct nvmem_device *devm_nvmem_device_g | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(devm_nvmem_device_get); | ||||
|   | ||||
| +static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) | ||||
| +{ | ||||
| +	struct nvmem_cell *cell; | ||||
| +	const char *name = NULL; | ||||
| + | ||||
| +	cell = kzalloc(sizeof(*cell), GFP_KERNEL); | ||||
| +	if (!cell) | ||||
| +		return ERR_PTR(-ENOMEM); | ||||
| + | ||||
| +	if (id) { | ||||
| +		name = kstrdup_const(id, GFP_KERNEL); | ||||
| +		if (!name) { | ||||
| +			kfree(cell); | ||||
| +			return ERR_PTR(-ENOMEM); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	cell->id = name; | ||||
| +	cell->entry = entry; | ||||
| + | ||||
| +	return cell; | ||||
| +} | ||||
| + | ||||
|  static struct nvmem_cell * | ||||
|  nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) | ||||
|  { | ||||
| +	struct nvmem_cell_entry *cell_entry; | ||||
|  	struct nvmem_cell *cell = ERR_PTR(-ENOENT); | ||||
|  	struct nvmem_cell_lookup *lookup; | ||||
|  	struct nvmem_device *nvmem; | ||||
| @@ -1168,11 +1194,15 @@ nvmem_cell_get_from_lookup(struct device | ||||
|  				break; | ||||
|  			} | ||||
|   | ||||
| -			cell = nvmem_find_cell_by_name(nvmem, | ||||
| -						       lookup->cell_name); | ||||
| -			if (!cell) { | ||||
| +			cell_entry = nvmem_find_cell_entry_by_name(nvmem, | ||||
| +								   lookup->cell_name); | ||||
| +			if (!cell_entry) { | ||||
|  				__nvmem_device_put(nvmem); | ||||
|  				cell = ERR_PTR(-ENOENT); | ||||
| +			} else { | ||||
| +				cell = nvmem_create_cell(cell_entry, con_id); | ||||
| +				if (IS_ERR(cell)) | ||||
| +					__nvmem_device_put(nvmem); | ||||
|  			} | ||||
|  			break; | ||||
|  		} | ||||
| @@ -1183,10 +1213,10 @@ nvmem_cell_get_from_lookup(struct device | ||||
|  } | ||||
|   | ||||
|  #if IS_ENABLED(CONFIG_OF) | ||||
| -static struct nvmem_cell * | ||||
| -nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) | ||||
| +static struct nvmem_cell_entry * | ||||
| +nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np) | ||||
|  { | ||||
| -	struct nvmem_cell *iter, *cell = NULL; | ||||
| +	struct nvmem_cell_entry *iter, *cell = NULL; | ||||
|   | ||||
|  	mutex_lock(&nvmem_mutex); | ||||
|  	list_for_each_entry(iter, &nvmem->cells, node) { | ||||
| @@ -1216,6 +1246,7 @@ struct nvmem_cell *of_nvmem_cell_get(str | ||||
|  { | ||||
|  	struct device_node *cell_np, *nvmem_np; | ||||
|  	struct nvmem_device *nvmem; | ||||
| +	struct nvmem_cell_entry *cell_entry; | ||||
|  	struct nvmem_cell *cell; | ||||
|  	int index = 0; | ||||
|   | ||||
| @@ -1236,12 +1267,16 @@ struct nvmem_cell *of_nvmem_cell_get(str | ||||
|  	if (IS_ERR(nvmem)) | ||||
|  		return ERR_CAST(nvmem); | ||||
|   | ||||
| -	cell = nvmem_find_cell_by_node(nvmem, cell_np); | ||||
| -	if (!cell) { | ||||
| +	cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); | ||||
| +	if (!cell_entry) { | ||||
|  		__nvmem_device_put(nvmem); | ||||
|  		return ERR_PTR(-ENOENT); | ||||
|  	} | ||||
|   | ||||
| +	cell = nvmem_create_cell(cell_entry, id); | ||||
| +	if (IS_ERR(cell)) | ||||
| +		__nvmem_device_put(nvmem); | ||||
| + | ||||
|  	return cell; | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(of_nvmem_cell_get); | ||||
| @@ -1347,13 +1382,17 @@ EXPORT_SYMBOL(devm_nvmem_cell_put); | ||||
|   */ | ||||
|  void nvmem_cell_put(struct nvmem_cell *cell) | ||||
|  { | ||||
| -	struct nvmem_device *nvmem = cell->nvmem; | ||||
| +	struct nvmem_device *nvmem = cell->entry->nvmem; | ||||
| + | ||||
| +	if (cell->id) | ||||
| +		kfree_const(cell->id); | ||||
|   | ||||
| +	kfree(cell); | ||||
|  	__nvmem_device_put(nvmem); | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_cell_put); | ||||
|   | ||||
| -static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf) | ||||
| +static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf) | ||||
|  { | ||||
|  	u8 *p, *b; | ||||
|  	int i, extra, bit_offset = cell->bit_offset; | ||||
| @@ -1387,8 +1426,8 @@ static void nvmem_shift_read_buffer_in_p | ||||
|  } | ||||
|   | ||||
|  static int __nvmem_cell_read(struct nvmem_device *nvmem, | ||||
| -		      struct nvmem_cell *cell, | ||||
| -		      void *buf, size_t *len) | ||||
| +		      struct nvmem_cell_entry *cell, | ||||
| +		      void *buf, size_t *len, const char *id) | ||||
|  { | ||||
|  	int rc; | ||||
|   | ||||
| @@ -1419,18 +1458,18 @@ static int __nvmem_cell_read(struct nvme | ||||
|   */ | ||||
|  void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) | ||||
|  { | ||||
| -	struct nvmem_device *nvmem = cell->nvmem; | ||||
| +	struct nvmem_device *nvmem = cell->entry->nvmem; | ||||
|  	u8 *buf; | ||||
|  	int rc; | ||||
|   | ||||
|  	if (!nvmem) | ||||
|  		return ERR_PTR(-EINVAL); | ||||
|   | ||||
| -	buf = kzalloc(cell->bytes, GFP_KERNEL); | ||||
| +	buf = kzalloc(cell->entry->bytes, GFP_KERNEL); | ||||
|  	if (!buf) | ||||
|  		return ERR_PTR(-ENOMEM); | ||||
|   | ||||
| -	rc = __nvmem_cell_read(nvmem, cell, buf, len); | ||||
| +	rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); | ||||
|  	if (rc) { | ||||
|  		kfree(buf); | ||||
|  		return ERR_PTR(rc); | ||||
| @@ -1440,7 +1479,7 @@ void *nvmem_cell_read(struct nvmem_cell | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_cell_read); | ||||
|   | ||||
| -static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, | ||||
| +static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell, | ||||
|  					     u8 *_buf, int len) | ||||
|  { | ||||
|  	struct nvmem_device *nvmem = cell->nvmem; | ||||
| @@ -1493,16 +1532,7 @@ err: | ||||
|  	return ERR_PTR(rc); | ||||
|  } | ||||
|   | ||||
| -/** | ||||
| - * nvmem_cell_write() - Write to a given nvmem cell | ||||
| - * | ||||
| - * @cell: nvmem cell to be written. | ||||
| - * @buf: Buffer to be written. | ||||
| - * @len: length of buffer to be written to nvmem cell. | ||||
| - * | ||||
| - * Return: length of bytes written or negative on failure. | ||||
| - */ | ||||
| -int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) | ||||
| +static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, size_t len) | ||||
|  { | ||||
|  	struct nvmem_device *nvmem = cell->nvmem; | ||||
|  	int rc; | ||||
| @@ -1528,6 +1558,21 @@ int nvmem_cell_write(struct nvmem_cell * | ||||
|   | ||||
|  	return len; | ||||
|  } | ||||
| + | ||||
| +/** | ||||
| + * nvmem_cell_write() - Write to a given nvmem cell | ||||
| + * | ||||
| + * @cell: nvmem cell to be written. | ||||
| + * @buf: Buffer to be written. | ||||
| + * @len: length of buffer to be written to nvmem cell. | ||||
| + * | ||||
| + * Return: length of bytes written or negative on failure. | ||||
| + */ | ||||
| +int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) | ||||
| +{ | ||||
| +	return __nvmem_cell_entry_write(cell->entry, buf, len); | ||||
| +} | ||||
| + | ||||
|  EXPORT_SYMBOL_GPL(nvmem_cell_write); | ||||
|   | ||||
|  static int nvmem_cell_read_common(struct device *dev, const char *cell_id, | ||||
| @@ -1630,7 +1675,7 @@ static const void *nvmem_cell_read_varia | ||||
|  	if (IS_ERR(cell)) | ||||
|  		return cell; | ||||
|   | ||||
| -	nbits = cell->nbits; | ||||
| +	nbits = cell->entry->nbits; | ||||
|  	buf = nvmem_cell_read(cell, len); | ||||
|  	nvmem_cell_put(cell); | ||||
|  	if (IS_ERR(buf)) | ||||
| @@ -1726,18 +1771,18 @@ EXPORT_SYMBOL_GPL(nvmem_cell_read_variab | ||||
|  ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem, | ||||
|  			   struct nvmem_cell_info *info, void *buf) | ||||
|  { | ||||
| -	struct nvmem_cell cell; | ||||
| +	struct nvmem_cell_entry cell; | ||||
|  	int rc; | ||||
|  	ssize_t len; | ||||
|   | ||||
|  	if (!nvmem) | ||||
|  		return -EINVAL; | ||||
|   | ||||
| -	rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); | ||||
| +	rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); | ||||
|  	if (rc) | ||||
|  		return rc; | ||||
|   | ||||
| -	rc = __nvmem_cell_read(nvmem, &cell, buf, &len); | ||||
| +	rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); | ||||
|  	if (rc) | ||||
|  		return rc; | ||||
|   | ||||
| @@ -1757,17 +1802,17 @@ EXPORT_SYMBOL_GPL(nvmem_device_cell_read | ||||
|  int nvmem_device_cell_write(struct nvmem_device *nvmem, | ||||
|  			    struct nvmem_cell_info *info, void *buf) | ||||
|  { | ||||
| -	struct nvmem_cell cell; | ||||
| +	struct nvmem_cell_entry cell; | ||||
|  	int rc; | ||||
|   | ||||
|  	if (!nvmem) | ||||
|  		return -EINVAL; | ||||
|   | ||||
| -	rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); | ||||
| +	rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); | ||||
|  	if (rc) | ||||
|  		return rc; | ||||
|   | ||||
| -	return nvmem_cell_write(&cell, buf, cell.bytes); | ||||
| +	return __nvmem_cell_entry_write(&cell, buf, cell.bytes); | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_device_cell_write); | ||||
|   | ||||
| @@ -0,0 +1,82 @@ | ||||
| From 5008062f1c3f5af3acf86164aa6fcc77b0c7bdce Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Wed, 13 Oct 2021 14:19:56 +0100 | ||||
| Subject: [PATCH] nvmem: core: add nvmem cell post processing callback | ||||
|  | ||||
| Some NVMEM providers have certain nvmem cells encoded, which requires | ||||
| post processing before actually using it. | ||||
|  | ||||
| For example mac-address is stored in either in ascii or delimited or reverse-order. | ||||
|  | ||||
| Having a post-process callback hook to provider drivers would enable them to | ||||
| do this vendor specific post processing before nvmem consumers see it. | ||||
|  | ||||
| Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211013131957.30271-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c           | 9 +++++++++ | ||||
|  include/linux/nvmem-provider.h | 5 +++++ | ||||
|  2 files changed, 14 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -38,6 +38,7 @@ struct nvmem_device { | ||||
|  	unsigned int		nkeepout; | ||||
|  	nvmem_reg_read_t	reg_read; | ||||
|  	nvmem_reg_write_t	reg_write; | ||||
| +	nvmem_cell_post_process_t cell_post_process; | ||||
|  	struct gpio_desc	*wp_gpio; | ||||
|  	void *priv; | ||||
|  }; | ||||
| @@ -798,6 +799,7 @@ struct nvmem_device *nvmem_register(cons | ||||
|  	nvmem->type = config->type; | ||||
|  	nvmem->reg_read = config->reg_read; | ||||
|  	nvmem->reg_write = config->reg_write; | ||||
| +	nvmem->cell_post_process = config->cell_post_process; | ||||
|  	nvmem->keepout = config->keepout; | ||||
|  	nvmem->nkeepout = config->nkeepout; | ||||
|  	if (config->of_node) | ||||
| @@ -1440,6 +1442,13 @@ static int __nvmem_cell_read(struct nvme | ||||
|  	if (cell->bit_offset || cell->nbits) | ||||
|  		nvmem_shift_read_buffer_in_place(cell, buf); | ||||
|   | ||||
| +	if (nvmem->cell_post_process) { | ||||
| +		rc = nvmem->cell_post_process(nvmem->priv, id, | ||||
| +					      cell->offset, buf, cell->bytes); | ||||
| +		if (rc) | ||||
| +			return rc; | ||||
| +	} | ||||
| + | ||||
|  	if (len) | ||||
|  		*len = cell->bytes; | ||||
|   | ||||
| --- a/include/linux/nvmem-provider.h | ||||
| +++ b/include/linux/nvmem-provider.h | ||||
| @@ -19,6 +19,9 @@ typedef int (*nvmem_reg_read_t)(void *pr | ||||
|  				void *val, size_t bytes); | ||||
|  typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, | ||||
|  				 void *val, size_t bytes); | ||||
| +/* used for vendor specific post processing of cell data */ | ||||
| +typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, | ||||
| +					  void *buf, size_t bytes); | ||||
|   | ||||
|  enum nvmem_type { | ||||
|  	NVMEM_TYPE_UNKNOWN = 0, | ||||
| @@ -62,6 +65,7 @@ struct nvmem_keepout { | ||||
|   * @no_of_node:	Device should not use the parent's of_node even if it's !NULL. | ||||
|   * @reg_read:	Callback to read data. | ||||
|   * @reg_write:	Callback to write data. | ||||
| + * @cell_post_process:	Callback for vendor specific post processing of cell data | ||||
|   * @size:	Device size. | ||||
|   * @word_size:	Minimum read/write access granularity. | ||||
|   * @stride:	Minimum read/write access stride. | ||||
| @@ -94,6 +98,7 @@ struct nvmem_config { | ||||
|  	bool			no_of_node; | ||||
|  	nvmem_reg_read_t	reg_read; | ||||
|  	nvmem_reg_write_t	reg_write; | ||||
| +	nvmem_cell_post_process_t cell_post_process; | ||||
|  	int	size; | ||||
|  	int	word_size; | ||||
|  	int	stride; | ||||
| @@ -0,0 +1,92 @@ | ||||
| From d0221a780cbc99fec6c27a98dba2828dc5735c00 Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Wed, 13 Oct 2021 14:19:57 +0100 | ||||
| Subject: [PATCH] nvmem: imx-ocotp: add support for post processing | ||||
|  | ||||
| Add .cell_post_process callback for imx-ocotp to deal with MAC address, | ||||
| since MAC address need to be reversed byte for some i.MX SoCs. | ||||
|  | ||||
| Tested-by: Joakim Zhang <qiangqing.zhang@nxp.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211013131957.30271-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/imx-ocotp.c | 25 +++++++++++++++++++++++++ | ||||
|  1 file changed, 25 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/imx-ocotp.c | ||||
| +++ b/drivers/nvmem/imx-ocotp.c | ||||
| @@ -97,6 +97,7 @@ struct ocotp_params { | ||||
|  	unsigned int bank_address_words; | ||||
|  	void (*set_timing)(struct ocotp_priv *priv); | ||||
|  	struct ocotp_ctrl_reg ctrl; | ||||
| +	bool reverse_mac_address; | ||||
|  }; | ||||
|   | ||||
|  static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) | ||||
| @@ -221,6 +222,25 @@ read_end: | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| +static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, | ||||
| +			     void *data, size_t bytes) | ||||
| +{ | ||||
| +	struct ocotp_priv *priv = context; | ||||
| + | ||||
| +	/* Deal with some post processing of nvmem cell data */ | ||||
| +	if (id && !strcmp(id, "mac-address")) { | ||||
| +		if (priv->params->reverse_mac_address) { | ||||
| +			u8 *buf = data; | ||||
| +			int i; | ||||
| + | ||||
| +			for (i = 0; i < bytes/2; i++) | ||||
| +				swap(buf[i], buf[bytes - i - 1]); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
|  static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv) | ||||
|  { | ||||
|  	unsigned long clk_rate; | ||||
| @@ -468,6 +488,7 @@ static struct nvmem_config imx_ocotp_nvm | ||||
|  	.stride = 1, | ||||
|  	.reg_read = imx_ocotp_read, | ||||
|  	.reg_write = imx_ocotp_write, | ||||
| +	.cell_post_process = imx_ocotp_cell_pp, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx6q_params = { | ||||
| @@ -530,6 +551,7 @@ static const struct ocotp_params imx8mq_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx8mm_params = { | ||||
| @@ -537,6 +559,7 @@ static const struct ocotp_params imx8mm_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx8mn_params = { | ||||
| @@ -544,6 +567,7 @@ static const struct ocotp_params imx8mn_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct ocotp_params imx8mp_params = { | ||||
| @@ -551,6 +575,7 @@ static const struct ocotp_params imx8mp_ | ||||
|  	.bank_address_words = 0, | ||||
|  	.set_timing = imx_ocotp_set_imx6_timing, | ||||
|  	.ctrl = IMX_OCOTP_BM_CTRL_8MP, | ||||
| +	.reverse_mac_address = true, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id imx_ocotp_dt_ids[] = { | ||||
| @@ -0,0 +1,47 @@ | ||||
| From 98e2c4efae214fb7086cac9117616eb6ea11475d Mon Sep 17 00:00:00 2001 | ||||
| From: Chunfeng Yun <chunfeng.yun@mediatek.com> | ||||
| Date: Thu, 9 Dec 2021 17:42:34 +0000 | ||||
| Subject: [PATCH] nvmem: mtk-efuse: support minimum one byte access stride and | ||||
|  granularity | ||||
|  | ||||
| In order to support nvmem bits property, should support minimum 1 byte | ||||
| read stride and minimum 1 byte read granularity at the same time. | ||||
|  | ||||
| Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20211209174235.14049-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/mtk-efuse.c | 13 +++++++------ | ||||
|  1 file changed, 7 insertions(+), 6 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/mtk-efuse.c | ||||
| +++ b/drivers/nvmem/mtk-efuse.c | ||||
| @@ -19,11 +19,12 @@ static int mtk_reg_read(void *context, | ||||
|  			unsigned int reg, void *_val, size_t bytes) | ||||
|  { | ||||
|  	struct mtk_efuse_priv *priv = context; | ||||
| -	u32 *val = _val; | ||||
| -	int i = 0, words = bytes / 4; | ||||
| +	void __iomem *addr = priv->base + reg; | ||||
| +	u8 *val = _val; | ||||
| +	int i; | ||||
|   | ||||
| -	while (words--) | ||||
| -		*val++ = readl(priv->base + reg + (i++ * 4)); | ||||
| +	for (i = 0; i < bytes; i++, val++) | ||||
| +		*val = readb(addr + i); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -45,8 +46,8 @@ static int mtk_efuse_probe(struct platfo | ||||
|  	if (IS_ERR(priv->base)) | ||||
|  		return PTR_ERR(priv->base); | ||||
|   | ||||
| -	econfig.stride = 4; | ||||
| -	econfig.word_size = 4; | ||||
| +	econfig.stride = 1; | ||||
| +	econfig.word_size = 1; | ||||
|  	econfig.reg_read = mtk_reg_read; | ||||
|  	econfig.size = resource_size(res); | ||||
|  	econfig.priv = priv; | ||||
| @@ -0,0 +1,72 @@ | ||||
| From 190fae468592bc2f0efc8b928920f8f712b5831e Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:15 +0000 | ||||
| Subject: [PATCH] nvmem: core: Remove unused devm_nvmem_unregister() | ||||
|  | ||||
| There are no users and seems no will come of the devm_nvmem_unregister(). | ||||
| Remove the function and remove the unused devm_nvmem_match() along with it. | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c           | 22 ---------------------- | ||||
|  include/linux/nvmem-provider.h |  8 -------- | ||||
|  2 files changed, 30 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -942,28 +942,6 @@ struct nvmem_device *devm_nvmem_register | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(devm_nvmem_register); | ||||
|   | ||||
| -static int devm_nvmem_match(struct device *dev, void *res, void *data) | ||||
| -{ | ||||
| -	struct nvmem_device **r = res; | ||||
| - | ||||
| -	return *r == data; | ||||
| -} | ||||
| - | ||||
| -/** | ||||
| - * devm_nvmem_unregister() - Unregister previously registered managed nvmem | ||||
| - * device. | ||||
| - * | ||||
| - * @dev: Device that uses the nvmem device. | ||||
| - * @nvmem: Pointer to previously registered nvmem device. | ||||
| - * | ||||
| - * Return: Will be negative on error or zero on success. | ||||
| - */ | ||||
| -int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) | ||||
| -{ | ||||
| -	return devres_release(dev, devm_nvmem_release, devm_nvmem_match, nvmem); | ||||
| -} | ||||
| -EXPORT_SYMBOL(devm_nvmem_unregister); | ||||
| - | ||||
|  static struct nvmem_device *__nvmem_device_get(void *data, | ||||
|  			int (*match)(struct device *dev, const void *data)) | ||||
|  { | ||||
| --- a/include/linux/nvmem-provider.h | ||||
| +++ b/include/linux/nvmem-provider.h | ||||
| @@ -135,8 +135,6 @@ void nvmem_unregister(struct nvmem_devic | ||||
|  struct nvmem_device *devm_nvmem_register(struct device *dev, | ||||
|  					 const struct nvmem_config *cfg); | ||||
|   | ||||
| -int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem); | ||||
| - | ||||
|  void nvmem_add_cell_table(struct nvmem_cell_table *table); | ||||
|  void nvmem_del_cell_table(struct nvmem_cell_table *table); | ||||
|   | ||||
| @@ -155,12 +153,6 @@ devm_nvmem_register(struct device *dev, | ||||
|  	return nvmem_register(c); | ||||
|  } | ||||
|   | ||||
| -static inline int | ||||
| -devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) | ||||
| -{ | ||||
| -	return -EOPNOTSUPP; | ||||
| -} | ||||
| - | ||||
|  static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} | ||||
|  static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} | ||||
|   | ||||
| @@ -0,0 +1,58 @@ | ||||
| From 5825b2c6762611e67ccaf3ccf64485365a120f0b Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:16 +0000 | ||||
| Subject: [PATCH] nvmem: core: Use devm_add_action_or_reset() | ||||
|  | ||||
| Slightly simplify the devm_nvmem_register() by using the | ||||
| devm_add_action_or_reset(). | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 22 +++++++++------------- | ||||
|  1 file changed, 9 insertions(+), 13 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -904,9 +904,9 @@ void nvmem_unregister(struct nvmem_devic | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_unregister); | ||||
|   | ||||
| -static void devm_nvmem_release(struct device *dev, void *res) | ||||
| +static void devm_nvmem_unregister(void *nvmem) | ||||
|  { | ||||
| -	nvmem_unregister(*(struct nvmem_device **)res); | ||||
| +	nvmem_unregister(nvmem); | ||||
|  } | ||||
|   | ||||
|  /** | ||||
| @@ -923,20 +923,16 @@ static void devm_nvmem_release(struct de | ||||
|  struct nvmem_device *devm_nvmem_register(struct device *dev, | ||||
|  					 const struct nvmem_config *config) | ||||
|  { | ||||
| -	struct nvmem_device **ptr, *nvmem; | ||||
| - | ||||
| -	ptr = devres_alloc(devm_nvmem_release, sizeof(*ptr), GFP_KERNEL); | ||||
| -	if (!ptr) | ||||
| -		return ERR_PTR(-ENOMEM); | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	int ret; | ||||
|   | ||||
|  	nvmem = nvmem_register(config); | ||||
| +	if (IS_ERR(nvmem)) | ||||
| +		return nvmem; | ||||
|   | ||||
| -	if (!IS_ERR(nvmem)) { | ||||
| -		*ptr = nvmem; | ||||
| -		devres_add(dev, ptr); | ||||
| -	} else { | ||||
| -		devres_free(ptr); | ||||
| -	} | ||||
| +	ret = devm_add_action_or_reset(dev, devm_nvmem_unregister, nvmem); | ||||
| +	if (ret) | ||||
| +		return ERR_PTR(ret); | ||||
|   | ||||
|  	return nvmem; | ||||
|  } | ||||
| @@ -0,0 +1,30 @@ | ||||
| From 8c751e0d9a5264376935a84429a2d468c8877d99 Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:17 +0000 | ||||
| Subject: [PATCH] nvmem: core: Check input parameter for NULL in | ||||
|  nvmem_unregister() | ||||
|  | ||||
| nvmem_unregister() frees resources and standard pattern is to allow | ||||
| caller to not care if it's NULL or not. This will reduce burden on | ||||
| the callers to perform this check. | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 3 ++- | ||||
|  1 file changed, 2 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -900,7 +900,8 @@ static void nvmem_device_release(struct | ||||
|   */ | ||||
|  void nvmem_unregister(struct nvmem_device *nvmem) | ||||
|  { | ||||
| -	kref_put(&nvmem->refcnt, nvmem_device_release); | ||||
| +	if (nvmem) | ||||
| +		kref_put(&nvmem->refcnt, nvmem_device_release); | ||||
|  } | ||||
|  EXPORT_SYMBOL_GPL(nvmem_unregister); | ||||
|   | ||||
| @@ -0,0 +1,29 @@ | ||||
| From 05196facc052385960028ac634447ecf6c764ec3 Mon Sep 17 00:00:00 2001 | ||||
| From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Date: Sun, 20 Feb 2022 15:15:18 +0000 | ||||
| Subject: [PATCH] nvmem: qfprom: fix kerneldoc warning | ||||
|  | ||||
| This patch fixes below kernel doc warning, | ||||
| warning: expecting prototype for qfprom_efuse_reg_write(). | ||||
| Prototype was for qfprom_reg_write() instead | ||||
|  | ||||
| No code changes. | ||||
|  | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-5-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/qfprom.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/qfprom.c | ||||
| +++ b/drivers/nvmem/qfprom.c | ||||
| @@ -244,7 +244,7 @@ err_clk_prepared: | ||||
|  } | ||||
|   | ||||
|  /** | ||||
| - * qfprom_efuse_reg_write() - Write to fuses. | ||||
| + * qfprom_reg_write() - Write to fuses. | ||||
|   * @context: Our driver data. | ||||
|   * @reg:     The offset to write at. | ||||
|   * @_val:    Pointer to data to write. | ||||
| @@ -0,0 +1,38 @@ | ||||
| From 07ae4fde9efada7878e1383d6ccc7da70315ca23 Mon Sep 17 00:00:00 2001 | ||||
| From: Samuel Holland <samuel@sholland.org> | ||||
| Date: Sun, 20 Feb 2022 15:15:20 +0000 | ||||
| Subject: [PATCH] nvmem: sunxi_sid: Add support for D1 variant | ||||
|  | ||||
| D1 has a smaller eFuse block than some other recent SoCs, and it no | ||||
| longer requires a workaround to read the eFuse data. | ||||
|  | ||||
| Signed-off-by: Samuel Holland <samuel@sholland.org> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-7-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/sunxi_sid.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/sunxi_sid.c | ||||
| +++ b/drivers/nvmem/sunxi_sid.c | ||||
| @@ -184,6 +184,11 @@ static const struct sunxi_sid_cfg sun8i_ | ||||
|  	.need_register_readout = true, | ||||
|  }; | ||||
|   | ||||
| +static const struct sunxi_sid_cfg sun20i_d1_cfg = { | ||||
| +	.value_offset = 0x200, | ||||
| +	.size = 0x100, | ||||
| +}; | ||||
| + | ||||
|  static const struct sunxi_sid_cfg sun50i_a64_cfg = { | ||||
|  	.value_offset = 0x200, | ||||
|  	.size = 0x100, | ||||
| @@ -200,6 +205,7 @@ static const struct of_device_id sunxi_s | ||||
|  	{ .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg }, | ||||
|  	{ .compatible = "allwinner,sun8i-a83t-sid", .data = &sun50i_a64_cfg }, | ||||
|  	{ .compatible = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_cfg }, | ||||
| +	{ .compatible = "allwinner,sun20i-d1-sid", .data = &sun20i_d1_cfg }, | ||||
|  	{ .compatible = "allwinner,sun50i-a64-sid", .data = &sun50i_a64_cfg }, | ||||
|  	{ .compatible = "allwinner,sun50i-h5-sid", .data = &sun50i_a64_cfg }, | ||||
|  	{ .compatible = "allwinner,sun50i-h6-sid", .data = &sun50i_h6_cfg }, | ||||
| @@ -0,0 +1,28 @@ | ||||
| From 4dc8d89faed9bb05f116fa1794fc955b14910386 Mon Sep 17 00:00:00 2001 | ||||
| From: Xiaoke Wang <xkernel.wang@foxmail.com> | ||||
| Date: Sun, 20 Feb 2022 15:15:21 +0000 | ||||
| Subject: [PATCH] nvmem: meson-mx-efuse: replace unnecessary devm_kstrdup() | ||||
|  | ||||
| Replace unnecessary devm_kstrdup() so to avoid redundant memory allocation. | ||||
|  | ||||
| Suggested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> | ||||
| Signed-off-by: Xiaoke Wang <xkernel.wang@foxmail.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/meson-mx-efuse.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/meson-mx-efuse.c | ||||
| +++ b/drivers/nvmem/meson-mx-efuse.c | ||||
| @@ -209,8 +209,7 @@ static int meson_mx_efuse_probe(struct p | ||||
|  	if (IS_ERR(efuse->base)) | ||||
|  		return PTR_ERR(efuse->base); | ||||
|   | ||||
| -	efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name, | ||||
| -					  GFP_KERNEL); | ||||
| +	efuse->config.name = drvdata->name; | ||||
|  	efuse->config.owner = THIS_MODULE; | ||||
|  	efuse->config.dev = &pdev->dev; | ||||
|  	efuse->config.priv = efuse; | ||||
| @@ -0,0 +1,139 @@ | ||||
| From f78451012b9e159afdba31c3eb69f223a9f42adc Mon Sep 17 00:00:00 2001 | ||||
| From: Michael Walle <michael@walle.cc> | ||||
| Date: Sun, 20 Feb 2022 15:15:23 +0000 | ||||
| Subject: [PATCH] nvmem: add driver for Layerscape SFP (Security Fuse | ||||
|  Processor) | ||||
|  | ||||
| Add support for the Security Fuse Processor found on Layerscape SoCs. | ||||
| This driver implements basic read access. | ||||
|  | ||||
| Signed-off-by: Michael Walle <michael@walle.cc> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220220151527.17216-10-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig          | 12 +++++ | ||||
|  drivers/nvmem/Makefile         |  2 + | ||||
|  drivers/nvmem/layerscape-sfp.c | 89 ++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 103 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/layerscape-sfp.c | ||||
|  | ||||
| --- 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_LAYERSCAPE_SFP | ||||
| +	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
| +	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver provides support to read the eFuses on Freescale | ||||
| +	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| +	  unique ID there. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called layerscape-sfp. | ||||
| + | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem. | ||||
|  nvmem-rmem-y			:= rmem.o | ||||
|  obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o | ||||
|  nvmem_brcm_nvram-y		:= brcm_nvram.o | ||||
| +obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
| +nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/layerscape-sfp.c | ||||
| @@ -0,0 +1,89 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0-only | ||||
| +/* | ||||
| + * Layerscape SFP driver | ||||
| + * | ||||
| + * Copyright (c) 2022 Michael Walle <michael@walle.cc> | ||||
| + * | ||||
| + */ | ||||
| + | ||||
| +#include <linux/device.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/mod_devicetable.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/property.h> | ||||
| + | ||||
| +#define LAYERSCAPE_SFP_OTP_OFFSET	0x0200 | ||||
| + | ||||
| +struct layerscape_sfp_priv { | ||||
| +	void __iomem *base; | ||||
| +}; | ||||
| + | ||||
| +struct layerscape_sfp_data { | ||||
| +	int size; | ||||
| +}; | ||||
| + | ||||
| +static int layerscape_sfp_read(void *context, unsigned int offset, void *val, | ||||
| +			       size_t bytes) | ||||
| +{ | ||||
| +	struct layerscape_sfp_priv *priv = context; | ||||
| + | ||||
| +	memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, | ||||
| +		      bytes); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config layerscape_sfp_nvmem_config = { | ||||
| +	.name = "fsl-sfp", | ||||
| +	.reg_read = layerscape_sfp_read, | ||||
| +}; | ||||
| + | ||||
| +static int layerscape_sfp_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	const struct layerscape_sfp_data *data; | ||||
| +	struct layerscape_sfp_priv *priv; | ||||
| +	struct nvmem_device *nvmem; | ||||
| + | ||||
| +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||||
| +	if (!priv) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	priv->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(priv->base)) | ||||
| +		return PTR_ERR(priv->base); | ||||
| + | ||||
| +	data = device_get_match_data(&pdev->dev); | ||||
| + | ||||
| +	layerscape_sfp_nvmem_config.size = data->size; | ||||
| +	layerscape_sfp_nvmem_config.dev = &pdev->dev; | ||||
| +	layerscape_sfp_nvmem_config.priv = priv; | ||||
| + | ||||
| +	nvmem = devm_nvmem_register(&pdev->dev, &layerscape_sfp_nvmem_config); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(nvmem); | ||||
| +} | ||||
| + | ||||
| +static const struct layerscape_sfp_data ls1028a_data = { | ||||
| +	.size = 0x88, | ||||
| +}; | ||||
| + | ||||
| +static const struct of_device_id layerscape_sfp_dt_ids[] = { | ||||
| +	{ .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, | ||||
| +	{}, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, layerscape_sfp_dt_ids); | ||||
| + | ||||
| +static struct platform_driver layerscape_sfp_driver = { | ||||
| +	.probe	= layerscape_sfp_probe, | ||||
| +	.driver = { | ||||
| +		.name	= "layerscape_sfp", | ||||
| +		.of_match_table = layerscape_sfp_dt_ids, | ||||
| +	}, | ||||
| +}; | ||||
| +module_platform_driver(layerscape_sfp_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Michael Walle <michael@walle.cc>"); | ||||
| +MODULE_DESCRIPTION("Layerscape Security Fuse Processor driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,32 @@ | ||||
| From bc5c75e0a5a9400f81a987cc720100ac475fa4d8 Mon Sep 17 00:00:00 2001 | ||||
| From: Knox Chiou <knoxchiou@chromium.org> | ||||
| Date: Wed, 23 Feb 2022 22:35:00 +0000 | ||||
| Subject: [PATCH] nvmem: qfprom: Increase fuse blow timeout to prevent write | ||||
|  fail | ||||
|  | ||||
| sc7180 blow fuses got slightly chances to hit qfprom_reg_write timeout. | ||||
| Current timeout is simply too low. Since blowing fuses is a | ||||
| very rare operation, so the risk associated with overestimating this | ||||
| number is low. | ||||
| Increase fuse blow timeout from 1ms to 10ms. | ||||
|  | ||||
| Reviewed-by: Douglas Anderson <dianders@chromium.org> | ||||
| Signed-off-by: Knox Chiou <knoxchiou@chromium.org> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220223223502.29454-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/qfprom.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/qfprom.c | ||||
| +++ b/drivers/nvmem/qfprom.c | ||||
| @@ -22,7 +22,7 @@ | ||||
|   | ||||
|  /* Amount of time required to hold charge to blow fuse in micro-seconds */ | ||||
|  #define QFPROM_FUSE_BLOW_POLL_US	100 | ||||
| -#define QFPROM_FUSE_BLOW_TIMEOUT_US	1000 | ||||
| +#define QFPROM_FUSE_BLOW_TIMEOUT_US	10000 | ||||
|   | ||||
|  #define QFPROM_BLOW_STATUS_OFFSET	0x048 | ||||
|  #define QFPROM_BLOW_STATUS_BUSY		0x1 | ||||
| @@ -0,0 +1,291 @@ | ||||
| From 8747ec2e9762ed9ae53b3a590938f454b6a1abdf Mon Sep 17 00:00:00 2001 | ||||
| From: Vincent Shih <vincent.sunplus@gmail.com> | ||||
| Date: Wed, 23 Feb 2022 22:35:01 +0000 | ||||
| Subject: [PATCH] nvmem: Add driver for OCOTP in Sunplus SP7021 | ||||
|  | ||||
| Add driver for OCOTP in Sunplus SP7021 | ||||
|  | ||||
| Signed-off-by: Vincent Shih <vincent.sunplus@gmail.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220223223502.29454-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  MAINTAINERS                   |   5 + | ||||
|  drivers/nvmem/Kconfig         |  12 ++ | ||||
|  drivers/nvmem/Makefile        |   2 + | ||||
|  drivers/nvmem/sunplus-ocotp.c | 228 ++++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 247 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/sunplus-ocotp.c | ||||
|  | ||||
| --- a/MAINTAINERS | ||||
| +++ b/MAINTAINERS | ||||
| @@ -17953,6 +17953,11 @@ L:	netdev@vger.kernel.org | ||||
|  S:	Maintained | ||||
|  F:	drivers/net/ethernet/dlink/sundance.c | ||||
|   | ||||
| +SUNPLUS OCOTP DRIVER | ||||
| +M:	Vincent Shih <vincent.sunplus@gmail.com> | ||||
| +S:	Maintained | ||||
| +F:	drivers/nvmem/sunplus-ocotp.c | ||||
| + | ||||
|  SUPERH | ||||
|  M:	Yoshinori Sato <ysato@users.sourceforge.jp> | ||||
|  M:	Rich Felker <dalias@libc.org> | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -312,4 +312,16 @@ config NVMEM_LAYERSCAPE_SFP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called layerscape-sfp. | ||||
|   | ||||
| +config NVMEM_SUNPLUS_OCOTP | ||||
| +	tristate "Sunplus SoC OTP support" | ||||
| +	depends on SOC_SP7021 || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This is a driver for the On-chip OTP controller (OCOTP) available | ||||
| +	  on Sunplus SoCs. It provides access to 128 bytes of one-time | ||||
| +	  programmable eFuse. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-sunplus-ocotp. | ||||
| + | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -63,3 +63,5 @@ obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_ | ||||
|  nvmem_brcm_nvram-y		:= brcm_nvram.o | ||||
|  obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
|  nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
| +obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o | ||||
| +nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/sunplus-ocotp.c | ||||
| @@ -0,0 +1,228 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| + | ||||
| +/* | ||||
| + * The OCOTP driver for Sunplus	SP7021 | ||||
| + * | ||||
| + * Copyright (C) 2019 Sunplus Technology Inc., All rights reserved. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitfield.h> | ||||
| +#include <linux/clk.h> | ||||
| +#include <linux/delay.h> | ||||
| +#include <linux/device.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/iopoll.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/of_device.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +/* | ||||
| + * OTP memory | ||||
| + * Each bank contains 4 words (32 bits). | ||||
| + * Bank 0 starts at offset 0 from the base. | ||||
| + */ | ||||
| + | ||||
| +#define OTP_WORDS_PER_BANK		4 | ||||
| +#define OTP_WORD_SIZE			sizeof(u32) | ||||
| +#define OTP_BIT_ADDR_OF_BANK		(8 * OTP_WORD_SIZE * OTP_WORDS_PER_BANK) | ||||
| +#define QAC628_OTP_NUM_BANKS		8 | ||||
| +#define QAC628_OTP_SIZE			(QAC628_OTP_NUM_BANKS * OTP_WORDS_PER_BANK * OTP_WORD_SIZE) | ||||
| +#define OTP_READ_TIMEOUT_US		200000 | ||||
| + | ||||
| +/* HB_GPIO */ | ||||
| +#define ADDRESS_8_DATA			0x20 | ||||
| + | ||||
| +/* OTP_RX */ | ||||
| +#define OTP_CONTROL_2			0x48 | ||||
| +#define OTP_RD_PERIOD			GENMASK(15, 8) | ||||
| +#define OTP_RD_PERIOD_MASK		~GENMASK(15, 8) | ||||
| +#define CPU_CLOCK			FIELD_PREP(OTP_RD_PERIOD, 30) | ||||
| +#define SEL_BAK_KEY2			BIT(5) | ||||
| +#define SEL_BAK_KEY2_MASK		~BIT(5) | ||||
| +#define SW_TRIM_EN			BIT(4) | ||||
| +#define SW_TRIM_EN_MASK			~BIT(4) | ||||
| +#define SEL_BAK_KEY			BIT(3) | ||||
| +#define SEL_BAK_KEY_MASK		~BIT(3) | ||||
| +#define OTP_READ			BIT(2) | ||||
| +#define OTP_LOAD_SECURE_DATA		BIT(1) | ||||
| +#define OTP_LOAD_SECURE_DATA_MASK	~BIT(1) | ||||
| +#define OTP_DO_CRC			BIT(0) | ||||
| +#define OTP_DO_CRC_MASK			~BIT(0) | ||||
| +#define OTP_STATUS			0x4c | ||||
| +#define OTP_READ_DONE			BIT(4) | ||||
| +#define OTP_READ_DONE_MASK		~BIT(4) | ||||
| +#define OTP_LOAD_SECURE_DONE_MASK	~BIT(2) | ||||
| +#define OTP_READ_ADDRESS		0x50 | ||||
| + | ||||
| +enum base_type { | ||||
| +	HB_GPIO, | ||||
| +	OTPRX, | ||||
| +	BASEMAX, | ||||
| +}; | ||||
| + | ||||
| +struct sp_ocotp_priv { | ||||
| +	struct device *dev; | ||||
| +	void __iomem *base[BASEMAX]; | ||||
| +	struct clk *clk; | ||||
| +}; | ||||
| + | ||||
| +struct sp_ocotp_data { | ||||
| +	int size; | ||||
| +}; | ||||
| + | ||||
| +const struct sp_ocotp_data  sp_otp_v0 = { | ||||
| +	.size = QAC628_OTP_SIZE, | ||||
| +}; | ||||
| + | ||||
| +static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value) | ||||
| +{ | ||||
| +	unsigned int addr_data; | ||||
| +	unsigned int byte_shift; | ||||
| +	unsigned int status; | ||||
| +	int ret; | ||||
| + | ||||
| +	addr_data = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); | ||||
| +	addr_data = addr_data / OTP_WORD_SIZE; | ||||
| + | ||||
| +	byte_shift = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); | ||||
| +	byte_shift = byte_shift % OTP_WORD_SIZE; | ||||
| + | ||||
| +	addr = addr / (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); | ||||
| +	addr = addr * OTP_BIT_ADDR_OF_BANK; | ||||
| + | ||||
| +	writel(readl(otp->base[OTPRX] + OTP_STATUS) & OTP_READ_DONE_MASK & | ||||
| +	       OTP_LOAD_SECURE_DONE_MASK, otp->base[OTPRX] + OTP_STATUS); | ||||
| +	writel(addr, otp->base[OTPRX] + OTP_READ_ADDRESS); | ||||
| +	writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) | OTP_READ, | ||||
| +	       otp->base[OTPRX] + OTP_CONTROL_2); | ||||
| +	writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) & SEL_BAK_KEY2_MASK & SW_TRIM_EN_MASK | ||||
| +	       & SEL_BAK_KEY_MASK & OTP_LOAD_SECURE_DATA_MASK & OTP_DO_CRC_MASK, | ||||
| +	       otp->base[OTPRX] + OTP_CONTROL_2); | ||||
| +	writel((readl(otp->base[OTPRX] + OTP_CONTROL_2) & OTP_RD_PERIOD_MASK) | CPU_CLOCK, | ||||
| +	       otp->base[OTPRX] + OTP_CONTROL_2); | ||||
| + | ||||
| +	ret = readl_poll_timeout(otp->base[OTPRX] + OTP_STATUS, status, | ||||
| +				 status & OTP_READ_DONE, 10, OTP_READ_TIMEOUT_US); | ||||
| + | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	*value = (readl(otp->base[HB_GPIO] + ADDRESS_8_DATA + addr_data * OTP_WORD_SIZE) | ||||
| +		  >> (8 * byte_shift)) & 0xff; | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes) | ||||
| +{ | ||||
| +	struct sp_ocotp_priv *otp = priv; | ||||
| +	unsigned int addr; | ||||
| +	char *buf = value; | ||||
| +	char val[4]; | ||||
| +	int ret; | ||||
| + | ||||
| +	ret = clk_enable(otp->clk); | ||||
| +	if (ret) | ||||
| +		return ret; | ||||
| + | ||||
| +	*buf = 0; | ||||
| +	for (addr = offset; addr < (offset + bytes); addr++) { | ||||
| +		ret = sp_otp_read_real(otp, addr, val); | ||||
| +		if (ret < 0) { | ||||
| +			dev_err(otp->dev, "OTP read fail:%d at %d", ret, addr); | ||||
| +			goto disable_clk; | ||||
| +		} | ||||
| + | ||||
| +		*buf++ = *val; | ||||
| +	} | ||||
| + | ||||
| +disable_clk: | ||||
| +	clk_disable(otp->clk); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config sp_ocotp_nvmem_config = { | ||||
| +	.name = "sp-ocotp", | ||||
| +	.read_only = true, | ||||
| +	.word_size = 1, | ||||
| +	.size = QAC628_OTP_SIZE, | ||||
| +	.stride = 1, | ||||
| +	.reg_read = sp_ocotp_read, | ||||
| +	.owner = THIS_MODULE, | ||||
| +}; | ||||
| + | ||||
| +static int sp_ocotp_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct device *dev = &pdev->dev; | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	struct sp_ocotp_priv *otp; | ||||
| +	struct resource *res; | ||||
| +	int ret; | ||||
| + | ||||
| +	otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); | ||||
| +	if (!otp) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	otp->dev = dev; | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio"); | ||||
| +	otp->base[HB_GPIO] = devm_ioremap_resource(dev, res); | ||||
| +	if (IS_ERR(otp->base[HB_GPIO])) | ||||
| +		return PTR_ERR(otp->base[HB_GPIO]); | ||||
| + | ||||
| +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx"); | ||||
| +	otp->base[OTPRX] = devm_ioremap_resource(dev, res); | ||||
| +	if (IS_ERR(otp->base[OTPRX])) | ||||
| +		return PTR_ERR(otp->base[OTPRX]); | ||||
| + | ||||
| +	otp->clk = devm_clk_get(&pdev->dev, NULL); | ||||
| +	if (IS_ERR(otp->clk)) | ||||
| +		return dev_err_probe(&pdev->dev, PTR_ERR(otp->clk), | ||||
| +						"devm_clk_get fail\n"); | ||||
| + | ||||
| +	ret = clk_prepare(otp->clk); | ||||
| +	if (ret < 0) { | ||||
| +		dev_err(dev, "failed to prepare clk: %d\n", ret); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	sp_ocotp_nvmem_config.priv = otp; | ||||
| +	sp_ocotp_nvmem_config.dev = dev; | ||||
| + | ||||
| +	nvmem = devm_nvmem_register(dev, &sp_ocotp_nvmem_config); | ||||
| +	if (IS_ERR(nvmem)) | ||||
| +		return dev_err_probe(&pdev->dev, PTR_ERR(nvmem), | ||||
| +						"register nvmem device fail\n"); | ||||
| + | ||||
| +	platform_set_drvdata(pdev, nvmem); | ||||
| + | ||||
| +	dev_dbg(dev, "banks:%d x wpb:%d x wsize:%d = %d", | ||||
| +		(int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK, | ||||
| +		(int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE); | ||||
| + | ||||
| +	dev_info(dev, "by Sunplus (C) 2020"); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id sp_ocotp_dt_ids[] = { | ||||
| +	{ .compatible = "sunplus,sp7021-ocotp", .data = &sp_otp_v0 }, | ||||
| +	{ } | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, sp_ocotp_dt_ids); | ||||
| + | ||||
| +static struct platform_driver sp_otp_driver = { | ||||
| +	.probe     = sp_ocotp_probe, | ||||
| +	.driver    = { | ||||
| +		.name           = "sunplus,sp7021-ocotp", | ||||
| +		.of_match_table = sp_ocotp_dt_ids, | ||||
| +	} | ||||
| +}; | ||||
| +module_platform_driver(sp_otp_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Vincent Shih <vincent.sunplus@gmail.com>"); | ||||
| +MODULE_DESCRIPTION("Sunplus On-Chip OTP driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| + | ||||
| @@ -0,0 +1,32 @@ | ||||
| From 6bd0ffeaa389866089e9573b2298ae58d6359b75 Mon Sep 17 00:00:00 2001 | ||||
| From: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Date: Mon, 21 Mar 2022 12:03:24 +0100 | ||||
| Subject: [PATCH] nvmem: bcm-ocotp: mark ACPI device ID table as maybe unused | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| "bcm_otpc_acpi_ids" is used with ACPI_PTR, so a build with !CONFIG_ACPI | ||||
| has a warning: | ||||
|  | ||||
|   drivers/nvmem/bcm-ocotp.c:247:36: error: | ||||
|     ‘bcm_otpc_acpi_ids’ defined but not used [-Werror=unused-const-variable=] | ||||
|  | ||||
| Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Link: https://lore.kernel.org/r/20220321110326.44652-1-krzk@kernel.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/bcm-ocotp.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/bcm-ocotp.c | ||||
| +++ b/drivers/nvmem/bcm-ocotp.c | ||||
| @@ -244,7 +244,7 @@ static const struct of_device_id bcm_otp | ||||
|  }; | ||||
|  MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids); | ||||
|   | ||||
| -static const struct acpi_device_id bcm_otpc_acpi_ids[] = { | ||||
| +static const struct acpi_device_id bcm_otpc_acpi_ids[] __maybe_unused = { | ||||
|  	{ .id = "BRCM0700", .driver_data = (kernel_ulong_t)&otp_map }, | ||||
|  	{ .id = "BRCM0701", .driver_data = (kernel_ulong_t)&otp_map_v2 }, | ||||
|  	{ /* sentinel */ } | ||||
| @@ -0,0 +1,30 @@ | ||||
| From 1066f8156351fcd997125257cea47cf805ba4f6d Mon Sep 17 00:00:00 2001 | ||||
| From: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Date: Mon, 21 Mar 2022 12:03:25 +0100 | ||||
| Subject: [PATCH] nvmem: sunplus-ocotp: staticize sp_otp_v0 | ||||
|  | ||||
| The "sp_otp_v0" file scope variable is not used outside, so make it | ||||
| static to fix warning: | ||||
|  | ||||
|   drivers/nvmem/sunplus-ocotp.c:74:29: sparse: | ||||
|     sparse: symbol 'sp_otp_v0' was not declared. Should it be static? | ||||
|  | ||||
| Reported-by: kernel test robot <lkp@intel.com> | ||||
| Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Link: https://lore.kernel.org/r/20220321110326.44652-2-krzk@kernel.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/sunplus-ocotp.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/sunplus-ocotp.c | ||||
| +++ b/drivers/nvmem/sunplus-ocotp.c | ||||
| @@ -71,7 +71,7 @@ struct sp_ocotp_data { | ||||
|  	int size; | ||||
|  }; | ||||
|   | ||||
| -const struct sp_ocotp_data  sp_otp_v0 = { | ||||
| +static const struct sp_ocotp_data sp_otp_v0 = { | ||||
|  	.size = QAC628_OTP_SIZE, | ||||
|  }; | ||||
|   | ||||
| @@ -0,0 +1,27 @@ | ||||
| From 874dfbcf219ccc42a2cbd187d087c7db82c3024b Mon Sep 17 00:00:00 2001 | ||||
| From: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Date: Mon, 21 Mar 2022 12:03:26 +0100 | ||||
| Subject: [PATCH] nvmem: sunplus-ocotp: drop useless probe confirmation | ||||
|  | ||||
| Printing probe success is discouraged, because we can use tracing for | ||||
| this purpose.  Remove useless print message after Sunplus OCOTP driver | ||||
| probe. | ||||
|  | ||||
| Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> | ||||
| Link: https://lore.kernel.org/r/20220321110326.44652-3-krzk@kernel.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/sunplus-ocotp.c | 2 -- | ||||
|  1 file changed, 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/sunplus-ocotp.c | ||||
| +++ b/drivers/nvmem/sunplus-ocotp.c | ||||
| @@ -202,8 +202,6 @@ static int sp_ocotp_probe(struct platfor | ||||
|  		(int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK, | ||||
|  		(int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE); | ||||
|   | ||||
| -	dev_info(dev, "by Sunplus (C) 2020"); | ||||
| - | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| 
 | ||||
| --- a/drivers/nvmem/core.c
 | ||||
| +++ b/drivers/nvmem/core.c
 | ||||
| @@ -462,6 +462,7 @@ static int nvmem_cell_info_to_nvmem_cell
 | ||||
| @@ -467,6 +467,7 @@ static int nvmem_cell_info_to_nvmem_cell
 | ||||
|   | ||||
|  	cell->bit_offset = info->bit_offset; | ||||
|  	cell->nbits = info->nbits; | ||||
| @@ -0,0 +1,130 @@ | ||||
| From b6b7ef932ae838209254f016ecf8862d716a5ced Mon Sep 17 00:00:00 2001 | ||||
| From: Sven Peter <sven@svenpeter.dev> | ||||
| Date: Fri, 29 Apr 2022 17:26:50 +0100 | ||||
| Subject: [PATCH] nvmem: Add Apple eFuse driver | ||||
|  | ||||
| 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> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-6-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig        | 12 ++++++ | ||||
|  drivers/nvmem/Makefile       |  2 + | ||||
|  drivers/nvmem/apple-efuses.c | 80 ++++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 94 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/apple-efuses.c | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -324,4 +324,16 @@ config NVMEM_SUNPLUS_OCOTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-sunplus-ocotp. | ||||
|   | ||||
| +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 | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -65,3 +65,5 @@ obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nv | ||||
|  nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
|  obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o | ||||
|  nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
| +nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/apple-efuses.c | ||||
| @@ -0,0 +1,80 @@ | ||||
| +// 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, | ||||
| +		.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, | ||||
| +	}, | ||||
| +	.probe = apple_efuses_probe, | ||||
| +}; | ||||
| + | ||||
| +module_platform_driver(apple_efuses_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,31 @@ | ||||
| From 517f6e2641a2802dce5a5aa0d18c7d37a35678d2 Mon Sep 17 00:00:00 2001 | ||||
| From: Minghao Chi <chi.minghao@zte.com.cn> | ||||
| Date: Fri, 29 Apr 2022 17:26:54 +0100 | ||||
| Subject: [PATCH] nvmem: qfprom: using pm_runtime_resume_and_get instead of | ||||
|  pm_runtime_get_sync | ||||
|  | ||||
| Using pm_runtime_resume_and_get is more appropriate | ||||
| for simplifing code | ||||
|  | ||||
| Reported-by: Zeal Robot <zealci@zte.com.cn> | ||||
| Signed-off-by: Minghao Chi <chi.minghao@zte.com.cn> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-10-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/qfprom.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/qfprom.c | ||||
| +++ b/drivers/nvmem/qfprom.c | ||||
| @@ -217,9 +217,8 @@ static int qfprom_enable_fuse_blowing(co | ||||
|  		goto err_clk_rate_set; | ||||
|  	} | ||||
|   | ||||
| -	ret = pm_runtime_get_sync(priv->dev); | ||||
| +	ret = pm_runtime_resume_and_get(priv->dev); | ||||
|  	if (ret < 0) { | ||||
| -		pm_runtime_put_noidle(priv->dev); | ||||
|  		dev_err(priv->dev, "Failed to enable power-domain\n"); | ||||
|  		goto err_reg_enable; | ||||
|  	} | ||||
| @@ -0,0 +1,109 @@ | ||||
| From 943eadbdb11314b41eacbcc484dfb7f93e271ff4 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Anderson <sean.anderson@seco.com> | ||||
| Date: Fri, 29 Apr 2022 17:27:00 +0100 | ||||
| Subject: [PATCH] nvmem: sfp: Use regmap | ||||
|  | ||||
| This converts the SFP driver to use regmap. This will allow easily | ||||
| supporting devices with different endians. We disallow byte-level | ||||
| access, as regmap_bulk_read doesn't support it (and it's unclear what | ||||
| the correct result would be when we have an endianness difference). | ||||
|  | ||||
| Signed-off-by: Sean Anderson <sean.anderson@seco.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-16-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig          |  1 + | ||||
|  drivers/nvmem/layerscape-sfp.c | 30 ++++++++++++++++++++++-------- | ||||
|  2 files changed, 23 insertions(+), 8 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -304,6 +304,7 @@ config NVMEM_LAYERSCAPE_SFP | ||||
|  	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
|  	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| +	select REGMAP_MMIO | ||||
|  	help | ||||
|  	  This driver provides support to read the eFuses on Freescale | ||||
|  	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| --- a/drivers/nvmem/layerscape-sfp.c | ||||
| +++ b/drivers/nvmem/layerscape-sfp.c | ||||
| @@ -13,15 +13,17 @@ | ||||
|  #include <linux/nvmem-provider.h> | ||||
|  #include <linux/platform_device.h> | ||||
|  #include <linux/property.h> | ||||
| +#include <linux/regmap.h> | ||||
|   | ||||
|  #define LAYERSCAPE_SFP_OTP_OFFSET	0x0200 | ||||
|   | ||||
|  struct layerscape_sfp_priv { | ||||
| -	void __iomem *base; | ||||
| +	struct regmap *regmap; | ||||
|  }; | ||||
|   | ||||
|  struct layerscape_sfp_data { | ||||
|  	int size; | ||||
| +	enum regmap_endian endian; | ||||
|  }; | ||||
|   | ||||
|  static int layerscape_sfp_read(void *context, unsigned int offset, void *val, | ||||
| @@ -29,15 +31,16 @@ static int layerscape_sfp_read(void *con | ||||
|  { | ||||
|  	struct layerscape_sfp_priv *priv = context; | ||||
|   | ||||
| -	memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, | ||||
| -		      bytes); | ||||
| - | ||||
| -	return 0; | ||||
| +	return regmap_bulk_read(priv->regmap, | ||||
| +				LAYERSCAPE_SFP_OTP_OFFSET + offset, val, | ||||
| +				bytes / 4); | ||||
|  } | ||||
|   | ||||
|  static struct nvmem_config layerscape_sfp_nvmem_config = { | ||||
|  	.name = "fsl-sfp", | ||||
|  	.reg_read = layerscape_sfp_read, | ||||
| +	.word_size = 4, | ||||
| +	.stride = 4, | ||||
|  }; | ||||
|   | ||||
|  static int layerscape_sfp_probe(struct platform_device *pdev) | ||||
| @@ -45,16 +48,26 @@ static int layerscape_sfp_probe(struct p | ||||
|  	const struct layerscape_sfp_data *data; | ||||
|  	struct layerscape_sfp_priv *priv; | ||||
|  	struct nvmem_device *nvmem; | ||||
| +	struct regmap_config config = { 0 }; | ||||
| +	void __iomem *base; | ||||
|   | ||||
|  	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||||
|  	if (!priv) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| -	priv->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| -	if (IS_ERR(priv->base)) | ||||
| -		return PTR_ERR(priv->base); | ||||
| +	base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(base)) | ||||
| +		return PTR_ERR(base); | ||||
|   | ||||
|  	data = device_get_match_data(&pdev->dev); | ||||
| +	config.reg_bits = 32; | ||||
| +	config.reg_stride = 4; | ||||
| +	config.val_bits = 32; | ||||
| +	config.val_format_endian = data->endian; | ||||
| +	config.max_register = LAYERSCAPE_SFP_OTP_OFFSET + data->size - 4; | ||||
| +	priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, &config); | ||||
| +	if (IS_ERR(priv->regmap)) | ||||
| +		return PTR_ERR(priv->regmap); | ||||
|   | ||||
|  	layerscape_sfp_nvmem_config.size = data->size; | ||||
|  	layerscape_sfp_nvmem_config.dev = &pdev->dev; | ||||
| @@ -67,6 +80,7 @@ static int layerscape_sfp_probe(struct p | ||||
|   | ||||
|  static const struct layerscape_sfp_data ls1028a_data = { | ||||
|  	.size = 0x88, | ||||
| +	.endian = REGMAP_ENDIAN_LITTLE, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id layerscape_sfp_dt_ids[] = { | ||||
| @@ -0,0 +1,38 @@ | ||||
| From 33a1c6618677fe33f8e84cb7bedc45abbce89a50 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Anderson <sean.anderson@seco.com> | ||||
| Date: Fri, 29 Apr 2022 17:27:01 +0100 | ||||
| Subject: [PATCH] nvmem: sfp: Add support for TA 2.1 devices | ||||
|  | ||||
| This adds support for Trust Architecture (TA) 2.1 devices to the SFP driver. | ||||
| There are few differences between TA 2.1 and TA 3.0, especially for | ||||
| read-only support, so just re-use the existing data. | ||||
|  | ||||
| Signed-off-by: Sean Anderson <sean.anderson@seco.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220429162701.2222-17-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/layerscape-sfp.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/layerscape-sfp.c | ||||
| +++ b/drivers/nvmem/layerscape-sfp.c | ||||
| @@ -78,12 +78,18 @@ static int layerscape_sfp_probe(struct p | ||||
|  	return PTR_ERR_OR_ZERO(nvmem); | ||||
|  } | ||||
|   | ||||
| +static const struct layerscape_sfp_data ls1021a_data = { | ||||
| +	.size = 0x88, | ||||
| +	.endian = REGMAP_ENDIAN_BIG, | ||||
| +}; | ||||
| + | ||||
|  static const struct layerscape_sfp_data ls1028a_data = { | ||||
|  	.size = 0x88, | ||||
|  	.endian = REGMAP_ENDIAN_LITTLE, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id layerscape_sfp_dt_ids[] = { | ||||
| +	{ .compatible = "fsl,ls1021a-sfp", .data = &ls1021a_data }, | ||||
|  	{ .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, | ||||
|  	{}, | ||||
|  }; | ||||
| @@ -0,0 +1,389 @@ | ||||
| From 98830350d3fc824c1ff5c338140fe20f041a5916 Mon Sep 17 00:00:00 2001 | ||||
| From: Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| Date: Wed, 6 Jul 2022 11:06:22 +0100 | ||||
| Subject: [PATCH] nvmem: microchip-otpc: add support | ||||
|  | ||||
| Add support for Microchip OTP controller available on SAMA7G5. The OTPC | ||||
| controls the access to a non-volatile memory. The memory behind OTPC is | ||||
| organized into packets, packets are composed by a fixed length header | ||||
| (4 bytes long) and a variable length payload (payload length is available | ||||
| in the header). When software request the data at an offset in memory | ||||
| the OTPC will return (via header + data registers) the whole packet that | ||||
| has a word at that offset. For the OTP memory layout like below: | ||||
|  | ||||
| offset  OTP Memory layout | ||||
|  | ||||
|          .           . | ||||
|          .    ...    . | ||||
|          .           . | ||||
| 0x0E     +-----------+	<--- packet X | ||||
|          | header  X | | ||||
| 0x12     +-----------+ | ||||
|          | payload X | | ||||
| 0x16     |           | | ||||
|          |           | | ||||
| 0x1A     |           | | ||||
|          +-----------+ | ||||
|          .           . | ||||
|          .    ...    . | ||||
|          .           . | ||||
|  | ||||
| if user requests data at address 0x16 the data started at 0x0E will be | ||||
| returned by controller. User will be able to fetch the whole packet | ||||
| starting at 0x0E (or parts of the packet) via proper registers. The same | ||||
| packet will be returned if software request the data at offset 0x0E or | ||||
| 0x12 or 0x1A. | ||||
|  | ||||
| The OTP will be populated by Microchip with at least 2 packets first one | ||||
| being boot configuration packet and the 2nd one being temperature | ||||
| calibration packet. The packet order will be preserved b/w different chip | ||||
| revisions but the packet sizes may change. | ||||
|  | ||||
| For the above reasons and to keep the same software able to work on all | ||||
| chip variants the read function of the driver is working with a packet | ||||
| id instead of an offset in OTP memory. | ||||
|  | ||||
| Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220706100627.6534-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  MAINTAINERS                    |   8 + | ||||
|  drivers/nvmem/Kconfig          |   7 + | ||||
|  drivers/nvmem/Makefile         |   2 + | ||||
|  drivers/nvmem/microchip-otpc.c | 288 +++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 305 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/microchip-otpc.c | ||||
|  | ||||
| --- a/MAINTAINERS | ||||
| +++ b/MAINTAINERS | ||||
| @@ -12353,6 +12353,14 @@ S:	Supported | ||||
|  F:	Documentation/devicetree/bindings/mtd/atmel-nand.txt | ||||
|  F:	drivers/mtd/nand/raw/atmel/* | ||||
|   | ||||
| +MICROCHIP OTPC DRIVER | ||||
| +M:	Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| +L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| +S:	Supported | ||||
| +F:	Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml | ||||
| +F:	drivers/nvmem/microchip-otpc.c | ||||
| +F:	dt-bindings/nvmem/microchip,sama7g5-otpc.h | ||||
| + | ||||
|  MICROCHIP PWM DRIVER | ||||
|  M:	Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
|  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -107,6 +107,13 @@ config MTK_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called efuse-mtk. | ||||
|   | ||||
| +config MICROCHIP_OTPC | ||||
| +	tristate "Microchip OTPC support" | ||||
| +	depends on ARCH_AT91 || COMPILE_TEST | ||||
| +	help | ||||
| +	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| +	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
| + | ||||
|  config NVMEM_NINTENDO_OTP | ||||
|  	tristate "Nintendo Wii and Wii U OTP Support" | ||||
|  	depends on WII || COMPILE_TEST | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -67,3 +67,5 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvm | ||||
|  nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
|  nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| +obj-$(CONFIG_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| +nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/microchip-otpc.c | ||||
| @@ -0,0 +1,288 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| +/* | ||||
| + * OTP Memory controller | ||||
| + * | ||||
| + * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries | ||||
| + * | ||||
| + * Author: Claudiu Beznea <claudiu.beznea@microchip.com> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/bitfield.h> | ||||
| +#include <linux/iopoll.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#define MCHP_OTPC_CR			(0x0) | ||||
| +#define MCHP_OTPC_CR_READ		BIT(6) | ||||
| +#define MCHP_OTPC_MR			(0x4) | ||||
| +#define MCHP_OTPC_MR_ADDR		GENMASK(31, 16) | ||||
| +#define MCHP_OTPC_AR			(0x8) | ||||
| +#define MCHP_OTPC_SR			(0xc) | ||||
| +#define MCHP_OTPC_SR_READ		BIT(6) | ||||
| +#define MCHP_OTPC_HR			(0x20) | ||||
| +#define MCHP_OTPC_HR_SIZE		GENMASK(15, 8) | ||||
| +#define MCHP_OTPC_DR			(0x24) | ||||
| + | ||||
| +#define MCHP_OTPC_NAME			"mchp-otpc" | ||||
| +#define MCHP_OTPC_SIZE			(11 * 1024) | ||||
| + | ||||
| +/** | ||||
| + * struct mchp_otpc - OTPC private data structure | ||||
| + * @base: base address | ||||
| + * @dev: struct device pointer | ||||
| + * @packets: list of packets in OTP memory | ||||
| + * @npackets: number of packets in OTP memory | ||||
| + */ | ||||
| +struct mchp_otpc { | ||||
| +	void __iomem *base; | ||||
| +	struct device *dev; | ||||
| +	struct list_head packets; | ||||
| +	u32 npackets; | ||||
| +}; | ||||
| + | ||||
| +/** | ||||
| + * struct mchp_otpc_packet - OTPC packet data structure | ||||
| + * @list: list head | ||||
| + * @id: packet ID | ||||
| + * @offset: packet offset (in words) in OTP memory | ||||
| + */ | ||||
| +struct mchp_otpc_packet { | ||||
| +	struct list_head list; | ||||
| +	u32 id; | ||||
| +	u32 offset; | ||||
| +}; | ||||
| + | ||||
| +static struct mchp_otpc_packet *mchp_otpc_id_to_packet(struct mchp_otpc *otpc, | ||||
| +						       u32 id) | ||||
| +{ | ||||
| +	struct mchp_otpc_packet *packet; | ||||
| + | ||||
| +	if (id >= otpc->npackets) | ||||
| +		return NULL; | ||||
| + | ||||
| +	list_for_each_entry(packet, &otpc->packets, list) { | ||||
| +		if (packet->id == id) | ||||
| +			return packet; | ||||
| +	} | ||||
| + | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| +static int mchp_otpc_prepare_read(struct mchp_otpc *otpc, | ||||
| +				  unsigned int offset) | ||||
| +{ | ||||
| +	u32 tmp; | ||||
| + | ||||
| +	/* Set address. */ | ||||
| +	tmp = readl_relaxed(otpc->base + MCHP_OTPC_MR); | ||||
| +	tmp &= ~MCHP_OTPC_MR_ADDR; | ||||
| +	tmp |= FIELD_PREP(MCHP_OTPC_MR_ADDR, offset); | ||||
| +	writel_relaxed(tmp, otpc->base + MCHP_OTPC_MR); | ||||
| + | ||||
| +	/* Set read. */ | ||||
| +	tmp = readl_relaxed(otpc->base + MCHP_OTPC_CR); | ||||
| +	tmp |= MCHP_OTPC_CR_READ; | ||||
| +	writel_relaxed(tmp, otpc->base + MCHP_OTPC_CR); | ||||
| + | ||||
| +	/* Wait for packet to be transferred into temporary buffers. */ | ||||
| +	return read_poll_timeout(readl_relaxed, tmp, !(tmp & MCHP_OTPC_SR_READ), | ||||
| +				 10000, 2000, false, otpc->base + MCHP_OTPC_SR); | ||||
| +} | ||||
| + | ||||
| +/* | ||||
| + * OTPC memory is organized into packets. Each packets contains a header and | ||||
| + * a payload. Header is 4 bytes long and contains the size of the payload. | ||||
| + * Payload size varies. The memory footprint is something as follows: | ||||
| + * | ||||
| + * Memory offset  Memory footprint     Packet ID | ||||
| + * -------------  ----------------     --------- | ||||
| + * | ||||
| + * 0x0            +------------+   <-- packet 0 | ||||
| + *                | header  0  | | ||||
| + * 0x4            +------------+ | ||||
| + *                | payload 0  | | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + * offset1        +------------+   <-- packet 1 | ||||
| + *                | header  1  | | ||||
| + * offset1 + 0x4  +------------+ | ||||
| + *                | payload 1  | | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + * offset2        +------------+   <-- packet 2 | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + * offsetN        +------------+   <-- packet N | ||||
| + *                | header  N  | | ||||
| + * offsetN + 0x4  +------------+ | ||||
| + *                | payload N  | | ||||
| + *                .            . | ||||
| + *                .    ...     . | ||||
| + *                .            . | ||||
| + *                +------------+ | ||||
| + * | ||||
| + * where offset1, offset2, offsetN depends on the size of payload 0, payload 1, | ||||
| + * payload N-1. | ||||
| + * | ||||
| + * The access to memory is done on a per packet basis: the control registers | ||||
| + * need to be updated with an offset address (within a packet range) and the | ||||
| + * data registers will be update by controller with information contained by | ||||
| + * that packet. E.g. if control registers are updated with any address within | ||||
| + * the range [offset1, offset2) the data registers are updated by controller | ||||
| + * with packet 1. Header data is accessible though MCHP_OTPC_HR register. | ||||
| + * Payload data is accessible though MCHP_OTPC_DR and MCHP_OTPC_AR registers. | ||||
| + * There is no direct mapping b/w the offset requested by software and the | ||||
| + * offset returned by hardware. | ||||
| + * | ||||
| + * For this, the read function will return the first requested bytes in the | ||||
| + * packet. The user will have to be aware of the memory footprint before doing | ||||
| + * the read request. | ||||
| + */ | ||||
| +static int mchp_otpc_read(void *priv, unsigned int off, void *val, | ||||
| +			  size_t bytes) | ||||
| +{ | ||||
| +	struct mchp_otpc *otpc = priv; | ||||
| +	struct mchp_otpc_packet *packet; | ||||
| +	u32 *buf = val; | ||||
| +	u32 offset; | ||||
| +	size_t len = 0; | ||||
| +	int ret, payload_size; | ||||
| + | ||||
| +	/* | ||||
| +	 * We reach this point with off being multiple of stride = 4 to | ||||
| +	 * be able to cross the subsystem. Inside the driver we use continuous | ||||
| +	 * unsigned integer numbers for packet id, thus devide off by 4 | ||||
| +	 * before passing it to mchp_otpc_id_to_packet(). | ||||
| +	 */ | ||||
| +	packet = mchp_otpc_id_to_packet(otpc, off / 4); | ||||
| +	if (!packet) | ||||
| +		return -EINVAL; | ||||
| +	offset = packet->offset; | ||||
| + | ||||
| +	while (len < bytes) { | ||||
| +		ret = mchp_otpc_prepare_read(otpc, offset); | ||||
| +		if (ret) | ||||
| +			return ret; | ||||
| + | ||||
| +		/* Read and save header content. */ | ||||
| +		*buf++ = readl_relaxed(otpc->base + MCHP_OTPC_HR); | ||||
| +		len += sizeof(*buf); | ||||
| +		offset++; | ||||
| +		if (len >= bytes) | ||||
| +			break; | ||||
| + | ||||
| +		/* Read and save payload content. */ | ||||
| +		payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, *(buf - 1)); | ||||
| +		writel_relaxed(0UL, otpc->base + MCHP_OTPC_AR); | ||||
| +		do { | ||||
| +			*buf++ = readl_relaxed(otpc->base + MCHP_OTPC_DR); | ||||
| +			len += sizeof(*buf); | ||||
| +			offset++; | ||||
| +			payload_size--; | ||||
| +		} while (payload_size >= 0 && len < bytes); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size) | ||||
| +{ | ||||
| +	struct mchp_otpc_packet *packet; | ||||
| +	u32 word, word_pos = 0, id = 0, npackets = 0, payload_size; | ||||
| +	int ret; | ||||
| + | ||||
| +	INIT_LIST_HEAD(&otpc->packets); | ||||
| +	*size = 0; | ||||
| + | ||||
| +	while (*size < MCHP_OTPC_SIZE) { | ||||
| +		ret = mchp_otpc_prepare_read(otpc, word_pos); | ||||
| +		if (ret) | ||||
| +			return ret; | ||||
| + | ||||
| +		word = readl_relaxed(otpc->base + MCHP_OTPC_HR); | ||||
| +		payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, word); | ||||
| +		if (!payload_size) | ||||
| +			break; | ||||
| + | ||||
| +		packet = devm_kzalloc(otpc->dev, sizeof(*packet), GFP_KERNEL); | ||||
| +		if (!packet) | ||||
| +			return -ENOMEM; | ||||
| + | ||||
| +		packet->id = id++; | ||||
| +		packet->offset = word_pos; | ||||
| +		INIT_LIST_HEAD(&packet->list); | ||||
| +		list_add_tail(&packet->list, &otpc->packets); | ||||
| + | ||||
| +		/* Count size by adding header and paload sizes. */ | ||||
| +		*size += 4 * (payload_size + 1); | ||||
| +		/* Next word: this packet (header, payload) position + 1. */ | ||||
| +		word_pos += payload_size + 2; | ||||
| + | ||||
| +		npackets++; | ||||
| +	} | ||||
| + | ||||
| +	otpc->npackets = npackets; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config mchp_nvmem_config = { | ||||
| +	.name = MCHP_OTPC_NAME, | ||||
| +	.type = NVMEM_TYPE_OTP, | ||||
| +	.read_only = true, | ||||
| +	.word_size = 4, | ||||
| +	.stride = 4, | ||||
| +	.reg_read = mchp_otpc_read, | ||||
| +}; | ||||
| + | ||||
| +static int mchp_otpc_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	struct mchp_otpc *otpc; | ||||
| +	u32 size; | ||||
| +	int ret; | ||||
| + | ||||
| +	otpc = devm_kzalloc(&pdev->dev, sizeof(*otpc), GFP_KERNEL); | ||||
| +	if (!otpc) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	otpc->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(otpc->base)) | ||||
| +		return PTR_ERR(otpc->base); | ||||
| + | ||||
| +	otpc->dev = &pdev->dev; | ||||
| +	ret = mchp_otpc_init_packets_list(otpc, &size); | ||||
| +	if (ret) | ||||
| +		return ret; | ||||
| + | ||||
| +	mchp_nvmem_config.dev = otpc->dev; | ||||
| +	mchp_nvmem_config.size = size; | ||||
| +	mchp_nvmem_config.priv = otpc; | ||||
| +	nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(nvmem); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id __maybe_unused mchp_otpc_ids[] = { | ||||
| +	{ .compatible = "microchip,sama7g5-otpc", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, mchp_otpc_ids); | ||||
| + | ||||
| +static struct platform_driver mchp_otpc_driver = { | ||||
| +	.probe = mchp_otpc_probe, | ||||
| +	.driver = { | ||||
| +		.name = MCHP_OTPC_NAME, | ||||
| +		.of_match_table = of_match_ptr(mchp_otpc_ids), | ||||
| +	}, | ||||
| +}; | ||||
| +module_platform_driver(mchp_otpc_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea@microchip.com>"); | ||||
| +MODULE_DESCRIPTION("Microchip SAMA7G5 OTPC driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,32 @@ | ||||
| From f5c97da8037b18d1256a58459fa96ed68e50fb41 Mon Sep 17 00:00:00 2001 | ||||
| From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> | ||||
| Date: Wed, 6 Jul 2022 11:06:27 +0100 | ||||
| Subject: [PATCH] nvmem: mtk-efuse: Simplify with | ||||
|  devm_platform_get_and_ioremap_resource() | ||||
|  | ||||
| Convert platform_get_resource(), devm_ioremap_resource() to a single | ||||
| call to devm_platform_get_and_ioremap_resource(), as this is exactly | ||||
| what this function does. | ||||
|  | ||||
| No functional changes. | ||||
|  | ||||
| Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220706100627.6534-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/mtk-efuse.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/mtk-efuse.c | ||||
| +++ b/drivers/nvmem/mtk-efuse.c | ||||
| @@ -41,8 +41,7 @@ static int mtk_efuse_probe(struct platfo | ||||
|  	if (!priv) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| -	priv->base = devm_ioremap_resource(dev, res); | ||||
| +	priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); | ||||
|  	if (IS_ERR(priv->base)) | ||||
|  		return PTR_ERR(priv->base); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| From f955dc14450695564926711cf9fa8e1d5d854302 Mon Sep 17 00:00:00 2001 | ||||
| From d5542923f200f95bddf524f36fd495f78aa28e3c Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 15 Jun 2022 21:43:00 +0200 | ||||
| Date: Fri, 16 Sep 2022 13:20:48 +0100 | ||||
| Subject: [PATCH] nvmem: add driver handling U-Boot environment variables | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -22,16 +22,24 @@ Kernel-parsed NVMEM cells can be read however by Linux drivers. This may | ||||
| be useful for Ethernet drivers for reading device MAC address which is | ||||
| often stored as U-Boot env variable. | ||||
| 
 | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de> | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  MAINTAINERS                |   1 + | ||||
|  drivers/nvmem/Kconfig      |  13 +++ | ||||
|  drivers/nvmem/Makefile     |   2 + | ||||
|  drivers/nvmem/u-boot-env.c | 218 +++++++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 234 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/u-boot-env.c | ||||
| 
 | ||||
| --- a/drivers/nvmem/Kconfig
 | ||||
| +++ b/drivers/nvmem/Kconfig
 | ||||
| @@ -300,4 +300,17 @@ config NVMEM_BRCM_NVRAM
 | ||||
|  	  This driver provides support for Broadcom's NVRAM that can be accessed | ||||
|  	  using I/O mapping. | ||||
| @@ -344,4 +344,17 @@ config NVMEM_APPLE_EFUSES
 | ||||
|  	  This driver can also be built as a module. If so, the module will | ||||
|  	  be called nvmem-apple-efuses. | ||||
|   | ||||
| +config NVMEM_U_BOOT_ENV
 | ||||
| +	tristate "U-Boot environment variables support"
 | ||||
| @@ -49,10 +57,10 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile
 | ||||
| +++ b/drivers/nvmem/Makefile
 | ||||
| @@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.
 | ||||
|  nvmem-rmem-y			:= rmem.o | ||||
|  obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o | ||||
|  nvmem_brcm_nvram-y		:= brcm_nvram.o | ||||
| @@ -69,3 +69,5 @@ obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvme
 | ||||
|  nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
|  obj-$(CONFIG_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
|  nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
| +obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o
 | ||||
| +nvmem_u-boot-env-y		:= u-boot-env.o
 | ||||
| --- /dev/null
 | ||||
| @@ -0,0 +1,47 @@ | ||||
| From 5544e90c81261e82e02bbf7c6015a4b9c8c825ef Mon Sep 17 00:00:00 2001 | ||||
| From: Gaosheng Cui <cuigaosheng1@huawei.com> | ||||
| Date: Fri, 16 Sep 2022 13:20:50 +0100 | ||||
| Subject: [PATCH] nvmem: core: add error handling for dev_set_name | ||||
|  | ||||
| The type of return value of dev_set_name is int, which may return | ||||
| wrong result, so we add error handling for it to reclaim memory | ||||
| of nvmem resource, and return early when an error occurs. | ||||
|  | ||||
| Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/core.c | 12 +++++++++--- | ||||
|  1 file changed, 9 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/core.c | ||||
| +++ b/drivers/nvmem/core.c | ||||
| @@ -810,18 +810,24 @@ struct nvmem_device *nvmem_register(cons | ||||
|   | ||||
|  	switch (config->id) { | ||||
|  	case NVMEM_DEVID_NONE: | ||||
| -		dev_set_name(&nvmem->dev, "%s", config->name); | ||||
| +		rval = dev_set_name(&nvmem->dev, "%s", config->name); | ||||
|  		break; | ||||
|  	case NVMEM_DEVID_AUTO: | ||||
| -		dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id); | ||||
| +		rval = dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id); | ||||
|  		break; | ||||
|  	default: | ||||
| -		dev_set_name(&nvmem->dev, "%s%d", | ||||
| +		rval = dev_set_name(&nvmem->dev, "%s%d", | ||||
|  			     config->name ? : "nvmem", | ||||
|  			     config->name ? config->id : nvmem->id); | ||||
|  		break; | ||||
|  	} | ||||
|   | ||||
| +	if (rval) { | ||||
| +		ida_free(&nvmem_ida, nvmem->id); | ||||
| +		kfree(nvmem); | ||||
| +		return ERR_PTR(rval); | ||||
| +	} | ||||
| + | ||||
|  	nvmem->read_only = device_property_present(config->dev, "read-only") || | ||||
|  			   config->read_only || !nvmem->reg_write; | ||||
|   | ||||
| @@ -0,0 +1,29 @@ | ||||
| From d3524bb5b9a0c567b853a0024526afe87dde01ed Mon Sep 17 00:00:00 2001 | ||||
| From: Kenneth Lee <klee33@uw.edu> | ||||
| Date: Fri, 16 Sep 2022 13:20:52 +0100 | ||||
| Subject: [PATCH] nvmem: brcm_nvram: Use kzalloc for allocating only one | ||||
|  element | ||||
|  | ||||
| Use kzalloc(...) rather than kcalloc(1, ...) because the number of | ||||
| elements we are specifying in this case is 1, so kzalloc would | ||||
| accomplish the same thing and we can simplify. | ||||
|  | ||||
| Signed-off-by: Kenneth Lee <klee33@uw.edu> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-6-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/brcm_nvram.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/brcm_nvram.c | ||||
| +++ b/drivers/nvmem/brcm_nvram.c | ||||
| @@ -96,7 +96,7 @@ static int brcm_nvram_parse(struct brcm_ | ||||
|   | ||||
|  	len = le32_to_cpu(header.len); | ||||
|   | ||||
| -	data = kcalloc(1, len, GFP_KERNEL); | ||||
| +	data = kzalloc(len, GFP_KERNEL); | ||||
|  	memcpy_fromio(data, priv->base, len); | ||||
|  	data[len - 1] = '\0'; | ||||
|   | ||||
| @@ -0,0 +1,281 @@ | ||||
| From 28fc7c986f01fdcfd28af648be2597624cac0e27 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 16 Sep 2022 13:20:54 +0100 | ||||
| Subject: [PATCH] nvmem: prefix all symbols with NVMEM_ | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This unifies all NVMEM symbols. They follow one style now. | ||||
|  | ||||
| Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com> | ||||
| Acked-by: Arnd Bergmann <arnd@arndb.de> | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  arch/arm/configs/multi_v7_defconfig |  6 +++--- | ||||
|  arch/arm/configs/qcom_defconfig     |  2 +- | ||||
|  arch/arm64/configs/defconfig        | 10 +++++----- | ||||
|  arch/mips/configs/ci20_defconfig    |  2 +- | ||||
|  drivers/cpufreq/Kconfig.arm         |  2 +- | ||||
|  drivers/nvmem/Kconfig               | 24 ++++++++++++------------ | ||||
|  drivers/nvmem/Makefile              | 24 ++++++++++++------------ | ||||
|  drivers/soc/mediatek/Kconfig        |  2 +- | ||||
|  drivers/thermal/qcom/Kconfig        |  2 +- | ||||
|  9 files changed, 37 insertions(+), 37 deletions(-) | ||||
|  | ||||
| --- a/arch/arm/configs/multi_v7_defconfig | ||||
| +++ b/arch/arm/configs/multi_v7_defconfig | ||||
| @@ -1125,10 +1125,10 @@ CONFIG_TI_PIPE3=y | ||||
|  CONFIG_TWL4030_USB=m | ||||
|  CONFIG_RAS=y | ||||
|  CONFIG_NVMEM_IMX_OCOTP=y | ||||
| -CONFIG_ROCKCHIP_EFUSE=m | ||||
| +CONFIG_NVMEM_ROCKCHIP_EFUSE=m | ||||
|  CONFIG_NVMEM_SUNXI_SID=y | ||||
|  CONFIG_NVMEM_VF610_OCOTP=y | ||||
| -CONFIG_MESON_MX_EFUSE=m | ||||
| +CONFIG_NVMEM_MESON_MX_EFUSE=m | ||||
|  CONFIG_NVMEM_RMEM=m | ||||
|  CONFIG_FSI=m | ||||
|  CONFIG_FSI_MASTER_GPIO=m | ||||
| --- a/arch/arm/configs/qcom_defconfig | ||||
| +++ b/arch/arm/configs/qcom_defconfig | ||||
| @@ -274,7 +274,7 @@ CONFIG_PHY_QCOM_USB_HS=y | ||||
|  CONFIG_PHY_QCOM_USB_HSIC=y | ||||
|  CONFIG_PHY_QCOM_QMP=y | ||||
|  CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y | ||||
| -CONFIG_QCOM_QFPROM=y | ||||
| +CONFIG_NVMEM_QCOM_QFPROM=y | ||||
|  CONFIG_INTERCONNECT=y | ||||
|  CONFIG_INTERCONNECT_QCOM=y | ||||
|  CONFIG_INTERCONNECT_QCOM_MSM8974=m | ||||
| --- a/arch/arm64/configs/defconfig | ||||
| +++ b/arch/arm64/configs/defconfig | ||||
| @@ -1135,11 +1135,11 @@ CONFIG_QCOM_L3_PMU=y | ||||
|  CONFIG_NVMEM_IMX_OCOTP=y | ||||
|  CONFIG_NVMEM_IMX_OCOTP_SCU=y | ||||
|  CONFIG_QCOM_QFPROM=y | ||||
| -CONFIG_MTK_EFUSE=y | ||||
| -CONFIG_ROCKCHIP_EFUSE=y | ||||
| +CONFIG_NVMEM_MTK_EFUSE=y | ||||
| +CONFIG_NVMEM_ROCKCHIP_EFUSE=y | ||||
|  CONFIG_NVMEM_SUNXI_SID=y | ||||
| -CONFIG_UNIPHIER_EFUSE=y | ||||
| -CONFIG_MESON_EFUSE=m | ||||
| +CONFIG_NVMEM_UNIPHIER_EFUSE=y | ||||
| +CONFIG_NVMEM_MESON_EFUSE=m | ||||
|  CONFIG_NVMEM_RMEM=m | ||||
|  CONFIG_FPGA=y | ||||
|  CONFIG_FPGA_MGR_STRATIX10_SOC=m | ||||
| --- a/arch/mips/configs/ci20_defconfig | ||||
| +++ b/arch/mips/configs/ci20_defconfig | ||||
| @@ -137,7 +137,7 @@ CONFIG_MEMORY=y | ||||
|  CONFIG_JZ4780_NEMC=y | ||||
|  CONFIG_PWM=y | ||||
|  CONFIG_PWM_JZ4740=m | ||||
| -CONFIG_JZ4780_EFUSE=y | ||||
| +CONFIG_NVMEM_JZ4780_EFUSE=y | ||||
|  CONFIG_JZ4770_PHY=y | ||||
|  CONFIG_EXT4_FS=y | ||||
|  # CONFIG_DNOTIFY is not set | ||||
| --- a/drivers/cpufreq/Kconfig.arm | ||||
| +++ b/drivers/cpufreq/Kconfig.arm | ||||
| @@ -153,7 +153,7 @@ config ARM_OMAP2PLUS_CPUFREQ | ||||
|  config ARM_QCOM_CPUFREQ_NVMEM | ||||
|  	tristate "Qualcomm nvmem based CPUFreq" | ||||
|  	depends on ARCH_QCOM | ||||
| -	depends on QCOM_QFPROM | ||||
| +	depends on NVMEM_QCOM_QFPROM | ||||
|  	depends on QCOM_SMEM | ||||
|  	select PM_OPP | ||||
|  	help | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -52,7 +52,7 @@ config NVMEM_IMX_OCOTP_SCU | ||||
|  	  This is a driver for the SCU On-Chip OTP Controller (OCOTP) | ||||
|  	  available on i.MX8 SoCs. | ||||
|   | ||||
| -config JZ4780_EFUSE | ||||
| +config NVMEM_JZ4780_EFUSE | ||||
|  	tristate "JZ4780 EFUSE Memory Support" | ||||
|  	depends on MACH_INGENIC || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -96,7 +96,7 @@ config NVMEM_MXS_OCOTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-mxs-ocotp. | ||||
|   | ||||
| -config MTK_EFUSE | ||||
| +config NVMEM_MTK_EFUSE | ||||
|  	tristate "Mediatek SoCs EFUSE support" | ||||
|  	depends on ARCH_MEDIATEK || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -107,7 +107,7 @@ config MTK_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called efuse-mtk. | ||||
|   | ||||
| -config MICROCHIP_OTPC | ||||
| +config NVMEM_MICROCHIP_OTPC | ||||
|  	tristate "Microchip OTPC support" | ||||
|  	depends on ARCH_AT91 || COMPILE_TEST | ||||
|  	help | ||||
| @@ -126,7 +126,7 @@ config NVMEM_NINTENDO_OTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-nintendo-otp. | ||||
|   | ||||
| -config QCOM_QFPROM | ||||
| +config NVMEM_QCOM_QFPROM | ||||
|  	tristate "QCOM QFPROM Support" | ||||
|  	depends on ARCH_QCOM || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -145,7 +145,7 @@ config NVMEM_SPMI_SDAM | ||||
|  	  Qualcomm Technologies, Inc. PMICs. It provides the clients | ||||
|  	  an interface to read/write to the SDAM module's shared memory. | ||||
|   | ||||
| -config ROCKCHIP_EFUSE | ||||
| +config NVMEM_ROCKCHIP_EFUSE | ||||
|  	tristate "Rockchip eFuse Support" | ||||
|  	depends on ARCH_ROCKCHIP || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -156,7 +156,7 @@ config ROCKCHIP_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_rockchip_efuse. | ||||
|   | ||||
| -config ROCKCHIP_OTP | ||||
| +config NVMEM_ROCKCHIP_OTP | ||||
|  	tristate "Rockchip OTP controller support" | ||||
|  	depends on ARCH_ROCKCHIP || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -199,7 +199,7 @@ config NVMEM_SUNXI_SID | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_sunxi_sid. | ||||
|   | ||||
| -config UNIPHIER_EFUSE | ||||
| +config NVMEM_UNIPHIER_EFUSE | ||||
|  	tristate "UniPhier SoCs eFuse support" | ||||
|  	depends on ARCH_UNIPHIER || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -221,7 +221,7 @@ config NVMEM_VF610_OCOTP | ||||
|  	  This driver can also be build as a module. If so, the module will | ||||
|  	  be called nvmem-vf610-ocotp. | ||||
|   | ||||
| -config MESON_EFUSE | ||||
| +config NVMEM_MESON_EFUSE | ||||
|  	tristate "Amlogic Meson GX eFuse Support" | ||||
|  	depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM | ||||
|  	help | ||||
| @@ -231,7 +231,7 @@ config MESON_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_meson_efuse. | ||||
|   | ||||
| -config MESON_MX_EFUSE | ||||
| +config NVMEM_MESON_MX_EFUSE | ||||
|  	tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" | ||||
|  	depends on ARCH_MESON || COMPILE_TEST | ||||
|  	help | ||||
| @@ -251,13 +251,13 @@ config NVMEM_SNVS_LPGPR | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-snvs-lpgpr. | ||||
|   | ||||
| -config RAVE_SP_EEPROM | ||||
| +config NVMEM_RAVE_SP_EEPROM | ||||
|  	tristate "Rave SP EEPROM Support" | ||||
|  	depends on RAVE_SP_CORE | ||||
|  	help | ||||
|  	  Say y here to enable Rave SP EEPROM support. | ||||
|   | ||||
| -config SC27XX_EFUSE | ||||
| +config NVMEM_SC27XX_EFUSE | ||||
|  	tristate "Spreadtrum SC27XX eFuse Support" | ||||
|  	depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| @@ -278,7 +278,7 @@ config NVMEM_ZYNQMP | ||||
|   | ||||
|  	  If sure, say yes. If unsure, say no. | ||||
|   | ||||
| -config SPRD_EFUSE | ||||
| +config NVMEM_SPRD_EFUSE | ||||
|  	tristate "Spreadtrum SoC eFuse Support" | ||||
|  	depends on ARCH_SPRD || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -15,7 +15,7 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-i | ||||
|  nvmem-imx-ocotp-y		:= imx-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o | ||||
|  nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o | ||||
| -obj-$(CONFIG_JZ4780_EFUSE)		+= nvmem_jz4780_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_JZ4780_EFUSE)		+= nvmem_jz4780_efuse.o | ||||
|  nvmem_jz4780_efuse-y		:= jz4780-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o | ||||
|  nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o | ||||
| @@ -25,37 +25,37 @@ obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-m | ||||
|  nvmem-mxs-ocotp-y		:= mxs-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_NINTENDO_OTP)	+= nvmem-nintendo-otp.o | ||||
|  nvmem-nintendo-otp-y		:= nintendo-otp.o | ||||
| -obj-$(CONFIG_MTK_EFUSE)		+= nvmem_mtk-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MTK_EFUSE)		+= nvmem_mtk-efuse.o | ||||
|  nvmem_mtk-efuse-y		:= mtk-efuse.o | ||||
| -obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o | ||||
| +obj-$(CONFIG_NVMEM_QCOM_QFPROM)	+= nvmem_qfprom.o | ||||
|  nvmem_qfprom-y			:= qfprom.o | ||||
|  obj-$(CONFIG_NVMEM_SPMI_SDAM)	+= nvmem_qcom-spmi-sdam.o | ||||
|  nvmem_qcom-spmi-sdam-y		+= qcom-spmi-sdam.o | ||||
| -obj-$(CONFIG_ROCKCHIP_EFUSE)	+= nvmem_rockchip_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE)	+= nvmem_rockchip_efuse.o | ||||
|  nvmem_rockchip_efuse-y		:= rockchip-efuse.o | ||||
| -obj-$(CONFIG_ROCKCHIP_OTP)	+= nvmem-rockchip-otp.o | ||||
| +obj-$(CONFIG_NVMEM_ROCKCHIP_OTP)	+= nvmem-rockchip-otp.o | ||||
|  nvmem-rockchip-otp-y		:= rockchip-otp.o | ||||
|  obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o | ||||
|  nvmem_stm32_romem-y 		:= stm32-romem.o | ||||
|  obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o | ||||
|  nvmem_sunxi_sid-y		:= sunxi_sid.o | ||||
| -obj-$(CONFIG_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
|  nvmem-uniphier-efuse-y		:= uniphier-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o | ||||
|  nvmem-vf610-ocotp-y		:= vf610-ocotp.o | ||||
| -obj-$(CONFIG_MESON_EFUSE)	+= nvmem_meson_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_EFUSE)	+= nvmem_meson_efuse.o | ||||
|  nvmem_meson_efuse-y		:= meson-efuse.o | ||||
| -obj-$(CONFIG_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
|  nvmem_meson_mx_efuse-y		:= meson-mx-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_SNVS_LPGPR)	+= nvmem_snvs_lpgpr.o | ||||
|  nvmem_snvs_lpgpr-y		:= snvs_lpgpr.o | ||||
| -obj-$(CONFIG_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
| +obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
|  nvmem-rave-sp-eeprom-y		:= rave-sp-eeprom.o | ||||
| -obj-$(CONFIG_SC27XX_EFUSE)	+= nvmem-sc27xx-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_SC27XX_EFUSE)	+= nvmem-sc27xx-efuse.o | ||||
|  nvmem-sc27xx-efuse-y		:= sc27xx-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_ZYNQMP)	+= nvmem_zynqmp_nvmem.o | ||||
|  nvmem_zynqmp_nvmem-y		:= zynqmp_nvmem.o | ||||
| -obj-$(CONFIG_SPRD_EFUSE)	+= nvmem_sprd_efuse.o | ||||
| +obj-$(CONFIG_NVMEM_SPRD_EFUSE)	+= nvmem_sprd_efuse.o | ||||
|  nvmem_sprd_efuse-y		:= sprd-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o | ||||
|  nvmem-rmem-y			:= rmem.o | ||||
| @@ -67,7 +67,7 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvm | ||||
|  nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
|  nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| -obj-$(CONFIG_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| +obj-$(CONFIG_NVMEM_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
|  nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
|  obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o | ||||
|  nvmem_u-boot-env-y		:= u-boot-env.o | ||||
| --- a/drivers/thermal/qcom/Kconfig | ||||
| +++ b/drivers/thermal/qcom/Kconfig | ||||
| @@ -1,7 +1,7 @@ | ||||
|  # SPDX-License-Identifier: GPL-2.0-only | ||||
|  config QCOM_TSENS | ||||
|  	tristate "Qualcomm TSENS Temperature Alarm" | ||||
| -	depends on QCOM_QFPROM | ||||
| +	depends on NVMEM_QCOM_QFPROM | ||||
|  	depends on ARCH_QCOM || COMPILE_TEST | ||||
|  	help | ||||
|  	  This enables the thermal sysfs driver for the TSENS device. It shows | ||||
| @@ -0,0 +1,535 @@ | ||||
| From a06d9e5a63b7c2f622c908cd9600ce735e70f7c6 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 16 Sep 2022 13:20:55 +0100 | ||||
| Subject: [PATCH] nvmem: sort config symbols alphabetically | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| 1. Match what most subsystems do | ||||
| 2. Simplify maintenance a bit | ||||
| 3. Reduce amount of conflicts for new drivers patches | ||||
|  | ||||
| While at it unify indent level in Makefile. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-9-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig  | 300 +++++++++++++++++++++-------------------- | ||||
|  drivers/nvmem/Makefile | 114 ++++++++-------- | ||||
|  2 files changed, 208 insertions(+), 206 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -21,6 +21,40 @@ config NVMEM_SYSFS | ||||
|  	 This interface is mostly used by userspace applications to | ||||
|  	 read/write directly into nvmem. | ||||
|   | ||||
| +# Devices | ||||
| + | ||||
| +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. | ||||
| + | ||||
| +config NVMEM_BCM_OCOTP | ||||
| +	tristate "Broadcom On-Chip OTP Controller support" | ||||
| +	depends on ARCH_BCM_IPROC || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	default ARCH_BCM_IPROC | ||||
| +	help | ||||
| +	  Say y here to enable read/write access to the Broadcom OTP | ||||
| +	  controller. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-bcm-ocotp. | ||||
| + | ||||
| +config NVMEM_BRCM_NVRAM | ||||
| +	tristate "Broadcom's NVRAM support" | ||||
| +	depends on ARCH_BCM_5301X || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver provides support for Broadcom's NVRAM that can be accessed | ||||
| +	  using I/O mapping. | ||||
| + | ||||
|  config NVMEM_IMX_IIM | ||||
|  	tristate "i.MX IC Identification Module support" | ||||
|  	depends on ARCH_MXC || COMPILE_TEST | ||||
| @@ -64,6 +98,19 @@ config NVMEM_JZ4780_EFUSE | ||||
|  	  To compile this driver as a module, choose M here: the module | ||||
|  	  will be called nvmem_jz4780_efuse. | ||||
|   | ||||
| +config NVMEM_LAYERSCAPE_SFP | ||||
| +	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
| +	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	select REGMAP_MMIO | ||||
| +	help | ||||
| +	  This driver provides support to read the eFuses on Freescale | ||||
| +	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| +	  unique ID there. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called layerscape-sfp. | ||||
| + | ||||
|  config NVMEM_LPC18XX_EEPROM | ||||
|  	tristate "NXP LPC18XX EEPROM Memory Support" | ||||
|  	depends on ARCH_LPC18XX || COMPILE_TEST | ||||
| @@ -84,17 +131,32 @@ config NVMEM_LPC18XX_OTP | ||||
|  	  To compile this driver as a module, choose M here: the module | ||||
|  	  will be called nvmem_lpc18xx_otp. | ||||
|   | ||||
| -config NVMEM_MXS_OCOTP | ||||
| -	tristate "Freescale MXS On-Chip OTP Memory Support" | ||||
| -	depends on ARCH_MXS || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| +config NVMEM_MESON_EFUSE | ||||
| +	tristate "Amlogic Meson GX eFuse Support" | ||||
| +	depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM | ||||
|  	help | ||||
| -	  If you say Y here, you will get readonly access to the | ||||
| -	  One Time Programmable memory pages that are stored | ||||
| -	  on the Freescale i.MX23/i.MX28 processor. | ||||
| +	  This is a driver to retrieve specific values from the eFuse found on | ||||
| +	  the Amlogic Meson GX SoCs. | ||||
|   | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-mxs-ocotp. | ||||
| +	  will be called nvmem_meson_efuse. | ||||
| + | ||||
| +config NVMEM_MESON_MX_EFUSE | ||||
| +	tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" | ||||
| +	depends on ARCH_MESON || COMPILE_TEST | ||||
| +	help | ||||
| +	  This is a driver to retrieve specific values from the eFuse found on | ||||
| +	  the Amlogic Meson6, Meson8 and Meson8b SoCs. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem_meson_mx_efuse. | ||||
| + | ||||
| +config NVMEM_MICROCHIP_OTPC | ||||
| +	tristate "Microchip OTPC support" | ||||
| +	depends on ARCH_AT91 || COMPILE_TEST | ||||
| +	help | ||||
| +	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| +	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
|   | ||||
|  config NVMEM_MTK_EFUSE | ||||
|  	tristate "Mediatek SoCs EFUSE support" | ||||
| @@ -107,12 +169,17 @@ config NVMEM_MTK_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called efuse-mtk. | ||||
|   | ||||
| -config NVMEM_MICROCHIP_OTPC | ||||
| -	tristate "Microchip OTPC support" | ||||
| -	depends on ARCH_AT91 || COMPILE_TEST | ||||
| +config NVMEM_MXS_OCOTP | ||||
| +	tristate "Freescale MXS On-Chip OTP Memory Support" | ||||
| +	depends on ARCH_MXS || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
|  	help | ||||
| -	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| -	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
| +	  If you say Y here, you will get readonly access to the | ||||
| +	  One Time Programmable memory pages that are stored | ||||
| +	  on the Freescale i.MX23/i.MX28 processor. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-mxs-ocotp. | ||||
|   | ||||
|  config NVMEM_NINTENDO_OTP | ||||
|  	tristate "Nintendo Wii and Wii U OTP Support" | ||||
| @@ -137,13 +204,21 @@ config NVMEM_QCOM_QFPROM | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_qfprom. | ||||
|   | ||||
| -config NVMEM_SPMI_SDAM | ||||
| -	tristate "SPMI SDAM Support" | ||||
| -	depends on SPMI | ||||
| +config NVMEM_RAVE_SP_EEPROM | ||||
| +	tristate "Rave SP EEPROM Support" | ||||
| +	depends on RAVE_SP_CORE | ||||
|  	help | ||||
| -	  This driver supports the Shared Direct Access Memory Module on | ||||
| -	  Qualcomm Technologies, Inc. PMICs. It provides the clients | ||||
| -	  an interface to read/write to the SDAM module's shared memory. | ||||
| +	  Say y here to enable Rave SP EEPROM support. | ||||
| + | ||||
| +config NVMEM_RMEM | ||||
| +	tristate "Reserved Memory Based Driver Support" | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver maps reserved memory into an nvmem device. It might be | ||||
| +	  useful to expose information left by firmware in memory. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-rmem. | ||||
|   | ||||
|  config NVMEM_ROCKCHIP_EFUSE | ||||
|  	tristate "Rockchip eFuse Support" | ||||
| @@ -167,79 +242,16 @@ config NVMEM_ROCKCHIP_OTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem_rockchip_otp. | ||||
|   | ||||
| -config NVMEM_BCM_OCOTP | ||||
| -	tristate "Broadcom On-Chip OTP Controller support" | ||||
| -	depends on ARCH_BCM_IPROC || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	default ARCH_BCM_IPROC | ||||
| -	help | ||||
| -	  Say y here to enable read/write access to the Broadcom OTP | ||||
| -	  controller. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-bcm-ocotp. | ||||
| - | ||||
| -config NVMEM_STM32_ROMEM | ||||
| -	tristate "STMicroelectronics STM32 factory-programmed memory support" | ||||
| -	depends on ARCH_STM32 || COMPILE_TEST | ||||
| -	help | ||||
| -	  Say y here to enable read-only access for STMicroelectronics STM32 | ||||
| -	  factory-programmed memory area. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-stm32-romem. | ||||
| - | ||||
| -config NVMEM_SUNXI_SID | ||||
| -	tristate "Allwinner SoCs SID support" | ||||
| -	depends on ARCH_SUNXI | ||||
| -	help | ||||
| -	  This is a driver for the 'security ID' available on various Allwinner | ||||
| -	  devices. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem_sunxi_sid. | ||||
| - | ||||
| -config NVMEM_UNIPHIER_EFUSE | ||||
| -	tristate "UniPhier SoCs eFuse support" | ||||
| -	depends on ARCH_UNIPHIER || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This is a simple driver to dump specified values of UniPhier SoC | ||||
| -	  from eFuse. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-uniphier-efuse. | ||||
| - | ||||
| -config NVMEM_VF610_OCOTP | ||||
| -	tristate "VF610 SoC OCOTP support" | ||||
| -	depends on SOC_VF610 || COMPILE_TEST | ||||
| +config NVMEM_SC27XX_EFUSE | ||||
| +	tristate "Spreadtrum SC27XX eFuse Support" | ||||
| +	depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||||
|  	depends on HAS_IOMEM | ||||
|  	help | ||||
| -	  This is a driver for the 'OCOTP' peripheral available on Vybrid | ||||
| -	  devices like VF5xx and VF6xx. | ||||
| - | ||||
| -	  This driver can also be build as a module. If so, the module will | ||||
| -	  be called nvmem-vf610-ocotp. | ||||
| - | ||||
| -config NVMEM_MESON_EFUSE | ||||
| -	tristate "Amlogic Meson GX eFuse Support" | ||||
| -	depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM | ||||
| -	help | ||||
| -	  This is a driver to retrieve specific values from the eFuse found on | ||||
| -	  the Amlogic Meson GX SoCs. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem_meson_efuse. | ||||
| - | ||||
| -config NVMEM_MESON_MX_EFUSE | ||||
| -	tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" | ||||
| -	depends on ARCH_MESON || COMPILE_TEST | ||||
| -	help | ||||
| -	  This is a driver to retrieve specific values from the eFuse found on | ||||
| -	  the Amlogic Meson6, Meson8 and Meson8b SoCs. | ||||
| +	  This is a simple driver to dump specified values of Spreadtrum | ||||
| +	  SC27XX PMICs from eFuse. | ||||
|   | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem_meson_mx_efuse. | ||||
| +	  will be called nvmem-sc27xx-efuse. | ||||
|   | ||||
|  config NVMEM_SNVS_LPGPR | ||||
|  	tristate "Support for Low Power General Purpose Register" | ||||
| @@ -251,32 +263,13 @@ config NVMEM_SNVS_LPGPR | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-snvs-lpgpr. | ||||
|   | ||||
| -config NVMEM_RAVE_SP_EEPROM | ||||
| -	tristate "Rave SP EEPROM Support" | ||||
| -	depends on RAVE_SP_CORE | ||||
| -	help | ||||
| -	  Say y here to enable Rave SP EEPROM support. | ||||
| - | ||||
| -config NVMEM_SC27XX_EFUSE | ||||
| -	tristate "Spreadtrum SC27XX eFuse Support" | ||||
| -	depends on MFD_SC27XX_PMIC || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This is a simple driver to dump specified values of Spreadtrum | ||||
| -	  SC27XX PMICs from eFuse. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-sc27xx-efuse. | ||||
| - | ||||
| -config NVMEM_ZYNQMP | ||||
| -	bool "Xilinx ZYNQMP SoC nvmem firmware support" | ||||
| -	depends on ARCH_ZYNQMP | ||||
| +config NVMEM_SPMI_SDAM | ||||
| +	tristate "SPMI SDAM Support" | ||||
| +	depends on SPMI | ||||
|  	help | ||||
| -	  This is a driver to access hardware related data like | ||||
| -	  soc revision, IDCODE... etc by using the firmware | ||||
| -	  interface. | ||||
| - | ||||
| -	  If sure, say yes. If unsure, say no. | ||||
| +	  This driver supports the Shared Direct Access Memory Module on | ||||
| +	  Qualcomm Technologies, Inc. PMICs. It provides the clients | ||||
| +	  an interface to read/write to the SDAM module's shared memory. | ||||
|   | ||||
|  config NVMEM_SPRD_EFUSE | ||||
|  	tristate "Spreadtrum SoC eFuse Support" | ||||
| @@ -289,36 +282,15 @@ config NVMEM_SPRD_EFUSE | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-sprd-efuse. | ||||
|   | ||||
| -config NVMEM_RMEM | ||||
| -	tristate "Reserved Memory Based Driver Support" | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This driver maps reserved memory into an nvmem device. It might be | ||||
| -	  useful to expose information left by firmware in memory. | ||||
| - | ||||
| -	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called nvmem-rmem. | ||||
| - | ||||
| -config NVMEM_BRCM_NVRAM | ||||
| -	tristate "Broadcom's NVRAM support" | ||||
| -	depends on ARCH_BCM_5301X || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	help | ||||
| -	  This driver provides support for Broadcom's NVRAM that can be accessed | ||||
| -	  using I/O mapping. | ||||
| - | ||||
| -config NVMEM_LAYERSCAPE_SFP | ||||
| -	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
| -	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| -	depends on HAS_IOMEM | ||||
| -	select REGMAP_MMIO | ||||
| +config NVMEM_STM32_ROMEM | ||||
| +	tristate "STMicroelectronics STM32 factory-programmed memory support" | ||||
| +	depends on ARCH_STM32 || COMPILE_TEST | ||||
|  	help | ||||
| -	  This driver provides support to read the eFuses on Freescale | ||||
| -	  Layerscape SoC's. For example, the vendor provides a per part | ||||
| -	  unique ID there. | ||||
| +	  Say y here to enable read-only access for STMicroelectronics STM32 | ||||
| +	  factory-programmed memory area. | ||||
|   | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
| -	  will be called layerscape-sfp. | ||||
| +	  will be called nvmem-stm32-romem. | ||||
|   | ||||
|  config NVMEM_SUNPLUS_OCOTP | ||||
|  	tristate "Sunplus SoC OTP support" | ||||
| @@ -332,17 +304,15 @@ config NVMEM_SUNPLUS_OCOTP | ||||
|  	  This driver can also be built as a module. If so, the module | ||||
|  	  will be called nvmem-sunplus-ocotp. | ||||
|   | ||||
| -config NVMEM_APPLE_EFUSES | ||||
| -	tristate "Apple eFuse support" | ||||
| -	depends on ARCH_APPLE || COMPILE_TEST | ||||
| -	default ARCH_APPLE | ||||
| +config NVMEM_SUNXI_SID | ||||
| +	tristate "Allwinner SoCs SID support" | ||||
| +	depends on ARCH_SUNXI | ||||
|  	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 is a driver for the 'security ID' available on various Allwinner | ||||
| +	  devices. | ||||
|   | ||||
| -	  This driver can also be built as a module. If so, the module will | ||||
| -	  be called nvmem-apple-efuses. | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem_sunxi_sid. | ||||
|   | ||||
|  config NVMEM_U_BOOT_ENV | ||||
|  	tristate "U-Boot environment variables support" | ||||
| @@ -357,4 +327,36 @@ config NVMEM_U_BOOT_ENV | ||||
|   | ||||
|  	  If compiled as module it will be called nvmem_u-boot-env. | ||||
|   | ||||
| +config NVMEM_UNIPHIER_EFUSE | ||||
| +	tristate "UniPhier SoCs eFuse support" | ||||
| +	depends on ARCH_UNIPHIER || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This is a simple driver to dump specified values of UniPhier SoC | ||||
| +	  from eFuse. | ||||
| + | ||||
| +	  This driver can also be built as a module. If so, the module | ||||
| +	  will be called nvmem-uniphier-efuse. | ||||
| + | ||||
| +config NVMEM_VF610_OCOTP | ||||
| +	tristate "VF610 SoC OCOTP support" | ||||
| +	depends on SOC_VF610 || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This is a driver for the 'OCOTP' peripheral available on Vybrid | ||||
| +	  devices like VF5xx and VF6xx. | ||||
| + | ||||
| +	  This driver can also be build as a module. If so, the module will | ||||
| +	  be called nvmem-vf610-ocotp. | ||||
| + | ||||
| +config NVMEM_ZYNQMP | ||||
| +	bool "Xilinx ZYNQMP SoC nvmem firmware support" | ||||
| +	depends on ARCH_ZYNQMP | ||||
| +	help | ||||
| +	  This is a driver to access hardware related data like | ||||
| +	  soc revision, IDCODE... etc by using the firmware | ||||
| +	  interface. | ||||
| + | ||||
| +	  If sure, say yes. If unsure, say no. | ||||
| + | ||||
|  endif | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -7,67 +7,67 @@ obj-$(CONFIG_NVMEM)		+= nvmem_core.o | ||||
|  nvmem_core-y			:= core.o | ||||
|   | ||||
|  # Devices | ||||
| -obj-$(CONFIG_NVMEM_BCM_OCOTP)	+= nvmem-bcm-ocotp.o | ||||
| -nvmem-bcm-ocotp-y		:= bcm-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_IMX_IIM)	+= nvmem-imx-iim.o | ||||
| -nvmem-imx-iim-y			:= imx-iim.o | ||||
| -obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o | ||||
| -nvmem-imx-ocotp-y		:= imx-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
| +nvmem-apple-efuses-y 			:= apple-efuses.o | ||||
| +obj-$(CONFIG_NVMEM_BCM_OCOTP)		+= nvmem-bcm-ocotp.o | ||||
| +nvmem-bcm-ocotp-y			:= bcm-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_BRCM_NVRAM)		+= nvmem_brcm_nvram.o | ||||
| +nvmem_brcm_nvram-y			:= brcm_nvram.o | ||||
| +obj-$(CONFIG_NVMEM_IMX_IIM)		+= nvmem-imx-iim.o | ||||
| +nvmem-imx-iim-y				:= imx-iim.o | ||||
| +obj-$(CONFIG_NVMEM_IMX_OCOTP)		+= nvmem-imx-ocotp.o | ||||
| +nvmem-imx-ocotp-y			:= imx-ocotp.o | ||||
|  obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o | ||||
| -nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o | ||||
| -obj-$(CONFIG_NVMEM_JZ4780_EFUSE)		+= nvmem_jz4780_efuse.o | ||||
| -nvmem_jz4780_efuse-y		:= jz4780-efuse.o | ||||
| +nvmem-imx-ocotp-scu-y			:= imx-ocotp-scu.o | ||||
| +obj-$(CONFIG_NVMEM_JZ4780_EFUSE)	+= nvmem_jz4780_efuse.o | ||||
| +nvmem_jz4780_efuse-y			:= jz4780-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
| +nvmem-layerscape-sfp-y			:= layerscape-sfp.o | ||||
|  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o | ||||
| -nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o | ||||
| -obj-$(CONFIG_NVMEM_LPC18XX_OTP)	+= nvmem_lpc18xx_otp.o | ||||
| -nvmem_lpc18xx_otp-y		:= lpc18xx_otp.o | ||||
| -obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-mxs-ocotp.o | ||||
| -nvmem-mxs-ocotp-y		:= mxs-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_NINTENDO_OTP)	+= nvmem-nintendo-otp.o | ||||
| -nvmem-nintendo-otp-y		:= nintendo-otp.o | ||||
| +nvmem_lpc18xx_eeprom-y			:= lpc18xx_eeprom.o | ||||
| +obj-$(CONFIG_NVMEM_LPC18XX_OTP)		+= nvmem_lpc18xx_otp.o | ||||
| +nvmem_lpc18xx_otp-y			:= lpc18xx_otp.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_EFUSE)		+= nvmem_meson_efuse.o | ||||
| +nvmem_meson_efuse-y			:= meson-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
| +nvmem_meson_mx_efuse-y			:= meson-mx-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| +nvmem-microchip-otpc-y			:= microchip-otpc.o | ||||
|  obj-$(CONFIG_NVMEM_MTK_EFUSE)		+= nvmem_mtk-efuse.o | ||||
| -nvmem_mtk-efuse-y		:= mtk-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_QCOM_QFPROM)	+= nvmem_qfprom.o | ||||
| -nvmem_qfprom-y			:= qfprom.o | ||||
| -obj-$(CONFIG_NVMEM_SPMI_SDAM)	+= nvmem_qcom-spmi-sdam.o | ||||
| -nvmem_qcom-spmi-sdam-y		+= qcom-spmi-sdam.o | ||||
| +nvmem_mtk-efuse-y			:= mtk-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_MXS_OCOTP)		+= nvmem-mxs-ocotp.o | ||||
| +nvmem-mxs-ocotp-y			:= mxs-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_NINTENDO_OTP)	+= nvmem-nintendo-otp.o | ||||
| +nvmem-nintendo-otp-y			:= nintendo-otp.o | ||||
| +obj-$(CONFIG_NVMEM_QCOM_QFPROM)		+= nvmem_qfprom.o | ||||
| +nvmem_qfprom-y				:= qfprom.o | ||||
| +obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
| +nvmem-rave-sp-eeprom-y			:= rave-sp-eeprom.o | ||||
| +obj-$(CONFIG_NVMEM_RMEM) 		+= nvmem-rmem.o | ||||
| +nvmem-rmem-y				:= rmem.o | ||||
|  obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE)	+= nvmem_rockchip_efuse.o | ||||
| -nvmem_rockchip_efuse-y		:= rockchip-efuse.o | ||||
| +nvmem_rockchip_efuse-y			:= rockchip-efuse.o | ||||
|  obj-$(CONFIG_NVMEM_ROCKCHIP_OTP)	+= nvmem-rockchip-otp.o | ||||
| -nvmem-rockchip-otp-y		:= rockchip-otp.o | ||||
| -obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o | ||||
| -nvmem_stm32_romem-y 		:= stm32-romem.o | ||||
| -obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o | ||||
| -nvmem_sunxi_sid-y		:= sunxi_sid.o | ||||
| -obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
| -nvmem-uniphier-efuse-y		:= uniphier-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o | ||||
| -nvmem-vf610-ocotp-y		:= vf610-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_MESON_EFUSE)	+= nvmem_meson_efuse.o | ||||
| -nvmem_meson_efuse-y		:= meson-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_MESON_MX_EFUSE)	+= nvmem_meson_mx_efuse.o | ||||
| -nvmem_meson_mx_efuse-y		:= meson-mx-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_SNVS_LPGPR)	+= nvmem_snvs_lpgpr.o | ||||
| -nvmem_snvs_lpgpr-y		:= snvs_lpgpr.o | ||||
| -obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM)	+= nvmem-rave-sp-eeprom.o | ||||
| -nvmem-rave-sp-eeprom-y		:= rave-sp-eeprom.o | ||||
| +nvmem-rockchip-otp-y			:= rockchip-otp.o | ||||
|  obj-$(CONFIG_NVMEM_SC27XX_EFUSE)	+= nvmem-sc27xx-efuse.o | ||||
| -nvmem-sc27xx-efuse-y		:= sc27xx-efuse.o | ||||
| -obj-$(CONFIG_NVMEM_ZYNQMP)	+= nvmem_zynqmp_nvmem.o | ||||
| -nvmem_zynqmp_nvmem-y		:= zynqmp_nvmem.o | ||||
| -obj-$(CONFIG_NVMEM_SPRD_EFUSE)	+= nvmem_sprd_efuse.o | ||||
| -nvmem_sprd_efuse-y		:= sprd-efuse.o | ||||
| -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_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
| -nvmem-layerscape-sfp-y		:= layerscape-sfp.o | ||||
| +nvmem-sc27xx-efuse-y			:= sc27xx-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_SNVS_LPGPR)		+= nvmem_snvs_lpgpr.o | ||||
| +nvmem_snvs_lpgpr-y			:= snvs_lpgpr.o | ||||
| +obj-$(CONFIG_NVMEM_SPMI_SDAM)		+= nvmem_qcom-spmi-sdam.o | ||||
| +nvmem_qcom-spmi-sdam-y			+= qcom-spmi-sdam.o | ||||
| +obj-$(CONFIG_NVMEM_SPRD_EFUSE)		+= nvmem_sprd_efuse.o | ||||
| +nvmem_sprd_efuse-y			:= sprd-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_STM32_ROMEM)		+= nvmem_stm32_romem.o | ||||
| +nvmem_stm32_romem-y 			:= stm32-romem.o | ||||
|  obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP)	+= nvmem_sunplus_ocotp.o | ||||
| -nvmem_sunplus_ocotp-y		:= sunplus-ocotp.o | ||||
| -obj-$(CONFIG_NVMEM_APPLE_EFUSES)	+= nvmem-apple-efuses.o | ||||
| -nvmem-apple-efuses-y 		:= apple-efuses.o | ||||
| -obj-$(CONFIG_NVMEM_MICROCHIP_OTPC)	+= nvmem-microchip-otpc.o | ||||
| -nvmem-microchip-otpc-y		:= microchip-otpc.o | ||||
| -obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o | ||||
| -nvmem_u-boot-env-y		:= u-boot-env.o | ||||
| +nvmem_sunplus_ocotp-y			:= sunplus-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_SUNXI_SID)		+= nvmem_sunxi_sid.o | ||||
| +nvmem_sunxi_sid-y			:= sunxi_sid.o | ||||
| +obj-$(CONFIG_NVMEM_U_BOOT_ENV)		+= nvmem_u-boot-env.o | ||||
| +nvmem_u-boot-env-y			:= u-boot-env.o | ||||
| +obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE)	+= nvmem-uniphier-efuse.o | ||||
| +nvmem-uniphier-efuse-y			:= uniphier-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_VF610_OCOTP)		+= nvmem-vf610-ocotp.o | ||||
| +nvmem-vf610-ocotp-y			:= vf610-ocotp.o | ||||
| +obj-$(CONFIG_NVMEM_ZYNQMP)		+= nvmem_zynqmp_nvmem.o | ||||
| +nvmem_zynqmp_nvmem-y			:= zynqmp_nvmem.o | ||||
| @@ -1,6 +1,6 @@ | ||||
| From d69efcf951df4dcc74a0e1554969c533aec8aa9b Mon Sep 17 00:00:00 2001 | ||||
| From d4d432670f7dee0a5432fcffcfc8699b25181ace Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 15 Sep 2022 22:06:29 +0200 | ||||
| Date: Fri, 16 Sep 2022 13:20:57 +0100 | ||||
| Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -13,6 +13,8 @@ This allows NVMEM consumers to use U-Boot environment variables. | ||||
| 
 | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-11-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
| @@ -0,0 +1,274 @@ | ||||
| From 9e8f208ad5229ddda97cd4a83ecf89c735d99592 Mon Sep 17 00:00:00 2001 | ||||
| From: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Date: Fri, 16 Sep 2022 13:20:59 +0100 | ||||
| Subject: [PATCH] nvmem: lan9662-otp: add support | ||||
|  | ||||
| Add support for OTP controller available on LAN9662. The OTPC controls | ||||
| the access to a non-volatile memory. The size of the memory is 8KB. | ||||
| The OTPC can access the memory based on an offset. | ||||
| Implement both the read and the write functionality. | ||||
|  | ||||
| Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-13-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig        |   8 ++ | ||||
|  drivers/nvmem/Makefile       |   2 + | ||||
|  drivers/nvmem/lan9662-otpc.c | 222 +++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 232 insertions(+) | ||||
|  create mode 100644 drivers/nvmem/lan9662-otpc.c | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -98,6 +98,14 @@ config NVMEM_JZ4780_EFUSE | ||||
|  	  To compile this driver as a module, choose M here: the module | ||||
|  	  will be called nvmem_jz4780_efuse. | ||||
|   | ||||
| +config NVMEM_LAN9662_OTPC | ||||
| +	tristate "Microchip LAN9662 OTP controller support" | ||||
| +	depends on SOC_LAN966 || COMPILE_TEST | ||||
| +	depends on HAS_IOMEM | ||||
| +	help | ||||
| +	  This driver enables the OTP controller available on Microchip LAN9662 | ||||
| +	  SoCs. It controls the access to the OTP memory connected to it. | ||||
| + | ||||
|  config NVMEM_LAYERSCAPE_SFP | ||||
|  	tristate "Layerscape SFP (Security Fuse Processor) support" | ||||
|  	depends on ARCH_LAYERSCAPE || COMPILE_TEST | ||||
| --- a/drivers/nvmem/Makefile | ||||
| +++ b/drivers/nvmem/Makefile | ||||
| @@ -21,6 +21,8 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvm | ||||
|  nvmem-imx-ocotp-scu-y			:= imx-ocotp-scu.o | ||||
|  obj-$(CONFIG_NVMEM_JZ4780_EFUSE)	+= nvmem_jz4780_efuse.o | ||||
|  nvmem_jz4780_efuse-y			:= jz4780-efuse.o | ||||
| +obj-$(CONFIG_NVMEM_LAN9662_OTPC)	+= nvmem-lan9662-otpc.o | ||||
| +nvmem-lan9662-otpc-y		:= lan9662-otpc.o | ||||
|  obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o | ||||
|  nvmem-layerscape-sfp-y			:= layerscape-sfp.o | ||||
|  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/nvmem/lan9662-otpc.c | ||||
| @@ -0,0 +1,222 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0 | ||||
| + | ||||
| +#include <linux/iopoll.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/nvmem-provider.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| + | ||||
| +#define OTP_OTP_PWR_DN(t)			(t + 0x00) | ||||
| +#define OTP_OTP_PWR_DN_OTP_PWRDN_N		BIT(0) | ||||
| +#define OTP_OTP_ADDR_HI(t)			(t + 0x04) | ||||
| +#define OTP_OTP_ADDR_LO(t)			(t + 0x08) | ||||
| +#define OTP_OTP_PRGM_DATA(t)			(t + 0x10) | ||||
| +#define OTP_OTP_PRGM_MODE(t)			(t + 0x14) | ||||
| +#define OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE	BIT(0) | ||||
| +#define OTP_OTP_RD_DATA(t)			(t + 0x18) | ||||
| +#define OTP_OTP_FUNC_CMD(t)			(t + 0x20) | ||||
| +#define OTP_OTP_FUNC_CMD_OTP_PROGRAM		BIT(1) | ||||
| +#define OTP_OTP_FUNC_CMD_OTP_READ		BIT(0) | ||||
| +#define OTP_OTP_CMD_GO(t)			(t + 0x28) | ||||
| +#define OTP_OTP_CMD_GO_OTP_GO			BIT(0) | ||||
| +#define OTP_OTP_PASS_FAIL(t)			(t + 0x2c) | ||||
| +#define OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED	BIT(3) | ||||
| +#define OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED	BIT(2) | ||||
| +#define OTP_OTP_PASS_FAIL_OTP_FAIL		BIT(0) | ||||
| +#define OTP_OTP_STATUS(t)			(t + 0x30) | ||||
| +#define OTP_OTP_STATUS_OTP_CPUMPEN		BIT(1) | ||||
| +#define OTP_OTP_STATUS_OTP_BUSY			BIT(0) | ||||
| + | ||||
| +#define OTP_MEM_SIZE 8192 | ||||
| +#define OTP_SLEEP_US 10 | ||||
| +#define OTP_TIMEOUT_US 500000 | ||||
| + | ||||
| +struct lan9662_otp { | ||||
| +	struct device *dev; | ||||
| +	void __iomem *base; | ||||
| +}; | ||||
| + | ||||
| +static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) | ||||
| +{ | ||||
| +	u32 val; | ||||
| + | ||||
| +	return readl_poll_timeout(reg, val, !(val & flag), | ||||
| +				  OTP_SLEEP_US, OTP_TIMEOUT_US); | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_power(struct lan9662_otp *otp, bool up) | ||||
| +{ | ||||
| +	void __iomem *pwrdn = OTP_OTP_PWR_DN(otp->base); | ||||
| + | ||||
| +	if (up) { | ||||
| +		writel(readl(pwrdn) & ~OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); | ||||
| +		if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), | ||||
| +						OTP_OTP_STATUS_OTP_CPUMPEN)) | ||||
| +			return -ETIMEDOUT; | ||||
| +	} else { | ||||
| +		writel(readl(pwrdn) | OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_execute(struct lan9662_otp *otp) | ||||
| +{ | ||||
| +	if (lan9662_otp_wait_flag_clear(OTP_OTP_CMD_GO(otp->base), | ||||
| +					OTP_OTP_CMD_GO_OTP_GO)) | ||||
| +		return -ETIMEDOUT; | ||||
| + | ||||
| +	if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), | ||||
| +					OTP_OTP_STATUS_OTP_BUSY)) | ||||
| +		return -ETIMEDOUT; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void lan9662_otp_set_address(struct lan9662_otp *otp, u32 offset) | ||||
| +{ | ||||
| +	writel(0xff & (offset >> 8), OTP_OTP_ADDR_HI(otp->base)); | ||||
| +	writel(0xff & offset, OTP_OTP_ADDR_LO(otp->base)); | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_read_byte(struct lan9662_otp *otp, u32 offset, u8 *dst) | ||||
| +{ | ||||
| +	u32 pass; | ||||
| +	int rc; | ||||
| + | ||||
| +	lan9662_otp_set_address(otp, offset); | ||||
| +	writel(OTP_OTP_FUNC_CMD_OTP_READ, OTP_OTP_FUNC_CMD(otp->base)); | ||||
| +	writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); | ||||
| +	rc = lan9662_otp_execute(otp); | ||||
| +	if (!rc) { | ||||
| +		pass = readl(OTP_OTP_PASS_FAIL(otp->base)); | ||||
| +		if (pass & OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED) | ||||
| +			return -EACCES; | ||||
| +		*dst = (u8) readl(OTP_OTP_RD_DATA(otp->base)); | ||||
| +	} | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 data) | ||||
| +{ | ||||
| +	u32 pass; | ||||
| +	int rc; | ||||
| + | ||||
| +	lan9662_otp_set_address(otp, offset); | ||||
| +	writel(OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE, OTP_OTP_PRGM_MODE(otp->base)); | ||||
| +	writel(data, OTP_OTP_PRGM_DATA(otp->base)); | ||||
| +	writel(OTP_OTP_FUNC_CMD_OTP_PROGRAM, OTP_OTP_FUNC_CMD(otp->base)); | ||||
| +	writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); | ||||
| + | ||||
| +	rc = lan9662_otp_execute(otp); | ||||
| +	if (!rc) { | ||||
| +		pass = readl(OTP_OTP_PASS_FAIL(otp->base)); | ||||
| +		if (pass & OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED) | ||||
| +			return -EACCES; | ||||
| +		if (pass & OTP_OTP_PASS_FAIL_OTP_FAIL) | ||||
| +			return -EIO; | ||||
| +	} | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_read(void *context, unsigned int offset, | ||||
| +			    void *_val, size_t bytes) | ||||
| +{ | ||||
| +	struct lan9662_otp *otp = context; | ||||
| +	u8 *val = _val; | ||||
| +	uint8_t data; | ||||
| +	int i, rc = 0; | ||||
| + | ||||
| +	lan9662_otp_power(otp, true); | ||||
| +	for (i = 0; i < bytes; i++) { | ||||
| +		rc = lan9662_otp_read_byte(otp, offset + i, &data); | ||||
| +		if (rc < 0) | ||||
| +			break; | ||||
| +		*val++ = data; | ||||
| +	} | ||||
| +	lan9662_otp_power(otp, false); | ||||
| + | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static int lan9662_otp_write(void *context, unsigned int offset, | ||||
| +			     void *_val, size_t bytes) | ||||
| +{ | ||||
| +	struct lan9662_otp *otp = context; | ||||
| +	u8 *val = _val; | ||||
| +	u8 data, newdata; | ||||
| +	int i, rc = 0; | ||||
| + | ||||
| +	lan9662_otp_power(otp, true); | ||||
| +	for (i = 0; i < bytes; i++) { | ||||
| +		/* Skip zero bytes */ | ||||
| +		if (val[i]) { | ||||
| +			rc = lan9662_otp_read_byte(otp, offset + i, &data); | ||||
| +			if (rc < 0) | ||||
| +				break; | ||||
| + | ||||
| +			newdata = data | val[i]; | ||||
| +			if (newdata == data) | ||||
| +				continue; | ||||
| + | ||||
| +			rc = lan9662_otp_write_byte(otp, offset + i, | ||||
| +						      newdata); | ||||
| +			if (rc < 0) | ||||
| +				break; | ||||
| +		} | ||||
| +	} | ||||
| +	lan9662_otp_power(otp, false); | ||||
| + | ||||
| +	return rc; | ||||
| +} | ||||
| + | ||||
| +static struct nvmem_config otp_config = { | ||||
| +	.name = "lan9662-otp", | ||||
| +	.stride = 1, | ||||
| +	.word_size = 1, | ||||
| +	.reg_read = lan9662_otp_read, | ||||
| +	.reg_write = lan9662_otp_write, | ||||
| +	.size = OTP_MEM_SIZE, | ||||
| +}; | ||||
| + | ||||
| +static int lan9662_otp_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct device *dev = &pdev->dev; | ||||
| +	struct nvmem_device *nvmem; | ||||
| +	struct lan9662_otp *otp; | ||||
| + | ||||
| +	otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); | ||||
| +	if (!otp) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	otp->dev = dev; | ||||
| +	otp->base = devm_platform_ioremap_resource(pdev, 0); | ||||
| +	if (IS_ERR(otp->base)) | ||||
| +		return PTR_ERR(otp->base); | ||||
| + | ||||
| +	otp_config.priv = otp; | ||||
| +	otp_config.dev = dev; | ||||
| + | ||||
| +	nvmem = devm_nvmem_register(dev, &otp_config); | ||||
| + | ||||
| +	return PTR_ERR_OR_ZERO(nvmem); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id lan9662_otp_match[] = { | ||||
| +	{ .compatible = "microchip,lan9662-otp", }, | ||||
| +	{ }, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, lan9662_otp_match); | ||||
| + | ||||
| +static struct platform_driver lan9662_otp_driver = { | ||||
| +	.probe = lan9662_otp_probe, | ||||
| +	.driver = { | ||||
| +		.name = "lan9662-otp", | ||||
| +		.of_match_table = lan9662_otp_match, | ||||
| +	}, | ||||
| +}; | ||||
| +module_platform_driver(lan9662_otp_driver); | ||||
| + | ||||
| +MODULE_AUTHOR("Horatiu Vultur <horatiu.vultur@microchip.com>"); | ||||
| +MODULE_DESCRIPTION("lan9662 OTP driver"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -1,6 +1,6 @@ | ||||
| From 60bbaad38109684b156e21112322e0a922f92cde Mon Sep 17 00:00:00 2001 | ||||
| From 3717ca3e0cc8683f93b41d3f06ca79631eb58715 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 18 Aug 2022 06:38:37 +0200 | ||||
| Date: Fri, 16 Sep 2022 13:21:00 +0100 | ||||
| Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -9,10 +9,12 @@ Content-Transfer-Encoding: 8bit | ||||
| This fixes: | ||||
| drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32 | ||||
| 
 | ||||
| Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") | ||||
| Reported-by: kernel test robot <lkp@intel.com> | ||||
| Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20220916122100.170016-14-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| @@ -0,0 +1,34 @@ | ||||
| From 1aeb122d214b92474c86fde00a03d6e2d69381b5 Mon Sep 17 00:00:00 2001 | ||||
| From: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Date: Wed, 28 Sep 2022 21:51:12 +0200 | ||||
| Subject: [PATCH] nvmem: lan9662-otp: Fix compatible string | ||||
|  | ||||
| The device tree bindings for lan9662-otp expects the compatible string | ||||
| to be one of following compatible strings: | ||||
| microchip,lan9662-otpc | ||||
| microchip,lan9668-otpc | ||||
|  | ||||
| The problem is that the lan9662-otp driver contains the | ||||
| microchip,lan9662-otp compatible string instead of | ||||
| microchip,lan9662-otpc. | ||||
| Fix this by updating the compatible string in the driver. | ||||
|  | ||||
| Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support") | ||||
| Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Link: https://lore.kernel.org/r/20220928195112.630351-1-horatiu.vultur@microchip.com | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/lan9662-otpc.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/lan9662-otpc.c | ||||
| +++ b/drivers/nvmem/lan9662-otpc.c | ||||
| @@ -203,7 +203,7 @@ static int lan9662_otp_probe(struct plat | ||||
|  } | ||||
|   | ||||
|  static const struct of_device_id lan9662_otp_match[] = { | ||||
| -	{ .compatible = "microchip,lan9662-otp", }, | ||||
| +	{ .compatible = "microchip,lan9662-otpc", }, | ||||
|  	{ }, | ||||
|  }; | ||||
|  MODULE_DEVICE_TABLE(of, lan9662_otp_match); | ||||
| @@ -1,4 +1,4 @@ | ||||
| From 7a69ff9c9bde03a690ea783970f664782fc303d8 Mon Sep 17 00:00:00 2001 | ||||
| From ee424f7d3960152f5f862bbb6943e59828dc7917 Mon Sep 17 00:00:00 2001 | ||||
| From: Christian Lamparter <chunkeey@gmail.com> | ||||
| Date: Fri, 4 Nov 2022 17:52:03 +0100 | ||||
| Subject: [PATCH] nvmem: u-boot-env: fix crc32_data_offset on redundant | ||||
| @@ -37,8 +37,11 @@ crc32 sum... which is unfortunate :( | ||||
| | | ||||
| 
 | ||||
| [0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951 | ||||
| 
 | ||||
| Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") | ||||
| Signed-off-by: Christian Lamparter <chunkeey@gmail.com> | ||||
| Link: https://lore.kernel.org/r/70a16eae113e08db2390b76e174f4837caa135c3.1667580636.git.chunkeey@gmail.com | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| @@ -0,0 +1,35 @@ | ||||
| From 022b68f271de0e53024e6d5e96fee8e76d25eb95 Mon Sep 17 00:00:00 2001 | ||||
| From: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Date: Fri, 18 Nov 2022 06:38:40 +0000 | ||||
| Subject: [PATCH] nvmem: lan9662-otp: Change return type of | ||||
|  lan9662_otp_wait_flag_clear() | ||||
|  | ||||
| The blamed commit introduced the following smatch warning in the | ||||
| function lan9662_otp_wait_flag_clear: | ||||
| drivers/nvmem/lan9662-otpc.c:43 lan9662_otp_wait_flag_clear() warn: signedness bug returning '(-110)' | ||||
|  | ||||
| Fix this by changing the return type of the function | ||||
| lan9662_otp_wait_flag_clear() to be int instead of bool. | ||||
|  | ||||
| Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support") | ||||
| Reported-by: kernel test robot <lkp@intel.com> | ||||
| Reported-by: Dan Carpenter <dan.carpenter@oracle.com> | ||||
| Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063840.6357-5-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/lan9662-otpc.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/lan9662-otpc.c | ||||
| +++ b/drivers/nvmem/lan9662-otpc.c | ||||
| @@ -36,7 +36,7 @@ struct lan9662_otp { | ||||
|  	void __iomem *base; | ||||
|  }; | ||||
|   | ||||
| -static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) | ||||
| +static int lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) | ||||
|  { | ||||
|  	u32 val; | ||||
|   | ||||
| @@ -0,0 +1,82 @@ | ||||
| From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001 | ||||
| From: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:20 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config | ||||
|  | ||||
| Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare | ||||
| the next SoC in STM32MP family. | ||||
|  | ||||
| Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++----- | ||||
|  1 file changed, 16 insertions(+), 5 deletions(-) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -22,16 +22,15 @@ | ||||
|  /* shadow registers offest */ | ||||
|  #define STM32MP15_BSEC_DATA0		0x200 | ||||
|   | ||||
| -/* 32 (x 32-bits) lower shadow registers */ | ||||
| -#define STM32MP15_BSEC_NUM_LOWER	32 | ||||
| - | ||||
|  struct stm32_romem_cfg { | ||||
|  	int size; | ||||
| +	u8 lower; | ||||
|  }; | ||||
|   | ||||
|  struct stm32_romem_priv { | ||||
|  	void __iomem *base; | ||||
|  	struct nvmem_config cfg; | ||||
| +	u8 lower; | ||||
|  }; | ||||
|   | ||||
|  static int stm32_romem_read(void *context, unsigned int offset, void *buf, | ||||
| @@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context | ||||
|  	for (i = roffset; (i < roffset + rbytes); i += 4) { | ||||
|  		u32 otp = i >> 2; | ||||
|   | ||||
| -		if (otp < STM32MP15_BSEC_NUM_LOWER) { | ||||
| +		if (otp < priv->lower) { | ||||
|  			/* read lower data from shadow registers */ | ||||
|  			val = readl_relaxed( | ||||
|  				priv->base + STM32MP15_BSEC_DATA0 + i); | ||||
| @@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat | ||||
|  	priv->cfg.priv = priv; | ||||
|  	priv->cfg.owner = THIS_MODULE; | ||||
|   | ||||
| +	priv->lower = 0; | ||||
| + | ||||
|  	cfg = (const struct stm32_romem_cfg *) | ||||
|  		of_match_device(dev->driver->of_match_table, dev)->data; | ||||
|  	if (!cfg) { | ||||
| @@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat | ||||
|  		priv->cfg.reg_read = stm32_romem_read; | ||||
|  	} else { | ||||
|  		priv->cfg.size = cfg->size; | ||||
| +		priv->lower = cfg->lower; | ||||
|  		priv->cfg.reg_read = stm32_bsec_read; | ||||
|  		priv->cfg.reg_write = stm32_bsec_write; | ||||
|  	} | ||||
| @@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat | ||||
|  	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); | ||||
|  } | ||||
|   | ||||
| +/* | ||||
| + * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) | ||||
| + * => 96 x 32-bits data words | ||||
| + * - Lower: 1K bits, 2:1 redundancy, incremental bit programming | ||||
| + *   => 32 (x 32-bits) lower shadow registers = words 0 to 31 | ||||
| + * - Upper: 2K bits, ECC protection, word programming only | ||||
| + *   => 64 (x 32-bits) = words 32 to 95 | ||||
| + */ | ||||
|  static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { | ||||
| -	.size = 384, /* 96 x 32-bits data words */ | ||||
| +	.size = 384, | ||||
| +	.lower = 32, | ||||
|  }; | ||||
|   | ||||
|  static const struct of_device_id stm32_romem_of_match[] = { | ||||
| @@ -0,0 +1,34 @@ | ||||
| From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001 | ||||
| From: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:21 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated | ||||
|  | ||||
| As the upper OTPs are ECC protected, they support only one 32 bits word | ||||
| programming. | ||||
| For a second modification of this word, these ECC become invalid and | ||||
| this OTP will be no more accessible, the shadowed value is invalid. | ||||
|  | ||||
| This patch adds a warning to indicate an upper OTP update, because this | ||||
| operation is dangerous as OTP is not locked by the driver after the first | ||||
| update to avoid a second update. | ||||
|  | ||||
| Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 3 +++ | ||||
|  1 file changed, 3 insertions(+) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| +	if (offset + bytes >= priv->lower * 4) | ||||
| +		dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n"); | ||||
| + | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -0,0 +1,26 @@ | ||||
| From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001 | ||||
| From: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:22 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: add nvmem type attribute | ||||
|  | ||||
| Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP | ||||
| so userspace is able to know how the data is stored in BSEC. | ||||
|  | ||||
| Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat | ||||
|  	priv->cfg.dev = dev; | ||||
|  	priv->cfg.priv = priv; | ||||
|  	priv->cfg.owner = THIS_MODULE; | ||||
| +	priv->cfg.type = NVMEM_TYPE_OTP; | ||||
|   | ||||
|  	priv->lower = 0; | ||||
|   | ||||
| @@ -0,0 +1,27 @@ | ||||
| From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001 | ||||
| From: Jiangshan Yi <yijiangshan@kylinos.cn> | ||||
| Date: Fri, 18 Nov 2022 06:39:24 +0000 | ||||
| Subject: [PATCH] nvmem: stm32: fix spelling typo in comment | ||||
|  | ||||
| Fix spelling typo in comment. | ||||
|  | ||||
| Reported-by: k2ci <kernel-bot@kylinos.cn> | ||||
| Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/stm32-romem.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/stm32-romem.c | ||||
| +++ b/drivers/nvmem/stm32-romem.c | ||||
| @@ -19,7 +19,7 @@ | ||||
|  #define STM32_SMC_WRITE_SHADOW		0x03 | ||||
|  #define STM32_SMC_READ_OTP		0x04 | ||||
|   | ||||
| -/* shadow registers offest */ | ||||
| +/* shadow registers offset */ | ||||
|  #define STM32MP15_BSEC_DATA0		0x200 | ||||
|   | ||||
|  struct stm32_romem_cfg { | ||||
| @@ -0,0 +1,27 @@ | ||||
| From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001 | ||||
| From: Colin Ian King <colin.i.king@gmail.com> | ||||
| Date: Fri, 18 Nov 2022 06:39:26 +0000 | ||||
| Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" -> | ||||
|  "controls" | ||||
|  | ||||
| There is a spelling mistake in a Kconfig description. Fix it. | ||||
|  | ||||
| Signed-off-by: Colin Ian King <colin.i.king@gmail.com> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| --- | ||||
|  drivers/nvmem/Kconfig | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/nvmem/Kconfig | ||||
| +++ b/drivers/nvmem/Kconfig | ||||
| @@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC | ||||
|  	depends on ARCH_AT91 || COMPILE_TEST | ||||
|  	help | ||||
|  	  This driver enable the OTP controller available on Microchip SAMA7G5 | ||||
| -	  SoCs. It controlls the access to the OTP memory connected to it. | ||||
| +	  SoCs. It controls the access to the OTP memory connected to it. | ||||
|   | ||||
|  config NVMEM_MTK_EFUSE | ||||
|  	tristate "Mediatek SoCs EFUSE support" | ||||
| @@ -1,6 +1,6 @@ | ||||
| From 5b4eaafbeac472fc19049152f18e88aecb2b2829 Mon Sep 17 00:00:00 2001 | ||||
| From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 17 Oct 2022 09:17:22 +0200 | ||||
| Date: Fri, 18 Nov 2022 06:39:27 +0000 | ||||
| Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| @@ -15,6 +15,8 @@ Add support for Broadcom's specific binding and their custom format. | ||||
| Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding") | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org | ||||
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | ||||
| ---
 | ||||
|  drivers/nvmem/u-boot-env.c | 14 ++++++++++++++ | ||||
|  1 file changed, 14 insertions(+) | ||||
| @@ -36,7 +36,7 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | ||||
| 
 | ||||
| --- a/drivers/nvmem/u-boot-env.c
 | ||||
| +++ b/drivers/nvmem/u-boot-env.c
 | ||||
| @@ -143,7 +143,7 @@ static int u_boot_env_parse(struct u_boo
 | ||||
| @@ -156,7 +156,7 @@ static int u_boot_env_parse(struct u_boo
 | ||||
|  	crc32_data_len = priv->mtd->size - crc32_data_offset; | ||||
|  	data_len = priv->mtd->size - data_offset; | ||||
|   | ||||
| @@ -541,6 +541,7 @@ CONFIG_NUMA=y | ||||
| CONFIG_NUMA_BALANCING=y | ||||
| CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y | ||||
| CONFIG_NVMEM=y | ||||
| # CONFIG_NVMEM_LAYERSCAPE_SFP is not set | ||||
| # CONFIG_NVMEM_SPMI_SDAM is not set | ||||
| CONFIG_NVMEM_SYSFS=y | ||||
| CONFIG_OF=y | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki