.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | #include <linux/idr.h> |
---|
2 | 3 | #include <linux/mutex.h> |
---|
3 | 4 | #include <linux/device.h> |
---|
4 | 5 | #include <linux/sysfs.h> |
---|
5 | | -#include <linux/gpio.h> |
---|
6 | 6 | #include <linux/gpio/consumer.h> |
---|
7 | 7 | #include <linux/gpio/driver.h> |
---|
8 | 8 | #include <linux/interrupt.h> |
---|
.. | .. |
---|
11 | 11 | #include <linux/ctype.h> |
---|
12 | 12 | |
---|
13 | 13 | #include "gpiolib.h" |
---|
| 14 | +#include "gpiolib-sysfs.h" |
---|
14 | 15 | |
---|
15 | 16 | #define GPIO_IRQF_TRIGGER_FALLING BIT(0) |
---|
16 | 17 | #define GPIO_IRQF_TRIGGER_RISING BIT(1) |
---|
.. | .. |
---|
80 | 81 | struct gpiod_data *data = dev_get_drvdata(dev); |
---|
81 | 82 | struct gpio_desc *desc = data->desc; |
---|
82 | 83 | ssize_t status; |
---|
| 84 | + int offset; |
---|
83 | 85 | |
---|
84 | 86 | mutex_lock(&data->mutex); |
---|
85 | | - |
---|
| 87 | + offset = gpio_chip_hwgpio(desc); |
---|
86 | 88 | if (sysfs_streq(buf, "high")) |
---|
87 | 89 | status = gpiod_direction_output_raw(desc, 1); |
---|
88 | 90 | else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low")) |
---|
89 | | - status = gpiod_direction_output_raw(desc, 0); |
---|
| 91 | + if (( offset == 8 ) || ( offset == 11 ) || ( offset == 12 ) || ( offset == 13 ) || ( offset == 14 )) |
---|
| 92 | + status = gpiod_direction_output_raw(desc, 1); |
---|
| 93 | + else |
---|
| 94 | + status = gpiod_direction_output_raw(desc, 0); |
---|
90 | 95 | else if (sysfs_streq(buf, "in")) |
---|
91 | 96 | status = gpiod_direction_input(desc); |
---|
92 | 97 | else |
---|
.. | .. |
---|
365 | 370 | static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, |
---|
366 | 371 | int n) |
---|
367 | 372 | { |
---|
368 | | - struct device *dev = container_of(kobj, struct device, kobj); |
---|
| 373 | + struct device *dev = kobj_to_dev(kobj); |
---|
369 | 374 | struct gpiod_data *data = dev_get_drvdata(dev); |
---|
370 | 375 | struct gpio_desc *desc = data->desc; |
---|
371 | 376 | umode_t mode = attr->mode; |
---|
.. | .. |
---|
444 | 449 | }; |
---|
445 | 450 | ATTRIBUTE_GROUPS(gpiochip); |
---|
446 | 451 | |
---|
447 | | -static struct gpio_desc *gpio_to_valid_desc(int gpio) |
---|
448 | | -{ |
---|
449 | | - return gpio_is_valid(gpio) ? gpio_to_desc(gpio) : NULL; |
---|
450 | | -} |
---|
451 | | - |
---|
452 | 452 | /* |
---|
453 | 453 | * /sys/class/gpio/export ... write-only |
---|
454 | 454 | * integer N ... number of GPIO to export (full access) |
---|
.. | .. |
---|
469 | 469 | if (status < 0) |
---|
470 | 470 | goto done; |
---|
471 | 471 | |
---|
472 | | - desc = gpio_to_valid_desc(gpio); |
---|
| 472 | + desc = gpio_to_desc(gpio); |
---|
473 | 473 | /* reject invalid GPIOs */ |
---|
474 | 474 | if (!desc) { |
---|
475 | 475 | pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); |
---|
.. | .. |
---|
522 | 522 | if (status < 0) |
---|
523 | 523 | goto done; |
---|
524 | 524 | |
---|
525 | | - desc = gpio_to_valid_desc(gpio); |
---|
| 525 | + desc = gpio_to_desc(gpio); |
---|
526 | 526 | /* reject bogus commands (gpio_unexport ignores them) */ |
---|
527 | 527 | if (!desc) { |
---|
528 | 528 | pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); |
---|
.. | .. |
---|
775 | 775 | parent = &gdev->dev; |
---|
776 | 776 | |
---|
777 | 777 | /* use chip->base for the ID; it's already known to be unique */ |
---|
778 | | - dev = device_create_with_groups(&gpio_class, parent, |
---|
779 | | - MKDEV(0, 0), |
---|
780 | | - chip, gpiochip_groups, |
---|
781 | | - "gpiochip%d", chip->base); |
---|
| 778 | + dev = device_create_with_groups(&gpio_class, parent, MKDEV(0, 0), chip, |
---|
| 779 | + gpiochip_groups, GPIOCHIP_NAME "%d", |
---|
| 780 | + chip->base); |
---|
782 | 781 | if (IS_ERR(dev)) |
---|
783 | 782 | return PTR_ERR(dev); |
---|
784 | 783 | |
---|