void __msm_gpio_set_polarity(unsigned gpio, unsigned val) { if (val) clr_gpio_bits(INTR_POL_CTL_HI, GPIO_INTR_CFG(gpio)); else set_gpio_bits(INTR_POL_CTL_HI, GPIO_INTR_CFG(gpio)); }
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 disable_summary_irq(unsigned gpio) { uint32_t intr_cfg; intr_cfg = readl(GPIO_INTR_CFG(gpio)); intr_cfg &= ~(INTR_RAW_STATUS_EN | INTR_ENABLE); writel(intr_cfg, GPIO_INTR_CFG(gpio)); clear_bit(gpio, enabled_irqs); }
/* * It is important that the local bitfield not come out of sync with the * interrupt-enable bits in the GPIO config registers, so all enabling and * disabling of summary IRQs is done via these little helpers. This also * helps keep the RAW_STATUS_EN bit in sync. */ static void enable_summary_irq(unsigned gpio) { uint32_t intr_cfg; intr_cfg = readl(GPIO_INTR_CFG(gpio)); intr_cfg |= INTR_RAW_STATUS_EN | INTR_ENABLE; writel(intr_cfg, GPIO_INTR_CFG(gpio)); set_bit(gpio, enabled_irqs); }
void __msm_gpio_set_intr_cfg_enable(unsigned gpio, unsigned val) { if (val) { set_gpio_bits(INTR_ENABLE, GPIO_INTR_CFG(gpio)); } else { clr_gpio_bits(INTR_ENABLE, GPIO_INTR_CFG(gpio)); } }
void __msm_gpio_set_intr_cfg_enable(unsigned gpio, unsigned val) { unsigned cfg; cfg = __raw_readl_no_log(GPIO_INTR_CFG(gpio)); if (val) { cfg &= ~INTR_DIR_CONN_EN; cfg |= INTR_ENABLE; } else { cfg &= ~INTR_ENABLE; } __raw_writel_no_log(cfg, GPIO_INTR_CFG(gpio)); }
static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) { uint32_t bits; unsigned long irq_flags; void *addr = GPIO_INTR_CFG(irq_to_gpio(irq)); spin_lock_irqsave(&gpio_lock, irq_flags); bits = readl(addr); if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { bits |= INTR_DECT_CTL_EDGE; irq_desc[irq].handle_irq = handle_edge_irq; } else { bits &= ~INTR_DECT_CTL_EDGE; irq_desc[irq].handle_irq = handle_level_irq; } if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) bits |= INTR_POL_CTL_HI; else bits &= ~INTR_POL_CTL_HI; writel(bits, addr); spin_unlock_irqrestore(&gpio_lock, irq_flags); return 0; }
void __msm_gpio_install_direct_irq(unsigned gpio, unsigned irq, unsigned int input_polarity) { unsigned cfg; set_gpio_bits(BIT(GPIO_OE_BIT), GPIO_CONFIG(gpio)); cfg = __raw_readl(GPIO_INTR_CFG(gpio)); cfg &= ~(INTR_TARGET_PROC_NONE | INTR_RAW_STATUS_EN | INTR_ENABLE); cfg |= INTR_TARGET_PROC_APPS | INTR_DIR_CONN_EN; __raw_writel(cfg, GPIO_INTR_CFG(gpio)); cfg = gpio; if (input_polarity) cfg |= DC_POLARITY_HI; __raw_writel(cfg, GPIO_DIR_CONN_INTR(irq)); }
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; }
unsigned __msm_gpio_get_intr_config(unsigned gpio) { return __raw_readl(GPIO_INTR_CFG(gpio)); }
#if defined(CONFIG_HTC_POWER_DEBUG) && defined(CONFIG_PINCTRL_MSM_TLMM_V3) void __msm_gpio_get_dump_info(unsigned gpio, struct msm_gpio_dump_info *data) { unsigned flags; flags = __raw_readl(GPIO_CONFIG(gpio)); data->pull = flags & 0x3; data->func_sel = (flags >> 2) & 0xf; data->drv = (flags >> 6) & 0x7; data->dir = (flags >> 9) & 0x1; if (data->dir) data->value = (__raw_readl(GPIO_IN_OUT(gpio)) >> 1) & 0x1; else { data->value = __raw_readl(GPIO_IN_OUT(gpio)) & 0x1; data->int_en = __raw_readl(GPIO_INTR_CFG(gpio)) & 0x1; if (data->int_en) data->int_owner = (__raw_readl(GPIO_INTR_CFG(gpio)) >> 5) & 0x7; } } #endif unsigned __msm_gpio_get_intr_cfg_enable(unsigned gpio) { return __msm_gpio_get_intr_config(gpio) & INTR_ENABLE; } 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