Commit ed43f2b4 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'intel-gpio-v5.8-1' of...

Merge tag 'intel-gpio-v5.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel into devel

intel-gpio for v5.8-1

* MSI support for Intel Merrifield
* Refactor gpio-pch to be up-to-date with recent kernel APIs
* Miscellaneous cleanups here and there

The following is an automated git shortlog grouped by driver:

ich:
 -  fix a typo

merrifield:
 -  Better show how GPIO and IRQ bases are derived from hardware
 -  Switch over to MSI interrupts

pch:
 -  Use in pch_irq_type() macros provided by IRQ core
 -  Refactor pch_irq_type() to avoid unnecessary locking
 -  Get rid of unneeded variable in IRQ handler
 -  Use BIT() and GENMASK() where it's appropriate
parents 29f9f8e1 7e73aa90
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ static struct {
	struct device *dev;
	struct gpio_chip chip;
	struct resource *gpio_base;	/* GPIO IO base */
	struct resource *pm_base;	/* Power Mangagment IO base */
	struct resource *pm_base;	/* Power Management IO base */
	struct ichx_desc *desc;	/* Pointer to chipset-specific description */
	u32 orig_gpio_ctrl;	/* Orig CTRL value, used to restore on exit */
	u8 use_gpio;		/* Which GPIO groups are usable */
+7 −3
Original line number Diff line number Diff line
@@ -443,8 +443,8 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id

	base = pcim_iomap_table(pdev)[1];

	irq_base = readl(base);
	gpio_base = readl(sizeof(u32) + base);
	irq_base = readl(base + 0 * sizeof(u32));
	gpio_base = readl(base + 1 * sizeof(u32));

	/* Release the IO mapping, since we already get the info from BAR1 */
	pcim_iounmap_regions(pdev, BIT(1));
@@ -473,6 +473,10 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id

	raw_spin_lock_init(&priv->lock);

	retval = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
	if (retval < 0)
		return retval;

	girq = &priv->chip.irq;
	girq->chip = &mrfld_irqchip;
	girq->init_hw = mrfld_irq_init_hw;
@@ -482,7 +486,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
				     sizeof(*girq->parents), GFP_KERNEL);
	if (!girq->parents)
		return -ENOMEM;
	girq->parents[0] = pdev->irq;
	girq->parents[0] = pci_irq_vector(pdev, 0);
	girq->first = irq_base;
	girq->default_type = IRQ_TYPE_NONE;
	girq->handler = handle_bad_irq;
+37 −36
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
/*
 * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
 */
#include <linux/bits.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
@@ -11,11 +12,11 @@
#include <linux/slab.h>

#define PCH_EDGE_FALLING	0
#define PCH_EDGE_RISING		BIT(0)
#define PCH_LEVEL_L		BIT(1)
#define PCH_LEVEL_H		(BIT(0) | BIT(1))
#define PCH_EDGE_BOTH		BIT(2)
#define PCH_IM_MASK		(BIT(0) | BIT(1) | BIT(2))
#define PCH_EDGE_RISING		1
#define PCH_LEVEL_L		2
#define PCH_LEVEL_H		3
#define PCH_EDGE_BOTH		4
#define PCH_IM_MASK		GENMASK(2, 0)

#define PCH_IRQ_BASE		24

@@ -103,9 +104,9 @@ static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
	spin_lock_irqsave(&chip->spinlock, flags);
	reg_val = ioread32(&chip->reg->po);
	if (val)
		reg_val |= (1 << nr);
		reg_val |= BIT(nr);
	else
		reg_val &= ~(1 << nr);
		reg_val &= ~BIT(nr);

	iowrite32(reg_val, &chip->reg->po);
	spin_unlock_irqrestore(&chip->spinlock, flags);
@@ -115,7 +116,7 @@ static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr)
{
	struct pch_gpio *chip =	gpiochip_get_data(gpio);

	return (ioread32(&chip->reg->pi) >> nr) & 1;
	return !!(ioread32(&chip->reg->pi) & BIT(nr));
}

static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
@@ -130,13 +131,14 @@ static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,

	reg_val = ioread32(&chip->reg->po);
	if (val)
		reg_val |= (1 << nr);
		reg_val |= BIT(nr);
	else
		reg_val &= ~(1 << nr);
		reg_val &= ~BIT(nr);
	iowrite32(reg_val, &chip->reg->po);

	pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1);
	pm |= (1 << nr);
	pm = ioread32(&chip->reg->pm);
	pm &= BIT(gpio_pins[chip->ioh]) - 1;
	pm |= BIT(nr);
	iowrite32(pm, &chip->reg->pm);

	spin_unlock_irqrestore(&chip->spinlock, flags);
@@ -151,8 +153,9 @@ static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
	unsigned long flags;

	spin_lock_irqsave(&chip->spinlock, flags);
	pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1);
	pm &= ~(1 << nr);
	pm = ioread32(&chip->reg->pm);
	pm &= BIT(gpio_pins[chip->ioh]) - 1;
	pm &= ~BIT(nr);
	iowrite32(pm, &chip->reg->pm);
	spin_unlock_irqrestore(&chip->spinlock, flags);

@@ -226,17 +229,15 @@ static int pch_irq_type(struct irq_data *d, unsigned int type)
	int ch, irq = d->irq;

	ch = irq - chip->irq_base;
	if (irq <= chip->irq_base + 7) {
	if (irq < chip->irq_base + 8) {
		im_reg = &chip->reg->im0;
		im_pos = ch;
		im_pos = ch - 0;
	} else {
		im_reg = &chip->reg->im1;
		im_pos = ch - 8;
	}
	dev_dbg(chip->dev, "irq=%d type=%d ch=%d pos=%d\n", irq, type, ch, im_pos);

	spin_lock_irqsave(&chip->spinlock, flags);

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		val = PCH_EDGE_RISING;
@@ -254,20 +255,21 @@ static int pch_irq_type(struct irq_data *d, unsigned int type)
		val = PCH_LEVEL_L;
		break;
	default:
		goto unlock;
		return 0;
	}

	spin_lock_irqsave(&chip->spinlock, flags);

	/* Set interrupt mode */
	im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4));
	iowrite32(im | (val << (im_pos * 4)), im_reg);

	/* And the handler */
	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
	if (type & IRQ_TYPE_LEVEL_MASK)
		irq_set_handler_locked(d, handle_level_irq);
	else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
	else if (type & IRQ_TYPE_EDGE_BOTH)
		irq_set_handler_locked(d, handle_edge_irq);

unlock:
	spin_unlock_irqrestore(&chip->spinlock, flags);
	return 0;
}
@@ -277,7 +279,7 @@ static void pch_irq_unmask(struct irq_data *d)
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct pch_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imaskclr);
	iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->imaskclr);
}

static void pch_irq_mask(struct irq_data *d)
@@ -285,7 +287,7 @@ static void pch_irq_mask(struct irq_data *d)
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct pch_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask);
	iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->imask);
}

static void pch_irq_ack(struct irq_data *d)
@@ -293,21 +295,22 @@ static void pch_irq_ack(struct irq_data *d)
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct pch_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr);
	iowrite32(BIT(d->irq - chip->irq_base), &chip->reg->iclr);
}

static irqreturn_t pch_gpio_handler(int irq, void *dev_id)
{
	struct pch_gpio *chip = dev_id;
	unsigned long reg_val = ioread32(&chip->reg->istatus);
	int i, ret = IRQ_NONE;
	int i;

	for_each_set_bit(i, &reg_val, gpio_pins[chip->ioh]) {
		dev_dbg(chip->dev, "[%d]:irq=%d  status=0x%lx\n", i, irq, reg_val);
	dev_dbg(chip->dev, "irq=%d  status=0x%lx\n", irq, reg_val);

	reg_val &= BIT(gpio_pins[chip->ioh]) - 1;
	for_each_set_bit(i, &reg_val, gpio_pins[chip->ioh])
		generic_handle_irq(chip->irq_base + i);
		ret = IRQ_HANDLED;
	}
	return ret;

	return IRQ_RETVAL(reg_val);
}

static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
@@ -344,7 +347,6 @@ static int pch_gpio_probe(struct pci_dev *pdev,
	s32 ret;
	struct pch_gpio *chip;
	int irq_base;
	u32 msk;

	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
@@ -357,7 +359,7 @@ static int pch_gpio_probe(struct pci_dev *pdev,
		return ret;
	}

	ret = pcim_iomap_regions(pdev, 1 << 1, KBUILD_MODNAME);
	ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME);
	if (ret) {
		dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret);
		return ret;
@@ -393,9 +395,8 @@ static int pch_gpio_probe(struct pci_dev *pdev,
	chip->irq_base = irq_base;

	/* Mask all interrupts, but enable them */
	msk = (1 << gpio_pins[chip->ioh]) - 1;
	iowrite32(msk, &chip->reg->imask);
	iowrite32(msk, &chip->reg->ien);
	iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->imask);
	iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->ien);

	ret = devm_request_irq(&pdev->dev, pdev->irq, pch_gpio_handler,
			       IRQF_SHARED, KBUILD_MODNAME, chip);