@@ -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;
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: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- drivers/pinctrl/intel/pinctrl-intel.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)