intel-pinctrl for v5.8-2
* Fix output pin value handling on Intel Baytrail The following is an automated git shortlog grouped by driver: baytrail: - Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH) -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqaflIX74DDDzMJJtb7wzTHR8rCgFAl72D7kACgkQb7wzTHR8 rCi6fw//f9XPaJiJwgN+TeN5UgsKwObF+muf1OMvw32y2wYjHeoP440exmddTMsz 58g0wlCQFK2oeNzqKE8T0cd7AdqZjzfBlTykhPkZsmGjo7jZZcNIjGNwhsNEwVb+ x+mcGcR5RobQkejF69G+2ZqWIgiJimied2KCa9JfuNgeCuqBXqdbfQO+LbMWE4SH 0aouvUc40LmfVWioYQ2IQe5yU1aGl0cgSOKf5Fx855XuHdcQYZITLKHDBGoTe4Yn kp3pTAkif/VakRdq04UOk4nzAcqmzThSdRnlxqWzCSSA2ZLUWhntEhXbl0xPAOQx o+FdoCSSjVvP4jH+Hj2ZF33GFJSBOF8XPE9mcnRJnfXOWMltA/vPOK7rvBlhKZOt QTlK3hV973K3vaK/2N9Cw066Cq/PqNf/CyLdQyVQUVBdzuRvYZhUswiXe6rRSzQC bdHnMx6h7+1I83+u6YQQDNyyLCXCDC2gMdbCBBnJx88oLTEQFkbkF61NywqMz8nJ 1WMeEFYcZmDGv019qXhDLV/Fyz2I9fxJDxOW3m/GEq1XR3sSmuXaVcbp2cpFNTNM da6Kurs+5FIPzG52PkL1QcKivwkt8l9w6KceQCZYBIW1ZVDFcHhThUNxhkJS4Dxf 4/yHfNG7J3n2ddoa1g3/KIEDNLaNtxaDYO9PcYntf6KvGKzjcig= =ju6S -----END PGP SIGNATURE----- Merge tag 'intel-pinctrl-v5.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel into fixes intel-pinctrl for v5.8-2 * Fix output pin value handling on Intel Baytrail The following is an automated git shortlog grouped by driver: baytrail: - Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH)
This commit is contained in:
commit
f8e99dde21
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user