diff --git a/[refs] b/[refs] index b9e7b5d825d1..17086eb41729 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 26a806c064b7be25fc7c255b5d83646cf4645a93 +refs/heads/master: 37c241ed668bd2271760c8e1e4138d1aba4d0b79 diff --git a/trunk/Documentation/devicetree/bindings/arm/pmu.txt b/trunk/Documentation/devicetree/bindings/arm/pmu.txt index 343781b9f246..1c044eb320cc 100644 --- a/trunk/Documentation/devicetree/bindings/arm/pmu.txt +++ b/trunk/Documentation/devicetree/bindings/arm/pmu.txt @@ -7,12 +7,8 @@ representation in the device tree should be done as under:- Required properties: - compatible : should be one of - "arm,cortex-a15-pmu" "arm,cortex-a9-pmu" "arm,cortex-a8-pmu" - "arm,cortex-a7-pmu" - "arm,cortex-a5-pmu" - "arm,arm11mpcore-pmu" "arm,arm1176-pmu" "arm,arm1136-pmu" - interrupts : 1 combined interrupt or 1 per core. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 437a7dd36843..fdc0119963e7 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -595,6 +595,7 @@ M: Will Deacon S: Maintained F: arch/arm/kernel/perf_event* F: arch/arm/oprofile/common.c +F: arch/arm/kernel/pmu.c F: arch/arm/include/asm/pmu.h F: arch/arm/kernel/hw_breakpoint.c F: arch/arm/include/asm/hw_breakpoint.h diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 46ef5652da68..c5f9ae5dbd1a 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1179,6 +1179,12 @@ config XSCALE_PMU depends on CPU_XSCALE default y +config CPU_HAS_PMU + depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \ + (!ARCH_OMAP3 || OMAP3_EMU) + default y + bool + config MULTI_IRQ_HANDLER bool help @@ -1751,7 +1757,7 @@ config HIGHPTE config HW_PERF_EVENTS bool "Enable hardware performance counter support for perf events" - depends on PERF_EVENTS + depends on PERF_EVENTS && CPU_HAS_PMU default y help Enable hardware performance counter support for perf events. If diff --git a/trunk/arch/arm/configs/kzm9d_defconfig b/trunk/arch/arm/configs/kzm9d_defconfig index 8c49df66cac3..26146ffea1a5 100644 --- a/trunk/arch/arm/configs/kzm9d_defconfig +++ b/trunk/arch/arm/configs/kzm9d_defconfig @@ -8,7 +8,6 @@ CONFIG_LOG_BUF_SHIFT=16 CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL_SYSCALL=y CONFIG_EMBEDDED=y -CONFIG_PERF_EVENTS=y CONFIG_SLAB=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set diff --git a/trunk/arch/arm/configs/kzm9g_defconfig b/trunk/arch/arm/configs/kzm9g_defconfig index 5d0c66708960..2388c8610627 100644 --- a/trunk/arch/arm/configs/kzm9g_defconfig +++ b/trunk/arch/arm/configs/kzm9g_defconfig @@ -14,7 +14,6 @@ CONFIG_NAMESPACES=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL_SYSCALL=y CONFIG_EMBEDDED=y -CONFIG_PERF_EVENTS=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y diff --git a/trunk/arch/arm/include/asm/perf_event.h b/trunk/arch/arm/include/asm/perf_event.h index 625cd621a436..e074948d8143 100644 --- a/trunk/arch/arm/include/asm/perf_event.h +++ b/trunk/arch/arm/include/asm/perf_event.h @@ -12,13 +12,6 @@ #ifndef __ARM_PERF_EVENT_H__ #define __ARM_PERF_EVENT_H__ -/* - * The ARMv7 CPU PMU supports up to 32 event counters. - */ -#define ARMPMU_MAX_HWEVENTS 32 - -#define HW_OP_UNSUPPORTED 0xFFFF -#define C(_x) PERF_COUNT_HW_CACHE_##_x -#define CACHE_OP_UNSUPPORTED 0xFFFF +/* Nothing to see here... */ #endif /* __ARM_PERF_EVENT_H__ */ diff --git a/trunk/arch/arm/include/asm/pmu.h b/trunk/arch/arm/include/asm/pmu.h index a26170dce02e..4432305f4a2a 100644 --- a/trunk/arch/arm/include/asm/pmu.h +++ b/trunk/arch/arm/include/asm/pmu.h @@ -15,6 +15,15 @@ #include #include +/* + * Types of PMUs that can be accessed directly and require mutual + * exclusion between profiling tools. + */ +enum arm_pmu_type { + ARM_PMU_DEVICE_CPU = 0, + ARM_NUM_PMU_DEVICES, +}; + /* * struct arm_pmu_platdata - ARM PMU platform data * @@ -22,24 +31,54 @@ * interrupt and passed the address of the low level handler, * and can be used to implement any platform specific handling * before or after calling it. - * @runtime_resume: an optional handler which will be called by the - * runtime PM framework following a call to pm_runtime_get(). - * Note that if pm_runtime_get() is called more than once in - * succession this handler will only be called once. - * @runtime_suspend: an optional handler which will be called by the - * runtime PM framework following a call to pm_runtime_put(). - * Note that if pm_runtime_get() is called more than once in - * succession this handler will only be called following the - * final call to pm_runtime_put() that actually disables the - * hardware. + * @enable_irq: an optional handler which will be called after + * request_irq and be used to handle some platform specific + * irq enablement + * @disable_irq: an optional handler which will be called before + * free_irq and be used to handle some platform specific + * irq disablement */ struct arm_pmu_platdata { irqreturn_t (*handle_irq)(int irq, void *dev, irq_handler_t pmu_handler); - int (*runtime_resume)(struct device *dev); - int (*runtime_suspend)(struct device *dev); + void (*enable_irq)(int irq); + void (*disable_irq)(int irq); }; +#ifdef CONFIG_CPU_HAS_PMU + +/** + * reserve_pmu() - reserve the hardware performance counters + * + * Reserve the hardware performance counters in the system for exclusive use. + * Returns 0 on success or -EBUSY if the lock is already held. + */ +extern int +reserve_pmu(enum arm_pmu_type type); + +/** + * release_pmu() - Relinquish control of the performance counters + * + * Release the performance counters and allow someone else to use them. + */ +extern void +release_pmu(enum arm_pmu_type type); + +#else /* CONFIG_CPU_HAS_PMU */ + +#include + +static inline int +reserve_pmu(enum arm_pmu_type type) +{ + return -ENODEV; +} + +static inline void +release_pmu(enum arm_pmu_type type) { } + +#endif /* CONFIG_CPU_HAS_PMU */ + #ifdef CONFIG_HW_PERF_EVENTS /* The events for a given PMU register set. */ @@ -64,6 +103,7 @@ struct pmu_hw_events { struct arm_pmu { struct pmu pmu; + enum arm_pmu_type type; cpumask_t active_irqs; char *name; irqreturn_t (*handle_irq)(int irq_num, void *dev); @@ -78,8 +118,6 @@ struct arm_pmu { void (*start)(void); void (*stop)(void); void (*reset)(void *); - int (*request_irq)(irq_handler_t handler); - void (*free_irq)(void); int (*map_event)(struct perf_event *event); int num_events; atomic_t active_events; @@ -91,9 +129,7 @@ struct arm_pmu { #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) -extern const struct dev_pm_ops armpmu_dev_pm_ops; - -int armpmu_register(struct arm_pmu *armpmu, char *name, int type); +int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type); u64 armpmu_event_update(struct perf_event *event, struct hw_perf_event *hwc, @@ -103,13 +139,6 @@ int armpmu_event_set_period(struct perf_event *event, struct hw_perf_event *hwc, int idx); -int armpmu_map_event(struct perf_event *event, - const unsigned (*event_map)[PERF_COUNT_HW_MAX], - const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX], - u32 raw_event_mask); - #endif /* CONFIG_HW_PERF_EVENTS */ #endif /* __ARM_PMU_H__ */ diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 1c4321430737..7ad2d5cf7008 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -69,7 +69,8 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o -obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o +obj-$(CONFIG_CPU_HAS_PMU) += pmu.o +obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 93971b1a4f0b..ab243b87118d 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -12,15 +12,68 @@ */ #define pr_fmt(fmt) "hw perfevents: " fmt +#include +#include #include +#include +#include #include -#include +#include #include +#include +#include #include #include #include +/* + * ARMv6 supports a maximum of 3 events, starting from index 0. If we add + * another platform that supports more, we need to increase this to be the + * largest of all platforms. + * + * ARMv7 supports up to 32 events: + * cycle counter CCNT + 31 events counters CNT0..30. + * Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters. + */ +#define ARMPMU_MAX_HWEVENTS 32 + +static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); +static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); +static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); + +#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) + +/* Set at runtime when we know what CPU type we are. */ +static struct arm_pmu *cpu_pmu; + +const char *perf_pmu_name(void) +{ + if (!cpu_pmu) + return NULL; + + return cpu_pmu->pmu.name; +} +EXPORT_SYMBOL_GPL(perf_pmu_name); + +int perf_num_counters(void) +{ + int max_events = 0; + + if (cpu_pmu != NULL) + max_events = cpu_pmu->num_events; + + return max_events; +} +EXPORT_SYMBOL_GPL(perf_num_counters); + +#define HW_OP_UNSUPPORTED 0xFFFF + +#define C(_x) \ + PERF_COUNT_HW_CACHE_##_x + +#define CACHE_OP_UNSUPPORTED 0xFFFF + static int armpmu_map_cache_event(const unsigned (*cache_map) [PERF_COUNT_HW_CACHE_MAX] @@ -51,7 +104,7 @@ armpmu_map_cache_event(const unsigned (*cache_map) } static int -armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) +armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config) { int mapping = (*event_map)[config]; return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping; @@ -63,20 +116,19 @@ armpmu_map_raw_event(u32 raw_event_mask, u64 config) return (int)(config & raw_event_mask); } -int -armpmu_map_event(struct perf_event *event, - const unsigned (*event_map)[PERF_COUNT_HW_MAX], - const unsigned (*cache_map) - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX], - u32 raw_event_mask) +static int map_cpu_event(struct perf_event *event, + const unsigned (*event_map)[PERF_COUNT_HW_MAX], + const unsigned (*cache_map) + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX], + u32 raw_event_mask) { u64 config = event->attr.config; switch (event->attr.type) { case PERF_TYPE_HARDWARE: - return armpmu_map_hw_event(event_map, config); + return armpmu_map_event(event_map, config); case PERF_TYPE_HW_CACHE: return armpmu_map_cache_event(cache_map, config); case PERF_TYPE_RAW: @@ -170,6 +222,7 @@ armpmu_stop(struct perf_event *event, int flags) */ if (!(hwc->state & PERF_HES_STOPPED)) { armpmu->disable(hwc, hwc->idx); + barrier(); /* why? */ armpmu_event_update(event, hwc, hwc->idx); hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; } @@ -297,41 +350,99 @@ validate_group(struct perf_event *event) return 0; } -static irqreturn_t armpmu_dispatch_irq(int irq, void *dev) +static irqreturn_t armpmu_platform_irq(int irq, void *dev) { struct arm_pmu *armpmu = (struct arm_pmu *) dev; struct platform_device *plat_device = armpmu->plat_device; struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev); - if (plat && plat->handle_irq) - return plat->handle_irq(irq, dev, armpmu->handle_irq); - else - return armpmu->handle_irq(irq, dev); + return plat->handle_irq(irq, dev, armpmu->handle_irq); } static void armpmu_release_hardware(struct arm_pmu *armpmu) { - armpmu->free_irq(); - pm_runtime_put_sync(&armpmu->plat_device->dev); + int i, irq, irqs; + struct platform_device *pmu_device = armpmu->plat_device; + struct arm_pmu_platdata *plat = + dev_get_platdata(&pmu_device->dev); + + irqs = min(pmu_device->num_resources, num_possible_cpus()); + + for (i = 0; i < irqs; ++i) { + if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs)) + continue; + irq = platform_get_irq(pmu_device, i); + if (irq >= 0) { + if (plat && plat->disable_irq) + plat->disable_irq(irq); + free_irq(irq, armpmu); + } + } + + release_pmu(armpmu->type); } static int armpmu_reserve_hardware(struct arm_pmu *armpmu) { - int err; + struct arm_pmu_platdata *plat; + irq_handler_t handle_irq; + int i, err, irq, irqs; struct platform_device *pmu_device = armpmu->plat_device; if (!pmu_device) return -ENODEV; - pm_runtime_get_sync(&pmu_device->dev); - err = armpmu->request_irq(armpmu_dispatch_irq); + err = reserve_pmu(armpmu->type); if (err) { - armpmu_release_hardware(armpmu); + pr_warning("unable to reserve pmu\n"); return err; } + plat = dev_get_platdata(&pmu_device->dev); + if (plat && plat->handle_irq) + handle_irq = armpmu_platform_irq; + else + handle_irq = armpmu->handle_irq; + + irqs = min(pmu_device->num_resources, num_possible_cpus()); + if (irqs < 1) { + pr_err("no irqs for PMUs defined\n"); + return -ENODEV; + } + + for (i = 0; i < irqs; ++i) { + err = 0; + irq = platform_get_irq(pmu_device, i); + if (irq < 0) + continue; + + /* + * If we have a single PMU interrupt that we can't shift, + * assume that we're running on a uniprocessor machine and + * continue. Otherwise, continue without this interrupt. + */ + if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) { + pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n", + irq, i); + continue; + } + + err = request_irq(irq, handle_irq, + IRQF_DISABLED | IRQF_NOBALANCING, + "arm-pmu", armpmu); + if (err) { + pr_err("unable to request IRQ%d for ARM PMU counters\n", + irq); + armpmu_release_hardware(armpmu); + return err; + } else if (plat && plat->enable_irq) + plat->enable_irq(irq); + + cpumask_set_cpu(i, &armpmu->active_irqs); + } + return 0; } @@ -470,32 +581,6 @@ static void armpmu_disable(struct pmu *pmu) armpmu->stop(); } -#ifdef CONFIG_PM_RUNTIME -static int armpmu_runtime_resume(struct device *dev) -{ - struct arm_pmu_platdata *plat = dev_get_platdata(dev); - - if (plat && plat->runtime_resume) - return plat->runtime_resume(dev); - - return 0; -} - -static int armpmu_runtime_suspend(struct device *dev) -{ - struct arm_pmu_platdata *plat = dev_get_platdata(dev); - - if (plat && plat->runtime_suspend) - return plat->runtime_suspend(dev); - - return 0; -} -#endif - -const struct dev_pm_ops armpmu_dev_pm_ops = { - SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL) -}; - static void __init armpmu_init(struct arm_pmu *armpmu) { atomic_set(&armpmu->active_events, 0); @@ -513,14 +598,174 @@ static void __init armpmu_init(struct arm_pmu *armpmu) }; } -int armpmu_register(struct arm_pmu *armpmu, char *name, int type) +int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) { armpmu_init(armpmu); - pr_info("enabled with %s PMU driver, %d counters available\n", - armpmu->name, armpmu->num_events); return perf_pmu_register(&armpmu->pmu, name, type); } +/* Include the PMU-specific implementations. */ +#include "perf_event_xscale.c" +#include "perf_event_v6.c" +#include "perf_event_v7.c" + +/* + * Ensure the PMU has sane values out of reset. + * This requires SMP to be available, so exists as a separate initcall. + */ +static int __init +cpu_pmu_reset(void) +{ + if (cpu_pmu && cpu_pmu->reset) + return on_each_cpu(cpu_pmu->reset, NULL, 1); + return 0; +} +arch_initcall(cpu_pmu_reset); + +/* + * PMU platform driver and devicetree bindings. + */ +static struct of_device_id armpmu_of_device_ids[] = { + {.compatible = "arm,cortex-a9-pmu"}, + {.compatible = "arm,cortex-a8-pmu"}, + {.compatible = "arm,arm1136-pmu"}, + {.compatible = "arm,arm1176-pmu"}, + {}, +}; + +static struct platform_device_id armpmu_plat_device_ids[] = { + {.name = "arm-pmu"}, + {}, +}; + +static int __devinit armpmu_device_probe(struct platform_device *pdev) +{ + if (!cpu_pmu) + return -ENODEV; + + cpu_pmu->plat_device = pdev; + return 0; +} + +static struct platform_driver armpmu_driver = { + .driver = { + .name = "arm-pmu", + .of_match_table = armpmu_of_device_ids, + }, + .probe = armpmu_device_probe, + .id_table = armpmu_plat_device_ids, +}; + +static int __init register_pmu_driver(void) +{ + return platform_driver_register(&armpmu_driver); +} +device_initcall(register_pmu_driver); + +static struct pmu_hw_events *armpmu_get_cpu_events(void) +{ + return &__get_cpu_var(cpu_hw_events); +} + +static void __init cpu_pmu_init(struct arm_pmu *armpmu) +{ + int cpu; + for_each_possible_cpu(cpu) { + struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu); + events->events = per_cpu(hw_events, cpu); + events->used_mask = per_cpu(used_mask, cpu); + raw_spin_lock_init(&events->pmu_lock); + } + armpmu->get_hw_events = armpmu_get_cpu_events; + armpmu->type = ARM_PMU_DEVICE_CPU; +} + +/* + * PMU hardware loses all context when a CPU goes offline. + * When a CPU is hotplugged back in, since some hardware registers are + * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading + * junk values out of them. + */ +static int __cpuinit pmu_cpu_notify(struct notifier_block *b, + unsigned long action, void *hcpu) +{ + if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) + return NOTIFY_DONE; + + if (cpu_pmu && cpu_pmu->reset) + cpu_pmu->reset(NULL); + + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata pmu_cpu_notifier = { + .notifier_call = pmu_cpu_notify, +}; + +/* + * CPU PMU identification and registration. + */ +static int __init +init_hw_perf_events(void) +{ + unsigned long cpuid = read_cpuid_id(); + unsigned long implementor = (cpuid & 0xFF000000) >> 24; + unsigned long part_number = (cpuid & 0xFFF0); + + /* ARM Ltd CPUs. */ + if (0x41 == implementor) { + switch (part_number) { + case 0xB360: /* ARM1136 */ + case 0xB560: /* ARM1156 */ + case 0xB760: /* ARM1176 */ + cpu_pmu = armv6pmu_init(); + break; + case 0xB020: /* ARM11mpcore */ + cpu_pmu = armv6mpcore_pmu_init(); + break; + case 0xC080: /* Cortex-A8 */ + cpu_pmu = armv7_a8_pmu_init(); + break; + case 0xC090: /* Cortex-A9 */ + cpu_pmu = armv7_a9_pmu_init(); + break; + case 0xC050: /* Cortex-A5 */ + cpu_pmu = armv7_a5_pmu_init(); + break; + case 0xC0F0: /* Cortex-A15 */ + cpu_pmu = armv7_a15_pmu_init(); + break; + case 0xC070: /* Cortex-A7 */ + cpu_pmu = armv7_a7_pmu_init(); + break; + } + /* Intel CPUs [xscale]. */ + } else if (0x69 == implementor) { + part_number = (cpuid >> 13) & 0x7; + switch (part_number) { + case 1: + cpu_pmu = xscale1pmu_init(); + break; + case 2: + cpu_pmu = xscale2pmu_init(); + break; + } + } + + if (cpu_pmu) { + pr_info("enabled with %s PMU driver, %d counters available\n", + cpu_pmu->name, cpu_pmu->num_events); + cpu_pmu_init(cpu_pmu); + register_cpu_notifier(&pmu_cpu_notifier); + armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW); + } else { + pr_info("no hardware support available\n"); + } + + return 0; +} +early_initcall(init_hw_perf_events); + /* * Callchain handling code. */ diff --git a/trunk/arch/arm/kernel/perf_event_cpu.c b/trunk/arch/arm/kernel/perf_event_cpu.c deleted file mode 100644 index 8d7d8d4de9d6..000000000000 --- a/trunk/arch/arm/kernel/perf_event_cpu.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) 2012 ARM Limited - * - * Author: Will Deacon - */ -#define pr_fmt(fmt) "CPU PMU: " fmt - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Set at runtime when we know what CPU type we are. */ -static struct arm_pmu *cpu_pmu; - -static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); -static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); -static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); - -/* - * Despite the names, these two functions are CPU-specific and are used - * by the OProfile/perf code. - */ -const char *perf_pmu_name(void) -{ - if (!cpu_pmu) - return NULL; - - return cpu_pmu->pmu.name; -} -EXPORT_SYMBOL_GPL(perf_pmu_name); - -int perf_num_counters(void) -{ - int max_events = 0; - - if (cpu_pmu != NULL) - max_events = cpu_pmu->num_events; - - return max_events; -} -EXPORT_SYMBOL_GPL(perf_num_counters); - -/* Include the PMU-specific implementations. */ -#include "perf_event_xscale.c" -#include "perf_event_v6.c" -#include "perf_event_v7.c" - -static struct pmu_hw_events *cpu_pmu_get_cpu_events(void) -{ - return &__get_cpu_var(cpu_hw_events); -} - -static void cpu_pmu_free_irq(void) -{ - int i, irq, irqs; - struct platform_device *pmu_device = cpu_pmu->plat_device; - - irqs = min(pmu_device->num_resources, num_possible_cpus()); - - for (i = 0; i < irqs; ++i) { - if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs)) - continue; - irq = platform_get_irq(pmu_device, i); - if (irq >= 0) - free_irq(irq, cpu_pmu); - } -} - -static int cpu_pmu_request_irq(irq_handler_t handler) -{ - int i, err, irq, irqs; - struct platform_device *pmu_device = cpu_pmu->plat_device; - - if (!pmu_device) - return -ENODEV; - - irqs = min(pmu_device->num_resources, num_possible_cpus()); - if (irqs < 1) { - pr_err("no irqs for PMUs defined\n"); - return -ENODEV; - } - - for (i = 0; i < irqs; ++i) { - err = 0; - irq = platform_get_irq(pmu_device, i); - if (irq < 0) - continue; - - /* - * If we have a single PMU interrupt that we can't shift, - * assume that we're running on a uniprocessor machine and - * continue. Otherwise, continue without this interrupt. - */ - if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) { - pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n", - irq, i); - continue; - } - - err = request_irq(irq, handler, IRQF_NOBALANCING, "arm-pmu", - cpu_pmu); - if (err) { - pr_err("unable to request IRQ%d for ARM PMU counters\n", - irq); - return err; - } - - cpumask_set_cpu(i, &cpu_pmu->active_irqs); - } - - return 0; -} - -static void __devinit cpu_pmu_init(struct arm_pmu *cpu_pmu) -{ - int cpu; - for_each_possible_cpu(cpu) { - struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu); - events->events = per_cpu(hw_events, cpu); - events->used_mask = per_cpu(used_mask, cpu); - raw_spin_lock_init(&events->pmu_lock); - } - - cpu_pmu->get_hw_events = cpu_pmu_get_cpu_events; - cpu_pmu->request_irq = cpu_pmu_request_irq; - cpu_pmu->free_irq = cpu_pmu_free_irq; - - /* Ensure the PMU has sane values out of reset. */ - if (cpu_pmu && cpu_pmu->reset) - on_each_cpu(cpu_pmu->reset, NULL, 1); -} - -/* - * PMU hardware loses all context when a CPU goes offline. - * When a CPU is hotplugged back in, since some hardware registers are - * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading - * junk values out of them. - */ -static int __cpuinit cpu_pmu_notify(struct notifier_block *b, - unsigned long action, void *hcpu) -{ - if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING) - return NOTIFY_DONE; - - if (cpu_pmu && cpu_pmu->reset) - cpu_pmu->reset(NULL); - - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata cpu_pmu_hotplug_notifier = { - .notifier_call = cpu_pmu_notify, -}; - -/* - * PMU platform driver and devicetree bindings. - */ -static struct of_device_id __devinitdata cpu_pmu_of_device_ids[] = { - {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init}, - {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init}, - {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init}, - {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init}, - {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init}, - {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init}, - {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init}, - {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init}, - {}, -}; - -static struct platform_device_id __devinitdata cpu_pmu_plat_device_ids[] = { - {.name = "arm-pmu"}, - {}, -}; - -/* - * CPU PMU identification and probing. - */ -static struct arm_pmu *__devinit probe_current_pmu(void) -{ - struct arm_pmu *pmu = NULL; - int cpu = get_cpu(); - unsigned long cpuid = read_cpuid_id(); - unsigned long implementor = (cpuid & 0xFF000000) >> 24; - unsigned long part_number = (cpuid & 0xFFF0); - - pr_info("probing PMU on CPU %d\n", cpu); - - /* ARM Ltd CPUs. */ - if (0x41 == implementor) { - switch (part_number) { - case 0xB360: /* ARM1136 */ - case 0xB560: /* ARM1156 */ - case 0xB760: /* ARM1176 */ - pmu = armv6pmu_init(); - break; - case 0xB020: /* ARM11mpcore */ - pmu = armv6mpcore_pmu_init(); - break; - case 0xC080: /* Cortex-A8 */ - pmu = armv7_a8_pmu_init(); - break; - case 0xC090: /* Cortex-A9 */ - pmu = armv7_a9_pmu_init(); - break; - case 0xC050: /* Cortex-A5 */ - pmu = armv7_a5_pmu_init(); - break; - case 0xC0F0: /* Cortex-A15 */ - pmu = armv7_a15_pmu_init(); - break; - case 0xC070: /* Cortex-A7 */ - pmu = armv7_a7_pmu_init(); - break; - } - /* Intel CPUs [xscale]. */ - } else if (0x69 == implementor) { - part_number = (cpuid >> 13) & 0x7; - switch (part_number) { - case 1: - pmu = xscale1pmu_init(); - break; - case 2: - pmu = xscale2pmu_init(); - break; - } - } - - put_cpu(); - return pmu; -} - -static int __devinit cpu_pmu_device_probe(struct platform_device *pdev) -{ - const struct of_device_id *of_id; - struct arm_pmu *(*init_fn)(void); - struct device_node *node = pdev->dev.of_node; - - if (cpu_pmu) { - pr_info("attempt to register multiple PMU devices!"); - return -ENOSPC; - } - - if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) { - init_fn = of_id->data; - cpu_pmu = init_fn(); - } else { - cpu_pmu = probe_current_pmu(); - } - - if (!cpu_pmu) - return -ENODEV; - - cpu_pmu->plat_device = pdev; - cpu_pmu_init(cpu_pmu); - register_cpu_notifier(&cpu_pmu_hotplug_notifier); - armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW); - - return 0; -} - -static struct platform_driver cpu_pmu_driver = { - .driver = { - .name = "arm-pmu", - .pm = &armpmu_dev_pm_ops, - .of_match_table = cpu_pmu_of_device_ids, - }, - .probe = cpu_pmu_device_probe, - .id_table = cpu_pmu_plat_device_ids, -}; - -static int __init register_pmu_driver(void) -{ - return platform_driver_register(&cpu_pmu_driver); -} -device_initcall(register_pmu_driver); diff --git a/trunk/arch/arm/kernel/perf_event_v6.c b/trunk/arch/arm/kernel/perf_event_v6.c index 6ccc07971745..c90fcb2b6967 100644 --- a/trunk/arch/arm/kernel/perf_event_v6.c +++ b/trunk/arch/arm/kernel/perf_event_v6.c @@ -645,7 +645,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc, static int armv6_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv6_perf_map, + return map_cpu_event(event, &armv6_perf_map, &armv6_perf_cache_map, 0xFF); } @@ -664,7 +664,7 @@ static struct arm_pmu armv6pmu = { .max_period = (1LLU << 32) - 1, }; -static struct arm_pmu *__devinit armv6pmu_init(void) +static struct arm_pmu *__init armv6pmu_init(void) { return &armv6pmu; } @@ -679,7 +679,7 @@ static struct arm_pmu *__devinit armv6pmu_init(void) static int armv6mpcore_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv6mpcore_perf_map, + return map_cpu_event(event, &armv6mpcore_perf_map, &armv6mpcore_perf_cache_map, 0xFF); } @@ -698,17 +698,17 @@ static struct arm_pmu armv6mpcore_pmu = { .max_period = (1LLU << 32) - 1, }; -static struct arm_pmu *__devinit armv6mpcore_pmu_init(void) +static struct arm_pmu *__init armv6mpcore_pmu_init(void) { return &armv6mpcore_pmu; } #else -static struct arm_pmu *__devinit armv6pmu_init(void) +static struct arm_pmu *__init armv6pmu_init(void) { return NULL; } -static struct arm_pmu *__devinit armv6mpcore_pmu_init(void) +static struct arm_pmu *__init armv6mpcore_pmu_init(void) { return NULL; } diff --git a/trunk/arch/arm/kernel/perf_event_v7.c b/trunk/arch/arm/kernel/perf_event_v7.c index bd4b090ebcfd..f04070bd2183 100644 --- a/trunk/arch/arm/kernel/perf_event_v7.c +++ b/trunk/arch/arm/kernel/perf_event_v7.c @@ -1204,31 +1204,31 @@ static void armv7pmu_reset(void *info) static int armv7_a8_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv7_a8_perf_map, + return map_cpu_event(event, &armv7_a8_perf_map, &armv7_a8_perf_cache_map, 0xFF); } static int armv7_a9_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv7_a9_perf_map, + return map_cpu_event(event, &armv7_a9_perf_map, &armv7_a9_perf_cache_map, 0xFF); } static int armv7_a5_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv7_a5_perf_map, + return map_cpu_event(event, &armv7_a5_perf_map, &armv7_a5_perf_cache_map, 0xFF); } static int armv7_a15_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv7_a15_perf_map, + return map_cpu_event(event, &armv7_a15_perf_map, &armv7_a15_perf_cache_map, 0xFF); } static int armv7_a7_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv7_a7_perf_map, + return map_cpu_event(event, &armv7_a7_perf_map, &armv7_a7_perf_cache_map, 0xFF); } @@ -1245,7 +1245,7 @@ static struct arm_pmu armv7pmu = { .max_period = (1LLU << 32) - 1, }; -static u32 __devinit armv7_read_num_pmnc_events(void) +static u32 __init armv7_read_num_pmnc_events(void) { u32 nb_cnt; @@ -1256,7 +1256,7 @@ static u32 __devinit armv7_read_num_pmnc_events(void) return nb_cnt + 1; } -static struct arm_pmu *__devinit armv7_a8_pmu_init(void) +static struct arm_pmu *__init armv7_a8_pmu_init(void) { armv7pmu.name = "ARMv7 Cortex-A8"; armv7pmu.map_event = armv7_a8_map_event; @@ -1264,7 +1264,7 @@ static struct arm_pmu *__devinit armv7_a8_pmu_init(void) return &armv7pmu; } -static struct arm_pmu *__devinit armv7_a9_pmu_init(void) +static struct arm_pmu *__init armv7_a9_pmu_init(void) { armv7pmu.name = "ARMv7 Cortex-A9"; armv7pmu.map_event = armv7_a9_map_event; @@ -1272,7 +1272,7 @@ static struct arm_pmu *__devinit armv7_a9_pmu_init(void) return &armv7pmu; } -static struct arm_pmu *__devinit armv7_a5_pmu_init(void) +static struct arm_pmu *__init armv7_a5_pmu_init(void) { armv7pmu.name = "ARMv7 Cortex-A5"; armv7pmu.map_event = armv7_a5_map_event; @@ -1280,7 +1280,7 @@ static struct arm_pmu *__devinit armv7_a5_pmu_init(void) return &armv7pmu; } -static struct arm_pmu *__devinit armv7_a15_pmu_init(void) +static struct arm_pmu *__init armv7_a15_pmu_init(void) { armv7pmu.name = "ARMv7 Cortex-A15"; armv7pmu.map_event = armv7_a15_map_event; @@ -1289,7 +1289,7 @@ static struct arm_pmu *__devinit armv7_a15_pmu_init(void) return &armv7pmu; } -static struct arm_pmu *__devinit armv7_a7_pmu_init(void) +static struct arm_pmu *__init armv7_a7_pmu_init(void) { armv7pmu.name = "ARMv7 Cortex-A7"; armv7pmu.map_event = armv7_a7_map_event; @@ -1298,27 +1298,27 @@ static struct arm_pmu *__devinit armv7_a7_pmu_init(void) return &armv7pmu; } #else -static struct arm_pmu *__devinit armv7_a8_pmu_init(void) +static struct arm_pmu *__init armv7_a8_pmu_init(void) { return NULL; } -static struct arm_pmu *__devinit armv7_a9_pmu_init(void) +static struct arm_pmu *__init armv7_a9_pmu_init(void) { return NULL; } -static struct arm_pmu *__devinit armv7_a5_pmu_init(void) +static struct arm_pmu *__init armv7_a5_pmu_init(void) { return NULL; } -static struct arm_pmu *__devinit armv7_a15_pmu_init(void) +static struct arm_pmu *__init armv7_a15_pmu_init(void) { return NULL; } -static struct arm_pmu *__devinit armv7_a7_pmu_init(void) +static struct arm_pmu *__init armv7_a7_pmu_init(void) { return NULL; } diff --git a/trunk/arch/arm/kernel/perf_event_xscale.c b/trunk/arch/arm/kernel/perf_event_xscale.c index 426e19f380a2..f759fe0bab63 100644 --- a/trunk/arch/arm/kernel/perf_event_xscale.c +++ b/trunk/arch/arm/kernel/perf_event_xscale.c @@ -430,7 +430,7 @@ xscale1pmu_write_counter(int counter, u32 val) static int xscale_map_event(struct perf_event *event) { - return armpmu_map_event(event, &xscale_perf_map, + return map_cpu_event(event, &xscale_perf_map, &xscale_perf_cache_map, 0xFF); } @@ -449,7 +449,7 @@ static struct arm_pmu xscale1pmu = { .max_period = (1LLU << 32) - 1, }; -static struct arm_pmu *__devinit xscale1pmu_init(void) +static struct arm_pmu *__init xscale1pmu_init(void) { return &xscale1pmu; } @@ -816,17 +816,17 @@ static struct arm_pmu xscale2pmu = { .max_period = (1LLU << 32) - 1, }; -static struct arm_pmu *__devinit xscale2pmu_init(void) +static struct arm_pmu *__init xscale2pmu_init(void) { return &xscale2pmu; } #else -static struct arm_pmu *__devinit xscale1pmu_init(void) +static struct arm_pmu *__init xscale1pmu_init(void) { return NULL; } -static struct arm_pmu *__devinit xscale2pmu_init(void) +static struct arm_pmu *__init xscale2pmu_init(void) { return NULL; } diff --git a/trunk/arch/arm/kernel/pmu.c b/trunk/arch/arm/kernel/pmu.c new file mode 100644 index 000000000000..2334bf8a650a --- /dev/null +++ b/trunk/arch/arm/kernel/pmu.c @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/kernel/pmu.c + * + * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles + * Copyright (C) 2010 ARM Ltd, Will Deacon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include + +/* + * PMU locking to ensure mutual exclusion between different subsystems. + */ +static unsigned long pmu_lock[BITS_TO_LONGS(ARM_NUM_PMU_DEVICES)]; + +int +reserve_pmu(enum arm_pmu_type type) +{ + return test_and_set_bit_lock(type, pmu_lock) ? -EBUSY : 0; +} +EXPORT_SYMBOL_GPL(reserve_pmu); + +void +release_pmu(enum arm_pmu_type type) +{ + clear_bit_unlock(type, pmu_lock); +} +EXPORT_SYMBOL_GPL(release_pmu); diff --git a/trunk/arch/arm/mach-bcmring/arch.c b/trunk/arch/arm/mach-bcmring/arch.c index 76e795323569..45c97b1ee9b1 100644 --- a/trunk/arch/arm/mach-bcmring/arch.c +++ b/trunk/arch/arm/mach-bcmring/arch.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -115,7 +116,7 @@ static struct resource pmu_resource = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .resource = &pmu_resource, .num_resources = 1, }; diff --git a/trunk/arch/arm/mach-imx/clk-imx35.c b/trunk/arch/arm/mach-imx/clk-imx35.c index cebc71d5a5af..c6422fb10bae 100644 --- a/trunk/arch/arm/mach-imx/clk-imx35.c +++ b/trunk/arch/arm/mach-imx/clk-imx35.c @@ -62,8 +62,8 @@ enum mx35_clks { kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate, rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, - wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate, - gpu2d_gate, clk_max + wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate, + clk_max }; static struct clk *clk[clk_max]; @@ -142,9 +142,6 @@ int __init mx35_clocks_init() clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4); - clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6); - clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0); clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2); clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4); @@ -195,7 +192,7 @@ int __init mx35_clocks_init() clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26); clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30); - clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MX35_CCM_CGR3, 0); + clk[csi_gate] = imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3, 0); clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2); clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4); @@ -231,7 +228,6 @@ int __init mx35_clocks_init() clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2"); clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); - clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad"); clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); @@ -259,7 +255,6 @@ int __init mx35_clocks_init() clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc"); clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0"); - clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); clk_prepare_enable(clk[spba_gate]); clk_prepare_enable(clk[gpio1_gate]); diff --git a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c index db70d23f95fa..4bdcaa97bd98 100644 --- a/trunk/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/trunk/arch/arm/mach-imx/clk-imx51-imx53.c @@ -49,7 +49,6 @@ static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; -static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; enum imx5_clks { dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, @@ -83,7 +82,6 @@ enum imx5_clks { ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate, ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, - can_sel, can1_serial_gate, can1_ipg_gate, clk_max }; @@ -423,12 +421,8 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); - clk[can_sel] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2, - mx53_can_sel, ARRAY_SIZE(mx53_can_sel)); - clk[can1_serial_gate] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22); - clk[can1_ipg_gate] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20); - clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8); - clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); + clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "ipg", MXC_CCM_CCGR4, 6); + clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 8); clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); for (i = 0; i < ARRAY_SIZE(clk); i++) @@ -461,10 +455,6 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi"); clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi"); clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi"); - clk_register_clkdev(clk[can1_ipg_gate], "ipg", "53fc8000.can"); - clk_register_clkdev(clk[can1_serial_gate], "per", "53fc8000.can"); - clk_register_clkdev(clk[can2_ipg_gate], "ipg", "53fcc000.can"); - clk_register_clkdev(clk[can2_serial_gate], "per", "53fcc000.can"); /* set SDHC root clock to 200MHZ*/ clk_set_rate(clk[esdhc_a_podf], 200000000); diff --git a/trunk/arch/arm/mach-lpc32xx/irq.c b/trunk/arch/arm/mach-lpc32xx/irq.c index 3c6332753358..5b1cc35e6fba 100644 --- a/trunk/arch/arm/mach-lpc32xx/irq.c +++ b/trunk/arch/arm/mach-lpc32xx/irq.c @@ -283,25 +283,21 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) case IRQ_TYPE_EDGE_RISING: /* Rising edge sensitive */ __lpc32xx_set_irq_type(d->hwirq, 1, 1); - __irq_set_handler_locked(d->hwirq, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: /* Falling edge sensitive */ __lpc32xx_set_irq_type(d->hwirq, 0, 1); - __irq_set_handler_locked(d->hwirq, handle_edge_irq); break; case IRQ_TYPE_LEVEL_LOW: /* Low level sensitive */ __lpc32xx_set_irq_type(d->hwirq, 0, 0); - __irq_set_handler_locked(d->hwirq, handle_level_irq); break; case IRQ_TYPE_LEVEL_HIGH: /* High level sensitive */ __lpc32xx_set_irq_type(d->hwirq, 1, 0); - __irq_set_handler_locked(d->hwirq, handle_level_irq); break; /* Other modes are not supported */ @@ -309,6 +305,9 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) return -EINVAL; } + /* Ok to use the level handler for all types */ + irq_set_handler(d->hwirq, handle_level_irq); + return 0; } diff --git a/trunk/arch/arm/mach-lpc32xx/phy3250.c b/trunk/arch/arm/mach-lpc32xx/phy3250.c index 8f2a2f8712d7..b07dcc90829d 100644 --- a/trunk/arch/arm/mach-lpc32xx/phy3250.c +++ b/trunk/arch/arm/mach-lpc32xx/phy3250.c @@ -37,8 +37,6 @@ #include #include #include -#include -#include #include #include @@ -225,14 +223,6 @@ static struct mmci_platform_data lpc32xx_mmci_data = { * gather, and the MMCI driver doesn't do it this way */ }; -static struct lpc32xx_slc_platform_data lpc32xx_slc_data = { - .dma_filter = pl08x_filter_id, -}; - -static struct lpc32xx_mlc_platform_data lpc32xx_mlc_data = { - .dma_filter = pl08x_filter_id, -}; - static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data), OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data), @@ -240,10 +230,6 @@ static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd), OF_DEV_AUXDATA("arm,pl18x", 0x20098000, "20098000.sd", &lpc32xx_mmci_data), - OF_DEV_AUXDATA("nxp,lpc3220-slc", 0x20020000, "20020000.flash", - &lpc32xx_slc_data), - OF_DEV_AUXDATA("nxp,lpc3220-mlc", 0x200a8000, "200a8000.flash", - &lpc32xx_mlc_data), { } }; @@ -267,6 +253,12 @@ static void __init lpc3250_machine_init(void) of_platform_populate(NULL, of_default_bus_match_table, lpc32xx_auxdata_lookup, NULL); + + /* Register GPIOs used on this board */ + if (gpio_request(MMC_PWR_ENABLE_GPIO, "mmc_power_en")) + pr_err("Error requesting gpio %u", MMC_PWR_ENABLE_GPIO); + else if (gpio_direction_output(MMC_PWR_ENABLE_GPIO, 1)) + pr_err("Error setting gpio %u to output", MMC_PWR_ENABLE_GPIO); } static char const *lpc32xx_dt_compat[] __initdata = { diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c index 02b9478b786f..c00c68961bb8 100644 --- a/trunk/arch/arm/mach-omap2/devices.c +++ b/trunk/arch/arm/mach-omap2/devices.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "iomap.h" #include @@ -447,7 +448,7 @@ static struct resource omap3_pmu_resource = { static struct platform_device omap_pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = 1, }; diff --git a/trunk/arch/arm/mach-pxa/devices.c b/trunk/arch/arm/mach-pxa/devices.c index c1f3b1279d97..166eee5b8a70 100644 --- a/trunk/arch/arm/mach-pxa/devices.c +++ b/trunk/arch/arm/mach-pxa/devices.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -41,7 +42,7 @@ static struct resource pxa_resource_pmu = { struct platform_device pxa_device_pmu = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .resource = &pxa_resource_pmu, .num_resources = 1, }; diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index d7a6e9cebba4..baf382c5e776 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -296,7 +297,7 @@ static struct resource pmu_resources[] = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(pmu_resources), .resource = pmu_resources, }; diff --git a/trunk/arch/arm/mach-realview/realview_pb1176.c b/trunk/arch/arm/mach-realview/realview_pb1176.c index 361f898884c8..b1d7cafa1a6d 100644 --- a/trunk/arch/arm/mach-realview/realview_pb1176.c +++ b/trunk/arch/arm/mach-realview/realview_pb1176.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -279,7 +280,7 @@ static struct resource pmu_resource = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = 1, .resource = &pmu_resource, }; diff --git a/trunk/arch/arm/mach-realview/realview_pb11mp.c b/trunk/arch/arm/mach-realview/realview_pb11mp.c index c56bc8d4d11b..a98c536e3327 100644 --- a/trunk/arch/arm/mach-realview/realview_pb11mp.c +++ b/trunk/arch/arm/mach-realview/realview_pb11mp.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -262,7 +263,7 @@ static struct resource pmu_resources[] = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(pmu_resources), .resource = pmu_resources, }; diff --git a/trunk/arch/arm/mach-realview/realview_pba8.c b/trunk/arch/arm/mach-realview/realview_pba8.c index 040937582453..59650174e6ed 100644 --- a/trunk/arch/arm/mach-realview/realview_pba8.c +++ b/trunk/arch/arm/mach-realview/realview_pba8.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -240,7 +241,7 @@ static struct resource pmu_resource = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = 1, .resource = &pmu_resource, }; diff --git a/trunk/arch/arm/mach-realview/realview_pbx.c b/trunk/arch/arm/mach-realview/realview_pbx.c index 97885dc11e8c..3f2f605624e9 100644 --- a/trunk/arch/arm/mach-realview/realview_pbx.c +++ b/trunk/arch/arm/mach-realview/realview_pbx.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -279,7 +280,7 @@ static struct resource pmu_resources[] = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(pmu_resources), .resource = pmu_resources, }; diff --git a/trunk/arch/arm/mach-shmobile/board-kzm9g.c b/trunk/arch/arm/mach-shmobile/board-kzm9g.c index fd21fb6f9953..53b7ea92c32c 100644 --- a/trunk/arch/arm/mach-shmobile/board-kzm9g.c +++ b/trunk/arch/arm/mach-shmobile/board-kzm9g.c @@ -763,13 +763,6 @@ static void __init kzm_init(void) platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); } -static void kzm9g_restart(char mode, const char *cmd) -{ -#define RESCNT2 0xe6188020 - /* Do soft power on reset */ - writel((1 << 31), RESCNT2); -} - static const char *kzm9g_boards_compat_dt[] __initdata = { "renesas,kzm9g", NULL, @@ -784,6 +777,5 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g") .init_machine = kzm_init, .init_late = shmobile_init_late, .timer = &shmobile_timer, - .restart = kzm9g_restart, .dt_compat = kzm9g_boards_compat_dt, MACHINE_END diff --git a/trunk/arch/arm/mach-shmobile/clock-r8a7779.c b/trunk/arch/arm/mach-shmobile/clock-r8a7779.c index 3cafb6ab5e9a..339c62c824d5 100644 --- a/trunk/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/trunk/arch/arm/mach-shmobile/clock-r8a7779.c @@ -86,16 +86,11 @@ static struct clk div4_clks[DIV4_NR] = { 0x0300, CLK_ENABLE_ON_INIT), }; -enum { MSTP323, MSTP322, MSTP321, MSTP320, - MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, +enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, MSTP016, MSTP015, MSTP014, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { - [MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 23, 0), /* SDHI0 */ - [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */ - [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */ - [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */ [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), /* SCIF0 */ [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), /* SCIF1 */ [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), /* SCIF2 */ @@ -154,10 +149,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */ - CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */ - CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ - CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ - CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ }; void __init r8a7779_clock_init(void) diff --git a/trunk/arch/arm/mach-shmobile/setup-emev2.c b/trunk/arch/arm/mach-shmobile/setup-emev2.c index 61446f30e397..dae9aa68bb09 100644 --- a/trunk/arch/arm/mach-shmobile/setup-emev2.c +++ b/trunk/arch/arm/mach-shmobile/setup-emev2.c @@ -356,26 +356,6 @@ static struct platform_device gio4_device = { }, }; -static struct resource pmu_resources[] = { - [0] = { - .start = 152, - .end = 152, - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = 153, - .end = 153, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device pmu_device = { - .name = "arm-pmu", - .id = -1, - .num_resources = ARRAY_SIZE(pmu_resources), - .resource = pmu_resources, -}; - static struct platform_device *emev2_early_devices[] __initdata = { &uart0_device, &uart1_device, @@ -390,7 +370,6 @@ static struct platform_device *emev2_late_devices[] __initdata = { &gio2_device, &gio3_device, &gio4_device, - &pmu_device, }; void __init emev2_add_standard_devices(void) diff --git a/trunk/arch/arm/mach-shmobile/setup-sh73a0.c b/trunk/arch/arm/mach-shmobile/setup-sh73a0.c index 38ed2ddd3265..d230af656fc9 100644 --- a/trunk/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/trunk/arch/arm/mach-shmobile/setup-sh73a0.c @@ -734,26 +734,6 @@ static struct platform_device mpdma0_device = { }, }; -static struct resource pmu_resources[] = { - [0] = { - .start = gic_spi(55), - .end = gic_spi(55), - .flags = IORESOURCE_IRQ, - }, - [1] = { - .start = gic_spi(56), - .end = gic_spi(56), - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device pmu_device = { - .name = "arm-pmu", - .id = -1, - .num_resources = ARRAY_SIZE(pmu_resources), - .resource = pmu_resources, -}; - static struct platform_device *sh73a0_early_devices[] __initdata = { &scif0_device, &scif1_device, @@ -777,7 +757,6 @@ static struct platform_device *sh73a0_late_devices[] __initdata = { &i2c4_device, &dma0_device, &mpdma0_device, - &pmu_device, }; #define SRCR2 0xe61580b0 diff --git a/trunk/arch/arm/mach-tegra/board-dt-tegra20.c b/trunk/arch/arm/mach-tegra/board-dt-tegra20.c index c0999633a9ab..b4e7cc14713c 100644 --- a/trunk/arch/arm/mach-tegra/board-dt-tegra20.c +++ b/trunk/arch/arm/mach-tegra/board-dt-tegra20.c @@ -71,6 +71,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { /* name parent rate enabled */ + { "uarta", "pll_p", 216000000, true }, { "uartd", "pll_p", 216000000, true }, { "usbd", "clk_m", 12000000, false }, { "usb2", "clk_m", 12000000, false }, diff --git a/trunk/arch/arm/mach-tegra/devices.c b/trunk/arch/arm/mach-tegra/devices.c index 61e9603744a7..c70e65ffa36b 100644 --- a/trunk/arch/arm/mach-tegra/devices.c +++ b/trunk/arch/arm/mach-tegra/devices.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -515,7 +516,7 @@ static struct resource tegra_pmu_resources[] = { struct platform_device tegra_pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(tegra_pmu_resources), .resource = tegra_pmu_resources, }; diff --git a/trunk/arch/arm/mach-ux500/cache-l2x0.c b/trunk/arch/arm/mach-ux500/cache-l2x0.c index 75d5b512a3d5..dc12394295d5 100644 --- a/trunk/arch/arm/mach-ux500/cache-l2x0.c +++ b/trunk/arch/arm/mach-ux500/cache-l2x0.c @@ -38,7 +38,7 @@ static int __init ux500_l2x0_init(void) { u32 aux_val = 0x3e000000; - if (cpu_is_u8500_family() || cpu_is_ux540_family()) + if (cpu_is_u8500_family()) l2x0_base = __io_address(U8500_L2CC_BASE); else ux500_unknown_soc(); diff --git a/trunk/arch/arm/mach-ux500/clock.c b/trunk/arch/arm/mach-ux500/clock.c index bc5a516a5865..8d73b066a18d 100644 --- a/trunk/arch/arm/mach-ux500/clock.c +++ b/trunk/arch/arm/mach-ux500/clock.c @@ -149,7 +149,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) unsigned long mturate; unsigned long retclk; - if (cpu_is_u8500_family() || cpu_is_ux540_family()) + if (cpu_is_u8500_family()) addr = __io_address(U8500_PRCMU_BASE); else ux500_unknown_soc(); diff --git a/trunk/arch/arm/mach-ux500/cpu-db8500.c b/trunk/arch/arm/mach-ux500/cpu-db8500.c index 8169f2c72d6c..db3c52d56ca4 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db8500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db8500.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -79,7 +80,7 @@ void __init u8500_map_io(void) iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc)); - if (cpu_is_ux540_family()) + if (cpu_is_u9540()) iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc)); else iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); @@ -121,7 +122,7 @@ struct arm_pmu_platdata db8500_pmu_platdata = { static struct platform_device db8500_pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(db8500_pmu_resources), .resource = db8500_pmu_resources, .dev.platform_data = &db8500_pmu_platdata, diff --git a/trunk/arch/arm/mach-ux500/cpu.c b/trunk/arch/arm/mach-ux500/cpu.c index 4b0a9b300312..e2360e7c770d 100644 --- a/trunk/arch/arm/mach-ux500/cpu.c +++ b/trunk/arch/arm/mach-ux500/cpu.c @@ -51,7 +51,7 @@ void __init ux500_init_irq(void) void __iomem *dist_base; void __iomem *cpu_base; - if (cpu_is_u8500_family() || cpu_is_ux540_family()) { + if (cpu_is_u8500_family()) { dist_base = __io_address(U8500_GIC_DIST_BASE); cpu_base = __io_address(U8500_GIC_CPU_BASE); } else diff --git a/trunk/arch/arm/mach-ux500/include/mach/id.h b/trunk/arch/arm/mach-ux500/include/mach/id.h index 9c42642ab168..c6e2db9e9e51 100644 --- a/trunk/arch/arm/mach-ux500/include/mach/id.h +++ b/trunk/arch/arm/mach-ux500/include/mach/id.h @@ -41,29 +41,43 @@ static inline bool __attribute_const__ cpu_is_u8500(void) return dbx500_partnumber() == 0x8500; } -static inline bool __attribute_const__ cpu_is_u8520(void) +static inline bool __attribute_const__ cpu_is_u9540(void) { - return dbx500_partnumber() == 0x8520; + return dbx500_partnumber() == 0x9540; } static inline bool cpu_is_u8500_family(void) { - return cpu_is_u8500() || cpu_is_u8520(); + return cpu_is_u8500() || cpu_is_u9540(); } -static inline bool __attribute_const__ cpu_is_u9540(void) +static inline bool __attribute_const__ cpu_is_u5500(void) { - return dbx500_partnumber() == 0x9540; + return dbx500_partnumber() == 0x5500; +} + +/* + * 5500 revisions + */ + +static inline bool __attribute_const__ cpu_is_u5500v1(void) +{ + return cpu_is_u5500() && (dbx500_revision() & 0xf0) == 0xA0; +} + +static inline bool __attribute_const__ cpu_is_u5500v2(void) +{ + return (dbx500_id.revision & 0xf0) == 0xB0; } -static inline bool __attribute_const__ cpu_is_u8540(void) +static inline bool __attribute_const__ cpu_is_u5500v20(void) { - return dbx500_partnumber() == 0x8540; + return cpu_is_u5500() && ((dbx500_revision() & 0xf0) == 0xB0); } -static inline bool cpu_is_ux540_family(void) +static inline bool __attribute_const__ cpu_is_u5500v21(void) { - return cpu_is_u9540() || cpu_is_u8540(); + return cpu_is_u5500() && (dbx500_revision() == 0xB1); } /* @@ -105,14 +119,14 @@ static inline bool cpu_is_u8500v21(void) return cpu_is_u8500() && (dbx500_revision() == 0xB1); } -static inline bool cpu_is_u8500v22(void) -{ - return cpu_is_u8500() && (dbx500_revision() == 0xB2); -} - static inline bool cpu_is_u8500v20_or_later(void) { - return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11()); + /* + * U9540 has so much in common with U8500 that is is considered a + * U8500 variant. + */ + return cpu_is_u9540() || + (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11()); } static inline bool ux500_is_svp(void) diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index a5dda68444db..da1d5ad5bd45 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -48,7 +48,7 @@ static void write_pen_release(int val) static void __iomem *scu_base_addr(void) { - if (cpu_is_u8500_family() || cpu_is_ux540_family()) + if (cpu_is_u8500_family()) return __io_address(U8500_SCU_BASE); else ux500_unknown_soc(); @@ -118,7 +118,7 @@ static void __init wakeup_secondary(void) { void __iomem *backupram; - if (cpu_is_u8500_family() || cpu_is_ux540_family()) + if (cpu_is_u8500_family()) backupram = __io_address(U8500_BACKUPRAM0_BASE); else ux500_unknown_soc(); diff --git a/trunk/arch/arm/mach-ux500/timer.c b/trunk/arch/arm/mach-ux500/timer.c index 6f39731951b0..66e7f00884ab 100644 --- a/trunk/arch/arm/mach-ux500/timer.c +++ b/trunk/arch/arm/mach-ux500/timer.c @@ -54,7 +54,7 @@ static void __init ux500_timer_init(void) void __iomem *tmp_base; struct device_node *np; - if (cpu_is_u8500_family() || cpu_is_ux540_family()) { + if (cpu_is_u8500_family()) { mtu_timer_base = __io_address(U8500_MTU0_BASE); prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); } else { diff --git a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c index e4073a60a864..61c492403b05 100644 --- a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -143,7 +144,7 @@ static struct resource pmu_resources[] = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(pmu_resources), .resource = pmu_resources, }; diff --git a/trunk/arch/arm/plat-iop/pmu.c b/trunk/arch/arm/plat-iop/pmu.c index ad9f9744a82d..a2024b8685a1 100644 --- a/trunk/arch/arm/plat-iop/pmu.c +++ b/trunk/arch/arm/plat-iop/pmu.c @@ -9,6 +9,7 @@ */ #include +#include #include static struct resource pmu_resource = { @@ -25,7 +26,7 @@ static struct resource pmu_resource = { static struct platform_device pmu_device = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .resource = &pmu_resource, .num_resources = 1, }; diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx3.h index f79f78a1c0ed..d8b65b51f2a9 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -512,16 +512,12 @@ enum iomux_pins { #define MX31_PIN_CSPI3_SPI_RDY__CTS3 IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_ALT1) #define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC) #define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RTS1__SFS IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_ALT2) #define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_TXD1__SCK IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_ALT2) #define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_RXD1__STXDA IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_ALT2) #define MX31_PIN_DCD_DCE1__DCD_DCE1 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_FUNC) #define MX31_PIN_RI_DCE1__RI_DCE1 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_FUNC) #define MX31_PIN_DSR_DCE1__DSR_DCE1 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_FUNC) #define MX31_PIN_DTR_DCE1__DTR_DCE1 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_FUNC) -#define MX31_PIN_DTR_DCE1__SRXDA IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_ALT2) #define MX31_PIN_CTS2__CTS2 IOMUX_MODE(MX31_PIN_CTS2, IOMUX_CONFIG_FUNC) #define MX31_PIN_RTS2__RTS2 IOMUX_MODE(MX31_PIN_RTS2, IOMUX_CONFIG_FUNC) #define MX31_PIN_TXD2__TXD2 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_FUNC) @@ -725,7 +721,6 @@ enum iomux_pins { #define MX31_PIN_KEY_ROW2_KEY_ROW2 IOMUX_MODE(MX31_PIN_KEY_ROW2, IOMUX_CONFIG_FUNC) #define MX31_PIN_KEY_ROW3_KEY_ROW3 IOMUX_MODE(MX31_PIN_KEY_ROW3, IOMUX_CONFIG_FUNC) #define MX31_PIN_KEY_ROW4_KEY_ROW4 IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_FUNC) -#define MX31_PIN_KEY_ROW4_GPIO IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO) #define MX31_PIN_KEY_ROW5_KEY_ROW5 IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_FUNC) #define MX31_PIN_KEY_ROW6_KEY_ROW6 IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_FUNC) #define MX31_PIN_KEY_ROW7_KEY_ROW7 IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_FUNC) diff --git a/trunk/arch/arm/plat-mxc/ssi-fiq.S b/trunk/arch/arm/plat-mxc/ssi-fiq.S index a8b93c5f29b5..8397a2dd19f2 100644 --- a/trunk/arch/arm/plat-mxc/ssi-fiq.S +++ b/trunk/arch/arm/plat-mxc/ssi-fiq.S @@ -34,98 +34,91 @@ .global imx_ssi_fiq_rx_buffer .global imx_ssi_fiq_tx_buffer -/* - * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol - * using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to - * mark the function body so that it can be copied to the FIQ vector in - * the vectors page. imx_ssi_fiq_start should only be called as the result - * of an FIQ: calling it directly will not work. - */ imx_ssi_fiq_start: - ldr r12, .L_imx_ssi_fiq_base + ldr r12, imx_ssi_fiq_base /* TX */ - ldr r13, .L_imx_ssi_fiq_tx_buffer + ldr r11, imx_ssi_fiq_tx_buffer /* shall we send? */ - ldr r11, [r12, #SSI_SIER] - tst r11, #SSI_SIER_TFE0_EN + ldr r13, [r12, #SSI_SIER] + tst r13, #SSI_SIER_TFE0_EN beq 1f /* TX FIFO empty? */ - ldr r11, [r12, #SSI_SISR] - tst r11, #SSI_SISR_TFE0 + ldr r13, [r12, #SSI_SISR] + tst r13, #SSI_SISR_TFE0 beq 1f mov r10, #0x10000 sub r10, #1 and r10, r10, r8 /* r10: current buffer offset */ - add r13, r13, r10 + add r11, r11, r10 - ldrh r11, [r13] - strh r11, [r12, #SSI_STX0] + ldrh r13, [r11] + strh r13, [r12, #SSI_STX0] - ldrh r11, [r13, #2] - strh r11, [r12, #SSI_STX0] + ldrh r13, [r11, #2] + strh r13, [r12, #SSI_STX0] - ldrh r11, [r13, #4] - strh r11, [r12, #SSI_STX0] + ldrh r13, [r11, #4] + strh r13, [r12, #SSI_STX0] - ldrh r11, [r13, #6] - strh r11, [r12, #SSI_STX0] + ldrh r13, [r11, #6] + strh r13, [r12, #SSI_STX0] add r10, #8 - lsr r11, r8, #16 /* r11: buffer size */ - cmp r10, r11 - lslgt r8, r11, #16 + lsr r13, r8, #16 /* r13: buffer size */ + cmp r10, r13 + lslgt r8, r13, #16 addle r8, #8 1: /* RX */ /* shall we receive? */ - ldr r11, [r12, #SSI_SIER] - tst r11, #SSI_SIER_RFF0_EN + ldr r13, [r12, #SSI_SIER] + tst r13, #SSI_SIER_RFF0_EN beq 1f /* RX FIFO full? */ - ldr r11, [r12, #SSI_SISR] - tst r11, #SSI_SISR_RFF0 + ldr r13, [r12, #SSI_SISR] + tst r13, #SSI_SISR_RFF0 beq 1f - ldr r13, .L_imx_ssi_fiq_rx_buffer + ldr r11, imx_ssi_fiq_rx_buffer mov r10, #0x10000 sub r10, #1 and r10, r10, r9 /* r10: current buffer offset */ - add r13, r13, r10 + add r11, r11, r10 - ldr r11, [r12, #SSI_SACNT] - tst r11, #SSI_SACNT_AC97EN + ldr r13, [r12, #SSI_SACNT] + tst r13, #SSI_SACNT_AC97EN - ldr r11, [r12, #SSI_SRX0] - strh r11, [r13] + ldr r13, [r12, #SSI_SRX0] + strh r13, [r11] - ldr r11, [r12, #SSI_SRX0] - strh r11, [r13, #2] + ldr r13, [r12, #SSI_SRX0] + strh r13, [r11, #2] /* dummy read to skip slot 12 */ - ldrne r11, [r12, #SSI_SRX0] + ldrne r13, [r12, #SSI_SRX0] - ldr r11, [r12, #SSI_SRX0] - strh r11, [r13, #4] + ldr r13, [r12, #SSI_SRX0] + strh r13, [r11, #4] - ldr r11, [r12, #SSI_SRX0] - strh r11, [r13, #6] + ldr r13, [r12, #SSI_SRX0] + strh r13, [r11, #6] /* dummy read to skip slot 12 */ - ldrne r11, [r12, #SSI_SRX0] + ldrne r13, [r12, #SSI_SRX0] add r10, #8 - lsr r11, r9, #16 /* r11: buffer size */ - cmp r10, r11 - lslgt r9, r11, #16 + lsr r13, r9, #16 /* r13: buffer size */ + cmp r10, r13 + lslgt r9, r13, #16 addle r9, #8 1: @@ -133,15 +126,11 @@ imx_ssi_fiq_start: subs pc, lr, #4 .align -.L_imx_ssi_fiq_base: imx_ssi_fiq_base: .word 0x0 -.L_imx_ssi_fiq_rx_buffer: imx_ssi_fiq_rx_buffer: .word 0x0 -.L_imx_ssi_fiq_tx_buffer: imx_ssi_fiq_tx_buffer: .word 0x0 -.L_imx_ssi_fiq_end: imx_ssi_fiq_end: diff --git a/trunk/arch/arm/plat-samsung/devs.c b/trunk/arch/arm/plat-samsung/devs.c index 6ff45d53362c..fc49f3dabd76 100644 --- a/trunk/arch/arm/plat-samsung/devs.c +++ b/trunk/arch/arm/plat-samsung/devs.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -1131,7 +1132,7 @@ static struct resource s5p_pmu_resource[] = { static struct platform_device s5p_device_pmu = { .name = "arm-pmu", - .id = -1, + .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(s5p_pmu_resource), .resource = s5p_pmu_resource, };