int ret;
unsigned int len, i;
unsigned int max_gpios = pctrl->soc->ngpios;
+ const int *reserved = pctrl->soc->reserved_gpios;
u16 *tmp;
+ /* Driver provided reserved list overrides DT and ACPI */
+ if (reserved) {
+ bitmap_fill(chip->valid_mask, max_gpios);
+ for (i = 0; reserved[i] >= 0; i++) {
+ if (i >= max_gpios || reserved[i] >= max_gpios) {
+ dev_err(pctrl->dev, "invalid list of reserved GPIOs\n");
+ return -EINVAL;
+ }
+ clear_bit(reserved[i], chip->valid_mask);
+ }
+
+ return 0;
+ }
+
/* The number of GPIOs in the ACPI tables */
len = ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL,
0);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
-static void msm_gpio_irq_unmask(struct irq_data *d)
+static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
raw_spin_lock_irqsave(&pctrl->lock, flags);
+ if (status_clear) {
+ /*
+ * clear the interrupt status bit before unmask to avoid
+ * any erroneous interrupts that would have got latched
+ * when the interrupt is not in use.
+ */
+ val = msm_readl_intr_status(pctrl, g);
+ val &= ~BIT(g->intr_status_bit);
+ msm_writel_intr_status(val, pctrl, g);
+ }
+
val = msm_readl_intr_cfg(pctrl, g);
val |= BIT(g->intr_raw_status_bit);
val |= BIT(g->intr_enable_bit);
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
+static void msm_gpio_irq_enable(struct irq_data *d)
+{
+
+ msm_gpio_irq_clear_unmask(d, true);
+}
+
+static void msm_gpio_irq_unmask(struct irq_data *d)
+{
+ msm_gpio_irq_clear_unmask(d, false);
+}
+
static void msm_gpio_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
{
+ if (pctrl->soc->reserved_gpios)
+ return true;
+
return device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0) > 0;
}
chip->need_valid_mask = msm_gpio_needs_valid_mask(pctrl);
pctrl->irq_chip.name = "msmgpio";
+ pctrl->irq_chip.irq_enable = msm_gpio_irq_enable;
pctrl->irq_chip.irq_mask = msm_gpio_irq_mask;
pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask;
pctrl->irq_chip.irq_ack = msm_gpio_irq_ack;