Skip to content

Commit

Permalink
Merge branch 'gic-fasteoi' of git://linux-arm.org/linux-2.6-wd into d…
Browse files Browse the repository at this point in the history
…evel-stable
  • Loading branch information
Russell King committed May 11, 2011
2 parents 7b76415 + 6ac77e4 commit 254c44e
Show file tree
Hide file tree
Showing 142 changed files with 1,952 additions and 1,586 deletions.
4 changes: 2 additions & 2 deletions Documentation/flexible-arrays.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before
entering atomic context, using:

int flex_array_prealloc(struct flex_array *array, unsigned int start,
unsigned int end, gfp_t flags);
unsigned int nr_elements, gfp_t flags);

This function will ensure that memory for the elements indexed in the range
defined by start and end has been allocated. Thereafter, a
defined by start and nr_elements has been allocated. Thereafter, a
flex_array_put() call on an element in that range is guaranteed not to
block.

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 39
EXTRAVERSION = -rc5
EXTRAVERSION = -rc7
NAME = Flesh-Eating Bats with Fangs

# *DOCUMENTATION*
Expand Down
84 changes: 45 additions & 39 deletions arch/arm/common/gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct gic_chip_data {
* Default make them NULL.
*/
struct irq_chip gic_arch_extn = {
.irq_ack = NULL,
.irq_eoi = NULL,
.irq_mask = NULL,
.irq_unmask = NULL,
.irq_retrigger = NULL,
Expand Down Expand Up @@ -84,21 +84,12 @@ static inline unsigned int gic_irq(struct irq_data *d)
/*
* Routines to acknowledge, disable and enable interrupts
*/
static void gic_ack_irq(struct irq_data *d)
{
spin_lock(&irq_controller_lock);
if (gic_arch_extn.irq_ack)
gic_arch_extn.irq_ack(d);
writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
spin_unlock(&irq_controller_lock);
}

static void gic_mask_irq(struct irq_data *d)
{
u32 mask = 1 << (d->irq % 32);

spin_lock(&irq_controller_lock);
writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
if (gic_arch_extn.irq_mask)
gic_arch_extn.irq_mask(d);
spin_unlock(&irq_controller_lock);
Expand All @@ -111,10 +102,21 @@ static void gic_unmask_irq(struct irq_data *d)
spin_lock(&irq_controller_lock);
if (gic_arch_extn.irq_unmask)
gic_arch_extn.irq_unmask(d);
writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
spin_unlock(&irq_controller_lock);
}

static void gic_eoi_irq(struct irq_data *d)
{
if (gic_arch_extn.irq_eoi) {
spin_lock(&irq_controller_lock);
gic_arch_extn.irq_eoi(d);
spin_unlock(&irq_controller_lock);
}

writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
}

static int gic_set_type(struct irq_data *d, unsigned int type)
{
void __iomem *base = gic_dist_base(d);
Expand All @@ -138,7 +140,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
if (gic_arch_extn.irq_set_type)
gic_arch_extn.irq_set_type(d, type);

val = readl(base + GIC_DIST_CONFIG + confoff);
val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
if (type == IRQ_TYPE_LEVEL_HIGH)
val &= ~confmask;
else if (type == IRQ_TYPE_EDGE_RISING)
Expand All @@ -148,15 +150,15 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
* As recommended by the spec, disable the interrupt before changing
* the configuration
*/
if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
enabled = true;
}

writel(val, base + GIC_DIST_CONFIG + confoff);
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);

if (enabled)
writel(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);

spin_unlock(&irq_controller_lock);

Expand Down Expand Up @@ -188,8 +190,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,

spin_lock(&irq_controller_lock);
d->node = cpu;
val = readl(reg) & ~mask;
writel(val | bit, reg);
val = readl_relaxed(reg) & ~mask;
writel_relaxed(val | bit, reg);
spin_unlock(&irq_controller_lock);

return 0;
Expand Down Expand Up @@ -218,11 +220,10 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
unsigned int cascade_irq, gic_irq;
unsigned long status;

/* primary controller ack'ing */
chip->irq_ack(&desc->irq_data);
chained_irq_enter(chip, desc);

spin_lock(&irq_controller_lock);
status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
spin_unlock(&irq_controller_lock);

gic_irq = (status & 0x3ff);
Expand All @@ -236,15 +237,14 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(cascade_irq);

out:
/* primary controller unmasking */
chip->irq_unmask(&desc->irq_data);
chained_irq_exit(chip, desc);
}

static struct irq_chip gic_chip = {
.name = "GIC",
.irq_ack = gic_ack_irq,
.irq_mask = gic_mask_irq,
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_eoi_irq,
.irq_set_type = gic_set_type,
.irq_retrigger = gic_retrigger,
#ifdef CONFIG_SMP
Expand Down Expand Up @@ -272,13 +272,13 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
cpumask |= cpumask << 8;
cpumask |= cpumask << 16;

writel(0, base + GIC_DIST_CTRL);
writel_relaxed(0, base + GIC_DIST_CTRL);

/*
* Find out how many interrupts are supported.
* The GIC only supports up to 1020 interrupt sources.
*/
gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
gic_irqs = (gic_irqs + 1) * 32;
if (gic_irqs > 1020)
gic_irqs = 1020;
Expand All @@ -287,26 +287,26 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
* Set all global interrupts to be level triggered, active low.
*/
for (i = 32; i < gic_irqs; i += 16)
writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);

/*
* Set all global interrupts to this CPU only.
*/
for (i = 32; i < gic_irqs; i += 4)
writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);

/*
* Set priority on all global interrupts.
*/
for (i = 32; i < gic_irqs; i += 4)
writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);

/*
* Disable all interrupts. Leave the PPI and SGIs alone
* as these enables are banked registers.
*/
for (i = 32; i < gic_irqs; i += 32)
writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);

/*
* Limit number of interrupts registered to the platform maximum
Expand All @@ -319,12 +319,12 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
* Setup the Linux IRQ subsystem.
*/
for (i = irq_start; i < irq_limit; i++) {
irq_set_chip_and_handler(i, &gic_chip, handle_level_irq);
irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
irq_set_chip_data(i, gic);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}

writel(1, base + GIC_DIST_CTRL);
writel_relaxed(1, base + GIC_DIST_CTRL);
}

static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
Expand All @@ -337,17 +337,17 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
*/
writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);

/*
* Set priority on PPI and SGI interrupts
*/
for (i = 0; i < 32; i += 4)
writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);

writel(0xf0, base + GIC_CPU_PRIMASK);
writel(1, base + GIC_CPU_CTRL);
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
writel_relaxed(1, base + GIC_CPU_CTRL);
}

void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
Expand Down Expand Up @@ -391,7 +391,13 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
unsigned long map = *cpus_addr(*mask);

/*
* Ensure that stores to Normal memory are visible to the
* other CPUs before issuing the IPI.
*/
dsb();

/* this always happens on GIC0 */
writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
}
#endif
48 changes: 48 additions & 0 deletions arch/arm/configs/at91x40_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
CONFIG_EXPERIMENTAL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EMBEDDED=y
# CONFIG_HOTPLUG is not set
# CONFIG_ELF_CORE is not set
# CONFIG_FUTEX is not set
# CONFIG_TIMERFD is not set
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
# CONFIG_LBDAF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
# CONFIG_MMU is not set
CONFIG_ARCH_AT91=y
CONFIG_ARCH_AT91X40=y
CONFIG_MACH_AT91EB01=y
CONFIG_AT91_EARLY_USART0=y
CONFIG_CPU_ARM7TDMI=y
CONFIG_SET_MEM_PARAM=y
CONFIG_DRAM_BASE=0x01000000
CONFIG_DRAM_SIZE=0x00400000
CONFIG_FLASH_MEM_BASE=0x01400000
CONFIG_PROCESSOR_ID=0x14000040
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_BINFMT_FLAT=y
# CONFIG_SUSPEND is not set
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_RAM=y
CONFIG_MTD_ROM=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_EXT2_FS=y
# CONFIG_DNOTIFY is not set
CONFIG_ROMFS_FS=y
# CONFIG_ENABLE_MUST_CHECK is not set
8 changes: 8 additions & 0 deletions arch/arm/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,12 +767,20 @@ long arch_ptrace(struct task_struct *child, long request,

#ifdef CONFIG_HAVE_HW_BREAKPOINT
case PTRACE_GETHBPREGS:
if (ptrace_get_breakpoints(child) < 0)
return -ESRCH;

ret = ptrace_gethbpregs(child, addr,
(unsigned long __user *)data);
ptrace_put_breakpoints(child);
break;
case PTRACE_SETHBPREGS:
if (ptrace_get_breakpoints(child) < 0)
return -ESRCH;

ret = ptrace_sethbpregs(child, addr,
(unsigned long __user *)data);
ptrace_put_breakpoints(child);
break;
#endif

Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-at91/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ config ARCH_AT91CAP9
select CPU_ARM926T
select GENERIC_CLOCKEVENTS
select HAVE_FB_ATMEL
select HAVE_NET_MACB

config ARCH_AT572D940HF
bool "AT572D940HF"
Expand Down
7 changes: 6 additions & 1 deletion arch/arm/mach-at91/board-eb01.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
#include <mach/board.h>
#include "generic.h"

static void __init at91eb01_init_irq(void)
{
at91x40_init_interrupts(NULL);
}

static void __init at91eb01_map_io(void)
{
at91x40_initialize(40000000);
Expand All @@ -38,7 +43,7 @@ static void __init at91eb01_map_io(void)
MACHINE_START(AT91EB01, "Atmel AT91 EB01")
/* Maintainer: Greg Ungerer <gerg@snapgear.com> */
.timer = &at91x40_timer,
.init_irq = at91x40_init_interrupts,
.init_irq = at91eb01_init_irq,
.map_io = at91eb01_map_io,
MACHINE_END

28 changes: 28 additions & 0 deletions arch/arm/mach-at91/include/mach/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define ARCH_ID_AT91SAM9G45 0x819b05a0
#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
#define ARCH_ID_AT91SAM9X5 0x819a05a0
#define ARCH_ID_AT91CAP9 0x039A03A0

#define ARCH_ID_AT91SAM9XE128 0x329973a0
Expand Down Expand Up @@ -55,6 +56,12 @@ static inline unsigned long at91_cpu_fully_identify(void)
#define ARCH_EXID_AT91SAM9G46 0x00000003
#define ARCH_EXID_AT91SAM9G45 0x00000004

#define ARCH_EXID_AT91SAM9G15 0x00000000
#define ARCH_EXID_AT91SAM9G35 0x00000001
#define ARCH_EXID_AT91SAM9X35 0x00000002
#define ARCH_EXID_AT91SAM9G25 0x00000003
#define ARCH_EXID_AT91SAM9X25 0x00000004

static inline unsigned long at91_exid_identify(void)
{
return at91_sys_read(AT91_DBGU_EXID);
Expand Down Expand Up @@ -143,6 +150,27 @@ static inline unsigned long at91cap9_rev_identify(void)
#define cpu_is_at91sam9m11() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9X5
#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5)
#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G15))
#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G35))
#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9X35))
#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G25))
#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9X25))
#else
#define cpu_is_at91sam9x5() (0)
#define cpu_is_at91sam9g15() (0)
#define cpu_is_at91sam9g35() (0)
#define cpu_is_at91sam9x35() (0)
#define cpu_is_at91sam9g25() (0)
#define cpu_is_at91sam9x25() (0)
#endif

#ifdef CONFIG_ARCH_AT91CAP9
#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
Expand Down
Loading

0 comments on commit 254c44e

Please sign in to comment.