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; else cfg &= ~INTR_DECT_CTL_EDGE; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) cfg |= INTR_POL_CTL_HI; else cfg &= ~INTR_POL_CTL_HI; __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); }
static void msm_gpio_irq_disable(unsigned int irq) { unsigned long irq_flags; unsigned gpio = irq_to_gpio(irq); spin_lock_irqsave(&gpio_lock, irq_flags); disable_summary_irq(gpio); writel(DC_IRQ_DISABLE | TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); spin_unlock_irqrestore(&gpio_lock, irq_flags); }
static void msm_gpio_irq_enable(unsigned int irq) { unsigned long irq_flags; unsigned gpio = irq_to_gpio(irq); spin_lock_irqsave(&gpio_lock, irq_flags); set_gpio_bit(gpio, GPIO_OE_CLR(gpio)); writel(DC_IRQ_DISABLE | TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio)); enable_summary_irq(gpio); spin_unlock_irqrestore(&gpio_lock, irq_flags); }
void __msm_gpio_install_direct_irq(unsigned gpio, unsigned irq, unsigned int input_polarity) { uint32_t bits; __raw_writel(__raw_readl(GPIO_CONFIG(gpio)) | BIT(GPIO_OE_BIT), GPIO_CONFIG(gpio)); __raw_writel(__raw_readl(GPIO_INTR_CFG(gpio)) & ~(INTR_RAW_STATUS_EN | INTR_ENABLE), GPIO_INTR_CFG(gpio)); __raw_writel(DC_IRQ_ENABLE | TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); bits = TARGET_PROC_SCORPION | (gpio << 3); if (input_polarity) bits |= DC_POLARITY_HI; __raw_writel(bits, DIR_CONN_INTR_CFG_SU(irq)); }
void __msm_gpio_set_intr_cfg_type(unsigned gpio, unsigned type) { unsigned cfg; 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; else cfg &= ~INTR_DECT_CTL_EDGE; if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) cfg |= INTR_POL_CTL_HI; else cfg &= ~INTR_POL_CTL_HI; __raw_writel(cfg, GPIO_INTR_CFG(gpio)); udelay(5); }
int msm_gpio_install_direct_irq(unsigned gpio, unsigned irq) { unsigned long irq_flags; if (gpio >= NR_MSM_GPIOS || irq >= NR_TLMM_SCSS_DIR_CONN_IRQ) return -EINVAL; spin_lock_irqsave(&tlmm_lock, irq_flags); writel(readl(GPIO_CONFIG(gpio)) | BIT(GPIO_OE_BIT), GPIO_CONFIG(gpio)); writel(readl(GPIO_INTR_CFG(gpio)) & ~(INTR_RAW_STATUS_EN | INTR_ENABLE), GPIO_INTR_CFG(gpio)); writel(DC_IRQ_ENABLE | TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); writel(DC_POLARITY_HI | TARGET_PROC_SCORPION | (gpio << 3), DIR_CONN_INTR_CFG_SU(irq)); spin_unlock_irqrestore(&tlmm_lock, irq_flags); return 0; }
int msm_gpio_install_direct_irq(unsigned gpio, unsigned irq) { int rc = -EINVAL; unsigned long irq_flags; if (gpio < NR_MSM_GPIOS && irq < NR_TLMM_SCSS_DIR_CONN_IRQ) { spin_lock_irqsave(&gpio_lock, irq_flags); set_gpio_bit(gpio, GPIO_OE_CLR(gpio)); disable_summary_irq(gpio); writel(DC_IRQ_ENABLE | TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); writel(DC_POLARITY_HI | TARGET_PROC_SCORPION | (gpio << 3), DIR_CONN_INTR_CFG_SU(irq)); spin_unlock_irqrestore(&gpio_lock, irq_flags); rc = 0; } return rc; }