Skip to content

Commit

Permalink
pinctrl: mediatek: avoid virtual gpio trying to set reg
Browse files Browse the repository at this point in the history
for virtual gpios, they should not do reg setting and
should behave as expected for eint function.

Signed-off-by: Mars Cheng <mars.cheng@mediatek.com>
Signed-off-by: Hanks Chen <hanks.chen@mediatek.com>
Acked-by: Sean Wang <sean.wang@kernel.org>
Link: https://lore.kernel.org/r/1595503197-15246-4-git-send-email-hanks.chen@mediatek.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Hanks Chen authored and Linus Walleij committed Aug 3, 2020
1 parent b07b616 commit edd5464
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
25 changes: 25 additions & 0 deletions drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,28 @@ static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
return EINT_NA;
}

/*
* Virtual GPIO only used inside SOC and not being exported to outside SOC.
* Some modules use virtual GPIO as eint (e.g. pmif or usb).
* In MTK platform, external interrupt (EINT) and GPIO is 1-1 mapping
* and we can set GPIO as eint.
* But some modules use specific eint which doesn't have real GPIO pin.
* So we use virtual GPIO to map it.
*/

bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n)
{
const struct mtk_pin_desc *desc;
bool virt_gpio = false;

desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];

if (desc->funcs && !desc->funcs[desc->eint.eint_m].name)
virt_gpio = true;

return virt_gpio;
}

static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
unsigned int *gpio_n,
struct gpio_chip **gpio_chip)
Expand Down Expand Up @@ -295,6 +317,9 @@ static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
if (err)
return err;

if (mtk_is_virt_gpio(hw, gpio_n))
return 0;

desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n];

err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
Expand Down
1 change: 1 addition & 0 deletions drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,5 @@ int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw,
int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 *val);

bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n);
#endif /* __PINCTRL_MTK_COMMON_V2_H */
7 changes: 7 additions & 0 deletions drivers/pinctrl/mediatek/pinctrl-paris.c
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,13 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
if (gpio >= hw->soc->npins)
return -EINVAL;

/*
* "Virtual" GPIOs are always and only used for interrupts
* Since they are only used for interrupts, they are always inputs
*/
if (mtk_is_virt_gpio(hw, gpio))
return 1;

desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];

err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
Expand Down

0 comments on commit edd5464

Please sign in to comment.