diff options
Diffstat (limited to 'drivers/mfd/ioc3.c')
-rw-r--r-- | drivers/mfd/ioc3.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/drivers/mfd/ioc3.c b/drivers/mfd/ioc3.c index 02998d4eb74b..58656837b7c6 100644 --- a/drivers/mfd/ioc3.c +++ b/drivers/mfd/ioc3.c @@ -14,6 +14,7 @@ #include <linux/delay.h> #include <linux/errno.h> #include <linux/interrupt.h> +#include <linux/irqdomain.h> #include <linux/mfd/core.h> #include <linux/module.h> #include <linux/pci.h> @@ -104,19 +105,15 @@ static void ioc3_irq_handler(struct irq_desc *desc) struct ioc3_priv_data *ipd = domain->host_data; struct ioc3 __iomem *regs = ipd->regs; u32 pending, mask; - unsigned int irq; pending = readl(®s->sio_ir); mask = readl(®s->sio_ies); pending &= mask; /* Mask off not enabled interrupts */ - if (pending) { - irq = irq_find_mapping(domain, __ffs(pending)); - if (irq) - generic_handle_irq(irq); - } else { + if (pending) + generic_handle_domain_irq(domain, __ffs(pending)); + else spurious_interrupt(); - } } /* @@ -142,10 +139,11 @@ static int ioc3_irq_domain_setup(struct ioc3_priv_data *ipd, int irq) goto err; domain = irq_domain_create_linear(fn, 24, &ioc3_irq_domain_ops, ipd); - if (!domain) + if (!domain) { + irq_domain_free_fwnode(fn); goto err; + } - irq_domain_free_fwnode(fn); ipd->domain = domain; irq_set_chained_handler_and_data(irq, ioc3_irq_handler, domain); @@ -157,13 +155,13 @@ err: return -ENOMEM; } -static struct resource ioc3_uarta_resources[] = { +static const struct resource ioc3_uarta_resources[] = { DEFINE_RES_MEM(offsetof(struct ioc3, sregs.uarta), sizeof_field(struct ioc3, sregs.uarta)), DEFINE_RES_IRQ(IOC3_IRQ_SERIAL_A) }; -static struct resource ioc3_uartb_resources[] = { +static const struct resource ioc3_uartb_resources[] = { DEFINE_RES_MEM(offsetof(struct ioc3, sregs.uartb), sizeof_field(struct ioc3, sregs.uartb)), DEFINE_RES_IRQ(IOC3_IRQ_SERIAL_B) @@ -212,7 +210,7 @@ static int ioc3_serial_setup(struct ioc3_priv_data *ipd) return 0; } -static struct resource ioc3_kbd_resources[] = { +static const struct resource ioc3_kbd_resources[] = { DEFINE_RES_MEM(offsetof(struct ioc3, serio), sizeof_field(struct ioc3, serio)), DEFINE_RES_IRQ(IOC3_IRQ_KBD) @@ -241,7 +239,7 @@ static int ioc3_kbd_setup(struct ioc3_priv_data *ipd) return 0; } -static struct resource ioc3_eth_resources[] = { +static const struct resource ioc3_eth_resources[] = { DEFINE_RES_MEM(offsetof(struct ioc3, eth), sizeof_field(struct ioc3, eth)), DEFINE_RES_MEM(offsetof(struct ioc3, ssram), @@ -249,7 +247,7 @@ static struct resource ioc3_eth_resources[] = { DEFINE_RES_IRQ(0) }; -static struct resource ioc3_w1_resources[] = { +static const struct resource ioc3_w1_resources[] = { DEFINE_RES_MEM(offsetof(struct ioc3, mcr), sizeof_field(struct ioc3, mcr)), }; @@ -293,7 +291,7 @@ static int ioc3_eth_setup(struct ioc3_priv_data *ipd) return 0; } -static struct resource ioc3_m48t35_resources[] = { +static const struct resource ioc3_m48t35_resources[] = { DEFINE_RES_MEM(IOC3_BYTEBUS_DEV0, M48T35_REG_SIZE) }; @@ -325,7 +323,7 @@ static struct ds1685_rtc_platform_data ip30_rtc_platform_data = { .access_type = ds1685_reg_indirect, }; -static struct resource ioc3_rtc_ds1685_resources[] = { +static const struct resource ioc3_rtc_ds1685_resources[] = { DEFINE_RES_MEM(IOC3_BYTEBUS_DEV1, 1), DEFINE_RES_MEM(IOC3_BYTEBUS_DEV2, 1), DEFINE_RES_IRQ(0) @@ -358,7 +356,7 @@ static int ioc3_ds1685_setup(struct ioc3_priv_data *ipd) }; -static struct resource ioc3_leds_resources[] = { +static const struct resource ioc3_leds_resources[] = { DEFINE_RES_MEM(offsetof(struct ioc3, gppr[0]), sizeof_field(struct ioc3, gppr[0])), DEFINE_RES_MEM(offsetof(struct ioc3, gppr[1]), @@ -615,7 +613,10 @@ static int ioc3_mfd_probe(struct pci_dev *pdev, /* Remove all already added MFD devices */ mfd_remove_devices(&ipd->pdev->dev); if (ipd->domain) { + struct fwnode_handle *fn = ipd->domain->fwnode; + irq_domain_remove(ipd->domain); + irq_domain_free_fwnode(fn); free_irq(ipd->domain_irq, (void *)ipd); } pci_iounmap(pdev, regs); @@ -642,7 +643,10 @@ static void ioc3_mfd_remove(struct pci_dev *pdev) /* Release resources */ mfd_remove_devices(&ipd->pdev->dev); if (ipd->domain) { + struct fwnode_handle *fn = ipd->domain->fwnode; + irq_domain_remove(ipd->domain); + irq_domain_free_fwnode(fn); free_irq(ipd->domain_irq, (void *)ipd); } pci_iounmap(pdev, ipd->regs); |