diff options
-rw-r--r-- | Documentation/devicetree/bindings/arm/pmu.txt | 21 | ||||
-rw-r--r-- | arch/arm/kernel/pmu.c | 34 |
2 files changed, 54 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt new file mode 100644 index 000000000000..1c044eb320cc --- /dev/null +++ b/Documentation/devicetree/bindings/arm/pmu.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | * ARM Performance Monitor Units | ||
2 | |||
3 | ARM cores often have a PMU for counting cpu and cache events like cache misses | ||
4 | and hits. The interface to the PMU is part of the ARM ARM. The ARM PMU | ||
5 | representation in the device tree should be done as under:- | ||
6 | |||
7 | Required properties: | ||
8 | |||
9 | - compatible : should be one of | ||
10 | "arm,cortex-a9-pmu" | ||
11 | "arm,cortex-a8-pmu" | ||
12 | "arm,arm1176-pmu" | ||
13 | "arm,arm1136-pmu" | ||
14 | - interrupts : 1 combined interrupt or 1 per core. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | pmu { | ||
19 | compatible = "arm,cortex-a9-pmu"; | ||
20 | interrupts = <100 101>; | ||
21 | }; | ||
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index de6b1b0860c2..2ce00be697ea 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/of_device.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | 22 | ||
22 | #include <asm/pmu.h> | 23 | #include <asm/pmu.h> |
@@ -45,14 +46,45 @@ static int __devinit pmu_register(struct platform_device *pdev, | |||
45 | return 0; | 46 | return 0; |
46 | } | 47 | } |
47 | 48 | ||
49 | #define OF_MATCH_PMU(_name, _type) { \ | ||
50 | .compatible = _name, \ | ||
51 | .data = (void *)_type, \ | ||
52 | } | ||
53 | |||
54 | #define OF_MATCH_CPU(name) OF_MATCH_PMU(name, ARM_PMU_DEVICE_CPU) | ||
55 | |||
56 | static struct of_device_id armpmu_of_device_ids[] = { | ||
57 | OF_MATCH_CPU("arm,cortex-a9-pmu"), | ||
58 | OF_MATCH_CPU("arm,cortex-a8-pmu"), | ||
59 | OF_MATCH_CPU("arm,arm1136-pmu"), | ||
60 | OF_MATCH_CPU("arm,arm1176-pmu"), | ||
61 | {}, | ||
62 | }; | ||
63 | |||
64 | enum arm_pmu_type armpmu_device_type(struct platform_device *pdev) | ||
65 | { | ||
66 | const struct of_device_id *of_id; | ||
67 | |||
68 | /* provided by of_device_id table */ | ||
69 | if (pdev->dev.of_node) { | ||
70 | of_id = of_match_device(armpmu_of_device_ids, &pdev->dev); | ||
71 | BUG_ON(!of_id); | ||
72 | return (enum arm_pmu_type)of_id->data; | ||
73 | } | ||
74 | |||
75 | /* Provided by a 'legacy' platform_device */ | ||
76 | return ARM_PMU_DEVICE_CPU; | ||
77 | } | ||
78 | |||
48 | static int __devinit armpmu_device_probe(struct platform_device *pdev) | 79 | static int __devinit armpmu_device_probe(struct platform_device *pdev) |
49 | { | 80 | { |
50 | return pmu_register(pdev, ARM_PMU_DEVICE_CPU); | 81 | return pmu_register(pdev, armpmu_device_type(pdev)); |
51 | } | 82 | } |
52 | 83 | ||
53 | static struct platform_driver armpmu_driver = { | 84 | static struct platform_driver armpmu_driver = { |
54 | .driver = { | 85 | .driver = { |
55 | .name = "arm-pmu", | 86 | .name = "arm-pmu", |
87 | .of_match_table = armpmu_of_device_ids, | ||
56 | }, | 88 | }, |
57 | .probe = armpmu_device_probe, | 89 | .probe = armpmu_device_probe, |
58 | }; | 90 | }; |