ARM: pmu: provide a registration mechanism for IRQs [v3]
Subsystems (5)
cover ARM: pmu: provide a registration mechanism for IRQs [v3]
This is version 3 of the patch series originally posted here:
v1: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-March/011162.html
v2: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-March/011339.html
Changes from version 2 include:
- PXA PMU registration moved out of mach-pxa and into plat-pxa
- Use of a platform_device to represent the PMU
- Fixes in pmu.c in response to comments from Jamie Iles
- Taken against 2.6.34-rc2
I'd like to submit this to the patch system soon, so please let me know if the mach-* and plat-* changes require any further work.
Will Deacon (6):
ARM: pmu: register IRQs at runtime
ARM: Realview: register PMU IRQs during board initialisation
ARM: OMAP: register PMU IRQs during board initialisation
ARM: BCMRING: register PMU IRQ during board initialisation
ARM: iop3xx: register PMU IRQs during board initialisation
ARM: pxa: register PMU IRQs during board initialisation
arch/arm/include/asm/pmu.h | 32 ++++---- arch/arm/kernel/perf_event.c | 36 +++++---- arch/arm/kernel/pmu.c | 127 +++++++++++++++++++---------- arch/arm/mach-bcmring/arch.c | 16 ++++ arch/arm/mach-omap2/devices.c | 34 ++++++++ arch/arm/mach-realview/realview_eb.c | 32 ++++++++ arch/arm/mach-realview/realview_pb1176.c | 15 ++++ arch/arm/mach-realview/realview_pb11mp.c | 32 ++++++++ arch/arm/mach-realview/realview_pba8.c | 15 ++++ arch/arm/mach-realview/realview_pbx.c | 32 ++++++++ arch/arm/plat-iop/Makefile | 2 + arch/arm/plat-iop/pmu.c | 40 +++++++++ arch/arm/plat-pxa/Makefile | 2 +- arch/arm/plat-pxa/pmu.c | 33 ++++++++ 14 files changed, 371 insertions(+), 77 deletions(-) create mode 100644 arch/arm/plat-iop/pmu.c create mode 100644 arch/arm/plat-pxa/pmu.c
PATCH 1/6 ARM: pmu: register IRQs at runtime
The current PMU infrastructure for ARM requires that the IRQs for the PMU device are fixed at compile time and are selected based on the ARCH_ or MACH_ flags. This has the disadvantage of tying the Kernel down to a particular board as far as profiling is concerned.
This patch replaces the compile-time IRQ registration with a runtime mechanism which allows the IRQs to be registered with the framework as a platform_device.
A further advantage of this change is that there is scope for registering different types of performance counters in the future by changing the id of the platform_device and attaching different resources to it.
--- arch/arm/include/asm/pmu.h | 32 ++++++----- arch/arm/kernel/perf_event.c | 36 ++++++------ arch/arm/kernel/pmu.c | 127 +++++++++++++++++++++++++++-------------- 3 files changed, 119 insertions(+), 76 deletions(-)
arch/arm/include/asm/pmu.h +17 -15
@@ -12,33 +12,33 @@#ifndef __ARM_PMU_H__#define __ARM_PMU_H__ -#ifdef CONFIG_CPU_HAS_PMU - -struct pmu_irqs { -const int *irqs; -int num_irqs; +enum arm_pmu_type { +ARM_PMU_DEVICE_CPU =0 , +ARM_NUM_PMU_DEVICES , }; +#ifdef CONFIG_CPU_HAS_PMU +/** * reserve_pmu() - reserve the hardware performance counters * * Reserve the hardware performance counters in the system for exclusive use. -* The 'struct pmu_irqs' for the system is returned on success, ERR_PTR() +* The platform_device for the system is returned on success, ERR_PTR() * encoded error on failure. */ -extern const struct pmu_irqs * -reserve_pmu (void ); +extern struct platform_device * +reserve_pmu (enum arm_pmu_type device);/** * release_pmu() - Relinquish control of the performance counters * * Release the performance counters and allow someone else to use them. * Callers must have disabled the counters and released IRQs before calling -* this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as +* this. The platform_device returned from reserve_pmu() must be passed as * a cookie. */ extern int -release_pmu (const struct pmu_irqs *irqs); +release_pmu (struct platform_device *pdev);/** * init_pmu() - Initialise the PMU.
@@ -48,24 +48,26 @@ release_pmu(const struct pmu_irqs *irqs);* the actual hardware initialisation. */ extern int -init_pmu (void ); +init_pmu (enum arm_pmu_type device);#else /* CONFIG_CPU_HAS_PMU */ -static inline const struct pmu_irqs * -reserve_pmu (void ) +#include <linux/err.h> + +static inline struct platform_device * +reserve_pmu (enum arm_pmu_type device) {return ERR_PTR (-ENODEV ); }static inline int -release_pmu (const struct pmu_irqs *irqs) +release_pmu (struct platform_device *pdev) {return -ENODEV ; }static inline int -init_pmu (void ) +init_pmu (enum arm_pmu_type device) {return -ENODEV ; }
arch/arm/kernel/perf_event.c +19 -17
@@ -17,6 +17,7 @@#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/perf_event.h> +#include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/uaccess.h>
@@ -26,7 +27,7 @@#include <asm/pmu.h> #include <asm/stacktrace.h> -static const struct pmu_irqs *pmu_irqs; +static struct platform_device *pmu_device;/* * Hardware lock to serialize accesses to PMU registers. Needed for the
@@ -317,35 +318,36 @@ armpmu_reserve_hardware(void)int i;int err; - pmu_irqs =reserve_pmu (); -if (IS_ERR (pmu_irqs)) { + pmu_device =reserve_pmu (ARM_PMU_DEVICE_CPU ); +if (IS_ERR (pmu_device)) {pr_warning ("unable to reserve pmu\n" ); -return PTR_ERR (pmu_irqs); +return PTR_ERR (pmu_device); } -init_pmu (); +init_pmu (ARM_PMU_DEVICE_CPU ); -if (pmu_irqs->num_irqs <1 ) { +if (pmu_device->num_resources <1 ) {pr_err ("no irqs for PMUs defined\n" );return -ENODEV ; } -for (i =0 ; i < pmu_irqs->num_irqs; ++i) { - err =request_irq (pmu_irqs->irqs[i], armpmu->handle_irq, +for (i =0 ; i < pmu_device->num_resources; ++i) { + err =request_irq (platform_get_irq (pmu_device, i), + armpmu->handle_irq,IRQF_DISABLED |IRQF_NOBALANCING ,"armpmu" ,NULL );if (err) { -pr_warning ("unable to request IRQ%d for ARM " -"perf counters\n" , pmu_irqs->irqs[i]); +pr_warning ("unable to request IRQ%d for ARM perf " +"counters\n" ,platform_get_irq (pmu_device, i));break ; } }if (err) {for (i = i -1 ; i >=0 ; --i) -free_irq (pmu_irqs->irqs[i],NULL ); -release_pmu (pmu_irqs); - pmu_irqs =NULL ; +free_irq (platform_get_irq (pmu_device, i),NULL ); +release_pmu (pmu_device); + pmu_device =NULL ; }return err;
@@ -356,12 +358,12 @@ armpmu_release_hardware(void) {int i; -for (i = pmu_irqs->num_irqs -1 ; i >=0 ; --i) -free_irq (pmu_irqs->irqs[i],NULL ); +for (i = pmu_device->num_resources -1 ; i >=0 ; --i) +free_irq (platform_get_irq (pmu_device, i),NULL ); armpmu->stop (); -release_pmu (pmu_irqs); - pmu_irqs =NULL ; +release_pmu (pmu_device); + pmu_device =NULL ; }static atomic_t active_events =ATOMIC_INIT (0 );
arch/arm/kernel/pmu.c +83 -44
171 lines not on this page · raw message
Signature · 1 line
1.6.3.3
PATCH 2/6 ARM: Realview: register PMU IRQs during board initialisation
This patch updates the initialisation routines for the Realview boards so that they register their PMU IRQs with the PMU framework in the Kernel.
--- arch/arm/mach-realview/realview_eb.c | 32 ++++++++++++++++++++++++++++++ arch/arm/mach-realview/realview_pb1176.c | 15 ++++++++++++++ arch/arm/mach-realview/realview_pb11mp.c | 32 ++++++++++++++++++++++++++++++ arch/arm/mach-realview/realview_pba8.c | 15 ++++++++++++++ arch/arm/mach-realview/realview_pbx.c | 32 ++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+), 0 deletions(-)
arch/arm/mach-realview/realview_eb.c +32 -0
@@ -31,6 +31,7 @@#include <asm/irq.h> #include <asm/leds.h> #include <asm/mach-types.h> +#include <asm/pmu.h> #include <asm/hardware/gic.h> #include <asm/hardware/icst307.h> #include <asm/hardware/cache-l2x0.h>
@@ -294,6 +295,36 @@ static struct resource realview_eb_isp1761_resources[] = { }, }; +static struct resource pmu_resources[] = { + [0 ] = { + .start =IRQ_EB11MP_PMU_CPU0 , + .end =IRQ_EB11MP_PMU_CPU0 , + .flags =IORESOURCE_IRQ , + }, + [1 ] = { + .start =IRQ_EB11MP_PMU_CPU1 , + .end =IRQ_EB11MP_PMU_CPU1 , + .flags =IORESOURCE_IRQ , + }, + [2 ] = { + .start =IRQ_EB11MP_PMU_CPU2 , + .end =IRQ_EB11MP_PMU_CPU2 , + .flags =IORESOURCE_IRQ , + }, + [3 ] = { + .start =IRQ_EB11MP_PMU_CPU3 , + .end =IRQ_EB11MP_PMU_CPU3 , + .flags =IORESOURCE_IRQ , + }, +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .num_resources =ARRAY_SIZE (pmu_resources), + .resource = pmu_resources, +}; +static void __init gic_init_irq (void ) {if (core_tile_eb11mp () ||core_tile_a9mp ()) {
@@ -407,6 +438,7 @@ static void __init realview_eb_init(void)* Bits: .... ...0 0111 1001 0000 .... .... .... */ l2x0_init (__io_address (REALVIEW_EB11MP_L220_BASE ),0x00790000 ,0xfe000fff );#endif +platform_device_register (&pmu_device); }realview_flash_register (&realview_eb_flash_resource,1 );
arch/arm/mach-realview/realview_pb1176.c +15 -0
@@ -31,6 +31,7 @@#include <asm/irq.h> #include <asm/leds.h> #include <asm/mach-types.h> +#include <asm/pmu.h> #include <asm/hardware/gic.h> #include <asm/hardware/icst307.h> #include <asm/hardware/cache-l2x0.h>
@@ -263,6 +264,19 @@ static struct resource realview_pb1176_isp1761_resources[] = { }, }; +static struct resource pmu_resource = { + .start =IRQ_DC1176_PMU_CPU0 , + .end =IRQ_DC1176_PMU_CPU0 , + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .num_resources =1 , + .resource = &pmu_resource, +}; +static void __init gic_init_irq (void ) {/* ARM1176 DevChip GIC, primary */
@@ -324,6 +338,7 @@ static void __init realview_pb1176_init(void)realview_eth_register (NULL , realview_pb1176_smsc911x_resources);platform_device_register (&realview_i2c_device);realview_usb_register (realview_pb1176_isp1761_resources); +platform_device_register (&pmu_device);for (i =0 ; i <ARRAY_SIZE (amba_devs); i++) {struct amba_device *d = amba_devs[i];
arch/arm/mach-realview/realview_pb11mp.c +32 -0
@@ -31,6 +31,7 @@#include <asm/irq.h> #include <asm/leds.h> #include <asm/mach-types.h> +#include <asm/pmu.h> #include <asm/hardware/gic.h> #include <asm/hardware/icst307.h> #include <asm/hardware/cache-l2x0.h>
@@ -260,6 +261,36 @@ static struct resource realview_pb11mp_isp1761_resources[] = { }, }; +static struct resource pmu_resources[] = { + [0 ] = { + .start =IRQ_TC11MP_PMU_CPU0 , + .end =IRQ_TC11MP_PMU_CPU0 , + .flags =IORESOURCE_IRQ , + }, + [1 ] = { + .start =IRQ_TC11MP_PMU_CPU1 , + .end =IRQ_TC11MP_PMU_CPU1 , + .flags =IORESOURCE_IRQ , + }, + [2 ] = { + .start =IRQ_TC11MP_PMU_CPU2 , + .end =IRQ_TC11MP_PMU_CPU2 , + .flags =IORESOURCE_IRQ , + }, + [3 ] = { + .start =IRQ_TC11MP_PMU_CPU3 , + .end =IRQ_TC11MP_PMU_CPU3 , + .flags =IORESOURCE_IRQ , + }, +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .num_resources =ARRAY_SIZE (pmu_resources), + .resource = pmu_resources, +}; +static void __init gic_init_irq (void ) {unsigned int pldctrl;
@@ -329,6 +360,7 @@ static void __init realview_pb11mp_init(void)platform_device_register (&realview_i2c_device);platform_device_register (&realview_cf_device);realview_usb_register (realview_pb11mp_isp1761_resources); +platform_device_register (&pmu_device);for (i =0 ; i <ARRAY_SIZE (amba_devs); i++) {struct amba_device *d = amba_devs[i];
arch/arm/mach-realview/realview_pba8.c +15 -0
@@ -30,6 +30,7 @@#include <asm/irq.h> #include <asm/leds.h> #include <asm/mach-types.h> +#include <asm/pmu.h> #include <asm/hardware/gic.h> #include <asm/hardware/icst307.h>
@@ -250,6 +251,19 @@ static struct resource realview_pba8_isp1761_resources[] = { }, }; +static struct resource pmu_resource = { + .start =IRQ_PBA8_PMU , + .end =IRQ_PBA8_PMU , + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .num_resources =1 , + .resource = &pmu_resource, +}; +static void __init gic_init_irq (void ) {/* ARM PB-A8 on-board GIC */
@@ -296,6 +310,7 @@ static void __init realview_pba8_init(void)platform_device_register (&realview_i2c_device);platform_device_register (&realview_cf_device);realview_usb_register (realview_pba8_isp1761_resources); +platform_device_register (&pmu_device);for (i =0 ; i <ARRAY_SIZE (amba_devs); i++) {struct amba_device *d = amba_devs[i];
arch/arm/mach-realview/realview_pbx.c +32 -0
@@ -29,6 +29,7 @@#include <asm/irq.h> #include <asm/leds.h> #include <asm/mach-types.h> +#include <asm/pmu.h> #include <asm/smp_twd.h> #include <asm/hardware/gic.h> #include <asm/hardware/cache-l2x0.h>
@@ -270,6 +271,36 @@ static struct resource realview_pbx_isp1761_resources[] = { }, }; +static struct resource pmu_resources[] = { + [0 ] = { + .start =IRQ_PBX_PMU_CPU0 , + .end =IRQ_PBX_PMU_CPU0 , + .flags =IORESOURCE_IRQ , + }, + [1 ] = { + .start =IRQ_PBX_PMU_CPU1 , + .end =IRQ_PBX_PMU_CPU1 , + .flags =IORESOURCE_IRQ , + }, + [2 ] = { + .start =IRQ_PBX_PMU_CPU2 , + .end =IRQ_PBX_PMU_CPU2 , + .flags =IORESOURCE_IRQ , + }, + [3 ] = { + .start =IRQ_PBX_PMU_CPU3 , + .end =IRQ_PBX_PMU_CPU3 , + .flags =IORESOURCE_IRQ , + }, +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .num_resources =ARRAY_SIZE (pmu_resources), + .resource = pmu_resources, +}; +static void __init gic_init_irq (void ) {/* ARM PBX on-board GIC */
@@ -354,6 +385,7 @@ static void __init realview_pbx_init(void)/* 16KB way size, 8-way associativity, parity disabled * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */ l2x0_init (l2x0_base,0x02520000 ,0xc0000fff ); + platform_device_register(&pmu_device); }#endif
Signature · 1 line
1.6.3.3
PATCH 3/6 ARM: OMAP: register PMU IRQs during board initialisation
This patch updates the initialisation routines for the OMAP2 and OMAP3 boards so that they register their PMU IRQs with the PMU framework in the Kernel.
--- arch/arm/mach-omap2/devices.c | 34 ++++++++++++++++++++++++++++++++++ 1 files changed, 34 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/devices.c +34 -0
@@ -17,8 +17,10 @@#include <linux/clk.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/map.h> +#include <asm/pmu.h> #include <plat/control.h> #include <plat/tc.h>
@@ -453,6 +455,37 @@ static void omap_init_mcspi(void)static inline void omap_init_mcspi (void ) {}#endif +static struct resource omap2_pmu_resource = { + .start =3 , + .end =3 , + .flags =IORESOURCE_IRQ , +}; + +static struct resource omap3_pmu_resource = { + .start =INT_34XX_BENCH_MPU_EMUL , + .end =INT_34XX_BENCH_MPU_EMUL , + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device omap_pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .num_resources =1 , +}; + +static void omap_init_pmu (void ) +{ +if (cpu_is_omap24xx ()) + omap_pmu_device.resource = &omap2_pmu_resource; +else if (cpu_is_omap34xx ()) + omap_pmu_device.resource = &omap3_pmu_resource; +else +return ; + +platform_device_register (&omap_pmu_device); +} + + #ifdef CONFIG_OMAP_SHA1_MD5 static struct resource sha1_md5_resources[] = { {
@@ -797,6 +830,7 @@ static int __init omap2_init_devices(void)omap_init_camera ();omap_init_mbox ();omap_init_mcspi (); +omap_init_pmu ();omap_hdq_init ();omap_init_sti ();omap_init_sha1_md5 ();
Signature · 1 line
1.6.3.3
PATCH 4/6 ARM: BCMRING: register PMU IRQ during board initialisation
This patch updates the initialisation routine for the BCMRING platform so that it registers its PMU IRQ with the PMU framework in the Kernel.
--- arch/arm/mach-bcmring/arch.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/mach-bcmring/arch.c +16 -0
@@ -29,6 +29,7 @@#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>
@@ -85,8 +86,23 @@ static struct platform_device nand_device = { .num_resources = ARRAY_SIZE(nand_resource), }; +static struct resource pmu_resource = { + .start =IRQ_PMUIRQ , + .end =IRQ_PMUIRQ , + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .resource = &pmu_resource, + .num_resources =1 , +}; + +static struct platform_device *devices[]__initdata = { &nand_device, + &pmu_device, };/****************************************************************************
Signature · 1 line
1.6.3.3
PATCH 5/6 ARM: iop3xx: register PMU IRQs during board initialisation
This patch adds an initcall for the iop3xx platforms so that they register their PMU IRQS with the PMU framework in the Kernel.
--- arch/arm/plat-iop/Makefile | 2 ++ arch/arm/plat-iop/pmu.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 0 deletions(-) create mode 100644 arch/arm/plat-iop/pmu.c
arch/arm/plat-iop/Makefile +2 -0
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IOP32X) += time.o obj-$(CONFIG_ARCH_IOP32X) += io.o obj-$(CONFIG_ARCH_IOP32X) += cp6.o obj-$(CONFIG_ARCH_IOP32X) += adma.o +obj-$(CONFIG_ARCH_IOP32X) += pmu.o # IOP33X obj-$(CONFIG_ARCH_IOP33X) += gpio.o
@@ -23,6 +24,7 @@ obj-$(CONFIG_ARCH_IOP33X) += time.o obj-$(CONFIG_ARCH_IOP33X) += io.o obj-$(CONFIG_ARCH_IOP33X) += cp6.o obj-$(CONFIG_ARCH_IOP33X) += adma.o +obj-$(CONFIG_ARCH_IOP33X) += pmu.o # IOP13XX obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
arch/arm/plat-iop/pmu.c new file +40 -0
@@ -0,0 +1,40 @@ +/* +* PMU IRQ registration for the iop3xx xscale PMU families. +* Copyright (C) 2010 Will Deacon, ARM Ltd. +* +* 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/platform_device.h> +#include <asm/pmu.h> +#include <mach/irqs.h> + +static struct resource pmu_resource = { +#ifdef CONFIG_ARCH_IOP32X + .start =IRQ_IOP32X_CORE_PMU , + .end =IRQ_IOP32X_CORE_PMU , +#endif +#ifdef CONFIG_ARCH_IOP33X + .start =IRQ_IOP33X_CORE_PMU , + .end =IRQ_IOP33X_CORE_PMU , +#endif + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .resource = &pmu_resource, + .num_resources =1 , +}; + +static int __init iop3xx_pmu_init (void ) +{ +platform_device_register (&pmu_device); +return 0 ; +} + +arch_initcall (iop3xx_pmu_init);
Signature · 1 line
1.6.3.3
PATCH 6/6 ARM: pxa: register PMU IRQs during board initialisation
This patch adds an initcall for the pxa platforms so that they register their PMU IRQs with the PMU framework in the Kernel.
--- arch/arm/plat-pxa/Makefile | 2 +- arch/arm/plat-pxa/pmu.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletions(-) create mode 100644 arch/arm/plat-pxa/pmu.c
arch/arm/plat-pxa/Makefile +1 -1
@@ -2,7 +2,7 @@ # Makefile for code common across different PXA processor families # -obj-y := dma.o +obj-y := dma.o pmu.o obj-$(CONFIG_GENERIC_GPIO) += gpio.o obj-$(CONFIG_PXA3xx) += mfp.o
arch/arm/plat-pxa/pmu.c new file +33 -0
@@ -0,0 +1,33 @@ +/* +* PMU IRQ registration for the PXA xscale PMU families. +* Copyright (C) 2010 Will Deacon, ARM Ltd. +* +* 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/platform_device.h> +#include <asm/pmu.h> +#include <mach/irqs.h> + +static struct resource pmu_resource = { + .start =IRQ_PMU , + .end =IRQ_PMU , + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .resource = &pmu_resource, + .num_resources =1 , +}; + +static int __init pxa_pmu_init (void ) +{ +platform_device_register (&pmu_device); +return 0 ; +} +arch_initcall (pxa_pmu_init);
Signature · 1 line
1.6.3.3
PATCH 4/6 ARM: BCMRING: register PMU IRQ during board initialisation
In reply to Will DeaconThanks Will.
I like this version using the platform device.
Quoted 49 lines · Will Deacon
This patch updates the initialisation routine for the BCMRING platform so that it registers its PMU IRQ with the PMU framework in the Kernel.
Cc Leo Chen <[email protected]>Signed-off-by Will Deacon <[email protected]>--- arch/arm/mach-bcmring/arch.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-)arch/arm/mach-bcmring/arch.c +16
-0@@ -29,6 +29,7 @@#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> @@ -85,8 +86,23 @@ static struct platform_device nand_device = { .num_resources = ARRAY_SIZE(nand_resource), }; +static struct resource pmu_resource = { + .start =IRQ_PMUIRQ , + .end =IRQ_PMUIRQ , + .flags =IORESOURCE_IRQ , +}; + +static struct platform_device pmu_device = { + .name ="arm-pmu" , + .id =ARM_PMU_DEVICE_CPU , + .resource = &pmu_resource, + .num_resources =1 , +}; + +static struct platform_device *devices[]__initdata = { &nand_device, + &pmu_device, };/**************************************************************************** Signature · 1 line
1.6.3.3
Signature · 4 lines
Leo Hao Chen ------------------------ Life is short, run long.
PATCH 1/6 ARM: pmu: register IRQs at runtime
In reply to Will DeaconQuoted 15 lines · Will Deacon
The current PMU infrastructure for ARM requires that the IRQs for the PMU device are fixed at compile time and are selected based on the
ARCH_orMACH_flags. This has the disadvantage of tying the Kernel down to a particular board as far as profiling is concerned.This patch replaces the compile-time IRQ registration with a runtime mechanism which allows the IRQs to be registered with the framework as a
platform_device.A further advantage of this change is that there is scope for registering different types of performance counters in the future by changing the id of the
platform_deviceand attaching different resources to it.Cc Russell King - ARM Linux <[email protected]>Cc Jamie Iles <[email protected]>Signed-off-by Will Deacon <[email protected]>
[snip]
Quoted 7 lines
arch/arm/kernel/perf_event.c +3
-2-for (i =0 ; i < pmu_irqs->num_irqs; ++i) { - err =request_irq (pmu_irqs->irqs[i], armpmu->handle_irq, +for (i =0 ; i < pmu_device->num_resources; ++i) { + err =request_irq (platform_get_irq (pmu_device, i), + armpmu->handle_irq,IRQF_DISABLED |IRQF_NOBALANCING ,"armpmu" ,NULL );
[snip]
arch/arm/kernel/perf_event.c armpmu_release_hardware(void) · line 362
Quoted 8 lines
arch/arm/kernel/perf_event.c +2
-2@@ -356,12 +358,12 @@ armpmu_release_hardware(void) {int i; -for (i = pmu_irqs->num_irqs -1 ; i >=0 ; --i) -free_irq (pmu_irqs->irqs[i],NULL ); +for (i = pmu_device->num_resources -1 ; i >=0 ; --i) +free_irq (platform_get_irq (pmu_device, i),NULL );
Hi Will,
This looks fine at the moment as all PMU's only have IRQ resources but if we ever have any with memory resources then we'll need to check the return value of platform_get_irq() to make sure that the resource is a valid IRQ. Apologies for not spotting it before! If we had:
int irq = platform_get_irq(pmu_device, i); if (irq < 0) continue;
or something similar to be a bit future proof then I'm happy with that and:
Jamie
cover ARM: pmu: provide a registration mechanism for IRQs [v3]
In reply to Will DeaconQuoted 4 lines · Will Deacon
This is version 3 of the patch series originally posted here:
v1: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-March/011162.html
v2: http://lists.infradead.org/pipermail/linux-arm-kernel/2010-March/011339.html
Unfortunately, these patches are inter-dependent - if I apply the realview patch to my 'versatile' branch without the first patch, then it breaks the realview build because ARM_PMU_DEVICE_CPU is not defined.
But if I apply the first patch initially, everything using the new PMU infrastructure breaks until the other patches are applied.
Please can we have an ordered set which doesn't break compilation. What I think should happen is the first patch should introduce the new definitions required for the platform data, and the rest of the first patch should come at the very end.
Thanks.
cover ARM: pmu: provide a registration mechanism for IRQs [v3]
Hi Russell,
Quoted 4 lines
Please can we have an ordered set which doesn't break compilation. What I think should happen is the first patch should introduce the new definitions required for the platform data, and the rest of the first patch should come at the very end.
Sorry about this. I've split up the first patch so that the first half is now:
ARM: pmu: add enum describing PMU types
This patch adds an enum describing the potential PMU device types in preparation for PMU device registration via platform devices.
arch/arm/include/asm/pmu.h +5 -0
@@ -12,6 +12,11 @@#ifndef __ARM_PMU_H__#define __ARM_PMU_H__ +enum arm_pmu_type { +ARM_PMU_DEVICE_CPU =0 , +ARM_NUM_PMU_DEVICES , +}; +#ifdef CONFIG_CPU_HAS_PMU struct pmu_irqs {
which gets rid of the compilation failures. I can either supersede the existing patch with two more or resubmit the whole series. Which would you prefer?
Thanks,
Will
cover ARM: pmu: provide a registration mechanism for IRQs [v3]
Quoted 34 lines · Will Deacon
Hi Russell,
Quoted 4 lines
Please can we have an ordered set which doesn't break compilation. What I think should happen is the first patch should introduce the new definitions required for the platform data, and the rest of the first patch should come at the very end.
Sorry about this. I've split up the first patch so that the first half is now:
ARM: pmu: add enum describing PMU types
This patch adds an enum describing the potential PMU device types in preparation for PMU device registration via platform devices.
arch/arm/include/asm/pmu.h +5
-0@@ -12,6 +12,11 @@#ifndef __ARM_PMU_H__#define __ARM_PMU_H__ +enum arm_pmu_type { +ARM_PMU_DEVICE_CPU =0 , +ARM_NUM_PMU_DEVICES , +}; +#ifdef CONFIG_CPU_HAS_PMU struct pmu_irqs {
Quoted 3 lines
which gets rid of the compilation failures. I can either supersede the existing patch with two more or resubmit the whole series. Which would you prefer?
Can you just deal with the single patch to be superseded; the rest are fine.
cover ARM: pmu: provide a registration mechanism for IRQs [v3]
Hello Russell,
Quoted 2 lines
Can you just deal with the single patch to be superseded; the rest are fine.
I've submitted the replacement patches as 6063/1 and 6064/1.
Thanks,
Will