Commit e64fbfa5 authored by Andy Shevchenko's avatar Andy Shevchenko
Browse files

pinctrl: intel: Protect IO in few call backs by lock



Protect IO in intel_gpio_get_direction(), intel_gpio_community_irq_handler(),
intel_config_get_debounce() and intel_config_get_pull() by lock. Even for
simple readl() we better serialize IO to avoid potential problems.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 81ab5542
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -526,11 +526,15 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
{
	const struct intel_community *community;
	void __iomem *padcfg1;
	unsigned long flags;
	u32 value, term;

	community = intel_get_community(pctrl, pin);
	padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);

	raw_spin_lock_irqsave(&pctrl->lock, flags);
	value = readl(padcfg1);
	raw_spin_unlock_irqrestore(&pctrl->lock, flags);

	term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT;

@@ -592,6 +596,7 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p
				     enum pin_config_param param, u32 *arg)
{
	void __iomem *padcfg2;
	unsigned long flags;
	unsigned long v;
	u32 value2;

@@ -599,7 +604,9 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p
	if (!padcfg2)
		return -ENOTSUPP;

	raw_spin_lock_irqsave(&pctrl->lock, flags);
	value2 = readl(padcfg2);
	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
	if (!(value2 & PADCFG2_DEBEN))
		return -EINVAL;

@@ -934,6 +941,7 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset,
static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
	struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
	unsigned long flags;
	void __iomem *reg;
	u32 padcfg0;
	int pin;
@@ -946,8 +954,9 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
	if (!reg)
		return -EINVAL;

	raw_spin_lock_irqsave(&pctrl->lock, flags);
	padcfg0 = readl(reg);

	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
	if (padcfg0 & PADCFG0_PMODE_MASK)
		return -EINVAL;

@@ -1134,12 +1143,17 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
	for (gpp = 0; gpp < community->ngpps; gpp++) {
		const struct intel_padgroup *padgrp = &community->gpps[gpp];
		unsigned long pending, enabled, gpp_offset;
		unsigned long flags;

		raw_spin_lock_irqsave(&pctrl->lock, flags);

		pending = readl(community->regs + community->is_offset +
				padgrp->reg_num * 4);
		enabled = readl(community->regs + community->ie_offset +
				padgrp->reg_num * 4);

		raw_spin_unlock_irqrestore(&pctrl->lock, flags);

		/* Only interrupts that are enabled */
		pending &= enabled;