Commit 45fe0b53 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'gpio-fixes-for-v5.10-rc3' of...

Merge tag 'gpio-fixes-for-v5.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into fixes

gpio fixes for v5.10-rc3

- fix missing conversion to gpiolib irqchip in gpio-dwapb
- fix bank properties for ast2600 variant in gpio-aspeed
- make sysfs work again when the character device is disabled
- fix interrupt handling in gpio-pcie-idio-24
parents 7ffa0816 10a2f11d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1114,6 +1114,7 @@ static const struct aspeed_gpio_config ast2500_config =

static const struct aspeed_bank_props ast2600_bank_props[] = {
	/*     input	  output   */
	{4, 0xffffffff,  0x00ffffff}, /* Q/R/S/T */
	{5, 0xffffffff,  0xffffff00}, /* U/V/W/X */
	{6, 0x0000ffff,  0x0000ffff}, /* Y/Z */
	{ },
+2 −2
Original line number Diff line number Diff line
@@ -343,8 +343,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
#ifdef CONFIG_PM_SLEEP
static int dwapb_irq_set_wake(struct irq_data *d, unsigned int enable)
{
	struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d);
	struct dwapb_gpio *gpio = igc->private;
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct dwapb_gpio *gpio = to_dwapb_gpio(gc);
	struct dwapb_context *ctx = gpio->ports[0].ctx;
	irq_hw_number_t bit = irqd_to_hwirq(d);

+56 −6
Original line number Diff line number Diff line
@@ -28,6 +28,47 @@
#include <linux/spinlock.h>
#include <linux/types.h>

/*
 * PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status
 *
 * Bit: Description
 *   0: Enable Interrupt Sources (Bit 0)
 *   1: Enable Interrupt Sources (Bit 1)
 *   2: Generate Internal PCI Bus Internal SERR# Interrupt
 *   3: Mailbox Interrupt Enable
 *   4: Power Management Interrupt Enable
 *   5: Power Management Interrupt
 *   6: Slave Read Local Data Parity Check Error Enable
 *   7: Slave Read Local Data Parity Check Error Status
 *   8: Internal PCI Wire Interrupt Enable
 *   9: PCI Express Doorbell Interrupt Enable
 *  10: PCI Abort Interrupt Enable
 *  11: Local Interrupt Input Enable
 *  12: Retry Abort Enable
 *  13: PCI Express Doorbell Interrupt Active
 *  14: PCI Abort Interrupt Active
 *  15: Local Interrupt Input Active
 *  16: Local Interrupt Output Enable
 *  17: Local Doorbell Interrupt Enable
 *  18: DMA Channel 0 Interrupt Enable
 *  19: DMA Channel 1 Interrupt Enable
 *  20: Local Doorbell Interrupt Active
 *  21: DMA Channel 0 Interrupt Active
 *  22: DMA Channel 1 Interrupt Active
 *  23: Built-In Self-Test (BIST) Interrupt Active
 *  24: Direct Master was the Bus Master during a Master or Target Abort
 *  25: DMA Channel 0 was the Bus Master during a Master or Target Abort
 *  26: DMA Channel 1 was the Bus Master during a Master or Target Abort
 *  27: Target Abort after internal 256 consecutive Master Retrys
 *  28: PCI Bus wrote data to LCS_MBOX0
 *  29: PCI Bus wrote data to LCS_MBOX1
 *  30: PCI Bus wrote data to LCS_MBOX2
 *  31: PCI Bus wrote data to LCS_MBOX3
 */
#define PLX_PEX8311_PCI_LCS_INTCSR  0x68
#define INTCSR_INTERNAL_PCI_WIRE    BIT(8)
#define INTCSR_LOCAL_INPUT          BIT(11)

/**
 * struct idio_24_gpio_reg - GPIO device registers structure
 * @out0_7:	Read: FET Outputs 0-7
@@ -92,6 +133,7 @@ struct idio_24_gpio_reg {
struct idio_24_gpio {
	struct gpio_chip chip;
	raw_spinlock_t lock;
	__u8 __iomem *plx;
	struct idio_24_gpio_reg __iomem *reg;
	unsigned long irq_mask;
};
@@ -334,13 +376,13 @@ static void idio_24_irq_mask(struct irq_data *data)
	unsigned long flags;
	const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
	unsigned char new_irq_mask;
	const unsigned long bank_offset = bit_offset/8 * 8;
	const unsigned long bank_offset = bit_offset / 8;
	unsigned char cos_enable_state;

	raw_spin_lock_irqsave(&idio24gpio->lock, flags);

	idio24gpio->irq_mask &= BIT(bit_offset);
	new_irq_mask = idio24gpio->irq_mask >> bank_offset;
	idio24gpio->irq_mask &= ~BIT(bit_offset);
	new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;

	if (!new_irq_mask) {
		cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
@@ -363,12 +405,12 @@ static void idio_24_irq_unmask(struct irq_data *data)
	unsigned long flags;
	unsigned char prev_irq_mask;
	const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
	const unsigned long bank_offset = bit_offset/8 * 8;
	const unsigned long bank_offset = bit_offset / 8;
	unsigned char cos_enable_state;

	raw_spin_lock_irqsave(&idio24gpio->lock, flags);

	prev_irq_mask = idio24gpio->irq_mask >> bank_offset;
	prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
	idio24gpio->irq_mask |= BIT(bit_offset);

	if (!prev_irq_mask) {
@@ -455,6 +497,7 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	struct device *const dev = &pdev->dev;
	struct idio_24_gpio *idio24gpio;
	int err;
	const size_t pci_plx_bar_index = 1;
	const size_t pci_bar_index = 2;
	const char *const name = pci_name(pdev);
	struct gpio_irq_chip *girq;
@@ -469,12 +512,13 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
		return err;
	}

	err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name);
	err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
	if (err) {
		dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
		return err;
	}

	idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
	idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];

	idio24gpio->chip.label = name;
@@ -504,6 +548,12 @@ static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)

	/* Software board reset */
	iowrite8(0, &idio24gpio->reg->soft_reset);
	/*
	 * enable PLX PEX8311 internal PCI wire interrupt and local interrupt
	 * input
	 */
	iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
		 idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);

	err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
	if (err) {
+0 −15
Original line number Diff line number Diff line
@@ -7,22 +7,7 @@

struct gpio_device;

#ifdef CONFIG_GPIO_CDEV

int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt);
void gpiolib_cdev_unregister(struct gpio_device *gdev);

#else

static inline int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
{
	return 0;
}

static inline void gpiolib_cdev_unregister(struct gpio_device *gdev)
{
}

#endif /* CONFIG_GPIO_CDEV */

#endif /* GPIOLIB_CDEV_H */
+15 −3
Original line number Diff line number Diff line
@@ -480,11 +480,23 @@ static void gpiodevice_release(struct device *dev)
	kfree(gdev);
}

#ifdef CONFIG_GPIO_CDEV
#define gcdev_register(gdev, devt)	gpiolib_cdev_register((gdev), (devt))
#define gcdev_unregister(gdev)		gpiolib_cdev_unregister((gdev))
#else
/*
 * gpiolib_cdev_register() indirectly calls device_add(), which is still
 * required even when cdev is not selected.
 */
#define gcdev_register(gdev, devt)	device_add(&(gdev)->dev)
#define gcdev_unregister(gdev)		device_del(&(gdev)->dev)
#endif

static int gpiochip_setup_dev(struct gpio_device *gdev)
{
	int ret;

	ret = gpiolib_cdev_register(gdev, gpio_devt);
	ret = gcdev_register(gdev, gpio_devt);
	if (ret)
		return ret;

@@ -500,7 +512,7 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
	return 0;

err_remove_device:
	gpiolib_cdev_unregister(gdev);
	gcdev_unregister(gdev);
	return ret;
}

@@ -825,7 +837,7 @@ void gpiochip_remove(struct gpio_chip *gc)
	 * be removed, else it will be dangling until the last user is
	 * gone.
	 */
	gpiolib_cdev_unregister(gdev);
	gcdev_unregister(gdev);
	put_device(&gdev->dev);
}
EXPORT_SYMBOL_GPL(gpiochip_remove);