mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: gpio: Re-arrange the write to RAW_STATUS_EN
Move enabling the RAW_STATUS_EN at the very beginning. Hardware team clarified that it is better to write to RAW_STATUS_EN before writing to any other INTR_CFG bits in order to prevent spurious interrupts. Removing writing to the GPIO_INTR_CFG_SU register for gpio-v2 and remove modifying any other bits except INTR_ENABLE in mask/unmask calls as it could cause spurious interrupts as well. Change-Id: Ia025b324ee3be8073960eac73899f733336cac4c CRs-Fixed: 346861 Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
This commit is contained in:
parent
3f3ba6ffeb
commit
8e6112aaca
2 changed files with 24 additions and 29 deletions
|
@ -149,10 +149,8 @@ void __msm_gpio_set_intr_cfg_enable(unsigned gpio, unsigned val)
|
|||
{
|
||||
if (val) {
|
||||
set_gpio_bits(INTR_ENABLE, GPIO_INTR_CFG(gpio));
|
||||
__raw_writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
|
||||
|
||||
} else {
|
||||
__raw_writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
|
||||
clr_gpio_bits(INTR_ENABLE, GPIO_INTR_CFG(gpio));
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +159,15 @@ void __msm_gpio_set_intr_cfg_type(unsigned gpio, unsigned type)
|
|||
{
|
||||
unsigned cfg;
|
||||
|
||||
/* RAW_STATUS_EN is left on for all gpio irqs. Due to the
|
||||
* internal circuitry of TLMM, toggling the RAW_STATUS
|
||||
* could cause the INTR_STATUS to be set for EDGE interrupts.
|
||||
*/
|
||||
cfg = __msm_gpio_get_intr_config(gpio);
|
||||
cfg |= INTR_RAW_STATUS_EN;
|
||||
__raw_writel(cfg, GPIO_INTR_CFG(gpio));
|
||||
__raw_writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
|
||||
|
||||
cfg = __msm_gpio_get_intr_config(gpio);
|
||||
if (type & IRQ_TYPE_EDGE_BOTH)
|
||||
cfg |= INTR_DECT_CTL_EDGE;
|
||||
|
@ -172,23 +179,13 @@ void __msm_gpio_set_intr_cfg_type(unsigned gpio, unsigned type)
|
|||
else
|
||||
cfg &= ~INTR_POL_CTL_HI;
|
||||
|
||||
/* RAW_STATUS_EN is left on for all gpio irqs. Due to the
|
||||
* internal circuitry of TLMM, toggling the RAW_STATUS
|
||||
* could cause the INTR_STATUS to be set for EDGE interrupts.
|
||||
*/
|
||||
cfg |= INTR_RAW_STATUS_EN;
|
||||
__raw_writel(cfg, GPIO_INTR_CFG(gpio));
|
||||
|
||||
/* Sometimes it might take a little while to update
|
||||
* the interrupt status after the RAW_STATUS is enabled
|
||||
* We clear the interrupt status before enabling the
|
||||
* interrupt in the unmask call-back.
|
||||
*/
|
||||
udelay(5);
|
||||
|
||||
/* Clear the interrupt status to clear out any spurious
|
||||
* irq as a result of the above operation
|
||||
*/
|
||||
__msm_gpio_set_intr_status(gpio);
|
||||
|
||||
}
|
||||
|
||||
void __gpio_tlmm_config(unsigned config)
|
||||
|
|
|
@ -155,11 +155,10 @@ void __msm_gpio_set_intr_cfg_enable(unsigned gpio, unsigned val)
|
|||
|
||||
cfg = __raw_readl(GPIO_INTR_CFG(gpio));
|
||||
if (val) {
|
||||
cfg &= ~(INTR_TARGET_PROC_NONE | INTR_DIR_CONN_EN);
|
||||
cfg |= INTR_ENABLE | INTR_TARGET_PROC_APPS;
|
||||
cfg &= ~INTR_DIR_CONN_EN;
|
||||
cfg |= INTR_ENABLE;
|
||||
} else {
|
||||
cfg &= ~(INTR_TARGET_PROC_APPS | INTR_ENABLE);
|
||||
cfg |= INTR_TARGET_PROC_NONE;
|
||||
cfg &= ~INTR_ENABLE;
|
||||
}
|
||||
__raw_writel(cfg, GPIO_INTR_CFG(gpio));
|
||||
}
|
||||
|
@ -168,6 +167,14 @@ void __msm_gpio_set_intr_cfg_type(unsigned gpio, unsigned type)
|
|||
{
|
||||
unsigned cfg;
|
||||
|
||||
cfg = __raw_readl(GPIO_INTR_CFG(gpio));
|
||||
|
||||
/* RAW_STATUS_EN is left on for all gpio irqs. Due to the
|
||||
* internal circuitry of TLMM, toggling the RAW_STATUS
|
||||
* could cause the INTR_STATUS to be set for EDGE interrupts.
|
||||
*/
|
||||
cfg |= (INTR_RAW_STATUS_EN | INTR_TARGET_PROC_APPS);
|
||||
__raw_writel(cfg, GPIO_INTR_CFG(gpio));
|
||||
cfg = __raw_readl(GPIO_INTR_CFG(gpio));
|
||||
cfg &= ~INTR_DECT_CTL_MASK;
|
||||
if (type == IRQ_TYPE_EDGE_RISING)
|
||||
|
@ -184,22 +191,13 @@ void __msm_gpio_set_intr_cfg_type(unsigned gpio, unsigned type)
|
|||
else
|
||||
cfg &= ~INTR_POL_CTL_HI;
|
||||
|
||||
/* RAW_STATUS_EN is left on for all gpio irqs. Due to the
|
||||
* internal circuitry of TLMM, toggling the RAW_STATUS
|
||||
* could cause the INTR_STATUS to be set for EDGE interrupts.
|
||||
*/
|
||||
cfg |= INTR_RAW_STATUS_EN;
|
||||
__raw_writel(cfg, GPIO_INTR_CFG(gpio));
|
||||
|
||||
/* Sometimes it might take a little while to update
|
||||
* the interrupt status after the RAW_STATUS is enabled
|
||||
* We clear the interrupt status before enabling the
|
||||
* interrupt in the unmask call-back.
|
||||
*/
|
||||
udelay(5);
|
||||
|
||||
/* Clear the interrupt status to clear out any spurious
|
||||
* irq as a result of the above operation
|
||||
*/
|
||||
__msm_gpio_set_intr_status(gpio);
|
||||
}
|
||||
|
||||
void __gpio_tlmm_config(unsigned config)
|
||||
|
|
Loading…
Reference in a new issue