arm: perf: make PMU probing data-driven
[linux-2.6-microblaze.git] / arch / arm / kernel / perf_event_cpu.c
index eb2c4d5..e7d2652 100644 (file)
@@ -120,7 +120,7 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
 
        irqs = min(pmu_device->num_resources, num_possible_cpus());
        if (irqs < 1) {
-               printk_once("perf/ARM: No irqs for PMU defined, sampling events not supported\n");
+               pr_warn_once("perf/ARM: No irqs for PMU defined, sampling events not supported\n");
                return 0;
        }
 
@@ -241,48 +241,34 @@ static struct platform_device_id cpu_pmu_plat_device_ids[] = {
        {},
 };
 
+static const struct pmu_probe_info pmu_probe_table[] = {
+       ARM_PMU_PROBE(ARM_CPU_PART_ARM1136, armv6_1136_pmu_init),
+       ARM_PMU_PROBE(ARM_CPU_PART_ARM1156, armv6_1156_pmu_init),
+       ARM_PMU_PROBE(ARM_CPU_PART_ARM1176, armv6_1176_pmu_init),
+       ARM_PMU_PROBE(ARM_CPU_PART_ARM11MPCORE, armv6mpcore_pmu_init),
+       ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8, armv7_a8_pmu_init),
+       ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9, armv7_a9_pmu_init),
+       XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V1, xscale1pmu_init),
+       XSCALE_PMU_PROBE(ARM_CPU_XSCALE_ARCH_V2, xscale2pmu_init),
+       { /* sentinel value */ }
+};
+
 /*
  * CPU PMU identification and probing.
  */
 static int probe_current_pmu(struct arm_pmu *pmu)
 {
        int cpu = get_cpu();
+       unsigned int cpuid = read_cpuid_id();
        int ret = -ENODEV;
+       const struct pmu_probe_info *info;
 
        pr_info("probing PMU on CPU %d\n", cpu);
 
-       switch (read_cpuid_part()) {
-       /* ARM Ltd CPUs. */
-       case ARM_CPU_PART_ARM1136:
-               ret = armv6_1136_pmu_init(pmu);
-               break;
-       case ARM_CPU_PART_ARM1156:
-               ret = armv6_1156_pmu_init(pmu);
-               break;
-       case ARM_CPU_PART_ARM1176:
-               ret = armv6_1176_pmu_init(pmu);
-               break;
-       case ARM_CPU_PART_ARM11MPCORE:
-               ret = armv6mpcore_pmu_init(pmu);
-               break;
-       case ARM_CPU_PART_CORTEX_A8:
-               ret = armv7_a8_pmu_init(pmu);
-               break;
-       case ARM_CPU_PART_CORTEX_A9:
-               ret = armv7_a9_pmu_init(pmu);
-               break;
-
-       default:
-               if (read_cpuid_implementor() == ARM_CPU_IMP_INTEL) {
-                       switch (xscale_cpu_arch_version()) {
-                       case ARM_CPU_XSCALE_ARCH_V1:
-                               ret = xscale1pmu_init(pmu);
-                               break;
-                       case ARM_CPU_XSCALE_ARCH_V2:
-                               ret = xscale2pmu_init(pmu);
-                               break;
-                       }
-               }
+       for (info = pmu_probe_table; info->init != NULL; info++) {
+               if ((cpuid & info->mask) != info->cpuid)
+                       continue;
+               ret = info->init(pmu);
                break;
        }
 
@@ -299,13 +285,13 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
        int ret = -ENODEV;
 
        if (cpu_pmu) {
-               pr_info("attempt to register multiple PMU devices!");
+               pr_info("attempt to register multiple PMU devices!\n");
                return -ENOSPC;
        }
 
        pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL);
        if (!pmu) {
-               pr_info("failed to allocate PMU device!");
+               pr_info("failed to allocate PMU device!\n");
                return -ENOMEM;
        }
 
@@ -320,7 +306,7 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
        }
 
        if (ret) {
-               pr_info("failed to probe PMU!");
+               pr_info("failed to probe PMU!\n");
                goto out_free;
        }
 
@@ -331,7 +317,7 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
                return 0;
 
 out_free:
-       pr_info("failed to register PMU devices!");
+       pr_info("failed to register PMU devices!\n");
        kfree(pmu);
        return ret;
 }