diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index f47b41dfd023..7ce79b512e01 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -10,6 +10,10 @@ #include "irq-gic-common.h" +#ifdef CONFIG_ROCKCHIP_AMP +#include +#endif + static DEFINE_RAW_SPINLOCK(irq_controller_lock); static const struct gic_kvm_info *gic_kvm_info; @@ -112,8 +116,25 @@ void gic_dist_config(void __iomem *base, int gic_irqs, /* * Set priority on all global interrupts. */ +#ifdef CONFIG_ROCKCHIP_AMP + for (i = 32; i < gic_irqs; i += 4) { + u32 amp_pri, j; + + amp_pri = 0; + for (j = 0; j < 4; j++) { + if (rockchip_amp_check_amp_irq(i + j)) { + amp_pri |= rockchip_amp_get_irq_prio(i + j) << + (j * 8); + } else { + amp_pri |= GICD_INT_DEF_PRI << (j * 8); + } + } + writel_relaxed(amp_pri, base + GIC_DIST_PRI + i); + } +#else for (i = 32; i < gic_irqs; i += 4) writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); +#endif /* * Deactivate and disable all SPIs. Leave the PPI and SGIs diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index ac027de9e5c4..cd3f72b4e2d6 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -47,6 +47,10 @@ #include "irq-gic-common.h" +#ifdef CONFIG_ROCKCHIP_AMP +#include +#endif + #ifdef CONFIG_ARM64 #include @@ -194,11 +198,19 @@ static int gic_peek_irq(struct irq_data *d, u32 offset) static void gic_mask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR); } static void gic_eoimode1_mask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_mask_irq(d); /* * When masking a forwarded interrupt, make sure it is @@ -214,6 +226,10 @@ static void gic_eoimode1_mask_irq(struct irq_data *d) static void gic_unmask_irq(struct irq_data *d) { +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif gic_poke_irq(d, GIC_DIST_ENABLE_SET); } @@ -221,6 +237,10 @@ static void gic_eoi_irq(struct irq_data *d) { u32 hwirq = gic_irq(d); +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(hwirq)) + return; +#endif if (hwirq < 16) hwirq = this_cpu_read(sgi_intid); @@ -231,6 +251,10 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d) { u32 hwirq = gic_irq(d); +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return; +#endif /* Do not deactivate an IRQ forwarded to a vcpu. */ if (irqd_is_forwarded_to_vcpu(d)) return; @@ -246,6 +270,10 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, { u32 reg; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif switch (which) { case IRQCHIP_STATE_PENDING: reg = val ? GIC_DIST_PENDING_SET : GIC_DIST_PENDING_CLEAR; @@ -296,6 +324,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type) unsigned int gicirq = gic_irq(d); int ret; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif + /* Interrupt configuration for SGIs can't be changed */ if (gicirq < 16) return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; @@ -492,10 +525,29 @@ static void gic_dist_init(struct gic_chip_data *gic) * Set all global interrupts to this CPU only. */ cpumask = gic_get_cpumask(gic); + +#ifdef CONFIG_ROCKCHIP_AMP + for (i = 32; i < gic_irqs; i += 4) { + u32 maskval; + unsigned int j; + + maskval = 0; + for (j = 0; j < 4; j++) { + if (rockchip_amp_check_amp_irq(i + j)) { + maskval |= rockchip_amp_get_irq_cpumask(i + j) << + (j * 8); + } else { + maskval |= cpumask << (j * 8); + } + } + writel_relaxed(maskval, base + GIC_DIST_TARGET + i * 4 / 4); + } +#else cpumask |= cpumask << 8; cpumask |= cpumask << 16; for (i = 32; i < gic_irqs; i += 4) writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); +#endif gic_dist_config(base, gic_irqs, NULL); @@ -847,6 +899,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); unsigned int cpu; +#ifdef CONFIG_ROCKCHIP_AMP + if (rockchip_amp_check_amp_irq(gic_irq(d))) + return -EINVAL; +#endif + if (!force) cpu = cpumask_any_and(mask_val, cpu_online_mask); else @@ -1509,6 +1566,10 @@ static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node) gic_enable_of_quirks(node, gic_quirks, gic); +#ifdef CONFIG_ROCKCHIP_AMP + rockchip_amp_get_gic_info(); +#endif + return 0; error: