diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 151 |
1 files changed, 84 insertions, 67 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4e51fe3c1fc4..21da9c19a0cb 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/debugfs.h> | 8 | #include <linux/debugfs.h> |
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/of_gpio.h> | ||
11 | #include <linux/idr.h> | 12 | #include <linux/idr.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
13 | 14 | ||
@@ -56,9 +57,9 @@ struct gpio_desc { | |||
56 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ | 57 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ |
57 | #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */ | 58 | #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */ |
58 | 59 | ||
59 | #define PDESC_ID_SHIFT 16 /* add new flags before this one */ | 60 | #define ID_SHIFT 16 /* add new flags before this one */ |
60 | 61 | ||
61 | #define GPIO_FLAGS_MASK ((1 << PDESC_ID_SHIFT) - 1) | 62 | #define GPIO_FLAGS_MASK ((1 << ID_SHIFT) - 1) |
62 | #define GPIO_TRIGGER_MASK (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE)) | 63 | #define GPIO_TRIGGER_MASK (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE)) |
63 | 64 | ||
64 | #ifdef CONFIG_DEBUG_FS | 65 | #ifdef CONFIG_DEBUG_FS |
@@ -68,12 +69,7 @@ struct gpio_desc { | |||
68 | static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; | 69 | static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; |
69 | 70 | ||
70 | #ifdef CONFIG_GPIO_SYSFS | 71 | #ifdef CONFIG_GPIO_SYSFS |
71 | struct poll_desc { | 72 | static DEFINE_IDR(dirent_idr); |
72 | struct work_struct work; | ||
73 | struct sysfs_dirent *value_sd; | ||
74 | }; | ||
75 | |||
76 | static struct idr pdesc_idr; | ||
77 | #endif | 73 | #endif |
78 | 74 | ||
79 | static inline void desc_set_label(struct gpio_desc *d, const char *label) | 75 | static inline void desc_set_label(struct gpio_desc *d, const char *label) |
@@ -324,24 +320,16 @@ static const DEVICE_ATTR(value, 0644, | |||
324 | 320 | ||
325 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) | 321 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) |
326 | { | 322 | { |
327 | struct work_struct *work = priv; | 323 | struct sysfs_dirent *value_sd = priv; |
328 | 324 | ||
329 | schedule_work(work); | 325 | sysfs_notify_dirent(value_sd); |
330 | return IRQ_HANDLED; | 326 | return IRQ_HANDLED; |
331 | } | 327 | } |
332 | 328 | ||
333 | static void gpio_notify_sysfs(struct work_struct *work) | ||
334 | { | ||
335 | struct poll_desc *pdesc; | ||
336 | |||
337 | pdesc = container_of(work, struct poll_desc, work); | ||
338 | sysfs_notify_dirent(pdesc->value_sd); | ||
339 | } | ||
340 | |||
341 | static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | 329 | static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, |
342 | unsigned long gpio_flags) | 330 | unsigned long gpio_flags) |
343 | { | 331 | { |
344 | struct poll_desc *pdesc; | 332 | struct sysfs_dirent *value_sd; |
345 | unsigned long irq_flags; | 333 | unsigned long irq_flags; |
346 | int ret, irq, id; | 334 | int ret, irq, id; |
347 | 335 | ||
@@ -352,18 +340,16 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | |||
352 | if (irq < 0) | 340 | if (irq < 0) |
353 | return -EIO; | 341 | return -EIO; |
354 | 342 | ||
355 | id = desc->flags >> PDESC_ID_SHIFT; | 343 | id = desc->flags >> ID_SHIFT; |
356 | pdesc = idr_find(&pdesc_idr, id); | 344 | value_sd = idr_find(&dirent_idr, id); |
357 | if (pdesc) { | 345 | if (value_sd) |
358 | free_irq(irq, &pdesc->work); | 346 | free_irq(irq, value_sd); |
359 | cancel_work_sync(&pdesc->work); | ||
360 | } | ||
361 | 347 | ||
362 | desc->flags &= ~GPIO_TRIGGER_MASK; | 348 | desc->flags &= ~GPIO_TRIGGER_MASK; |
363 | 349 | ||
364 | if (!gpio_flags) { | 350 | if (!gpio_flags) { |
365 | ret = 0; | 351 | ret = 0; |
366 | goto free_sd; | 352 | goto free_id; |
367 | } | 353 | } |
368 | 354 | ||
369 | irq_flags = IRQF_SHARED; | 355 | irq_flags = IRQF_SHARED; |
@@ -374,55 +360,46 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | |||
374 | irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? | 360 | irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? |
375 | IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; | 361 | IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; |
376 | 362 | ||
377 | if (!pdesc) { | 363 | if (!value_sd) { |
378 | pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL); | 364 | value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value"); |
379 | if (!pdesc) { | 365 | if (!value_sd) { |
380 | ret = -ENOMEM; | 366 | ret = -ENODEV; |
381 | goto err_out; | 367 | goto err_out; |
382 | } | 368 | } |
383 | 369 | ||
384 | do { | 370 | do { |
385 | ret = -ENOMEM; | 371 | ret = -ENOMEM; |
386 | if (idr_pre_get(&pdesc_idr, GFP_KERNEL)) | 372 | if (idr_pre_get(&dirent_idr, GFP_KERNEL)) |
387 | ret = idr_get_new_above(&pdesc_idr, | 373 | ret = idr_get_new_above(&dirent_idr, value_sd, |
388 | pdesc, 1, &id); | 374 | 1, &id); |
389 | } while (ret == -EAGAIN); | 375 | } while (ret == -EAGAIN); |
390 | 376 | ||
391 | if (ret) | 377 | if (ret) |
392 | goto free_mem; | 378 | goto free_sd; |
393 | 379 | ||
394 | desc->flags &= GPIO_FLAGS_MASK; | 380 | desc->flags &= GPIO_FLAGS_MASK; |
395 | desc->flags |= (unsigned long)id << PDESC_ID_SHIFT; | 381 | desc->flags |= (unsigned long)id << ID_SHIFT; |
396 | 382 | ||
397 | if (desc->flags >> PDESC_ID_SHIFT != id) { | 383 | if (desc->flags >> ID_SHIFT != id) { |
398 | ret = -ERANGE; | 384 | ret = -ERANGE; |
399 | goto free_id; | 385 | goto free_id; |
400 | } | 386 | } |
401 | |||
402 | pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value"); | ||
403 | if (!pdesc->value_sd) { | ||
404 | ret = -ENODEV; | ||
405 | goto free_id; | ||
406 | } | ||
407 | INIT_WORK(&pdesc->work, gpio_notify_sysfs); | ||
408 | } | 387 | } |
409 | 388 | ||
410 | ret = request_irq(irq, gpio_sysfs_irq, irq_flags, | 389 | ret = request_any_context_irq(irq, gpio_sysfs_irq, irq_flags, |
411 | "gpiolib", &pdesc->work); | 390 | "gpiolib", value_sd); |
412 | if (ret) | 391 | if (ret < 0) |
413 | goto free_sd; | 392 | goto free_id; |
414 | 393 | ||
415 | desc->flags |= gpio_flags; | 394 | desc->flags |= gpio_flags; |
416 | return 0; | 395 | return 0; |
417 | 396 | ||
418 | free_sd: | ||
419 | if (pdesc) | ||
420 | sysfs_put(pdesc->value_sd); | ||
421 | free_id: | 397 | free_id: |
422 | idr_remove(&pdesc_idr, id); | 398 | idr_remove(&dirent_idr, id); |
423 | desc->flags &= GPIO_FLAGS_MASK; | 399 | desc->flags &= GPIO_FLAGS_MASK; |
424 | free_mem: | 400 | free_sd: |
425 | kfree(pdesc); | 401 | if (value_sd) |
402 | sysfs_put(value_sd); | ||
426 | err_out: | 403 | err_out: |
427 | return ret; | 404 | return ret; |
428 | } | 405 | } |
@@ -993,8 +970,6 @@ static int __init gpiolib_sysfs_init(void) | |||
993 | unsigned long flags; | 970 | unsigned long flags; |
994 | unsigned gpio; | 971 | unsigned gpio; |
995 | 972 | ||
996 | idr_init(&pdesc_idr); | ||
997 | |||
998 | status = class_register(&gpio_class); | 973 | status = class_register(&gpio_class); |
999 | if (status < 0) | 974 | if (status < 0) |
1000 | return status; | 975 | return status; |
@@ -1100,16 +1075,24 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1100 | } | 1075 | } |
1101 | } | 1076 | } |
1102 | 1077 | ||
1078 | of_gpiochip_add(chip); | ||
1079 | |||
1103 | unlock: | 1080 | unlock: |
1104 | spin_unlock_irqrestore(&gpio_lock, flags); | 1081 | spin_unlock_irqrestore(&gpio_lock, flags); |
1105 | if (status == 0) | 1082 | |
1106 | status = gpiochip_export(chip); | 1083 | if (status) |
1084 | goto fail; | ||
1085 | |||
1086 | status = gpiochip_export(chip); | ||
1087 | if (status) | ||
1088 | goto fail; | ||
1089 | |||
1090 | return 0; | ||
1107 | fail: | 1091 | fail: |
1108 | /* failures here can mean systems won't boot... */ | 1092 | /* failures here can mean systems won't boot... */ |
1109 | if (status) | 1093 | pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", |
1110 | pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", | 1094 | chip->base, chip->base + chip->ngpio - 1, |
1111 | chip->base, chip->base + chip->ngpio - 1, | 1095 | chip->label ? : "generic"); |
1112 | chip->label ? : "generic"); | ||
1113 | return status; | 1096 | return status; |
1114 | } | 1097 | } |
1115 | EXPORT_SYMBOL_GPL(gpiochip_add); | 1098 | EXPORT_SYMBOL_GPL(gpiochip_add); |
@@ -1128,6 +1111,8 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
1128 | 1111 | ||
1129 | spin_lock_irqsave(&gpio_lock, flags); | 1112 | spin_lock_irqsave(&gpio_lock, flags); |
1130 | 1113 | ||
1114 | of_gpiochip_remove(chip); | ||
1115 | |||
1131 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 1116 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { |
1132 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { | 1117 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { |
1133 | status = -EBUSY; | 1118 | status = -EBUSY; |
@@ -1148,6 +1133,38 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
1148 | } | 1133 | } |
1149 | EXPORT_SYMBOL_GPL(gpiochip_remove); | 1134 | EXPORT_SYMBOL_GPL(gpiochip_remove); |
1150 | 1135 | ||
1136 | /** | ||
1137 | * gpiochip_find() - iterator for locating a specific gpio_chip | ||
1138 | * @data: data to pass to match function | ||
1139 | * @callback: Callback function to check gpio_chip | ||
1140 | * | ||
1141 | * Similar to bus_find_device. It returns a reference to a gpio_chip as | ||
1142 | * determined by a user supplied @match callback. The callback should return | ||
1143 | * 0 if the device doesn't match and non-zero if it does. If the callback is | ||
1144 | * non-zero, this function will return to the caller and not iterate over any | ||
1145 | * more gpio_chips. | ||
1146 | */ | ||
1147 | struct gpio_chip *gpiochip_find(void *data, | ||
1148 | int (*match)(struct gpio_chip *chip, void *data)) | ||
1149 | { | ||
1150 | struct gpio_chip *chip = NULL; | ||
1151 | unsigned long flags; | ||
1152 | int i; | ||
1153 | |||
1154 | spin_lock_irqsave(&gpio_lock, flags); | ||
1155 | for (i = 0; i < ARCH_NR_GPIOS; i++) { | ||
1156 | if (!gpio_desc[i].chip) | ||
1157 | continue; | ||
1158 | |||
1159 | if (match(gpio_desc[i].chip, data)) { | ||
1160 | chip = gpio_desc[i].chip; | ||
1161 | break; | ||
1162 | } | ||
1163 | } | ||
1164 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
1165 | |||
1166 | return chip; | ||
1167 | } | ||
1151 | 1168 | ||
1152 | /* These "optional" allocation calls help prevent drivers from stomping | 1169 | /* These "optional" allocation calls help prevent drivers from stomping |
1153 | * on each other, and help provide better diagnostics in debugfs. | 1170 | * on each other, and help provide better diagnostics in debugfs. |
@@ -1229,7 +1246,7 @@ void gpio_free(unsigned gpio) | |||
1229 | if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) { | 1246 | if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) { |
1230 | if (chip->free) { | 1247 | if (chip->free) { |
1231 | spin_unlock_irqrestore(&gpio_lock, flags); | 1248 | spin_unlock_irqrestore(&gpio_lock, flags); |
1232 | might_sleep_if(extra_checks && chip->can_sleep); | 1249 | might_sleep_if(chip->can_sleep); |
1233 | chip->free(chip, gpio - chip->base); | 1250 | chip->free(chip, gpio - chip->base); |
1234 | spin_lock_irqsave(&gpio_lock, flags); | 1251 | spin_lock_irqsave(&gpio_lock, flags); |
1235 | } | 1252 | } |
@@ -1367,7 +1384,7 @@ int gpio_direction_input(unsigned gpio) | |||
1367 | 1384 | ||
1368 | spin_unlock_irqrestore(&gpio_lock, flags); | 1385 | spin_unlock_irqrestore(&gpio_lock, flags); |
1369 | 1386 | ||
1370 | might_sleep_if(extra_checks && chip->can_sleep); | 1387 | might_sleep_if(chip->can_sleep); |
1371 | 1388 | ||
1372 | if (status) { | 1389 | if (status) { |
1373 | status = chip->request(chip, gpio); | 1390 | status = chip->request(chip, gpio); |
@@ -1420,7 +1437,7 @@ int gpio_direction_output(unsigned gpio, int value) | |||
1420 | 1437 | ||
1421 | spin_unlock_irqrestore(&gpio_lock, flags); | 1438 | spin_unlock_irqrestore(&gpio_lock, flags); |
1422 | 1439 | ||
1423 | might_sleep_if(extra_checks && chip->can_sleep); | 1440 | might_sleep_if(chip->can_sleep); |
1424 | 1441 | ||
1425 | if (status) { | 1442 | if (status) { |
1426 | status = chip->request(chip, gpio); | 1443 | status = chip->request(chip, gpio); |
@@ -1478,7 +1495,7 @@ int gpio_set_debounce(unsigned gpio, unsigned debounce) | |||
1478 | 1495 | ||
1479 | spin_unlock_irqrestore(&gpio_lock, flags); | 1496 | spin_unlock_irqrestore(&gpio_lock, flags); |
1480 | 1497 | ||
1481 | might_sleep_if(extra_checks && chip->can_sleep); | 1498 | might_sleep_if(chip->can_sleep); |
1482 | 1499 | ||
1483 | return chip->set_debounce(chip, gpio, debounce); | 1500 | return chip->set_debounce(chip, gpio, debounce); |
1484 | 1501 | ||
@@ -1528,7 +1545,7 @@ int __gpio_get_value(unsigned gpio) | |||
1528 | struct gpio_chip *chip; | 1545 | struct gpio_chip *chip; |
1529 | 1546 | ||
1530 | chip = gpio_to_chip(gpio); | 1547 | chip = gpio_to_chip(gpio); |
1531 | WARN_ON(extra_checks && chip->can_sleep); | 1548 | WARN_ON(chip->can_sleep); |
1532 | return chip->get ? chip->get(chip, gpio - chip->base) : 0; | 1549 | return chip->get ? chip->get(chip, gpio - chip->base) : 0; |
1533 | } | 1550 | } |
1534 | EXPORT_SYMBOL_GPL(__gpio_get_value); | 1551 | EXPORT_SYMBOL_GPL(__gpio_get_value); |
@@ -1547,7 +1564,7 @@ void __gpio_set_value(unsigned gpio, int value) | |||
1547 | struct gpio_chip *chip; | 1564 | struct gpio_chip *chip; |
1548 | 1565 | ||
1549 | chip = gpio_to_chip(gpio); | 1566 | chip = gpio_to_chip(gpio); |
1550 | WARN_ON(extra_checks && chip->can_sleep); | 1567 | WARN_ON(chip->can_sleep); |
1551 | chip->set(chip, gpio - chip->base, value); | 1568 | chip->set(chip, gpio - chip->base, value); |
1552 | } | 1569 | } |
1553 | EXPORT_SYMBOL_GPL(__gpio_set_value); | 1570 | EXPORT_SYMBOL_GPL(__gpio_set_value); |