Commit 374e72d7 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'intel-pinctrl-v5.19-2' of...

Merge tag 'intel-pinctrl-v5.19-2' of gitolite.kernel.org:pub/scm/linux/kernel/git/pinctrl/intel into devel

intel-pinctrl for v5.19-2

* Fix immutable IRQ chip examples in the GPIO documentation
* Make use of immutable IRQ chip in Intel pin control drivers
* Add module alias for Intel Apollo Lake

The following is an automated git shortlog grouped by driver:

baytrail:
 -  make irq_chip immutable

broxton:
 -  Add module alias for Intel Apollo Lake

cherryview:
 -  Use GPIO chip pointer in chv_gpio_irq_mask_unmask()
 -  make irq_chip immutable

Documentation:
 -  gpio: Advertise irqd_to_hwirq() helper in the examples
 -  gpio: Fix IRQ mask and unmask examples

intel:
 -  Fix kernel doc format, i.e. add return sections
 -  Drop unused irqchip member in struct intel_pinctrl
 -  make irq_chip immutable

lynxpoint:
 -  make irq_chip immutable
parents 80a50466 7b923e67
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -429,7 +429,8 @@ call into the core gpiolib code:

  static void my_gpio_mask_irq(struct irq_data *d)
  {
      struct gpio_chip *gc = irq_desc_get_handler_data(d);
      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
      irq_hw_number_t hwirq = irqd_to_hwirq(d);

      /*
       * Perform any necessary action to mask the interrupt,
@@ -437,14 +438,15 @@ call into the core gpiolib code:
       * state.
       */

      gpiochip_disable_irq(gc, d->hwirq);
      gpiochip_disable_irq(gc, hwirq);
  }

  static void my_gpio_unmask_irq(struct irq_data *d)
  {
      struct gpio_chip *gc = irq_desc_get_handler_data(d);
      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
      irq_hw_number_t hwirq = irqd_to_hwirq(d);

      gpiochip_enable_irq(gc, d->hwirq);
      gpiochip_enable_irq(gc, hwirq);

      /*
       * Perform any necessary action to unmask the interrupt,
@@ -501,7 +503,8 @@ the interrupt separately and go with it:

  static void my_gpio_mask_irq(struct irq_data *d)
  {
      struct gpio_chip *gc = irq_desc_get_handler_data(d);
      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
      irq_hw_number_t hwirq = irqd_to_hwirq(d);

      /*
       * Perform any necessary action to mask the interrupt,
@@ -509,14 +512,15 @@ the interrupt separately and go with it:
       * state.
       */

      gpiochip_disable_irq(gc, d->hwirq);
      gpiochip_disable_irq(gc, hwirq);
  }

  static void my_gpio_unmask_irq(struct irq_data *d)
  {
      struct gpio_chip *gc = irq_desc_get_handler_data(d);
      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
      irq_hw_number_t hwirq = irqd_to_hwirq(d);

      gpiochip_enable_irq(gc, d->hwirq);
      gpiochip_enable_irq(gc, hwirq);

      /*
       * Perform any necessary action to unmask the interrupt,
@@ -576,7 +580,8 @@ In this case the typical set-up will look like this:

  static void my_gpio_mask_irq(struct irq_data *d)
  {
      struct gpio_chip *gc = irq_desc_get_handler_data(d);
      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
      irq_hw_number_t hwirq = irqd_to_hwirq(d);

      /*
       * Perform any necessary action to mask the interrupt,
@@ -584,15 +589,16 @@ In this case the typical set-up will look like this:
       * state.
       */

      gpiochip_disable_irq(gc, d->hwirq);
      gpiochip_disable_irq(gc, hwirq);
      irq_mask_mask_parent(d);
  }

  static void my_gpio_unmask_irq(struct irq_data *d)
  {
      struct gpio_chip *gc = irq_desc_get_handler_data(d);
      struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
      irq_hw_number_t hwirq = irqd_to_hwirq(d);

      gpiochip_enable_irq(gc, d->hwirq);
      gpiochip_enable_irq(gc, hwirq);

      /*
       * Perform any necessary action to unmask the interrupt,
+25 −17
Original line number Diff line number Diff line
@@ -1350,15 +1350,15 @@ static void byt_irq_ack(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *vg = gpiochip_get_data(gc);
	unsigned int offset = irqd_to_hwirq(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	void __iomem *reg;

	reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
	reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG);
	if (!reg)
		return;

	raw_spin_lock(&byt_lock);
	writel(BIT(offset % 32), reg);
	writel(BIT(hwirq % 32), reg);
	raw_spin_unlock(&byt_lock);
}

@@ -1366,20 +1366,24 @@ static void byt_irq_mask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *vg = gpiochip_get_data(gc);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
	byt_gpio_clear_triggering(vg, hwirq);
	gpiochip_disable_irq(gc, hwirq);
}

static void byt_irq_unmask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *vg = gpiochip_get_data(gc);
	unsigned int offset = irqd_to_hwirq(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	unsigned long flags;
	void __iomem *reg;
	u32 value;

	reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
	gpiochip_enable_irq(gc, hwirq);

	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
	if (!reg)
		return;

@@ -1412,12 +1416,13 @@ static void byt_irq_unmask(struct irq_data *d)
static int byt_irq_type(struct irq_data *d, unsigned int type)
{
	struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
	u32 offset = irqd_to_hwirq(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	u32 value;
	unsigned long flags;
	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
	void __iomem *reg;

	if (!reg || offset >= vg->chip.ngpio)
	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
	if (!reg)
		return -EINVAL;

	raw_spin_lock_irqsave(&byt_lock, flags);
@@ -1447,6 +1452,16 @@ static int byt_irq_type(struct irq_data *d, unsigned int type)
	return 0;
}

static const struct irq_chip byt_gpio_irq_chip = {
	.name		= "BYT-GPIO",
	.irq_ack	= byt_irq_ack,
	.irq_mask	= byt_irq_mask,
	.irq_unmask	= byt_irq_unmask,
	.irq_set_type	= byt_irq_type,
	.flags		= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static void byt_gpio_irq_handler(struct irq_desc *desc)
{
	struct irq_data *data = irq_desc_get_irq_data(desc);
@@ -1633,15 +1648,8 @@ static int byt_gpio_probe(struct intel_pinctrl *vg)
	if (irq > 0) {
		struct gpio_irq_chip *girq;

		vg->irqchip.name = "BYT-GPIO",
		vg->irqchip.irq_ack = byt_irq_ack,
		vg->irqchip.irq_mask = byt_irq_mask,
		vg->irqchip.irq_unmask = byt_irq_unmask,
		vg->irqchip.irq_set_type = byt_irq_type,
		vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED,

		girq = &gc->irq;
		girq->chip = &vg->irqchip;
		gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip);
		girq->init_hw = byt_gpio_irq_init_hw;
		girq->init_valid_mask = byt_init_irq_valid_mask;
		girq->parent_handler = byt_gpio_irq_handler;
+1 −0
Original line number Diff line number Diff line
@@ -1035,4 +1035,5 @@ module_exit(bxt_pinctrl_exit);
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:apollolake-pinctrl");
MODULE_ALIAS("platform:broxton-pinctrl");
+38 −28
Original line number Diff line number Diff line
@@ -1242,12 +1242,12 @@ static void chv_gpio_irq_ack(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
	int pin = irqd_to_hwirq(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	u32 intr_line;

	raw_spin_lock(&chv_lock);

	intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0);
	intr_line = chv_readl(pctrl, hwirq, CHV_PADCTRL0);
	intr_line &= CHV_PADCTRL0_INTSEL_MASK;
	intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;
	chv_pctrl_writel(pctrl, CHV_INTSTAT, BIT(intr_line));
@@ -1255,17 +1255,15 @@ static void chv_gpio_irq_ack(struct irq_data *d)
	raw_spin_unlock(&chv_lock);
}

static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
static void chv_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwirq, bool mask)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
	int pin = irqd_to_hwirq(d);
	u32 value, intr_line;
	unsigned long flags;

	raw_spin_lock_irqsave(&chv_lock, flags);

	intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0);
	intr_line = chv_readl(pctrl, hwirq, CHV_PADCTRL0);
	intr_line &= CHV_PADCTRL0_INTSEL_MASK;
	intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT;

@@ -1281,12 +1279,20 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask)

static void chv_gpio_irq_mask(struct irq_data *d)
{
	chv_gpio_irq_mask_unmask(d, true);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	chv_gpio_irq_mask_unmask(gc, hwirq, true);
	gpiochip_disable_irq(gc, hwirq);
}

static void chv_gpio_irq_unmask(struct irq_data *d)
{
	chv_gpio_irq_mask_unmask(d, false);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	gpiochip_enable_irq(gc, hwirq);
	chv_gpio_irq_mask_unmask(gc, hwirq, false);
}

static unsigned chv_gpio_irq_startup(struct irq_data *d)
@@ -1306,17 +1312,17 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)
		struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
		struct device *dev = pctrl->dev;
		struct intel_community_context *cctx = &pctrl->context.communities[0];
		unsigned int pin = irqd_to_hwirq(d);
		irq_hw_number_t hwirq = irqd_to_hwirq(d);
		irq_flow_handler_t handler;
		unsigned long flags;
		u32 intsel, value;

		raw_spin_lock_irqsave(&chv_lock, flags);
		intsel = chv_readl(pctrl, pin, CHV_PADCTRL0);
		intsel = chv_readl(pctrl, hwirq, CHV_PADCTRL0);
		intsel &= CHV_PADCTRL0_INTSEL_MASK;
		intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;

		value = chv_readl(pctrl, pin, CHV_PADCTRL1);
		value = chv_readl(pctrl, hwirq, CHV_PADCTRL1);
		if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL)
			handler = handle_level_irq;
		else
@@ -1324,9 +1330,9 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d)

		if (cctx->intr_lines[intsel] == CHV_INVALID_HWIRQ) {
			irq_set_handler_locked(d, handler);
			dev_dbg(dev, "using interrupt line %u for IRQ_TYPE_NONE on pin %u\n",
				intsel, pin);
			cctx->intr_lines[intsel] = pin;
			dev_dbg(dev, "using interrupt line %u for IRQ_TYPE_NONE on pin %lu\n",
				intsel, hwirq);
			cctx->intr_lines[intsel] = hwirq;
		}
		raw_spin_unlock_irqrestore(&chv_lock, flags);
	}
@@ -1392,14 +1398,14 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
	unsigned int pin = irqd_to_hwirq(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	unsigned long flags;
	u32 value;
	int ret;

	raw_spin_lock_irqsave(&chv_lock, flags);

	ret = chv_gpio_set_intr_line(pctrl, pin);
	ret = chv_gpio_set_intr_line(pctrl, hwirq);
	if (ret)
		goto out_unlock;

@@ -1416,8 +1422,8 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type)
	 * 2. If the pin cfg is not locked in BIOS:
	 *	Driver programs the IntWakeCfg bits and save the mapping.
	 */
	if (!chv_pad_locked(pctrl, pin)) {
		value = chv_readl(pctrl, pin, CHV_PADCTRL1);
	if (!chv_pad_locked(pctrl, hwirq)) {
		value = chv_readl(pctrl, hwirq, CHV_PADCTRL1);
		value &= ~CHV_PADCTRL1_INTWAKECFG_MASK;
		value &= ~CHV_PADCTRL1_INVRXTX_MASK;

@@ -1434,7 +1440,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type)
				value |= CHV_PADCTRL1_INVRXTX_RXDATA;
		}

		chv_writel(pctrl, pin, CHV_PADCTRL1, value);
		chv_writel(pctrl, hwirq, CHV_PADCTRL1, value);
	}

	if (type & IRQ_TYPE_EDGE_BOTH)
@@ -1448,6 +1454,17 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type)
	return ret;
}

static const struct irq_chip chv_gpio_irq_chip = {
	.name		= "chv-gpio",
	.irq_startup	= chv_gpio_irq_startup,
	.irq_ack	= chv_gpio_irq_ack,
	.irq_mask	= chv_gpio_irq_mask,
	.irq_unmask	= chv_gpio_irq_unmask,
	.irq_set_type	= chv_gpio_irq_type,
	.flags		= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static void chv_gpio_irq_handler(struct irq_desc *desc)
{
	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
@@ -1611,15 +1628,8 @@ static int chv_gpio_probe(struct intel_pinctrl *pctrl, int irq)
	chip->base = -1;

	pctrl->irq = irq;
	pctrl->irqchip.name = "chv-gpio";
	pctrl->irqchip.irq_startup = chv_gpio_irq_startup;
	pctrl->irqchip.irq_ack = chv_gpio_irq_ack;
	pctrl->irqchip.irq_mask = chv_gpio_irq_mask;
	pctrl->irqchip.irq_unmask = chv_gpio_irq_unmask;
	pctrl->irqchip.irq_set_type = chv_gpio_irq_type;
	pctrl->irqchip.flags = IRQCHIP_SKIP_SET_WAKE;

	chip->irq.chip = &pctrl->irqchip;

	gpio_irq_chip_set_chip(&chip->irq, &chv_gpio_irq_chip);
	chip->irq.init_hw = chv_gpio_irq_init_hw;
	chip->irq.parent_handler = chv_gpio_irq_handler;
	chip->irq.num_parents = 1;
+30 −15
Original line number Diff line number Diff line
@@ -858,6 +858,9 @@ static const struct pinctrl_desc intel_pinctrl_desc = {
 * When coming through gpiolib irqchip, the GPIO offset is not
 * automatically translated to pinctrl pin number. This function can be
 * used to find out the corresponding pinctrl pin.
 *
 * Return: a pin number and pointers to the community and pad group, which
 * the pin belongs to, or negative error code if translation can't be done.
 */
static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
			     const struct intel_community **community,
@@ -899,6 +902,8 @@ static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset,
 * @pin: pin number
 *
 * Translate the pin number of pinctrl to GPIO offset
 *
 * Return: a GPIO offset, or negative error code if translation can't be done.
 */
static __maybe_unused int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin)
{
@@ -1039,15 +1044,14 @@ static void intel_gpio_irq_ack(struct irq_data *d)
	}
}

static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)
static void intel_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwirq, bool mask)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
	const struct intel_community *community;
	const struct intel_padgroup *padgrp;
	int pin;

	pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp);
	pin = intel_gpio_to_pin(pctrl, hwirq, &community, &padgrp);
	if (pin >= 0) {
		unsigned int gpp, gpp_offset;
		unsigned long flags;
@@ -1077,12 +1081,20 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask)

static void intel_gpio_irq_mask(struct irq_data *d)
{
	intel_gpio_irq_mask_unmask(d, true);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	intel_gpio_irq_mask_unmask(gc, hwirq, true);
	gpiochip_disable_irq(gc, hwirq);
}

static void intel_gpio_irq_unmask(struct irq_data *d)
{
	intel_gpio_irq_mask_unmask(d, false);
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	gpiochip_enable_irq(gc, hwirq);
	intel_gpio_irq_mask_unmask(gc, hwirq, false);
}

static int intel_gpio_irq_type(struct irq_data *d, unsigned int type)
@@ -1157,6 +1169,17 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on)
	return 0;
}

static const struct irq_chip intel_gpio_irq_chip = {
	.name = "intel-gpio",
	.irq_ack = intel_gpio_irq_ack,
	.irq_mask = intel_gpio_irq_mask,
	.irq_unmask = intel_gpio_irq_unmask,
	.irq_set_type = intel_gpio_irq_type,
	.irq_set_wake = intel_gpio_irq_wake,
	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl,
					    const struct intel_community *community)
{
@@ -1319,15 +1342,6 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
	pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges;
	pctrl->irq = irq;

	/* Setup IRQ chip */
	pctrl->irqchip.name = dev_name(pctrl->dev);
	pctrl->irqchip.irq_ack = intel_gpio_irq_ack;
	pctrl->irqchip.irq_mask = intel_gpio_irq_mask;
	pctrl->irqchip.irq_unmask = intel_gpio_irq_unmask;
	pctrl->irqchip.irq_set_type = intel_gpio_irq_type;
	pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake;
	pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND;

	/*
	 * On some platforms several GPIO controllers share the same interrupt
	 * line.
@@ -1340,8 +1354,9 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq)
		return ret;
	}

	/* Setup IRQ chip */
	girq = &pctrl->chip.irq;
	girq->chip = &pctrl->irqchip;
	gpio_irq_chip_set_chip(girq, &intel_gpio_irq_chip);
	/* This will let us handle the IRQ in the driver */
	girq->parent_handler = NULL;
	girq->num_parents = 0;
Loading