Commit ca7e7822 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

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

Merge tag 'intel-gpio-v5.17-1' of gitolite.kernel.org:pub/scm/linux/kernel/git/andy/linux-gpio-intel into gpio/for-next

intel-gpio for v5.17-1

- Don't set type for IRQ already in use in case of ACPI
- Drop unused call from GPIO ACPI library
- Clean up ML IOH and PCH GPIO drivers to make it closer to each other
- Clarify use of register file version in DesignWare driver
- other minor tweaks
parents c73960bb 9d5f0f66
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -53,7 +53,9 @@
#define GPIO_SWPORT_DR_STRIDE	0x0c /* register stride 3*32 bits */
#define GPIO_SWPORT_DDR_STRIDE	0x0c /* register stride 3*32 bits */

#define GPIO_REG_OFFSET_V1	0
#define GPIO_REG_OFFSET_V2	1
#define GPIO_REG_OFFSET_MASK	BIT(0)

#define GPIO_INTMASK_V2		0x44
#define GPIO_INTTYPE_LEVEL_V2	0x34
@@ -141,7 +143,7 @@ static inline u32 gpio_reg_v2_convert(unsigned int offset)

static inline u32 gpio_reg_convert(struct dwapb_gpio *gpio, unsigned int offset)
{
	if (gpio->flags & GPIO_REG_OFFSET_V2)
	if ((gpio->flags & GPIO_REG_OFFSET_MASK) == GPIO_REG_OFFSET_V2)
		return gpio_reg_v2_convert(offset);

	return offset;
@@ -668,15 +670,15 @@ static int dwapb_get_clks(struct dwapb_gpio *gpio)
}

static const struct of_device_id dwapb_of_match[] = {
	{ .compatible = "snps,dw-apb-gpio", .data = (void *)0},
	{ .compatible = "snps,dw-apb-gpio", .data = (void *)GPIO_REG_OFFSET_V1},
	{ .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2},
	{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, dwapb_of_match);

static const struct acpi_device_id dwapb_acpi_match[] = {
	{"HISI0181", 0},
	{"APMC0D07", 0},
	{"HISI0181", GPIO_REG_OFFSET_V1},
	{"APMC0D07", GPIO_REG_OFFSET_V1},
	{"APMC0D81", GPIO_REG_OFFSET_V2},
	{ }
};
+26 −26
Original line number Diff line number Diff line
@@ -98,9 +98,9 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
	spin_lock_irqsave(&chip->spinlock, flags);
	reg_val = ioread32(&chip->reg->regs[chip->ch].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->regs[chip->ch].po);
	spin_unlock_irqrestore(&chip->spinlock, flags);
@@ -110,7 +110,7 @@ static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
{
	struct ioh_gpio *chip =	gpiochip_get_data(gpio);

	return !!(ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr));
	return !!(ioread32(&chip->reg->regs[chip->ch].pi) & BIT(nr));
}

static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
@@ -122,16 +122,16 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
	unsigned long flags;

	spin_lock_irqsave(&chip->spinlock, flags);
	pm = ioread32(&chip->reg->regs[chip->ch].pm) &
					((1 << num_ports[chip->ch]) - 1);
	pm |= (1 << nr);
	pm = ioread32(&chip->reg->regs[chip->ch].pm);
	pm &= BIT(num_ports[chip->ch]) - 1;
	pm |= BIT(nr);
	iowrite32(pm, &chip->reg->regs[chip->ch].pm);

	reg_val = ioread32(&chip->reg->regs[chip->ch].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->regs[chip->ch].po);

	spin_unlock_irqrestore(&chip->spinlock, flags);
@@ -146,9 +146,9 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
	unsigned long flags;

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

@@ -304,7 +304,7 @@ static void ioh_irq_unmask(struct irq_data *d)
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base),
	iowrite32(BIT(d->irq - chip->irq_base),
		  &chip->reg->regs[chip->ch].imaskclr);
}

@@ -313,7 +313,7 @@ static void ioh_irq_mask(struct irq_data *d)
	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
	struct ioh_gpio *chip = gc->private;

	iowrite32(1 << (d->irq - chip->irq_base),
	iowrite32(BIT(d->irq - chip->irq_base),
		  &chip->reg->regs[chip->ch].imask);
}

@@ -326,7 +326,7 @@ static void ioh_irq_disable(struct irq_data *d)

	spin_lock_irqsave(&chip->spinlock, flags);
	ien = ioread32(&chip->reg->regs[chip->ch].ien);
	ien &= ~(1 << (d->irq - chip->irq_base));
	ien &= ~BIT(d->irq - chip->irq_base);
	iowrite32(ien, &chip->reg->regs[chip->ch].ien);
	spin_unlock_irqrestore(&chip->spinlock, flags);
}
@@ -340,7 +340,7 @@ static void ioh_irq_enable(struct irq_data *d)

	spin_lock_irqsave(&chip->spinlock, flags);
	ien = ioread32(&chip->reg->regs[chip->ch].ien);
	ien |= 1 << (d->irq - chip->irq_base);
	ien |= BIT(d->irq - chip->irq_base);
	iowrite32(ien, &chip->reg->regs[chip->ch].ien);
	spin_unlock_irqrestore(&chip->spinlock, flags);
}
@@ -401,6 +401,7 @@ static int ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip,
static int ioh_gpio_probe(struct pci_dev *pdev,
				    const struct pci_device_id *id)
{
	struct device *dev = &pdev->dev;
	int ret;
	int i, j;
	struct ioh_gpio *chip;
@@ -410,19 +411,19 @@ static int ioh_gpio_probe(struct pci_dev *pdev,

	ret = pci_enable_device(pdev);
	if (ret) {
		dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__);
		dev_err(dev, "%s : pci_enable_device failed", __func__);
		goto err_pci_enable;
	}

	ret = pci_request_regions(pdev, KBUILD_MODNAME);
	if (ret) {
		dev_err(&pdev->dev, "pci_request_regions failed-%d", ret);
		dev_err(dev, "pci_request_regions failed-%d", ret);
		goto err_request_regions;
	}

	base = pci_iomap(pdev, 1, 0);
	if (!base) {
		dev_err(&pdev->dev, "%s : pci_iomap failed", __func__);
		dev_err(dev, "%s : pci_iomap failed", __func__);
		ret = -ENOMEM;
		goto err_iomap;
	}
@@ -435,7 +436,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev,

	chip = chip_save;
	for (i = 0; i < 8; i++, chip++) {
		chip->dev = &pdev->dev;
		chip->dev = dev;
		chip->base = base;
		chip->reg = chip->base;
		chip->ch = i;
@@ -443,17 +444,17 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
		ioh_gpio_setup(chip, num_ports[i]);
		ret = gpiochip_add_data(&chip->gpio, chip);
		if (ret) {
			dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n");
			dev_err(dev, "IOH gpio: Failed to register GPIO\n");
			goto err_gpiochip_add;
		}
	}

	chip = chip_save;
	for (j = 0; j < 8; j++, chip++) {
		irq_base = devm_irq_alloc_descs(&pdev->dev, -1, IOH_IRQ_BASE,
		irq_base = devm_irq_alloc_descs(dev, -1, IOH_IRQ_BASE,
						num_ports[j], NUMA_NO_NODE);
		if (irq_base < 0) {
			dev_warn(&pdev->dev,
			dev_warn(dev,
				"ml_ioh_gpio: Failed to get IRQ base num\n");
			ret = irq_base;
			goto err_gpiochip_add;
@@ -467,11 +468,10 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
	}

	chip = chip_save;
	ret = devm_request_irq(&pdev->dev, pdev->irq, ioh_gpio_handler,
	ret = devm_request_irq(dev, pdev->irq, ioh_gpio_handler,
			       IRQF_SHARED, KBUILD_MODNAME, chip);
	if (ret != 0) {
		dev_err(&pdev->dev,
			"%s request_irq failed\n", __func__);
		dev_err(dev, "%s request_irq failed\n", __func__);
		goto err_gpiochip_add;
	}

@@ -498,7 +498,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev,

err_pci_enable:

	dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret);
	dev_err(dev, "%s Failed returns %d\n", __func__, ret);
	return ret;
}

+20 −22
Original line number Diff line number Diff line
@@ -346,51 +346,45 @@ static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip,
static int pch_gpio_probe(struct pci_dev *pdev,
				    const struct pci_device_id *id)
{
	struct device *dev = &pdev->dev;
	s32 ret;
	struct pch_gpio *chip;
	int irq_base;

	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	chip->dev = &pdev->dev;
	chip->dev = dev;
	ret = pcim_enable_device(pdev);
	if (ret) {
		dev_err(&pdev->dev, "pci_enable_device FAILED");
		dev_err(dev, "pci_enable_device FAILED");
		return ret;
	}

	ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME);
	if (ret) {
		dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret);
		dev_err(dev, "pci_request_regions FAILED-%d", ret);
		return ret;
	}

	chip->base = pcim_iomap_table(pdev)[1];

	if (pdev->device == 0x8803)
		chip->ioh = INTEL_EG20T_PCH;
	else if (pdev->device == 0x8014)
		chip->ioh = OKISEMI_ML7223m_IOH;
	else if (pdev->device == 0x8043)
		chip->ioh = OKISEMI_ML7223n_IOH;

	chip->ioh = id->driver_data;
	chip->reg = chip->base;
	pci_set_drvdata(pdev, chip);
	spin_lock_init(&chip->spinlock);
	pch_gpio_setup(chip);

	ret = devm_gpiochip_add_data(&pdev->dev, &chip->gpio, chip);
	ret = devm_gpiochip_add_data(dev, &chip->gpio, chip);
	if (ret) {
		dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n");
		dev_err(dev, "PCH gpio: Failed to register GPIO\n");
		return ret;
	}

	irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0,
	irq_base = devm_irq_alloc_descs(dev, -1, 0,
					gpio_pins[chip->ioh], NUMA_NO_NODE);
	if (irq_base < 0) {
		dev_warn(&pdev->dev, "PCH gpio: Failed to get IRQ base num\n");
		dev_warn(dev, "PCH gpio: Failed to get IRQ base num\n");
		chip->irq_base = -1;
		return 0;
	}
@@ -400,10 +394,10 @@ static int pch_gpio_probe(struct pci_dev *pdev,
	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,
	ret = devm_request_irq(dev, pdev->irq, pch_gpio_handler,
			       IRQF_SHARED, KBUILD_MODNAME, chip);
	if (ret) {
		dev_err(&pdev->dev, "request_irq failed\n");
		dev_err(dev, "request_irq failed\n");
		return ret;
	}

@@ -439,10 +433,14 @@ static int __maybe_unused pch_gpio_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume);

static const struct pci_device_id pch_gpio_pcidev_id[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) },
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) },
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8043) },
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8803) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803),
	  .driver_data = INTEL_EG20T_PCH },
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014),
	  .driver_data = OKISEMI_ML7223m_IOH },
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8043),
	  .driver_data = OKISEMI_ML7223n_IOH },
	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8803),
	  .driver_data = INTEL_EG20T_PCH },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id);
+1 −1
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned int gpio_num,
	/*
	 * according to the datasheet, writing to the level register has no
	 * effect when GPIO is programmed as input.
	 * Actually the the level register is read-only when configured as input.
	 * Actually the level register is read-only when configured as input.
	 * Thus presetting the output level before switching to output is _NOT_ possible.
	 * Hence we set the level after configuring the GPIO as output.
	 * But we cannot prevent a short low pulse if direction is set to high
+22 −29
Original line number Diff line number Diff line
@@ -219,14 +219,13 @@ EXPORT_SYMBOL_GPL(acpi_gpio_get_io_resource);
static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
				      struct acpi_gpio_event *event)
{
	struct device *parent = acpi_gpio->chip->parent;
	int ret, value;

	ret = request_threaded_irq(event->irq, NULL, event->handler,
				   event->irqflags | IRQF_ONESHOT, "ACPI:Event", event);
	if (ret) {
		dev_err(acpi_gpio->chip->parent,
			"Failed to setup interrupt handler for %d\n",
			event->irq);
		dev_err(parent, "Failed to setup interrupt handler for %d\n", event->irq);
		return;
	}

@@ -347,8 +346,7 @@ static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in)

	return false;
err:
	pr_err_once("Error invalid value for gpiolib_acpi.ignore_wake: %s\n",
		    ignore_wake);
	pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_wake: %s\n", ignore_wake);
	return false;
}

@@ -579,36 +577,24 @@ void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
}
EXPORT_SYMBOL_GPL(acpi_dev_remove_driver_gpios);

static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res)
static void acpi_dev_release_driver_gpios(void *adev)
{
	acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev));
	acpi_dev_remove_driver_gpios(adev);
}

int devm_acpi_dev_add_driver_gpios(struct device *dev,
				   const struct acpi_gpio_mapping *gpios)
{
	void *res;
	struct acpi_device *adev = ACPI_COMPANION(dev);
	int ret;

	res = devres_alloc(devm_acpi_dev_release_driver_gpios, 0, GFP_KERNEL);
	if (!res)
		return -ENOMEM;

	ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), gpios);
	if (ret) {
		devres_free(res);
	ret = acpi_dev_add_driver_gpios(adev, gpios);
	if (ret)
		return ret;
	}
	devres_add(dev, res);
	return 0;
}
EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios);

void devm_acpi_dev_remove_driver_gpios(struct device *dev)
{
	WARN_ON(devres_release(dev, devm_acpi_dev_release_driver_gpios, NULL, NULL));
	return devm_add_action_or_reset(dev, acpi_dev_release_driver_gpios, adev);
}
EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios);
EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios);

static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
				      const char *name, int index,
@@ -941,7 +927,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev,

	if (info.gpioint &&
	    (*dflags == GPIOD_OUT_LOW || *dflags == GPIOD_OUT_HIGH)) {
		dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
		dev_dbg(&adev->dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
		return ERR_PTR(-ENOENT);
	}

@@ -1056,10 +1042,17 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind
			irq_flags = acpi_dev_get_irq_type(info.triggering,
							  info.polarity);

			/* Set type if specified and different than the current one */
			/*
			 * If the IRQ is not already in use then set type
			 * if specified and different than the current one.
			 */
			if (can_request_irq(irq, irq_flags)) {
				if (irq_flags != IRQ_TYPE_NONE &&
				    irq_flags != irq_get_trigger_type(irq))
					irq_set_irq_type(irq, irq_flags);
			} else {
				dev_dbg(&adev->dev, "IRQ %d already in use\n", irq);
			}

			return irq;
		}
Loading