mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 06:55:13 +08:00
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: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
This commit is contained in:
parent
81ab5542d7
commit
e64fbfa51e
@ -526,11 +526,15 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin,
|
|||||||
{
|
{
|
||||||
const struct intel_community *community;
|
const struct intel_community *community;
|
||||||
void __iomem *padcfg1;
|
void __iomem *padcfg1;
|
||||||
|
unsigned long flags;
|
||||||
u32 value, term;
|
u32 value, term;
|
||||||
|
|
||||||
community = intel_get_community(pctrl, pin);
|
community = intel_get_community(pctrl, pin);
|
||||||
padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
|
padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1);
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
value = readl(padcfg1);
|
value = readl(padcfg1);
|
||||||
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT;
|
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)
|
enum pin_config_param param, u32 *arg)
|
||||||
{
|
{
|
||||||
void __iomem *padcfg2;
|
void __iomem *padcfg2;
|
||||||
|
unsigned long flags;
|
||||||
unsigned long v;
|
unsigned long v;
|
||||||
u32 value2;
|
u32 value2;
|
||||||
|
|
||||||
@ -599,7 +604,9 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p
|
|||||||
if (!padcfg2)
|
if (!padcfg2)
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
value2 = readl(padcfg2);
|
value2 = readl(padcfg2);
|
||||||
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
if (!(value2 & PADCFG2_DEBEN))
|
if (!(value2 & PADCFG2_DEBEN))
|
||||||
return -EINVAL;
|
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)
|
static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||||
{
|
{
|
||||||
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
struct intel_pinctrl *pctrl = gpiochip_get_data(chip);
|
||||||
|
unsigned long flags;
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
u32 padcfg0;
|
u32 padcfg0;
|
||||||
int pin;
|
int pin;
|
||||||
@ -946,8 +954,9 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
|||||||
if (!reg)
|
if (!reg)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
padcfg0 = readl(reg);
|
padcfg0 = readl(reg);
|
||||||
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
if (padcfg0 & PADCFG0_PMODE_MASK)
|
if (padcfg0 & PADCFG0_PMODE_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -1134,12 +1143,17 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
|
|||||||
for (gpp = 0; gpp < community->ngpps; gpp++) {
|
for (gpp = 0; gpp < community->ngpps; gpp++) {
|
||||||
const struct intel_padgroup *padgrp = &community->gpps[gpp];
|
const struct intel_padgroup *padgrp = &community->gpps[gpp];
|
||||||
unsigned long pending, enabled, gpp_offset;
|
unsigned long pending, enabled, gpp_offset;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&pctrl->lock, flags);
|
||||||
|
|
||||||
pending = readl(community->regs + community->is_offset +
|
pending = readl(community->regs + community->is_offset +
|
||||||
padgrp->reg_num * 4);
|
padgrp->reg_num * 4);
|
||||||
enabled = readl(community->regs + community->ie_offset +
|
enabled = readl(community->regs + community->ie_offset +
|
||||||
padgrp->reg_num * 4);
|
padgrp->reg_num * 4);
|
||||||
|
|
||||||
|
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
|
||||||
|
|
||||||
/* Only interrupts that are enabled */
|
/* Only interrupts that are enabled */
|
||||||
pending &= enabled;
|
pending &= enabled;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user