Commit 7ec46b51 authored by Marc Zyngier's avatar Marc Zyngier

irqchip/gic: Refactor SMP configuration

As we are about to change quite a lot of the SMP support code,
let's start by moving it around so that it minimizes the amount
of #ifdefery.
Reviewed-by: default avatarValentin Schneider <valentin.schneider@arm.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 64b499d8
...@@ -325,28 +325,6 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) ...@@ -325,28 +325,6 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
return 0; return 0;
} }
#ifdef CONFIG_SMP
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force)
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d);
unsigned int cpu;
if (!force)
cpu = cpumask_any_and(mask_val, cpu_online_mask);
else
cpu = cpumask_first(mask_val);
if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
return -EINVAL;
writeb_relaxed(gic_cpu_map[cpu], reg);
irq_data_update_effective_affinity(d, cpumask_of(cpu));
return IRQ_SET_MASK_OK_DONE;
}
#endif
static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
{ {
u32 irqstat, irqnr; u32 irqstat, irqnr;
...@@ -795,6 +773,26 @@ static int gic_pm_init(struct gic_chip_data *gic) ...@@ -795,6 +773,26 @@ static int gic_pm_init(struct gic_chip_data *gic)
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force)
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d);
unsigned int cpu;
if (!force)
cpu = cpumask_any_and(mask_val, cpu_online_mask);
else
cpu = cpumask_first(mask_val);
if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
return -EINVAL;
writeb_relaxed(gic_cpu_map[cpu], reg);
irq_data_update_effective_affinity(d, cpumask_of(cpu));
return IRQ_SET_MASK_OK_DONE;
}
static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{ {
int cpu; int cpu;
...@@ -824,6 +822,23 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) ...@@ -824,6 +822,23 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
gic_unlock_irqrestore(flags); gic_unlock_irqrestore(flags);
} }
static int gic_starting_cpu(unsigned int cpu)
{
gic_cpu_init(&gic_data[0]);
return 0;
}
static __init void gic_smp_init(void)
{
set_smp_cross_call(gic_raise_softirq);
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
"irqchip/arm/gic:starting",
gic_starting_cpu, NULL);
}
#else
#define gic_smp_init() do { } while(0)
#define gic_set_affinity NULL
#endif #endif
#ifdef CONFIG_BL_SWITCHER #ifdef CONFIG_BL_SWITCHER
...@@ -1027,12 +1042,6 @@ static int gic_irq_domain_translate(struct irq_domain *d, ...@@ -1027,12 +1042,6 @@ static int gic_irq_domain_translate(struct irq_domain *d,
return -EINVAL; return -EINVAL;
} }
static int gic_starting_cpu(unsigned int cpu)
{
gic_cpu_init(&gic_data[0]);
return 0;
}
static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *arg) unsigned int nr_irqs, void *arg)
{ {
...@@ -1079,10 +1088,8 @@ static void gic_init_chip(struct gic_chip_data *gic, struct device *dev, ...@@ -1079,10 +1088,8 @@ static void gic_init_chip(struct gic_chip_data *gic, struct device *dev,
gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity; gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity;
} }
#ifdef CONFIG_SMP
if (gic == &gic_data[0]) if (gic == &gic_data[0])
gic->chip.irq_set_affinity = gic_set_affinity; gic->chip.irq_set_affinity = gic_set_affinity;
#endif
} }
static int gic_init_bases(struct gic_chip_data *gic, static int gic_init_bases(struct gic_chip_data *gic,
...@@ -1199,12 +1206,7 @@ static int __init __gic_init_bases(struct gic_chip_data *gic, ...@@ -1199,12 +1206,7 @@ static int __init __gic_init_bases(struct gic_chip_data *gic,
*/ */
for (i = 0; i < NR_GIC_CPU_IF; i++) for (i = 0; i < NR_GIC_CPU_IF; i++)
gic_cpu_map[i] = 0xff; gic_cpu_map[i] = 0xff;
#ifdef CONFIG_SMP
set_smp_cross_call(gic_raise_softirq);
#endif
cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING,
"irqchip/arm/gic:starting",
gic_starting_cpu, NULL);
set_handle_irq(gic_handle_irq); set_handle_irq(gic_handle_irq);
if (static_branch_likely(&supports_deactivate_key)) if (static_branch_likely(&supports_deactivate_key))
pr_info("GIC: Using split EOI/Deactivate mode\n"); pr_info("GIC: Using split EOI/Deactivate mode\n");
...@@ -1221,6 +1223,8 @@ static int __init __gic_init_bases(struct gic_chip_data *gic, ...@@ -1221,6 +1223,8 @@ static int __init __gic_init_bases(struct gic_chip_data *gic,
ret = gic_init_bases(gic, handle); ret = gic_init_bases(gic, handle);
if (ret) if (ret)
kfree(name); kfree(name);
else if (gic == &gic_data[0])
gic_smp_init();
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment