Loading Documentation/devicetree/bindings/arm/cpus.txt 0 → 100644 +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>; }; }; arch/arm/common/gic.c +36 −9 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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. Loading Loading @@ -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); Loading Loading @@ -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. Loading Loading @@ -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 Loading arch/arm/include/asm/Kbuild +0 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ generic-y += local64.h generic-y += msgbuf.h generic-y += param.h generic-y += parport.h generic-y += percpu.h generic-y += poll.h generic-y += resource.h generic-y += sections.h Loading arch/arm/include/asm/cpu.h +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ struct cpuinfo_arm { struct cpu cpu; u32 cpuid; #ifdef CONFIG_SMP unsigned int loops_per_jiffy; #endif Loading arch/arm/include/asm/cputype.h +13 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
Documentation/devicetree/bindings/arm/cpus.txt 0 → 100644 +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>; }; };
arch/arm/common/gic.c +36 −9 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading @@ -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. Loading Loading @@ -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); Loading Loading @@ -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. Loading Loading @@ -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 Loading
arch/arm/include/asm/Kbuild +0 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ generic-y += local64.h generic-y += msgbuf.h generic-y += param.h generic-y += parport.h generic-y += percpu.h generic-y += poll.h generic-y += resource.h generic-y += sections.h Loading
arch/arm/include/asm/cpu.h +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ struct cpuinfo_arm { struct cpu cpu; u32 cpuid; #ifdef CONFIG_SMP unsigned int loops_per_jiffy; #endif Loading
arch/arm/include/asm/cputype.h +13 −0 Original line number Diff line number Diff line Loading @@ -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 Loading