diff options
-rw-r--r-- | drivers/pinctrl/core.c | 198 | ||||
-rw-r--r-- | drivers/pinctrl/core.h | 10 | ||||
-rw-r--r-- | drivers/pinctrl/pinconf.c | 107 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.c | 21 | ||||
-rw-r--r-- | include/linux/pinctrl/pinctrl.h | 1 |
5 files changed, 215 insertions, 122 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 6af6d8d117df..aefc3394db91 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -18,11 +18,8 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/radix-tree.h> | ||
22 | #include <linux/err.h> | 21 | #include <linux/err.h> |
23 | #include <linux/list.h> | 22 | #include <linux/list.h> |
24 | #include <linux/mutex.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
27 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
28 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
@@ -44,16 +41,16 @@ struct pinctrl_maps { | |||
44 | unsigned num_maps; | 41 | unsigned num_maps; |
45 | }; | 42 | }; |
46 | 43 | ||
47 | /* Global list of pin control devices */ | 44 | /* Mutex taken by all entry points */ |
48 | static DEFINE_MUTEX(pinctrldev_list_mutex); | 45 | DEFINE_MUTEX(pinctrl_mutex); |
46 | |||
47 | /* Global list of pin control devices (struct pinctrl_dev) */ | ||
49 | static LIST_HEAD(pinctrldev_list); | 48 | static LIST_HEAD(pinctrldev_list); |
50 | 49 | ||
51 | /* List of pin controller handles */ | 50 | /* List of pin controller handles (struct pinctrl) */ |
52 | static DEFINE_MUTEX(pinctrl_list_mutex); | ||
53 | static LIST_HEAD(pinctrl_list); | 51 | static LIST_HEAD(pinctrl_list); |
54 | 52 | ||
55 | /* Global pinctrl maps */ | 53 | /* List of pinctrl maps (struct pinctrl_maps) */ |
56 | static DEFINE_MUTEX(pinctrl_maps_mutex); | ||
57 | static LIST_HEAD(pinctrl_maps); | 54 | static LIST_HEAD(pinctrl_maps); |
58 | 55 | ||
59 | #define for_each_maps(_maps_node_, _i_, _map_) \ | 56 | #define for_each_maps(_maps_node_, _i_, _map_) \ |
@@ -90,7 +87,6 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) | |||
90 | if (!devname) | 87 | if (!devname) |
91 | return NULL; | 88 | return NULL; |
92 | 89 | ||
93 | mutex_lock(&pinctrldev_list_mutex); | ||
94 | list_for_each_entry(pctldev, &pinctrldev_list, node) { | 90 | list_for_each_entry(pctldev, &pinctrldev_list, node) { |
95 | if (!strcmp(dev_name(pctldev->dev), devname)) { | 91 | if (!strcmp(dev_name(pctldev->dev), devname)) { |
96 | /* Matched on device name */ | 92 | /* Matched on device name */ |
@@ -98,7 +94,6 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) | |||
98 | break; | 94 | break; |
99 | } | 95 | } |
100 | } | 96 | } |
101 | mutex_unlock(&pinctrldev_list_mutex); | ||
102 | 97 | ||
103 | return found ? pctldev : NULL; | 98 | return found ? pctldev : NULL; |
104 | } | 99 | } |
@@ -143,11 +138,11 @@ bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) | |||
143 | if (pin < 0) | 138 | if (pin < 0) |
144 | return false; | 139 | return false; |
145 | 140 | ||
141 | mutex_lock(&pinctrl_mutex); | ||
146 | pindesc = pin_desc_get(pctldev, pin); | 142 | pindesc = pin_desc_get(pctldev, pin); |
147 | if (pindesc == NULL) | 143 | mutex_unlock(&pinctrl_mutex); |
148 | return false; | ||
149 | 144 | ||
150 | return true; | 145 | return pindesc != NULL; |
151 | } | 146 | } |
152 | EXPORT_SYMBOL_GPL(pin_is_valid); | 147 | EXPORT_SYMBOL_GPL(pin_is_valid); |
153 | 148 | ||
@@ -191,8 +186,6 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, | |||
191 | return -ENOMEM; | 186 | return -ENOMEM; |
192 | } | 187 | } |
193 | 188 | ||
194 | spin_lock_init(&pindesc->lock); | ||
195 | |||
196 | /* Set owner */ | 189 | /* Set owner */ |
197 | pindesc->pctldev = pctldev; | 190 | pindesc->pctldev = pctldev; |
198 | 191 | ||
@@ -243,16 +236,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) | |||
243 | struct pinctrl_gpio_range *range = NULL; | 236 | struct pinctrl_gpio_range *range = NULL; |
244 | 237 | ||
245 | /* Loop over the ranges */ | 238 | /* Loop over the ranges */ |
246 | mutex_lock(&pctldev->gpio_ranges_lock); | ||
247 | list_for_each_entry(range, &pctldev->gpio_ranges, node) { | 239 | list_for_each_entry(range, &pctldev->gpio_ranges, node) { |
248 | /* Check if we're in the valid range */ | 240 | /* Check if we're in the valid range */ |
249 | if (gpio >= range->base && | 241 | if (gpio >= range->base && |
250 | gpio < range->base + range->npins) { | 242 | gpio < range->base + range->npins) { |
251 | mutex_unlock(&pctldev->gpio_ranges_lock); | ||
252 | return range; | 243 | return range; |
253 | } | 244 | } |
254 | } | 245 | } |
255 | mutex_unlock(&pctldev->gpio_ranges_lock); | ||
256 | 246 | ||
257 | return NULL; | 247 | return NULL; |
258 | } | 248 | } |
@@ -274,7 +264,6 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, | |||
274 | struct pinctrl_dev *pctldev = NULL; | 264 | struct pinctrl_dev *pctldev = NULL; |
275 | 265 | ||
276 | /* Loop over the pin controllers */ | 266 | /* Loop over the pin controllers */ |
277 | mutex_lock(&pinctrldev_list_mutex); | ||
278 | list_for_each_entry(pctldev, &pinctrldev_list, node) { | 267 | list_for_each_entry(pctldev, &pinctrldev_list, node) { |
279 | struct pinctrl_gpio_range *range; | 268 | struct pinctrl_gpio_range *range; |
280 | 269 | ||
@@ -282,11 +271,9 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, | |||
282 | if (range != NULL) { | 271 | if (range != NULL) { |
283 | *outdev = pctldev; | 272 | *outdev = pctldev; |
284 | *outrange = range; | 273 | *outrange = range; |
285 | mutex_unlock(&pinctrldev_list_mutex); | ||
286 | return 0; | 274 | return 0; |
287 | } | 275 | } |
288 | } | 276 | } |
289 | mutex_unlock(&pinctrldev_list_mutex); | ||
290 | 277 | ||
291 | return -EINVAL; | 278 | return -EINVAL; |
292 | } | 279 | } |
@@ -302,9 +289,9 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, | |||
302 | void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, | 289 | void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, |
303 | struct pinctrl_gpio_range *range) | 290 | struct pinctrl_gpio_range *range) |
304 | { | 291 | { |
305 | mutex_lock(&pctldev->gpio_ranges_lock); | 292 | mutex_lock(&pinctrl_mutex); |
306 | list_add_tail(&range->node, &pctldev->gpio_ranges); | 293 | list_add_tail(&range->node, &pctldev->gpio_ranges); |
307 | mutex_unlock(&pctldev->gpio_ranges_lock); | 294 | mutex_unlock(&pinctrl_mutex); |
308 | } | 295 | } |
309 | EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); | 296 | EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); |
310 | 297 | ||
@@ -316,9 +303,9 @@ EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); | |||
316 | void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, | 303 | void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, |
317 | struct pinctrl_gpio_range *range) | 304 | struct pinctrl_gpio_range *range) |
318 | { | 305 | { |
319 | mutex_lock(&pctldev->gpio_ranges_lock); | 306 | mutex_lock(&pinctrl_mutex); |
320 | list_del(&range->node); | 307 | list_del(&range->node); |
321 | mutex_unlock(&pctldev->gpio_ranges_lock); | 308 | mutex_unlock(&pinctrl_mutex); |
322 | } | 309 | } |
323 | EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); | 310 | EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); |
324 | 311 | ||
@@ -368,14 +355,21 @@ int pinctrl_request_gpio(unsigned gpio) | |||
368 | int ret; | 355 | int ret; |
369 | int pin; | 356 | int pin; |
370 | 357 | ||
358 | mutex_lock(&pinctrl_mutex); | ||
359 | |||
371 | ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); | 360 | ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); |
372 | if (ret) | 361 | if (ret) { |
362 | mutex_unlock(&pinctrl_mutex); | ||
373 | return -EINVAL; | 363 | return -EINVAL; |
364 | } | ||
374 | 365 | ||
375 | /* Convert to the pin controllers number space */ | 366 | /* Convert to the pin controllers number space */ |
376 | pin = gpio - range->base + range->pin_base; | 367 | pin = gpio - range->base + range->pin_base; |
377 | 368 | ||
378 | return pinmux_request_gpio(pctldev, range, pin, gpio); | 369 | ret = pinmux_request_gpio(pctldev, range, pin, gpio); |
370 | |||
371 | mutex_unlock(&pinctrl_mutex); | ||
372 | return ret; | ||
379 | } | 373 | } |
380 | EXPORT_SYMBOL_GPL(pinctrl_request_gpio); | 374 | EXPORT_SYMBOL_GPL(pinctrl_request_gpio); |
381 | 375 | ||
@@ -394,14 +388,20 @@ void pinctrl_free_gpio(unsigned gpio) | |||
394 | int ret; | 388 | int ret; |
395 | int pin; | 389 | int pin; |
396 | 390 | ||
391 | mutex_lock(&pinctrl_mutex); | ||
392 | |||
397 | ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); | 393 | ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); |
398 | if (ret) | 394 | if (ret) { |
395 | mutex_unlock(&pinctrl_mutex); | ||
399 | return; | 396 | return; |
397 | } | ||
400 | 398 | ||
401 | /* Convert to the pin controllers number space */ | 399 | /* Convert to the pin controllers number space */ |
402 | pin = gpio - range->base + range->pin_base; | 400 | pin = gpio - range->base + range->pin_base; |
403 | 401 | ||
404 | return pinmux_free_gpio(pctldev, pin, range); | 402 | pinmux_free_gpio(pctldev, pin, range); |
403 | |||
404 | mutex_unlock(&pinctrl_mutex); | ||
405 | } | 405 | } |
406 | EXPORT_SYMBOL_GPL(pinctrl_free_gpio); | 406 | EXPORT_SYMBOL_GPL(pinctrl_free_gpio); |
407 | 407 | ||
@@ -432,7 +432,11 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) | |||
432 | */ | 432 | */ |
433 | int pinctrl_gpio_direction_input(unsigned gpio) | 433 | int pinctrl_gpio_direction_input(unsigned gpio) |
434 | { | 434 | { |
435 | return pinctrl_gpio_direction(gpio, true); | 435 | int ret; |
436 | mutex_lock(&pinctrl_mutex); | ||
437 | ret = pinctrl_gpio_direction(gpio, true); | ||
438 | mutex_unlock(&pinctrl_mutex); | ||
439 | return ret; | ||
436 | } | 440 | } |
437 | EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); | 441 | EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); |
438 | 442 | ||
@@ -446,7 +450,11 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); | |||
446 | */ | 450 | */ |
447 | int pinctrl_gpio_direction_output(unsigned gpio) | 451 | int pinctrl_gpio_direction_output(unsigned gpio) |
448 | { | 452 | { |
449 | return pinctrl_gpio_direction(gpio, false); | 453 | int ret; |
454 | mutex_lock(&pinctrl_mutex); | ||
455 | ret = pinctrl_gpio_direction(gpio, false); | ||
456 | mutex_unlock(&pinctrl_mutex); | ||
457 | return ret; | ||
450 | } | 458 | } |
451 | EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); | 459 | EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); |
452 | 460 | ||
@@ -479,7 +487,6 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) | |||
479 | dev_err(dev, "failed to alloc struct pinctrl\n"); | 487 | dev_err(dev, "failed to alloc struct pinctrl\n"); |
480 | return ERR_PTR(-ENOMEM); | 488 | return ERR_PTR(-ENOMEM); |
481 | } | 489 | } |
482 | mutex_init(&p->mutex); | ||
483 | pinmux_init_pinctrl_handle(p); | 490 | pinmux_init_pinctrl_handle(p); |
484 | 491 | ||
485 | /* Iterate over the pin control maps to locate the right ones */ | 492 | /* Iterate over the pin control maps to locate the right ones */ |
@@ -531,9 +538,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) | |||
531 | num_maps, devname, name ? name : "(undefined)"); | 538 | num_maps, devname, name ? name : "(undefined)"); |
532 | 539 | ||
533 | /* Add the pinmux to the global list */ | 540 | /* Add the pinmux to the global list */ |
534 | mutex_lock(&pinctrl_list_mutex); | ||
535 | list_add_tail(&p->node, &pinctrl_list); | 541 | list_add_tail(&p->node, &pinctrl_list); |
536 | mutex_unlock(&pinctrl_list_mutex); | ||
537 | 542 | ||
538 | return p; | 543 | return p; |
539 | } | 544 | } |
@@ -549,74 +554,91 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name) | |||
549 | { | 554 | { |
550 | struct pinctrl *p; | 555 | struct pinctrl *p; |
551 | 556 | ||
552 | mutex_lock(&pinctrl_maps_mutex); | 557 | mutex_lock(&pinctrl_mutex); |
553 | p = pinctrl_get_locked(dev, name); | 558 | p = pinctrl_get_locked(dev, name); |
554 | mutex_unlock(&pinctrl_maps_mutex); | 559 | mutex_unlock(&pinctrl_mutex); |
555 | 560 | ||
556 | return p; | 561 | return p; |
557 | } | 562 | } |
558 | EXPORT_SYMBOL_GPL(pinctrl_get); | 563 | EXPORT_SYMBOL_GPL(pinctrl_get); |
559 | 564 | ||
560 | /** | 565 | static void pinctrl_put_locked(struct pinctrl *p) |
561 | * pinctrl_put() - release a previously claimed pin control handle | ||
562 | * @p: a pin control handle previously claimed by pinctrl_get() | ||
563 | */ | ||
564 | void pinctrl_put(struct pinctrl *p) | ||
565 | { | 566 | { |
566 | if (p == NULL) | 567 | if (p == NULL) |
567 | return; | 568 | return; |
568 | 569 | ||
569 | mutex_lock(&p->mutex); | ||
570 | if (p->usecount) | 570 | if (p->usecount) |
571 | pr_warn("releasing pin control handle with active users!\n"); | 571 | pr_warn("releasing pin control handle with active users!\n"); |
572 | /* Free the groups and all acquired pins */ | 572 | /* Free the groups and all acquired pins */ |
573 | pinmux_put(p); | 573 | pinmux_put(p); |
574 | mutex_unlock(&p->mutex); | ||
575 | 574 | ||
576 | /* Remove from list */ | 575 | /* Remove from list */ |
577 | mutex_lock(&pinctrl_list_mutex); | ||
578 | list_del(&p->node); | 576 | list_del(&p->node); |
579 | mutex_unlock(&pinctrl_list_mutex); | ||
580 | 577 | ||
581 | kfree(p); | 578 | kfree(p); |
582 | } | 579 | } |
583 | EXPORT_SYMBOL_GPL(pinctrl_put); | ||
584 | 580 | ||
585 | /** | 581 | /** |
586 | * pinctrl_enable() - enable a certain pin controller setting | 582 | * pinctrl_put() - release a previously claimed pin control handle |
587 | * @p: the pin control handle to enable, previously claimed by pinctrl_get() | 583 | * @p: a pin control handle previously claimed by pinctrl_get() |
588 | */ | 584 | */ |
589 | int pinctrl_enable(struct pinctrl *p) | 585 | void pinctrl_put(struct pinctrl *p) |
586 | { | ||
587 | mutex_lock(&pinctrl_mutex); | ||
588 | pinctrl_put(p); | ||
589 | mutex_unlock(&pinctrl_mutex); | ||
590 | } | ||
591 | EXPORT_SYMBOL_GPL(pinctrl_put); | ||
592 | |||
593 | static int pinctrl_enable_locked(struct pinctrl *p) | ||
590 | { | 594 | { |
591 | int ret = 0; | 595 | int ret = 0; |
592 | 596 | ||
593 | if (p == NULL) | 597 | if (p == NULL) |
594 | return -EINVAL; | 598 | return -EINVAL; |
595 | mutex_lock(&p->mutex); | 599 | |
596 | if (p->usecount++ == 0) { | 600 | if (p->usecount++ == 0) { |
597 | ret = pinmux_enable(p); | 601 | ret = pinmux_enable(p); |
598 | if (ret) | 602 | if (ret) |
599 | p->usecount--; | 603 | p->usecount--; |
600 | } | 604 | } |
601 | mutex_unlock(&p->mutex); | 605 | |
602 | return ret; | 606 | return ret; |
603 | } | 607 | } |
604 | EXPORT_SYMBOL_GPL(pinctrl_enable); | ||
605 | 608 | ||
606 | /** | 609 | /** |
607 | * pinctrl_disable() - disable a certain pin control setting | 610 | * pinctrl_enable() - enable a certain pin controller setting |
608 | * @p: the pin control handle to disable, previously claimed by pinctrl_get() | 611 | * @p: the pin control handle to enable, previously claimed by pinctrl_get() |
609 | */ | 612 | */ |
610 | void pinctrl_disable(struct pinctrl *p) | 613 | int pinctrl_enable(struct pinctrl *p) |
614 | { | ||
615 | int ret; | ||
616 | mutex_lock(&pinctrl_mutex); | ||
617 | ret = pinctrl_enable_locked(p); | ||
618 | mutex_unlock(&pinctrl_mutex); | ||
619 | return ret; | ||
620 | } | ||
621 | EXPORT_SYMBOL_GPL(pinctrl_enable); | ||
622 | |||
623 | static void pinctrl_disable_locked(struct pinctrl *p) | ||
611 | { | 624 | { |
612 | if (p == NULL) | 625 | if (p == NULL) |
613 | return; | 626 | return; |
614 | 627 | ||
615 | mutex_lock(&p->mutex); | ||
616 | if (--p->usecount == 0) { | 628 | if (--p->usecount == 0) { |
617 | pinmux_disable(p); | 629 | pinmux_disable(p); |
618 | } | 630 | } |
619 | mutex_unlock(&p->mutex); | 631 | } |
632 | |||
633 | /** | ||
634 | * pinctrl_disable() - disable a certain pin control setting | ||
635 | * @p: the pin control handle to disable, previously claimed by pinctrl_get() | ||
636 | */ | ||
637 | void pinctrl_disable(struct pinctrl *p) | ||
638 | { | ||
639 | mutex_lock(&pinctrl_mutex); | ||
640 | pinctrl_disable_locked(p); | ||
641 | mutex_unlock(&pinctrl_mutex); | ||
620 | } | 642 | } |
621 | EXPORT_SYMBOL_GPL(pinctrl_disable); | 643 | EXPORT_SYMBOL_GPL(pinctrl_disable); |
622 | 644 | ||
@@ -676,9 +698,9 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, | |||
676 | return -ENOMEM; | 698 | return -ENOMEM; |
677 | } | 699 | } |
678 | 700 | ||
679 | mutex_lock(&pinctrl_maps_mutex); | 701 | mutex_lock(&pinctrl_mutex); |
680 | list_add_tail(&maps_node->node, &pinctrl_maps); | 702 | list_add_tail(&maps_node->node, &pinctrl_maps); |
681 | mutex_unlock(&pinctrl_maps_mutex); | 703 | mutex_unlock(&pinctrl_mutex); |
682 | 704 | ||
683 | return 0; | 705 | return 0; |
684 | } | 706 | } |
@@ -693,6 +715,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) | |||
693 | 715 | ||
694 | seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); | 716 | seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); |
695 | 717 | ||
718 | mutex_lock(&pinctrl_mutex); | ||
719 | |||
696 | /* The pin number can be retrived from the pin controller descriptor */ | 720 | /* The pin number can be retrived from the pin controller descriptor */ |
697 | for (i = 0; i < pctldev->desc->npins; i++) { | 721 | for (i = 0; i < pctldev->desc->npins; i++) { |
698 | struct pin_desc *desc; | 722 | struct pin_desc *desc; |
@@ -713,6 +737,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) | |||
713 | seq_puts(s, "\n"); | 737 | seq_puts(s, "\n"); |
714 | } | 738 | } |
715 | 739 | ||
740 | mutex_unlock(&pinctrl_mutex); | ||
741 | |||
716 | return 0; | 742 | return 0; |
717 | } | 743 | } |
718 | 744 | ||
@@ -726,6 +752,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) | |||
726 | if (!ops) | 752 | if (!ops) |
727 | return 0; | 753 | return 0; |
728 | 754 | ||
755 | mutex_lock(&pinctrl_mutex); | ||
756 | |||
729 | seq_puts(s, "registered pin groups:\n"); | 757 | seq_puts(s, "registered pin groups:\n"); |
730 | while (ops->list_groups(pctldev, selector) >= 0) { | 758 | while (ops->list_groups(pctldev, selector) >= 0) { |
731 | const unsigned *pins; | 759 | const unsigned *pins; |
@@ -748,6 +776,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) | |||
748 | selector++; | 776 | selector++; |
749 | } | 777 | } |
750 | 778 | ||
779 | mutex_unlock(&pinctrl_mutex); | ||
751 | 780 | ||
752 | return 0; | 781 | return 0; |
753 | } | 782 | } |
@@ -759,8 +788,9 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) | |||
759 | 788 | ||
760 | seq_puts(s, "GPIO ranges handled:\n"); | 789 | seq_puts(s, "GPIO ranges handled:\n"); |
761 | 790 | ||
791 | mutex_lock(&pinctrl_mutex); | ||
792 | |||
762 | /* Loop over the ranges */ | 793 | /* Loop over the ranges */ |
763 | mutex_lock(&pctldev->gpio_ranges_lock); | ||
764 | list_for_each_entry(range, &pctldev->gpio_ranges, node) { | 794 | list_for_each_entry(range, &pctldev->gpio_ranges, node) { |
765 | seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", | 795 | seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", |
766 | range->id, range->name, | 796 | range->id, range->name, |
@@ -768,7 +798,8 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) | |||
768 | range->pin_base, | 798 | range->pin_base, |
769 | (range->pin_base + range->npins - 1)); | 799 | (range->pin_base + range->npins - 1)); |
770 | } | 800 | } |
771 | mutex_unlock(&pctldev->gpio_ranges_lock); | 801 | |
802 | mutex_unlock(&pinctrl_mutex); | ||
772 | 803 | ||
773 | return 0; | 804 | return 0; |
774 | } | 805 | } |
@@ -778,7 +809,9 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) | |||
778 | struct pinctrl_dev *pctldev; | 809 | struct pinctrl_dev *pctldev; |
779 | 810 | ||
780 | seq_puts(s, "name [pinmux] [pinconf]\n"); | 811 | seq_puts(s, "name [pinmux] [pinconf]\n"); |
781 | mutex_lock(&pinctrldev_list_mutex); | 812 | |
813 | mutex_lock(&pinctrl_mutex); | ||
814 | |||
782 | list_for_each_entry(pctldev, &pinctrldev_list, node) { | 815 | list_for_each_entry(pctldev, &pinctrldev_list, node) { |
783 | seq_printf(s, "%s ", pctldev->desc->name); | 816 | seq_printf(s, "%s ", pctldev->desc->name); |
784 | if (pctldev->desc->pmxops) | 817 | if (pctldev->desc->pmxops) |
@@ -791,7 +824,8 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) | |||
791 | seq_puts(s, "no"); | 824 | seq_puts(s, "no"); |
792 | seq_puts(s, "\n"); | 825 | seq_puts(s, "\n"); |
793 | } | 826 | } |
794 | mutex_unlock(&pinctrldev_list_mutex); | 827 | |
828 | mutex_unlock(&pinctrl_mutex); | ||
795 | 829 | ||
796 | return 0; | 830 | return 0; |
797 | } | 831 | } |
@@ -804,7 +838,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) | |||
804 | 838 | ||
805 | seq_puts(s, "Pinctrl maps:\n"); | 839 | seq_puts(s, "Pinctrl maps:\n"); |
806 | 840 | ||
807 | mutex_lock(&pinctrl_maps_mutex); | 841 | mutex_lock(&pinctrl_mutex); |
842 | |||
808 | for_each_maps(maps_node, i, map) { | 843 | for_each_maps(maps_node, i, map) { |
809 | seq_printf(s, "%s:\n", map->name); | 844 | seq_printf(s, "%s:\n", map->name); |
810 | seq_printf(s, " device: %s\n", map->dev_name); | 845 | seq_printf(s, " device: %s\n", map->dev_name); |
@@ -813,7 +848,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) | |||
813 | seq_printf(s, " group: %s\n", map->group ? map->group : | 848 | seq_printf(s, " group: %s\n", map->group ? map->group : |
814 | "(default)"); | 849 | "(default)"); |
815 | } | 850 | } |
816 | mutex_unlock(&pinctrl_maps_mutex); | 851 | |
852 | mutex_unlock(&pinctrl_mutex); | ||
817 | 853 | ||
818 | return 0; | 854 | return 0; |
819 | } | 855 | } |
@@ -823,6 +859,9 @@ static int pinctrl_show(struct seq_file *s, void *what) | |||
823 | struct pinctrl *p; | 859 | struct pinctrl *p; |
824 | 860 | ||
825 | seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); | 861 | seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); |
862 | |||
863 | mutex_lock(&pinctrl_mutex); | ||
864 | |||
826 | list_for_each_entry(p, &pinctrl_list, node) { | 865 | list_for_each_entry(p, &pinctrl_list, node) { |
827 | struct pinctrl_dev *pctldev = p->pctldev; | 866 | struct pinctrl_dev *pctldev = p->pctldev; |
828 | 867 | ||
@@ -841,6 +880,8 @@ static int pinctrl_show(struct seq_file *s, void *what) | |||
841 | p->dev ? dev_name(p->dev) : "(system)"); | 880 | p->dev ? dev_name(p->dev) : "(system)"); |
842 | } | 881 | } |
843 | 882 | ||
883 | mutex_unlock(&pinctrl_mutex); | ||
884 | |||
844 | return 0; | 885 | return 0; |
845 | } | 886 | } |
846 | 887 | ||
@@ -1008,7 +1049,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, | |||
1008 | pctldev->driver_data = driver_data; | 1049 | pctldev->driver_data = driver_data; |
1009 | INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); | 1050 | INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); |
1010 | INIT_LIST_HEAD(&pctldev->gpio_ranges); | 1051 | INIT_LIST_HEAD(&pctldev->gpio_ranges); |
1011 | mutex_init(&pctldev->gpio_ranges_lock); | ||
1012 | pctldev->dev = dev; | 1052 | pctldev->dev = dev; |
1013 | 1053 | ||
1014 | /* If we're implementing pinmuxing, check the ops for sanity */ | 1054 | /* If we're implementing pinmuxing, check the ops for sanity */ |
@@ -1042,12 +1082,16 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, | |||
1042 | goto out_err; | 1082 | goto out_err; |
1043 | } | 1083 | } |
1044 | 1084 | ||
1045 | mutex_lock(&pinctrldev_list_mutex); | 1085 | mutex_lock(&pinctrl_mutex); |
1086 | |||
1046 | list_add_tail(&pctldev->node, &pinctrldev_list); | 1087 | list_add_tail(&pctldev->node, &pinctrldev_list); |
1047 | mutex_unlock(&pinctrldev_list_mutex); | 1088 | |
1048 | pctldev->p = pinctrl_get(pctldev->dev, PINCTRL_STATE_DEFAULT); | 1089 | pctldev->p = pinctrl_get_locked(pctldev->dev, PINCTRL_STATE_DEFAULT); |
1049 | if (!IS_ERR(pctldev->p)) | 1090 | if (!IS_ERR(pctldev->p)) |
1050 | pinctrl_enable(pctldev->p); | 1091 | pinctrl_enable_locked(pctldev->p); |
1092 | |||
1093 | mutex_unlock(&pinctrl_mutex); | ||
1094 | |||
1051 | pinctrl_init_device_debugfs(pctldev); | 1095 | pinctrl_init_device_debugfs(pctldev); |
1052 | 1096 | ||
1053 | return pctldev; | 1097 | return pctldev; |
@@ -1070,18 +1114,22 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) | |||
1070 | return; | 1114 | return; |
1071 | 1115 | ||
1072 | pinctrl_remove_device_debugfs(pctldev); | 1116 | pinctrl_remove_device_debugfs(pctldev); |
1117 | |||
1118 | mutex_lock(&pinctrl_mutex); | ||
1119 | |||
1073 | if (!IS_ERR(pctldev->p)) { | 1120 | if (!IS_ERR(pctldev->p)) { |
1074 | pinctrl_disable(pctldev->p); | 1121 | pinctrl_disable_locked(pctldev->p); |
1075 | pinctrl_put(pctldev->p); | 1122 | pinctrl_put_locked(pctldev->p); |
1076 | } | 1123 | } |
1124 | |||
1077 | /* TODO: check that no pinmuxes are still active? */ | 1125 | /* TODO: check that no pinmuxes are still active? */ |
1078 | mutex_lock(&pinctrldev_list_mutex); | ||
1079 | list_del(&pctldev->node); | 1126 | list_del(&pctldev->node); |
1080 | mutex_unlock(&pinctrldev_list_mutex); | ||
1081 | /* Destroy descriptor tree */ | 1127 | /* Destroy descriptor tree */ |
1082 | pinctrl_free_pindescs(pctldev, pctldev->desc->pins, | 1128 | pinctrl_free_pindescs(pctldev, pctldev->desc->pins, |
1083 | pctldev->desc->npins); | 1129 | pctldev->desc->npins); |
1084 | kfree(pctldev); | 1130 | kfree(pctldev); |
1131 | |||
1132 | mutex_unlock(&pinctrl_mutex); | ||
1085 | } | 1133 | } |
1086 | EXPORT_SYMBOL_GPL(pinctrl_unregister); | 1134 | EXPORT_SYMBOL_GPL(pinctrl_unregister); |
1087 | 1135 | ||
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index e1dfdb3c144f..8808f25a07d4 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
@@ -9,6 +9,8 @@ | |||
9 | * License terms: GNU General Public License (GPL) version 2 | 9 | * License terms: GNU General Public License (GPL) version 2 |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/mutex.h> | ||
13 | #include <linux/radix-tree.h> | ||
12 | #include <linux/pinctrl/pinconf.h> | 14 | #include <linux/pinctrl/pinconf.h> |
13 | 15 | ||
14 | struct pinctrl_gpio_range; | 16 | struct pinctrl_gpio_range; |
@@ -22,7 +24,6 @@ struct pinctrl_gpio_range; | |||
22 | * this radix tree | 24 | * this radix tree |
23 | * @gpio_ranges: a list of GPIO ranges that is handled by this pin controller, | 25 | * @gpio_ranges: a list of GPIO ranges that is handled by this pin controller, |
24 | * ranges are added to this list at runtime | 26 | * ranges are added to this list at runtime |
25 | * @gpio_ranges_lock: lock for the GPIO ranges list | ||
26 | * @dev: the device entry for this pin controller | 27 | * @dev: the device entry for this pin controller |
27 | * @owner: module providing the pin controller, used for refcounting | 28 | * @owner: module providing the pin controller, used for refcounting |
28 | * @driver_data: driver data for drivers registering to the pin controller | 29 | * @driver_data: driver data for drivers registering to the pin controller |
@@ -35,7 +36,6 @@ struct pinctrl_dev { | |||
35 | struct pinctrl_desc *desc; | 36 | struct pinctrl_desc *desc; |
36 | struct radix_tree_root pin_desc_tree; | 37 | struct radix_tree_root pin_desc_tree; |
37 | struct list_head gpio_ranges; | 38 | struct list_head gpio_ranges; |
38 | struct mutex gpio_ranges_lock; | ||
39 | struct device *dev; | 39 | struct device *dev; |
40 | struct module *owner; | 40 | struct module *owner; |
41 | void *driver_data; | 41 | void *driver_data; |
@@ -52,7 +52,6 @@ struct pinctrl_dev { | |||
52 | * @usecount: the number of active users of this pin controller setting, used | 52 | * @usecount: the number of active users of this pin controller setting, used |
53 | * to keep track of nested use cases | 53 | * to keep track of nested use cases |
54 | * @pctldev: pin control device handling this pin control handle | 54 | * @pctldev: pin control device handling this pin control handle |
55 | * @mutex: a lock for the pin control state holder | ||
56 | * @groups: the group selectors for the pinmux device and | 55 | * @groups: the group selectors for the pinmux device and |
57 | * selector combination handling this pinmux, this is a list that | 56 | * selector combination handling this pinmux, this is a list that |
58 | * will be traversed on all pinmux operations such as | 57 | * will be traversed on all pinmux operations such as |
@@ -63,7 +62,6 @@ struct pinctrl { | |||
63 | struct device *dev; | 62 | struct device *dev; |
64 | unsigned usecount; | 63 | unsigned usecount; |
65 | struct pinctrl_dev *pctldev; | 64 | struct pinctrl_dev *pctldev; |
66 | struct mutex mutex; | ||
67 | #ifdef CONFIG_PINMUX | 65 | #ifdef CONFIG_PINMUX |
68 | struct list_head groups; | 66 | struct list_head groups; |
69 | #endif | 67 | #endif |
@@ -75,14 +73,12 @@ struct pinctrl { | |||
75 | * @name: a name for the pin, e.g. the name of the pin/pad/finger on a | 73 | * @name: a name for the pin, e.g. the name of the pin/pad/finger on a |
76 | * datasheet or such | 74 | * datasheet or such |
77 | * @dynamic_name: if the name of this pin was dynamically allocated | 75 | * @dynamic_name: if the name of this pin was dynamically allocated |
78 | * @lock: a lock to protect the descriptor structure | ||
79 | * @owner: the device holding this pin or NULL of no device has claimed it | 76 | * @owner: the device holding this pin or NULL of no device has claimed it |
80 | */ | 77 | */ |
81 | struct pin_desc { | 78 | struct pin_desc { |
82 | struct pinctrl_dev *pctldev; | 79 | struct pinctrl_dev *pctldev; |
83 | const char *name; | 80 | const char *name; |
84 | bool dynamic_name; | 81 | bool dynamic_name; |
85 | spinlock_t lock; | ||
86 | /* These fields only added when supporting pinmux drivers */ | 82 | /* These fields only added when supporting pinmux drivers */ |
87 | #ifdef CONFIG_PINMUX | 83 | #ifdef CONFIG_PINMUX |
88 | const char *owner; | 84 | const char *owner; |
@@ -99,3 +95,5 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, | |||
99 | { | 95 | { |
100 | return radix_tree_lookup(&pctldev->pin_desc_tree, pin); | 96 | return radix_tree_lookup(&pctldev->pin_desc_tree, pin); |
101 | } | 97 | } |
98 | |||
99 | extern struct mutex pinctrl_mutex; | ||
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 3f018a1cc14b..e0a453790a40 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c | |||
@@ -64,15 +64,23 @@ int pin_config_get(const char *dev_name, const char *name, | |||
64 | struct pinctrl_dev *pctldev; | 64 | struct pinctrl_dev *pctldev; |
65 | int pin; | 65 | int pin; |
66 | 66 | ||
67 | mutex_lock(&pinctrl_mutex); | ||
68 | |||
67 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 69 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
68 | if (!pctldev) | 70 | if (!pctldev) { |
69 | return -EINVAL; | 71 | pin = -EINVAL; |
72 | goto unlock; | ||
73 | } | ||
70 | 74 | ||
71 | pin = pin_get_from_name(pctldev, name); | 75 | pin = pin_get_from_name(pctldev, name); |
72 | if (pin < 0) | 76 | if (pin < 0) |
73 | return pin; | 77 | goto unlock; |
74 | 78 | ||
75 | return pin_config_get_for_pin(pctldev, pin, config); | 79 | pin = pin_config_get_for_pin(pctldev, pin, config); |
80 | |||
81 | unlock: | ||
82 | mutex_unlock(&pinctrl_mutex); | ||
83 | return pin; | ||
76 | } | 84 | } |
77 | EXPORT_SYMBOL(pin_config_get); | 85 | EXPORT_SYMBOL(pin_config_get); |
78 | 86 | ||
@@ -110,17 +118,27 @@ int pin_config_set(const char *dev_name, const char *name, | |||
110 | unsigned long config) | 118 | unsigned long config) |
111 | { | 119 | { |
112 | struct pinctrl_dev *pctldev; | 120 | struct pinctrl_dev *pctldev; |
113 | int pin; | 121 | int pin, ret; |
122 | |||
123 | mutex_lock(&pinctrl_mutex); | ||
114 | 124 | ||
115 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 125 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
116 | if (!pctldev) | 126 | if (!pctldev) { |
117 | return -EINVAL; | 127 | ret = -EINVAL; |
128 | goto unlock; | ||
129 | } | ||
118 | 130 | ||
119 | pin = pin_get_from_name(pctldev, name); | 131 | pin = pin_get_from_name(pctldev, name); |
120 | if (pin < 0) | 132 | if (pin < 0) { |
121 | return pin; | 133 | ret = pin; |
134 | goto unlock; | ||
135 | } | ||
136 | |||
137 | ret = pin_config_set_for_pin(pctldev, pin, config); | ||
122 | 138 | ||
123 | return pin_config_set_for_pin(pctldev, pin, config); | 139 | unlock: |
140 | mutex_unlock(&pinctrl_mutex); | ||
141 | return ret; | ||
124 | } | 142 | } |
125 | EXPORT_SYMBOL(pin_config_set); | 143 | EXPORT_SYMBOL(pin_config_set); |
126 | 144 | ||
@@ -129,25 +147,36 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, | |||
129 | { | 147 | { |
130 | struct pinctrl_dev *pctldev; | 148 | struct pinctrl_dev *pctldev; |
131 | const struct pinconf_ops *ops; | 149 | const struct pinconf_ops *ops; |
132 | int selector; | 150 | int selector, ret; |
151 | |||
152 | mutex_lock(&pinctrl_mutex); | ||
133 | 153 | ||
134 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 154 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
135 | if (!pctldev) | 155 | if (!pctldev) { |
136 | return -EINVAL; | 156 | ret = -EINVAL; |
157 | goto unlock; | ||
158 | } | ||
137 | ops = pctldev->desc->confops; | 159 | ops = pctldev->desc->confops; |
138 | 160 | ||
139 | if (!ops || !ops->pin_config_group_get) { | 161 | if (!ops || !ops->pin_config_group_get) { |
140 | dev_err(pctldev->dev, "cannot get configuration for pin " | 162 | dev_err(pctldev->dev, "cannot get configuration for pin " |
141 | "group, missing group config get function in " | 163 | "group, missing group config get function in " |
142 | "driver\n"); | 164 | "driver\n"); |
143 | return -EINVAL; | 165 | ret = -EINVAL; |
166 | goto unlock; | ||
144 | } | 167 | } |
145 | 168 | ||
146 | selector = pinctrl_get_group_selector(pctldev, pin_group); | 169 | selector = pinctrl_get_group_selector(pctldev, pin_group); |
147 | if (selector < 0) | 170 | if (selector < 0) { |
148 | return selector; | 171 | ret = selector; |
172 | goto unlock; | ||
173 | } | ||
149 | 174 | ||
150 | return ops->pin_config_group_get(pctldev, selector, config); | 175 | ret = ops->pin_config_group_get(pctldev, selector, config); |
176 | |||
177 | unlock: | ||
178 | mutex_unlock(&pinctrl_mutex); | ||
179 | return ret; | ||
151 | } | 180 | } |
152 | EXPORT_SYMBOL(pin_config_group_get); | 181 | EXPORT_SYMBOL(pin_config_group_get); |
153 | 182 | ||
@@ -163,27 +192,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, | |||
163 | int ret; | 192 | int ret; |
164 | int i; | 193 | int i; |
165 | 194 | ||
195 | mutex_lock(&pinctrl_mutex); | ||
196 | |||
166 | pctldev = get_pinctrl_dev_from_devname(dev_name); | 197 | pctldev = get_pinctrl_dev_from_devname(dev_name); |
167 | if (!pctldev) | 198 | if (!pctldev) { |
168 | return -EINVAL; | 199 | ret = -EINVAL; |
200 | goto unlock; | ||
201 | } | ||
169 | ops = pctldev->desc->confops; | 202 | ops = pctldev->desc->confops; |
170 | pctlops = pctldev->desc->pctlops; | 203 | pctlops = pctldev->desc->pctlops; |
171 | 204 | ||
172 | if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { | 205 | if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { |
173 | dev_err(pctldev->dev, "cannot configure pin group, missing " | 206 | dev_err(pctldev->dev, "cannot configure pin group, missing " |
174 | "config function in driver\n"); | 207 | "config function in driver\n"); |
175 | return -EINVAL; | 208 | ret = -EINVAL; |
209 | goto unlock; | ||
176 | } | 210 | } |
177 | 211 | ||
178 | selector = pinctrl_get_group_selector(pctldev, pin_group); | 212 | selector = pinctrl_get_group_selector(pctldev, pin_group); |
179 | if (selector < 0) | 213 | if (selector < 0) { |
180 | return selector; | 214 | ret = selector; |
215 | goto unlock; | ||
216 | } | ||
181 | 217 | ||
182 | ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); | 218 | ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); |
183 | if (ret) { | 219 | if (ret) { |
184 | dev_err(pctldev->dev, "cannot configure pin group, error " | 220 | dev_err(pctldev->dev, "cannot configure pin group, error " |
185 | "getting pins\n"); | 221 | "getting pins\n"); |
186 | return ret; | 222 | goto unlock; |
187 | } | 223 | } |
188 | 224 | ||
189 | /* | 225 | /* |
@@ -197,23 +233,30 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, | |||
197 | * pin-by-pin as well, it returns -EAGAIN. | 233 | * pin-by-pin as well, it returns -EAGAIN. |
198 | */ | 234 | */ |
199 | if (ret != -EAGAIN) | 235 | if (ret != -EAGAIN) |
200 | return ret; | 236 | goto unlock; |
201 | } | 237 | } |
202 | 238 | ||
203 | /* | 239 | /* |
204 | * If the controller cannot handle entire groups, we configure each pin | 240 | * If the controller cannot handle entire groups, we configure each pin |
205 | * individually. | 241 | * individually. |
206 | */ | 242 | */ |
207 | if (!ops->pin_config_set) | 243 | if (!ops->pin_config_set) { |
208 | return 0; | 244 | ret = 0; |
245 | goto unlock; | ||
246 | } | ||
209 | 247 | ||
210 | for (i = 0; i < num_pins; i++) { | 248 | for (i = 0; i < num_pins; i++) { |
211 | ret = ops->pin_config_set(pctldev, pins[i], config); | 249 | ret = ops->pin_config_set(pctldev, pins[i], config); |
212 | if (ret < 0) | 250 | if (ret < 0) |
213 | return ret; | 251 | goto unlock; |
214 | } | 252 | } |
215 | 253 | ||
216 | return 0; | 254 | ret = 0; |
255 | |||
256 | unlock: | ||
257 | mutex_unlock(&pinctrl_mutex); | ||
258 | |||
259 | return ret; | ||
217 | } | 260 | } |
218 | EXPORT_SYMBOL(pin_config_group_set); | 261 | EXPORT_SYMBOL(pin_config_group_set); |
219 | 262 | ||
@@ -236,6 +279,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) | |||
236 | seq_puts(s, "Pin config settings per pin\n"); | 279 | seq_puts(s, "Pin config settings per pin\n"); |
237 | seq_puts(s, "Format: pin (name): pinmux setting array\n"); | 280 | seq_puts(s, "Format: pin (name): pinmux setting array\n"); |
238 | 281 | ||
282 | mutex_lock(&pinctrl_mutex); | ||
283 | |||
239 | /* The pin number can be retrived from the pin controller descriptor */ | 284 | /* The pin number can be retrived from the pin controller descriptor */ |
240 | for (i = 0; i < pctldev->desc->npins; i++) { | 285 | for (i = 0; i < pctldev->desc->npins; i++) { |
241 | struct pin_desc *desc; | 286 | struct pin_desc *desc; |
@@ -254,6 +299,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) | |||
254 | seq_printf(s, "\n"); | 299 | seq_printf(s, "\n"); |
255 | } | 300 | } |
256 | 301 | ||
302 | mutex_unlock(&pinctrl_mutex); | ||
303 | |||
257 | return 0; | 304 | return 0; |
258 | } | 305 | } |
259 | 306 | ||
@@ -280,6 +327,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) | |||
280 | seq_puts(s, "Pin config settings per pin group\n"); | 327 | seq_puts(s, "Pin config settings per pin group\n"); |
281 | seq_puts(s, "Format: group (name): pinmux setting array\n"); | 328 | seq_puts(s, "Format: group (name): pinmux setting array\n"); |
282 | 329 | ||
330 | mutex_lock(&pinctrl_mutex); | ||
331 | |||
283 | while (pctlops->list_groups(pctldev, selector) >= 0) { | 332 | while (pctlops->list_groups(pctldev, selector) >= 0) { |
284 | const char *gname = pctlops->get_group_name(pctldev, selector); | 333 | const char *gname = pctlops->get_group_name(pctldev, selector); |
285 | 334 | ||
@@ -290,6 +339,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) | |||
290 | selector++; | 339 | selector++; |
291 | } | 340 | } |
292 | 341 | ||
342 | mutex_unlock(&pinctrl_mutex); | ||
343 | |||
293 | return 0; | 344 | return 0; |
294 | } | 345 | } |
295 | 346 | ||
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index f409f161ea1d..7342c26f4246 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <linux/radix-tree.h> | 19 | #include <linux/radix-tree.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
22 | #include <linux/mutex.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/string.h> | 22 | #include <linux/string.h> |
25 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
26 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
@@ -96,15 +94,12 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
96 | goto out; | 94 | goto out; |
97 | } | 95 | } |
98 | 96 | ||
99 | spin_lock(&desc->lock); | ||
100 | if (desc->owner && strcmp(desc->owner, owner)) { | 97 | if (desc->owner && strcmp(desc->owner, owner)) { |
101 | spin_unlock(&desc->lock); | ||
102 | dev_err(pctldev->dev, | 98 | dev_err(pctldev->dev, |
103 | "pin already requested\n"); | 99 | "pin already requested\n"); |
104 | goto out; | 100 | goto out; |
105 | } | 101 | } |
106 | desc->owner = owner; | 102 | desc->owner = owner; |
107 | spin_unlock(&desc->lock); | ||
108 | 103 | ||
109 | /* Let each pin increase references to this module */ | 104 | /* Let each pin increase references to this module */ |
110 | if (!try_module_get(pctldev->owner)) { | 105 | if (!try_module_get(pctldev->owner)) { |
@@ -131,11 +126,8 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
131 | dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", | 126 | dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", |
132 | pctldev->desc->name, pin); | 127 | pctldev->desc->name, pin); |
133 | out_free_pin: | 128 | out_free_pin: |
134 | if (status) { | 129 | if (status) |
135 | spin_lock(&desc->lock); | ||
136 | desc->owner = NULL; | 130 | desc->owner = NULL; |
137 | spin_unlock(&desc->lock); | ||
138 | } | ||
139 | out: | 131 | out: |
140 | if (status) | 132 | if (status) |
141 | dev_err(pctldev->dev, "pin-%d (%s) status %d\n", | 133 | dev_err(pctldev->dev, "pin-%d (%s) status %d\n", |
@@ -178,10 +170,8 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, | |||
178 | else if (ops->free) | 170 | else if (ops->free) |
179 | ops->free(pctldev, pin); | 171 | ops->free(pctldev, pin); |
180 | 172 | ||
181 | spin_lock(&desc->lock); | ||
182 | owner = desc->owner; | 173 | owner = desc->owner; |
183 | desc->owner = NULL; | 174 | desc->owner = NULL; |
184 | spin_unlock(&desc->lock); | ||
185 | module_put(pctldev->owner); | 175 | module_put(pctldev->owner); |
186 | 176 | ||
187 | return owner; | 177 | return owner; |
@@ -580,6 +570,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what) | |||
580 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; | 570 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; |
581 | unsigned func_selector = 0; | 571 | unsigned func_selector = 0; |
582 | 572 | ||
573 | mutex_lock(&pinctrl_mutex); | ||
574 | |||
583 | while (pmxops->list_functions(pctldev, func_selector) >= 0) { | 575 | while (pmxops->list_functions(pctldev, func_selector) >= 0) { |
584 | const char *func = pmxops->get_function_name(pctldev, | 576 | const char *func = pmxops->get_function_name(pctldev, |
585 | func_selector); | 577 | func_selector); |
@@ -600,9 +592,10 @@ static int pinmux_functions_show(struct seq_file *s, void *what) | |||
600 | seq_puts(s, "]\n"); | 592 | seq_puts(s, "]\n"); |
601 | 593 | ||
602 | func_selector++; | 594 | func_selector++; |
603 | |||
604 | } | 595 | } |
605 | 596 | ||
597 | mutex_unlock(&pinctrl_mutex); | ||
598 | |||
606 | return 0; | 599 | return 0; |
607 | } | 600 | } |
608 | 601 | ||
@@ -614,6 +607,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
614 | seq_puts(s, "Pinmux settings per pin\n"); | 607 | seq_puts(s, "Pinmux settings per pin\n"); |
615 | seq_puts(s, "Format: pin (name): owner\n"); | 608 | seq_puts(s, "Format: pin (name): owner\n"); |
616 | 609 | ||
610 | mutex_lock(&pinctrl_mutex); | ||
611 | |||
617 | /* The pin number can be retrived from the pin controller descriptor */ | 612 | /* The pin number can be retrived from the pin controller descriptor */ |
618 | for (i = 0; i < pctldev->desc->npins; i++) { | 613 | for (i = 0; i < pctldev->desc->npins; i++) { |
619 | struct pin_desc *desc; | 614 | struct pin_desc *desc; |
@@ -635,6 +630,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
635 | is_hog ? " (HOG)" : ""); | 630 | is_hog ? " (HOG)" : ""); |
636 | } | 631 | } |
637 | 632 | ||
633 | mutex_unlock(&pinctrl_mutex); | ||
634 | |||
638 | return 0; | 635 | return 0; |
639 | } | 636 | } |
640 | 637 | ||
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 411fe232adf1..bbdd7e16bada 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h | |||
@@ -15,7 +15,6 @@ | |||
15 | #ifdef CONFIG_PINCTRL | 15 | #ifdef CONFIG_PINCTRL |
16 | 16 | ||
17 | #include <linux/radix-tree.h> | 17 | #include <linux/radix-tree.h> |
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/list.h> | 18 | #include <linux/list.h> |
20 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
21 | 20 | ||