mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +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"
|
#include "irq-gic-common.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_AMP
|
||||||
|
#include <soc/rockchip/rockchip_amp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
|
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
|
||||||
|
|
||||||
static const struct gic_kvm_info *gic_kvm_info;
|
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.
|
* 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)
|
for (i = 32; i < gic_irqs; i += 4)
|
||||||
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
|
writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deactivate and disable all SPIs. Leave the PPI and SGIs
|
* Deactivate and disable all SPIs. Leave the PPI and SGIs
|
||||||
|
|||||||
@@ -47,6 +47,10 @@
|
|||||||
|
|
||||||
#include "irq-gic-common.h"
|
#include "irq-gic-common.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_AMP
|
||||||
|
#include <soc/rockchip/rockchip_amp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARM64
|
#ifdef CONFIG_ARM64
|
||||||
#include <asm/cpufeature.h>
|
#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)
|
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);
|
gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gic_eoimode1_mask_irq(struct irq_data *d)
|
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);
|
gic_mask_irq(d);
|
||||||
/*
|
/*
|
||||||
* When masking a forwarded interrupt, make sure it is
|
* 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)
|
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);
|
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);
|
u32 hwirq = gic_irq(d);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_AMP
|
||||||
|
if (rockchip_amp_check_amp_irq(hwirq))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
if (hwirq < 16)
|
if (hwirq < 16)
|
||||||
hwirq = this_cpu_read(sgi_intid);
|
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);
|
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. */
|
/* Do not deactivate an IRQ forwarded to a vcpu. */
|
||||||
if (irqd_is_forwarded_to_vcpu(d))
|
if (irqd_is_forwarded_to_vcpu(d))
|
||||||
return;
|
return;
|
||||||
@@ -246,6 +270,10 @@ static int gic_irq_set_irqchip_state(struct irq_data *d,
|
|||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_AMP
|
||||||
|
if (rockchip_amp_check_amp_irq(gic_irq(d)))
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case IRQCHIP_STATE_PENDING:
|
case IRQCHIP_STATE_PENDING:
|
||||||
reg = val ? GIC_DIST_PENDING_SET : GIC_DIST_PENDING_CLEAR;
|
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);
|
unsigned int gicirq = gic_irq(d);
|
||||||
int ret;
|
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 */
|
/* Interrupt configuration for SGIs can't be changed */
|
||||||
if (gicirq < 16)
|
if (gicirq < 16)
|
||||||
return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0;
|
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.
|
* Set all global interrupts to this CPU only.
|
||||||
*/
|
*/
|
||||||
cpumask = gic_get_cpumask(gic);
|
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 << 8;
|
||||||
cpumask |= cpumask << 16;
|
cpumask |= cpumask << 16;
|
||||||
for (i = 32; i < gic_irqs; i += 4)
|
for (i = 32; i < gic_irqs; i += 4)
|
||||||
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
|
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
gic_dist_config(base, gic_irqs, NULL);
|
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);
|
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d);
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_AMP
|
||||||
|
if (rockchip_amp_check_amp_irq(gic_irq(d)))
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!force)
|
if (!force)
|
||||||
cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
||||||
else
|
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);
|
gic_enable_of_quirks(node, gic_quirks, gic);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ROCKCHIP_AMP
|
||||||
|
rockchip_amp_get_gic_info();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|||||||
Reference in New Issue
Block a user