Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 225750
b: refs/heads/master
c: a0b7bd0
h: refs/heads/master
v: v3
  • Loading branch information
Russell King committed Dec 8, 2010
1 parent 4474abf commit 8c87f64
Show file tree
Hide file tree
Showing 46 changed files with 507 additions and 239 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ac61d143ffe2a6db4d4bcf47c21a5159d6a1b644
refs/heads/master: a0b7bd0829194c03921915a68ee4a331ee394223
69 changes: 21 additions & 48 deletions trunk/arch/arm/common/gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@

static DEFINE_SPINLOCK(irq_controller_lock);

/* Address of GIC 0 CPU interface */
void __iomem *gic_cpu_base_addr __read_mostly;

struct gic_chip_data {
unsigned int irq_offset;
void __iomem *dist_base;
Expand All @@ -48,7 +45,7 @@ struct gic_chip_data {
#define MAX_GIC_NR 1
#endif

static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
static struct gic_chip_data gic_data[MAX_GIC_NR];

static inline void __iomem *gic_dist_base(unsigned int irq)
{
Expand Down Expand Up @@ -216,16 +213,21 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
set_irq_chained_handler(irq, gic_handle_cascade_irq);
}

static void __init gic_dist_init(struct gic_chip_data *gic,
unsigned int irq_start)
void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
unsigned int irq_start)
{
unsigned int gic_irqs, irq_limit, i;
void __iomem *base = gic->dist_base;
u32 cpumask = 1 << smp_processor_id();

if (gic_nr >= MAX_GIC_NR)
BUG();

cpumask |= cpumask << 8;
cpumask |= cpumask << 16;

gic_data[gic_nr].dist_base = base;
gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;

writel(0, base + GIC_DIST_CTRL);

/*
Expand Down Expand Up @@ -265,7 +267,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
/*
* Limit number of interrupts registered to the platform maximum
*/
irq_limit = gic->irq_offset + gic_irqs;
irq_limit = gic_data[gic_nr].irq_offset + gic_irqs;
if (WARN_ON(irq_limit > NR_IRQS))
irq_limit = NR_IRQS;

Expand All @@ -274,20 +276,27 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
*/
for (i = irq_start; i < irq_limit; i++) {
set_irq_chip(i, &gic_chip);
set_irq_chip_data(i, gic);
set_irq_chip_data(i, &gic_data[gic_nr]);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}

writel(1, base + GIC_DIST_CTRL);
}

static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
{
void __iomem *dist_base = gic->dist_base;
void __iomem *base = gic->cpu_base;
void __iomem *dist_base;
int i;

if (gic_nr >= MAX_GIC_NR)
BUG();

dist_base = gic_data[gic_nr].dist_base;
BUG_ON(!dist_base);

gic_data[gic_nr].cpu_base = base;

/*
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
Expand All @@ -305,42 +314,6 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
writel(1, base + GIC_CPU_CTRL);
}

void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __iomem *dist_base, void __iomem *cpu_base)
{
struct gic_chip_data *gic;

BUG_ON(gic_nr >= MAX_GIC_NR);

gic = &gic_data[gic_nr];
gic->dist_base = dist_base;
gic->cpu_base = cpu_base;
gic->irq_offset = (irq_start - 1) & ~31;

if (gic_nr == 0)
gic_cpu_base_addr = cpu_base;

gic_dist_init(gic, irq_start);
gic_cpu_init(gic);
}

void __cpuinit gic_secondary_init(unsigned int gic_nr)
{
BUG_ON(gic_nr >= MAX_GIC_NR);

gic_cpu_init(&gic_data[gic_nr]);
}

void __cpuinit gic_enable_ppi(unsigned int irq)
{
unsigned long flags;

local_irq_save(flags);
irq_to_desc(irq)->status |= IRQ_NOPROBE;
gic_unmask_irq(irq);
local_irq_restore(flags);
}

#ifdef CONFIG_SMP
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
Expand Down
75 changes: 0 additions & 75 deletions trunk/arch/arm/include/asm/hardware/entry-macro-gic.S

This file was deleted.

7 changes: 2 additions & 5 deletions trunk/arch/arm/include/asm/hardware/gic.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@
#define GIC_DIST_SOFTINT 0xf00

#ifndef __ASSEMBLY__
extern void __iomem *gic_cpu_base_addr;

void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
void gic_secondary_init(unsigned int);
void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
void gic_enable_ppi(unsigned int);
#endif

#endif
4 changes: 2 additions & 2 deletions trunk/arch/arm/include/asm/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,13 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED)
#define ioremap_wc(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_WC)
#define iounmap(cookie) __iounmap(cookie)
#define iounmap __iounmap
#else
#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC)
#define iounmap(cookie) __arch_iounmap(cookie)
#define iounmap __arch_iounmap
#endif

/*
Expand Down
7 changes: 6 additions & 1 deletion trunk/arch/arm/kernel/smp_twd.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ static void __cpuinit twd_calibrate_rate(void)
*/
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
unsigned long flags;

twd_calibrate_rate();

clk->name = "local_timer";
Expand All @@ -141,7 +143,10 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clk->min_delta_ns = clockevent_delta2ns(0xf, clk);

/* Make sure our local interrupt controller has this enabled */
gic_enable_ppi(clk->irq);
local_irq_save(flags);
irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
get_irq_chip(clk->irq)->unmask(clk->irq);
local_irq_restore(flags);

clockevents_register_device(clk);
}
Expand Down
7 changes: 5 additions & 2 deletions trunk/arch/arm/mach-cns3xxx/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,13 @@ void __init cns3xxx_map_io(void)
}

/* used by entry-macro.S */
void __iomem *gic_cpu_base_addr;

void __init cns3xxx_init_irq(void)
{
gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
__io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT);
gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29);
gic_cpu_init(0, gic_cpu_base_addr);
}

void cns3xxx_power_off(void)
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/mach-cns3xxx/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#ifndef __CNS3XXX_CORE_H
#define __CNS3XXX_CORE_H

extern void __iomem *gic_cpu_base_addr;
extern struct sys_timer cns3xxx_timer;

void __init cns3xxx_map_io(void);
Expand Down
66 changes: 65 additions & 1 deletion trunk/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,74 @@
*/

#include <mach/hardware.h>
#include <asm/hardware/entry-macro-gic.S>
#include <asm/hardware/gic.h>

.macro disable_fiq
.endm

.macro get_irqnr_preamble, base, tmp
ldr \base, =gic_cpu_base_addr
ldr \base, [\base]
.endm

.macro arch_ret_to_user, tmp1, tmp2
.endm

/*
* The interrupt numbering scheme is defined in the
* interrupt controller spec. To wit:
*
* Interrupts 0-15 are IPI
* 16-28 are reserved
* 29-31 are local. We allow 30 to be used for the watchdog.
* 32-1020 are global
* 1021-1022 are reserved
* 1023 is "spurious" (no interrupt)
*
* For now, we ignore all local interrupts so only return an interrupt if it's
* between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
*
* A simple read from the controller will tell us the number of the highest
* priority enabled interrupt. We then just need to check whether it is in the
* valid range for an IRQ (30-1020 inclusive).
*/

.macro get_irqnr_and_base, irqnr, irqstat, base, tmp

ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */

ldr \tmp, =1021

bic \irqnr, \irqstat, #0x1c00

cmp \irqnr, #29
cmpcc \irqnr, \irqnr
cmpne \irqnr, \tmp
cmpcs \irqnr, \irqnr

.endm

/* We assume that irqstat (the raw value of the IRQ acknowledge
* register) is preserved from the macro above.
* If there is an IPI, we immediately signal end of interrupt on the
* controller, since this requires the original irqstat value which
* we won't easily be able to recreate later.
*/

.macro test_for_ipi, irqnr, irqstat, base, tmp
bic \irqnr, \irqstat, #0x1c00
cmp \irqnr, #16
strcc \irqstat, [\base, #GIC_CPU_EOI]
cmpcs \irqnr, \irqnr
.endm

/* As above, this assumes that irqstat and base are preserved.. */

.macro test_for_ltirq, irqnr, irqstat, base, tmp
bic \irqnr, \irqstat, #0x1c00
mov \tmp, #0
cmp \irqnr, #29
moveq \tmp, #1
streq \irqstat, [\base, #GIC_CPU_EOI]
cmp \tmp, #0
.endm
4 changes: 2 additions & 2 deletions trunk/arch/arm/mach-davinci/include/mach/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
#define __mem_isa(a) (a)

#ifndef __ASSEMBLER__
#define __arch_ioremap(p, s, t) davinci_ioremap(p, s, t)
#define __arch_iounmap(v) davinci_iounmap(v)
#define __arch_ioremap davinci_ioremap
#define __arch_iounmap davinci_iounmap

void __iomem *davinci_ioremap(unsigned long phys, size_t size,
unsigned int type);
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/arm/mach-iop13xx/include/mach/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extern u32 iop13xx_atux_mem_base;
extern size_t iop13xx_atue_mem_size;
extern size_t iop13xx_atux_mem_size;

#define __arch_ioremap(a, s, f) __iop13xx_ioremap(a, s, f)
#define __arch_iounmap(a) __iop13xx_iounmap(a)
#define __arch_ioremap __iop13xx_ioremap
#define __arch_iounmap __iop13xx_iounmap

#endif
4 changes: 2 additions & 2 deletions trunk/arch/arm/mach-iop32x/include/mach/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
#define __mem_pci(a) (a)

#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
#define __arch_iounmap(a) __iop3xx_iounmap(a)
#define __arch_ioremap __iop3xx_ioremap
#define __arch_iounmap __iop3xx_iounmap

#endif
Loading

0 comments on commit 8c87f64

Please sign in to comment.