aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib-sysfs.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2015-05-04 11:10:37 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-05-12 04:47:12 -0400
commitc43960fbcc514b0ec8169a66ba9955608e6775a7 (patch)
tree10c73074ebb45203f2d7446ed7c24f06a19ce8e1 /drivers/gpio/gpiolib-sysfs.c
parentf0b7866a02370d9a03b0be497b9f88d982b8b67d (diff)
gpio: sysfs: add gpiod class-device data
Add gpiod class-device data. This is a first step in getting rid of the insane gpio-descriptor flag overloading, backward irq-interface implementation, and course grained sysfs-interface locking (a single static mutex for every operation on all exported gpios in a system). Signed-off-by: Johan Hovold <johan@kernel.org> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib-sysfs.c')
-rw-r--r--drivers/gpio/gpiolib-sysfs.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 10baf31efe74..097e7e539c9d 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -6,9 +6,14 @@
6#include <linux/gpio/driver.h> 6#include <linux/gpio/driver.h>
7#include <linux/interrupt.h> 7#include <linux/interrupt.h>
8#include <linux/kdev_t.h> 8#include <linux/kdev_t.h>
9#include <linux/slab.h>
9 10
10#include "gpiolib.h" 11#include "gpiolib.h"
11 12
13struct gpiod_data {
14 struct gpio_desc *desc;
15};
16
12static DEFINE_IDR(dirent_idr); 17static DEFINE_IDR(dirent_idr);
13 18
14 19
@@ -41,7 +46,8 @@ static DEFINE_MUTEX(sysfs_lock);
41static ssize_t direction_show(struct device *dev, 46static ssize_t direction_show(struct device *dev,
42 struct device_attribute *attr, char *buf) 47 struct device_attribute *attr, char *buf)
43{ 48{
44 struct gpio_desc *desc = dev_get_drvdata(dev); 49 struct gpiod_data *data = dev_get_drvdata(dev);
50 struct gpio_desc *desc = data->desc;
45 ssize_t status; 51 ssize_t status;
46 52
47 mutex_lock(&sysfs_lock); 53 mutex_lock(&sysfs_lock);
@@ -58,7 +64,8 @@ static ssize_t direction_show(struct device *dev,
58static ssize_t direction_store(struct device *dev, 64static ssize_t direction_store(struct device *dev,
59 struct device_attribute *attr, const char *buf, size_t size) 65 struct device_attribute *attr, const char *buf, size_t size)
60{ 66{
61 struct gpio_desc *desc = dev_get_drvdata(dev); 67 struct gpiod_data *data = dev_get_drvdata(dev);
68 struct gpio_desc *desc = data->desc;
62 ssize_t status; 69 ssize_t status;
63 70
64 mutex_lock(&sysfs_lock); 71 mutex_lock(&sysfs_lock);
@@ -80,7 +87,8 @@ static DEVICE_ATTR_RW(direction);
80static ssize_t value_show(struct device *dev, 87static ssize_t value_show(struct device *dev,
81 struct device_attribute *attr, char *buf) 88 struct device_attribute *attr, char *buf)
82{ 89{
83 struct gpio_desc *desc = dev_get_drvdata(dev); 90 struct gpiod_data *data = dev_get_drvdata(dev);
91 struct gpio_desc *desc = data->desc;
84 ssize_t status; 92 ssize_t status;
85 93
86 mutex_lock(&sysfs_lock); 94 mutex_lock(&sysfs_lock);
@@ -94,7 +102,8 @@ static ssize_t value_show(struct device *dev,
94static ssize_t value_store(struct device *dev, 102static ssize_t value_store(struct device *dev,
95 struct device_attribute *attr, const char *buf, size_t size) 103 struct device_attribute *attr, const char *buf, size_t size)
96{ 104{
97 struct gpio_desc *desc = dev_get_drvdata(dev); 105 struct gpiod_data *data = dev_get_drvdata(dev);
106 struct gpio_desc *desc = data->desc;
98 ssize_t status; 107 ssize_t status;
99 108
100 mutex_lock(&sysfs_lock); 109 mutex_lock(&sysfs_lock);
@@ -225,7 +234,8 @@ static const struct {
225static ssize_t edge_show(struct device *dev, 234static ssize_t edge_show(struct device *dev,
226 struct device_attribute *attr, char *buf) 235 struct device_attribute *attr, char *buf)
227{ 236{
228 const struct gpio_desc *desc = dev_get_drvdata(dev); 237 struct gpiod_data *data = dev_get_drvdata(dev);
238 struct gpio_desc *desc = data->desc;
229 unsigned long mask; 239 unsigned long mask;
230 ssize_t status = 0; 240 ssize_t status = 0;
231 int i; 241 int i;
@@ -247,7 +257,8 @@ static ssize_t edge_show(struct device *dev,
247static ssize_t edge_store(struct device *dev, 257static ssize_t edge_store(struct device *dev,
248 struct device_attribute *attr, const char *buf, size_t size) 258 struct device_attribute *attr, const char *buf, size_t size)
249{ 259{
250 struct gpio_desc *desc = dev_get_drvdata(dev); 260 struct gpiod_data *data = dev_get_drvdata(dev);
261 struct gpio_desc *desc = data->desc;
251 ssize_t status; 262 ssize_t status;
252 int i; 263 int i;
253 264
@@ -297,7 +308,8 @@ static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
297static ssize_t active_low_show(struct device *dev, 308static ssize_t active_low_show(struct device *dev,
298 struct device_attribute *attr, char *buf) 309 struct device_attribute *attr, char *buf)
299{ 310{
300 const struct gpio_desc *desc = dev_get_drvdata(dev); 311 struct gpiod_data *data = dev_get_drvdata(dev);
312 struct gpio_desc *desc = data->desc;
301 ssize_t status; 313 ssize_t status;
302 314
303 mutex_lock(&sysfs_lock); 315 mutex_lock(&sysfs_lock);
@@ -313,7 +325,8 @@ static ssize_t active_low_show(struct device *dev,
313static ssize_t active_low_store(struct device *dev, 325static ssize_t active_low_store(struct device *dev,
314 struct device_attribute *attr, const char *buf, size_t size) 326 struct device_attribute *attr, const char *buf, size_t size)
315{ 327{
316 struct gpio_desc *desc = dev_get_drvdata(dev); 328 struct gpiod_data *data = dev_get_drvdata(dev);
329 struct gpio_desc *desc = data->desc;
317 ssize_t status; 330 ssize_t status;
318 long value; 331 long value;
319 332
@@ -333,7 +346,8 @@ static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr,
333 int n) 346 int n)
334{ 347{
335 struct device *dev = container_of(kobj, struct device, kobj); 348 struct device *dev = container_of(kobj, struct device, kobj);
336 struct gpio_desc *desc = dev_get_drvdata(dev); 349 struct gpiod_data *data = dev_get_drvdata(dev);
350 struct gpio_desc *desc = data->desc;
337 umode_t mode = attr->mode; 351 umode_t mode = attr->mode;
338 bool show_direction = test_bit(FLAG_SYSFS_DIR, &desc->flags); 352 bool show_direction = test_bit(FLAG_SYSFS_DIR, &desc->flags);
339 353
@@ -525,6 +539,7 @@ static struct class gpio_class = {
525int gpiod_export(struct gpio_desc *desc, bool direction_may_change) 539int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
526{ 540{
527 struct gpio_chip *chip; 541 struct gpio_chip *chip;
542 struct gpiod_data *data;
528 unsigned long flags; 543 unsigned long flags;
529 int status; 544 int status;
530 const char *ioname = NULL; 545 const char *ioname = NULL;
@@ -549,7 +564,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
549 /* check if chip is being removed */ 564 /* check if chip is being removed */
550 if (!chip || !chip->cdev) { 565 if (!chip || !chip->cdev) {
551 status = -ENODEV; 566 status = -ENODEV;
552 goto fail_unlock; 567 goto err_unlock;
553 } 568 }
554 569
555 spin_lock_irqsave(&gpio_lock, flags); 570 spin_lock_irqsave(&gpio_lock, flags);
@@ -561,7 +576,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
561 test_bit(FLAG_REQUESTED, &desc->flags), 576 test_bit(FLAG_REQUESTED, &desc->flags),
562 test_bit(FLAG_EXPORT, &desc->flags)); 577 test_bit(FLAG_EXPORT, &desc->flags));
563 status = -EPERM; 578 status = -EPERM;
564 goto fail_unlock; 579 goto err_unlock;
565 } 580 }
566 581
567 if (chip->direction_input && chip->direction_output && 582 if (chip->direction_input && chip->direction_output &&
@@ -571,33 +586,45 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
571 586
572 spin_unlock_irqrestore(&gpio_lock, flags); 587 spin_unlock_irqrestore(&gpio_lock, flags);
573 588
589 data = kzalloc(sizeof(*data), GFP_KERNEL);
590 if (!data) {
591 status = -ENOMEM;
592 goto err_unlock;
593 }
594
595 data->desc = desc;
596
574 offset = gpio_chip_hwgpio(desc); 597 offset = gpio_chip_hwgpio(desc);
575 if (chip->names && chip->names[offset]) 598 if (chip->names && chip->names[offset])
576 ioname = chip->names[offset]; 599 ioname = chip->names[offset];
577 600
578 dev = device_create_with_groups(&gpio_class, chip->dev, 601 dev = device_create_with_groups(&gpio_class, chip->dev,
579 MKDEV(0, 0), desc, gpio_groups, 602 MKDEV(0, 0), data, gpio_groups,
580 ioname ? ioname : "gpio%u", 603 ioname ? ioname : "gpio%u",
581 desc_to_gpio(desc)); 604 desc_to_gpio(desc));
582 if (IS_ERR(dev)) { 605 if (IS_ERR(dev)) {
583 status = PTR_ERR(dev); 606 status = PTR_ERR(dev);
584 goto fail_unlock; 607 goto err_free_data;
585 } 608 }
586 609
587 set_bit(FLAG_EXPORT, &desc->flags); 610 set_bit(FLAG_EXPORT, &desc->flags);
588 mutex_unlock(&sysfs_lock); 611 mutex_unlock(&sysfs_lock);
589 return 0; 612 return 0;
590 613
591fail_unlock: 614err_free_data:
615 kfree(data);
616err_unlock:
592 mutex_unlock(&sysfs_lock); 617 mutex_unlock(&sysfs_lock);
593 gpiod_dbg(desc, "%s: status %d\n", __func__, status); 618 gpiod_dbg(desc, "%s: status %d\n", __func__, status);
594 return status; 619 return status;
595} 620}
596EXPORT_SYMBOL_GPL(gpiod_export); 621EXPORT_SYMBOL_GPL(gpiod_export);
597 622
598static int match_export(struct device *dev, const void *data) 623static int match_export(struct device *dev, const void *desc)
599{ 624{
600 return dev_get_drvdata(dev) == data; 625 struct gpiod_data *data = dev_get_drvdata(dev);
626
627 return data->desc == desc;
601} 628}
602 629
603/** 630/**
@@ -653,6 +680,7 @@ EXPORT_SYMBOL_GPL(gpiod_export_link);
653 */ 680 */
654void gpiod_unexport(struct gpio_desc *desc) 681void gpiod_unexport(struct gpio_desc *desc)
655{ 682{
683 struct gpiod_data *data;
656 int status = 0; 684 int status = 0;
657 struct device *dev = NULL; 685 struct device *dev = NULL;
658 686
@@ -676,6 +704,7 @@ void gpiod_unexport(struct gpio_desc *desc)
676 mutex_unlock(&sysfs_lock); 704 mutex_unlock(&sysfs_lock);
677 705
678 if (dev) { 706 if (dev) {
707 data = dev_get_drvdata(dev);
679 device_unregister(dev); 708 device_unregister(dev);
680 /* 709 /*
681 * Release irq after deregistration to prevent race with 710 * Release irq after deregistration to prevent race with
@@ -683,6 +712,7 @@ void gpiod_unexport(struct gpio_desc *desc)
683 */ 712 */
684 gpio_setup_irq(desc, dev, 0); 713 gpio_setup_irq(desc, dev, 0);
685 put_device(dev); 714 put_device(dev);
715 kfree(data);
686 } 716 }
687 717
688 if (status) 718 if (status)