projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge tag 'md/4.1-rc4-fixes' of git://neil.brown.name/md
[firefly-linux-kernel-4.4.55.git]
/
drivers
/
gpio
/
gpiolib-sysfs.c
diff --git
a/drivers/gpio/gpiolib-sysfs.c
b/drivers/gpio/gpiolib-sysfs.c
index 7722ed53bd651faae15692621d099551ef9bf308..af3bc7a8033bdcbaa2e93602bb107fbe12968d35 100644
(file)
--- a/
drivers/gpio/gpiolib-sysfs.c
+++ b/
drivers/gpio/gpiolib-sysfs.c
@@
-551,6
+551,7
@@
static struct class gpio_class = {
*/
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
{
*/
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
{
+ struct gpio_chip *chip;
unsigned long flags;
int status;
const char *ioname = NULL;
unsigned long flags;
int status;
const char *ioname = NULL;
@@
-568,8
+569,16
@@
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
return -EINVAL;
}
return -EINVAL;
}
+ chip = desc->chip;
+
mutex_lock(&sysfs_lock);
mutex_lock(&sysfs_lock);
+ /* check if chip is being removed */
+ if (!chip || !chip->exported) {
+ status = -ENODEV;
+ goto fail_unlock;
+ }
+
spin_lock_irqsave(&gpio_lock, flags);
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
test_bit(FLAG_EXPORT, &desc->flags)) {
spin_lock_irqsave(&gpio_lock, flags);
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
test_bit(FLAG_EXPORT, &desc->flags)) {
@@
-783,12
+792,15
@@
void gpiochip_unexport(struct gpio_chip *chip)
{
int status;
struct device *dev;
{
int status;
struct device *dev;
+ struct gpio_desc *desc;
+ unsigned int i;
mutex_lock(&sysfs_lock);
dev = class_find_device(&gpio_class, NULL, chip, match_export);
if (dev) {
put_device(dev);
device_unregister(dev);
mutex_lock(&sysfs_lock);
dev = class_find_device(&gpio_class, NULL, chip, match_export);
if (dev) {
put_device(dev);
device_unregister(dev);
+ /* prevent further gpiod exports */
chip->exported = false;
status = 0;
} else
chip->exported = false;
status = 0;
} else
@@
-797,6
+809,13
@@
void gpiochip_unexport(struct gpio_chip *chip)
if (status)
chip_dbg(chip, "%s: status %d\n", __func__, status);
if (status)
chip_dbg(chip, "%s: status %d\n", __func__, status);
+
+ /* unregister gpiod class devices owned by sysfs */
+ for (i = 0; i < chip->ngpio; i++) {
+ desc = &chip->desc[i];
+ if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
+ gpiod_free(desc);
+ }
}
static int __init gpiolib_sysfs_init(void)
}
static int __init gpiolib_sysfs_init(void)