Loading arch/arm/include/asm/pmu.h +14 −0 Original line number Diff line number Diff line Loading @@ -12,11 +12,25 @@ #ifndef __ARM_PMU_H__ #define __ARM_PMU_H__ #include <linux/interrupt.h> enum arm_pmu_type { ARM_PMU_DEVICE_CPU = 0, ARM_NUM_PMU_DEVICES, }; /* * struct arm_pmu_platdata - ARM PMU platform data * * @handle_irq: an optional handler which will be called from the interrupt and * passed the address of the low level handler, and can be used to implement * any platform specific handling before or after calling it. */ struct arm_pmu_platdata { irqreturn_t (*handle_irq)(int irq, void *dev, irq_handler_t pmu_handler); }; #ifdef CONFIG_CPU_HAS_PMU /** Loading arch/arm/kernel/perf_event.c +16 −1 Original line number Diff line number Diff line Loading @@ -377,9 +377,18 @@ validate_group(struct perf_event *event) return 0; } static irqreturn_t armpmu_platform_irq(int irq, void *dev) { struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev); return plat->handle_irq(irq, dev, armpmu->handle_irq); } static int armpmu_reserve_hardware(void) { struct arm_pmu_platdata *plat; irq_handler_t handle_irq; int i, err = -ENODEV, irq; pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); Loading @@ -390,6 +399,12 @@ armpmu_reserve_hardware(void) init_pmu(ARM_PMU_DEVICE_CPU); plat = dev_get_platdata(&pmu_device->dev); if (plat && plat->handle_irq) handle_irq = armpmu_platform_irq; else handle_irq = armpmu->handle_irq; if (pmu_device->num_resources < 1) { pr_err("no irqs for PMUs defined\n"); return -ENODEV; Loading @@ -400,7 +415,7 @@ armpmu_reserve_hardware(void) if (irq < 0) continue; err = request_irq(irq, armpmu->handle_irq, err = request_irq(irq, handle_irq, IRQF_DISABLED | IRQF_NOBALANCING, "armpmu", NULL); if (err) { Loading arch/arm/mach-ux500/cpu-db8500.c +47 −4 Original line number Diff line number Diff line Loading @@ -12,22 +12,20 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/amba/bus.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/io.h> #include <asm/mach/map.h> #include <asm/pmu.h> #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> #include "devices-db8500.h" static struct platform_device *platform_devs[] __initdata = { &u8500_dma40_device, }; /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_uart_io_desc[] __initdata = { __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), Loading Loading @@ -89,6 +87,51 @@ void __init u8500_map_io(void) iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); } static struct resource db8500_pmu_resources[] = { [0] = { .start = IRQ_DB8500_PMU, .end = IRQ_DB8500_PMU, .flags = IORESOURCE_IRQ, }, }; /* * The PMU IRQ lines of two cores are wired together into a single interrupt. * Bounce the interrupt to the other core if it's not ours. */ static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler) { irqreturn_t ret = handler(irq, dev); int other = !smp_processor_id(); if (ret == IRQ_NONE && cpu_online(other)) irq_set_affinity(irq, cpumask_of(other)); /* * We should be able to get away with the amount of IRQ_NONEs we give, * while still having the spurious IRQ detection code kick in if the * interrupt really starts hitting spuriously. */ return ret; } static struct arm_pmu_platdata db8500_pmu_platdata = { .handle_irq = db8500_pmu_handler, }; static struct platform_device db8500_pmu_device = { .name = "arm-pmu", .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(db8500_pmu_resources), .resource = db8500_pmu_resources, .dev.platform_data = &db8500_pmu_platdata, }; static struct platform_device *platform_devs[] __initdata = { &u8500_dma40_device, &db8500_pmu_device, }; static resource_size_t __initdata db8500_gpio_base[] = { U8500_GPIOBANK0_BASE, U8500_GPIOBANK1_BASE, Loading Loading
arch/arm/include/asm/pmu.h +14 −0 Original line number Diff line number Diff line Loading @@ -12,11 +12,25 @@ #ifndef __ARM_PMU_H__ #define __ARM_PMU_H__ #include <linux/interrupt.h> enum arm_pmu_type { ARM_PMU_DEVICE_CPU = 0, ARM_NUM_PMU_DEVICES, }; /* * struct arm_pmu_platdata - ARM PMU platform data * * @handle_irq: an optional handler which will be called from the interrupt and * passed the address of the low level handler, and can be used to implement * any platform specific handling before or after calling it. */ struct arm_pmu_platdata { irqreturn_t (*handle_irq)(int irq, void *dev, irq_handler_t pmu_handler); }; #ifdef CONFIG_CPU_HAS_PMU /** Loading
arch/arm/kernel/perf_event.c +16 −1 Original line number Diff line number Diff line Loading @@ -377,9 +377,18 @@ validate_group(struct perf_event *event) return 0; } static irqreturn_t armpmu_platform_irq(int irq, void *dev) { struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev); return plat->handle_irq(irq, dev, armpmu->handle_irq); } static int armpmu_reserve_hardware(void) { struct arm_pmu_platdata *plat; irq_handler_t handle_irq; int i, err = -ENODEV, irq; pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); Loading @@ -390,6 +399,12 @@ armpmu_reserve_hardware(void) init_pmu(ARM_PMU_DEVICE_CPU); plat = dev_get_platdata(&pmu_device->dev); if (plat && plat->handle_irq) handle_irq = armpmu_platform_irq; else handle_irq = armpmu->handle_irq; if (pmu_device->num_resources < 1) { pr_err("no irqs for PMUs defined\n"); return -ENODEV; Loading @@ -400,7 +415,7 @@ armpmu_reserve_hardware(void) if (irq < 0) continue; err = request_irq(irq, armpmu->handle_irq, err = request_irq(irq, handle_irq, IRQF_DISABLED | IRQF_NOBALANCING, "armpmu", NULL); if (err) { Loading
arch/arm/mach-ux500/cpu-db8500.c +47 −4 Original line number Diff line number Diff line Loading @@ -12,22 +12,20 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/amba/bus.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/io.h> #include <asm/mach/map.h> #include <asm/pmu.h> #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> #include "devices-db8500.h" static struct platform_device *platform_devs[] __initdata = { &u8500_dma40_device, }; /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_uart_io_desc[] __initdata = { __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), Loading Loading @@ -89,6 +87,51 @@ void __init u8500_map_io(void) iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); } static struct resource db8500_pmu_resources[] = { [0] = { .start = IRQ_DB8500_PMU, .end = IRQ_DB8500_PMU, .flags = IORESOURCE_IRQ, }, }; /* * The PMU IRQ lines of two cores are wired together into a single interrupt. * Bounce the interrupt to the other core if it's not ours. */ static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler) { irqreturn_t ret = handler(irq, dev); int other = !smp_processor_id(); if (ret == IRQ_NONE && cpu_online(other)) irq_set_affinity(irq, cpumask_of(other)); /* * We should be able to get away with the amount of IRQ_NONEs we give, * while still having the spurious IRQ detection code kick in if the * interrupt really starts hitting spuriously. */ return ret; } static struct arm_pmu_platdata db8500_pmu_platdata = { .handle_irq = db8500_pmu_handler, }; static struct platform_device db8500_pmu_device = { .name = "arm-pmu", .id = ARM_PMU_DEVICE_CPU, .num_resources = ARRAY_SIZE(db8500_pmu_resources), .resource = db8500_pmu_resources, .dev.platform_data = &db8500_pmu_platdata, }; static struct platform_device *platform_devs[] __initdata = { &u8500_dma40_device, &db8500_pmu_device, }; static resource_size_t __initdata db8500_gpio_base[] = { U8500_GPIOBANK0_BASE, U8500_GPIOBANK1_BASE, Loading