mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
irqchip/gic: support config amp os irqs
Signed-off-by: Tony Xie <tony.xie@rock-chips.com> Change-Id: Id7ff9d5cccfe5656462542fcfa68fef51cdd910e
This commit is contained in:
@@ -10,6 +10,10 @@
|
||||
|
||||
#include "irq-gic-common.h"
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_AMP
|
||||
#include <soc/rockchip/rockchip_amp.h>
|
||||
#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
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
|
||||
#include "irq-gic-common.h"
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_AMP
|
||||
#include <soc/rockchip/rockchip_amp.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
#include <asm/cpufeature.h>
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user