Pull Pin control fixes from Linus Walleij: "Pin control fixes for the v4.5 series, all are individual driver fixes: - Fix the PXA2xx driver to export its init function so we do not break modular compiles. - Hide unused functions in the Nomadik driver. - Fix up direction control in the Mediatek driver. - Toggle the sunxi GPIO lines to input when you read them on the H3 GPIO controller, lest you only get garbage. - Fix up the number of settings in the MVEBU driver. - Fix a serious SMP race condition in the Samsung driver" * tag 'pinctrl-v4.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: pinctrl: samsung: fix SMP race condition pinctrl: mvebu: fix num_settings in mpp group assignment pinctrl: sunxi: H3 requires irq_read_needs_mux pinctrl: mediatek: fix direction control issue pinctrl: nomadik: hide unused functions pinctrl: pxa: export pxa2xx_pinctrl_init()
Unified · Split
| @@ -347,6 +347,7 @@ static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev, · 346 unmodified lines | |||
| 347 | ret = mtk_pconf_set_pull_select(pctl, pin, true, false, arg); | 347 | ret = mtk_pconf_set_pull_select(pctl, pin, true, false, arg); |
| 348 | break; | 348 | break; |
| 349 | case PIN_CONFIG_INPUT_ENABLE: | 349 | case PIN_CONFIG_INPUT_ENABLE: |
| 350 | mtk_pmx_gpio_set_direction(pctldev, NULL, pin, true); | ||
| 350 | ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); | 351 | ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); |
| 351 | break; | 352 | break; |
| 352 | case PIN_CONFIG_OUTPUT: | 353 | case PIN_CONFIG_OUTPUT: |
| @@ -354,6 +355,7 @@ static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev, · 1 unmodified line | |||
| 354 | ret = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false); | 355 | ret = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false); |
| 355 | break; | 356 | break; |
| 356 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: | 357 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
| 358 | mtk_pmx_gpio_set_direction(pctldev, NULL, pin, true); | ||
| 357 | ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); | 359 | ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); |
| 358 | break; | 360 | break; |
| 359 | case PIN_CONFIG_DRIVE_STRENGTH: | 361 | case PIN_CONFIG_DRIVE_STRENGTH: |
| @@ -666,16 +666,19 @@ int mvebu_pinctrl_probe(struct platform_device *pdev) · 665 unmodified lines | |||
| 666 | struct mvebu_mpp_ctrl_setting *set = &mode->settings[0]; | 666 | struct mvebu_mpp_ctrl_setting *set = &mode->settings[0]; |
| 667 | struct mvebu_pinctrl_group *grp; | 667 | struct mvebu_pinctrl_group *grp; |
| 668 | unsigned num_settings; | 668 | unsigned num_settings; |
| 669 | unsigned supp_settings; | ||
| 669 | 670 | ||
| 670 | for (num_settings = 0; ; set++) { | 671 | for (num_settings = 0, supp_settings = 0; ; set++) { |
| 671 | if (!set->name) | 672 | if (!set->name) |
| 672 | break; | 673 | break; |
| 673 | 674 | ||
| 675 | num_settings++; | ||
| 676 | |||
| 674 | /* skip unsupported settings for this variant */ | 677 | /* skip unsupported settings for this variant */ |
| 675 | if (pctl->variant && !(pctl->variant & set->variant)) | 678 | if (pctl->variant && !(pctl->variant & set->variant)) |
| 676 | continue; | 679 | continue; |
| 677 | 680 | ||
| 678 | num_settings++; | 681 | supp_settings++; |
| 679 | 682 | ||
| 680 | /* find gpio/gpo/gpi settings */ | 683 | /* find gpio/gpo/gpi settings */ |
| 681 | if (strcmp(set->name, "gpio") == 0) | 684 | if (strcmp(set->name, "gpio") == 0) |
| @@ -688,7 +691,7 @@ int mvebu_pinctrl_probe(struct platform_device *pdev) · 6 unmodified lines | |||
| 688 | } | 691 | } |
| 689 | 692 | ||
| 690 | /* skip modes with no settings for this variant */ | 693 | /* skip modes with no settings for this variant */ |
| 691 | if (!num_settings) | 694 | if (!supp_settings) |
| 692 | continue; | 695 | continue; |
| 693 | 696 | ||
| 694 | grp = mvebu_pinctrl_find_group_by_pid(pctl, mode->pid); | 697 | grp = mvebu_pinctrl_find_group_by_pid(pctl, mode->pid); |
| @@ -191,6 +191,7 @@ static void abx500_gpio_set(struct gpio_chip *chip, unsigned offset, int val) · 190 unmodified lines | |||
| 191 | dev_err(pct->dev, "%s write failed (%d)\n", __func__, ret); | 191 | dev_err(pct->dev, "%s write failed (%d)\n", __func__, ret); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | #ifdef CONFIG_DEBUG_FS | ||
| 194 | static int abx500_get_pull_updown(struct abx500_pinctrl *pct, int offset, | 195 | static int abx500_get_pull_updown(struct abx500_pinctrl *pct, int offset, |
| 195 | enum abx500_gpio_pull_updown *pull_updown) | 196 | enum abx500_gpio_pull_updown *pull_updown) |
| 196 | { | 197 | { |
| @@ -226,6 +227,7 @@ out: · 29 unmodified lines | |||
| 226 | 227 | ||
| 227 | return ret; | 228 | return ret; |
| 228 | } | 229 | } |
| 230 | #endif | ||
| 229 | 231 | ||
| 230 | static int abx500_set_pull_updown(struct abx500_pinctrl *pct, | 232 | static int abx500_set_pull_updown(struct abx500_pinctrl *pct, |
| 231 | int offset, enum abx500_gpio_pull_updown val) | 233 | int offset, enum abx500_gpio_pull_updown val) |
| @@ -468,6 +470,7 @@ out: · 236 unmodified lines | |||
| 468 | return ret; | 470 | return ret; |
| 469 | } | 471 | } |
| 470 | 472 | ||
| 473 | #ifdef CONFIG_DEBUG_FS | ||
| 471 | static int abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, | 474 | static int abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, |
| 472 | unsigned gpio) | 475 | unsigned gpio) |
| 473 | { | 476 | { |
| @@ -553,8 +556,6 @@ out: · 79 unmodified lines | |||
| 553 | return ret; | 556 | return ret; |
| 554 | } | 557 | } |
| 555 | 558 | ||
| 556 | #ifdef CONFIG_DEBUG_FS | ||
| 557 | |||
| 558 | #include <linux/seq_file.h> | 559 | #include <linux/seq_file.h> |
| 559 | 560 | ||
| 560 | static void abx500_gpio_dbg_show_one(struct seq_file *s, | 561 | static void abx500_gpio_dbg_show_one(struct seq_file *s, |
| @@ -426,6 +426,7 @@ int pxa2xx_pinctrl_init(struct platform_device *pdev, · 425 unmodified lines | |||
| 426 | 426 | ||
| 427 | return 0; | 427 | return 0; |
| 428 | } | 428 | } |
| 429 | EXPORT_SYMBOL(pxa2xx_pinctrl_init); | ||
| 429 | 430 | ||
| 430 | int pxa2xx_pinctrl_exit(struct platform_device *pdev) | 431 | int pxa2xx_pinctrl_exit(struct platform_device *pdev) |
| 431 | { | 432 | { |
| @@ -514,25 +514,35 @@ static const struct pinconf_ops samsung_pinconf_ops = { · 513 unmodified lines | |||
| 514 | .pin_config_group_set = samsung_pinconf_group_set, | 514 | .pin_config_group_set = samsung_pinconf_group_set, |
| 515 | }; | 515 | }; |
| 516 | 516 | ||
| 517 | /* gpiolib gpio_set callback function */ | 517 | /* |
| 518 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | 518 | * The samsung_gpio_set_vlaue() should be called with "bank->slock" held |
| 519 | * to avoid race condition. | ||
| 520 | */ | ||
| 521 | static void samsung_gpio_set_value(struct gpio_chip *gc, | ||
| 522 | unsigned offset, int value) | ||
| 519 | { | 523 | { |
| 520 | struct samsung_pin_bank *bank = gpiochip_get_data(gc); | 524 | struct samsung_pin_bank *bank = gpiochip_get_data(gc); |
| 521 | const struct samsung_pin_bank_type *type = bank->type; | 525 | const struct samsung_pin_bank_type *type = bank->type; |
| 522 | unsigned long flags; | ||
| 523 | void __iomem *reg; | 526 | void __iomem *reg; |
| 524 | u32 data; | 527 | u32 data; |
| 525 | 528 | ||
| 526 | reg = bank->drvdata->virt_base + bank->pctl_offset; | 529 | reg = bank->drvdata->virt_base + bank->pctl_offset; |
| 527 | 530 | ||
| 528 | spin_lock_irqsave(&bank->slock, flags); | ||
| 529 | |||
| 530 | data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); | 531 | data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); |
| 531 | data &= ~(1 << offset); | 532 | data &= ~(1 << offset); |
| 532 | if (value) | 533 | if (value) |
| 533 | data |= 1 << offset; | 534 | data |= 1 << offset; |
| 534 | writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]); | 535 | writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]); |
| 536 | } | ||
| 537 | |||
| 538 | /* gpiolib gpio_set callback function */ | ||
| 539 | static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | ||
| 540 | { | ||
| 541 | struct samsung_pin_bank *bank = gpiochip_get_data(gc); | ||
| 542 | unsigned long flags; | ||
| 535 | 543 | ||
| 544 | spin_lock_irqsave(&bank->slock, flags); | ||
| 545 | samsung_gpio_set_value(gc, offset, value); | ||
| 536 | spin_unlock_irqrestore(&bank->slock, flags); | 546 | spin_unlock_irqrestore(&bank->slock, flags); |
| 537 | } | 547 | } |
| 538 | 548 | ||
| @@ -553,6 +563,8 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) · 14 unmodified lines | |||
| 553 | } | 563 | } |
| 554 | 564 | ||
| 555 | /* | 565 | /* |
| 566 | * The samsung_gpio_set_direction() should be called with "bank->slock" held | ||
| 567 | * to avoid race condition. | ||
| 556 | * The calls to gpio_direction_output() and gpio_direction_input() | 568 | * The calls to gpio_direction_output() and gpio_direction_input() |
| 557 | * leads to this function call. | 569 | * leads to this function call. |
| 558 | */ | 570 | */ |
| @@ -564,7 +576,6 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, · 5 unmodified lines | |||
| 564 | struct samsung_pinctrl_drv_data *drvdata; | 576 | struct samsung_pinctrl_drv_data *drvdata; |
| 565 | void __iomem *reg; | 577 | void __iomem *reg; |
| 566 | u32 data, mask, shift; | 578 | u32 data, mask, shift; |
| 567 | unsigned long flags; | ||
| 568 | 579 | ||
| 569 | bank = gpiochip_get_data(gc); | 580 | bank = gpiochip_get_data(gc); |
| 570 | type = bank->type; | 581 | type = bank->type; |
| @@ -581,31 +592,42 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, · 10 unmodified lines | |||
| 581 | reg += 4; | 592 | reg += 4; |
| 582 | } | 593 | } |
| 583 | 594 | ||
| 584 | spin_lock_irqsave(&bank->slock, flags); | ||
| 585 | |||
| 586 | data = readl(reg); | 595 | data = readl(reg); |
| 587 | data &= ~(mask << shift); | 596 | data &= ~(mask << shift); |
| 588 | if (!input) | 597 | if (!input) |
| 589 | data |= FUNC_OUTPUT << shift; | 598 | data |= FUNC_OUTPUT << shift; |
| 590 | writel(data, reg); | 599 | writel(data, reg); |
| 591 | 600 | ||
| 592 | spin_unlock_irqrestore(&bank->slock, flags); | ||
| 593 | |||
| 594 | return 0; | 601 | return 0; |
| 595 | } | 602 | } |
| 596 | 603 | ||
| 597 | /* gpiolib gpio_direction_input callback function. */ | 604 | /* gpiolib gpio_direction_input callback function. */ |
| 598 | static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | 605 | static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) |
| 599 | { | 606 | { |
| 600 | return samsung_gpio_set_direction(gc, offset, true); | 607 | struct samsung_pin_bank *bank = gpiochip_get_data(gc); |
| 608 | unsigned long flags; | ||
| 609 | int ret; | ||
| 610 | |||
| 611 | spin_lock_irqsave(&bank->slock, flags); | ||
| 612 | ret = samsung_gpio_set_direction(gc, offset, true); | ||
| 613 | spin_unlock_irqrestore(&bank->slock, flags); | ||
| 614 | return ret; | ||
| 601 | } | 615 | } |
| 602 | 616 | ||
| 603 | /* gpiolib gpio_direction_output callback function. */ | 617 | /* gpiolib gpio_direction_output callback function. */ |
| 604 | static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, | 618 | static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, |
| 605 | int value) | 619 | int value) |
| 606 | { | 620 | { |
| 607 | samsung_gpio_set(gc, offset, value); | 621 | struct samsung_pin_bank *bank = gpiochip_get_data(gc); |
| 608 | return samsung_gpio_set_direction(gc, offset, false); | 622 | unsigned long flags; |
| 623 | int ret; | ||
| 624 | |||
| 625 | spin_lock_irqsave(&bank->slock, flags); | ||
| 626 | samsung_gpio_set_value(gc, offset, value); | ||
| 627 | ret = samsung_gpio_set_direction(gc, offset, false); | ||
| 628 | spin_unlock_irqrestore(&bank->slock, flags); | ||
| 629 | |||
| 630 | return ret; | ||
| 609 | } | 631 | } |
| 610 | 632 | ||
| 611 | /* | 633 | /* |
| @@ -492,6 +492,7 @@ static const struct sunxi_pinctrl_desc sun8i_h3_pinctrl_data = { · 491 unmodified lines | |||
| 492 | .pins = sun8i_h3_pins, | 492 | .pins = sun8i_h3_pins, |
| 493 | .npins = ARRAY_SIZE(sun8i_h3_pins), | 493 | .npins = ARRAY_SIZE(sun8i_h3_pins), |
| 494 | .irq_banks = 2, | 494 | .irq_banks = 2, |
| 495 | .irq_read_needs_mux = true | ||
| 495 | }; | 496 | }; |
| 496 | 497 | ||
| 497 | static int sun8i_h3_pinctrl_probe(struct platform_device *pdev) | 498 | static int sun8i_h3_pinctrl_probe(struct platform_device *pdev) |