Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 326431
b: refs/heads/master
c: 04236f9
h: refs/heads/master
i:
  326429: 5bcd150
  326427: 6feb2b7
  326423: 7010f30
  326415: 6c53cca
  326399: 0640209
v: v3
  • Loading branch information
Will Deacon committed Aug 23, 2012
1 parent b3ad317 commit 6242c49
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 104 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9f44f9a234020947dd16500a203c9580a66ed67d
refs/heads/master: 04236f9fe07462849215c67cae6147661368bfad
175 changes: 91 additions & 84 deletions trunk/arch/arm/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/of.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
Expand Down Expand Up @@ -610,9 +611,11 @@ 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);
}

Expand All @@ -621,74 +624,12 @@ int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type)
#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-a15-pmu"},
{.compatible = "arm,cortex-a9-pmu"},
{.compatible = "arm,cortex-a8-pmu"},
{.compatible = "arm,cortex-a7-pmu"},
{.compatible = "arm,cortex-a5-pmu"},
{.compatible = "arm,arm11mpcore-pmu"},
{.compatible = "arm,arm1176-pmu"},
{.compatible = "arm,arm1136-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 const struct dev_pm_ops armpmu_dev_pm_ops = {
SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
};

static struct platform_driver armpmu_driver = {
.driver = {
.name = "arm-pmu",
.pm = &armpmu_dev_pm_ops,
.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)
static void __devinit cpu_pmu_init(struct arm_pmu *cpu_pmu)
{
int cpu;
for_each_possible_cpu(cpu) {
Expand All @@ -697,7 +638,11 @@ static void __init cpu_pmu_init(struct arm_pmu *armpmu)
events->used_mask = per_cpu(used_mask, cpu);
raw_spin_lock_init(&events->pmu_lock);
}
armpmu->get_hw_events = armpmu_get_cpu_events;
cpu_pmu->get_hw_events = armpmu_get_cpu_events;

/* Ensure the PMU has sane values out of reset. */
if (cpu_pmu && cpu_pmu->reset)
on_each_cpu(cpu_pmu->reset, NULL, 1);
}

/*
Expand All @@ -722,69 +667,131 @@ static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
.notifier_call = pmu_cpu_notify,
};

static const struct dev_pm_ops armpmu_dev_pm_ops = {
SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
};

/*
* 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 registration.
* CPU PMU identification and probing.
*/
static int __init
init_hw_perf_events(void)
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 */
cpu_pmu = armv6pmu_init();
pmu = armv6pmu_init();
break;
case 0xB020: /* ARM11mpcore */
cpu_pmu = armv6mpcore_pmu_init();
pmu = armv6mpcore_pmu_init();
break;
case 0xC080: /* Cortex-A8 */
cpu_pmu = armv7_a8_pmu_init();
pmu = armv7_a8_pmu_init();
break;
case 0xC090: /* Cortex-A9 */
cpu_pmu = armv7_a9_pmu_init();
pmu = armv7_a9_pmu_init();
break;
case 0xC050: /* Cortex-A5 */
cpu_pmu = armv7_a5_pmu_init();
pmu = armv7_a5_pmu_init();
break;
case 0xC0F0: /* Cortex-A15 */
cpu_pmu = armv7_a15_pmu_init();
pmu = armv7_a15_pmu_init();
break;
case 0xC070: /* Cortex-A7 */
cpu_pmu = armv7_a7_pmu_init();
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();
pmu = xscale1pmu_init();
break;
case 2:
cpu_pmu = xscale2pmu_init();
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("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);
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 {
pr_info("no hardware support available\n");
cpu_pmu = probe_current_pmu();
}

if (!cpu_pmu)
return -ENODEV;

cpu_pmu->plat_device = pdev;
cpu_pmu_init(cpu_pmu);
register_cpu_notifier(&pmu_cpu_notifier);
armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);

return 0;
}
early_initcall(init_hw_perf_events);

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);

/*
* Callchain handling code.
Expand Down
8 changes: 4 additions & 4 deletions trunk/arch/arm/kernel/perf_event_v6.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
22 changes: 11 additions & 11 deletions trunk/arch/arm/kernel/perf_event_v7.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -1256,31 +1256,31 @@ 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;
armv7pmu.num_events = armv7_read_num_pmnc_events();
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;
armv7pmu.num_events = armv7_read_num_pmnc_events();
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;
armv7pmu.num_events = armv7_read_num_pmnc_events();
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;
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit 6242c49

Please sign in to comment.