Merge tag 'tegra-for-3.7-cpu-hotplug' of git://git.kernel.org/pub/scm/linux/kernel...
authorOlof Johansson <olof@lixom.net>
Mon, 17 Sep 2012 01:33:23 +0000 (18:33 -0700)
committerOlof Johansson <olof@lixom.net>
Mon, 17 Sep 2012 01:33:23 +0000 (18:33 -0700)
From Stephen Warren:

ARM: tegra: implement CPU hotplug

This branch implements CPU hot-plugging support for both Tegra20 and
Tegra30. Portions of the implementation are contained in the clock
driver, hence this branch is based on the common clock conversion in
order to avoid duplicating work.

By Joseph Lo
via Stephen Warren
* tag 'tegra-for-3.7-cpu-hotplug' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
  ARM: tegra20: add CPU hotplug support
  ARM: tegra30: add CPU hotplug support
  ARM: tegra: clean up the common assembly macros into sleep.h
  ARM: tegra: replace the CPU CAR access code by tegra_cpu_car_ops
  ARM: tegra: introduce tegra_cpu_car_ops structures

43 files changed:
Documentation/devicetree/bindings/arm/pmu.txt
MAINTAINERS
arch/arm/Kconfig
arch/arm/configs/kzm9d_defconfig
arch/arm/configs/kzm9g_defconfig
arch/arm/include/asm/perf_event.h
arch/arm/include/asm/pmu.h
arch/arm/kernel/Makefile
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_cpu.c [new file with mode: 0644]
arch/arm/kernel/perf_event_v6.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/perf_event_xscale.c
arch/arm/kernel/pmu.c [deleted file]
arch/arm/mach-bcmring/arch.c
arch/arm/mach-imx/clk-imx35.c
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-lpc32xx/irq.c
arch/arm/mach-lpc32xx/phy3250.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/mach-shmobile/clock-r8a7779.c
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-tegra/devices.c
arch/arm/mach-ux500/cache-l2x0.c
arch/arm/mach-ux500/clock.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/include/mach/id.h
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-ux500/timer.c
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/plat-iop/pmu.c
arch/arm/plat-mxc/include/mach/iomux-mx3.h
arch/arm/plat-mxc/ssi-fiq.S
arch/arm/plat-samsung/devs.c

index 1c044eb320cc4fb6ed4f269ebaaa763794c485e7..343781b9f246773ce880f9427623ebbd12202f32 100644 (file)
@@ -7,8 +7,12 @@ 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.
index fdc0119963e70f12c4f9e1eae3a613447e7d8781..437a7dd368435bc0a6c159215eb2fca2eab2f638 100644 (file)
@@ -595,7 +595,6 @@ M:  Will Deacon <will.deacon@arm.com>
 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
index b23213d2764ee42c74a465fe59aa24f2baf71f6d..60355f1cc4b4d5f19333bede2dd36914b2683470 100644 (file)
@@ -1180,12 +1180,6 @@ 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
@@ -1758,7 +1752,7 @@ config HIGHPTE
 
 config HW_PERF_EVENTS
        bool "Enable hardware performance counter support for perf events"
-       depends on PERF_EVENTS && CPU_HAS_PMU
+       depends on PERF_EVENTS
        default y
        help
          Enable hardware performance counter support for perf events. If
index 26146ffea1a50d2860ffcc2b647da7ea8c8a3bcb..8c49df66cac3401d73d71fd41ad573259b3de036 100644 (file)
@@ -8,6 +8,7 @@ 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
index 2388c86106277dccb08e0c24820a6e4a0a733630..5d0c66708960c7d4f2cf4d20dc31fc205f0c6c88 100644 (file)
@@ -14,6 +14,7 @@ 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
index e074948d81431cec24598e088a696202d52f1615..625cd621a436db1d24d1d9ee53dffe0fe0ff70d8 100644 (file)
 #ifndef __ARM_PERF_EVENT_H__
 #define __ARM_PERF_EVENT_H__
 
-/* Nothing to see here... */
+/*
+ * 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
 
 #endif /* __ARM_PERF_EVENT_H__ */
index 4432305f4a2aa1b2e89bf69beaf032929816f78d..a26170dce02e4b735ddab00a5ead32883e07b1b2 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/perf_event.h>
 
-/*
- * 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
  *
@@ -31,54 +22,24 @@ enum arm_pmu_type {
  *     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.
- * @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
+ * @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.
  */
 struct arm_pmu_platdata {
        irqreturn_t (*handle_irq)(int irq, void *dev,
                                  irq_handler_t pmu_handler);
-       void (*enable_irq)(int irq);
-       void (*disable_irq)(int irq);
+       int (*runtime_resume)(struct device *dev);
+       int (*runtime_suspend)(struct device *dev);
 };
 
-#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 <linux/err.h>
-
-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. */
@@ -103,7 +64,6 @@ 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);
@@ -118,6 +78,8 @@ 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;
@@ -129,7 +91,9 @@ struct arm_pmu {
 
 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
 
-int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
+extern const struct dev_pm_ops armpmu_dev_pm_ops;
+
+int armpmu_register(struct arm_pmu *armpmu, char *name, int type);
 
 u64 armpmu_event_update(struct perf_event *event,
                        struct hw_perf_event *hwc,
@@ -139,6 +103,13 @@ 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__ */
index 7ad2d5cf700825892278c55920ded6f77e60558e..1c43214307376718114ea4409a48fb01a9ac6a08 100644 (file)
@@ -69,8 +69,7 @@ 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_CPU_HAS_PMU)      += pmu.o
-obj-$(CONFIG_HW_PERF_EVENTS)   += perf_event.o
+obj-$(CONFIG_HW_PERF_EVENTS)   += perf_event.o perf_event_cpu.o
 AFLAGS_iwmmxt.o                        := -Wa,-mcpu=iwmmxt
 obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
 
index ab243b87118da54628c25b0069ecc52cc0d2f717..93971b1a4f0bb0d38eebd573f8618e994273b079 100644 (file)
  */
 #define pr_fmt(fmt) "hw perfevents: " fmt
 
-#include <linux/bitmap.h>
-#include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/perf_event.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
 #include <linux/uaccess.h>
 
-#include <asm/cputype.h>
-#include <asm/irq.h>
 #include <asm/irq_regs.h>
 #include <asm/pmu.h>
 #include <asm/stacktrace.h>
 
-/*
- * 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]
@@ -104,7 +51,7 @@ armpmu_map_cache_event(const unsigned (*cache_map)
 }
 
 static int
-armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
+armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
 {
        int mapping = (*event_map)[config];
        return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
@@ -116,19 +63,20 @@ armpmu_map_raw_event(u32 raw_event_mask, u64 config)
        return (int)(config & 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)
+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)
 {
        u64 config = event->attr.config;
 
        switch (event->attr.type) {
        case PERF_TYPE_HARDWARE:
-               return armpmu_map_event(event_map, config);
+               return armpmu_map_hw_event(event_map, config);
        case PERF_TYPE_HW_CACHE:
                return armpmu_map_cache_event(cache_map, config);
        case PERF_TYPE_RAW:
@@ -222,7 +170,6 @@ 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;
        }
@@ -350,99 +297,41 @@ validate_group(struct perf_event *event)
        return 0;
 }
 
-static irqreturn_t armpmu_platform_irq(int irq, void *dev)
+static irqreturn_t armpmu_dispatch_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);
 
-       return plat->handle_irq(irq, dev, armpmu->handle_irq);
+       if (plat && plat->handle_irq)
+               return plat->handle_irq(irq, dev, armpmu->handle_irq);
+       else
+               return armpmu->handle_irq(irq, dev);
 }
 
 static void
 armpmu_release_hardware(struct arm_pmu *armpmu)
 {
-       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);
+       armpmu->free_irq();
+       pm_runtime_put_sync(&armpmu->plat_device->dev);
 }
 
 static int
 armpmu_reserve_hardware(struct arm_pmu *armpmu)
 {
-       struct arm_pmu_platdata *plat;
-       irq_handler_t handle_irq;
-       int i, err, irq, irqs;
+       int err;
        struct platform_device *pmu_device = armpmu->plat_device;
 
        if (!pmu_device)
                return -ENODEV;
 
-       err = reserve_pmu(armpmu->type);
+       pm_runtime_get_sync(&pmu_device->dev);
+       err = armpmu->request_irq(armpmu_dispatch_irq);
        if (err) {
-               pr_warning("unable to reserve pmu\n");
+               armpmu_release_hardware(armpmu);
                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;
 }
 
@@ -581,6 +470,32 @@ 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);
@@ -598,174 +513,14 @@ static void __init armpmu_init(struct arm_pmu *armpmu)
        };
 }
 
-int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type)
+int 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/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
new file mode 100644 (file)
index 0000000..8d7d8d4
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * 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 <will.deacon@arm.com>
+ */
+#define pr_fmt(fmt) "CPU PMU: " fmt
+
+#include <linux/bitmap.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include <asm/cputype.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+
+/* 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);
index c90fcb2b69676b1f462c5be0160de35d9b2f1b26..6ccc0797174555ebc805a1aabe0bd77941badef0 100644 (file)
@@ -645,7 +645,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
 
 static int armv6_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv6_perf_map,
+       return armpmu_map_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 *__init armv6pmu_init(void)
+static struct arm_pmu *__devinit armv6pmu_init(void)
 {
        return &armv6pmu;
 }
@@ -679,7 +679,7 @@ static struct arm_pmu *__init armv6pmu_init(void)
 
 static int armv6mpcore_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv6mpcore_perf_map,
+       return armpmu_map_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 *__init armv6mpcore_pmu_init(void)
+static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
 {
        return &armv6mpcore_pmu;
 }
 #else
-static struct arm_pmu *__init armv6pmu_init(void)
+static struct arm_pmu *__devinit armv6pmu_init(void)
 {
        return NULL;
 }
 
-static struct arm_pmu *__init armv6mpcore_pmu_init(void)
+static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
 {
        return NULL;
 }
index f04070bd21838dd9146d694066d756d2bb1e753a..bd4b090ebcfd8e2b6132a5d2e52a9eb890a34ea9 100644 (file)
@@ -1204,31 +1204,31 @@ static void armv7pmu_reset(void *info)
 
 static int armv7_a8_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv7_a8_perf_map,
+       return armpmu_map_event(event, &armv7_a8_perf_map,
                                &armv7_a8_perf_cache_map, 0xFF);
 }
 
 static int armv7_a9_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv7_a9_perf_map,
+       return armpmu_map_event(event, &armv7_a9_perf_map,
                                &armv7_a9_perf_cache_map, 0xFF);
 }
 
 static int armv7_a5_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv7_a5_perf_map,
+       return armpmu_map_event(event, &armv7_a5_perf_map,
                                &armv7_a5_perf_cache_map, 0xFF);
 }
 
 static int armv7_a15_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv7_a15_perf_map,
+       return armpmu_map_event(event, &armv7_a15_perf_map,
                                &armv7_a15_perf_cache_map, 0xFF);
 }
 
 static int armv7_a7_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &armv7_a7_perf_map,
+       return armpmu_map_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 __init armv7_read_num_pmnc_events(void)
+static u32 __devinit armv7_read_num_pmnc_events(void)
 {
        u32 nb_cnt;
 
@@ -1256,7 +1256,7 @@ static u32 __init armv7_read_num_pmnc_events(void)
        return nb_cnt + 1;
 }
 
-static struct arm_pmu *__init armv7_a8_pmu_init(void)
+static struct arm_pmu *__devinit 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 *__init armv7_a8_pmu_init(void)
        return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a9_pmu_init(void)
+static struct arm_pmu *__devinit 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 *__init armv7_a9_pmu_init(void)
        return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a5_pmu_init(void)
+static struct arm_pmu *__devinit 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 *__init armv7_a5_pmu_init(void)
        return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a15_pmu_init(void)
+static struct arm_pmu *__devinit 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 *__init armv7_a15_pmu_init(void)
        return &armv7pmu;
 }
 
-static struct arm_pmu *__init armv7_a7_pmu_init(void)
+static struct arm_pmu *__devinit 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 *__init armv7_a7_pmu_init(void)
        return &armv7pmu;
 }
 #else
-static struct arm_pmu *__init armv7_a8_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
 {
        return NULL;
 }
 
-static struct arm_pmu *__init armv7_a9_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
 {
        return NULL;
 }
 
-static struct arm_pmu *__init armv7_a5_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
 {
        return NULL;
 }
 
-static struct arm_pmu *__init armv7_a15_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
 {
        return NULL;
 }
 
-static struct arm_pmu *__init armv7_a7_pmu_init(void)
+static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
 {
        return NULL;
 }
index f759fe0bab632303b34484001ca2b6a9e91452f1..426e19f380a2f935b7b1c9706a6c50613ce4e272 100644 (file)
@@ -430,7 +430,7 @@ xscale1pmu_write_counter(int counter, u32 val)
 
 static int xscale_map_event(struct perf_event *event)
 {
-       return map_cpu_event(event, &xscale_perf_map,
+       return armpmu_map_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 *__init xscale1pmu_init(void)
+static struct arm_pmu *__devinit xscale1pmu_init(void)
 {
        return &xscale1pmu;
 }
@@ -816,17 +816,17 @@ static struct arm_pmu xscale2pmu = {
        .max_period     = (1LLU << 32) - 1,
 };
 
-static struct arm_pmu *__init xscale2pmu_init(void)
+static struct arm_pmu *__devinit xscale2pmu_init(void)
 {
        return &xscale2pmu;
 }
 #else
-static struct arm_pmu *__init xscale1pmu_init(void)
+static struct arm_pmu *__devinit xscale1pmu_init(void)
 {
        return NULL;
 }
 
-static struct arm_pmu *__init xscale2pmu_init(void)
+static struct arm_pmu *__devinit xscale2pmu_init(void)
 {
        return NULL;
 }
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
deleted file mode 100644 (file)
index 2334bf8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  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 <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/pmu.h>
-
-/*
- * 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);
index 45c97b1ee9b1d59ba923a69b50e94337b48da993..76e795323569ee61ec164ed8a29138c5f392b9d9 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
-#include <asm/pmu.h>
 
 #include <asm/mach/arch.h>
 #include <mach/dma.h>
@@ -116,7 +115,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .resource       = &pmu_resource,
        .num_resources  = 1,
 };
index c6422fb10bae37756693f3323f79df62e4fc932e..cebc71d5a5afdc060d0e869468e334916aa8fb4a 100644 (file)
@@ -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, iim_gate, gpu2d_gate,
-       clk_max
+       wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
+       gpu2d_gate, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -142,6 +142,9 @@ 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);
@@ -192,7 +195,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", "ipg", base + MX35_CCM_CGR3,  0);
+       clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", 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);
 
@@ -228,6 +231,7 @@ 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");
@@ -255,6 +259,7 @@ 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]);
index 4bdcaa97bd9803be209f5deed8b771a4b21094d6..db70d23f95fa5a1de788b7701a4bb0d2aece2351 100644 (file)
@@ -49,6 +49,7 @@ 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,
@@ -82,6 +83,7 @@ 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
 };
 
@@ -421,8 +423,12 @@ 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[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[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[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
 
        for (i = 0; i < ARRAY_SIZE(clk); i++)
@@ -455,6 +461,10 @@ 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);
index 5b1cc35e6fba8603ab8c7faf5b25c09e6fd84eb7..3c6332753358eefa51e9b55bd038be310352db6a 100644 (file)
@@ -283,21 +283,25 @@ 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 */
@@ -305,9 +309,6 @@ 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;
 }
 
index b07dcc90829d7c3b2227bca72594d0381263ca1e..8f2a2f8712d7614c07c37b31ce458ba59eba381b 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/clk.h>
+#include <linux/mtd/lpc32xx_slc.h>
+#include <linux/mtd/lpc32xx_mlc.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -223,6 +225,14 @@ 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),
@@ -230,6 +240,10 @@ 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),
        { }
 };
 
@@ -253,12 +267,6 @@ 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 = {
index c00c68961bb848d16a68802003a4ee6402cf4710..02b9478b786f0b1e42c886a7196b3b3e5fd441cb 100644 (file)
@@ -23,7 +23,6 @@
 #include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 
 #include "iomap.h"
 #include <plat/board.h>
@@ -448,7 +447,7 @@ static struct resource omap3_pmu_resource = {
 
 static struct platform_device omap_pmu_device = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .num_resources  = 1,
 };
 
index 166eee5b8a70fe8f4bc555543ea8027564ee0392..c1f3b1279d97bc588ba7d9a44d18b45cc63cde80 100644 (file)
@@ -6,7 +6,6 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/i2c/pxa-i2c.h>
 
-#include <asm/pmu.h>
 #include <mach/udc.h>
 #include <mach/pxa3xx-u2d.h>
 #include <mach/pxafb.h>
@@ -42,7 +41,7 @@ static struct resource pxa_resource_pmu = {
 
 struct platform_device pxa_device_pmu = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .resource       = &pxa_resource_pmu,
        .num_resources  = 1,
 };
index baf382c5e77601957b2ef8982ccdd61552f9b2f2..d7a6e9cebba4792d9306091bdf8e5c7043a69135 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -297,7 +296,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
        .name                   = "arm-pmu",
-       .id                     = ARM_PMU_DEVICE_CPU,
+       .id                     = -1,
        .num_resources          = ARRAY_SIZE(pmu_resources),
        .resource               = pmu_resources,
 };
index b1d7cafa1a6d2e295c2f95529b1d556df4b85db1..361f898884c890ca2769267970b412dd53dce25f 100644 (file)
@@ -34,7 +34,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -280,7 +279,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
        .name                   = "arm-pmu",
-       .id                     = ARM_PMU_DEVICE_CPU,
+       .id                     = -1,
        .num_resources          = 1,
        .resource               = &pmu_resource,
 };
index a98c536e3327afa9823a2b29ffd081258be2ae5a..c56bc8d4d11ba2730a67d50a775b9c706b397f14 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -263,7 +262,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
        .name                   = "arm-pmu",
-       .id                     = ARM_PMU_DEVICE_CPU,
+       .id                     = -1,
        .num_resources          = ARRAY_SIZE(pmu_resources),
        .resource               = pmu_resources,
 };
index 59650174e6ed39e9c3bc9e44441beb48b22a4214..0409375824531e883fb2916ec9b2c888f24aa8e4 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 
@@ -241,7 +240,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
        .name                   = "arm-pmu",
-       .id                     = ARM_PMU_DEVICE_CPU,
+       .id                     = -1,
        .num_resources          = 1,
        .resource               = &pmu_resource,
 };
index 3f2f605624e95270fd1039e64a3a0a2d2180cd06..97885dc11e8cb89575c96cc69fb07f7f9bb40dd9 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
-#include <asm/pmu.h>
 #include <asm/smp_twd.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
@@ -280,7 +279,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
        .name                   = "arm-pmu",
-       .id                     = ARM_PMU_DEVICE_CPU,
+       .id                     = -1,
        .num_resources          = ARRAY_SIZE(pmu_resources),
        .resource               = pmu_resources,
 };
index 53b7ea92c32c119bcfc6d44a96b92fac915363da..fd21fb6f99538b696fa6d8fe5d3d9c34c3e8afab 100644 (file)
@@ -763,6 +763,13 @@ 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,
@@ -777,5 +784,6 @@ 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
index 339c62c824d5178ba1a22ef1fac082edd65cd9ba..3cafb6ab5e9aafb09e900b4821e291eab3493e29 100644 (file)
@@ -86,11 +86,16 @@ static struct clk div4_clks[DIV4_NR] = {
                                      0x0300, CLK_ENABLE_ON_INIT),
 };
 
-enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+enum { MSTP323, MSTP322, MSTP321, MSTP320,
+       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 */
@@ -149,6 +154,10 @@ 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)
index dae9aa68bb0996da98014ab093732ce411572b61..61446f30e397df38a45857e3b38c5d0b9f41c652 100644 (file)
@@ -356,6 +356,26 @@ 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,
@@ -370,6 +390,7 @@ static struct platform_device *emev2_late_devices[] __initdata = {
        &gio2_device,
        &gio3_device,
        &gio4_device,
+       &pmu_device,
 };
 
 void __init emev2_add_standard_devices(void)
index d230af656fc9c57418906e7ce3af785b7117ffc1..38ed2ddd32655de26939cb4d6048079ba0ddb63e 100644 (file)
@@ -734,6 +734,26 @@ 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,
@@ -757,6 +777,7 @@ static struct platform_device *sh73a0_late_devices[] __initdata = {
        &i2c4_device,
        &dma0_device,
        &mpdma0_device,
+       &pmu_device,
 };
 
 #define SRCR2          0xe61580b0
index c70e65ffa36ba8a91e16b372c8c616abd4414c20..61e9603744a778dfa53e25084e1d04449def7e3b 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/fsl_devices.h>
 #include <linux/serial_8250.h>
 #include <linux/i2c-tegra.h>
-#include <asm/pmu.h>
 #include <mach/irqs.h>
 #include <mach/iomap.h>
 #include <mach/dma.h>
@@ -516,7 +515,7 @@ static struct resource tegra_pmu_resources[] = {
 
 struct platform_device tegra_pmu_device = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(tegra_pmu_resources),
        .resource       = tegra_pmu_resources,
 };
index dc12394295d5e5e8a6798e9295225aeb50b5039d..75d5b512a3d54fc8adf547be4aa128d3735a92a8 100644 (file)
@@ -38,7 +38,7 @@ static int __init ux500_l2x0_init(void)
 {
        u32 aux_val = 0x3e000000;
 
-       if (cpu_is_u8500_family())
+       if (cpu_is_u8500_family() || cpu_is_ux540_family())
                l2x0_base = __io_address(U8500_L2CC_BASE);
        else
                ux500_unknown_soc();
index 8d73b066a18d31dda628af949f7c84c260bd56a7..bc5a516a58651d987e6985fafad9d6364203194d 100644 (file)
@@ -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())
+       if (cpu_is_u8500_family() || cpu_is_ux540_family())
                addr = __io_address(U8500_PRCMU_BASE);
        else
                ux500_unknown_soc();
index db3c52d56ca46ad54bddbcaaa2f48d7c64f025a6..8169f2c72d6c593964db1a7f8a1abf88592db0ac 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mfd/abx500/ab8500.h>
 
 #include <asm/mach/map.h>
-#include <asm/pmu.h>
 #include <plat/gpio-nomadik.h>
 #include <mach/hardware.h>
 #include <mach/setup.h>
@@ -80,7 +79,7 @@ void __init u8500_map_io(void)
 
        iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc));
 
-       if (cpu_is_u9540())
+       if (cpu_is_ux540_family())
                iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
        else
                iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
@@ -122,7 +121,7 @@ struct arm_pmu_platdata db8500_pmu_platdata = {
 
 static struct platform_device db8500_pmu_device = {
        .name                   = "arm-pmu",
-       .id                     = ARM_PMU_DEVICE_CPU,
+       .id                     = -1,
        .num_resources          = ARRAY_SIZE(db8500_pmu_resources),
        .resource               = db8500_pmu_resources,
        .dev.platform_data      = &db8500_pmu_platdata,
index e2360e7c770d3a6c99b8abedfc38810503f290a7..4b0a9b3003123e51da736e6421aede1e29eaaf46 100644 (file)
@@ -51,7 +51,7 @@ void __init ux500_init_irq(void)
        void __iomem *dist_base;
        void __iomem *cpu_base;
 
-       if (cpu_is_u8500_family()) {
+       if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
                dist_base = __io_address(U8500_GIC_DIST_BASE);
                cpu_base = __io_address(U8500_GIC_CPU_BASE);
        } else
index c6e2db9e9e5143db632a422fee1ff46067651715..9c42642ab1680b4ca5d7ec22c6cd6e51b8c82e7b 100644 (file)
@@ -41,43 +41,29 @@ static inline bool __attribute_const__ cpu_is_u8500(void)
        return dbx500_partnumber() == 0x8500;
 }
 
-static inline bool __attribute_const__ cpu_is_u9540(void)
+static inline bool __attribute_const__ cpu_is_u8520(void)
 {
-       return dbx500_partnumber() == 0x9540;
+       return dbx500_partnumber() == 0x8520;
 }
 
 static inline bool cpu_is_u8500_family(void)
 {
-       return cpu_is_u8500() || cpu_is_u9540();
-}
-
-static inline bool __attribute_const__ cpu_is_u5500(void)
-{
-       return dbx500_partnumber() == 0x5500;
-}
-
-/*
- * 5500 revisions
- */
-
-static inline bool __attribute_const__ cpu_is_u5500v1(void)
-{
-       return cpu_is_u5500() && (dbx500_revision() & 0xf0) == 0xA0;
+       return cpu_is_u8500() || cpu_is_u8520();
 }
 
-static inline bool __attribute_const__ cpu_is_u5500v2(void)
+static inline bool __attribute_const__ cpu_is_u9540(void)
 {
-       return (dbx500_id.revision & 0xf0) == 0xB0;
+       return dbx500_partnumber() == 0x9540;
 }
 
-static inline bool __attribute_const__ cpu_is_u5500v20(void)
+static inline bool __attribute_const__ cpu_is_u8540(void)
 {
-       return cpu_is_u5500() && ((dbx500_revision() & 0xf0) == 0xB0);
+       return dbx500_partnumber() == 0x8540;
 }
 
-static inline bool __attribute_const__ cpu_is_u5500v21(void)
+static inline bool cpu_is_ux540_family(void)
 {
-       return cpu_is_u5500() && (dbx500_revision() == 0xB1);
+       return cpu_is_u9540() || cpu_is_u8540();
 }
 
 /*
@@ -119,14 +105,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)
 {
-       /*
-        * 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());
+       return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11());
 }
 
 static inline bool ux500_is_svp(void)
index da1d5ad5bd4531ae3d142e8a65f39de6d67eae56..a5dda68444dbdfaeed8ae19b571e8fdfea1190b5 100644 (file)
@@ -48,7 +48,7 @@ static void write_pen_release(int val)
 
 static void __iomem *scu_base_addr(void)
 {
-       if (cpu_is_u8500_family())
+       if (cpu_is_u8500_family() || cpu_is_ux540_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())
+       if (cpu_is_u8500_family() || cpu_is_ux540_family())
                backupram = __io_address(U8500_BACKUPRAM0_BASE);
        else
                ux500_unknown_soc();
index 66e7f00884ab4b4443d51f56c211ae7ac6385f49..6f39731951b051a49213eafd32ece237904f0638 100644 (file)
@@ -54,7 +54,7 @@ static void __init ux500_timer_init(void)
        void __iomem *tmp_base;
        struct device_node *np;
 
-       if (cpu_is_u8500_family()) {
+       if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
                mtu_timer_base = __io_address(U8500_MTU0_BASE);
                prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
        } else {
index 61c492403b05f46957787a7836ef12a0eee44695..e4073a60a86457968a871fb8ad3096c1970f892c 100644 (file)
@@ -13,7 +13,6 @@
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
-#include <asm/pmu.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 
@@ -144,7 +143,7 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(pmu_resources),
        .resource       = pmu_resources,
 };
index a2024b8685a15a37a0141132bcc49ce8f80aa599..ad9f9744a82d12b22e4c8d8407e686867b79f351 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 #include <linux/platform_device.h>
-#include <asm/pmu.h>
 #include <mach/irqs.h>
 
 static struct resource pmu_resource = {
@@ -26,7 +25,7 @@ static struct resource pmu_resource = {
 
 static struct platform_device pmu_device = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .resource       = &pmu_resource,
        .num_resources  = 1,
 };
index d8b65b51f2a994d4b00e4a83568cbeb4378d16fa..f79f78a1c0edbe16fe10fbc1478d931c398a75a5 100644 (file)
@@ -512,12 +512,16 @@ 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)
@@ -721,6 +725,7 @@ 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)
index 8397a2dd19f2d6caad2adb5824ca13537c8d19fd..a8b93c5f29b5321a3b0ef341cfb07d601218a2d2 100644 (file)
                .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, imx_ssi_fiq_base
+               ldr r12, .L_imx_ssi_fiq_base
 
                /* TX */
-               ldr r11, imx_ssi_fiq_tx_buffer
+               ldr r13, .L_imx_ssi_fiq_tx_buffer
 
                /* shall we send? */
-               ldr r13, [r12, #SSI_SIER]
-               tst r13, #SSI_SIER_TFE0_EN
+               ldr r11, [r12, #SSI_SIER]
+               tst r11, #SSI_SIER_TFE0_EN
                beq 1f
 
                /* TX FIFO empty? */
-               ldr r13, [r12, #SSI_SISR]
-               tst r13, #SSI_SISR_TFE0
+               ldr r11, [r12, #SSI_SISR]
+               tst r11, #SSI_SISR_TFE0
                beq 1f
 
                mov r10, #0x10000
                sub r10, #1
                and r10, r10, r8        /* r10: current buffer offset */
 
-               add r11, r11, r10
+               add r13, r13, r10
 
-               ldrh r13, [r11]
-               strh r13, [r12, #SSI_STX0]
+               ldrh r11, [r13]
+               strh r11, [r12, #SSI_STX0]
 
-               ldrh r13, [r11, #2]
-               strh r13, [r12, #SSI_STX0]
+               ldrh r11, [r13, #2]
+               strh r11, [r12, #SSI_STX0]
 
-               ldrh r13, [r11, #4]
-               strh r13, [r12, #SSI_STX0]
+               ldrh r11, [r13, #4]
+               strh r11, [r12, #SSI_STX0]
 
-               ldrh r13, [r11, #6]
-               strh r13, [r12, #SSI_STX0]
+               ldrh r11, [r13, #6]
+               strh r11, [r12, #SSI_STX0]
 
                add r10, #8
-               lsr r13, r8, #16        /* r13: buffer size */
-               cmp r10, r13
-               lslgt r8, r13, #16
+               lsr r11, r8, #16        /* r11: buffer size */
+               cmp r10, r11
+               lslgt r8, r11, #16
                addle r8, #8
 1:
                /* RX */
 
                /* shall we receive? */
-               ldr r13, [r12, #SSI_SIER]
-               tst r13, #SSI_SIER_RFF0_EN
+               ldr r11, [r12, #SSI_SIER]
+               tst r11, #SSI_SIER_RFF0_EN
                beq 1f
 
                /* RX FIFO full? */
-               ldr r13, [r12, #SSI_SISR]
-               tst r13, #SSI_SISR_RFF0
+               ldr r11, [r12, #SSI_SISR]
+               tst r11, #SSI_SISR_RFF0
                beq 1f
 
-               ldr r11, imx_ssi_fiq_rx_buffer
+               ldr r13, .L_imx_ssi_fiq_rx_buffer
 
                mov r10, #0x10000
                sub r10, #1
                and r10, r10, r9        /* r10: current buffer offset */
 
-               add r11, r11, r10
+               add r13, r13, r10
 
-               ldr r13, [r12, #SSI_SACNT]
-               tst r13, #SSI_SACNT_AC97EN
+               ldr r11, [r12, #SSI_SACNT]
+               tst r11, #SSI_SACNT_AC97EN
 
-               ldr r13, [r12, #SSI_SRX0]
-               strh r13, [r11]
+               ldr r11, [r12, #SSI_SRX0]
+               strh r11, [r13]
 
-               ldr r13, [r12, #SSI_SRX0]
-               strh r13, [r11, #2]
+               ldr r11, [r12, #SSI_SRX0]
+               strh r11, [r13, #2]
 
                /* dummy read to skip slot 12 */
-               ldrne r13, [r12, #SSI_SRX0]
+               ldrne r11, [r12, #SSI_SRX0]
 
-               ldr r13, [r12, #SSI_SRX0]
-               strh r13, [r11, #4]
+               ldr r11, [r12, #SSI_SRX0]
+               strh r11, [r13, #4]
 
-               ldr r13, [r12, #SSI_SRX0]
-               strh r13, [r11, #6]
+               ldr r11, [r12, #SSI_SRX0]
+               strh r11, [r13, #6]
 
                /* dummy read to skip slot 12 */
-               ldrne r13, [r12, #SSI_SRX0]
+               ldrne r11, [r12, #SSI_SRX0]
 
                add r10, #8
-               lsr r13, r9, #16        /* r13: buffer size */
-               cmp r10, r13
-               lslgt r9, r13, #16
+               lsr r11, r9, #16        /* r11: buffer size */
+               cmp r10, r11
+               lslgt r9, r11, #16
                addle r9, #8
 
 1:
@@ -126,11 +133,15 @@ 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:
 
index fc49f3dabd7653624b7f9ccc8e78ef12b102d527..6ff45d53362c1a0ef61d0806626829223f96e78e 100644 (file)
@@ -35,7 +35,6 @@
 #include <media/s5p_hdmi.h>
 
 #include <asm/irq.h>
-#include <asm/pmu.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -1132,7 +1131,7 @@ static struct resource s5p_pmu_resource[] = {
 
 static struct platform_device s5p_device_pmu = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(s5p_pmu_resource),
        .resource       = s5p_pmu_resource,
 };
This page took 0.068685 seconds and 5 git commands to generate.