Message ID | 87tz4i981a.fsf@deeprootsystems.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Kevin Hilman |
Headers | show |
Hi Kevin, Thank you for showing steady interest in this driver. On Tue, Apr 21, 2009 at 9:15 AM, Kevin Hilman <khilman@deeprootsystems.com> wrote: > > Hi Kyuwon, > > While I still like the concept of this driver, I'm still not quite > happy about how it is implemented for various reasons. Most of which > have to do with the fact that this driver does many things that really > should be the job of other layers. In particular, the list of > omap3_wake_events is a bit troubling. It really should be handled by > the omapdev layer. You'll see that you are duplicating the data that > is handled there. Rather, we should just extend the omapdev data to > handle the wakeup events for that device. If you allow me to insert a new field whose name is "mask" in the omapdev struct, I think I can extend the omapdev to handle the wakeup events. > Also, I still think the WKST register reading should be done in the > PRCM interrupt handler. In your previous attempt, you were seeing a > bunch of non-device wakeup related interrupts. Can you try again > with the attached patch (thanks to Paul Walmseley) which should help > us debug why you were seeing spurious PRCM interrupts. First of all, sorry for giving you the wrong information in the previous mail. I found that we actually have configured GPTIMER12 as the system timer. And I tried with the attached patch, but I can't see any debug message. However even now, PRCM interrupt handler is invoked quite often due to the system timer. As far as I know, after Peter's [OMAP3: PM: CPUidle: Add new lower-latency C1 state] patch is applied, the system is in 'wfi' state in every idle state. So whenever the system timer wake up the system from idle, I think PRCM interrupt occurs. Do you think still the WKST register should be read in the PRCM interrupt handler? ;) > Also, I know we discussed this before, but I think the GPIO wakeup > source stuff really belongs in a separate patch, and if you think it > is still useful, and cannot be done by just enabling a GPIO IRQ from > the board file, I suggest you propose a patch to the generic GPIO > layer to add this interface. OK, I will remove this GPIO wakeup feature. But I want to know more detailed information about wakeup event . So, instead of using the GPIO wakeup, I'm planning using WAKEUPEVENT bit in CONTROL_PADCONF_x registers. >> diff --git a/arch/arm/mach-omap2/prcm-common.h >> b/arch/arm/mach-omap2/prcm-common.h >> index cb1ae84..1f340aa 100644 >> --- a/arch/arm/mach-omap2/prcm-common.h >> +++ b/arch/arm/mach-omap2/prcm-common.h >> @@ -273,6 +273,10 @@ >> #define OMAP3430_ST_D2D_SHIFT 3 >> #define OMAP3430_ST_D2D_MASK (1 << 3) >> >> +/* PM_WKST3_CORE, CM_IDLEST3_CORE shared bits */ >> +#define OMAP3430_ST_USBTLL_SHIFT 2 >> +#define OMAP3430_ST_USBTLL_MASK (1 << 2) >> + >> /* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */ >> #define OMAP3430_EN_GPIO1 (1 << 3) >> #define OMAP3430_EN_GPIO1_SHIFT 3 >> diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h >> b/arch/arm/mach-omap2/prm-regbits-34xx.h >> index 06fee29..f0a6395 100644 >> --- a/arch/arm/mach-omap2/prm-regbits-34xx.h >> +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h >> @@ -332,6 +332,8 @@ >> /* PM_IVA2GRPSEL1_CORE specific bits */ >> >> /* PM_WKST1_CORE specific bits */ >> +#define OMAP3430_ST_MMC3_SHIFT 30 >> +#define OMAP3430_ST_MMC3_MASK (1 << 30) >> >> /* PM_PWSTCTRL_CORE specific bits */ >> #define OMAP3430_MEM2ONSTATE_SHIFT 18 >> @@ -432,6 +434,9 @@ >> >> /* PM_PREPWSTST_PER specific bits */ >> >> +/* PM_WKST_USBHOST specific bits */ >> +#define OMAP3430_ST_USBHOST (1 << 0) >> + >> /* RM_RSTST_EMU specific bits */ > > All these new bit defines should all be 3430ES2_*. OK, I will fix it. Thanks & Regards, Kyuwon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Kyuwon, Kim Kyuwon <chammoru@gmail.com> writes: > Hi Kevin, > Thank you for showing steady interest in this driver. > > On Tue, Apr 21, 2009 at 9:15 AM, Kevin Hilman > <khilman@deeprootsystems.com> wrote: >> >> Hi Kyuwon, >> >> While I still like the concept of this driver, I'm still not quite >> happy about how it is implemented for various reasons. Most of which >> have to do with the fact that this driver does many things that really >> should be the job of other layers. In particular, the list of >> omap3_wake_events is a bit troubling. It really should be handled by >> the omapdev layer. You'll see that you are duplicating the data that >> is handled there. Rather, we should just extend the omapdev data to >> handle the wakeup events for that device. > > If you allow me to insert a new field whose name is "mask" in the > omapdev struct, I think I can extend the omapdev to handle the wakeup > events. Extending omapdev would be fine. >> Also, I still think the WKST register reading should be done in the >> PRCM interrupt handler. In your previous attempt, you were seeing a >> bunch of non-device wakeup related interrupts. Can you try again >> with the attached patch (thanks to Paul Walmseley) which should help >> us debug why you were seeing spurious PRCM interrupts. > > First of all, sorry for giving you the wrong information in the > previous mail. I found that we actually have configured GPTIMER12 as > the system timer. And I tried with the attached patch, but I can't > see any debug message. However even now, PRCM interrupt handler is > invoked quite often due to the system timer. That's what I assumed was happening. > As far as I know, after Peter's [OMAP3: PM: CPUidle: Add new > lower-latency C1 state] patch is applied, the system is in 'wfi' state > in every idle state. So whenever the system timer wake up the system > from idle, I think PRCM interrupt occurs. Do you think still the WKST > register should be read in the PRCM interrupt handler? ;) Yes. The WKST registers are already being read in the handler so they can be properly cleared. All you are adding is the saving of them. In addition, you should not enter idle between the time the system wakes from resume and your resume handler runs so you should be able to get the correct WKST values. >> Also, I know we discussed this before, but I think the GPIO wakeup >> source stuff really belongs in a separate patch, and if you think it >> is still useful, and cannot be done by just enabling a GPIO IRQ from >> the board file, I suggest you propose a patch to the generic GPIO >> layer to add this interface. > > OK, I will remove this GPIO wakeup feature. But I want to know more > detailed information about wakeup event . So, instead of using the > GPIO wakeup, I'm planning using WAKEUPEVENT bit in CONTROL_PADCONF_x > registers. That sounds OK. The current mux layer is lacking any knowledge of the wake bits in the PADCONF regs, so I'd be interested in any ideas you have of adding that support. Kevin -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Apr 30, 2009 at 11:21 PM, Kevin Hilman <khilman@deeprootsystems.com> wrote: >>> Also, I still think the WKST register reading should be done in the >>> PRCM interrupt handler. In your previous attempt, you were seeing a >>> bunch of non-device wakeup related interrupts. Can you try again >>> with the attached patch (thanks to Paul Walmseley) which should help >>> us debug why you were seeing spurious PRCM interrupts. >> >> First of all, sorry for giving you the wrong information in the >> previous mail. I found that we actually have configured GPTIMER12 as >> the system timer. And I tried with the attached patch, but I can't >> see any debug message. However even now, PRCM interrupt handler is >> invoked quite often due to the system timer. > > That's what I assumed was happening. > >> As far as I know, after Peter's [OMAP3: PM: CPUidle: Add new >> lower-latency C1 state] patch is applied, the system is in 'wfi' state >> in every idle state. So whenever the system timer wake up the system >> from idle, I think PRCM interrupt occurs. Do you think still the WKST >> register should be read in the PRCM interrupt handler? ;) > > Yes. The WKST registers are already being read in the handler so they > can be properly cleared. All you are adding is the saving of them. > > In addition, you should not enter idle between the time the system > wakes from resume and your resume handler runs so you should be able > to get the correct WKST values. OK, Your idea is more reasonable. I modified as you said. thanks. >>> Also, I know we discussed this before, but I think the GPIO wakeup >>> source stuff really belongs in a separate patch, and if you think it >>> is still useful, and cannot be done by just enabling a GPIO IRQ from >>> the board file, I suggest you propose a patch to the generic GPIO >>> layer to add this interface. >> >> OK, I will remove this GPIO wakeup feature. But I want to know more >> detailed information about wakeup event . So, instead of using the >> GPIO wakeup, I'm planning using WAKEUPEVENT bit in CONTROL_PADCONF_x >> registers. > > That sounds OK. The current mux layer is lacking any knowledge of the > wake bits in the PADCONF regs, so I'd be interested in any ideas you > have of adding that support. I added my ideas about CONTROL_PADCONF_x into the new version of wake source driver. I will send it soon. Please review this new version again and feel free to give your opinion. Regards, Kyuwon (ê·œì›) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From 114168fca85ba38421c84a7163ea4ae98b452577 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 20 Apr 2009 17:49:04 -0600 Subject: [PATCH] OMAP3 PM: improve PRCM interrupt handler This test patch fixes a few obvious bugs in the OMAP3xxx PRCM interrupt handler. Clearing wakeup sources is now only done when the PRM indicates a wakeup source interrupt. Since we don't handle any other types of PRCM interrupts right now, warn if we get any other type of PRCM interrupt. Either code needs to be added to the PRCM interrupt handler to react to these, or these other interrupts should be masked off at init. Also, PM_WKST register contents should be ANDed with the contents of the MPUGRPSEL registers. Otherwise the MPU PRCM interrupt handler could wind up clearing wakeup events meant for the IVA PRCM interrupt handler. For a production version of this patch, we should not read MPUGRPSEL from the PRM, since those reads are very slow; rather, we should use a cached version from struct powerdomain (not yet implemented) Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> --- arch/arm/mach-omap2/pm34xx.c | 78 +++++++++++++++++++++++++++++++++-------- 1 files changed, 62 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7474cfa..7e78a3b 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -194,14 +194,18 @@ static void omap3_save_secure_ram_context(u32 target_mpu_state) } } -/* PRCM Interrupt Handler for wakeups */ -static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) +static int _prcm_int_handle_wakeup(void) { - u32 wkst, irqstatus_mpu; - u32 fclk, iclk; + u32 wkst, fclk, iclk; + int c = 0; + + /* FIXME: MPUGRPSEL reads beow should be done from an SDRAM + * local copy in the struct powerdomain since PRM reads + * are very slow. */ /* WKUP */ wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST); + wkst &= prm_read_mod_reg(WKUP_MOD, OMAP3430_PM_MPUGRPSEL); if (wkst) { iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN); fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN); @@ -211,10 +215,12 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) while (prm_read_mod_reg(WKUP_MOD, PM_WKST)); cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN); cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN); + c++; } /* CORE */ wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1); + wkst &= prm_read_mod_reg(CORE_MOD, OMAP3430_PM_MPUGRPSEL1); if (wkst) { iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1); fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); @@ -224,21 +230,32 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) while (prm_read_mod_reg(CORE_MOD, PM_WKST1)); cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1); cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1); + c++; } - wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3); - if (wkst) { - iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3); - fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3); - cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3); - cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3); - prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3); - while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3)); - cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3); - cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3); + if (omap_rev() > OMAP3430_REV_ES1_0) { + wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3); + wkst &= prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_MPUGRPSEL3); + if (wkst) { + iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3); + fclk = cm_read_mod_reg(CORE_MOD, + OMAP3430ES2_CM_FCLKEN3); + cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3); + cm_set_mod_reg_bits(wkst, CORE_MOD, + OMAP3430ES2_CM_FCLKEN3); + prm_write_mod_reg(wkst, CORE_MOD, + OMAP3430ES2_PM_WKST3); + while (prm_read_mod_reg(CORE_MOD, + OMAP3430ES2_PM_WKST3)); + cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3); + cm_write_mod_reg(fclk, CORE_MOD, + OMAP3430ES2_CM_FCLKEN3); + c++; + } } /* PER */ wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST); + wkst &= prm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); if (wkst) { iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN); fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN); @@ -248,11 +265,14 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST)); cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN); cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN); + c++; } if (omap_rev() > OMAP3430_REV_ES1_0) { /* USBHOST */ wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST); + wkst &= prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, + OMAP3430_PM_MPUGRPSEL); if (wkst) { iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN); @@ -271,12 +291,38 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD, CM_FCLKEN); } + c++; } + return c; +} + +/* PRCM Interrupt Handler for wakeups */ +static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) +{ + u32 irqstatus_mpu; + int c; + irqstatus_mpu = prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET); + + if (irqstatus_mpu & OMAP3430_WKUP_ST) { + c = _prcm_int_handle_wakeup(); + + /* + * Is the MPU PRCM interrupt handler racing with the + * IVA2 PRCM interrupt handler ? + */ + WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup " + "but no wakeup sources are marked\n"); + } else { + /* XXX we need to expand our PRCM interrupt handler */ + WARN(1, "prcm: WARNING: PRCM interrupt received, but no " + "code to handle it (%08x)\n", irqstatus_mpu); + } + prm_write_mod_reg(irqstatus_mpu, OCP_MOD, - OMAP2_PRM_IRQSTATUS_MPU_OFFSET); + OMAP2_PRM_IRQSTATUS_MPU_OFFSET); while (prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET)); @@ -969,7 +1015,7 @@ int __init omap3_pm_init(void) * supervised mode for powerdomains */ prcm_setup_regs(); - ret = request_irq(INT_34XX_PRCM_MPU_IRQ, + ret = request_irq(INT_34XX_PRCM_MPU_IRQ, (irq_handler_t)prcm_interrupt_handler, IRQF_DISABLED, "prcm", NULL); if (ret) { -- 1.6.2.2