root/drivers/nvmem/nvmem-sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. type_show
  2. bin_attr_nvmem_read
  3. bin_attr_nvmem_write
  4. nvmem_sysfs_get_groups
  5. nvmem_sysfs_setup_compat
  6. nvmem_sysfs_remove_compat

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (c) 2019, Linaro Limited
   4  */
   5 #include "nvmem.h"
   6 
   7 static const char * const nvmem_type_str[] = {
   8         [NVMEM_TYPE_UNKNOWN] = "Unknown",
   9         [NVMEM_TYPE_EEPROM] = "EEPROM",
  10         [NVMEM_TYPE_OTP] = "OTP",
  11         [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed",
  12 };
  13 
  14 #ifdef CONFIG_DEBUG_LOCK_ALLOC
  15 static struct lock_class_key eeprom_lock_key;
  16 #endif
  17 
  18 static ssize_t type_show(struct device *dev,
  19                          struct device_attribute *attr, char *buf)
  20 {
  21         struct nvmem_device *nvmem = to_nvmem_device(dev);
  22 
  23         return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
  24 }
  25 
  26 static DEVICE_ATTR_RO(type);
  27 
  28 static struct attribute *nvmem_attrs[] = {
  29         &dev_attr_type.attr,
  30         NULL,
  31 };
  32 
  33 static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
  34                                     struct bin_attribute *attr,
  35                                     char *buf, loff_t pos, size_t count)
  36 {
  37         struct device *dev;
  38         struct nvmem_device *nvmem;
  39         int rc;
  40 
  41         if (attr->private)
  42                 dev = attr->private;
  43         else
  44                 dev = container_of(kobj, struct device, kobj);
  45         nvmem = to_nvmem_device(dev);
  46 
  47         /* Stop the user from reading */
  48         if (pos >= nvmem->size)
  49                 return 0;
  50 
  51         if (count < nvmem->word_size)
  52                 return -EINVAL;
  53 
  54         if (pos + count > nvmem->size)
  55                 count = nvmem->size - pos;
  56 
  57         count = round_down(count, nvmem->word_size);
  58 
  59         if (!nvmem->reg_read)
  60                 return -EPERM;
  61 
  62         rc = nvmem->reg_read(nvmem->priv, pos, buf, count);
  63 
  64         if (rc)
  65                 return rc;
  66 
  67         return count;
  68 }
  69 
  70 static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
  71                                      struct bin_attribute *attr,
  72                                      char *buf, loff_t pos, size_t count)
  73 {
  74         struct device *dev;
  75         struct nvmem_device *nvmem;
  76         int rc;
  77 
  78         if (attr->private)
  79                 dev = attr->private;
  80         else
  81                 dev = container_of(kobj, struct device, kobj);
  82         nvmem = to_nvmem_device(dev);
  83 
  84         /* Stop the user from writing */
  85         if (pos >= nvmem->size)
  86                 return -EFBIG;
  87 
  88         if (count < nvmem->word_size)
  89                 return -EINVAL;
  90 
  91         if (pos + count > nvmem->size)
  92                 count = nvmem->size - pos;
  93 
  94         count = round_down(count, nvmem->word_size);
  95 
  96         if (!nvmem->reg_write)
  97                 return -EPERM;
  98 
  99         rc = nvmem->reg_write(nvmem->priv, pos, buf, count);
 100 
 101         if (rc)
 102                 return rc;
 103 
 104         return count;
 105 }
 106 
 107 /* default read/write permissions */
 108 static struct bin_attribute bin_attr_rw_nvmem = {
 109         .attr   = {
 110                 .name   = "nvmem",
 111                 .mode   = 0644,
 112         },
 113         .read   = bin_attr_nvmem_read,
 114         .write  = bin_attr_nvmem_write,
 115 };
 116 
 117 static struct bin_attribute *nvmem_bin_rw_attributes[] = {
 118         &bin_attr_rw_nvmem,
 119         NULL,
 120 };
 121 
 122 static const struct attribute_group nvmem_bin_rw_group = {
 123         .bin_attrs      = nvmem_bin_rw_attributes,
 124         .attrs          = nvmem_attrs,
 125 };
 126 
 127 static const struct attribute_group *nvmem_rw_dev_groups[] = {
 128         &nvmem_bin_rw_group,
 129         NULL,
 130 };
 131 
 132 /* read only permission */
 133 static struct bin_attribute bin_attr_ro_nvmem = {
 134         .attr   = {
 135                 .name   = "nvmem",
 136                 .mode   = 0444,
 137         },
 138         .read   = bin_attr_nvmem_read,
 139 };
 140 
 141 static struct bin_attribute *nvmem_bin_ro_attributes[] = {
 142         &bin_attr_ro_nvmem,
 143         NULL,
 144 };
 145 
 146 static const struct attribute_group nvmem_bin_ro_group = {
 147         .bin_attrs      = nvmem_bin_ro_attributes,
 148         .attrs          = nvmem_attrs,
 149 };
 150 
 151 static const struct attribute_group *nvmem_ro_dev_groups[] = {
 152         &nvmem_bin_ro_group,
 153         NULL,
 154 };
 155 
 156 /* default read/write permissions, root only */
 157 static struct bin_attribute bin_attr_rw_root_nvmem = {
 158         .attr   = {
 159                 .name   = "nvmem",
 160                 .mode   = 0600,
 161         },
 162         .read   = bin_attr_nvmem_read,
 163         .write  = bin_attr_nvmem_write,
 164 };
 165 
 166 static struct bin_attribute *nvmem_bin_rw_root_attributes[] = {
 167         &bin_attr_rw_root_nvmem,
 168         NULL,
 169 };
 170 
 171 static const struct attribute_group nvmem_bin_rw_root_group = {
 172         .bin_attrs      = nvmem_bin_rw_root_attributes,
 173         .attrs          = nvmem_attrs,
 174 };
 175 
 176 static const struct attribute_group *nvmem_rw_root_dev_groups[] = {
 177         &nvmem_bin_rw_root_group,
 178         NULL,
 179 };
 180 
 181 /* read only permission, root only */
 182 static struct bin_attribute bin_attr_ro_root_nvmem = {
 183         .attr   = {
 184                 .name   = "nvmem",
 185                 .mode   = 0400,
 186         },
 187         .read   = bin_attr_nvmem_read,
 188 };
 189 
 190 static struct bin_attribute *nvmem_bin_ro_root_attributes[] = {
 191         &bin_attr_ro_root_nvmem,
 192         NULL,
 193 };
 194 
 195 static const struct attribute_group nvmem_bin_ro_root_group = {
 196         .bin_attrs      = nvmem_bin_ro_root_attributes,
 197         .attrs          = nvmem_attrs,
 198 };
 199 
 200 static const struct attribute_group *nvmem_ro_root_dev_groups[] = {
 201         &nvmem_bin_ro_root_group,
 202         NULL,
 203 };
 204 
 205 const struct attribute_group **nvmem_sysfs_get_groups(
 206                                         struct nvmem_device *nvmem,
 207                                         const struct nvmem_config *config)
 208 {
 209         if (config->root_only)
 210                 return nvmem->read_only ?
 211                         nvmem_ro_root_dev_groups :
 212                         nvmem_rw_root_dev_groups;
 213 
 214         return nvmem->read_only ? nvmem_ro_dev_groups : nvmem_rw_dev_groups;
 215 }
 216 
 217 /*
 218  * nvmem_setup_compat() - Create an additional binary entry in
 219  * drivers sys directory, to be backwards compatible with the older
 220  * drivers/misc/eeprom drivers.
 221  */
 222 int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
 223                               const struct nvmem_config *config)
 224 {
 225         int rval;
 226 
 227         if (!config->compat)
 228                 return 0;
 229 
 230         if (!config->base_dev)
 231                 return -EINVAL;
 232 
 233         if (nvmem->read_only) {
 234                 if (config->root_only)
 235                         nvmem->eeprom = bin_attr_ro_root_nvmem;
 236                 else
 237                         nvmem->eeprom = bin_attr_ro_nvmem;
 238         } else {
 239                 if (config->root_only)
 240                         nvmem->eeprom = bin_attr_rw_root_nvmem;
 241                 else
 242                         nvmem->eeprom = bin_attr_rw_nvmem;
 243         }
 244         nvmem->eeprom.attr.name = "eeprom";
 245         nvmem->eeprom.size = nvmem->size;
 246 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 247         nvmem->eeprom.attr.key = &eeprom_lock_key;
 248 #endif
 249         nvmem->eeprom.private = &nvmem->dev;
 250         nvmem->base_dev = config->base_dev;
 251 
 252         rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom);
 253         if (rval) {
 254                 dev_err(&nvmem->dev,
 255                         "Failed to create eeprom binary file %d\n", rval);
 256                 return rval;
 257         }
 258 
 259         nvmem->flags |= FLAG_COMPAT;
 260 
 261         return 0;
 262 }
 263 
 264 void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
 265                               const struct nvmem_config *config)
 266 {
 267         if (config->compat)
 268                 device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
 269 }

/* [<][>][^][v][top][bottom][index][help] */