Message ID | 20210810073510.18218-1-qiangqing.zhang@nxp.com |
---|---|
Headers | show |
Series | nvmem: introduce "reverse-data" property | expand |
On 10/08/2021 08:35, Joakim Zhang wrote: > This patch intends to introduce "reverse-data" property at nvmem > provider side to reverse buffer. > > For a case used from Ethernet driver, of_get_mac_address() may call > of_get_mac_addr_nvmem() to get MAC address from nvmem device. MAC address > programed in imx-ocopt is MSB first in lowest address, so need reverse Is all the data stored in imx-ocopt reverse byte order? or someone decided to change the order for only mac-address? > data then feedback to nvmem consumer. E.g. MAC address read from > imx-ocopt is 98:e2:06:9f:04:00, after reversed the data is > 00:04:9f:06:e2:98. > > Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com> > --- > drivers/nvmem/core.c | 30 ++++++++++++++++++++++++++++++ > include/linux/nvmem-provider.h | 2 ++ > 2 files changed, 32 insertions(+) > > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > index b3bc30a04ed7..ccc2c5801c8e 100644 > --- a/drivers/nvmem/core.c > +++ b/drivers/nvmem/core.c > @@ -55,6 +55,7 @@ struct nvmem_cell { > struct device_node *np; > struct nvmem_device *nvmem; > struct list_head node; > + u32 flags; This flag also needs to go in struct nvmem_cell_info too. > }; > > static DEFINE_MUTEX(nvmem_mutex); > @@ -92,6 +93,26 @@ static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, > return -EINVAL; > } > > +static int nvmem_buffer_reverse(void *bufaddr, int len) > +{ > + u8 *buf = (u8 *)bufaddr; > + u8 *temp; > + int i; > + > + temp = kzalloc(len, GFP_KERNEL); > + if (!temp) > + return -ENOMEM; > + > + memcpy(temp, buf, len); > + > + for (i = 0; i < len; i++) > + buf[i] = temp[len - i - 1]; > + You could possibly simplify this. static void nvmem_buffer_reverse(u8 *buf, int len) { int i; for (i = 0; i < len/2; i++) swap(buf[i], buf[len - i - 1]); } > + kfree(temp); > + > + return 0; > +} > + > static int nvmem_access_with_keepouts(struct nvmem_device *nvmem, > unsigned int offset, void *val, > size_t bytes, int write) > @@ -705,6 +726,9 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) > cell->bytes = be32_to_cpup(addr); > cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); > > + if (of_property_read_bool(child, "reverse-data")) > + cell->flags |= NVMEM_FLAGS_REVERSE_DATA; > + > addr = of_get_property(child, "bits", &len); > if (addr && len == (2 * sizeof(u32))) { > cell->bit_offset = be32_to_cpup(addr++); > @@ -1398,6 +1422,12 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem, > if (cell->bit_offset || cell->nbits) > nvmem_shift_read_buffer_in_place(cell, buf); > > + if (cell->flags & NVMEM_FLAGS_REVERSE_DATA) { > + rc = nvmem_buffer_reverse(buf, cell->bytes); > + if (rc < 0) > + return rc; > + } > + > if (len) > *len = cell->bytes; > > diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h > index 104505e9028f..364ac2a61b11 100644 > --- a/include/linux/nvmem-provider.h > +++ b/include/linux/nvmem-provider.h > @@ -31,6 +31,8 @@ enum nvmem_type { > #define NVMEM_DEVID_NONE (-1) > #define NVMEM_DEVID_AUTO (-2) > > +#define NVMEM_FLAGS_REVERSE_DATA BIT(0) Maybe NVMEM_FLAGS_REVERSE_BYTE_ORDER and some kerneldoc would help new users. --srini > + > /** > * struct nvmem_keepout - NVMEM register keepout range. > * >
> -----Original Message----- > From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > Sent: 2021年8月11日 17:52 > To: Joakim Zhang <qiangqing.zhang@nxp.com>; robh+dt@kernel.org; > shawnguo@kernel.org > Cc: kernel@pengutronix.de; dl-linux-imx <linux-imx@nxp.com>; > devicetree@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH V1 2/4] nvmem: core: introduce "reverse-data" property > to reverse buffer > > > > On 10/08/2021 08:35, Joakim Zhang wrote: > > This patch intends to introduce "reverse-data" property at nvmem > > provider side to reverse buffer. > > > > For a case used from Ethernet driver, of_get_mac_address() may call > > of_get_mac_addr_nvmem() to get MAC address from nvmem device. MAC > > address programed in imx-ocopt is MSB first in lowest address, so need > > reverse > > Is all the data stored in imx-ocopt reverse byte order? No, it depends on how users program these data. > or someone decided to change the order for only mac-address? No, will not change the order for mac-address, would be consistent. > > > data then feedback to nvmem consumer. E.g. MAC address read from > > imx-ocopt is 98:e2:06:9f:04:00, after reversed the data is > > 00:04:9f:06:e2:98. > > > > Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com> > > --- > > drivers/nvmem/core.c | 30 > ++++++++++++++++++++++++++++++ > > include/linux/nvmem-provider.h | 2 ++ > > 2 files changed, 32 insertions(+) > > > > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index > > b3bc30a04ed7..ccc2c5801c8e 100644 > > --- a/drivers/nvmem/core.c > > +++ b/drivers/nvmem/core.c > > @@ -55,6 +55,7 @@ struct nvmem_cell { > > struct device_node *np; > > struct nvmem_device *nvmem; > > struct list_head node; > > + u32 flags; > > This flag also needs to go in struct nvmem_cell_info too. OK. > > }; > > > > static DEFINE_MUTEX(nvmem_mutex); > > @@ -92,6 +93,26 @@ static int __nvmem_reg_write(struct nvmem_device > *nvmem, unsigned int offset, > > return -EINVAL; > > } > > > > +static int nvmem_buffer_reverse(void *bufaddr, int len) { > > + u8 *buf = (u8 *)bufaddr; > > + u8 *temp; > > + int i; > > + > > + temp = kzalloc(len, GFP_KERNEL); > > + if (!temp) > > + return -ENOMEM; > > + > > + memcpy(temp, buf, len); > > + > > + for (i = 0; i < len; i++) > > + buf[i] = temp[len - i - 1]; > > + > > You could possibly simplify this. > > static void nvmem_buffer_reverse(u8 *buf, int len) { > int i; > > for (i = 0; i < len/2; i++) > swap(buf[i], buf[len - i - 1]); > } Thanks. > > + kfree(temp); > > + > > + return 0; > > +} > > + > > static int nvmem_access_with_keepouts(struct nvmem_device *nvmem, > > unsigned int offset, void *val, > > size_t bytes, int write) > > @@ -705,6 +726,9 @@ static int nvmem_add_cells_from_of(struct > nvmem_device *nvmem) > > cell->bytes = be32_to_cpup(addr); > > cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); > > > > + if (of_property_read_bool(child, "reverse-data")) > > + cell->flags |= NVMEM_FLAGS_REVERSE_DATA; > > + > > addr = of_get_property(child, "bits", &len); > > if (addr && len == (2 * sizeof(u32))) { > > cell->bit_offset = be32_to_cpup(addr++); @@ -1398,6 > +1422,12 @@ > > static int __nvmem_cell_read(struct nvmem_device *nvmem, > > if (cell->bit_offset || cell->nbits) > > nvmem_shift_read_buffer_in_place(cell, buf); > > > > + if (cell->flags & NVMEM_FLAGS_REVERSE_DATA) { > > + rc = nvmem_buffer_reverse(buf, cell->bytes); > > + if (rc < 0) > > + return rc; > > + } > > + > > if (len) > > *len = cell->bytes; > > > > diff --git a/include/linux/nvmem-provider.h > > b/include/linux/nvmem-provider.h index 104505e9028f..364ac2a61b11 > > 100644 > > --- a/include/linux/nvmem-provider.h > > +++ b/include/linux/nvmem-provider.h > > @@ -31,6 +31,8 @@ enum nvmem_type { > > #define NVMEM_DEVID_NONE (-1) > > #define NVMEM_DEVID_AUTO (-2) > > > > +#define NVMEM_FLAGS_REVERSE_DATA BIT(0) > > Maybe NVMEM_FLAGS_REVERSE_BYTE_ORDER and some kerneldoc would > help new users. Yes, will rename it, could you please point me where nvmem kerneldoc there to add new info? Best Regards, Joakim Zhang > --srini > > + > > /** > > * struct nvmem_keepout - NVMEM register keepout range. > > * > >