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,
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,
struct pinctrl_gpio_range *range,
unsigned int offset,
......@@ -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);
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;
u32 value;
......@@ -817,14 +831,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
value &= ~BYT_DIR_MASK;
if (input)
value |= BYT_OUTPUT_EN;
else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
/*
* 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");
else
byt_gpio_direct_irq_check(vg, offset);
writel(value, val_reg);
......@@ -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)
{
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,
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)
return ret;
raw_spin_lock_irqsave(&byt_lock, flags);
byt_gpio_set(chip, offset, value);
byt_gpio_direct_irq_check(vg, offset);
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;
}
......
......@@ -252,7 +252,7 @@ static const struct amd_pingroup kerncz_groups[] = {
{
.name = "uart0",
.pins = uart0_pins,
.npins = 9,
.npins = 5,
},
{
.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