mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
A couple of fixes for interrupt chip drivers:
- Ensure to skip the clear register space in the MBIGEN driver when calculating the node register index. Otherwise the clear register is clobbered and the wrong node registers are accessed. - Fix a signed/unsigned confusion in the loongarch CPU driver which converts an error code to a huge "valid" interrupt number. - Convert the mesion GPIO interrupt controller lock to a raw spinlock so it works on RT. - Add a missing static to a internal function in the pic32 EVIC driver. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmavcLQTHHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYoYN3D/9kS+JGtkDdk1RazGtHKTMrPh+rRxKD P3UF3ApI2/G1gyOemcJWhxp8Y2iI5PqOJOwe+t82hMMSwWeOCKVcDcH0nL/RKmL1 DxC2pcXAm+WUbwwdcMsj3k5oYE/3AlNVp/KYluTwmnZoXu4o2MFkXOZUn+sTLdi3 NU3q0uslc5InbC/Dqh7YSC0g/QqnQhPFgrfbgFX0mg2ixchvWqcu/tYqTsPj0Jgz ZHaBUDQLdDL1ngCgAeiD2m9+qkFZRdjiYiV4xcRXc+kvCOWcRKo1CEX6hBmJh9YQ fTjDzrFcXihKdp8ivWlZ34BaYyQobS14wbuZ5TcyD8XuO7h6/gkeeoaClpXHHZSN T1O1vN2xxvn+wqge60HupPAAPBPmtX3cXW1bw1znSEDSSXhcYWD8J33kMZQZRSAw xZXipqSi9vy0s8ZGhk7abNR+uEWAaCM9a4r4UEF15nAIgZjlLN9QwVTsZ12lwyte aeH1HxV7Vv3775qy5SJkoRiWBMTSXy0G69ho/pjatE2GHmkJnncx5VGGh+SMg/Ri xWOfwq36rv8YaTmoAWm/j3FsLnMDEqCju+sOO3J+5H24Zb5BUiLmeInkqi3j+jDq NoFZyT2c7W94YiAUIL7nf5CJ1Sdlm7LIsyoKFtq6AkmTiZGI6henUc6c+3Q8Sihk 802+TD53qdu/Qw== =WBFB -----END PGP SIGNATURE----- Merge tag 'irq-urgent-2024-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull irq fixes from Thomas Gleixner: "A couple of fixes for interrupt chip drivers: - Make sure to skip the clear register space in the MBIGEN driver when calculating the node register index. Otherwise the clear register is clobbered and the wrong node registers are accessed. - Fix a signed/unsigned confusion in the loongarch CPU driver which converts an error code to a huge "valid" interrupt number. - Convert the mesion GPIO interrupt controller lock to a raw spinlock so it works on RT. - Add a missing static to a internal function in the pic32 EVIC driver" * tag 'irq-urgent-2024-08-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/mbigen: Fix mbigen node address layout irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to 'raw_spinlock_t' irqchip/irq-pic32-evic: Add missing 'static' to internal function irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq()
This commit is contained in:
commit
953f776459
@ -18,11 +18,13 @@ struct fwnode_handle *cpuintc_handle;
|
||||
|
||||
static u32 lpic_gsi_to_irq(u32 gsi)
|
||||
{
|
||||
int irq = 0;
|
||||
|
||||
/* Only pch irqdomain transferring is required for LoongArch. */
|
||||
if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ)
|
||||
return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
|
||||
irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
|
||||
|
||||
return 0;
|
||||
return (irq > 0) ? irq : 0;
|
||||
}
|
||||
|
||||
static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi)
|
||||
|
@ -64,6 +64,20 @@ struct mbigen_device {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static inline unsigned int get_mbigen_node_offset(unsigned int nid)
|
||||
{
|
||||
unsigned int offset = nid * MBIGEN_NODE_OFFSET;
|
||||
|
||||
/*
|
||||
* To avoid touched clear register in unexpected way, we need to directly
|
||||
* skip clear register when access to more than 10 mbigen nodes.
|
||||
*/
|
||||
if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET))
|
||||
offset += MBIGEN_NODE_OFFSET;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
|
||||
{
|
||||
unsigned int nid, pin;
|
||||
@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
|
||||
nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
|
||||
pin = hwirq % IRQS_PER_MBIGEN_NODE;
|
||||
|
||||
return pin * 4 + nid * MBIGEN_NODE_OFFSET
|
||||
+ REG_MBIGEN_VEC_OFFSET;
|
||||
return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET;
|
||||
}
|
||||
|
||||
static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
|
||||
@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
|
||||
*mask = 1 << (irq_ofst % 32);
|
||||
ofst = irq_ofst / 32 * 4;
|
||||
|
||||
*addr = ofst + nid * MBIGEN_NODE_OFFSET
|
||||
+ REG_MBIGEN_TYPE_OFFSET;
|
||||
*addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
|
||||
|
@ -178,7 +178,7 @@ struct meson_gpio_irq_controller {
|
||||
void __iomem *base;
|
||||
u32 channel_irqs[MAX_NUM_CHANNEL];
|
||||
DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
|
||||
spinlock_t lock;
|
||||
raw_spinlock_t lock;
|
||||
};
|
||||
|
||||
static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
|
||||
@ -187,14 +187,14 @@ static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
|
||||
unsigned long flags;
|
||||
u32 tmp;
|
||||
|
||||
spin_lock_irqsave(&ctl->lock, flags);
|
||||
raw_spin_lock_irqsave(&ctl->lock, flags);
|
||||
|
||||
tmp = readl_relaxed(ctl->base + reg);
|
||||
tmp &= ~mask;
|
||||
tmp |= val;
|
||||
writel_relaxed(tmp, ctl->base + reg);
|
||||
|
||||
spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
}
|
||||
|
||||
static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
|
||||
@ -244,12 +244,12 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
|
||||
unsigned long flags;
|
||||
unsigned int idx;
|
||||
|
||||
spin_lock_irqsave(&ctl->lock, flags);
|
||||
raw_spin_lock_irqsave(&ctl->lock, flags);
|
||||
|
||||
/* Find a free channel */
|
||||
idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
|
||||
if (idx >= ctl->params->nr_channels) {
|
||||
spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
pr_err("No channel available\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
@ -257,7 +257,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
|
||||
/* Mark the channel as used */
|
||||
set_bit(idx, ctl->channel_map);
|
||||
|
||||
spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&ctl->lock, flags);
|
||||
|
||||
/*
|
||||
* Setup the mux of the channel to route the signal of the pad
|
||||
@ -567,7 +567,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
|
||||
if (!ctl)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&ctl->lock);
|
||||
raw_spin_lock_init(&ctl->lock);
|
||||
|
||||
ctl->base = of_iomap(node, 0);
|
||||
if (!ctl->base) {
|
||||
|
@ -161,9 +161,9 @@ static int pic32_irq_domain_map(struct irq_domain *d, unsigned int virq,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pic32_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
|
||||
const u32 *intspec, unsigned int intsize,
|
||||
irq_hw_number_t *out_hwirq, unsigned int *out_type)
|
||||
static int pic32_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
|
||||
const u32 *intspec, unsigned int intsize,
|
||||
irq_hw_number_t *out_hwirq, unsigned int *out_type)
|
||||
{
|
||||
struct evic_chip_data *priv = d->host_data;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user