forked from Minki/linux
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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAl+lXTgACgkQEacuoBRx 13IEOA/+LTZNQJIUjWNk/xd3OQL5n2VMRbPOcnz6tkC/mAO7ZvPWuYlTR2qXPA7V vxNea9vczcjl5Qjda7HjyPfnds+31XTw/QLIUwMOVgQatV4fzZK/0fGrubkWftLM h+MJoIrm76+b2qJ8ax6z7ks8OnDgM24vJE2G5fBrgexl/bCfpzlFriv4bBRWQOiD sccJZM6yHifL+ObK30qcqI0s57fyZEOYTv5LnMUKyTDn7CmTXIefNGV1bN3LWnOA +/g7YuE8eedumMCegnrQbysnvVum1aQADnMV0krMs/+ykg32aWo4vFw2KbscVruc lB+s54+Gy3pBoSIRQA18/17L2mjyKmCGIWbQecQImCLU8kYfmdRqlN+HDof91oIa QaeoEvsZlXQ0pmEiGegEFNF9dNFldoY0OMQ7X7Bm3tVUshV0V7lKz5YUNJ6W/0PB ksxEdk3/doMfyJxAOHae0vvb8iK87T2pEEpqr4VhoewCe7E0D4L07P5WSkokn+1X OYFkdD3lAiXeY4AF7j5kM57OK525DmyO5ANqXAJSyjqJBtze8fIYDQ+yd5LugJO0 yUExb5bKPvMmN7g70btq53EaS7sSq7EbwRM5hC64B85lmjAh75mkBZDgsNOKOeD6 TsI+v8XsN7m/BrCSRBN1WrpwdMkt1c+1tEqGv9jJFzwYuIp5CTo= =dR2J -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
45fe0b539b
@ -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 */
|
||||
{ },
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user