Commit 25aadbd2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v5.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fixes from Linus Walleij:

 - Fix an issue in the AMD driver for the UART0 group

 - Fix a glitch issue in the Baytrail pin controller

* tag 'pinctrl-v5.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH)
  pinctrl: amd: fix npins for uart0 in kerncz_groups
parents 3f883432 f8e99dde
...@@ -800,6 +800,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, ...@@ -800,6 +800,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
pm_runtime_put(vg->dev); pm_runtime_put(vg->dev);
} }
static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg,
unsigned int offset)
{
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
/*
* Before making any direction modifications, do a check if gpio is set
* for direct IRQ. On Bay Trail, setting GPIO to output does not make
* sense, so let's at least inform the caller before they shoot
* themselves in the foot.
*/
if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
}
static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned int offset, unsigned int offset,
...@@ -807,7 +822,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, ...@@ -807,7 +822,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
{ {
struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
unsigned long flags; unsigned long flags;
u32 value; u32 value;
...@@ -817,14 +831,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, ...@@ -817,14 +831,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
value &= ~BYT_DIR_MASK; value &= ~BYT_DIR_MASK;
if (input) if (input)
value |= BYT_OUTPUT_EN; value |= BYT_OUTPUT_EN;
else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) else
/* byt_gpio_direct_irq_check(vg, offset);
* Before making any direction modifications, do a check if gpio
* is set for direct IRQ. On baytrail, setting GPIO to output
* does not make sense, so let's at least inform the caller before
* they shoot themselves in the foot.
*/
dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
writel(value, val_reg); writel(value, val_reg);
...@@ -1165,19 +1173,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) ...@@ -1165,19 +1173,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{ {
return pinctrl_gpio_direction_input(chip->base + offset); struct intel_pinctrl *vg = gpiochip_get_data(chip);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 reg;
raw_spin_lock_irqsave(&byt_lock, flags);
reg = readl(val_reg);
reg &= ~BYT_DIR_MASK;
reg |= BYT_OUTPUT_EN;
writel(reg, val_reg);
raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0;
} }
/*
* Note despite the temptation this MUST NOT be converted into a call to
* pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
* MUST be done as a single BYT_VAL_REG register write.
* See the commit message of the commit adding this comment for details.
*/
static int byt_gpio_direction_output(struct gpio_chip *chip, static int byt_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value) unsigned int offset, int value)
{ {
int ret = pinctrl_gpio_direction_output(chip->base + offset); struct intel_pinctrl *vg = gpiochip_get_data(chip);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
unsigned long flags;
u32 reg;
if (ret) raw_spin_lock_irqsave(&byt_lock, flags);
return ret;
byt_gpio_direct_irq_check(vg, offset);
byt_gpio_set(chip, offset, value); reg = readl(val_reg);
reg &= ~BYT_DIR_MASK;
if (value)
reg |= BYT_LEVEL;
else
reg &= ~BYT_LEVEL;
writel(reg, val_reg);
raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0; return 0;
} }
......
...@@ -252,7 +252,7 @@ static const struct amd_pingroup kerncz_groups[] = { ...@@ -252,7 +252,7 @@ static const struct amd_pingroup kerncz_groups[] = {
{ {
.name = "uart0", .name = "uart0",
.pins = uart0_pins, .pins = uart0_pins,
.npins = 9, .npins = 5,
}, },
{ {
.name = "uart1", .name = "uart1",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment