Skip to content

Commit 9e8e891

Browse files
dilingerMarc Zyngier
authored andcommitted
irqchip/mmp: Mask off interrupts from other cores
On mmp3, there's an extra set of ICU registers (ICU2) that handle interrupts on the extra cores. When masking off interrupts on MP1, these should be masked as well. We add a new interrupt controller via device tree to identify when we're looking at an mmp3 machine via compatible field of "marvell,mmp3-intc". [[email protected]: Changed "mrvl,mmp3-intc" compatible strings to "marvell,mmp3-intc". Tidied up the subject line a bit.] Signed-off-by: Andres Salomon <[email protected]> Signed-off-by: Lubomir Rintel <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] -- Changes since v1: - Moved mmp3-specific mmp_icu2_base initialization from mmp_init_bases() to mmp3_of_init() so that we don't have to check for marvell,mmp3-intc compatibility twice. - Drop an superfluous call to irq_set_default_host() arch/arm/mach-mmp/regs-icu.h | 3 +++ drivers/irqchip/irq-mmp.c | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) Signed-off-by: Andres Salomon <[email protected]> Signed-off-by: Lubomir Rintel <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a46bc5f commit 9e8e891

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

arch/arm/mach-mmp/regs-icu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#define ICU_VIRT_BASE (AXI_VIRT_BASE + 0x82000)
1212
#define ICU_REG(x) (ICU_VIRT_BASE + (x))
1313

14+
#define ICU2_VIRT_BASE (AXI_VIRT_BASE + 0x84000)
15+
#define ICU2_REG(x) (ICU2_VIRT_BASE + (x))
16+
1417
#define ICU_INT_CONF(n) ICU_REG((n) << 2)
1518
#define ICU_INT_CONF_MASK (0xf)
1619

drivers/irqchip/irq-mmp.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct icu_chip_data {
4444
unsigned int conf_enable;
4545
unsigned int conf_disable;
4646
unsigned int conf_mask;
47+
unsigned int conf2_mask;
4748
unsigned int clr_mfp_irq_base;
4849
unsigned int clr_mfp_hwirq;
4950
struct irq_domain *domain;
@@ -53,9 +54,11 @@ struct mmp_intc_conf {
5354
unsigned int conf_enable;
5455
unsigned int conf_disable;
5556
unsigned int conf_mask;
57+
unsigned int conf2_mask;
5658
};
5759

5860
static void __iomem *mmp_icu_base;
61+
static void __iomem *mmp_icu2_base;
5962
static struct icu_chip_data icu_data[MAX_ICU_NR];
6063
static int max_icu_nr;
6164

@@ -98,6 +101,16 @@ static void icu_mask_irq(struct irq_data *d)
98101
r &= ~data->conf_mask;
99102
r |= data->conf_disable;
100103
writel_relaxed(r, mmp_icu_base + (hwirq << 2));
104+
105+
if (data->conf2_mask) {
106+
/*
107+
* ICU1 (above) only controls PJ4 MP1; if using SMP,
108+
* we need to also mask the MP2 and MM cores via ICU2.
109+
*/
110+
r = readl_relaxed(mmp_icu2_base + (hwirq << 2));
111+
r &= ~data->conf2_mask;
112+
writel_relaxed(r, mmp_icu2_base + (hwirq << 2));
113+
}
101114
} else {
102115
r = readl_relaxed(data->reg_mask) | (1 << hwirq);
103116
writel_relaxed(r, data->reg_mask);
@@ -201,6 +214,14 @@ static const struct mmp_intc_conf mmp2_conf = {
201214
MMP2_ICU_INT_ROUTE_PJ4_FIQ,
202215
};
203216

217+
static struct mmp_intc_conf mmp3_conf = {
218+
.conf_enable = 0x20,
219+
.conf_disable = 0x0,
220+
.conf_mask = MMP2_ICU_INT_ROUTE_PJ4_IRQ |
221+
MMP2_ICU_INT_ROUTE_PJ4_FIQ,
222+
.conf2_mask = 0xf0,
223+
};
224+
204225
static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs)
205226
{
206227
int hwirq;
@@ -426,6 +447,33 @@ static int __init mmp2_of_init(struct device_node *node,
426447
}
427448
IRQCHIP_DECLARE(mmp2_intc, "mrvl,mmp2-intc", mmp2_of_init);
428449

450+
static int __init mmp3_of_init(struct device_node *node,
451+
struct device_node *parent)
452+
{
453+
int ret;
454+
455+
mmp_icu2_base = of_iomap(node, 1);
456+
if (!mmp_icu2_base) {
457+
pr_err("Failed to get interrupt controller register #2\n");
458+
return -ENODEV;
459+
}
460+
461+
ret = mmp_init_bases(node);
462+
if (ret < 0) {
463+
iounmap(mmp_icu2_base);
464+
return ret;
465+
}
466+
467+
icu_data[0].conf_enable = mmp3_conf.conf_enable;
468+
icu_data[0].conf_disable = mmp3_conf.conf_disable;
469+
icu_data[0].conf_mask = mmp3_conf.conf_mask;
470+
icu_data[0].conf2_mask = mmp3_conf.conf2_mask;
471+
set_handle_irq(mmp2_handle_irq);
472+
max_icu_nr = 1;
473+
return 0;
474+
}
475+
IRQCHIP_DECLARE(mmp3_intc, "marvell,mmp3-intc", mmp3_of_init);
476+
429477
static int __init mmp2_mux_of_init(struct device_node *node,
430478
struct device_node *parent)
431479
{

0 commit comments

Comments
 (0)