* [PATCH] arm64: Skip apply SSBS call for non SSBS system
@ 2020-08-04 14:14 Gaurav Kohli
2020-08-04 14:14 ` [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY Gaurav Kohli
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Gaurav Kohli @ 2020-08-04 14:14 UTC (permalink / raw)
To: will, linux-arm-kernel, maz
Cc: Gaurav Kohli, linux-arm-msm, linux-kernel, neeraju
In a system where no cpu's implement SSBS, for
them no need to set pstate. This might help to save
few cpu cycles during context switch.
Signed-off-by: Gaurav Kohli <gkohli@codeaurora.org>
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6089638..79f80f1 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -477,6 +477,13 @@ static void ssbs_thread_switch(struct task_struct *next)
struct pt_regs *regs = task_pt_regs(next);
/*
+ * For Targets which don't have SSBS support, they
+ * can return from here.
+ */
+ if (!IS_ENABLED(CONFIG_ARM64_SSBD))
+ return;
+
+ /*
* Nothing to do for kernel threads, but 'regs' may be junk
* (e.g. idle task) so check the flags and bail early.
*/
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center,
Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY 2020-08-04 14:14 [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli @ 2020-08-04 14:14 ` Gaurav Kohli 2020-08-04 14:25 ` Gaurav Kohli 2020-08-04 14:14 ` [PATCH] nvmem: core: add NVMEM_SYSFS Kconfig Gaurav Kohli ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Gaurav Kohli @ 2020-08-04 14:14 UTC (permalink / raw) To: will, linux-arm-kernel, maz Cc: linux-arm-msm, Srinivas Kandagatla, linux-kernel, neeraju From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Some users might not want to expose nvmem entry to sysfs and only intend to use kernel interface so add such provision. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> --- Documentation/ABI/stable/sysfs-bus-nvmem | 2 ++ drivers/nvmem/Kconfig | 5 +++++ drivers/nvmem/core.c | 11 ++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-bus-nvmem b/Documentation/ABI/stable/sysfs-bus-nvmem index 5923ab4620c5..12aab0a85fea 100644 --- a/Documentation/ABI/stable/sysfs-bus-nvmem +++ b/Documentation/ABI/stable/sysfs-bus-nvmem @@ -6,6 +6,8 @@ Description: This file allows user to read/write the raw NVMEM contents. Permissions for write to this file depends on the nvmem provider configuration. + Note: This file is not present if CONFIG_NVMEM_NO_SYSFS_ENTRY + is enabled ex: hexdump /sys/bus/nvmem/devices/qfprom0/nvmem diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 0a7a470ee859..6ab3276d287c 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -192,4 +192,9 @@ config SC27XX_EFUSE This driver can also be built as a module. If so, the module will be called nvmem-sc27xx-efuse. +config NVMEM_NO_SYSFS_ENTRY + bool "No nvmem sysfs entry" + + help + Say Yes if you do not want to add nvmem entry to sysfs. endif diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index b9a0270883a0..c70f183fe379 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -216,7 +216,7 @@ static const struct attribute_group nvmem_bin_rw_group = { .attrs = nvmem_attrs, }; -static const struct attribute_group *nvmem_rw_dev_groups[] = { +static const __maybe_unused struct attribute_group *nvmem_rw_dev_groups[] = { &nvmem_bin_rw_group, NULL, }; @@ -240,7 +240,7 @@ static const struct attribute_group nvmem_bin_ro_group = { .attrs = nvmem_attrs, }; -static const struct attribute_group *nvmem_ro_dev_groups[] = { +static const __maybe_unused struct attribute_group *nvmem_ro_dev_groups[] = { &nvmem_bin_ro_group, NULL, }; @@ -265,7 +265,7 @@ static const struct attribute_group nvmem_bin_rw_root_group = { .attrs = nvmem_attrs, }; -static const struct attribute_group *nvmem_rw_root_dev_groups[] = { +static const __maybe_unused struct attribute_group *nvmem_rw_root_dev_groups[] = { &nvmem_bin_rw_root_group, NULL, }; @@ -289,7 +289,7 @@ static const struct attribute_group nvmem_bin_ro_root_group = { .attrs = nvmem_attrs, }; -static const struct attribute_group *nvmem_ro_root_dev_groups[] = { +static const __maybe_unused struct attribute_group *nvmem_ro_root_dev_groups[] = { &nvmem_bin_ro_root_group, NULL, }; @@ -688,6 +688,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->read_only = device_property_present(config->dev, "read-only") | config->read_only; +#if !defined(CONFIG_NVMEM_NO_SYSFS_ENTRY) if (config->root_only) nvmem->dev.groups = nvmem->read_only ? nvmem_ro_root_dev_groups : @@ -696,7 +697,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->dev.groups = nvmem->read_only ? nvmem_ro_dev_groups : nvmem_rw_dev_groups; - +#endif device_initialize(&nvmem->dev); dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); -- 2.21.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY 2020-08-04 14:14 ` [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY Gaurav Kohli @ 2020-08-04 14:25 ` Gaurav Kohli 0 siblings, 0 replies; 8+ messages in thread From: Gaurav Kohli @ 2020-08-04 14:25 UTC (permalink / raw) To: will, linux-arm-kernel, maz Cc: linux-arm-msm, Srinivas Kandagatla, linux-kernel, neeraju Please ignore this patch, some problem in my git send mail. Apologies for the spam. On 8/4/2020 7:44 PM, Gaurav Kohli wrote: > From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > > Some users might not want to expose nvmem entry to sysfs and > only intend to use kernel interface so add such provision. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- > Documentation/ABI/stable/sysfs-bus-nvmem | 2 ++ > drivers/nvmem/Kconfig | 5 +++++ > drivers/nvmem/core.c | 11 ++++++----- > 3 files changed, 13 insertions(+), 5 deletions(-) > > diff --git a/Documentation/ABI/stable/sysfs-bus-nvmem > b/Documentation/ABI/stable/sysfs-bus-nvmem > index 5923ab4620c5..12aab0a85fea 100644 > --- a/Documentation/ABI/stable/sysfs-bus-nvmem > +++ b/Documentation/ABI/stable/sysfs-bus-nvmem > @@ -6,6 +6,8 @@ Description: > This file allows user to read/write the raw NVMEM contents. > Permissions for write to this file depends on the nvmem > provider configuration. > + Note: This file is not present if CONFIG_NVMEM_NO_SYSFS_ENTRY > + is enabled > > ex: > hexdump /sys/bus/nvmem/devices/qfprom0/nvmem > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig > index 0a7a470ee859..6ab3276d287c 100644 > --- a/drivers/nvmem/Kconfig > +++ b/drivers/nvmem/Kconfig > @@ -192,4 +192,9 @@ config SC27XX_EFUSE > This driver can also be built as a module. If so, the module > will be called nvmem-sc27xx-efuse. > > +config NVMEM_NO_SYSFS_ENTRY > + bool "No nvmem sysfs entry" > + > + help > + Say Yes if you do not want to add nvmem entry to sysfs. > endif > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > index b9a0270883a0..c70f183fe379 100644 > --- a/drivers/nvmem/core.c > +++ b/drivers/nvmem/core.c > @@ -216,7 +216,7 @@ static const struct attribute_group > nvmem_bin_rw_group = { > .attrs = nvmem_attrs, > }; > > -static const struct attribute_group *nvmem_rw_dev_groups[] = { > +static const __maybe_unused struct attribute_group > *nvmem_rw_dev_groups[] = { > &nvmem_bin_rw_group, > NULL, > }; > @@ -240,7 +240,7 @@ static const struct attribute_group > nvmem_bin_ro_group = { > .attrs = nvmem_attrs, > }; > > -static const struct attribute_group *nvmem_ro_dev_groups[] = { > +static const __maybe_unused struct attribute_group > *nvmem_ro_dev_groups[] = { > &nvmem_bin_ro_group, > NULL, > }; > @@ -265,7 +265,7 @@ static const struct attribute_group > nvmem_bin_rw_root_group = { > .attrs = nvmem_attrs, > }; > > -static const struct attribute_group *nvmem_rw_root_dev_groups[] = { > +static const __maybe_unused struct attribute_group > *nvmem_rw_root_dev_groups[] = { > &nvmem_bin_rw_root_group, > NULL, > }; > @@ -289,7 +289,7 @@ static const struct attribute_group > nvmem_bin_ro_root_group = { > .attrs = nvmem_attrs, > }; > > -static const struct attribute_group *nvmem_ro_root_dev_groups[] = { > +static const __maybe_unused struct attribute_group > *nvmem_ro_root_dev_groups[] = { > &nvmem_bin_ro_root_group, > NULL, > }; > @@ -688,6 +688,7 @@ struct nvmem_device *nvmem_register(const struct > nvmem_config *config) > nvmem->read_only = device_property_present(config->dev, "read-only") | > config->read_only; > > +#if !defined(CONFIG_NVMEM_NO_SYSFS_ENTRY) > if (config->root_only) > nvmem->dev.groups = nvmem->read_only ? > nvmem_ro_root_dev_groups : > @@ -696,7 +697,7 @@ struct nvmem_device *nvmem_register(const struct > nvmem_config *config) > nvmem->dev.groups = nvmem->read_only ? > nvmem_ro_dev_groups : > nvmem_rw_dev_groups; > - > +#endif > device_initialize(&nvmem->dev); > > dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); > -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] nvmem: core: add NVMEM_SYSFS Kconfig 2020-08-04 14:14 [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli 2020-08-04 14:14 ` [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY Gaurav Kohli @ 2020-08-04 14:14 ` Gaurav Kohli 2020-08-04 14:26 ` Gaurav Kohli 2020-08-11 4:48 ` [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli 2020-08-12 13:30 ` Will Deacon 3 siblings, 1 reply; 8+ messages in thread From: Gaurav Kohli @ 2020-08-04 14:14 UTC (permalink / raw) To: will, linux-arm-kernel, maz, gregkh Cc: maxime.ripard, linux-arm-msm, linux-kernel, gkohli, Srinivas Kandagatla, neeraju From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Many nvmem providers are not very keen on having default sysfs nvmem entry, as most of the usecases for them are inside kernel itself. And in some cases read/writes to some areas in nvmem are restricted and trapped at secure monitor level, so accessing them from userspace would result in board reboots. This patch adds new NVMEM_SYSFS Kconfig to make binary sysfs entry an optional one. This provision will give more flexibility to users. This patch also moves existing sysfs code to a new file so that its not compiled in when its not really required. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> --- Documentation/ABI/stable/sysfs-bus-nvmem | 2 + drivers/nvmem/Kconfig | 9 + drivers/nvmem/Makefile | 3 + drivers/nvmem/core.c | 264 +---------------------- drivers/nvmem/nvmem-sysfs.c | 256 ++++++++++++++++++++++ drivers/nvmem/nvmem.h | 62 ++++++ 6 files changed, 336 insertions(+), 260 deletions(-) create mode 100644 drivers/nvmem/nvmem-sysfs.c create mode 100644 drivers/nvmem/nvmem.h diff --git a/Documentation/ABI/stable/sysfs-bus-nvmem b/Documentation/ABI/stable/sysfs-bus-nvmem index 5923ab4620c5..9ffba8576f7b 100644 --- a/Documentation/ABI/stable/sysfs-bus-nvmem +++ b/Documentation/ABI/stable/sysfs-bus-nvmem @@ -6,6 +6,8 @@ Description: This file allows user to read/write the raw NVMEM contents. Permissions for write to this file depends on the nvmem provider configuration. + Note: This file is only present if CONFIG_NVMEM_SYSFS + is enabled ex: hexdump /sys/bus/nvmem/devices/qfprom0/nvmem diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index a90e9a1ebe55..e316811e9c04 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -13,6 +13,15 @@ menuconfig NVMEM if NVMEM +config NVMEM_SYSFS + bool "/sys/bus/nvmem/devices/*/nvmem (sysfs interface)" + depends on SYSFS + help + Say Y here to add a sysfs interface for NVMEM. + + This interface is mostly used by userspace applications to + read/write directly into nvmem. + config NVMEM_IMX_IIM tristate "i.MX IC Identification Module support" depends on ARCH_MXC || COMPILE_TEST diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index 4c7ba12a7005..c1fe4768dfef 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -6,6 +6,9 @@ obj-$(CONFIG_NVMEM) += nvmem_core.o nvmem_core-y := core.o +obj-$(CONFIG_NVMEM_SYSFS) += nvmem_sysfs.o +nvmem_sysfs-y := nvmem-sysfs.o + # Devices obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o nvmem-bcm-ocotp-y := bcm-ocotp.o diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 5abebf2128b8..c7892c3da91f 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -17,27 +17,7 @@ #include <linux/nvmem-provider.h> #include <linux/of.h> #include <linux/slab.h> - -struct nvmem_device { - struct module *owner; - struct device dev; - int stride; - int word_size; - int id; - struct kref refcnt; - size_t size; - bool read_only; - int flags; - enum nvmem_type type; - struct bin_attribute eeprom; - struct device *base_dev; - struct list_head cells; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; - void *priv; -}; - -#define FLAG_COMPAT BIT(0) +#include "nvmem.h" struct nvmem_cell { const char *name; @@ -61,18 +41,7 @@ static LIST_HEAD(nvmem_lookup_list); static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); -static const char * const nvmem_type_str[] = { - [NVMEM_TYPE_UNKNOWN] = "Unknown", - [NVMEM_TYPE_EEPROM] = "EEPROM", - [NVMEM_TYPE_OTP] = "OTP", - [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed", -}; - -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static struct lock_class_key eeprom_lock_key; -#endif -#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, void *val, size_t bytes) { @@ -91,187 +60,6 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, return -EINVAL; } -static ssize_t type_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct nvmem_device *nvmem = to_nvmem_device(dev); - - return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); -} - -static DEVICE_ATTR_RO(type); - -static struct attribute *nvmem_attrs[] = { - &dev_attr_type.attr, - NULL, -}; - -static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t pos, size_t count) -{ - struct device *dev; - struct nvmem_device *nvmem; - int rc; - - if (attr->private) - dev = attr->private; - else - dev = container_of(kobj, struct device, kobj); - nvmem = to_nvmem_device(dev); - - /* Stop the user from reading */ - if (pos >= nvmem->size) - return 0; - - if (count < nvmem->word_size) - return -EINVAL; - - if (pos + count > nvmem->size) - count = nvmem->size - pos; - - count = round_down(count, nvmem->word_size); - - rc = nvmem_reg_read(nvmem, pos, buf, count); - - if (rc) - return rc; - - return count; -} - -static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t pos, size_t count) -{ - struct device *dev; - struct nvmem_device *nvmem; - int rc; - - if (attr->private) - dev = attr->private; - else - dev = container_of(kobj, struct device, kobj); - nvmem = to_nvmem_device(dev); - - /* Stop the user from writing */ - if (pos >= nvmem->size) - return -EFBIG; - - if (count < nvmem->word_size) - return -EINVAL; - - if (pos + count > nvmem->size) - count = nvmem->size - pos; - - count = round_down(count, nvmem->word_size); - - rc = nvmem_reg_write(nvmem, pos, buf, count); - - if (rc) - return rc; - - return count; -} - -/* default read/write permissions */ -static struct bin_attribute bin_attr_rw_nvmem = { - .attr = { - .name = "nvmem", - .mode = 0644, - }, - .read = bin_attr_nvmem_read, - .write = bin_attr_nvmem_write, -}; - -static struct bin_attribute *nvmem_bin_rw_attributes[] = { - &bin_attr_rw_nvmem, - NULL, -}; - -static const struct attribute_group nvmem_bin_rw_group = { - .bin_attrs = nvmem_bin_rw_attributes, - .attrs = nvmem_attrs, -}; - -static const struct attribute_group *nvmem_rw_dev_groups[] = { - &nvmem_bin_rw_group, - NULL, -}; - -/* read only permission */ -static struct bin_attribute bin_attr_ro_nvmem = { - .attr = { - .name = "nvmem", - .mode = 0444, - }, - .read = bin_attr_nvmem_read, -}; - -static struct bin_attribute *nvmem_bin_ro_attributes[] = { - &bin_attr_ro_nvmem, - NULL, -}; - -static const struct attribute_group nvmem_bin_ro_group = { - .bin_attrs = nvmem_bin_ro_attributes, - .attrs = nvmem_attrs, -}; - -static const struct attribute_group *nvmem_ro_dev_groups[] = { - &nvmem_bin_ro_group, - NULL, -}; - -/* default read/write permissions, root only */ -static struct bin_attribute bin_attr_rw_root_nvmem = { - .attr = { - .name = "nvmem", - .mode = 0600, - }, - .read = bin_attr_nvmem_read, - .write = bin_attr_nvmem_write, -}; - -static struct bin_attribute *nvmem_bin_rw_root_attributes[] = { - &bin_attr_rw_root_nvmem, - NULL, -}; - -static const struct attribute_group nvmem_bin_rw_root_group = { - .bin_attrs = nvmem_bin_rw_root_attributes, - .attrs = nvmem_attrs, -}; - -static const struct attribute_group *nvmem_rw_root_dev_groups[] = { - &nvmem_bin_rw_root_group, - NULL, -}; - -/* read only permission, root only */ -static struct bin_attribute bin_attr_ro_root_nvmem = { - .attr = { - .name = "nvmem", - .mode = 0400, - }, - .read = bin_attr_nvmem_read, -}; - -static struct bin_attribute *nvmem_bin_ro_root_attributes[] = { - &bin_attr_ro_root_nvmem, - NULL, -}; - -static const struct attribute_group nvmem_bin_ro_root_group = { - .bin_attrs = nvmem_bin_ro_root_attributes, - .attrs = nvmem_attrs, -}; - -static const struct attribute_group *nvmem_ro_root_dev_groups[] = { - &nvmem_bin_ro_root_group, - NULL, -}; - static void nvmem_release(struct device *dev) { struct nvmem_device *nvmem = to_nvmem_device(dev); @@ -422,43 +210,6 @@ static int nvmem_add_cells(struct nvmem_device *nvmem, return rval; } -/* - * nvmem_setup_compat() - Create an additional binary entry in - * drivers sys directory, to be backwards compatible with the older - * drivers/misc/eeprom drivers. - */ -static int nvmem_setup_compat(struct nvmem_device *nvmem, - const struct nvmem_config *config) -{ - int rval; - - if (!config->base_dev) - return -EINVAL; - - if (nvmem->read_only) - nvmem->eeprom = bin_attr_ro_root_nvmem; - else - nvmem->eeprom = bin_attr_rw_root_nvmem; - nvmem->eeprom.attr.name = "eeprom"; - nvmem->eeprom.size = nvmem->size; -#ifdef CONFIG_DEBUG_LOCK_ALLOC - nvmem->eeprom.attr.key = &eeprom_lock_key; -#endif - nvmem->eeprom.private = &nvmem->dev; - nvmem->base_dev = config->base_dev; - - rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom); - if (rval) { - dev_err(&nvmem->dev, - "Failed to create eeprom binary file %d\n", rval); - return rval; - } - - nvmem->flags |= FLAG_COMPAT; - - return 0; -} - /** * nvmem_register_notifier() - Register a notifier block for nvmem events. * @@ -651,14 +402,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->read_only = device_property_present(config->dev, "read-only") || config->read_only || !nvmem->reg_write; - if (config->root_only) - nvmem->dev.groups = nvmem->read_only ? - nvmem_ro_root_dev_groups : - nvmem_rw_root_dev_groups; - else - nvmem->dev.groups = nvmem->read_only ? - nvmem_ro_dev_groups : - nvmem_rw_dev_groups; + nvmem->dev.groups = nvmem_sysfs_get_groups(nvmem, config); device_initialize(&nvmem->dev); @@ -669,7 +413,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) goto err_put_device; if (config->compat) { - rval = nvmem_setup_compat(nvmem, config); + rval = nvmem_sysfs_setup_compat(nvmem, config); if (rval) goto err_device_del; } @@ -696,7 +440,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem_device_remove_all_cells(nvmem); err_teardown_compat: if (config->compat) - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); + nvmem_sysfs_remove_compat(nvmem, config); err_device_del: device_del(&nvmem->dev); err_put_device: diff --git a/drivers/nvmem/nvmem-sysfs.c b/drivers/nvmem/nvmem-sysfs.c new file mode 100644 index 000000000000..6f303b91f6e7 --- /dev/null +++ b/drivers/nvmem/nvmem-sysfs.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Linaro Limited + */ +#include "nvmem.h" + +static const char * const nvmem_type_str[] = { + [NVMEM_TYPE_UNKNOWN] = "Unknown", + [NVMEM_TYPE_EEPROM] = "EEPROM", + [NVMEM_TYPE_OTP] = "OTP", + [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed", +}; + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +static struct lock_class_key eeprom_lock_key; +#endif + +static ssize_t type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvmem_device *nvmem = to_nvmem_device(dev); + + return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); +} + +static DEVICE_ATTR_RO(type); + +static struct attribute *nvmem_attrs[] = { + &dev_attr_type.attr, + NULL, +}; + +static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t pos, size_t count) +{ + struct device *dev; + struct nvmem_device *nvmem; + int rc; + + if (attr->private) + dev = attr->private; + else + dev = container_of(kobj, struct device, kobj); + nvmem = to_nvmem_device(dev); + + /* Stop the user from reading */ + if (pos >= nvmem->size) + return 0; + + if (count < nvmem->word_size) + return -EINVAL; + + if (pos + count > nvmem->size) + count = nvmem->size - pos; + + count = round_down(count, nvmem->word_size); + + rc = nvmem->reg_read(nvmem->priv, pos, buf, count); + + if (rc) + return rc; + + return count; +} + +static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t pos, size_t count) +{ + struct device *dev; + struct nvmem_device *nvmem; + int rc; + + if (attr->private) + dev = attr->private; + else + dev = container_of(kobj, struct device, kobj); + nvmem = to_nvmem_device(dev); + + /* Stop the user from writing */ + if (pos >= nvmem->size) + return -EFBIG; + + if (count < nvmem->word_size) + return -EINVAL; + + if (pos + count > nvmem->size) + count = nvmem->size - pos; + + count = round_down(count, nvmem->word_size); + + rc = nvmem->reg_write(nvmem->priv, pos, buf, count); + + if (rc) + return rc; + + return count; +} + +/* default read/write permissions */ +static struct bin_attribute bin_attr_rw_nvmem = { + .attr = { + .name = "nvmem", + .mode = 0644, + }, + .read = bin_attr_nvmem_read, + .write = bin_attr_nvmem_write, +}; + +static struct bin_attribute *nvmem_bin_rw_attributes[] = { + &bin_attr_rw_nvmem, + NULL, +}; + +static const struct attribute_group nvmem_bin_rw_group = { + .bin_attrs = nvmem_bin_rw_attributes, + .attrs = nvmem_attrs, +}; + +static const struct attribute_group *nvmem_rw_dev_groups[] = { + &nvmem_bin_rw_group, + NULL, +}; + +/* read only permission */ +static struct bin_attribute bin_attr_ro_nvmem = { + .attr = { + .name = "nvmem", + .mode = 0444, + }, + .read = bin_attr_nvmem_read, +}; + +static struct bin_attribute *nvmem_bin_ro_attributes[] = { + &bin_attr_ro_nvmem, + NULL, +}; + +static const struct attribute_group nvmem_bin_ro_group = { + .bin_attrs = nvmem_bin_ro_attributes, + .attrs = nvmem_attrs, +}; + +static const struct attribute_group *nvmem_ro_dev_groups[] = { + &nvmem_bin_ro_group, + NULL, +}; + +/* default read/write permissions, root only */ +static struct bin_attribute bin_attr_rw_root_nvmem = { + .attr = { + .name = "nvmem", + .mode = 0600, + }, + .read = bin_attr_nvmem_read, + .write = bin_attr_nvmem_write, +}; + +static struct bin_attribute *nvmem_bin_rw_root_attributes[] = { + &bin_attr_rw_root_nvmem, + NULL, +}; + +static const struct attribute_group nvmem_bin_rw_root_group = { + .bin_attrs = nvmem_bin_rw_root_attributes, + .attrs = nvmem_attrs, +}; + +static const struct attribute_group *nvmem_rw_root_dev_groups[] = { + &nvmem_bin_rw_root_group, + NULL, +}; + +/* read only permission, root only */ +static struct bin_attribute bin_attr_ro_root_nvmem = { + .attr = { + .name = "nvmem", + .mode = 0400, + }, + .read = bin_attr_nvmem_read, +}; + +static struct bin_attribute *nvmem_bin_ro_root_attributes[] = { + &bin_attr_ro_root_nvmem, + NULL, +}; + +static const struct attribute_group nvmem_bin_ro_root_group = { + .bin_attrs = nvmem_bin_ro_root_attributes, + .attrs = nvmem_attrs, +}; + +static const struct attribute_group *nvmem_ro_root_dev_groups[] = { + &nvmem_bin_ro_root_group, + NULL, +}; + +const struct attribute_group **nvmem_sysfs_get_groups( + struct nvmem_device *nvmem, + const struct nvmem_config *config) +{ + if (config->root_only) + return nvmem->read_only ? + nvmem_ro_root_dev_groups : + nvmem_rw_root_dev_groups; + + return nvmem->read_only ? nvmem_ro_dev_groups : nvmem_rw_dev_groups; +} + +/* + * nvmem_setup_compat() - Create an additional binary entry in + * drivers sys directory, to be backwards compatible with the older + * drivers/misc/eeprom drivers. + */ +int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, + const struct nvmem_config *config) +{ + int rval; + + if (!config->compat) + return 0; + + if (!config->base_dev) + return -EINVAL; + + if (nvmem->read_only) + nvmem->eeprom = bin_attr_ro_root_nvmem; + else + nvmem->eeprom = bin_attr_rw_root_nvmem; + nvmem->eeprom.attr.name = "eeprom"; + nvmem->eeprom.size = nvmem->size; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + nvmem->eeprom.attr.key = &eeprom_lock_key; +#endif + nvmem->eeprom.private = &nvmem->dev; + nvmem->base_dev = config->base_dev; + + rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom); + if (rval) { + dev_err(&nvmem->dev, + "Failed to create eeprom binary file %d\n", rval); + return rval; + } + + nvmem->flags |= FLAG_COMPAT; + + return 0; +} + +void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, + const struct nvmem_config *config) +{ + if (config->compat) + device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); +} diff --git a/drivers/nvmem/nvmem.h b/drivers/nvmem/nvmem.h new file mode 100644 index 000000000000..eb8ed7121fa3 --- /dev/null +++ b/drivers/nvmem/nvmem.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DRIVERS_NVMEM_H +#define _DRIVERS_NVMEM_H + +#include <linux/device.h> +#include <linux/fs.h> +#include <linux/kref.h> +#include <linux/list.h> +#include <linux/nvmem-consumer.h> +#include <linux/nvmem-provider.h> + +struct nvmem_device { + struct module *owner; + struct device dev; + int stride; + int word_size; + int id; + struct kref refcnt; + size_t size; + bool read_only; + int flags; + enum nvmem_type type; + struct bin_attribute eeprom; + struct device *base_dev; + struct list_head cells; + nvmem_reg_read_t reg_read; + nvmem_reg_write_t reg_write; + void *priv; +}; + +#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) +#define FLAG_COMPAT BIT(0) + +#ifdef CONFIG_NVMEM_SYSFS +const struct attribute_group **nvmem_sysfs_get_groups( + struct nvmem_device *nvmem, + const struct nvmem_config *config); +int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, + const struct nvmem_config *config); +void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, + const struct nvmem_config *config); +#else +static inline const struct attribute_group **nvmem_sysfs_get_groups( + struct nvmem_device *nvmem, + const struct nvmem_config *config) +{ + return NULL; +} + +static inline int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, + const struct nvmem_config *config) +{ + return -ENOSYS; +} +static inline void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, + const struct nvmem_config *config) +{ +} +#endif /* CONFIG_NVMEM_SYSFS */ + +#endif /* _DRIVERS_NVMEM_H */ _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] nvmem: core: add NVMEM_SYSFS Kconfig 2020-08-04 14:14 ` [PATCH] nvmem: core: add NVMEM_SYSFS Kconfig Gaurav Kohli @ 2020-08-04 14:26 ` Gaurav Kohli 0 siblings, 0 replies; 8+ messages in thread From: Gaurav Kohli @ 2020-08-04 14:26 UTC (permalink / raw) To: will, linux-arm-kernel, maz, gregkh Cc: maxime.ripard, linux-arm-msm, Srinivas Kandagatla, linux-kernel, neeraju Please ignore this patch also, sent due to git send mistake. Apologies for the spam. On 8/4/2020 7:44 PM, Gaurav Kohli wrote: > From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > > Many nvmem providers are not very keen on having default sysfs > nvmem entry, as most of the usecases for them are inside kernel > itself. And in some cases read/writes to some areas in nvmem are > restricted and trapped at secure monitor level, so accessing them > from userspace would result in board reboots. > > This patch adds new NVMEM_SYSFS Kconfig to make binary sysfs entry > an optional one. This provision will give more flexibility to users. > This patch also moves existing sysfs code to a new file so that its > not compiled in when its not really required. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> > --- > Documentation/ABI/stable/sysfs-bus-nvmem | 2 + > drivers/nvmem/Kconfig | 9 + > drivers/nvmem/Makefile | 3 + > drivers/nvmem/core.c | 264 +---------------------- > drivers/nvmem/nvmem-sysfs.c | 256 ++++++++++++++++++++++ > drivers/nvmem/nvmem.h | 62 ++++++ > 6 files changed, 336 insertions(+), 260 deletions(-) > create mode 100644 drivers/nvmem/nvmem-sysfs.c > create mode 100644 drivers/nvmem/nvmem.h > > diff --git a/Documentation/ABI/stable/sysfs-bus-nvmem b/Documentation/ABI/stable/sysfs-bus-nvmem > index 5923ab4620c5..9ffba8576f7b 100644 > --- a/Documentation/ABI/stable/sysfs-bus-nvmem > +++ b/Documentation/ABI/stable/sysfs-bus-nvmem > @@ -6,6 +6,8 @@ Description: > This file allows user to read/write the raw NVMEM contents. > Permissions for write to this file depends on the nvmem > provider configuration. > + Note: This file is only present if CONFIG_NVMEM_SYSFS > + is enabled > > ex: > hexdump /sys/bus/nvmem/devices/qfprom0/nvmem > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig > index a90e9a1ebe55..e316811e9c04 100644 > --- a/drivers/nvmem/Kconfig > +++ b/drivers/nvmem/Kconfig > @@ -13,6 +13,15 @@ menuconfig NVMEM > > if NVMEM > > +config NVMEM_SYSFS > + bool "/sys/bus/nvmem/devices/*/nvmem (sysfs interface)" > + depends on SYSFS > + help > + Say Y here to add a sysfs interface for NVMEM. > + > + This interface is mostly used by userspace applications to > + read/write directly into nvmem. > + > config NVMEM_IMX_IIM > tristate "i.MX IC Identification Module support" > depends on ARCH_MXC || COMPILE_TEST > diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile > index 4c7ba12a7005..c1fe4768dfef 100644 > --- a/drivers/nvmem/Makefile > +++ b/drivers/nvmem/Makefile > @@ -6,6 +6,9 @@ > obj-$(CONFIG_NVMEM) += nvmem_core.o > nvmem_core-y := core.o > > +obj-$(CONFIG_NVMEM_SYSFS) += nvmem_sysfs.o > +nvmem_sysfs-y := nvmem-sysfs.o > + > # Devices > obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o > nvmem-bcm-ocotp-y := bcm-ocotp.o > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > index 5abebf2128b8..c7892c3da91f 100644 > --- a/drivers/nvmem/core.c > +++ b/drivers/nvmem/core.c > @@ -17,27 +17,7 @@ > #include <linux/nvmem-provider.h> > #include <linux/of.h> > #include <linux/slab.h> > - > -struct nvmem_device { > - struct module *owner; > - struct device dev; > - int stride; > - int word_size; > - int id; > - struct kref refcnt; > - size_t size; > - bool read_only; > - int flags; > - enum nvmem_type type; > - struct bin_attribute eeprom; > - struct device *base_dev; > - struct list_head cells; > - nvmem_reg_read_t reg_read; > - nvmem_reg_write_t reg_write; > - void *priv; > -}; > - > -#define FLAG_COMPAT BIT(0) > +#include "nvmem.h" > > struct nvmem_cell { > const char *name; > @@ -61,18 +41,7 @@ static LIST_HEAD(nvmem_lookup_list); > > static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); > > -static const char * const nvmem_type_str[] = { > - [NVMEM_TYPE_UNKNOWN] = "Unknown", > - [NVMEM_TYPE_EEPROM] = "EEPROM", > - [NVMEM_TYPE_OTP] = "OTP", > - [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed", > -}; > - > -#ifdef CONFIG_DEBUG_LOCK_ALLOC > -static struct lock_class_key eeprom_lock_key; > -#endif > > -#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) > static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, > void *val, size_t bytes) > { > @@ -91,187 +60,6 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, > return -EINVAL; > } > > -static ssize_t type_show(struct device *dev, > - struct device_attribute *attr, char *buf) > -{ > - struct nvmem_device *nvmem = to_nvmem_device(dev); > - > - return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); > -} > - > -static DEVICE_ATTR_RO(type); > - > -static struct attribute *nvmem_attrs[] = { > - &dev_attr_type.attr, > - NULL, > -}; > - > -static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, > - struct bin_attribute *attr, > - char *buf, loff_t pos, size_t count) > -{ > - struct device *dev; > - struct nvmem_device *nvmem; > - int rc; > - > - if (attr->private) > - dev = attr->private; > - else > - dev = container_of(kobj, struct device, kobj); > - nvmem = to_nvmem_device(dev); > - > - /* Stop the user from reading */ > - if (pos >= nvmem->size) > - return 0; > - > - if (count < nvmem->word_size) > - return -EINVAL; > - > - if (pos + count > nvmem->size) > - count = nvmem->size - pos; > - > - count = round_down(count, nvmem->word_size); > - > - rc = nvmem_reg_read(nvmem, pos, buf, count); > - > - if (rc) > - return rc; > - > - return count; > -} > - > -static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, > - struct bin_attribute *attr, > - char *buf, loff_t pos, size_t count) > -{ > - struct device *dev; > - struct nvmem_device *nvmem; > - int rc; > - > - if (attr->private) > - dev = attr->private; > - else > - dev = container_of(kobj, struct device, kobj); > - nvmem = to_nvmem_device(dev); > - > - /* Stop the user from writing */ > - if (pos >= nvmem->size) > - return -EFBIG; > - > - if (count < nvmem->word_size) > - return -EINVAL; > - > - if (pos + count > nvmem->size) > - count = nvmem->size - pos; > - > - count = round_down(count, nvmem->word_size); > - > - rc = nvmem_reg_write(nvmem, pos, buf, count); > - > - if (rc) > - return rc; > - > - return count; > -} > - > -/* default read/write permissions */ > -static struct bin_attribute bin_attr_rw_nvmem = { > - .attr = { > - .name = "nvmem", > - .mode = 0644, > - }, > - .read = bin_attr_nvmem_read, > - .write = bin_attr_nvmem_write, > -}; > - > -static struct bin_attribute *nvmem_bin_rw_attributes[] = { > - &bin_attr_rw_nvmem, > - NULL, > -}; > - > -static const struct attribute_group nvmem_bin_rw_group = { > - .bin_attrs = nvmem_bin_rw_attributes, > - .attrs = nvmem_attrs, > -}; > - > -static const struct attribute_group *nvmem_rw_dev_groups[] = { > - &nvmem_bin_rw_group, > - NULL, > -}; > - > -/* read only permission */ > -static struct bin_attribute bin_attr_ro_nvmem = { > - .attr = { > - .name = "nvmem", > - .mode = 0444, > - }, > - .read = bin_attr_nvmem_read, > -}; > - > -static struct bin_attribute *nvmem_bin_ro_attributes[] = { > - &bin_attr_ro_nvmem, > - NULL, > -}; > - > -static const struct attribute_group nvmem_bin_ro_group = { > - .bin_attrs = nvmem_bin_ro_attributes, > - .attrs = nvmem_attrs, > -}; > - > -static const struct attribute_group *nvmem_ro_dev_groups[] = { > - &nvmem_bin_ro_group, > - NULL, > -}; > - > -/* default read/write permissions, root only */ > -static struct bin_attribute bin_attr_rw_root_nvmem = { > - .attr = { > - .name = "nvmem", > - .mode = 0600, > - }, > - .read = bin_attr_nvmem_read, > - .write = bin_attr_nvmem_write, > -}; > - > -static struct bin_attribute *nvmem_bin_rw_root_attributes[] = { > - &bin_attr_rw_root_nvmem, > - NULL, > -}; > - > -static const struct attribute_group nvmem_bin_rw_root_group = { > - .bin_attrs = nvmem_bin_rw_root_attributes, > - .attrs = nvmem_attrs, > -}; > - > -static const struct attribute_group *nvmem_rw_root_dev_groups[] = { > - &nvmem_bin_rw_root_group, > - NULL, > -}; > - > -/* read only permission, root only */ > -static struct bin_attribute bin_attr_ro_root_nvmem = { > - .attr = { > - .name = "nvmem", > - .mode = 0400, > - }, > - .read = bin_attr_nvmem_read, > -}; > - > -static struct bin_attribute *nvmem_bin_ro_root_attributes[] = { > - &bin_attr_ro_root_nvmem, > - NULL, > -}; > - > -static const struct attribute_group nvmem_bin_ro_root_group = { > - .bin_attrs = nvmem_bin_ro_root_attributes, > - .attrs = nvmem_attrs, > -}; > - > -static const struct attribute_group *nvmem_ro_root_dev_groups[] = { > - &nvmem_bin_ro_root_group, > - NULL, > -}; > - > static void nvmem_release(struct device *dev) > { > struct nvmem_device *nvmem = to_nvmem_device(dev); > @@ -422,43 +210,6 @@ static int nvmem_add_cells(struct nvmem_device *nvmem, > return rval; > } > > -/* > - * nvmem_setup_compat() - Create an additional binary entry in > - * drivers sys directory, to be backwards compatible with the older > - * drivers/misc/eeprom drivers. > - */ > -static int nvmem_setup_compat(struct nvmem_device *nvmem, > - const struct nvmem_config *config) > -{ > - int rval; > - > - if (!config->base_dev) > - return -EINVAL; > - > - if (nvmem->read_only) > - nvmem->eeprom = bin_attr_ro_root_nvmem; > - else > - nvmem->eeprom = bin_attr_rw_root_nvmem; > - nvmem->eeprom.attr.name = "eeprom"; > - nvmem->eeprom.size = nvmem->size; > -#ifdef CONFIG_DEBUG_LOCK_ALLOC > - nvmem->eeprom.attr.key = &eeprom_lock_key; > -#endif > - nvmem->eeprom.private = &nvmem->dev; > - nvmem->base_dev = config->base_dev; > - > - rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom); > - if (rval) { > - dev_err(&nvmem->dev, > - "Failed to create eeprom binary file %d\n", rval); > - return rval; > - } > - > - nvmem->flags |= FLAG_COMPAT; > - > - return 0; > -} > - > /** > * nvmem_register_notifier() - Register a notifier block for nvmem events. > * > @@ -651,14 +402,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) > nvmem->read_only = device_property_present(config->dev, "read-only") || > config->read_only || !nvmem->reg_write; > > - if (config->root_only) > - nvmem->dev.groups = nvmem->read_only ? > - nvmem_ro_root_dev_groups : > - nvmem_rw_root_dev_groups; > - else > - nvmem->dev.groups = nvmem->read_only ? > - nvmem_ro_dev_groups : > - nvmem_rw_dev_groups; > + nvmem->dev.groups = nvmem_sysfs_get_groups(nvmem, config); > > device_initialize(&nvmem->dev); > > @@ -669,7 +413,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) > goto err_put_device; > > if (config->compat) { > - rval = nvmem_setup_compat(nvmem, config); > + rval = nvmem_sysfs_setup_compat(nvmem, config); > if (rval) > goto err_device_del; > } > @@ -696,7 +440,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) > nvmem_device_remove_all_cells(nvmem); > err_teardown_compat: > if (config->compat) > - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); > + nvmem_sysfs_remove_compat(nvmem, config); > err_device_del: > device_del(&nvmem->dev); > err_put_device: > diff --git a/drivers/nvmem/nvmem-sysfs.c b/drivers/nvmem/nvmem-sysfs.c > new file mode 100644 > index 000000000000..6f303b91f6e7 > --- /dev/null > +++ b/drivers/nvmem/nvmem-sysfs.c > @@ -0,0 +1,256 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2019, Linaro Limited > + */ > +#include "nvmem.h" > + > +static const char * const nvmem_type_str[] = { > + [NVMEM_TYPE_UNKNOWN] = "Unknown", > + [NVMEM_TYPE_EEPROM] = "EEPROM", > + [NVMEM_TYPE_OTP] = "OTP", > + [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed", > +}; > + > +#ifdef CONFIG_DEBUG_LOCK_ALLOC > +static struct lock_class_key eeprom_lock_key; > +#endif > + > +static ssize_t type_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct nvmem_device *nvmem = to_nvmem_device(dev); > + > + return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); > +} > + > +static DEVICE_ATTR_RO(type); > + > +static struct attribute *nvmem_attrs[] = { > + &dev_attr_type.attr, > + NULL, > +}; > + > +static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj, > + struct bin_attribute *attr, > + char *buf, loff_t pos, size_t count) > +{ > + struct device *dev; > + struct nvmem_device *nvmem; > + int rc; > + > + if (attr->private) > + dev = attr->private; > + else > + dev = container_of(kobj, struct device, kobj); > + nvmem = to_nvmem_device(dev); > + > + /* Stop the user from reading */ > + if (pos >= nvmem->size) > + return 0; > + > + if (count < nvmem->word_size) > + return -EINVAL; > + > + if (pos + count > nvmem->size) > + count = nvmem->size - pos; > + > + count = round_down(count, nvmem->word_size); > + > + rc = nvmem->reg_read(nvmem->priv, pos, buf, count); > + > + if (rc) > + return rc; > + > + return count; > +} > + > +static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, > + struct bin_attribute *attr, > + char *buf, loff_t pos, size_t count) > +{ > + struct device *dev; > + struct nvmem_device *nvmem; > + int rc; > + > + if (attr->private) > + dev = attr->private; > + else > + dev = container_of(kobj, struct device, kobj); > + nvmem = to_nvmem_device(dev); > + > + /* Stop the user from writing */ > + if (pos >= nvmem->size) > + return -EFBIG; > + > + if (count < nvmem->word_size) > + return -EINVAL; > + > + if (pos + count > nvmem->size) > + count = nvmem->size - pos; > + > + count = round_down(count, nvmem->word_size); > + > + rc = nvmem->reg_write(nvmem->priv, pos, buf, count); > + > + if (rc) > + return rc; > + > + return count; > +} > + > +/* default read/write permissions */ > +static struct bin_attribute bin_attr_rw_nvmem = { > + .attr = { > + .name = "nvmem", > + .mode = 0644, > + }, > + .read = bin_attr_nvmem_read, > + .write = bin_attr_nvmem_write, > +}; > + > +static struct bin_attribute *nvmem_bin_rw_attributes[] = { > + &bin_attr_rw_nvmem, > + NULL, > +}; > + > +static const struct attribute_group nvmem_bin_rw_group = { > + .bin_attrs = nvmem_bin_rw_attributes, > + .attrs = nvmem_attrs, > +}; > + > +static const struct attribute_group *nvmem_rw_dev_groups[] = { > + &nvmem_bin_rw_group, > + NULL, > +}; > + > +/* read only permission */ > +static struct bin_attribute bin_attr_ro_nvmem = { > + .attr = { > + .name = "nvmem", > + .mode = 0444, > + }, > + .read = bin_attr_nvmem_read, > +}; > + > +static struct bin_attribute *nvmem_bin_ro_attributes[] = { > + &bin_attr_ro_nvmem, > + NULL, > +}; > + > +static const struct attribute_group nvmem_bin_ro_group = { > + .bin_attrs = nvmem_bin_ro_attributes, > + .attrs = nvmem_attrs, > +}; > + > +static const struct attribute_group *nvmem_ro_dev_groups[] = { > + &nvmem_bin_ro_group, > + NULL, > +}; > + > +/* default read/write permissions, root only */ > +static struct bin_attribute bin_attr_rw_root_nvmem = { > + .attr = { > + .name = "nvmem", > + .mode = 0600, > + }, > + .read = bin_attr_nvmem_read, > + .write = bin_attr_nvmem_write, > +}; > + > +static struct bin_attribute *nvmem_bin_rw_root_attributes[] = { > + &bin_attr_rw_root_nvmem, > + NULL, > +}; > + > +static const struct attribute_group nvmem_bin_rw_root_group = { > + .bin_attrs = nvmem_bin_rw_root_attributes, > + .attrs = nvmem_attrs, > +}; > + > +static const struct attribute_group *nvmem_rw_root_dev_groups[] = { > + &nvmem_bin_rw_root_group, > + NULL, > +}; > + > +/* read only permission, root only */ > +static struct bin_attribute bin_attr_ro_root_nvmem = { > + .attr = { > + .name = "nvmem", > + .mode = 0400, > + }, > + .read = bin_attr_nvmem_read, > +}; > + > +static struct bin_attribute *nvmem_bin_ro_root_attributes[] = { > + &bin_attr_ro_root_nvmem, > + NULL, > +}; > + > +static const struct attribute_group nvmem_bin_ro_root_group = { > + .bin_attrs = nvmem_bin_ro_root_attributes, > + .attrs = nvmem_attrs, > +}; > + > +static const struct attribute_group *nvmem_ro_root_dev_groups[] = { > + &nvmem_bin_ro_root_group, > + NULL, > +}; > + > +const struct attribute_group **nvmem_sysfs_get_groups( > + struct nvmem_device *nvmem, > + const struct nvmem_config *config) > +{ > + if (config->root_only) > + return nvmem->read_only ? > + nvmem_ro_root_dev_groups : > + nvmem_rw_root_dev_groups; > + > + return nvmem->read_only ? nvmem_ro_dev_groups : nvmem_rw_dev_groups; > +} > + > +/* > + * nvmem_setup_compat() - Create an additional binary entry in > + * drivers sys directory, to be backwards compatible with the older > + * drivers/misc/eeprom drivers. > + */ > +int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, > + const struct nvmem_config *config) > +{ > + int rval; > + > + if (!config->compat) > + return 0; > + > + if (!config->base_dev) > + return -EINVAL; > + > + if (nvmem->read_only) > + nvmem->eeprom = bin_attr_ro_root_nvmem; > + else > + nvmem->eeprom = bin_attr_rw_root_nvmem; > + nvmem->eeprom.attr.name = "eeprom"; > + nvmem->eeprom.size = nvmem->size; > +#ifdef CONFIG_DEBUG_LOCK_ALLOC > + nvmem->eeprom.attr.key = &eeprom_lock_key; > +#endif > + nvmem->eeprom.private = &nvmem->dev; > + nvmem->base_dev = config->base_dev; > + > + rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom); > + if (rval) { > + dev_err(&nvmem->dev, > + "Failed to create eeprom binary file %d\n", rval); > + return rval; > + } > + > + nvmem->flags |= FLAG_COMPAT; > + > + return 0; > +} > + > +void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, > + const struct nvmem_config *config) > +{ > + if (config->compat) > + device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); > +} > diff --git a/drivers/nvmem/nvmem.h b/drivers/nvmem/nvmem.h > new file mode 100644 > index 000000000000..eb8ed7121fa3 > --- /dev/null > +++ b/drivers/nvmem/nvmem.h > @@ -0,0 +1,62 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +#ifndef _DRIVERS_NVMEM_H > +#define _DRIVERS_NVMEM_H > + > +#include <linux/device.h> > +#include <linux/fs.h> > +#include <linux/kref.h> > +#include <linux/list.h> > +#include <linux/nvmem-consumer.h> > +#include <linux/nvmem-provider.h> > + > +struct nvmem_device { > + struct module *owner; > + struct device dev; > + int stride; > + int word_size; > + int id; > + struct kref refcnt; > + size_t size; > + bool read_only; > + int flags; > + enum nvmem_type type; > + struct bin_attribute eeprom; > + struct device *base_dev; > + struct list_head cells; > + nvmem_reg_read_t reg_read; > + nvmem_reg_write_t reg_write; > + void *priv; > +}; > + > +#define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) > +#define FLAG_COMPAT BIT(0) > + > +#ifdef CONFIG_NVMEM_SYSFS > +const struct attribute_group **nvmem_sysfs_get_groups( > + struct nvmem_device *nvmem, > + const struct nvmem_config *config); > +int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, > + const struct nvmem_config *config); > +void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, > + const struct nvmem_config *config); > +#else > +static inline const struct attribute_group **nvmem_sysfs_get_groups( > + struct nvmem_device *nvmem, > + const struct nvmem_config *config) > +{ > + return NULL; > +} > + > +static inline int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, > + const struct nvmem_config *config) > +{ > + return -ENOSYS; > +} > +static inline void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem, > + const struct nvmem_config *config) > +{ > +} > +#endif /* CONFIG_NVMEM_SYSFS */ > + > +#endif /* _DRIVERS_NVMEM_H */ > -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] arm64: Skip apply SSBS call for non SSBS system 2020-08-04 14:14 [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli 2020-08-04 14:14 ` [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY Gaurav Kohli 2020-08-04 14:14 ` [PATCH] nvmem: core: add NVMEM_SYSFS Kconfig Gaurav Kohli @ 2020-08-11 4:48 ` Gaurav Kohli 2020-08-12 13:30 ` Will Deacon 3 siblings, 0 replies; 8+ messages in thread From: Gaurav Kohli @ 2020-08-11 4:48 UTC (permalink / raw) To: will, linux-arm-kernel, maz, Catalin Marinas Cc: linux-arm-msm, linux-kernel, neeraju Hi, Please let us know, is below patch good to have or not for non ssbs systems. On 8/4/2020 7:44 PM, Gaurav Kohli wrote: > In a system where no cpu's implement SSBS, for > them no need to set pstate. This might help to save > few cpu cycles during context switch. > > Signed-off-by: Gaurav Kohli <gkohli@codeaurora.org> > > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c > index 6089638..79f80f1 100644 > --- a/arch/arm64/kernel/process.c > +++ b/arch/arm64/kernel/process.c > @@ -477,6 +477,13 @@ static void ssbs_thread_switch(struct task_struct *next) > struct pt_regs *regs = task_pt_regs(next); > > /* > + * For Targets which don't have SSBS support, they > + * can return from here. > + */ > + if (!IS_ENABLED(CONFIG_ARM64_SSBD)) > + return; > + > + /* > * Nothing to do for kernel threads, but 'regs' may be junk > * (e.g. idle task) so check the flags and bail early. > */ > -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] arm64: Skip apply SSBS call for non SSBS system 2020-08-04 14:14 [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli ` (2 preceding siblings ...) 2020-08-11 4:48 ` [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli @ 2020-08-12 13:30 ` Will Deacon 2020-08-12 14:15 ` Gaurav Kohli 3 siblings, 1 reply; 8+ messages in thread From: Will Deacon @ 2020-08-12 13:30 UTC (permalink / raw) To: Gaurav Kohli; +Cc: maz, neeraju, linux-kernel, linux-arm-kernel, linux-arm-msm On Tue, Aug 04, 2020 at 07:44:42PM +0530, Gaurav Kohli wrote: > In a system where no cpu's implement SSBS, for > them no need to set pstate. This might help to save > few cpu cycles during context switch. > > Signed-off-by: Gaurav Kohli <gkohli@codeaurora.org> > > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c > index 6089638..79f80f1 100644 > --- a/arch/arm64/kernel/process.c > +++ b/arch/arm64/kernel/process.c > @@ -477,6 +477,13 @@ static void ssbs_thread_switch(struct task_struct *next) > struct pt_regs *regs = task_pt_regs(next); > > /* > + * For Targets which don't have SSBS support, they > + * can return from here. > + */ > + if (!IS_ENABLED(CONFIG_ARM64_SSBD)) > + return; Does this actually make a measurable difference? Will _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] arm64: Skip apply SSBS call for non SSBS system 2020-08-12 13:30 ` Will Deacon @ 2020-08-12 14:15 ` Gaurav Kohli 0 siblings, 0 replies; 8+ messages in thread From: Gaurav Kohli @ 2020-08-12 14:15 UTC (permalink / raw) To: Will Deacon; +Cc: maz, neeraju, linux-kernel, linux-arm-kernel, linux-arm-msm On 8/12/2020 7:00 PM, Will Deacon wrote: > On Tue, Aug 04, 2020 at 07:44:42PM +0530, Gaurav Kohli wrote: >> In a system where no cpu's implement SSBS, for >> them no need to set pstate. This might help to save >> few cpu cycles during context switch. >> >> Signed-off-by: Gaurav Kohli <gkohli@codeaurora.org> >> >> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c >> index 6089638..79f80f1 100644 >> --- a/arch/arm64/kernel/process.c >> +++ b/arch/arm64/kernel/process.c >> @@ -477,6 +477,13 @@ static void ssbs_thread_switch(struct task_struct *next) >> struct pt_regs *regs = task_pt_regs(next); >> >> /* >> + * For Targets which don't have SSBS support, they >> + * can return from here. >> + */ >> + if (!IS_ENABLED(CONFIG_ARM64_SSBD)) >> + return; > > Does this actually make a measurable difference? > > Will > Hi Will, While doing code review between older kernel and latest kernel for context switch case, there i have found this and thought it is good to have for non-ssbs system to return early(as this might improve). Please let me know if you want to run some tests. Regards Gaurav _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-08-12 14:17 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-08-04 14:14 [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli 2020-08-04 14:14 ` [PATCH] nvmem: core: add support to NVMEM_NO_SYSFS_ENTRY Gaurav Kohli 2020-08-04 14:25 ` Gaurav Kohli 2020-08-04 14:14 ` [PATCH] nvmem: core: add NVMEM_SYSFS Kconfig Gaurav Kohli 2020-08-04 14:26 ` Gaurav Kohli 2020-08-11 4:48 ` [PATCH] arm64: Skip apply SSBS call for non SSBS system Gaurav Kohli 2020-08-12 13:30 ` Will Deacon 2020-08-12 14:15 ` Gaurav Kohli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox