aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2011-06-22 10:30:51 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-06-29 05:27:08 -0400
commitf12482c9393da2c1f5cb3217f29aa79c653dd980 (patch)
tree3963f2607ea13feb1d384df5da7727148101d652
parent090ab3ff8ebb842c0f159d34d57d6e51bd94ace1 (diff)
ARM: 6974/1: pmu: refactor reservation
Currently, PMU platform_device reservation relies on some minor abuse of the platform_device::id field for determining the type of PMU. This is problematic for device tree based probing, where the ID cannot be controlled. This patch removes reliance on the id field, and depends on each PMU's platform driver to figure out which type it is. As all PMUs handled by the current platform_driver name "arm-pmu" are CPU PMUs, this convention is hardcoded. New PMU types can be supported through the use of {of,platform}_device_id tables Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Jamie Iles <jamie@jamieiles.com> Acked-by: Will Deacon <will.deacon@arm.com> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/include/asm/pmu.h2
-rw-r--r--arch/arm/kernel/perf_event.c4
-rw-r--r--arch/arm/kernel/pmu.c33
3 files changed, 22 insertions, 17 deletions
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 7544ce6b481a..67c70a31a1be 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -52,7 +52,7 @@ reserve_pmu(enum arm_pmu_type device);
52 * a cookie. 52 * a cookie.
53 */ 53 */
54extern int 54extern int
55release_pmu(struct platform_device *pdev); 55release_pmu(enum arm_pmu_type type);
56 56
57/** 57/**
58 * init_pmu() - Initialise the PMU. 58 * init_pmu() - Initialise the PMU.
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d53c0abc4dd3..a6c643f2d2ca 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -435,7 +435,7 @@ armpmu_reserve_hardware(void)
435 if (irq >= 0) 435 if (irq >= 0)
436 free_irq(irq, NULL); 436 free_irq(irq, NULL);
437 } 437 }
438 release_pmu(pmu_device); 438 release_pmu(ARM_PMU_DEVICE_CPU);
439 pmu_device = NULL; 439 pmu_device = NULL;
440 } 440 }
441 441
@@ -454,7 +454,7 @@ armpmu_release_hardware(void)
454 } 454 }
455 armpmu->stop(); 455 armpmu->stop();
456 456
457 release_pmu(pmu_device); 457 release_pmu(ARM_PMU_DEVICE_CPU);
458 pmu_device = NULL; 458 pmu_device = NULL;
459} 459}
460 460
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
index 2c79eec19262..87942b931c62 100644
--- a/arch/arm/kernel/pmu.c
+++ b/arch/arm/kernel/pmu.c
@@ -25,36 +25,41 @@ static volatile long pmu_lock;
25 25
26static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES]; 26static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES];
27 27
28static int __devinit pmu_device_probe(struct platform_device *pdev) 28static int __devinit pmu_register(struct platform_device *pdev,
29 enum arm_pmu_type type)
29{ 30{
30 31 if (type < 0 || type >= ARM_NUM_PMU_DEVICES) {
31 if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) {
32 pr_warning("received registration request for unknown " 32 pr_warning("received registration request for unknown "
33 "device %d\n", pdev->id); 33 "device %d\n", type);
34 return -EINVAL; 34 return -EINVAL;
35 } 35 }
36 36
37 if (pmu_devices[pdev->id]) 37 if (pmu_devices[type])
38 pr_warning("registering new PMU device type %d overwrites " 38 pr_warning("registering new PMU device type %d overwrites "
39 "previous registration!\n", pdev->id); 39 "previous registration!\n", type);
40 else 40 else
41 pr_info("registered new PMU device of type %d\n", 41 pr_info("registered new PMU device of type %d\n",
42 pdev->id); 42 type);
43 43
44 pmu_devices[pdev->id] = pdev; 44 pmu_devices[type] = pdev;
45 return 0; 45 return 0;
46} 46}
47 47
48static struct platform_driver pmu_driver = { 48static int __devinit armpmu_device_probe(struct platform_device *pdev)
49{
50 return pmu_register(pdev, ARM_PMU_DEVICE_CPU);
51}
52
53static struct platform_driver armpmu_driver = {
49 .driver = { 54 .driver = {
50 .name = "arm-pmu", 55 .name = "arm-pmu",
51 }, 56 },
52 .probe = pmu_device_probe, 57 .probe = armpmu_device_probe,
53}; 58};
54 59
55static int __init register_pmu_driver(void) 60static int __init register_pmu_driver(void)
56{ 61{
57 return platform_driver_register(&pmu_driver); 62 return platform_driver_register(&armpmu_driver);
58} 63}
59device_initcall(register_pmu_driver); 64device_initcall(register_pmu_driver);
60 65
@@ -77,11 +82,11 @@ reserve_pmu(enum arm_pmu_type device)
77EXPORT_SYMBOL_GPL(reserve_pmu); 82EXPORT_SYMBOL_GPL(reserve_pmu);
78 83
79int 84int
80release_pmu(struct platform_device *pdev) 85release_pmu(enum arm_pmu_type device)
81{ 86{
82 if (WARN_ON(pdev != pmu_devices[pdev->id])) 87 if (WARN_ON(!pmu_devices[device]))
83 return -EINVAL; 88 return -EINVAL;
84 clear_bit_unlock(pdev->id, &pmu_lock); 89 clear_bit_unlock(device, &pmu_lock);
85 return 0; 90 return 0;
86} 91}
87EXPORT_SYMBOL_GPL(release_pmu); 92EXPORT_SYMBOL_GPL(release_pmu);