Commit 254c44ea authored by Russell King's avatar Russell King
Browse files

Merge branch 'gic-fasteoi' of git://linux-arm.org/linux-2.6-wd into devel-stable

parents 7b764153 6ac77e46
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before
entering atomic context, using:
entering atomic context, using:


    int flex_array_prealloc(struct flex_array *array, unsigned int start,
    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
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
flex_array_put() call on an element in that range is guaranteed not to
block.
block.


+1 −1
Original line number Original line Diff line number Diff line
VERSION = 2
VERSION = 2
PATCHLEVEL = 6
PATCHLEVEL = 6
SUBLEVEL = 39
SUBLEVEL = 39
EXTRAVERSION = -rc5
EXTRAVERSION = -rc7
NAME = Flesh-Eating Bats with Fangs
NAME = Flesh-Eating Bats with Fangs


# *DOCUMENTATION*
# *DOCUMENTATION*
+45 −39
Original line number Original line Diff line number Diff line
@@ -49,7 +49,7 @@ struct gic_chip_data {
 * Default make them NULL.
 * Default make them NULL.
 */
 */
struct irq_chip gic_arch_extn = {
struct irq_chip gic_arch_extn = {
	.irq_ack	= NULL,
	.irq_eoi	= NULL,
	.irq_mask	= NULL,
	.irq_mask	= NULL,
	.irq_unmask	= NULL,
	.irq_unmask	= NULL,
	.irq_retrigger	= NULL,
	.irq_retrigger	= NULL,
@@ -84,21 +84,12 @@ static inline unsigned int gic_irq(struct irq_data *d)
/*
/*
 * Routines to acknowledge, disable and enable interrupts
 * 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)
static void gic_mask_irq(struct irq_data *d)
{
{
	u32 mask = 1 << (d->irq % 32);
	u32 mask = 1 << (d->irq % 32);


	spin_lock(&irq_controller_lock);
	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)
	if (gic_arch_extn.irq_mask)
		gic_arch_extn.irq_mask(d);
		gic_arch_extn.irq_mask(d);
	spin_unlock(&irq_controller_lock);
	spin_unlock(&irq_controller_lock);
@@ -111,10 +102,21 @@ static void gic_unmask_irq(struct irq_data *d)
	spin_lock(&irq_controller_lock);
	spin_lock(&irq_controller_lock);
	if (gic_arch_extn.irq_unmask)
	if (gic_arch_extn.irq_unmask)
		gic_arch_extn.irq_unmask(d);
		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);
	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)
static int gic_set_type(struct irq_data *d, unsigned int type)
{
{
	void __iomem *base = gic_dist_base(d);
	void __iomem *base = gic_dist_base(d);
@@ -138,7 +140,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
	if (gic_arch_extn.irq_set_type)
	if (gic_arch_extn.irq_set_type)
		gic_arch_extn.irq_set_type(d, 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)
	if (type == IRQ_TYPE_LEVEL_HIGH)
		val &= ~confmask;
		val &= ~confmask;
	else if (type == IRQ_TYPE_EDGE_RISING)
	else if (type == IRQ_TYPE_EDGE_RISING)
@@ -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
	 * As recommended by the spec, disable the interrupt before changing
	 * the configuration
	 * the configuration
	 */
	 */
	if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
	if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
		writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
		enabled = true;
		enabled = true;
	}
	}


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


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


	spin_unlock(&irq_controller_lock);
	spin_unlock(&irq_controller_lock);


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


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


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


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


	spin_lock(&irq_controller_lock);
	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);
	spin_unlock(&irq_controller_lock);


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


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


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


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


	/*
	/*
	 * Find out how many interrupts are supported.
	 * Find out how many interrupts are supported.
	 * The GIC only supports up to 1020 interrupt sources.
	 * 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;
	gic_irqs = (gic_irqs + 1) * 32;
	if (gic_irqs > 1020)
	if (gic_irqs > 1020)
		gic_irqs = 1020;
		gic_irqs = 1020;
@@ -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.
	 * Set all global interrupts to be level triggered, active low.
	 */
	 */
	for (i = 32; i < gic_irqs; i += 16)
	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.
	 * Set all global interrupts to this CPU only.
	 */
	 */
	for (i = 32; i < gic_irqs; i += 4)
	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.
	 * Set priority on all global interrupts.
	 */
	 */
	for (i = 32; i < gic_irqs; i += 4)
	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
	 * Disable all interrupts.  Leave the PPI and SGIs alone
	 * as these enables are banked registers.
	 * as these enables are banked registers.
	 */
	 */
	for (i = 32; i < gic_irqs; i += 32)
	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
	 * Limit number of interrupts registered to the platform maximum
@@ -319,12 +319,12 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
	 * Setup the Linux IRQ subsystem.
	 * Setup the Linux IRQ subsystem.
	 */
	 */
	for (i = irq_start; i < irq_limit; i++) {
	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);
		irq_set_chip_data(i, gic);
		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
		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)
static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
@@ -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
	 * Deal with the banked PPI and SGI interrupts - disable all
	 * PPI interrupts, ensure all SGI interrupts are enabled.
	 * PPI interrupts, ensure all SGI interrupts are enabled.
	 */
	 */
	writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
	writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
	writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
	writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);


	/*
	/*
	 * Set priority on PPI and SGI interrupts
	 * Set priority on PPI and SGI interrupts
	 */
	 */
	for (i = 0; i < 32; i += 4)
	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_relaxed(0xf0, base + GIC_CPU_PRIMASK);
	writel(1, base + GIC_CPU_CTRL);
	writel_relaxed(1, base + GIC_CPU_CTRL);
}
}


void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
@@ -391,7 +391,13 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
{
	unsigned long map = *cpus_addr(*mask);
	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 */
	/* 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
#endif
+48 −0
Original line number Original line Diff line number Diff line
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 −0
Original line number Original line Diff line number Diff line
@@ -767,12 +767,20 @@ long arch_ptrace(struct task_struct *child, long request,


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

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

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


Loading