MIPS: Make GIC code platform independent.
The GIC interrupt code is used by multiple platforms and the current code was half Malta dependent code. These changes abstract away the platform specific differences. Signed-off-by: Steven J. Hill <sjhill@mips.com>
This commit is contained in:
parent
ec47b27434
commit
0b271f5600
4 changed files with 81 additions and 72 deletions
|
@ -341,15 +341,44 @@ struct gic_shared_intr_map {
|
|||
unsigned int local_intr_mask;
|
||||
};
|
||||
|
||||
/* GIC nomenclature for Core Interrupt Pins. */
|
||||
#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
|
||||
#define GIC_CPU_INT1 1 /* . */
|
||||
#define GIC_CPU_INT2 2 /* . */
|
||||
#define GIC_CPU_INT3 3 /* . */
|
||||
#define GIC_CPU_INT4 4 /* . */
|
||||
#define GIC_CPU_INT5 5 /* Core Interrupt 5 */
|
||||
|
||||
/* Local GIC interrupts. */
|
||||
#define GIC_INT_TMR (GIC_CPU_INT5)
|
||||
#define GIC_INT_PERFCTR (GIC_CPU_INT5)
|
||||
|
||||
/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
|
||||
#define GIC_CPU_TO_VEC_OFFSET (2)
|
||||
|
||||
/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
|
||||
#define GIC_PIN_TO_VEC_OFFSET (1)
|
||||
|
||||
extern unsigned long _gic_base;
|
||||
extern unsigned int gic_irq_base;
|
||||
extern unsigned int gic_irq_flags[];
|
||||
extern struct gic_shared_intr_map gic_shared_intr_map[];
|
||||
|
||||
extern void gic_init(unsigned long gic_base_addr,
|
||||
unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
|
||||
unsigned int intrmap_size, unsigned int irqbase);
|
||||
|
||||
extern void gic_clocksource_init(unsigned int);
|
||||
extern unsigned int gic_get_int(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 void gic_bind_eic_interrupt(int irq, int set);
|
||||
extern unsigned int gic_get_timer_pending(void);
|
||||
extern void gic_enable_interrupt(int irq_vec);
|
||||
extern void gic_disable_interrupt(int irq_vec);
|
||||
extern void gic_irq_ack(struct irq_data *d);
|
||||
extern void gic_finish_irq(struct irq_data *d);
|
||||
extern void gic_platform_init(int irqs, struct irq_chip *irq_controller);
|
||||
|
||||
#endif /* _ASM_GICREGS_H */
|
||||
|
|
|
@ -1,31 +1,16 @@
|
|||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* Defines for the Malta interrupt controller.
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2000,2012 MIPS Technologies, Inc. All rights reserved.
|
||||
* Carsten Langgaard <carstenl@mips.com>
|
||||
* Steven J. Hill <sjhill@mips.com>
|
||||
*/
|
||||
#ifndef _MIPS_MALTAINT_H
|
||||
#define _MIPS_MALTAINT_H
|
||||
|
||||
#include <irq.h>
|
||||
#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
|
||||
|
||||
/*
|
||||
* Interrupts 0..15 are used for Malta ISA compatible interrupts
|
||||
|
@ -78,26 +63,6 @@
|
|||
#define MSC01E_INT_PERFCTR 10
|
||||
#define MSC01E_INT_CPUCTR 11
|
||||
|
||||
/* GIC's Nomenclature for Core Interrupt Pins on the Malta */
|
||||
#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
|
||||
#define GIC_CPU_INT1 1 /* . */
|
||||
#define GIC_CPU_INT2 2 /* . */
|
||||
#define GIC_CPU_INT3 3 /* . */
|
||||
#define GIC_CPU_INT4 4 /* . */
|
||||
#define GIC_CPU_INT5 5 /* Core Interrupt 5 */
|
||||
|
||||
/* MALTA GIC local interrupts */
|
||||
#define GIC_INT_TMR (GIC_CPU_INT5)
|
||||
#define GIC_INT_PERFCTR (GIC_CPU_INT5)
|
||||
|
||||
/* GIC constants */
|
||||
/* Add 2 to convert non-eic hw int # to eic vector # */
|
||||
#define GIC_CPU_TO_VEC_OFFSET (2)
|
||||
/* If we map an intr to pin X, GIC will actually generate vector X+1 */
|
||||
#define GIC_PIN_TO_VEC_OFFSET (1)
|
||||
|
||||
#define GIC_EXT_INTR(x) x
|
||||
|
||||
/* External Interrupts used for IPI */
|
||||
#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16
|
||||
#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
|
||||
|
@ -108,10 +73,4 @@
|
|||
#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22
|
||||
#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23
|
||||
|
||||
#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void maltaint_init(void);
|
||||
#endif
|
||||
|
||||
#endif /* !(_MIPS_MALTAINT_H) */
|
||||
|
|
|
@ -12,12 +12,11 @@
|
|||
#include <asm-generic/bitops/find.h>
|
||||
|
||||
|
||||
static unsigned long _gic_base;
|
||||
static unsigned int _irqbase;
|
||||
static unsigned int gic_irq_flags[GIC_NUM_INTRS];
|
||||
#define GIC_IRQ_FLAG_EDGE 0x0001
|
||||
unsigned long _gic_base;
|
||||
unsigned int gic_irq_base;
|
||||
unsigned int gic_irq_flags[GIC_NUM_INTRS];
|
||||
|
||||
struct gic_pcpu_mask pcpu_masks[NR_CPUS];
|
||||
static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
|
||||
static struct gic_pending_regs pending_regs[NR_CPUS];
|
||||
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
|
||||
|
||||
|
@ -87,27 +86,16 @@ unsigned int gic_get_int(void)
|
|||
return i;
|
||||
}
|
||||
|
||||
static void gic_irq_ack(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_CLR_INTR_MASK(irq);
|
||||
|
||||
if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE)
|
||||
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
|
||||
}
|
||||
|
||||
static void gic_mask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
unsigned int irq = d->irq - gic_irq_base;
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_CLR_INTR_MASK(irq);
|
||||
}
|
||||
|
||||
static void gic_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
unsigned int irq = d->irq - gic_irq_base;
|
||||
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
|
||||
GIC_SET_INTR_MASK(irq);
|
||||
}
|
||||
|
@ -119,7 +107,7 @@ static DEFINE_SPINLOCK(gic_lock);
|
|||
static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
|
||||
bool force)
|
||||
{
|
||||
unsigned int irq = d->irq - _irqbase;
|
||||
unsigned int irq = d->irq - gic_irq_base;
|
||||
cpumask_t tmp = CPU_MASK_NONE;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
@ -194,7 +182,7 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
|
|||
if (flags & GIC_FLAG_TRANSPARENT)
|
||||
GIC_SET_INTR_MASK(intr);
|
||||
if (trigtype == GIC_TRIG_EDGE)
|
||||
gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
|
||||
gic_irq_flags[intr] |= GIC_TRIG_EDGE;
|
||||
}
|
||||
|
||||
static void __init gic_basic_init(int numintrs, int numvpes,
|
||||
|
@ -227,9 +215,6 @@ static void __init gic_basic_init(int numintrs, int numvpes,
|
|||
}
|
||||
|
||||
vpe_local_setup(numvpes);
|
||||
|
||||
for (i = _irqbase; i < (_irqbase + numintrs); i++)
|
||||
irq_set_chip(i, &gic_irq_controller);
|
||||
}
|
||||
|
||||
void __init gic_init(unsigned long gic_base_addr,
|
||||
|
@ -242,7 +227,7 @@ void __init gic_init(unsigned long gic_base_addr,
|
|||
|
||||
_gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
|
||||
gic_addrspace_size);
|
||||
_irqbase = irqbase;
|
||||
gic_irq_base = irqbase;
|
||||
|
||||
GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
|
||||
numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
|
||||
|
@ -255,4 +240,6 @@ void __init gic_init(unsigned long gic_base_addr,
|
|||
pr_debug("%s called\n", __func__);
|
||||
|
||||
gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
|
||||
|
||||
gic_platform_init(numintrs, &gic_irq_controller);
|
||||
}
|
||||
|
|
|
@ -747,3 +747,37 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
|
|||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void gic_enable_interrupt(int irq_vec)
|
||||
{
|
||||
GIC_SET_INTR_MASK(irq_vec);
|
||||
}
|
||||
|
||||
void gic_disable_interrupt(int irq_vec)
|
||||
{
|
||||
GIC_CLR_INTR_MASK(irq_vec);
|
||||
}
|
||||
|
||||
void gic_irq_ack(struct irq_data *d)
|
||||
{
|
||||
int irq = (d->irq - gic_irq_base);
|
||||
|
||||
GIC_CLR_INTR_MASK(irq);
|
||||
|
||||
if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
|
||||
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
|
||||
}
|
||||
|
||||
void gic_finish_irq(struct irq_data *d)
|
||||
{
|
||||
/* Enable interrupts. */
|
||||
GIC_SET_INTR_MASK(d->irq - gic_irq_base);
|
||||
}
|
||||
|
||||
void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
|
||||
irq_set_chip(i, irq_controller);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue