Commit bb11cff3 authored by Qais Yousef's avatar Qais Yousef Committed by Thomas Gleixner

MIPS: Make smp CMP, CPS and MT use the new generic IPI functions

This commit does several things to avoid breaking bisectability.

	1- Remove IPI init code from irqchip/mips-gic
	2- Implement the new irqchip->send_ipi() in irqchip/mips-gic
	3- Select GENERIC_IRQ_IPI Kconfig symbol for MIPS_GIC
	4- Change MIPS SMP to use the generic IPI implementation

Only the SMP variants that use GIC were converted as it's the only irqchip that
will have the support for generic IPI for now.
Signed-off-by: default avatarQais Yousef <qais.yousef@imgtec.com>
Acked-by: default avatarRalf Baechle <ralf@linux-mips.org>
Cc: <jason@lakedaemon.net>
Cc: <marc.zyngier@arm.com>
Cc: <jiang.liu@linux.intel.com>
Cc: <linux-mips@linux-mips.org>
Cc: <lisa.parratt@imgtec.com>
Cc: Qais Yousef <qsyousef@gmail.com>
Link: http://lkml.kernel.org/r/1449580830-23652-18-git-send-email-qais.yousef@imgtec.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent fbde2d7d
...@@ -44,8 +44,9 @@ static inline void plat_smp_setup(void) ...@@ -44,8 +44,9 @@ static inline void plat_smp_setup(void)
mp_ops->smp_setup(); mp_ops->smp_setup();
} }
extern void gic_send_ipi_single(int cpu, unsigned int action); extern void mips_smp_send_ipi_single(int cpu, unsigned int action);
extern void gic_send_ipi_mask(const struct cpumask *mask, unsigned int action); extern void mips_smp_send_ipi_mask(const struct cpumask *mask,
unsigned int action);
#else /* !CONFIG_SMP */ #else /* !CONFIG_SMP */
......
...@@ -149,8 +149,8 @@ void __init cmp_prepare_cpus(unsigned int max_cpus) ...@@ -149,8 +149,8 @@ void __init cmp_prepare_cpus(unsigned int max_cpus)
} }
struct plat_smp_ops cmp_smp_ops = { struct plat_smp_ops cmp_smp_ops = {
.send_ipi_single = gic_send_ipi_single, .send_ipi_single = mips_smp_send_ipi_single,
.send_ipi_mask = gic_send_ipi_mask, .send_ipi_mask = mips_smp_send_ipi_mask,
.init_secondary = cmp_init_secondary, .init_secondary = cmp_init_secondary,
.smp_finish = cmp_smp_finish, .smp_finish = cmp_smp_finish,
.boot_secondary = cmp_boot_secondary, .boot_secondary = cmp_boot_secondary,
......
...@@ -472,8 +472,8 @@ static struct plat_smp_ops cps_smp_ops = { ...@@ -472,8 +472,8 @@ static struct plat_smp_ops cps_smp_ops = {
.boot_secondary = cps_boot_secondary, .boot_secondary = cps_boot_secondary,
.init_secondary = cps_init_secondary, .init_secondary = cps_init_secondary,
.smp_finish = cps_smp_finish, .smp_finish = cps_smp_finish,
.send_ipi_single = gic_send_ipi_single, .send_ipi_single = mips_smp_send_ipi_single,
.send_ipi_mask = gic_send_ipi_mask, .send_ipi_mask = mips_smp_send_ipi_mask,
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
.cpu_disable = cps_cpu_disable, .cpu_disable = cps_cpu_disable,
.cpu_die = cps_cpu_die, .cpu_die = cps_cpu_die,
......
...@@ -121,7 +121,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) ...@@ -121,7 +121,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action)
#ifdef CONFIG_MIPS_GIC #ifdef CONFIG_MIPS_GIC
if (gic_present) { if (gic_present) {
gic_send_ipi_single(cpu, action); mips_smp_send_ipi_single(cpu, action);
return; return;
} }
#endif #endif
......
...@@ -209,6 +209,7 @@ config KEYSTONE_IRQ ...@@ -209,6 +209,7 @@ config KEYSTONE_IRQ
config MIPS_GIC config MIPS_GIC
bool bool
select GENERIC_IRQ_IPI
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
select MIPS_CM select MIPS_CM
......
...@@ -280,9 +280,11 @@ static void gic_bind_eic_interrupt(int irq, int set) ...@@ -280,9 +280,11 @@ static void gic_bind_eic_interrupt(int irq, int set)
GIC_VPE_EIC_SS(irq), set); GIC_VPE_EIC_SS(irq), set);
} }
void gic_send_ipi(unsigned int intr) static void gic_send_ipi(struct irq_data *d, unsigned int cpu)
{ {
gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(intr)); irq_hw_number_t hwirq = GIC_HWIRQ_TO_SHARED(irqd_to_hwirq(d));
gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(hwirq));
} }
int gic_get_c0_compare_int(void) int gic_get_c0_compare_int(void)
...@@ -495,6 +497,7 @@ static struct irq_chip gic_edge_irq_controller = { ...@@ -495,6 +497,7 @@ static struct irq_chip gic_edge_irq_controller = {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.irq_set_affinity = gic_set_affinity, .irq_set_affinity = gic_set_affinity,
#endif #endif
.ipi_send_single = gic_send_ipi,
}; };
static void gic_handle_local_int(bool chained) static void gic_handle_local_int(bool chained)
...@@ -588,83 +591,6 @@ static void gic_irq_dispatch(struct irq_desc *desc) ...@@ -588,83 +591,6 @@ static void gic_irq_dispatch(struct irq_desc *desc)
gic_handle_shared_int(true); gic_handle_shared_int(true);
} }
#ifdef CONFIG_MIPS_GIC_IPI
static int gic_resched_int_base;
static int gic_call_int_base;
unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
{
return gic_resched_int_base + cpu;
}
unsigned int plat_ipi_call_int_xlate(unsigned int cpu)
{
return gic_call_int_base + cpu;
}
static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
{
scheduler_ipi();
return IRQ_HANDLED;
}
static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
{
generic_smp_call_function_interrupt();
return IRQ_HANDLED;
}
static struct irqaction irq_resched = {
.handler = ipi_resched_interrupt,
.flags = IRQF_PERCPU,
.name = "IPI resched"
};
static struct irqaction irq_call = {
.handler = ipi_call_interrupt,
.flags = IRQF_PERCPU,
.name = "IPI call"
};
static __init void gic_ipi_init_one(unsigned int intr, int cpu,
struct irqaction *action)
{
int virq = irq_create_mapping(gic_irq_domain,
GIC_SHARED_TO_HWIRQ(intr));
int i;
gic_map_to_vpe(intr, mips_cm_vp_id(cpu));
for (i = 0; i < NR_CPUS; i++)
clear_bit(intr, pcpu_masks[i].pcpu_mask);
set_bit(intr, pcpu_masks[cpu].pcpu_mask);
irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
irq_set_handler(virq, handle_percpu_irq);
setup_irq(virq, action);
}
static __init void gic_ipi_init(void)
{
int i;
/* Use last 2 * NR_CPUS interrupts as IPIs */
gic_resched_int_base = gic_shared_intrs - nr_cpu_ids;
gic_call_int_base = gic_resched_int_base - nr_cpu_ids;
for (i = 0; i < nr_cpu_ids; i++) {
gic_ipi_init_one(gic_call_int_base + i, i, &irq_call);
gic_ipi_init_one(gic_resched_int_base + i, i, &irq_resched);
}
}
#else
static inline void gic_ipi_init(void)
{
}
#endif
static void __init gic_basic_init(void) static void __init gic_basic_init(void)
{ {
unsigned int i; unsigned int i;
...@@ -1105,8 +1031,6 @@ static void __init __gic_init(unsigned long gic_base_addr, ...@@ -1105,8 +1031,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
bitmap_set(ipi_resrv, gic_shared_intrs - 2 * gic_vpes, 2 * gic_vpes); bitmap_set(ipi_resrv, gic_shared_intrs - 2 * gic_vpes, 2 * gic_vpes);
gic_basic_init(); gic_basic_init();
gic_ipi_init();
} }
void __init gic_init(unsigned long gic_base_addr, void __init gic_init(unsigned long gic_base_addr,
......
...@@ -261,9 +261,6 @@ extern void gic_write_compare(cycle_t cnt); ...@@ -261,9 +261,6 @@ extern void gic_write_compare(cycle_t cnt);
extern void gic_write_cpu_compare(cycle_t cnt, int cpu); extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
extern void gic_start_count(void); extern void gic_start_count(void);
extern void gic_stop_count(void); extern void gic_stop_count(void);
extern void gic_send_ipi(unsigned int intr);
extern unsigned int plat_ipi_call_int_xlate(unsigned int);
extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
extern int gic_get_c0_compare_int(void); extern int gic_get_c0_compare_int(void);
extern int gic_get_c0_perfcount_int(void); extern int gic_get_c0_perfcount_int(void);
extern int gic_get_c0_fdc_int(void); extern int gic_get_c0_fdc_int(void);
......
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