diff --git a/drivers/pinctrl/qcom/pinctrl-lahaina.c b/drivers/pinctrl/qcom/pinctrl-lahaina.c index e728d23ab399..b2bf0d27ec6f 100644 --- a/drivers/pinctrl/qcom/pinctrl-lahaina.c +++ b/drivers/pinctrl/qcom/pinctrl-lahaina.c @@ -1966,7 +1966,7 @@ static const struct msm_gpio_wakeirq_map lahaina_pdc_map[] = { { 190, 144 }, { 198, 91 }, { 200, 133 }, { 202, 135 }, }; -static const struct msm_pinctrl_soc_data lahaina_pinctrl = { +static struct msm_pinctrl_soc_data lahaina_pinctrl = { .pins = lahaina_pins, .npins = ARRAY_SIZE(lahaina_pins), .functions = lahaina_functions, @@ -1995,9 +1995,40 @@ static void lahaina_pinctrl_config_mpm_wake_disable_gpios(void) msm_gpio_mpm_wake_set(config_mpm_wake_disable_gpios[i], false); } +static int lahaina_pinctrl_no_wake_probe(struct platform_device *pdev) +{ + const __be32 *prop; + uint32_t *no_wake_gpios; + int i, length; + + prop = of_get_property(pdev->dev.of_node, "no-wake-gpios", &length); + if (!prop) + return -ENOENT; + + length = length / sizeof(u32); + + no_wake_gpios = devm_kzalloc(&pdev->dev, length * sizeof(uint32_t), GFP_KERNEL); + if (!no_wake_gpios) + return -ENOMEM; + + for (i = 0; i < length; i++) + no_wake_gpios[i] = be32_to_cpu(prop[i]); + + lahaina_pinctrl.no_wake_gpios = no_wake_gpios; + lahaina_pinctrl.n_no_wake_gpios = length; + + return 0; +} + static int lahaina_pinctrl_probe(struct platform_device *pdev) { - int ret; + int length, ret; + + if (of_find_property(pdev->dev.of_node, "no-wake-gpios", &length)) { + ret = lahaina_pinctrl_no_wake_probe(pdev); + if (ret) + return ret; + } ret = msm_pinctrl_probe(pdev, &lahaina_pinctrl); if (ret) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 73971fcd6003..9fef3573478f 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -894,11 +894,11 @@ static void msm_gpio_irq_enable(struct irq_data *d) irq_chip_enable_parent(d); } - if (pctrl->mpm_wake_ctl) - msm_gpio_mpm_wake_set(d->hwirq, true); - - if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { + if (pctrl->mpm_wake_ctl) + msm_gpio_mpm_wake_set(d->hwirq, true); return; + } msm_gpio_irq_clear_unmask(d, true); } @@ -921,11 +921,11 @@ static void msm_gpio_irq_disable(struct irq_data *d) irq_chip_disable_parent(d); } - if (pctrl->mpm_wake_ctl) - msm_gpio_mpm_wake_set(d->hwirq, false); - - if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) { + if (pctrl->mpm_wake_ctl) + msm_gpio_mpm_wake_set(d->hwirq, false); return; + } msm_gpio_irq_mask(d); } @@ -1288,6 +1288,9 @@ static int msm_gpio_wakeirq(struct gpio_chip *gc, *parent = GPIO_NO_WAKE_IRQ; *parent_type = IRQ_TYPE_EDGE_RISING; + if (!test_bit(child, pctrl->skip_wake_irqs)) + return 0; + for (i = 0; i < pctrl->soc->nwakeirq_map; i++) { map = &pctrl->soc->wakeirq_map[i]; if (map->gpio == child) { @@ -1358,6 +1361,16 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) gpio = pctrl->soc->wakeirq_map[i].gpio; set_bit(gpio, pctrl->skip_wake_irqs); } + + if (pctrl->soc->no_wake_gpios) { + for (i = 0; i < pctrl->soc->n_no_wake_gpios; i++) { + gpio = pctrl->soc->no_wake_gpios[i]; + if (test_bit(gpio, pctrl->skip_wake_irqs)) { + clear_bit(gpio, pctrl->skip_wake_irqs); + msm_gpio_mpm_wake_set(gpio, false); + } + } + } } girq = &chip->irq; diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h index 98b65bdb8155..5bcac8855500 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.h +++ b/drivers/pinctrl/qcom/pinctrl-msm.h @@ -147,6 +147,8 @@ struct msm_gpio_wakeirq_map { * @pull_no_keeper: The SoC does not support keeper bias. * @wakeirq_map: The map of wakeup capable GPIOs and the pin at PDC/MPM * @nwakeirq_map: The number of entries in @hierarchy_map + * @no_wake_gpios: The list of non-wakeup capable GPIOs + * @n_no_wake_gpios:The number of entries in non-wakeup capable gpios * @dir_conn: An array describing all the pins directly connected to GIC. */ struct msm_pinctrl_soc_data { @@ -163,6 +165,8 @@ struct msm_pinctrl_soc_data { const int *reserved_gpios; const struct msm_gpio_wakeirq_map *wakeirq_map; unsigned int nwakeirq_map; + unsigned int *no_wake_gpios; + unsigned int n_no_wake_gpios; struct pinctrl_qup *qup_regs; unsigned int nqup_regs; struct msm_dir_conn *dir_conn;