All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rajendra Nayak <rnayak@ti.com>
To: Tero Kristo <t-kristo@ti.com>
Cc: linux-omap@vger.kernel.org, paul@pwsan.com, khilman@ti.com,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [RFC 1/6] ARM: OMAP3: PRM: move prcm interrupt handlers to PRM driver code
Date: Mon, 16 Jul 2012 16:56:25 +0530	[thread overview]
Message-ID: <5003FA61.2050003@ti.com> (raw)
In-Reply-To: <1342197459-7920-2-git-send-email-t-kristo@ti.com>

On Friday 13 July 2012 10:07 PM, Tero Kristo wrote:
> PM code doesn't really care about the PRCM wakeup + io interrupts on
> OMAP3, as these are used only for acking PRCM internal events, and the
> IO chain handler is taken care of by hwmod code. Thus move the interrupt
> handling logic from pm34xx.c to prm2xxx_3xxx.c file. This patch also
> includes a minor cleanup for removing the priority handling and replacing
> it with a mechanism for acking pending events. This gets rid of the need
> for registering the shared interrupt handlers in specific order.

It would be easier to review if you were to split this into 2 patches,
one which moves functions around as-is and another which does the
cleanup/optimization. Having both in one is kinda hard to review.

>
> Signed-off-by: Tero Kristo<t-kristo@ti.com>
> ---
>   arch/arm/mach-omap2/pm34xx.c       |  109 +------------------------------
>   arch/arm/mach-omap2/prcm-common.h  |   10 ++--
>   arch/arm/mach-omap2/prm2xxx_3xxx.c |  124 ++++++++++++++++++++++++++++++++++--
>   arch/arm/mach-omap2/prm2xxx_3xxx.h |    1 +
>   arch/arm/mach-omap2/prm44xx.c      |    4 +-
>   arch/arm/mach-omap2/prm_common.c   |   42 ++----------
>   6 files changed, 138 insertions(+), 152 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index d25a9d8..474ed9d 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -133,85 +133,6 @@ static void omap3_save_secure_ram_context(void)
>   	}
>   }
>
> -/*
> - * PRCM Interrupt Handler Helper Function
> - *
> - * The purpose of this function is to clear any wake-up events latched
> - * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
> - * may occur whilst attempting to clear a PM_WKST_x register and thus
> - * set another bit in this register. A while loop is used to ensure
> - * that any peripheral wake-up events occurring while attempting to
> - * clear the PM_WKST_x are detected and cleared.
> - */
> -static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
> -{
> -	u32 wkst, fclk, iclk, clken;
> -	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
> -	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
> -	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
> -	u16 grpsel_off = (regs == 3) ?
> -		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
> -	int c = 0;
> -
> -	wkst = omap2_prm_read_mod_reg(module, wkst_off);
> -	wkst&= omap2_prm_read_mod_reg(module, grpsel_off);
> -	wkst&= ~ignore_bits;
> -	if (wkst) {
> -		iclk = omap2_cm_read_mod_reg(module, iclk_off);
> -		fclk = omap2_cm_read_mod_reg(module, fclk_off);
> -		while (wkst) {
> -			clken = wkst;
> -			omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
> -			/*
> -			 * For USBHOST, we don't know whether HOST1 or
> -			 * HOST2 woke us up, so enable both f-clocks
> -			 */
> -			if (module == OMAP3430ES2_USBHOST_MOD)
> -				clken |= 1<<  OMAP3430ES2_EN_USBHOST2_SHIFT;
> -			omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
> -			omap2_prm_write_mod_reg(wkst, module, wkst_off);
> -			wkst = omap2_prm_read_mod_reg(module, wkst_off);
> -			wkst&= ~ignore_bits;
> -			c++;
> -		}
> -		omap2_cm_write_mod_reg(iclk, module, iclk_off);
> -		omap2_cm_write_mod_reg(fclk, module, fclk_off);
> -	}
> -
> -	return c;
> -}
> -
> -static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
> -{
> -	int c;
> -
> -	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
> -		~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
> -
> -	return c ? IRQ_HANDLED : IRQ_NONE;
> -}
> -
> -static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
> -{
> -	int c;
> -
> -	/*
> -	 * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
> -	 * these are handled in a separate handler to avoid acking
> -	 * IO events before parsing in mux code
> -	 */
> -	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
> -		OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
> -	c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
> -	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
> -	if (omap_rev()>  OMAP3430_REV_ES1_0) {
> -		c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
> -		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
> -	}
> -
> -	return c ? IRQ_HANDLED : IRQ_NONE;
> -}
> -
>   static void omap34xx_save_context(u32 *save)
>   {
>   	u32 val;
> @@ -671,29 +592,10 @@ int __init omap3_pm_init(void)
>   	 * supervised mode for powerdomains */
>   	prcm_setup_regs();
>
> -	ret = request_irq(omap_prcm_event_to_irq("wkup"),
> -		_prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
> -
> -	if (ret) {
> -		pr_err("pm: Failed to request pm_wkup irq\n");
> -		goto err1;
> -	}
> -
> -	/* IO interrupt is shared with mux code */
> -	ret = request_irq(omap_prcm_event_to_irq("io"),
> -		_prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
> -		omap3_pm_init);
> -	enable_irq(omap_prcm_event_to_irq("io"));
> -
> -	if (ret) {
> -		pr_err("pm: Failed to request pm_io irq\n");
> -		goto err2;
> -	}
> -
>   	ret = pwrdm_for_each(pwrdms_setup, NULL);
>   	if (ret) {
>   		pr_err("Failed to setup powerdomains\n");
> -		goto err3;
> +		goto err;
>   	}
>
>   	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
> @@ -702,7 +604,7 @@ int __init omap3_pm_init(void)
>   	if (mpu_pwrdm == NULL) {
>   		pr_err("Failed to get mpu_pwrdm\n");
>   		ret = -EINVAL;
> -		goto err3;
> +		goto err;
>   	}
>
>   	neon_pwrdm = pwrdm_lookup("neon_pwrdm");
> @@ -750,14 +652,11 @@ int __init omap3_pm_init(void)
>   	omap3_save_scratchpad_contents();
>   	return ret;
>
> -err3:
> +err:
>   	list_for_each_entry_safe(pwrst, tmp,&pwrst_list, node) {
>   		list_del(&pwrst->node);
>   		kfree(pwrst);
>   	}
> -	free_irq(omap_prcm_event_to_irq("io"), omap3_pm_init);
> -err2:
> -	free_irq(omap_prcm_event_to_irq("wkup"), NULL);
> -err1:
> +
>   	return ret;
>   }
> diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
> index fca23cb..ad23bb4 100644
> --- a/arch/arm/mach-omap2/prcm-common.h
> +++ b/arch/arm/mach-omap2/prcm-common.h
> @@ -466,6 +466,7 @@ struct omap_prcm_irq {
>    * @ocp_barrier: fn ptr to force buffered PRM writes to complete
>    * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs
>    * @restore_irqen: fn ptr to save and clear IRQENABLE regs
> + * @ack_pending_events: fn ptr to ack pending events after handling
>    * @saved_mask: IRQENABLE regs are saved here during suspend
>    * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true
>    * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init
> @@ -487,18 +488,17 @@ struct omap_prcm_irq_setup {
>   	void (*ocp_barrier)(void);
>   	void (*save_and_clear_irqen)(u32 *saved_mask);
>   	void (*restore_irqen)(u32 *saved_mask);
> +	void (*ack_pending_events)(unsigned long *events);
>   	u32 *saved_mask;
> -	u32 *priority_mask;
>   	int base_irq;
>   	bool suspended;
>   	bool suspend_save_flag;
>   };
>
>   /* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */
> -#define OMAP_PRCM_IRQ(_name, _offset, _priority) {	\
> -	.name = _name,					\
> -	.offset = _offset,				\
> -	.priority = _priority				\
> +#define OMAP_PRCM_IRQ(_name, _offset) {	\
> +	.name = _name,			\
> +	.offset = _offset,		\
>   	}
>
>   extern void omap_prcm_irq_cleanup(void);
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> index a0309de..3761019 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> @@ -16,6 +16,7 @@
>   #include<linux/err.h>
>   #include<linux/io.h>
>   #include<linux/irq.h>
> +#include<linux/interrupt.h>
>
>   #include "common.h"
>   #include<plat/cpu.h>
> @@ -28,10 +29,11 @@
>   #include "cm2xxx_3xxx.h"
>   #include "prm-regbits-24xx.h"
>   #include "prm-regbits-34xx.h"
> +#include "cm-regbits-34xx.h"
>
>   static const struct omap_prcm_irq omap3_prcm_irqs[] = {
> -	OMAP_PRCM_IRQ("wkup",	0,	0),
> -	OMAP_PRCM_IRQ("io",	9,	1),
> +	OMAP_PRCM_IRQ("wkup",	0),
> +	OMAP_PRCM_IRQ("io",	9),
>   };
>
>   static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
> @@ -45,6 +47,7 @@ static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
>   	.ocp_barrier		=&omap3xxx_prm_ocp_barrier,
>   	.save_and_clear_irqen	=&omap3xxx_prm_save_and_clear_irqen,
>   	.restore_irqen		=&omap3xxx_prm_restore_irqen,
> +	.ack_pending_events	=&omap3xxx_prm_clear_wakeups,
>   };
>
>   u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
> @@ -349,18 +352,127 @@ static void __init omap3xxx_prm_enable_io_wakeup(void)
>   					   PM_WKEN);
>   }
>
> +/**
> + * prcm_clear_mod_irqs - clear module level wakeup irqs for omap3
> + * @module: prm module to clear
> + * @regs: register set to use, either 1 or 3
> + *
> + * The purpose of this function is to clear any wake-up events latched
> + * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
> + * may occur whilst attempting to clear a PM_WKST_x register and thus
> + * set another bit in this register. A while loop is used to ensure
> + * that any peripheral wake-up events occurring while attempting to
> + * clear the PM_WKST_x are detected and cleared. Returns the number
> + * of active wakeup events detected, or 0 if none.
> + */
> +static int _prcm_clear_mod_irqs(s16 module, u8 regs)
> +{
> +	u32 wkst, fclk, iclk, clken;
> +	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
> +	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
> +	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
> +	u16 grpsel_off = (regs == 3) ?
> +		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
> +	int c = 0;
> +
> +	wkst = omap2_prm_read_mod_reg(module, wkst_off);
> +	wkst&= omap2_prm_read_mod_reg(module, grpsel_off);
> +	if (wkst) {
> +		iclk = omap2_cm_read_mod_reg(module, iclk_off);
> +		fclk = omap2_cm_read_mod_reg(module, fclk_off);
> +		while (wkst) {
> +			clken = wkst;
> +			omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
> +			/*
> +			 * For USBHOST, we don't know whether HOST1 or
> +			 * HOST2 woke us up, so enable both f-clocks
> +			 */
> +			if (module == OMAP3430ES2_USBHOST_MOD)
> +				clken |= 1<<  OMAP3430ES2_EN_USBHOST2_SHIFT;
> +			omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
> +			omap2_prm_write_mod_reg(wkst, module, wkst_off);
> +			wkst = omap2_prm_read_mod_reg(module, wkst_off);
> +			c++;
> +		}
> +		omap2_cm_write_mod_reg(iclk, module, iclk_off);
> +		omap2_cm_write_mod_reg(fclk, module, fclk_off);
> +	}
> +
> +	return c;
> +}
> +
> +/**
> + * omap3xxx_prm_clear_wakeups - clears wakeup event sources
> + * @events: active PRCM interrupt event mask
> + *
> + * This function will first check if PRCM chain handler detected
> + * a wakeup event or not. If yes, it will continue to clear any
> + * pending wakeup events from PRCM module. Typically the module
> + * will generate an actual interrupt together with the wakeup event,
> + * which will then be handled separately by the driver code.
> + */
> +void omap3xxx_prm_clear_wakeups(unsigned long *events)
> +{
> +	int c;
> +
> +	/*
> +	 * If we didn't come here because of a wakeup event, do nothing
> +	 */
> +	if (!(events[0]&  OMAP3430_WKUP_ST_MASK))
> +		return;
> +
> +	c = _prcm_clear_mod_irqs(WKUP_MOD, 1);
> +	c += _prcm_clear_mod_irqs(CORE_MOD, 1);
> +	c += _prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
> +	if (omap_rev()>  OMAP3430_REV_ES1_0) {
> +		c += _prcm_clear_mod_irqs(CORE_MOD, 3);
> +		c += _prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
> +	}
> +}
> +
> +/**
> + * _prcm_int_handle_wakeup - dummy irq handler for prcm wakeup event
> + * @irq: not used, irq common API
> + * @unused: not used, irq common API
> + *
> + * Dummy handler for PRCM wakeup event interrupt. On software level,
> + * this handler doesn't do anything, but it is needed for hardware
> + * to function properly. Adding this handler will enable the wakeup
> + * event generation from PRCM, which is needed to get CPU out of
> + * WFI. Otherwise the CPU will get stuck on the WFI instruction
> + * indefinitely, as the MPU powerdomain remains idle.
> + */
> +static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
> +{
> +	return IRQ_HANDLED;
> +}
> +
>   static int __init omap3xxx_prcm_init(void)
>   {
> -	int ret = 0;
> +	int ret;
>
>   	if (cpu_is_omap34xx()) {
>   		omap3xxx_prm_enable_io_wakeup();
>   		ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
> -		if (!ret)
> -			irq_set_status_flags(omap_prcm_event_to_irq("io"),
> -					     IRQ_NOAUTOEN);
> +		if (ret) {
> +			pr_err("%s: failed to register chain handler: %d\n",
> +				__func__, ret);
> +			return ret;
> +		}
> +
> +		ret = request_irq(omap_prcm_event_to_irq("wkup"),
> +			_prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "prcm_wkup",
> +			NULL);
> +		if (ret) {
> +			pr_err("%s: failed to request prcm_wkup irq: %d\n",
> +				__func__, ret);
> +			goto err;
> +		}
>   	}
>
> +	return 0;
> +err:
> +	omap_prcm_irq_cleanup();
>   	return ret;
>   }
>   subsys_initcall(omap3xxx_prcm_init);
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> index 1ba3d65..078df35 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> @@ -322,6 +322,7 @@ extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
>   extern void omap3xxx_prm_ocp_barrier(void);
>   extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
>   extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
> +extern void omap3xxx_prm_clear_wakeups(unsigned long *events);
>
>   #endif	/* CONFIG_ARCH_OMAP4 */
>
> diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
> index bb727c2..fd26279 100644
> --- a/arch/arm/mach-omap2/prm44xx.c
> +++ b/arch/arm/mach-omap2/prm44xx.c
> @@ -30,8 +30,8 @@
>   #include "prminst44xx.h"
>
>   static const struct omap_prcm_irq omap4_prcm_irqs[] = {
> -	OMAP_PRCM_IRQ("wkup",   0,      0),
> -	OMAP_PRCM_IRQ("io",     9,      1),
> +	OMAP_PRCM_IRQ("wkup",	0),
> +	OMAP_PRCM_IRQ("io",	9),
>   };
>
>   static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
> diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
> index dfe00dd..4643651 100644
> --- a/arch/arm/mach-omap2/prm_common.c
> +++ b/arch/arm/mach-omap2/prm_common.c
> @@ -57,21 +57,6 @@ static struct omap_prcm_irq_setup *prcm_irq_setup;
>   /* Private functions */
>
>   /*
> - * Move priority events from events to priority_events array
> - */
> -static void omap_prcm_events_filter_priority(unsigned long *events,
> -	unsigned long *priority_events)
> -{
> -	int i;
> -
> -	for (i = 0; i<  prcm_irq_setup->nr_regs; i++) {
> -		priority_events[i] =
> -			events[i]&  prcm_irq_setup->priority_mask[i];
> -		events[i] ^= priority_events[i];
> -	}
> -}
> -
> -/*
>    * PRCM Interrupt Handler
>    *
>    * This is a common handler for the OMAP PRCM interrupts. Pending
> @@ -82,7 +67,6 @@ static void omap_prcm_events_filter_priority(unsigned long *events,
>   static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
>   {
>   	unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
> -	unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
>   	struct irq_chip *chip = irq_desc_get_chip(desc);
>   	unsigned int virtirq;
>   	int nr_irqs = prcm_irq_setup->nr_regs * 32;
> @@ -113,20 +97,19 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
>   		if (find_first_bit(pending, nr_irqs)>= nr_irqs)
>   			break;
>
> -		omap_prcm_events_filter_priority(pending, priority_pending);
> -
>   		/*
>   		 * Loop on all currently pending irqs so that new irqs
>   		 * cannot starve previously pending irqs
>   		 */
> -
> -		/* Serve priority events first */
> -		for_each_set_bit(virtirq, priority_pending, nr_irqs)
> -			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
> -
> -		/* Serve normal events next */
>   		for_each_set_bit(virtirq, pending, nr_irqs)
>   			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
> +
> +		/*
> +		 * Ack pending events if needed, this will clean the
> +		 * wakeup events on omap3
> +		 */
> +		if (prcm_irq_setup->ack_pending_events)
> +			prcm_irq_setup->ack_pending_events(pending);
>   	}
>   	if (chip->irq_ack)
>   		chip->irq_ack(&desc->irq_data);
> @@ -191,9 +174,6 @@ void omap_prcm_irq_cleanup(void)
>   	kfree(prcm_irq_setup->saved_mask);
>   	prcm_irq_setup->saved_mask = NULL;
>
> -	kfree(prcm_irq_setup->priority_mask);
> -	prcm_irq_setup->priority_mask = NULL;
> -
>   	irq_set_chained_handler(prcm_irq_setup->irq, NULL);
>
>   	if (prcm_irq_setup->base_irq>  0)
> @@ -262,11 +242,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
>
>   	prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
>   	prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
> -	prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
> -		GFP_KERNEL);
>
> -	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
> -	    !prcm_irq_setup->priority_mask) {
> +	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask) {
>   		pr_err("PRCM: kzalloc failed\n");
>   		goto err;
>   	}
> @@ -276,9 +253,6 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
>   	for (i = 0; i<  irq_setup->nr_irqs; i++) {
>   		offset = irq_setup->irqs[i].offset;
>   		mask[offset>>  5] |= 1<<  (offset&  0x1f);
> -		if (irq_setup->irqs[i].priority)
> -			irq_setup->priority_mask[offset>>  5] |=
> -				1<<  (offset&  0x1f);
>   	}
>
>   	irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);


WARNING: multiple messages have this Message-ID (diff)
From: rnayak@ti.com (Rajendra Nayak)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC 1/6] ARM: OMAP3: PRM: move prcm interrupt handlers to PRM driver code
Date: Mon, 16 Jul 2012 16:56:25 +0530	[thread overview]
Message-ID: <5003FA61.2050003@ti.com> (raw)
In-Reply-To: <1342197459-7920-2-git-send-email-t-kristo@ti.com>

On Friday 13 July 2012 10:07 PM, Tero Kristo wrote:
> PM code doesn't really care about the PRCM wakeup + io interrupts on
> OMAP3, as these are used only for acking PRCM internal events, and the
> IO chain handler is taken care of by hwmod code. Thus move the interrupt
> handling logic from pm34xx.c to prm2xxx_3xxx.c file. This patch also
> includes a minor cleanup for removing the priority handling and replacing
> it with a mechanism for acking pending events. This gets rid of the need
> for registering the shared interrupt handlers in specific order.

It would be easier to review if you were to split this into 2 patches,
one which moves functions around as-is and another which does the
cleanup/optimization. Having both in one is kinda hard to review.

>
> Signed-off-by: Tero Kristo<t-kristo@ti.com>
> ---
>   arch/arm/mach-omap2/pm34xx.c       |  109 +------------------------------
>   arch/arm/mach-omap2/prcm-common.h  |   10 ++--
>   arch/arm/mach-omap2/prm2xxx_3xxx.c |  124 ++++++++++++++++++++++++++++++++++--
>   arch/arm/mach-omap2/prm2xxx_3xxx.h |    1 +
>   arch/arm/mach-omap2/prm44xx.c      |    4 +-
>   arch/arm/mach-omap2/prm_common.c   |   42 ++----------
>   6 files changed, 138 insertions(+), 152 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index d25a9d8..474ed9d 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -133,85 +133,6 @@ static void omap3_save_secure_ram_context(void)
>   	}
>   }
>
> -/*
> - * PRCM Interrupt Handler Helper Function
> - *
> - * The purpose of this function is to clear any wake-up events latched
> - * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
> - * may occur whilst attempting to clear a PM_WKST_x register and thus
> - * set another bit in this register. A while loop is used to ensure
> - * that any peripheral wake-up events occurring while attempting to
> - * clear the PM_WKST_x are detected and cleared.
> - */
> -static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
> -{
> -	u32 wkst, fclk, iclk, clken;
> -	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
> -	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
> -	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
> -	u16 grpsel_off = (regs == 3) ?
> -		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
> -	int c = 0;
> -
> -	wkst = omap2_prm_read_mod_reg(module, wkst_off);
> -	wkst&= omap2_prm_read_mod_reg(module, grpsel_off);
> -	wkst&= ~ignore_bits;
> -	if (wkst) {
> -		iclk = omap2_cm_read_mod_reg(module, iclk_off);
> -		fclk = omap2_cm_read_mod_reg(module, fclk_off);
> -		while (wkst) {
> -			clken = wkst;
> -			omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
> -			/*
> -			 * For USBHOST, we don't know whether HOST1 or
> -			 * HOST2 woke us up, so enable both f-clocks
> -			 */
> -			if (module == OMAP3430ES2_USBHOST_MOD)
> -				clken |= 1<<  OMAP3430ES2_EN_USBHOST2_SHIFT;
> -			omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
> -			omap2_prm_write_mod_reg(wkst, module, wkst_off);
> -			wkst = omap2_prm_read_mod_reg(module, wkst_off);
> -			wkst&= ~ignore_bits;
> -			c++;
> -		}
> -		omap2_cm_write_mod_reg(iclk, module, iclk_off);
> -		omap2_cm_write_mod_reg(fclk, module, fclk_off);
> -	}
> -
> -	return c;
> -}
> -
> -static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
> -{
> -	int c;
> -
> -	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
> -		~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
> -
> -	return c ? IRQ_HANDLED : IRQ_NONE;
> -}
> -
> -static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
> -{
> -	int c;
> -
> -	/*
> -	 * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
> -	 * these are handled in a separate handler to avoid acking
> -	 * IO events before parsing in mux code
> -	 */
> -	c = prcm_clear_mod_irqs(WKUP_MOD, 1,
> -		OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
> -	c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
> -	c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
> -	if (omap_rev()>  OMAP3430_REV_ES1_0) {
> -		c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
> -		c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
> -	}
> -
> -	return c ? IRQ_HANDLED : IRQ_NONE;
> -}
> -
>   static void omap34xx_save_context(u32 *save)
>   {
>   	u32 val;
> @@ -671,29 +592,10 @@ int __init omap3_pm_init(void)
>   	 * supervised mode for powerdomains */
>   	prcm_setup_regs();
>
> -	ret = request_irq(omap_prcm_event_to_irq("wkup"),
> -		_prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
> -
> -	if (ret) {
> -		pr_err("pm: Failed to request pm_wkup irq\n");
> -		goto err1;
> -	}
> -
> -	/* IO interrupt is shared with mux code */
> -	ret = request_irq(omap_prcm_event_to_irq("io"),
> -		_prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
> -		omap3_pm_init);
> -	enable_irq(omap_prcm_event_to_irq("io"));
> -
> -	if (ret) {
> -		pr_err("pm: Failed to request pm_io irq\n");
> -		goto err2;
> -	}
> -
>   	ret = pwrdm_for_each(pwrdms_setup, NULL);
>   	if (ret) {
>   		pr_err("Failed to setup powerdomains\n");
> -		goto err3;
> +		goto err;
>   	}
>
>   	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
> @@ -702,7 +604,7 @@ int __init omap3_pm_init(void)
>   	if (mpu_pwrdm == NULL) {
>   		pr_err("Failed to get mpu_pwrdm\n");
>   		ret = -EINVAL;
> -		goto err3;
> +		goto err;
>   	}
>
>   	neon_pwrdm = pwrdm_lookup("neon_pwrdm");
> @@ -750,14 +652,11 @@ int __init omap3_pm_init(void)
>   	omap3_save_scratchpad_contents();
>   	return ret;
>
> -err3:
> +err:
>   	list_for_each_entry_safe(pwrst, tmp,&pwrst_list, node) {
>   		list_del(&pwrst->node);
>   		kfree(pwrst);
>   	}
> -	free_irq(omap_prcm_event_to_irq("io"), omap3_pm_init);
> -err2:
> -	free_irq(omap_prcm_event_to_irq("wkup"), NULL);
> -err1:
> +
>   	return ret;
>   }
> diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
> index fca23cb..ad23bb4 100644
> --- a/arch/arm/mach-omap2/prcm-common.h
> +++ b/arch/arm/mach-omap2/prcm-common.h
> @@ -466,6 +466,7 @@ struct omap_prcm_irq {
>    * @ocp_barrier: fn ptr to force buffered PRM writes to complete
>    * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs
>    * @restore_irqen: fn ptr to save and clear IRQENABLE regs
> + * @ack_pending_events: fn ptr to ack pending events after handling
>    * @saved_mask: IRQENABLE regs are saved here during suspend
>    * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true
>    * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init
> @@ -487,18 +488,17 @@ struct omap_prcm_irq_setup {
>   	void (*ocp_barrier)(void);
>   	void (*save_and_clear_irqen)(u32 *saved_mask);
>   	void (*restore_irqen)(u32 *saved_mask);
> +	void (*ack_pending_events)(unsigned long *events);
>   	u32 *saved_mask;
> -	u32 *priority_mask;
>   	int base_irq;
>   	bool suspended;
>   	bool suspend_save_flag;
>   };
>
>   /* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */
> -#define OMAP_PRCM_IRQ(_name, _offset, _priority) {	\
> -	.name = _name,					\
> -	.offset = _offset,				\
> -	.priority = _priority				\
> +#define OMAP_PRCM_IRQ(_name, _offset) {	\
> +	.name = _name,			\
> +	.offset = _offset,		\
>   	}
>
>   extern void omap_prcm_irq_cleanup(void);
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> index a0309de..3761019 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
> @@ -16,6 +16,7 @@
>   #include<linux/err.h>
>   #include<linux/io.h>
>   #include<linux/irq.h>
> +#include<linux/interrupt.h>
>
>   #include "common.h"
>   #include<plat/cpu.h>
> @@ -28,10 +29,11 @@
>   #include "cm2xxx_3xxx.h"
>   #include "prm-regbits-24xx.h"
>   #include "prm-regbits-34xx.h"
> +#include "cm-regbits-34xx.h"
>
>   static const struct omap_prcm_irq omap3_prcm_irqs[] = {
> -	OMAP_PRCM_IRQ("wkup",	0,	0),
> -	OMAP_PRCM_IRQ("io",	9,	1),
> +	OMAP_PRCM_IRQ("wkup",	0),
> +	OMAP_PRCM_IRQ("io",	9),
>   };
>
>   static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
> @@ -45,6 +47,7 @@ static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
>   	.ocp_barrier		=&omap3xxx_prm_ocp_barrier,
>   	.save_and_clear_irqen	=&omap3xxx_prm_save_and_clear_irqen,
>   	.restore_irqen		=&omap3xxx_prm_restore_irqen,
> +	.ack_pending_events	=&omap3xxx_prm_clear_wakeups,
>   };
>
>   u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
> @@ -349,18 +352,127 @@ static void __init omap3xxx_prm_enable_io_wakeup(void)
>   					   PM_WKEN);
>   }
>
> +/**
> + * prcm_clear_mod_irqs - clear module level wakeup irqs for omap3
> + * @module: prm module to clear
> + * @regs: register set to use, either 1 or 3
> + *
> + * The purpose of this function is to clear any wake-up events latched
> + * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
> + * may occur whilst attempting to clear a PM_WKST_x register and thus
> + * set another bit in this register. A while loop is used to ensure
> + * that any peripheral wake-up events occurring while attempting to
> + * clear the PM_WKST_x are detected and cleared. Returns the number
> + * of active wakeup events detected, or 0 if none.
> + */
> +static int _prcm_clear_mod_irqs(s16 module, u8 regs)
> +{
> +	u32 wkst, fclk, iclk, clken;
> +	u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
> +	u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
> +	u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
> +	u16 grpsel_off = (regs == 3) ?
> +		OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
> +	int c = 0;
> +
> +	wkst = omap2_prm_read_mod_reg(module, wkst_off);
> +	wkst&= omap2_prm_read_mod_reg(module, grpsel_off);
> +	if (wkst) {
> +		iclk = omap2_cm_read_mod_reg(module, iclk_off);
> +		fclk = omap2_cm_read_mod_reg(module, fclk_off);
> +		while (wkst) {
> +			clken = wkst;
> +			omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
> +			/*
> +			 * For USBHOST, we don't know whether HOST1 or
> +			 * HOST2 woke us up, so enable both f-clocks
> +			 */
> +			if (module == OMAP3430ES2_USBHOST_MOD)
> +				clken |= 1<<  OMAP3430ES2_EN_USBHOST2_SHIFT;
> +			omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
> +			omap2_prm_write_mod_reg(wkst, module, wkst_off);
> +			wkst = omap2_prm_read_mod_reg(module, wkst_off);
> +			c++;
> +		}
> +		omap2_cm_write_mod_reg(iclk, module, iclk_off);
> +		omap2_cm_write_mod_reg(fclk, module, fclk_off);
> +	}
> +
> +	return c;
> +}
> +
> +/**
> + * omap3xxx_prm_clear_wakeups - clears wakeup event sources
> + * @events: active PRCM interrupt event mask
> + *
> + * This function will first check if PRCM chain handler detected
> + * a wakeup event or not. If yes, it will continue to clear any
> + * pending wakeup events from PRCM module. Typically the module
> + * will generate an actual interrupt together with the wakeup event,
> + * which will then be handled separately by the driver code.
> + */
> +void omap3xxx_prm_clear_wakeups(unsigned long *events)
> +{
> +	int c;
> +
> +	/*
> +	 * If we didn't come here because of a wakeup event, do nothing
> +	 */
> +	if (!(events[0]&  OMAP3430_WKUP_ST_MASK))
> +		return;
> +
> +	c = _prcm_clear_mod_irqs(WKUP_MOD, 1);
> +	c += _prcm_clear_mod_irqs(CORE_MOD, 1);
> +	c += _prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
> +	if (omap_rev()>  OMAP3430_REV_ES1_0) {
> +		c += _prcm_clear_mod_irqs(CORE_MOD, 3);
> +		c += _prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
> +	}
> +}
> +
> +/**
> + * _prcm_int_handle_wakeup - dummy irq handler for prcm wakeup event
> + * @irq: not used, irq common API
> + * @unused: not used, irq common API
> + *
> + * Dummy handler for PRCM wakeup event interrupt. On software level,
> + * this handler doesn't do anything, but it is needed for hardware
> + * to function properly. Adding this handler will enable the wakeup
> + * event generation from PRCM, which is needed to get CPU out of
> + * WFI. Otherwise the CPU will get stuck on the WFI instruction
> + * indefinitely, as the MPU powerdomain remains idle.
> + */
> +static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
> +{
> +	return IRQ_HANDLED;
> +}
> +
>   static int __init omap3xxx_prcm_init(void)
>   {
> -	int ret = 0;
> +	int ret;
>
>   	if (cpu_is_omap34xx()) {
>   		omap3xxx_prm_enable_io_wakeup();
>   		ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
> -		if (!ret)
> -			irq_set_status_flags(omap_prcm_event_to_irq("io"),
> -					     IRQ_NOAUTOEN);
> +		if (ret) {
> +			pr_err("%s: failed to register chain handler: %d\n",
> +				__func__, ret);
> +			return ret;
> +		}
> +
> +		ret = request_irq(omap_prcm_event_to_irq("wkup"),
> +			_prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "prcm_wkup",
> +			NULL);
> +		if (ret) {
> +			pr_err("%s: failed to request prcm_wkup irq: %d\n",
> +				__func__, ret);
> +			goto err;
> +		}
>   	}
>
> +	return 0;
> +err:
> +	omap_prcm_irq_cleanup();
>   	return ret;
>   }
>   subsys_initcall(omap3xxx_prcm_init);
> diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> index 1ba3d65..078df35 100644
> --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
> +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
> @@ -322,6 +322,7 @@ extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
>   extern void omap3xxx_prm_ocp_barrier(void);
>   extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
>   extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
> +extern void omap3xxx_prm_clear_wakeups(unsigned long *events);
>
>   #endif	/* CONFIG_ARCH_OMAP4 */
>
> diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
> index bb727c2..fd26279 100644
> --- a/arch/arm/mach-omap2/prm44xx.c
> +++ b/arch/arm/mach-omap2/prm44xx.c
> @@ -30,8 +30,8 @@
>   #include "prminst44xx.h"
>
>   static const struct omap_prcm_irq omap4_prcm_irqs[] = {
> -	OMAP_PRCM_IRQ("wkup",   0,      0),
> -	OMAP_PRCM_IRQ("io",     9,      1),
> +	OMAP_PRCM_IRQ("wkup",	0),
> +	OMAP_PRCM_IRQ("io",	9),
>   };
>
>   static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
> diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
> index dfe00dd..4643651 100644
> --- a/arch/arm/mach-omap2/prm_common.c
> +++ b/arch/arm/mach-omap2/prm_common.c
> @@ -57,21 +57,6 @@ static struct omap_prcm_irq_setup *prcm_irq_setup;
>   /* Private functions */
>
>   /*
> - * Move priority events from events to priority_events array
> - */
> -static void omap_prcm_events_filter_priority(unsigned long *events,
> -	unsigned long *priority_events)
> -{
> -	int i;
> -
> -	for (i = 0; i<  prcm_irq_setup->nr_regs; i++) {
> -		priority_events[i] =
> -			events[i]&  prcm_irq_setup->priority_mask[i];
> -		events[i] ^= priority_events[i];
> -	}
> -}
> -
> -/*
>    * PRCM Interrupt Handler
>    *
>    * This is a common handler for the OMAP PRCM interrupts. Pending
> @@ -82,7 +67,6 @@ static void omap_prcm_events_filter_priority(unsigned long *events,
>   static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
>   {
>   	unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
> -	unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
>   	struct irq_chip *chip = irq_desc_get_chip(desc);
>   	unsigned int virtirq;
>   	int nr_irqs = prcm_irq_setup->nr_regs * 32;
> @@ -113,20 +97,19 @@ static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
>   		if (find_first_bit(pending, nr_irqs)>= nr_irqs)
>   			break;
>
> -		omap_prcm_events_filter_priority(pending, priority_pending);
> -
>   		/*
>   		 * Loop on all currently pending irqs so that new irqs
>   		 * cannot starve previously pending irqs
>   		 */
> -
> -		/* Serve priority events first */
> -		for_each_set_bit(virtirq, priority_pending, nr_irqs)
> -			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
> -
> -		/* Serve normal events next */
>   		for_each_set_bit(virtirq, pending, nr_irqs)
>   			generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
> +
> +		/*
> +		 * Ack pending events if needed, this will clean the
> +		 * wakeup events on omap3
> +		 */
> +		if (prcm_irq_setup->ack_pending_events)
> +			prcm_irq_setup->ack_pending_events(pending);
>   	}
>   	if (chip->irq_ack)
>   		chip->irq_ack(&desc->irq_data);
> @@ -191,9 +174,6 @@ void omap_prcm_irq_cleanup(void)
>   	kfree(prcm_irq_setup->saved_mask);
>   	prcm_irq_setup->saved_mask = NULL;
>
> -	kfree(prcm_irq_setup->priority_mask);
> -	prcm_irq_setup->priority_mask = NULL;
> -
>   	irq_set_chained_handler(prcm_irq_setup->irq, NULL);
>
>   	if (prcm_irq_setup->base_irq>  0)
> @@ -262,11 +242,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
>
>   	prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
>   	prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
> -	prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
> -		GFP_KERNEL);
>
> -	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
> -	    !prcm_irq_setup->priority_mask) {
> +	if (!prcm_irq_chips || !prcm_irq_setup->saved_mask) {
>   		pr_err("PRCM: kzalloc failed\n");
>   		goto err;
>   	}
> @@ -276,9 +253,6 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
>   	for (i = 0; i<  irq_setup->nr_irqs; i++) {
>   		offset = irq_setup->irqs[i].offset;
>   		mask[offset>>  5] |= 1<<  (offset&  0x1f);
> -		if (irq_setup->irqs[i].priority)
> -			irq_setup->priority_mask[offset>>  5] |=
> -				1<<  (offset&  0x1f);
>   	}
>
>   	irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);

  reply	other threads:[~2012-07-16 11:26 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-13 16:37 [RFC 0/6] ARM: OMAP3+: minor PM core code cleanup Tero Kristo
2012-07-13 16:37 ` Tero Kristo
2012-07-13 16:37 ` [RFC 1/6] ARM: OMAP3: PRM: move prcm interrupt handlers to PRM driver code Tero Kristo
2012-07-13 16:37   ` Tero Kristo
2012-07-16 11:26   ` Rajendra Nayak [this message]
2012-07-16 11:26     ` Rajendra Nayak
2012-07-16 11:41     ` Tero Kristo
2012-07-16 11:41       ` Tero Kristo
2012-07-31  0:31   ` Kevin Hilman
2012-07-31  0:31     ` Kevin Hilman
2012-08-07  7:28     ` Tony Lindgren
2012-08-07  7:28       ` Tony Lindgren
2012-07-13 16:37 ` [RFC 2/6] ARM: OMAP3: clock data: prevent IVA2 DPLL low power stop mode Tero Kristo
2012-07-13 16:37   ` Tero Kristo
2012-07-13 16:37 ` [RFC 3/6] ARM: OMAP3: hwmod data: fix iva2 reset info Tero Kristo
2012-07-13 16:37   ` Tero Kristo
2012-07-16  0:12   ` Paul Walmsley
2012-07-16  0:12     ` Paul Walmsley
2012-07-13 16:37 ` [RFC 4/6] ARM: OMAP3: hwmod data: add custom setup_preprogram for iva hwmod Tero Kristo
2012-07-13 16:37   ` Tero Kristo
2012-07-13 16:37 ` [RFC 5/6] ARM: OMAP3: hwmod data: add sad2d hwmod Tero Kristo
2012-07-13 16:37   ` Tero Kristo
2012-07-16  1:14   ` Paul Walmsley
2012-07-16  1:14     ` Paul Walmsley
2012-07-16  1:28   ` Paul Walmsley
2012-07-16  1:28     ` Paul Walmsley
2012-07-13 16:37 ` [RFC 6/6] ARM: OMAP3: hwmod data: add custom setup_preprogram for " Tero Kristo
2012-07-13 16:37   ` Tero Kristo
2012-07-30 20:53 ` [RFC 0/6] ARM: OMAP3+: minor PM core code cleanup Kevin Hilman
2012-07-30 20:53   ` Kevin Hilman

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=5003FA61.2050003@ti.com \
    --to=rnayak@ti.com \
    --cc=khilman@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    --cc=t-kristo@ti.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.