pinctrl: qcom: Add support to disable gpio wakeup and direct connect

GPIOs that are in wakeirq_map have direct interrupt to GIC and they
do not use tlmm's summary irq. On certain devices its needed to
disable direct connect and gpio irq is not used for wakeup however
require to use tlmm's summary irq when device is awake.

Add support to list such gpios in target device tree and disable
wakeup and configure to not use direct connect interrupt.

Change-Id: I669f5df6d642679216e04708c54f620de8d9517b
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
This commit is contained in:
Maulik Shah 2021-02-23 14:13:28 +05:30
parent 98ed180626
commit 67f4ca01d3
3 changed files with 58 additions and 10 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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;