Skip to content

Commit

Permalink
Merge tag 'irq-urgent-2024-08-04' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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()
  • Loading branch information
torvalds committed Aug 4, 2024
2 parents 3bc70ad + 6be6cba commit 953f776
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 16 deletions.
6 changes: 4 additions & 2 deletions drivers/irqchip/irq-loongarch-cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
20 changes: 16 additions & 4 deletions drivers/irqchip/irq-mbigen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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,
Expand Down
14 changes: 7 additions & 7 deletions drivers/irqchip/irq-meson-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -244,20 +244,20 @@ 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;
}

/* 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
Expand Down Expand Up @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions drivers/irqchip/irq-pic32-evic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 953f776

Please sign in to comment.