Commit 14dbe186 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

pinctrl: msmgpio: Make the irqchip immutable



Prevent gpiolib from messing with the irqchip by advertising
the irq_chip structure as immutable, making it const, and adding
the various calls that gpiolib relies upon.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20220419141846.598305-8-maz@kernel.org
parent 374b87a0
Loading
Loading
Loading
Loading
+33 −20
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@
 * @chip:           gpiochip handle.
 * @desc:           pin controller descriptor
 * @restart_nb:     restart notifier block.
 * @irq_chip:       irq chip information
 * @irq:            parent irq for the TLMM irq_chip.
 * @intr_target_use_scm: route irq to application cpu using scm calls
 * @lock:           Spinlock to protect register resources as well
@@ -63,7 +62,6 @@ struct msm_pinctrl {
	struct pinctrl_desc desc;
	struct notifier_block restart_nb;

	struct irq_chip irq_chip;
	int irq;

	bool intr_target_use_scm;
@@ -868,6 +866,8 @@ static void msm_gpio_irq_enable(struct irq_data *d)
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct msm_pinctrl *pctrl = gpiochip_get_data(gc);

	gpiochip_enable_irq(gc, d->hwirq);

	if (d->parent_data)
		irq_chip_enable_parent(d);

@@ -885,6 +885,8 @@ static void msm_gpio_irq_disable(struct irq_data *d)

	if (!test_bit(d->hwirq, pctrl->skip_wake_irqs))
		msm_gpio_irq_mask(d);

	gpiochip_disable_irq(gc, d->hwirq);
}

/**
@@ -958,6 +960,14 @@ static void msm_gpio_irq_ack(struct irq_data *d)
	raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}

static void msm_gpio_irq_eoi(struct irq_data *d)
{
	d = d->parent_data;

	if (d)
		d->chip->irq_eoi(d);
}

static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d,
						       unsigned int type)
{
@@ -1255,6 +1265,26 @@ static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
	return device_property_count_u16(pctrl->dev, "gpios") > 0;
}

static const struct irq_chip msm_gpio_irq_chip = {
	.name			= "msmgpio",
	.irq_enable		= msm_gpio_irq_enable,
	.irq_disable		= msm_gpio_irq_disable,
	.irq_mask		= msm_gpio_irq_mask,
	.irq_unmask		= msm_gpio_irq_unmask,
	.irq_ack		= msm_gpio_irq_ack,
	.irq_eoi		= msm_gpio_irq_eoi,
	.irq_set_type		= msm_gpio_irq_set_type,
	.irq_set_wake		= msm_gpio_irq_set_wake,
	.irq_request_resources	= msm_gpio_irq_reqres,
	.irq_release_resources	= msm_gpio_irq_relres,
	.irq_set_affinity	= msm_gpio_irq_set_affinity,
	.irq_set_vcpu_affinity	= msm_gpio_irq_set_vcpu_affinity,
	.flags			= (IRQCHIP_MASK_ON_SUSPEND |
				   IRQCHIP_SET_TYPE_MASKED |
				   IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND |
				   IRQCHIP_IMMUTABLE),
};

static int msm_gpio_init(struct msm_pinctrl *pctrl)
{
	struct gpio_chip *chip;
@@ -1276,22 +1306,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
	if (msm_gpio_needs_valid_mask(pctrl))
		chip->init_valid_mask = msm_gpio_init_valid_mask;

	pctrl->irq_chip.name = "msmgpio";
	pctrl->irq_chip.irq_enable = msm_gpio_irq_enable;
	pctrl->irq_chip.irq_disable = msm_gpio_irq_disable;
	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;
	pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type;
	pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake;
	pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres;
	pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres;
	pctrl->irq_chip.irq_set_affinity = msm_gpio_irq_set_affinity;
	pctrl->irq_chip.irq_set_vcpu_affinity = msm_gpio_irq_set_vcpu_affinity;
	pctrl->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND |
				IRQCHIP_SET_TYPE_MASKED |
				IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND;

	np = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0);
	if (np) {
		chip->irq.parent_domain = irq_find_matching_host(np,
@@ -1300,7 +1314,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
		if (!chip->irq.parent_domain)
			return -EPROBE_DEFER;
		chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq;
		pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent;
		/*
		 * Let's skip handling the GPIOs, if the parent irqchip
		 * is handling the direct connect IRQ of the GPIO.
@@ -1313,7 +1326,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
	}

	girq = &chip->irq;
	girq->chip = &pctrl->irq_chip;
	gpio_irq_chip_set_chip(girq, &msm_gpio_irq_chip);
	girq->parent_handler = msm_gpio_irq_handler;
	girq->fwnode = pctrl->dev->fwnode;
	girq->num_parents = 1;