Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 191834
b: refs/heads/master
c: 49c006b
h: refs/heads/master
v: v3
  • Loading branch information
Will Deacon authored and Russell King committed May 17, 2010
1 parent 2e5ffae commit d1b2fa1
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 82 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: 98830bc9967b18d6f9a614a1f354f5580196ef85
refs/heads/master: 49c006b93769a86bec2b32b9234abf016ac0d50e
22 changes: 21 additions & 1 deletion trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ config ARCH_VEXPRESS

config ARCH_AT91
bool "Atmel AT91"
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select ARCH_USES_GETTIMEOFFSET
Expand Down Expand Up @@ -325,6 +326,7 @@ config ARCH_CLPS711X
config ARCH_GEMINI
bool "Cortina Systems Gemini"
select CPU_FA526
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
help
Expand All @@ -347,6 +349,7 @@ config ARCH_EP93XX
select CPU_ARM920T
select ARM_AMBA
select ARM_VIC
select GENERIC_GPIO
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_HOLES_MEMORYMODEL
Expand Down Expand Up @@ -379,6 +382,7 @@ config ARCH_STMP3XXX
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select USB_ARCH_HAS_EHCI
help
Support for systems based on the Freescale 3xxx CPUs.
Expand Down Expand Up @@ -417,6 +421,7 @@ config ARCH_IOP32X
select CPU_XSCALE
select PLAT_IOP
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
Support for Intel's 80219 and IOP32X (XScale) family of
Expand All @@ -428,6 +433,7 @@ config ARCH_IOP33X
select CPU_XSCALE
select PLAT_IOP
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
Support for Intel's IOP33X (XScale) family of processors.
Expand Down Expand Up @@ -479,6 +485,7 @@ config ARCH_L7200
config ARCH_DOVE
bool "Marvell Dove"
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
Expand All @@ -490,6 +497,7 @@ config ARCH_KIRKWOOD
bool "Marvell Kirkwood"
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
Expand All @@ -511,6 +519,7 @@ config ARCH_MV78XX0
bool "Marvell MV78xx0"
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
Expand All @@ -524,6 +533,7 @@ config ARCH_ORION5X
depends on MMU
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
Expand All @@ -536,6 +546,7 @@ config ARCH_ORION5X
config ARCH_MMP
bool "Marvell PXA168/910/MMP2"
depends on MMU
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select COMMON_CLKDEV
select GENERIC_TIME
Expand All @@ -548,7 +559,8 @@ config ARCH_MMP
config ARCH_KS8695
bool "Micrel/Kendin KS8695"
select CPU_ARM922T
select ARCH_REQUIRE_GPIOLIB
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
help
Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
Expand All @@ -571,6 +583,7 @@ config ARCH_W90X900
bool "Nuvoton W90X900 CPU"
select CPU_ARM926T
select ARCH_REQUIRE_GPIOLIB
select GENERIC_GPIO
select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
Expand Down Expand Up @@ -604,6 +617,7 @@ config ARCH_PXA
depends on MMU
select ARCH_MTD_XIP
select ARCH_HAS_CPUFREQ
select GENERIC_GPIO
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
Expand Down Expand Up @@ -652,6 +666,7 @@ config ARCH_SA1100
select ARCH_MTD_XIP
select ARCH_HAS_CPUFREQ
select CPU_FREQ
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select HAVE_CLK
Expand All @@ -675,6 +690,7 @@ config ARCH_S3C64XX
bool "Samsung S3C64XX"
select PLAT_SAMSUNG
select CPU_V6
select GENERIC_GPIO
select ARM_VIC
select HAVE_CLK
select NO_IOPORT
Expand Down Expand Up @@ -785,6 +801,7 @@ config ARCH_NOMADIK
select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
Support for the Nomadik platform by ST-Ericsson
Expand All @@ -794,6 +811,7 @@ config ARCH_DAVINCI
select CPU_ARM926T
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select ZONE_DMA
select HAVE_IDE
Expand All @@ -805,6 +823,7 @@ config ARCH_DAVINCI

config ARCH_OMAP
bool "TI OMAP"
select GENERIC_GPIO
select HAVE_CLK
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
Expand All @@ -820,6 +839,7 @@ config PLAT_SPEAR
select ARCH_REQUIRE_GPIOLIB
select COMMON_CLKDEV
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select GENERIC_TIME
select HAVE_CLK
help
Expand Down
27 changes: 12 additions & 15 deletions trunk/arch/arm/include/asm/pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,26 @@ enum arm_pmu_type {

#ifdef CONFIG_CPU_HAS_PMU

struct pmu_irqs {
const int *irqs;
int num_irqs;
};

/**
* 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.
Expand All @@ -53,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;
}
Expand Down
52 changes: 31 additions & 21 deletions trunk/arch/arm/kernel/perf_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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
Expand Down Expand Up @@ -314,38 +315,44 @@ validate_group(struct perf_event *event)
static int
armpmu_reserve_hardware(void)
{
int i;
int err;
int i, err = -ENODEV, irq;

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) {
irq = platform_get_irq(pmu_device, i);
if (irq < 0)
continue;

err = request_irq(irq, 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", irq);
break;
}
}

if (err) {
for (i = i - 1; i >= 0; --i)
free_irq(pmu_irqs->irqs[i], NULL);
release_pmu(pmu_irqs);
pmu_irqs = NULL;
for (i = i - 1; i >= 0; --i) {
irq = platform_get_irq(pmu_device, i);
if (irq >= 0)
free_irq(irq, NULL);
}
release_pmu(pmu_device);
pmu_device = NULL;
}

return err;
Expand All @@ -354,14 +361,17 @@ armpmu_reserve_hardware(void)
static void
armpmu_release_hardware(void)
{
int i;
int i, irq;

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) {
irq = platform_get_irq(pmu_device, i);
if (irq >= 0)
free_irq(irq, 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);
Expand Down
Loading

0 comments on commit d1b2fa1

Please sign in to comment.