gpio: aspeed-sgpio: Convert aspeed_sgpio.lock to raw_spinlock
[ Upstream commit ab39d6988dd53f354130438d8afa5596a2440fed ] The gpio-aspeed-sgpio driver implements an irq_chip which need to be invoked from hardirq context. Since spin_lock() can sleep with PREEMPT_RT, it is no longer legal to invoke it while interrupts are disabled. This also causes lockdep to complain about: [ 25.919465] [ BUG: Invalid wait context ] because aspeed_sgpio.lock (spin_lock_t) is taken under irq_desc.lock (raw_spinlock_t). Let's use of raw_spinlock_t instead of spinlock_t. Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d9332eab23
commit
8bb1290e90
@@ -31,7 +31,7 @@ struct aspeed_sgpio {
|
|||||||
struct gpio_chip chip;
|
struct gpio_chip chip;
|
||||||
struct irq_chip intc;
|
struct irq_chip intc;
|
||||||
struct clk *pclk;
|
struct clk *pclk;
|
||||||
spinlock_t lock;
|
raw_spinlock_t lock;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
int irq;
|
int irq;
|
||||||
};
|
};
|
||||||
@@ -173,12 +173,12 @@ static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
|
|||||||
enum aspeed_sgpio_reg reg;
|
enum aspeed_sgpio_reg reg;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
|
|
||||||
reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata;
|
reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata;
|
||||||
rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
|
rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -215,11 +215,11 @@ static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
|
|||||||
struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
|
struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
|
|
||||||
sgpio_set_value(gc, offset, val);
|
sgpio_set_value(gc, offset, val);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
|
static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
|
||||||
@@ -236,9 +236,9 @@ static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int v
|
|||||||
/* No special action is required for setting the direction; we'll
|
/* No special action is required for setting the direction; we'll
|
||||||
* error-out in sgpio_set_value if this isn't an output GPIO */
|
* error-out in sgpio_set_value if this isn't an output GPIO */
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
rc = sgpio_set_value(gc, offset, val);
|
rc = sgpio_set_value(gc, offset, val);
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -277,11 +277,11 @@ static void aspeed_sgpio_irq_ack(struct irq_data *d)
|
|||||||
|
|
||||||
status_addr = bank_reg(gpio, bank, reg_irq_status);
|
status_addr = bank_reg(gpio, bank, reg_irq_status);
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
|
|
||||||
iowrite32(bit, status_addr);
|
iowrite32(bit, status_addr);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
|
static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
|
||||||
@@ -296,7 +296,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
|
|||||||
irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
|
irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
|
||||||
addr = bank_reg(gpio, bank, reg_irq_enable);
|
addr = bank_reg(gpio, bank, reg_irq_enable);
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
|
|
||||||
reg = ioread32(addr);
|
reg = ioread32(addr);
|
||||||
if (set)
|
if (set)
|
||||||
@@ -306,7 +306,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
|
|||||||
|
|
||||||
iowrite32(reg, addr);
|
iowrite32(reg, addr);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aspeed_sgpio_irq_mask(struct irq_data *d)
|
static void aspeed_sgpio_irq_mask(struct irq_data *d)
|
||||||
@@ -355,7 +355,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
|
|
||||||
addr = bank_reg(gpio, bank, reg_irq_type0);
|
addr = bank_reg(gpio, bank, reg_irq_type0);
|
||||||
reg = ioread32(addr);
|
reg = ioread32(addr);
|
||||||
@@ -372,7 +372,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
|
|||||||
reg = (reg & ~bit) | type2;
|
reg = (reg & ~bit) | type2;
|
||||||
iowrite32(reg, addr);
|
iowrite32(reg, addr);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
|
|
||||||
irq_set_handler_locked(d, handler);
|
irq_set_handler_locked(d, handler);
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
|
|||||||
|
|
||||||
reg = bank_reg(gpio, to_bank(offset), reg_tolerance);
|
reg = bank_reg(gpio, to_bank(offset), reg_tolerance);
|
||||||
|
|
||||||
spin_lock_irqsave(&gpio->lock, flags);
|
raw_spin_lock_irqsave(&gpio->lock, flags);
|
||||||
|
|
||||||
val = readl(reg);
|
val = readl(reg);
|
||||||
|
|
||||||
@@ -478,7 +478,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
|
|||||||
|
|
||||||
writel(val, reg);
|
writel(val, reg);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpio->lock, flags);
|
raw_spin_unlock_irqrestore(&gpio->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -575,7 +575,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev)
|
|||||||
iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval |
|
iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval |
|
||||||
ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL);
|
ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL);
|
||||||
|
|
||||||
spin_lock_init(&gpio->lock);
|
raw_spin_lock_init(&gpio->lock);
|
||||||
|
|
||||||
gpio->chip.parent = &pdev->dev;
|
gpio->chip.parent = &pdev->dev;
|
||||||
gpio->chip.ngpio = nr_gpios * 2;
|
gpio->chip.ngpio = nr_gpios * 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user