Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e38eb34a authored by Russell King's avatar Russell King
Browse files

Merge branch 'cluster-boot-protocol' of git://linux-arm.org/linux-2.6-lp into devel-stable

parents 2079f30e 384a2902
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
* ARM CPUs binding description

The device tree allows to describe the layout of CPUs in a system through
the "cpus" node, which in turn contains a number of subnodes (ie "cpu")
defining properties for every cpu.

Bindings for CPU nodes follow the ePAPR standard, available from:

http://devicetree.org

For the ARM architecture every CPU node must contain the following properties:

- device_type:	must be "cpu"
- reg:		property matching the CPU MPIDR[23:0] register bits
		reg[31:24] bits must be set to 0
- compatible:	should be one of:
		"arm,arm1020"
		"arm,arm1020e"
		"arm,arm1022"
		"arm,arm1026"
		"arm,arm720"
		"arm,arm740"
		"arm,arm7tdmi"
		"arm,arm920"
		"arm,arm922"
		"arm,arm925"
		"arm,arm926"
		"arm,arm940"
		"arm,arm946"
		"arm,arm9tdmi"
		"arm,cortex-a5"
		"arm,cortex-a7"
		"arm,cortex-a8"
		"arm,cortex-a9"
		"arm,cortex-a15"
		"arm,arm1136"
		"arm,arm1156"
		"arm,arm1176"
		"arm,arm11mpcore"
		"faraday,fa526"
		"intel,sa110"
		"intel,sa1100"
		"marvell,feroceon"
		"marvell,mohawk"
		"marvell,xsc3"
		"marvell,xscale"

Example:

	cpus {
		#size-cells = <0>;
		#address-cells = <1>;

		CPU0: cpu@0 {
			device_type = "cpu";
			compatible = "arm,cortex-a15";
			reg = <0x0>;
		};

		CPU1: cpu@1 {
			device_type = "cpu";
			compatible = "arm,cortex-a15";
			reg = <0x1>;
		};

		CPU2: cpu@100 {
			device_type = "cpu";
			compatible = "arm,cortex-a7";
			reg = <0x100>;
		};

		CPU3: cpu@101 {
			device_type = "cpu";
			compatible = "arm,cortex-a7";
			reg = <0x101>;
		};
	};
+36 −9
Original line number Diff line number Diff line
@@ -69,6 +69,14 @@ struct gic_chip_data {

static DEFINE_RAW_SPINLOCK(irq_controller_lock);

/*
 * The GIC mapping of CPU interfaces does not necessarily match
 * the logical CPU numbering.  Let's use a mapping as returned
 * by the GIC itself.
 */
#define NR_GIC_CPU_IF 8
static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;

/*
 * Supported arch specific GIC irq extension.
 * Default make them NULL.
@@ -238,11 +246,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
	u32 val, mask, bit;

	if (cpu >= 8 || cpu >= nr_cpu_ids)
	if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
		return -EINVAL;

	mask = 0xff << shift;
	bit = 1 << (cpu_logical_map(cpu) + shift);
	bit = gic_cpu_map[cpu] << shift;

	raw_spin_lock(&irq_controller_lock);
	val = readl_relaxed(reg) & ~mask;
@@ -349,11 +357,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
	u32 cpumask;
	unsigned int gic_irqs = gic->gic_irqs;
	void __iomem *base = gic_data_dist_base(gic);
	u32 cpu = cpu_logical_map(smp_processor_id());

	cpumask = 1 << cpu;
	cpumask |= cpumask << 8;
	cpumask |= cpumask << 16;

	writel_relaxed(0, base + GIC_DIST_CTRL);

@@ -366,6 +369,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
	/*
	 * Set all global interrupts to this CPU only.
	 */
	cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0);
	for (i = 32; i < gic_irqs; i += 4)
		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);

@@ -389,8 +393,24 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
	void __iomem *dist_base = gic_data_dist_base(gic);
	void __iomem *base = gic_data_cpu_base(gic);
	unsigned int cpu_mask, cpu = smp_processor_id();
	int i;

	/*
	 * Get what the GIC says our CPU mask is.
	 */
	BUG_ON(cpu >= NR_GIC_CPU_IF);
	cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0);
	gic_cpu_map[cpu] = cpu_mask;

	/*
	 * Clear our mask from the other map entries in case they're
	 * still undefined.
	 */
	for (i = 0; i < NR_GIC_CPU_IF; i++)
		if (i != cpu)
			gic_cpu_map[i] &= ~cpu_mask;

	/*
	 * Deal with the banked PPI and SGI interrupts - disable all
	 * PPI interrupts, ensure all SGI interrupts are enabled.
@@ -646,7 +666,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
{
	irq_hw_number_t hwirq_base;
	struct gic_chip_data *gic;
	int gic_irqs, irq_base;
	int gic_irqs, irq_base, i;

	BUG_ON(gic_nr >= MAX_GIC_NR);

@@ -682,6 +702,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
		gic_set_base_accessor(gic, gic_get_common_base);
	}

	/*
	 * Initialize the CPU interface map to all CPUs.
	 * It will be refined as each CPU probes its ID.
	 */
	for (i = 0; i < NR_GIC_CPU_IF; i++)
		gic_cpu_map[i] = 0xff;

	/*
	 * For primary GICs, skip over SGIs.
	 * For secondary GICs, skip over PPIs, too.
@@ -737,7 +764,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)

	/* Convert our logical CPU mask into a physical one. */
	for_each_cpu(cpu, mask)
		map |= 1 << cpu_logical_map(cpu);
		map |= gic_cpu_map[cpu];

	/*
	 * Ensure that stores to Normal memory are visible to the
+13 −0
Original line number Diff line number Diff line
@@ -25,6 +25,19 @@
#define CPUID_EXT_ISAR4	"c2, 4"
#define CPUID_EXT_ISAR5	"c2, 5"

#define MPIDR_SMP_BITMASK (0x3 << 30)
#define MPIDR_SMP_VALUE (0x2 << 30)

#define MPIDR_MT_BITMASK (0x1 << 24)

#define MPIDR_HWID_BITMASK 0xFFFFFF

#define MPIDR_LEVEL_BITS 8
#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)

#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)

extern unsigned int processor_id;

#ifdef CONFIG_CPU_CP15
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@

extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
extern void arm_dt_memblock_reserve(void);
extern void __init arm_dt_init_cpu_maps(void);

#else /* CONFIG_OF */

@@ -24,6 +25,7 @@ static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
}

static inline void arm_dt_memblock_reserve(void) { }
static inline void arm_dt_init_cpu_maps(void) { }

#endif /* CONFIG_OF */
#endif /* ASMARM_PROM_H */
+17 −0
Original line number Diff line number Diff line
@@ -5,6 +5,9 @@
#ifndef __ASMARM_SMP_PLAT_H
#define __ASMARM_SMP_PLAT_H

#include <linux/cpumask.h>
#include <linux/err.h>

#include <asm/cputype.h>

/*
@@ -48,5 +51,19 @@ static inline int cache_ops_need_broadcast(void)
 */
extern int __cpu_logical_map[];
#define cpu_logical_map(cpu)	__cpu_logical_map[cpu]
/*
 * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
 *  - mpidr: MPIDR[23:0] to be used for the look-up
 *
 * Returns the cpu logical index or -EINVAL on look-up error
 */
static inline int get_logical_index(u32 mpidr)
{
	int cpu;
	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
		if (cpu_logical_map(cpu) == mpidr)
			return cpu;
	return -EINVAL;
}

#endif
Loading