Re: [PATCH 4/6] ARM: OMAP4: PMU: Add runtime PM support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kevin,

On 05/29/2012 04:17 PM, Kevin Hilman wrote:
> Jon Hunter <jon-hunter@xxxxxx> writes:
> 
>> From: Jon Hunter <jon-hunter@xxxxxx>
>>
>> This patch is based upon Ming Lei's patch to add runtime PM support for OMAP4
>> [1]. In Ming's original patch the CTI interrupts were being enabled during
>> runtime when the PMU was used but they were only configured once during init.
>> Therefore move the configuration of the CTI interrupts to the runtime PM
>> functions.
> 
> Lovely.  This is exactly the workaround I was hoping to see.   Thanks!
> 
> Some comments below...

Thanks! Great timing, I am getting ready to post V2 :-)

>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074153.html
>>
>> Cc: Ming Lei <ming.lei@xxxxxxxxxxxxx>
>> Cc: Will Deacon <will.deacon@xxxxxxx>
>> Cc: Benoit Cousson <b-cousson@xxxxxx>
>> Cc: Paul Walmsley <paul@xxxxxxxxx>
>> Cc: Kevin Hilman <khilman@xxxxxx>
>>
>> Signed-off-by: Jon Hunter <jon-hunter@xxxxxx>
>> ---
>>  arch/arm/mach-omap2/devices.c |   50 ++++++++++++++++++++++------------------
>>  1 files changed, 27 insertions(+), 23 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
>> index 636533d..b02aa81 100644
>> --- a/arch/arm/mach-omap2/devices.c
>> +++ b/arch/arm/mach-omap2/devices.c
>> @@ -18,6 +18,7 @@
>>  #include <linux/slab.h>
>>  #include <linux/of.h>
>>  #incluhttp://marc.info/?l=linux-arm-kernel&m=132227620816504&w=2de <linux/platform_data/omap4-keypad.h>
>> +#include <linux/pm_runtime.h>
>>  
>>  #include <mach/hardware.h>
>>  #include <mach/irqs.h>
>> @@ -434,13 +435,22 @@ static struct omap_device_pm_latency omap_pmu_latency[] = {
>>  };
>>  
>>  static struct cti omap4_cti[2];
>> +static struct platform_device *pmu_dev;
>>  
>>  static void omap4_enable_cti(int irq)
>>  {
>> -	if (irq == OMAP44XX_IRQ_CTI0)
>> +	pm_runtime_get_sync(&pmu_dev->dev);
>> +	if (irq == OMAP44XX_IRQ_CTI0) {
>> +		/* configure CTI0 for pmu irq routing */
>> +		cti_unlock(&omap4_cti[0]);
>> +		cti_map_trigger(&omap4_cti[0], 1, 6, 2);
>>  		cti_enablook at thisle(&omap4_cti[0]);
>> -	else if (irq == OMAP44XX_IRQ_CTI1)
>> +	} else if (irq == OMAP44XX_IRQ_CTI1) {
>> +		/* configure CTI1 for pmu irq routing */
>> +		cti_unlolook at thisck(&omap4_cti[1]);
>> +		cti_map_trigger(&omap4_cti[1], 1, 6, 2);
>>  		cti_enable(&omap4_cti[1]);
>> +	}
>>  }
> 
> The cti_* functions really belong in the ->runtime_resume() callback.
> 
> In the case of multiple users, I don't think the current implementation
> will do what is intended.  IOW, you only want to (re)init for the first
> user (when runtime PM usecount goes from zero to one.)   That is when
> the ->runtime_resume() is called.   For a 2nd user, the
> ->runtime_resume() callback will not be called, but the cti_* functions
> will still be called.   I don't think that is what you want.

Ah, yes that would not work. Ok, let me make that change.

>>  static void omap4_disable_cti(int irq)
>> @@ -449,6 +459,7 @@ static void omap4_disable_cti(int irq)
>>  		cti_disable(&omap4_cti[0]);
>>  	else if (irq == OMAP44XX_IRQ_CTI1)
>>  		cti_disable(&omap4_cti[1]);
>> +	pm_runtime_put(&pmu_dev->dev);
> 
> Similarily here.  the cti_ functions should be in the
> ->runtime_suspend() callback.

Ok, will change that too.

>>  }
>>  
>>  static irqreturn_t omap4_pmu_handler(int irq, void *dev, irq_handler_t handler)
>> @@ -461,27 +472,20 @@ static irqreturn_t omap4_pmu_handler(int irq, void *dev, irq_handler_t handler)
>>  	return handler(irq, dev);
>>  }
>>  
>> -static void __init omap4_configure_pmu_irq(void)
>> +static int __init omap4_configure_pmu(void)
>>  {
>> -	void __iomem *base0;
>> -	void __iomem *base1;
>> +	omap4_cti[0].base = ioremap(OMAP44XX_CTI0_BASE, SZ_4K);
>> +	omap4_cti[1].base = ioremap(OMAP44XX_CTI1_BASE, SZ_4K);
>>  
>> -	base0 = ioremap(OMAP44XX_CTI0_BASE, SZ_4K);
>> -	base1 = ioremap(OMAP44XX_CTI1_BASE, SZ_4K);
>> -	if (!base0 && !base1) {
>> +	if (!omap4_cti[0].base || !omap4_cti[1].base) {
>>  		pr_err("ioremap for OMAP4 CTI failed\n");
>> -		return;
>> +		return -ENOMEM;
>>  	}
>>  
>> -	/*configure CTI0 for pmu irq routing*/
>> -	cti_init(&omap4_cti[0], base0, OMAP44XX_IRQ_CTI0, 6);
>> -	cti_unlock(&omap4_cti[0]);
>> -	cti_map_trigger(&omap4_cti[0], 1, 6, 2);
>> +	cti_init(&omap4_cti[0], omap4_cti[0].base, OMAP44XX_IRQ_CTI0, 6);
>> +	cti_init(&omap4_cti[1], omap4_cti[1].base, OMAP44XX_IRQ_CTI1, 6);
>>  
>> -	/*configure CTI1 for pmu irq routing*/
>> -	cti_init(&omap4_cti[1], base1, OMAP44XX_IRQ_CTI1, 6);
>> -	cti_unlock(&omap4_cti[1]);
>> -	cti_map_trigger(&omap4_cti[1], 1, 6, 2);
>> +	return 0;
>>  }
>>  
>>  static struct platform_device* __init omap4_init_pmu(void)
>> @@ -492,6 +496,9 @@ static struct platform_device* __init omap4_init_pmu(void)
>>  	struct omap_hwmod* oh[3];
>>  	char *dev_name = "arm-pmu";
>>  
>> +	if (omap4_configure_pmu())
>> +		return NULL;
>> +
>>  	hw = "l3_main_3";
>>  	oh[0] = omap_hwmod_lookup(hw);
>>  	if (!oh[0]) {
>> @@ -530,14 +537,11 @@ static void __init omap_init_pmu(void)
>>  	} else if (cpu_is_omap34xx()) {
>>  		omap_pmu_device.resource = &omap3_pmu_resource;
>>  	} else if (cpu_is_omap44xx()) {
>> -		struct platform_device *pd;
>> -
>> -		pd = omap4_init_pmu();
>> -		if (!pd)
>> +		pmu_dev = omap4_init_pmu();
> 
> Shouldn't the device be accessible for this call?
> 
> IOW, with runtime PM, there should be a get/put around this.

This function does not actually touch the hardware and so it should be ok.

Cheers
Jon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux