From: jon-hunter@ti.com (Jon Hunter)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V2 01/10] ARM: PMU: Add runtime PM Support
Date: Fri, 8 Jun 2012 10:24:32 -0500 [thread overview]
Message-ID: <4FD21930.4000800@ti.com> (raw)
In-Reply-To: <20120608094708.GC19062@mudshark.cambridge.arm.com>
Hi Will,
On 06/08/2012 04:47 AM, Will Deacon wrote:
> Hi Jon,
>
> On Thu, Jun 07, 2012 at 10:22:03PM +0100, Jon Hunter wrote:
>> diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
>> index 186c8cb..00adb98 100644
>> --- a/arch/arm/kernel/perf_event.c
>> +++ b/arch/arm/kernel/perf_event.c
>> @@ -20,6 +20,7 @@
>> #include <linux/platform_device.h>
>> #include <linux/spinlock.h>
>> #include <linux/uaccess.h>
>> +#include <linux/pm_runtime.h>
>>
>> #include <asm/cputype.h>
>> #include <asm/irq.h>
>> @@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>> {
>> int i, irq, irqs;
>> 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());
>>
>> @@ -376,14 +375,12 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
>> if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
>> continue;
>> irq = platform_get_irq(pmu_device, i);
>> - if (irq >= 0) {
>> - if (plat && plat->disable_irq)
>> - plat->disable_irq(irq);
>> + if (irq >= 0)
>> free_irq(irq, armpmu);
>> - }
>> }
>>
>> release_pmu(armpmu->type);
>> + pm_runtime_put_sync(&armpmu->plat_device->dev);
>
> We probably want to suspend the device before releasing it, otherwise we
> could race against somebody else trying to initialise the PMU again.
>
>>
>> static int
>> @@ -403,6 +400,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>> return err;
>> }
>>
>> + pm_runtime_get_sync(&armpmu->plat_device->dev);
>
> Better pass &pmu_device->dev instead (similarly in release).
>
>> +
>> plat = dev_get_platdata(&pmu_device->dev);
>> if (plat && plat->handle_irq)
>> handle_irq = armpmu_platform_irq;
>> @@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
>> irq);
>> armpmu_release_hardware(armpmu);
>> return err;
>> - } else if (plat && plat->enable_irq)
>> - plat->enable_irq(irq);
>> + }
>>
>> cpumask_set_cpu(i, &armpmu->active_irqs);
>> }
>> @@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
>> armpmu->stop();
>> }
>
> There are potential failure paths in the reservation code here where we
> don't `put' the PMU back. Can you move the pm_runtime_get_sync call later in
> the function, or does it have to called before we enable the IRQ line?
>
>> +#ifdef CONFIG_PM_RUNTIME
>> +static int armpmu_runtime_resume(struct device *dev)
>> +{
>> + struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> + if (plat->runtime_resume)
>
> I think you need to check plat too since it may be NULL on other platforms.
>
>> + return plat->runtime_resume(dev);
>> +
>> + return 0;
>> +}
>> +
>> +static int armpmu_runtime_suspend(struct device *dev)
>> +{
>> + struct arm_pmu_platdata *plat = dev_get_platdata(dev);
>> +
>> + if (plat->runtime_suspend)
>
> Same here.
Here is an updated version. I was going to send out a V3, but I wanted
to wait to see if others had more comments first.
Cheers
Jon
>From c53dcbe091928d293f14e890c2b38be57692ccca Mon Sep 17 00:00:00 2001
From: Jon Hunter <jon-hunter@ti.com>
Date: Thu, 31 May 2012 13:05:20 -0500
Subject: [PATCH] ARM: PMU: Add runtime PM Support
Add runtime PM support to the ARM PMU driver so that devices such as OMAP
supporting dynamic PM can use the platform->runtime_* hooks to initialise
hardware at runtime. Without having these runtime PM hooks in place any
configuration of the PMU hardware would be lost when low power states are
entered and hence would prevent PMU from working.
This change also replaces the PMU platform functions enable_irq and disable_irq
added by Ming Lei with runtime_resume and runtime_suspend funtions. Ming had
added the enable_irq and disable_irq functions as a method to configure the
cross trigger interface on OMAP4 for routing the PMU interrupts. By adding
runtime PM support, we can move the code called by enable_irq and disable_irq
into the runtime PM callbacks runtime_resume and runtime_suspend.
Cc: Ming Lei <ming.lei@canonical.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
arch/arm/include/asm/pmu.h | 20 ++++++++++++--------
arch/arm/kernel/perf_event.c | 41 +++++++++++++++++++++++++++++++++--------
2 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 90114fa..77b023b 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -31,18 +31,22 @@ enum arm_pmu_type {
* 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.
- * @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
+ * @runtime_resume: an optional handler which will be called by the
+ * runtime PM framework following a call to pm_runtime_get().
+ * Note that if pm_runtime_get() is called more than once in
+ * succession this handler will only be called once.
+ * @runtime_suspend: an optional handler which will be called by the
+ * runtime PM framework following a call to pm_runtime_put().
+ * Note that if pm_runtime_get() is called more than once in
+ * succession this handler will only be called following the
+ * final call to pm_runtime_put() that actually disables the
+ * hardware.
*/
struct arm_pmu_platdata {
irqreturn_t (*handle_irq)(int irq, void *dev,
irq_handler_t pmu_handler);
- void (*enable_irq)(int irq);
- void (*disable_irq)(int irq);
+ int (*runtime_resume)(struct device *dev);
+ int (*runtime_suspend)(struct device *dev);
};
#ifdef CONFIG_CPU_HAS_PMU
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 186c8cb..2878651 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
#include <asm/cputype.h>
#include <asm/irq.h>
@@ -367,8 +368,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
{
int i, irq, irqs;
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());
@@ -376,13 +375,11 @@ armpmu_release_hardware(struct arm_pmu *armpmu)
if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs))
continue;
irq = platform_get_irq(pmu_device, i);
- if (irq >= 0) {
- if (plat && plat->disable_irq)
- plat->disable_irq(irq);
+ if (irq >= 0)
free_irq(irq, armpmu);
- }
}
+ pm_runtime_put_sync(&pmu_device->dev);
release_pmu(armpmu->type);
}
@@ -415,6 +412,8 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
return -ENODEV;
}
+ pm_runtime_get_sync(&pmu_device->dev);
+
for (i = 0; i < irqs; ++i) {
err = 0;
irq = platform_get_irq(pmu_device, i);
@@ -440,8 +439,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
irq);
armpmu_release_hardware(armpmu);
return err;
- } else if (plat && plat->enable_irq)
- plat->enable_irq(irq);
+ }
cpumask_set_cpu(i, &armpmu->active_irqs);
}
@@ -584,6 +582,28 @@ static void armpmu_disable(struct pmu *pmu)
armpmu->stop();
}
+#ifdef CONFIG_PM_RUNTIME
+static int armpmu_runtime_resume(struct device *dev)
+{
+ struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+ if (plat && plat->runtime_resume)
+ return plat->runtime_resume(dev);
+
+ return 0;
+}
+
+static int armpmu_runtime_suspend(struct device *dev)
+{
+ struct arm_pmu_platdata *plat = dev_get_platdata(dev);
+
+ if (plat && plat->runtime_suspend)
+ return plat->runtime_suspend(dev);
+
+ return 0;
+}
+#endif
+
static void __init armpmu_init(struct arm_pmu *armpmu)
{
atomic_set(&armpmu->active_events, 0);
@@ -650,9 +670,14 @@ static int __devinit armpmu_device_probe(struct platform_device *pdev)
return 0;
}
+static const struct dev_pm_ops armpmu_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
+};
+
static struct platform_driver armpmu_driver = {
.driver = {
.name = "arm-pmu",
+ .pm = &armpmu_dev_pm_ops,
.of_match_table = armpmu_of_device_ids,
},
.probe = armpmu_device_probe,
--
1.7.9.5
next prev parent reply other threads:[~2012-06-08 15:24 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-07 21:22 [PATCH V2 00/10] ARM: OMAP4: Add PMU Support Jon Hunter
2012-06-07 21:22 ` [PATCH V2 01/10] ARM: PMU: Add runtime PM Support Jon Hunter
2012-06-08 9:47 ` Will Deacon
2012-06-08 14:17 ` Jon Hunter
2012-06-08 15:24 ` Jon Hunter [this message]
2012-06-11 17:39 ` Will Deacon
2012-06-11 19:01 ` Jon Hunter
2012-06-12 9:28 ` Will Deacon
2012-06-12 21:17 ` Jon Hunter
2012-06-12 21:31 ` Will Deacon
2012-06-12 22:41 ` Jon Hunter
2012-07-02 9:55 ` Will Deacon
2012-07-02 16:50 ` Jon Hunter
2012-07-02 22:01 ` Will Deacon
2012-07-06 0:40 ` Jon Hunter
2012-07-26 0:41 ` Jon Hunter
2012-07-26 15:05 ` Will Deacon
2012-07-26 15:16 ` Jon Hunter
2012-07-31 15:14 ` Will Deacon
2012-07-31 23:07 ` Jon Hunter
2012-08-01 20:47 ` Will Deacon
2012-08-01 22:34 ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 02/10] ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD Jon Hunter
2012-06-07 21:22 ` [PATCH V2 03/10] ARM: OMAP4: Re-map the CTIs IRQs from MPU to DEBUGSS Jon Hunter
2012-06-13 6:07 ` Pandita, Vikram
2012-06-13 6:13 ` Pandita, Vikram
2012-06-13 6:19 ` Shilimkar, Santosh
2012-06-07 21:22 ` [PATCH V2 04/10] ARM: OMAP4430: Create PMU device via HWMOD Jon Hunter
2012-06-07 21:22 ` [PATCH V2 05/10] ARM: OMAP2+: PMU: Add runtime PM support Jon Hunter
2012-06-07 21:22 ` [PATCH V2 06/10] ARM: OMAP4: Route PMU IRQs to CTI IRQs Jon Hunter
2012-06-07 21:22 ` [PATCH V2 07/10] ARM: OMAP4: CLKDM: Update supported transition modes Jon Hunter
2012-07-04 15:38 ` Paul Walmsley
2012-07-05 17:14 ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 08/10] ARM: OMAP4: Prevent EMU power domain transitioning to OFF when in-use Jon Hunter
2012-07-12 21:17 ` Paul Walmsley
2012-07-13 13:54 ` Jon Hunter
2012-07-13 14:00 ` Will Deacon
2012-07-13 14:07 ` Jon Hunter
2012-07-20 22:24 ` Jon Hunter
2012-07-13 21:00 ` Paul Walmsley
2012-07-16 18:27 ` Jon Hunter
2012-07-16 18:38 ` Paul Walmsley
2012-07-16 19:38 ` Jon Hunter
2012-07-20 22:24 ` Jon Hunter
2012-07-30 23:26 ` Jon Hunter
2012-07-31 4:36 ` Jon Hunter
2012-07-31 18:16 ` Jon Hunter
2012-08-01 0:20 ` Jon Hunter
2012-08-01 15:08 ` Paul Walmsley
2012-08-01 18:17 ` Jon Hunter
2012-08-01 15:36 ` Paul Walmsley
2012-08-01 19:41 ` Jon Hunter
2012-08-02 7:34 ` Shilimkar, Santosh
2012-10-08 22:24 ` Jon Hunter
2012-10-09 4:41 ` Paul Walmsley
2012-07-31 20:56 ` Jon Hunter
2012-06-07 21:22 ` [PATCH V2 09/10] ARM: OMAP4: Enable PMU for OMAP4460/70 Jon Hunter
2012-06-07 21:22 ` [PATCH V2 10/10] ARM: OMAP2+: PMU: Add QoS constraint Jon Hunter
2012-06-07 23:36 ` [PATCH V2 00/10] ARM: OMAP4: Add PMU Support Jon Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FD21930.4000800@ti.com \
--to=jon-hunter@ti.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).