mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00:00
arm: pmu: allow platform specific irq enable/disable handling
This patch introduces .enable_irq and .disable_irq into struct arm_pmu_platdata, so platform specific irq enablement can be handled after request_irq, and platform specific irq disablement can be handled before free_irq. This patch is for support of pmu irq routed from CTI on omap4. Acked-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Ming Lei <ming.lei@canonical.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
14eec97ff4
commit
e0516a64e7
2 changed files with 20 additions and 5 deletions
|
@ -27,13 +27,22 @@ enum arm_pmu_type {
|
||||||
/*
|
/*
|
||||||
* struct arm_pmu_platdata - ARM PMU platform data
|
* struct arm_pmu_platdata - ARM PMU platform data
|
||||||
*
|
*
|
||||||
* @handle_irq: an optional handler which will be called from the interrupt and
|
* @handle_irq: an optional handler which will be called from the
|
||||||
* passed the address of the low level handler, and can be used to implement
|
* interrupt and passed the address of the low level handler,
|
||||||
* any platform specific handling before or after calling it.
|
* and can be used to implement any platform specific handling
|
||||||
|
* before or after calling it.
|
||||||
|
* @enable_irq: an optional handler which will be called after
|
||||||
|
* request_irq and be used to handle some platform specific
|
||||||
|
* irq enablement
|
||||||
|
* @disable_irq: an optional handler which will be called before
|
||||||
|
* free_irq and be used to handle some platform specific
|
||||||
|
* irq disablement
|
||||||
*/
|
*/
|
||||||
struct arm_pmu_platdata {
|
struct arm_pmu_platdata {
|
||||||
irqreturn_t (*handle_irq)(int irq, void *dev,
|
irqreturn_t (*handle_irq)(int irq, void *dev,
|
||||||
irq_handler_t pmu_handler);
|
irq_handler_t pmu_handler);
|
||||||
|
void (*enable_irq)(int irq);
|
||||||
|
void (*disable_irq)(int irq);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_HAS_PMU
|
#ifdef CONFIG_CPU_HAS_PMU
|
||||||
|
|
|
@ -380,6 +380,8 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
|
||||||
{
|
{
|
||||||
int i, irq, irqs;
|
int i, irq, irqs;
|
||||||
struct platform_device *pmu_device = armpmu->plat_device;
|
struct platform_device *pmu_device = armpmu->plat_device;
|
||||||
|
struct arm_pmu_platdata *plat =
|
||||||
|
dev_get_platdata(&pmu_device->dev);
|
||||||
|
|
||||||
irqs = min(pmu_device->num_resources, num_possible_cpus());
|
irqs = min(pmu_device->num_resources, num_possible_cpus());
|
||||||
|
|
||||||
|
@ -387,8 +389,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
|
||||||
if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
|
if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
|
||||||
continue;
|
continue;
|
||||||
irq = platform_get_irq(pmu_device, i);
|
irq = platform_get_irq(pmu_device, i);
|
||||||
if (irq >= 0)
|
if (irq >= 0) {
|
||||||
|
if (plat && plat->disable_irq)
|
||||||
|
plat->disable_irq(irq);
|
||||||
free_irq(irq, armpmu);
|
free_irq(irq, armpmu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_pmu(armpmu->type);
|
release_pmu(armpmu->type);
|
||||||
|
@ -448,7 +453,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
|
||||||
irq);
|
irq);
|
||||||
armpmu_release_hardware(armpmu);
|
armpmu_release_hardware(armpmu);
|
||||||
return err;
|
return err;
|
||||||
}
|
} else if (plat && plat->enable_irq)
|
||||||
|
plat->enable_irq(irq);
|
||||||
|
|
||||||
cpumask_set_cpu(i, &armpmu->active_irqs);
|
cpumask_set_cpu(i, &armpmu->active_irqs);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue