LCOV - code coverage report
Current view: top level - drivers/gpio - gpiolib-sysfs.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 16 245 6.5 %
Date: 2020-09-30 20:25:40 Functions: 2 25 8.0 %
Branches: 5 162 3.1 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : #include <linux/idr.h>
       3                 :            : #include <linux/mutex.h>
       4                 :            : #include <linux/device.h>
       5                 :            : #include <linux/sysfs.h>
       6                 :            : #include <linux/gpio/consumer.h>
       7                 :            : #include <linux/gpio/driver.h>
       8                 :            : #include <linux/interrupt.h>
       9                 :            : #include <linux/kdev_t.h>
      10                 :            : #include <linux/slab.h>
      11                 :            : #include <linux/ctype.h>
      12                 :            : 
      13                 :            : #include "gpiolib.h"
      14                 :            : 
      15                 :            : #define GPIO_IRQF_TRIGGER_FALLING       BIT(0)
      16                 :            : #define GPIO_IRQF_TRIGGER_RISING        BIT(1)
      17                 :            : #define GPIO_IRQF_TRIGGER_BOTH          (GPIO_IRQF_TRIGGER_FALLING | \
      18                 :            :                                          GPIO_IRQF_TRIGGER_RISING)
      19                 :            : 
      20                 :            : struct gpiod_data {
      21                 :            :         struct gpio_desc *desc;
      22                 :            : 
      23                 :            :         struct mutex mutex;
      24                 :            :         struct kernfs_node *value_kn;
      25                 :            :         int irq;
      26                 :            :         unsigned char irq_flags;
      27                 :            : 
      28                 :            :         bool direction_can_change;
      29                 :            : };
      30                 :            : 
      31                 :            : /*
      32                 :            :  * Lock to serialise gpiod export and unexport, and prevent re-export of
      33                 :            :  * gpiod whose chip is being unregistered.
      34                 :            :  */
      35                 :            : static DEFINE_MUTEX(sysfs_lock);
      36                 :            : 
      37                 :            : /*
      38                 :            :  * /sys/class/gpio/gpioN... only for GPIOs that are exported
      39                 :            :  *   /direction
      40                 :            :  *      * MAY BE OMITTED if kernel won't allow direction changes
      41                 :            :  *      * is read/write as "in" or "out"
      42                 :            :  *      * may also be written as "high" or "low", initializing
      43                 :            :  *        output value as specified ("out" implies "low")
      44                 :            :  *   /value
      45                 :            :  *      * always readable, subject to hardware behavior
      46                 :            :  *      * may be writable, as zero/nonzero
      47                 :            :  *   /edge
      48                 :            :  *      * configures behavior of poll(2) on /value
      49                 :            :  *      * available only if pin can generate IRQs on input
      50                 :            :  *      * is read/write as "none", "falling", "rising", or "both"
      51                 :            :  *   /active_low
      52                 :            :  *      * configures polarity of /value
      53                 :            :  *      * is read/write as zero/nonzero
      54                 :            :  *      * also affects existing and subsequent "falling" and "rising"
      55                 :            :  *        /edge configuration
      56                 :            :  */
      57                 :            : 
      58                 :          0 : static ssize_t direction_show(struct device *dev,
      59                 :            :                 struct device_attribute *attr, char *buf)
      60                 :            : {
      61                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
      62                 :          0 :         struct gpio_desc *desc = data->desc;
      63                 :            :         ssize_t                 status;
      64                 :            : 
      65                 :          0 :         mutex_lock(&data->mutex);
      66                 :            : 
      67                 :          0 :         gpiod_get_direction(desc);
      68         [ #  # ]:          0 :         status = sprintf(buf, "%s\n",
      69                 :            :                         test_bit(FLAG_IS_OUT, &desc->flags)
      70                 :            :                                 ? "out" : "in");
      71                 :            : 
      72                 :          0 :         mutex_unlock(&data->mutex);
      73                 :            : 
      74                 :          0 :         return status;
      75                 :            : }
      76                 :            : 
      77                 :          0 : static ssize_t direction_store(struct device *dev,
      78                 :            :                 struct device_attribute *attr, const char *buf, size_t size)
      79                 :            : {
      80                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
      81                 :          0 :         struct gpio_desc *desc = data->desc;
      82                 :            :         ssize_t                 status;
      83                 :            : 
      84                 :          0 :         mutex_lock(&data->mutex);
      85                 :            : 
      86         [ #  # ]:          0 :         if (sysfs_streq(buf, "high"))
      87                 :          0 :                 status = gpiod_direction_output_raw(desc, 1);
      88   [ #  #  #  # ]:          0 :         else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low"))
      89                 :          0 :                 status = gpiod_direction_output_raw(desc, 0);
      90         [ #  # ]:          0 :         else if (sysfs_streq(buf, "in"))
      91                 :          0 :                 status = gpiod_direction_input(desc);
      92                 :            :         else
      93                 :            :                 status = -EINVAL;
      94                 :            : 
      95                 :          0 :         mutex_unlock(&data->mutex);
      96                 :            : 
      97         [ #  # ]:          0 :         return status ? : size;
      98                 :            : }
      99                 :            : static DEVICE_ATTR_RW(direction);
     100                 :            : 
     101                 :          0 : static ssize_t value_show(struct device *dev,
     102                 :            :                 struct device_attribute *attr, char *buf)
     103                 :            : {
     104                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     105                 :          0 :         struct gpio_desc *desc = data->desc;
     106                 :            :         ssize_t                 status;
     107                 :            : 
     108                 :          0 :         mutex_lock(&data->mutex);
     109                 :            : 
     110                 :          0 :         status = gpiod_get_value_cansleep(desc);
     111         [ #  # ]:          0 :         if (status < 0)
     112                 :            :                 goto err;
     113                 :            : 
     114                 :          0 :         buf[0] = '0' + status;
     115                 :          0 :         buf[1] = '\n';
     116                 :            :         status = 2;
     117                 :            : err:
     118                 :          0 :         mutex_unlock(&data->mutex);
     119                 :            : 
     120                 :          0 :         return status;
     121                 :            : }
     122                 :            : 
     123                 :          0 : static ssize_t value_store(struct device *dev,
     124                 :            :                 struct device_attribute *attr, const char *buf, size_t size)
     125                 :            : {
     126                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     127                 :          0 :         struct gpio_desc *desc = data->desc;
     128                 :            :         ssize_t status = 0;
     129                 :            : 
     130                 :          0 :         mutex_lock(&data->mutex);
     131                 :            : 
     132         [ #  # ]:          0 :         if (!test_bit(FLAG_IS_OUT, &desc->flags)) {
     133                 :            :                 status = -EPERM;
     134                 :            :         } else {
     135                 :            :                 long            value;
     136                 :            : 
     137   [ #  #  #  #  :          0 :                 if (size <= 2 && isdigit(buf[0]) &&
                   #  # ]
     138         [ #  # ]:          0 :                     (size == 1 || buf[1] == '\n'))
     139                 :          0 :                         value = buf[0] - '0';
     140                 :            :                 else
     141                 :            :                         status = kstrtol(buf, 0, &value);
     142         [ #  # ]:          0 :                 if (status == 0) {
     143                 :          0 :                         gpiod_set_value_cansleep(desc, value);
     144                 :          0 :                         status = size;
     145                 :            :                 }
     146                 :            :         }
     147                 :            : 
     148                 :          0 :         mutex_unlock(&data->mutex);
     149                 :            : 
     150                 :          0 :         return status;
     151                 :            : }
     152                 :            : static DEVICE_ATTR_PREALLOC(value, S_IWUSR | S_IRUGO, value_show, value_store);
     153                 :            : 
     154                 :          0 : static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
     155                 :            : {
     156                 :            :         struct gpiod_data *data = priv;
     157                 :            : 
     158                 :          0 :         sysfs_notify_dirent(data->value_kn);
     159                 :            : 
     160                 :          0 :         return IRQ_HANDLED;
     161                 :            : }
     162                 :            : 
     163                 :            : /* Caller holds gpiod-data mutex. */
     164                 :          0 : static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags)
     165                 :            : {
     166                 :            :         struct gpiod_data       *data = dev_get_drvdata(dev);
     167                 :          0 :         struct gpio_desc        *desc = data->desc;
     168                 :            :         unsigned long           irq_flags;
     169                 :            :         int                     ret;
     170                 :            : 
     171                 :          0 :         data->irq = gpiod_to_irq(desc);
     172         [ #  # ]:          0 :         if (data->irq < 0)
     173                 :            :                 return -EIO;
     174                 :            : 
     175                 :          0 :         data->value_kn = sysfs_get_dirent(dev->kobj.sd, "value");
     176         [ #  # ]:          0 :         if (!data->value_kn)
     177                 :            :                 return -ENODEV;
     178                 :            : 
     179                 :            :         irq_flags = IRQF_SHARED;
     180         [ #  # ]:          0 :         if (flags & GPIO_IRQF_TRIGGER_FALLING)
     181                 :          0 :                 irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
     182         [ #  # ]:          0 :                         IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
     183         [ #  # ]:          0 :         if (flags & GPIO_IRQF_TRIGGER_RISING)
     184                 :          0 :                 irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
     185         [ #  # ]:          0 :                         IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
     186                 :            : 
     187                 :            :         /*
     188                 :            :          * FIXME: This should be done in the irq_request_resources callback
     189                 :            :          *        when the irq is requested, but a few drivers currently fail
     190                 :            :          *        to do so.
     191                 :            :          *
     192                 :            :          *        Remove this redundant call (along with the corresponding
     193                 :            :          *        unlock) when those drivers have been fixed.
     194                 :            :          */
     195                 :          0 :         ret = gpiochip_lock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc));
     196         [ #  # ]:          0 :         if (ret < 0)
     197                 :            :                 goto err_put_kn;
     198                 :            : 
     199                 :          0 :         ret = request_any_context_irq(data->irq, gpio_sysfs_irq, irq_flags,
     200                 :            :                                 "gpiolib", data);
     201         [ #  # ]:          0 :         if (ret < 0)
     202                 :            :                 goto err_unlock;
     203                 :            : 
     204                 :          0 :         data->irq_flags = flags;
     205                 :            : 
     206                 :          0 :         return 0;
     207                 :            : 
     208                 :            : err_unlock:
     209                 :          0 :         gpiochip_unlock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc));
     210                 :            : err_put_kn:
     211                 :          0 :         sysfs_put(data->value_kn);
     212                 :            : 
     213                 :          0 :         return ret;
     214                 :            : }
     215                 :            : 
     216                 :            : /*
     217                 :            :  * Caller holds gpiod-data mutex (unless called after class-device
     218                 :            :  * deregistration).
     219                 :            :  */
     220                 :          0 : static void gpio_sysfs_free_irq(struct device *dev)
     221                 :            : {
     222                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     223                 :          0 :         struct gpio_desc *desc = data->desc;
     224                 :            : 
     225                 :          0 :         data->irq_flags = 0;
     226                 :          0 :         free_irq(data->irq, data);
     227                 :          0 :         gpiochip_unlock_as_irq(desc->gdev->chip, gpio_chip_hwgpio(desc));
     228                 :          0 :         sysfs_put(data->value_kn);
     229                 :          0 : }
     230                 :            : 
     231                 :            : static const struct {
     232                 :            :         const char *name;
     233                 :            :         unsigned char flags;
     234                 :            : } trigger_types[] = {
     235                 :            :         { "none",    0 },
     236                 :            :         { "falling", GPIO_IRQF_TRIGGER_FALLING },
     237                 :            :         { "rising",  GPIO_IRQF_TRIGGER_RISING },
     238                 :            :         { "both",    GPIO_IRQF_TRIGGER_BOTH },
     239                 :            : };
     240                 :            : 
     241                 :          0 : static ssize_t edge_show(struct device *dev,
     242                 :            :                 struct device_attribute *attr, char *buf)
     243                 :            : {
     244                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     245                 :            :         ssize_t status = 0;
     246                 :            :         int i;
     247                 :            : 
     248                 :          0 :         mutex_lock(&data->mutex);
     249                 :            : 
     250         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(trigger_types); i++) {
     251         [ #  # ]:          0 :                 if (data->irq_flags == trigger_types[i].flags) {
     252                 :          0 :                         status = sprintf(buf, "%s\n", trigger_types[i].name);
     253                 :          0 :                         break;
     254                 :            :                 }
     255                 :            :         }
     256                 :            : 
     257                 :          0 :         mutex_unlock(&data->mutex);
     258                 :            : 
     259                 :          0 :         return status;
     260                 :            : }
     261                 :            : 
     262                 :          0 : static ssize_t edge_store(struct device *dev,
     263                 :            :                 struct device_attribute *attr, const char *buf, size_t size)
     264                 :            : {
     265                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     266                 :            :         unsigned char flags;
     267                 :          0 :         ssize_t status = size;
     268                 :            :         int i;
     269                 :            : 
     270         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(trigger_types); i++) {
     271         [ #  # ]:          0 :                 if (sysfs_streq(trigger_types[i].name, buf))
     272                 :            :                         break;
     273                 :            :         }
     274                 :            : 
     275         [ #  # ]:          0 :         if (i == ARRAY_SIZE(trigger_types))
     276                 :            :                 return -EINVAL;
     277                 :            : 
     278                 :          0 :         flags = trigger_types[i].flags;
     279                 :            : 
     280                 :          0 :         mutex_lock(&data->mutex);
     281                 :            : 
     282         [ #  # ]:          0 :         if (flags == data->irq_flags) {
     283                 :            :                 status = size;
     284                 :            :                 goto out_unlock;
     285                 :            :         }
     286                 :            : 
     287         [ #  # ]:          0 :         if (data->irq_flags)
     288                 :          0 :                 gpio_sysfs_free_irq(dev);
     289                 :            : 
     290         [ #  # ]:          0 :         if (flags) {
     291                 :          0 :                 status = gpio_sysfs_request_irq(dev, flags);
     292         [ #  # ]:          0 :                 if (!status)
     293                 :            :                         status = size;
     294                 :            :         }
     295                 :            : 
     296                 :            : out_unlock:
     297                 :          0 :         mutex_unlock(&data->mutex);
     298                 :            : 
     299                 :          0 :         return status;
     300                 :            : }
     301                 :            : static DEVICE_ATTR_RW(edge);
     302                 :            : 
     303                 :            : /* Caller holds gpiod-data mutex. */
     304                 :          0 : static int gpio_sysfs_set_active_low(struct device *dev, int value)
     305                 :            : {
     306                 :            :         struct gpiod_data       *data = dev_get_drvdata(dev);
     307                 :          0 :         struct gpio_desc        *desc = data->desc;
     308                 :            :         int                     status = 0;
     309                 :          0 :         unsigned int            flags = data->irq_flags;
     310                 :            : 
     311         [ #  # ]:          0 :         if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
     312                 :            :                 return 0;
     313                 :            : 
     314         [ #  # ]:          0 :         if (value)
     315                 :          0 :                 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
     316                 :            :         else
     317                 :          0 :                 clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
     318                 :            : 
     319                 :            :         /* reconfigure poll(2) support if enabled on one edge only */
     320         [ #  # ]:          0 :         if (flags == GPIO_IRQF_TRIGGER_FALLING ||
     321                 :            :                                         flags == GPIO_IRQF_TRIGGER_RISING) {
     322                 :          0 :                 gpio_sysfs_free_irq(dev);
     323                 :          0 :                 status = gpio_sysfs_request_irq(dev, flags);
     324                 :            :         }
     325                 :            : 
     326                 :          0 :         return status;
     327                 :            : }
     328                 :            : 
     329                 :          0 : static ssize_t active_low_show(struct device *dev,
     330                 :            :                 struct device_attribute *attr, char *buf)
     331                 :            : {
     332                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     333                 :          0 :         struct gpio_desc *desc = data->desc;
     334                 :            :         ssize_t                 status;
     335                 :            : 
     336                 :          0 :         mutex_lock(&data->mutex);
     337                 :            : 
     338                 :          0 :         status = sprintf(buf, "%d\n",
     339                 :            :                                 !!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
     340                 :            : 
     341                 :          0 :         mutex_unlock(&data->mutex);
     342                 :            : 
     343                 :          0 :         return status;
     344                 :            : }
     345                 :            : 
     346                 :          0 : static ssize_t active_low_store(struct device *dev,
     347                 :            :                 struct device_attribute *attr, const char *buf, size_t size)
     348                 :            : {
     349                 :            :         struct gpiod_data       *data = dev_get_drvdata(dev);
     350                 :            :         ssize_t                 status;
     351                 :            :         long                    value;
     352                 :            : 
     353                 :          0 :         mutex_lock(&data->mutex);
     354                 :            : 
     355                 :            :         status = kstrtol(buf, 0, &value);
     356         [ #  # ]:          0 :         if (status == 0)
     357                 :          0 :                 status = gpio_sysfs_set_active_low(dev, value);
     358                 :            : 
     359                 :          0 :         mutex_unlock(&data->mutex);
     360                 :            : 
     361         [ #  # ]:          0 :         return status ? : size;
     362                 :            : }
     363                 :            : static DEVICE_ATTR_RW(active_low);
     364                 :            : 
     365                 :          0 : static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
     366                 :            :                                int n)
     367                 :            : {
     368                 :            :         struct device *dev = container_of(kobj, struct device, kobj);
     369                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     370                 :          0 :         struct gpio_desc *desc = data->desc;
     371                 :          0 :         umode_t mode = attr->mode;
     372                 :          0 :         bool show_direction = data->direction_can_change;
     373                 :            : 
     374         [ #  # ]:          0 :         if (attr == &dev_attr_direction.attr) {
     375         [ #  # ]:          0 :                 if (!show_direction)
     376                 :            :                         mode = 0;
     377         [ #  # ]:          0 :         } else if (attr == &dev_attr_edge.attr) {
     378         [ #  # ]:          0 :                 if (gpiod_to_irq(desc) < 0)
     379                 :            :                         mode = 0;
     380   [ #  #  #  # ]:          0 :                 if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags))
     381                 :            :                         mode = 0;
     382                 :            :         }
     383                 :            : 
     384                 :          0 :         return mode;
     385                 :            : }
     386                 :            : 
     387                 :            : static struct attribute *gpio_attrs[] = {
     388                 :            :         &dev_attr_direction.attr,
     389                 :            :         &dev_attr_edge.attr,
     390                 :            :         &dev_attr_value.attr,
     391                 :            :         &dev_attr_active_low.attr,
     392                 :            :         NULL,
     393                 :            : };
     394                 :            : 
     395                 :            : static const struct attribute_group gpio_group = {
     396                 :            :         .attrs = gpio_attrs,
     397                 :            :         .is_visible = gpio_is_visible,
     398                 :            : };
     399                 :            : 
     400                 :            : static const struct attribute_group *gpio_groups[] = {
     401                 :            :         &gpio_group,
     402                 :            :         NULL
     403                 :            : };
     404                 :            : 
     405                 :            : /*
     406                 :            :  * /sys/class/gpio/gpiochipN/
     407                 :            :  *   /base ... matching gpio_chip.base (N)
     408                 :            :  *   /label ... matching gpio_chip.label
     409                 :            :  *   /ngpio ... matching gpio_chip.ngpio
     410                 :            :  */
     411                 :            : 
     412                 :          0 : static ssize_t base_show(struct device *dev,
     413                 :            :                                struct device_attribute *attr, char *buf)
     414                 :            : {
     415                 :            :         const struct gpio_chip  *chip = dev_get_drvdata(dev);
     416                 :            : 
     417                 :          0 :         return sprintf(buf, "%d\n", chip->base);
     418                 :            : }
     419                 :            : static DEVICE_ATTR_RO(base);
     420                 :            : 
     421                 :          0 : static ssize_t label_show(struct device *dev,
     422                 :            :                                struct device_attribute *attr, char *buf)
     423                 :            : {
     424                 :            :         const struct gpio_chip  *chip = dev_get_drvdata(dev);
     425                 :            : 
     426         [ #  # ]:          0 :         return sprintf(buf, "%s\n", chip->label ? : "");
     427                 :            : }
     428                 :            : static DEVICE_ATTR_RO(label);
     429                 :            : 
     430                 :          0 : static ssize_t ngpio_show(struct device *dev,
     431                 :            :                                struct device_attribute *attr, char *buf)
     432                 :            : {
     433                 :            :         const struct gpio_chip  *chip = dev_get_drvdata(dev);
     434                 :            : 
     435                 :          0 :         return sprintf(buf, "%u\n", chip->ngpio);
     436                 :            : }
     437                 :            : static DEVICE_ATTR_RO(ngpio);
     438                 :            : 
     439                 :            : static struct attribute *gpiochip_attrs[] = {
     440                 :            :         &dev_attr_base.attr,
     441                 :            :         &dev_attr_label.attr,
     442                 :            :         &dev_attr_ngpio.attr,
     443                 :            :         NULL,
     444                 :            : };
     445                 :            : ATTRIBUTE_GROUPS(gpiochip);
     446                 :            : 
     447                 :            : /*
     448                 :            :  * /sys/class/gpio/export ... write-only
     449                 :            :  *      integer N ... number of GPIO to export (full access)
     450                 :            :  * /sys/class/gpio/unexport ... write-only
     451                 :            :  *      integer N ... number of GPIO to unexport
     452                 :            :  */
     453                 :          0 : static ssize_t export_store(struct class *class,
     454                 :            :                                 struct class_attribute *attr,
     455                 :            :                                 const char *buf, size_t len)
     456                 :            : {
     457                 :            :         long                    gpio;
     458                 :            :         struct gpio_desc        *desc;
     459                 :            :         int                     status;
     460                 :            : 
     461                 :            :         status = kstrtol(buf, 0, &gpio);
     462         [ #  # ]:          0 :         if (status < 0)
     463                 :            :                 goto done;
     464                 :            : 
     465                 :          0 :         desc = gpio_to_desc(gpio);
     466                 :            :         /* reject invalid GPIOs */
     467         [ #  # ]:          0 :         if (!desc) {
     468                 :          0 :                 pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
     469                 :          0 :                 return -EINVAL;
     470                 :            :         }
     471                 :            : 
     472                 :            :         /* No extra locking here; FLAG_SYSFS just signifies that the
     473                 :            :          * request and export were done by on behalf of userspace, so
     474                 :            :          * they may be undone on its behalf too.
     475                 :            :          */
     476                 :            : 
     477                 :          0 :         status = gpiod_request(desc, "sysfs");
     478         [ #  # ]:          0 :         if (status < 0) {
     479         [ #  # ]:          0 :                 if (status == -EPROBE_DEFER)
     480                 :            :                         status = -ENODEV;
     481                 :            :                 goto done;
     482                 :            :         }
     483                 :            : 
     484                 :          0 :         status = gpiod_set_transitory(desc, false);
     485         [ #  # ]:          0 :         if (!status) {
     486                 :          0 :                 status = gpiod_export(desc, true);
     487         [ #  # ]:          0 :                 if (status < 0)
     488                 :          0 :                         gpiod_free(desc);
     489                 :            :                 else
     490                 :          0 :                         set_bit(FLAG_SYSFS, &desc->flags);
     491                 :            :         }
     492                 :            : 
     493                 :            : done:
     494                 :            :         if (status)
     495                 :            :                 pr_debug("%s: status %d\n", __func__, status);
     496         [ #  # ]:          0 :         return status ? : len;
     497                 :            : }
     498                 :            : static CLASS_ATTR_WO(export);
     499                 :            : 
     500                 :          0 : static ssize_t unexport_store(struct class *class,
     501                 :            :                                 struct class_attribute *attr,
     502                 :            :                                 const char *buf, size_t len)
     503                 :            : {
     504                 :            :         long                    gpio;
     505                 :            :         struct gpio_desc        *desc;
     506                 :            :         int                     status;
     507                 :            : 
     508                 :            :         status = kstrtol(buf, 0, &gpio);
     509         [ #  # ]:          0 :         if (status < 0)
     510                 :            :                 goto done;
     511                 :            : 
     512                 :          0 :         desc = gpio_to_desc(gpio);
     513                 :            :         /* reject bogus commands (gpio_unexport ignores them) */
     514         [ #  # ]:          0 :         if (!desc) {
     515                 :          0 :                 pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
     516                 :          0 :                 return -EINVAL;
     517                 :            :         }
     518                 :            : 
     519                 :            :         status = -EINVAL;
     520                 :            : 
     521                 :            :         /* No extra locking here; FLAG_SYSFS just signifies that the
     522                 :            :          * request and export were done by on behalf of userspace, so
     523                 :            :          * they may be undone on its behalf too.
     524                 :            :          */
     525         [ #  # ]:          0 :         if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) {
     526                 :            :                 status = 0;
     527                 :          0 :                 gpiod_free(desc);
     528                 :            :         }
     529                 :            : done:
     530                 :            :         if (status)
     531                 :            :                 pr_debug("%s: status %d\n", __func__, status);
     532         [ #  # ]:          0 :         return status ? : len;
     533                 :            : }
     534                 :            : static CLASS_ATTR_WO(unexport);
     535                 :            : 
     536                 :            : static struct attribute *gpio_class_attrs[] = {
     537                 :            :         &class_attr_export.attr,
     538                 :            :         &class_attr_unexport.attr,
     539                 :            :         NULL,
     540                 :            : };
     541                 :            : ATTRIBUTE_GROUPS(gpio_class);
     542                 :            : 
     543                 :            : static struct class gpio_class = {
     544                 :            :         .name =         "gpio",
     545                 :            :         .owner =        THIS_MODULE,
     546                 :            : 
     547                 :            :         .class_groups = gpio_class_groups,
     548                 :            : };
     549                 :            : 
     550                 :            : 
     551                 :            : /**
     552                 :            :  * gpiod_export - export a GPIO through sysfs
     553                 :            :  * @desc: GPIO to make available, already requested
     554                 :            :  * @direction_may_change: true if userspace may change GPIO direction
     555                 :            :  * Context: arch_initcall or later
     556                 :            :  *
     557                 :            :  * When drivers want to make a GPIO accessible to userspace after they
     558                 :            :  * have requested it -- perhaps while debugging, or as part of their
     559                 :            :  * public interface -- they may use this routine.  If the GPIO can
     560                 :            :  * change direction (some can't) and the caller allows it, userspace
     561                 :            :  * will see "direction" sysfs attribute which may be used to change
     562                 :            :  * the gpio's direction.  A "value" attribute will always be provided.
     563                 :            :  *
     564                 :            :  * Returns zero on success, else an error.
     565                 :            :  */
     566                 :          0 : int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
     567                 :            : {
     568                 :            :         struct gpio_chip        *chip;
     569                 :            :         struct gpio_device      *gdev;
     570                 :            :         struct gpiod_data       *data;
     571                 :            :         unsigned long           flags;
     572                 :            :         int                     status;
     573                 :            :         const char              *ioname = NULL;
     574                 :            :         struct device           *dev;
     575                 :            :         int                     offset;
     576                 :            : 
     577                 :            :         /* can't export until sysfs is available ... */
     578         [ #  # ]:          0 :         if (!gpio_class.p) {
     579                 :            :                 pr_debug("%s: called too early!\n", __func__);
     580                 :            :                 return -ENOENT;
     581                 :            :         }
     582                 :            : 
     583         [ #  # ]:          0 :         if (!desc) {
     584                 :            :                 pr_debug("%s: invalid gpio descriptor\n", __func__);
     585                 :            :                 return -EINVAL;
     586                 :            :         }
     587                 :            : 
     588                 :          0 :         gdev = desc->gdev;
     589                 :          0 :         chip = gdev->chip;
     590                 :            : 
     591                 :          0 :         mutex_lock(&sysfs_lock);
     592                 :            : 
     593                 :            :         /* check if chip is being removed */
     594   [ #  #  #  # ]:          0 :         if (!chip || !gdev->mockdev) {
     595                 :            :                 status = -ENODEV;
     596                 :            :                 goto err_unlock;
     597                 :            :         }
     598                 :            : 
     599                 :          0 :         spin_lock_irqsave(&gpio_lock, flags);
     600   [ #  #  #  # ]:          0 :         if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
     601                 :            :              test_bit(FLAG_EXPORT, &desc->flags)) {
     602                 :            :                 spin_unlock_irqrestore(&gpio_lock, flags);
     603                 :            :                 gpiod_dbg(desc, "%s: unavailable (requested=%d, exported=%d)\n",
     604                 :            :                                 __func__,
     605                 :            :                                 test_bit(FLAG_REQUESTED, &desc->flags),
     606                 :            :                                 test_bit(FLAG_EXPORT, &desc->flags));
     607                 :            :                 status = -EPERM;
     608                 :          0 :                 goto err_unlock;
     609                 :            :         }
     610                 :            :         spin_unlock_irqrestore(&gpio_lock, flags);
     611                 :            : 
     612                 :          0 :         data = kzalloc(sizeof(*data), GFP_KERNEL);
     613         [ #  # ]:          0 :         if (!data) {
     614                 :            :                 status = -ENOMEM;
     615                 :            :                 goto err_unlock;
     616                 :            :         }
     617                 :            : 
     618                 :          0 :         data->desc = desc;
     619                 :          0 :         mutex_init(&data->mutex);
     620   [ #  #  #  # ]:          0 :         if (chip->direction_input && chip->direction_output)
     621                 :          0 :                 data->direction_can_change = direction_may_change;
     622                 :            :         else
     623                 :          0 :                 data->direction_can_change = false;
     624                 :            : 
     625                 :            :         offset = gpio_chip_hwgpio(desc);
     626   [ #  #  #  # ]:          0 :         if (chip->names && chip->names[offset])
     627                 :            :                 ioname = chip->names[offset];
     628                 :            : 
     629         [ #  # ]:          0 :         dev = device_create_with_groups(&gpio_class, &gdev->dev,
     630                 :            :                                         MKDEV(0, 0), data, gpio_groups,
     631                 :            :                                         ioname ? ioname : "gpio%u",
     632                 :            :                                         desc_to_gpio(desc));
     633         [ #  # ]:          0 :         if (IS_ERR(dev)) {
     634                 :            :                 status = PTR_ERR(dev);
     635                 :            :                 goto err_free_data;
     636                 :            :         }
     637                 :            : 
     638                 :          0 :         set_bit(FLAG_EXPORT, &desc->flags);
     639                 :          0 :         mutex_unlock(&sysfs_lock);
     640                 :          0 :         return 0;
     641                 :            : 
     642                 :            : err_free_data:
     643                 :          0 :         kfree(data);
     644                 :            : err_unlock:
     645                 :          0 :         mutex_unlock(&sysfs_lock);
     646                 :            :         gpiod_dbg(desc, "%s: status %d\n", __func__, status);
     647                 :          0 :         return status;
     648                 :            : }
     649                 :            : EXPORT_SYMBOL_GPL(gpiod_export);
     650                 :            : 
     651                 :          0 : static int match_export(struct device *dev, const void *desc)
     652                 :            : {
     653                 :            :         struct gpiod_data *data = dev_get_drvdata(dev);
     654                 :            : 
     655                 :          0 :         return data->desc == desc;
     656                 :            : }
     657                 :            : 
     658                 :            : /**
     659                 :            :  * gpiod_export_link - create a sysfs link to an exported GPIO node
     660                 :            :  * @dev: device under which to create symlink
     661                 :            :  * @name: name of the symlink
     662                 :            :  * @desc: GPIO to create symlink to, already exported
     663                 :            :  *
     664                 :            :  * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
     665                 :            :  * node. Caller is responsible for unlinking.
     666                 :            :  *
     667                 :            :  * Returns zero on success, else an error.
     668                 :            :  */
     669                 :          0 : int gpiod_export_link(struct device *dev, const char *name,
     670                 :            :                       struct gpio_desc *desc)
     671                 :            : {
     672                 :            :         struct device *cdev;
     673                 :            :         int ret;
     674                 :            : 
     675         [ #  # ]:          0 :         if (!desc) {
     676                 :          0 :                 pr_warn("%s: invalid GPIO\n", __func__);
     677                 :          0 :                 return -EINVAL;
     678                 :            :         }
     679                 :            : 
     680                 :          0 :         cdev = class_find_device(&gpio_class, NULL, desc, match_export);
     681         [ #  # ]:          0 :         if (!cdev)
     682                 :            :                 return -ENODEV;
     683                 :            : 
     684                 :          0 :         ret = sysfs_create_link(&dev->kobj, &cdev->kobj, name);
     685                 :          0 :         put_device(cdev);
     686                 :            : 
     687                 :          0 :         return ret;
     688                 :            : }
     689                 :            : EXPORT_SYMBOL_GPL(gpiod_export_link);
     690                 :            : 
     691                 :            : /**
     692                 :            :  * gpiod_unexport - reverse effect of gpiod_export()
     693                 :            :  * @desc: GPIO to make unavailable
     694                 :            :  *
     695                 :            :  * This is implicit on gpiod_free().
     696                 :            :  */
     697                 :          0 : void gpiod_unexport(struct gpio_desc *desc)
     698                 :            : {
     699                 :            :         struct gpiod_data *data;
     700                 :            :         struct device *dev;
     701                 :            : 
     702         [ #  # ]:          0 :         if (!desc) {
     703                 :          0 :                 pr_warn("%s: invalid GPIO\n", __func__);
     704                 :          0 :                 return;
     705                 :            :         }
     706                 :            : 
     707                 :          0 :         mutex_lock(&sysfs_lock);
     708                 :            : 
     709         [ #  # ]:          0 :         if (!test_bit(FLAG_EXPORT, &desc->flags))
     710                 :            :                 goto err_unlock;
     711                 :            : 
     712                 :          0 :         dev = class_find_device(&gpio_class, NULL, desc, match_export);
     713         [ #  # ]:          0 :         if (!dev)
     714                 :            :                 goto err_unlock;
     715                 :            : 
     716                 :            :         data = dev_get_drvdata(dev);
     717                 :            : 
     718                 :          0 :         clear_bit(FLAG_EXPORT, &desc->flags);
     719                 :            : 
     720                 :          0 :         device_unregister(dev);
     721                 :            : 
     722                 :            :         /*
     723                 :            :          * Release irq after deregistration to prevent race with edge_store.
     724                 :            :          */
     725         [ #  # ]:          0 :         if (data->irq_flags)
     726                 :          0 :                 gpio_sysfs_free_irq(dev);
     727                 :            : 
     728                 :          0 :         mutex_unlock(&sysfs_lock);
     729                 :            : 
     730                 :          0 :         put_device(dev);
     731                 :          0 :         kfree(data);
     732                 :            : 
     733                 :          0 :         return;
     734                 :            : 
     735                 :            : err_unlock:
     736                 :          0 :         mutex_unlock(&sysfs_lock);
     737                 :            : }
     738                 :            : EXPORT_SYMBOL_GPL(gpiod_unexport);
     739                 :            : 
     740                 :        207 : int gpiochip_sysfs_register(struct gpio_device *gdev)
     741                 :            : {
     742                 :            :         struct device   *dev;
     743                 :            :         struct device   *parent;
     744                 :        207 :         struct gpio_chip *chip = gdev->chip;
     745                 :            : 
     746                 :            :         /*
     747                 :            :          * Many systems add gpio chips for SOC support very early,
     748                 :            :          * before driver model support is available.  In those cases we
     749                 :            :          * register later, in gpiolib_sysfs_init() ... here we just
     750                 :            :          * verify that _some_ field of gpio_class got initialized.
     751                 :            :          */
     752         [ +  - ]:        207 :         if (!gpio_class.p)
     753                 :            :                 return 0;
     754                 :            : 
     755                 :            :         /*
     756                 :            :          * For sysfs backward compatibility we need to preserve this
     757                 :            :          * preferred parenting to the gpio_chip parent field, if set.
     758                 :            :          */
     759         [ -  + ]:        207 :         if (chip->parent)
     760                 :            :                 parent = chip->parent;
     761                 :            :         else
     762                 :          0 :                 parent = &gdev->dev;
     763                 :            : 
     764                 :            :         /* use chip->base for the ID; it's already known to be unique */
     765                 :        207 :         dev = device_create_with_groups(&gpio_class, parent,
     766                 :            :                                         MKDEV(0, 0),
     767                 :            :                                         chip, gpiochip_groups,
     768                 :            :                                         "gpiochip%d", chip->base);
     769         [ -  + ]:        207 :         if (IS_ERR(dev))
     770                 :          0 :                 return PTR_ERR(dev);
     771                 :            : 
     772                 :        207 :         mutex_lock(&sysfs_lock);
     773                 :        207 :         gdev->mockdev = dev;
     774                 :        207 :         mutex_unlock(&sysfs_lock);
     775                 :            : 
     776                 :        207 :         return 0;
     777                 :            : }
     778                 :            : 
     779                 :          0 : void gpiochip_sysfs_unregister(struct gpio_device *gdev)
     780                 :            : {
     781                 :            :         struct gpio_desc *desc;
     782                 :          0 :         struct gpio_chip *chip = gdev->chip;
     783                 :            :         unsigned int i;
     784                 :            : 
     785         [ #  # ]:          0 :         if (!gdev->mockdev)
     786                 :          0 :                 return;
     787                 :            : 
     788                 :          0 :         device_unregister(gdev->mockdev);
     789                 :            : 
     790                 :            :         /* prevent further gpiod exports */
     791                 :          0 :         mutex_lock(&sysfs_lock);
     792                 :          0 :         gdev->mockdev = NULL;
     793                 :          0 :         mutex_unlock(&sysfs_lock);
     794                 :            : 
     795                 :            :         /* unregister gpiod class devices owned by sysfs */
     796         [ #  # ]:          0 :         for (i = 0; i < chip->ngpio; i++) {
     797                 :          0 :                 desc = &gdev->descs[i];
     798         [ #  # ]:          0 :                 if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
     799                 :          0 :                         gpiod_free(desc);
     800                 :            :         }
     801                 :            : }
     802                 :            : 
     803                 :        207 : static int __init gpiolib_sysfs_init(void)
     804                 :            : {
     805                 :            :         int             status;
     806                 :            :         unsigned long   flags;
     807                 :            :         struct gpio_device *gdev;
     808                 :            : 
     809                 :        207 :         status = class_register(&gpio_class);
     810         [ +  - ]:        207 :         if (status < 0)
     811                 :            :                 return status;
     812                 :            : 
     813                 :            :         /* Scan and register the gpio_chips which registered very
     814                 :            :          * early (e.g. before the class_register above was called).
     815                 :            :          *
     816                 :            :          * We run before arch_initcall() so chip->dev nodes can have
     817                 :            :          * registered, and so arch_initcall() can always gpio_export().
     818                 :            :          */
     819                 :        207 :         spin_lock_irqsave(&gpio_lock, flags);
     820         [ -  + ]:        207 :         list_for_each_entry(gdev, &gpio_devices, list) {
     821         [ #  # ]:          0 :                 if (gdev->mockdev)
     822                 :          0 :                         continue;
     823                 :            : 
     824                 :            :                 /*
     825                 :            :                  * TODO we yield gpio_lock here because
     826                 :            :                  * gpiochip_sysfs_register() acquires a mutex. This is unsafe
     827                 :            :                  * and needs to be fixed.
     828                 :            :                  *
     829                 :            :                  * Also it would be nice to use gpiochip_find() here so we
     830                 :            :                  * can keep gpio_chips local to gpiolib.c, but the yield of
     831                 :            :                  * gpio_lock prevents us from doing this.
     832                 :            :                  */
     833                 :            :                 spin_unlock_irqrestore(&gpio_lock, flags);
     834                 :          0 :                 status = gpiochip_sysfs_register(gdev);
     835                 :          0 :                 spin_lock_irqsave(&gpio_lock, flags);
     836                 :            :         }
     837                 :            :         spin_unlock_irqrestore(&gpio_lock, flags);
     838                 :            : 
     839                 :        207 :         return status;
     840                 :            : }
     841                 :            : postcore_initcall(gpiolib_sysfs_init);

Generated by: LCOV version 1.14