cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ioc3.c (16206B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * SGI IOC3 multifunction device driver
      4 *
      5 * Copyright (C) 2018, 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
      6 *
      7 * Based on work by:
      8 *   Stanislaw Skowronek <skylark@unaligned.org>
      9 *   Joshua Kinard <kumba@gentoo.org>
     10 *   Brent Casavant <bcasavan@sgi.com> - IOC4 master driver
     11 *   Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer
     12 */
     13
     14#include <linux/delay.h>
     15#include <linux/errno.h>
     16#include <linux/interrupt.h>
     17#include <linux/irqdomain.h>
     18#include <linux/mfd/core.h>
     19#include <linux/module.h>
     20#include <linux/pci.h>
     21#include <linux/platform_device.h>
     22#include <linux/platform_data/sgi-w1.h>
     23#include <linux/rtc/ds1685.h>
     24
     25#include <asm/pci/bridge.h>
     26#include <asm/sn/ioc3.h>
     27
     28#define IOC3_IRQ_SERIAL_A	6
     29#define IOC3_IRQ_SERIAL_B	15
     30#define IOC3_IRQ_KBD		22
     31
     32/* Bitmask for selecting which IRQs are level triggered */
     33#define IOC3_LVL_MASK	(BIT(IOC3_IRQ_SERIAL_A) | BIT(IOC3_IRQ_SERIAL_B))
     34
     35#define M48T35_REG_SIZE	32768	/* size of m48t35 registers */
     36
     37/* 1.2 us latency timer (40 cycles at 33 MHz) */
     38#define IOC3_LATENCY	40
     39
     40struct ioc3_priv_data {
     41	struct irq_domain *domain;
     42	struct ioc3 __iomem *regs;
     43	struct pci_dev *pdev;
     44	int domain_irq;
     45};
     46
     47static void ioc3_irq_ack(struct irq_data *d)
     48{
     49	struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
     50	unsigned int hwirq = irqd_to_hwirq(d);
     51
     52	writel(BIT(hwirq), &ipd->regs->sio_ir);
     53}
     54
     55static void ioc3_irq_mask(struct irq_data *d)
     56{
     57	struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
     58	unsigned int hwirq = irqd_to_hwirq(d);
     59
     60	writel(BIT(hwirq), &ipd->regs->sio_iec);
     61}
     62
     63static void ioc3_irq_unmask(struct irq_data *d)
     64{
     65	struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
     66	unsigned int hwirq = irqd_to_hwirq(d);
     67
     68	writel(BIT(hwirq), &ipd->regs->sio_ies);
     69}
     70
     71static struct irq_chip ioc3_irq_chip = {
     72	.name		= "IOC3",
     73	.irq_ack	= ioc3_irq_ack,
     74	.irq_mask	= ioc3_irq_mask,
     75	.irq_unmask	= ioc3_irq_unmask,
     76};
     77
     78static int ioc3_irq_domain_map(struct irq_domain *d, unsigned int irq,
     79			      irq_hw_number_t hwirq)
     80{
     81	/* Set level IRQs for every interrupt contained in IOC3_LVL_MASK */
     82	if (BIT(hwirq) & IOC3_LVL_MASK)
     83		irq_set_chip_and_handler(irq, &ioc3_irq_chip, handle_level_irq);
     84	else
     85		irq_set_chip_and_handler(irq, &ioc3_irq_chip, handle_edge_irq);
     86
     87	irq_set_chip_data(irq, d->host_data);
     88	return 0;
     89}
     90
     91static void ioc3_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
     92{
     93	irq_set_chip_and_handler(irq, NULL, NULL);
     94	irq_set_chip_data(irq, NULL);
     95}
     96
     97static const struct irq_domain_ops ioc3_irq_domain_ops = {
     98	.map = ioc3_irq_domain_map,
     99	.unmap = ioc3_irq_domain_unmap,
    100};
    101
    102static void ioc3_irq_handler(struct irq_desc *desc)
    103{
    104	struct irq_domain *domain = irq_desc_get_handler_data(desc);
    105	struct ioc3_priv_data *ipd = domain->host_data;
    106	struct ioc3 __iomem *regs = ipd->regs;
    107	u32 pending, mask;
    108
    109	pending = readl(&regs->sio_ir);
    110	mask = readl(&regs->sio_ies);
    111	pending &= mask; /* Mask off not enabled interrupts */
    112
    113	if (pending)
    114		generic_handle_domain_irq(domain, __ffs(pending));
    115	else
    116		spurious_interrupt();
    117}
    118
    119/*
    120 * System boards/BaseIOs use more interrupt pins of the bridge ASIC
    121 * to which the IOC3 is connected. Since the IOC3 MFD driver
    122 * knows wiring of these extra pins, we use the map_irq function
    123 * to get interrupts activated
    124 */
    125static int ioc3_map_irq(struct pci_dev *pdev, int slot, int pin)
    126{
    127	struct pci_host_bridge *hbrg = pci_find_host_bridge(pdev->bus);
    128
    129	return hbrg->map_irq(pdev, slot, pin);
    130}
    131
    132static int ioc3_irq_domain_setup(struct ioc3_priv_data *ipd, int irq)
    133{
    134	struct irq_domain *domain;
    135	struct fwnode_handle *fn;
    136
    137	fn = irq_domain_alloc_named_fwnode("IOC3");
    138	if (!fn)
    139		goto err;
    140
    141	domain = irq_domain_create_linear(fn, 24, &ioc3_irq_domain_ops, ipd);
    142	if (!domain) {
    143		irq_domain_free_fwnode(fn);
    144		goto err;
    145	}
    146
    147	ipd->domain = domain;
    148
    149	irq_set_chained_handler_and_data(irq, ioc3_irq_handler, domain);
    150	ipd->domain_irq = irq;
    151	return 0;
    152
    153err:
    154	dev_err(&ipd->pdev->dev, "irq domain setup failed\n");
    155	return -ENOMEM;
    156}
    157
    158static const struct resource ioc3_uarta_resources[] = {
    159	DEFINE_RES_MEM(offsetof(struct ioc3, sregs.uarta),
    160		       sizeof_field(struct ioc3, sregs.uarta)),
    161	DEFINE_RES_IRQ(IOC3_IRQ_SERIAL_A)
    162};
    163
    164static const struct resource ioc3_uartb_resources[] = {
    165	DEFINE_RES_MEM(offsetof(struct ioc3, sregs.uartb),
    166		       sizeof_field(struct ioc3, sregs.uartb)),
    167	DEFINE_RES_IRQ(IOC3_IRQ_SERIAL_B)
    168};
    169
    170static struct mfd_cell ioc3_serial_cells[] = {
    171	{
    172		.name = "ioc3-serial8250",
    173		.resources = ioc3_uarta_resources,
    174		.num_resources = ARRAY_SIZE(ioc3_uarta_resources),
    175	},
    176	{
    177		.name = "ioc3-serial8250",
    178		.resources = ioc3_uartb_resources,
    179		.num_resources = ARRAY_SIZE(ioc3_uartb_resources),
    180	}
    181};
    182
    183static int ioc3_serial_setup(struct ioc3_priv_data *ipd)
    184{
    185	int ret;
    186
    187	/* Set gpio pins for RS232/RS422 mode selection */
    188	writel(GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL,
    189		&ipd->regs->gpcr_s);
    190	/* Select RS232 mode for uart a */
    191	writel(0, &ipd->regs->gppr[6]);
    192	/* Select RS232 mode for uart b */
    193	writel(0, &ipd->regs->gppr[7]);
    194
    195	/* Switch both ports to 16650 mode */
    196	writel(readl(&ipd->regs->port_a.sscr) & ~SSCR_DMA_EN,
    197	       &ipd->regs->port_a.sscr);
    198	writel(readl(&ipd->regs->port_b.sscr) & ~SSCR_DMA_EN,
    199	       &ipd->regs->port_b.sscr);
    200	udelay(1000); /* Wait until mode switch is done */
    201
    202	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
    203			      ioc3_serial_cells, ARRAY_SIZE(ioc3_serial_cells),
    204			      &ipd->pdev->resource[0], 0, ipd->domain);
    205	if (ret) {
    206		dev_err(&ipd->pdev->dev, "Failed to add 16550 subdevs\n");
    207		return ret;
    208	}
    209
    210	return 0;
    211}
    212
    213static const struct resource ioc3_kbd_resources[] = {
    214	DEFINE_RES_MEM(offsetof(struct ioc3, serio),
    215		       sizeof_field(struct ioc3, serio)),
    216	DEFINE_RES_IRQ(IOC3_IRQ_KBD)
    217};
    218
    219static struct mfd_cell ioc3_kbd_cells[] = {
    220	{
    221		.name = "ioc3-kbd",
    222		.resources = ioc3_kbd_resources,
    223		.num_resources = ARRAY_SIZE(ioc3_kbd_resources),
    224	}
    225};
    226
    227static int ioc3_kbd_setup(struct ioc3_priv_data *ipd)
    228{
    229	int ret;
    230
    231	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
    232			      ioc3_kbd_cells, ARRAY_SIZE(ioc3_kbd_cells),
    233			      &ipd->pdev->resource[0], 0, ipd->domain);
    234	if (ret) {
    235		dev_err(&ipd->pdev->dev, "Failed to add 16550 subdevs\n");
    236		return ret;
    237	}
    238
    239	return 0;
    240}
    241
    242static const struct resource ioc3_eth_resources[] = {
    243	DEFINE_RES_MEM(offsetof(struct ioc3, eth),
    244		       sizeof_field(struct ioc3, eth)),
    245	DEFINE_RES_MEM(offsetof(struct ioc3, ssram),
    246		       sizeof_field(struct ioc3, ssram)),
    247	DEFINE_RES_IRQ(0)
    248};
    249
    250static const struct resource ioc3_w1_resources[] = {
    251	DEFINE_RES_MEM(offsetof(struct ioc3, mcr),
    252		       sizeof_field(struct ioc3, mcr)),
    253};
    254static struct sgi_w1_platform_data ioc3_w1_platform_data;
    255
    256static struct mfd_cell ioc3_eth_cells[] = {
    257	{
    258		.name = "ioc3-eth",
    259		.resources = ioc3_eth_resources,
    260		.num_resources = ARRAY_SIZE(ioc3_eth_resources),
    261	},
    262	{
    263		.name = "sgi_w1",
    264		.resources = ioc3_w1_resources,
    265		.num_resources = ARRAY_SIZE(ioc3_w1_resources),
    266		.platform_data = &ioc3_w1_platform_data,
    267		.pdata_size = sizeof(ioc3_w1_platform_data),
    268	}
    269};
    270
    271static int ioc3_eth_setup(struct ioc3_priv_data *ipd)
    272{
    273	int ret;
    274
    275	/* Enable One-Wire bus */
    276	writel(GPCR_MLAN_EN, &ipd->regs->gpcr_s);
    277
    278	/* Generate unique identifier */
    279	snprintf(ioc3_w1_platform_data.dev_id,
    280		 sizeof(ioc3_w1_platform_data.dev_id), "ioc3-%012llx",
    281		 ipd->pdev->resource->start);
    282
    283	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
    284			      ioc3_eth_cells, ARRAY_SIZE(ioc3_eth_cells),
    285			      &ipd->pdev->resource[0], ipd->pdev->irq, NULL);
    286	if (ret) {
    287		dev_err(&ipd->pdev->dev, "Failed to add ETH/W1 subdev\n");
    288		return ret;
    289	}
    290
    291	return 0;
    292}
    293
    294static const struct resource ioc3_m48t35_resources[] = {
    295	DEFINE_RES_MEM(IOC3_BYTEBUS_DEV0, M48T35_REG_SIZE)
    296};
    297
    298static struct mfd_cell ioc3_m48t35_cells[] = {
    299	{
    300		.name = "rtc-m48t35",
    301		.resources = ioc3_m48t35_resources,
    302		.num_resources = ARRAY_SIZE(ioc3_m48t35_resources),
    303	}
    304};
    305
    306static int ioc3_m48t35_setup(struct ioc3_priv_data *ipd)
    307{
    308	int ret;
    309
    310	ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
    311			      ioc3_m48t35_cells, ARRAY_SIZE(ioc3_m48t35_cells),
    312			      &ipd->pdev->resource[0], 0, ipd->domain);
    313	if (ret)
    314		dev_err(&ipd->pdev->dev, "Failed to add M48T35 subdev\n");
    315
    316	return ret;
    317}
    318
    319static struct ds1685_rtc_platform_data ip30_rtc_platform_data = {
    320	.bcd_mode = false,
    321	.no_irq = false,
    322	.uie_unsupported = true,
    323	.access_type = ds1685_reg_indirect,
    324};
    325
    326static const struct resource ioc3_rtc_ds1685_resources[] = {
    327	DEFINE_RES_MEM(IOC3_BYTEBUS_DEV1, 1),
    328	DEFINE_RES_MEM(IOC3_BYTEBUS_DEV2, 1),
    329	DEFINE_RES_IRQ(0)
    330};
    331
    332static struct mfd_cell ioc3_ds1685_cells[] = {
    333	{
    334		.name = "rtc-ds1685",
    335		.resources = ioc3_rtc_ds1685_resources,
    336		.num_resources = ARRAY_SIZE(ioc3_rtc_ds1685_resources),
    337		.platform_data = &ip30_rtc_platform_data,
    338		.pdata_size = sizeof(ip30_rtc_platform_data),
    339		.id = PLATFORM_DEVID_NONE,
    340	}
    341};
    342
    343static int ioc3_ds1685_setup(struct ioc3_priv_data *ipd)
    344{
    345	int ret, irq;
    346
    347	irq = ioc3_map_irq(ipd->pdev, 6, 0);
    348
    349	ret = mfd_add_devices(&ipd->pdev->dev, 0, ioc3_ds1685_cells,
    350			      ARRAY_SIZE(ioc3_ds1685_cells),
    351			      &ipd->pdev->resource[0], irq, NULL);
    352	if (ret)
    353		dev_err(&ipd->pdev->dev, "Failed to add DS1685 subdev\n");
    354
    355	return ret;
    356};
    357
    358
    359static const struct resource ioc3_leds_resources[] = {
    360	DEFINE_RES_MEM(offsetof(struct ioc3, gppr[0]),
    361		       sizeof_field(struct ioc3, gppr[0])),
    362	DEFINE_RES_MEM(offsetof(struct ioc3, gppr[1]),
    363		       sizeof_field(struct ioc3, gppr[1])),
    364};
    365
    366static struct mfd_cell ioc3_led_cells[] = {
    367	{
    368		.name = "ip30-leds",
    369		.resources = ioc3_leds_resources,
    370		.num_resources = ARRAY_SIZE(ioc3_leds_resources),
    371		.id = PLATFORM_DEVID_NONE,
    372	}
    373};
    374
    375static int ioc3_led_setup(struct ioc3_priv_data *ipd)
    376{
    377	int ret;
    378
    379	ret = mfd_add_devices(&ipd->pdev->dev, 0, ioc3_led_cells,
    380			      ARRAY_SIZE(ioc3_led_cells),
    381			      &ipd->pdev->resource[0], 0, ipd->domain);
    382	if (ret)
    383		dev_err(&ipd->pdev->dev, "Failed to add LED subdev\n");
    384
    385	return ret;
    386}
    387
    388static int ip27_baseio_setup(struct ioc3_priv_data *ipd)
    389{
    390	int ret, io_irq;
    391
    392	io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
    393			      PCI_INTERRUPT_INTB);
    394	ret = ioc3_irq_domain_setup(ipd, io_irq);
    395	if (ret)
    396		return ret;
    397
    398	ret = ioc3_eth_setup(ipd);
    399	if (ret)
    400		return ret;
    401
    402	ret = ioc3_serial_setup(ipd);
    403	if (ret)
    404		return ret;
    405
    406	return ioc3_m48t35_setup(ipd);
    407}
    408
    409static int ip27_baseio6g_setup(struct ioc3_priv_data *ipd)
    410{
    411	int ret, io_irq;
    412
    413	io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
    414			      PCI_INTERRUPT_INTB);
    415	ret = ioc3_irq_domain_setup(ipd, io_irq);
    416	if (ret)
    417		return ret;
    418
    419	ret = ioc3_eth_setup(ipd);
    420	if (ret)
    421		return ret;
    422
    423	ret = ioc3_serial_setup(ipd);
    424	if (ret)
    425		return ret;
    426
    427	ret = ioc3_m48t35_setup(ipd);
    428	if (ret)
    429		return ret;
    430
    431	return ioc3_kbd_setup(ipd);
    432}
    433
    434static int ip27_mio_setup(struct ioc3_priv_data *ipd)
    435{
    436	int ret;
    437
    438	ret = ioc3_irq_domain_setup(ipd, ipd->pdev->irq);
    439	if (ret)
    440		return ret;
    441
    442	ret = ioc3_serial_setup(ipd);
    443	if (ret)
    444		return ret;
    445
    446	return ioc3_kbd_setup(ipd);
    447}
    448
    449static int ip30_sysboard_setup(struct ioc3_priv_data *ipd)
    450{
    451	int ret, io_irq;
    452
    453	io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
    454			      PCI_INTERRUPT_INTB);
    455	ret = ioc3_irq_domain_setup(ipd, io_irq);
    456	if (ret)
    457		return ret;
    458
    459	ret = ioc3_eth_setup(ipd);
    460	if (ret)
    461		return ret;
    462
    463	ret = ioc3_serial_setup(ipd);
    464	if (ret)
    465		return ret;
    466
    467	ret = ioc3_kbd_setup(ipd);
    468	if (ret)
    469		return ret;
    470
    471	ret = ioc3_ds1685_setup(ipd);
    472	if (ret)
    473		return ret;
    474
    475	return ioc3_led_setup(ipd);
    476}
    477
    478static int ioc3_menet_setup(struct ioc3_priv_data *ipd)
    479{
    480	int ret, io_irq;
    481
    482	io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
    483			      PCI_INTERRUPT_INTB);
    484	ret = ioc3_irq_domain_setup(ipd, io_irq);
    485	if (ret)
    486		return ret;
    487
    488	ret = ioc3_eth_setup(ipd);
    489	if (ret)
    490		return ret;
    491
    492	return ioc3_serial_setup(ipd);
    493}
    494
    495static int ioc3_menet4_setup(struct ioc3_priv_data *ipd)
    496{
    497	return ioc3_eth_setup(ipd);
    498}
    499
    500static int ioc3_cad_duo_setup(struct ioc3_priv_data *ipd)
    501{
    502	int ret, io_irq;
    503
    504	io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
    505			      PCI_INTERRUPT_INTB);
    506	ret = ioc3_irq_domain_setup(ipd, io_irq);
    507	if (ret)
    508		return ret;
    509
    510	ret = ioc3_eth_setup(ipd);
    511	if (ret)
    512		return ret;
    513
    514	return ioc3_kbd_setup(ipd);
    515}
    516
    517/* Helper macro for filling ioc3_info array */
    518#define IOC3_SID(_name, _sid, _setup) \
    519	{								   \
    520		.name = _name,						   \
    521		.sid = PCI_VENDOR_ID_SGI | (IOC3_SUBSYS_ ## _sid << 16),   \
    522		.setup = _setup,					   \
    523	}
    524
    525static struct {
    526	const char *name;
    527	u32 sid;
    528	int (*setup)(struct ioc3_priv_data *ipd);
    529} ioc3_infos[] = {
    530	IOC3_SID("IP27 BaseIO6G", IP27_BASEIO6G, &ip27_baseio6g_setup),
    531	IOC3_SID("IP27 MIO", IP27_MIO, &ip27_mio_setup),
    532	IOC3_SID("IP27 BaseIO", IP27_BASEIO, &ip27_baseio_setup),
    533	IOC3_SID("IP29 System Board", IP29_SYSBOARD, &ip27_baseio6g_setup),
    534	IOC3_SID("IP30 System Board", IP30_SYSBOARD, &ip30_sysboard_setup),
    535	IOC3_SID("MENET", MENET, &ioc3_menet_setup),
    536	IOC3_SID("MENET4", MENET4, &ioc3_menet4_setup)
    537};
    538#undef IOC3_SID
    539
    540static int ioc3_setup(struct ioc3_priv_data *ipd)
    541{
    542	u32 sid;
    543	int i;
    544
    545	/* Clear IRQs */
    546	writel(~0, &ipd->regs->sio_iec);
    547	writel(~0, &ipd->regs->sio_ir);
    548	writel(0, &ipd->regs->eth.eier);
    549	writel(~0, &ipd->regs->eth.eisr);
    550
    551	/* Read subsystem vendor id and subsystem id */
    552	pci_read_config_dword(ipd->pdev, PCI_SUBSYSTEM_VENDOR_ID, &sid);
    553
    554	for (i = 0; i < ARRAY_SIZE(ioc3_infos); i++)
    555		if (sid == ioc3_infos[i].sid) {
    556			pr_info("ioc3: %s\n", ioc3_infos[i].name);
    557			return ioc3_infos[i].setup(ipd);
    558		}
    559
    560	/* Treat everything not identified by PCI subid as CAD DUO */
    561	pr_info("ioc3: CAD DUO\n");
    562	return ioc3_cad_duo_setup(ipd);
    563}
    564
    565static int ioc3_mfd_probe(struct pci_dev *pdev,
    566			  const struct pci_device_id *pci_id)
    567{
    568	struct ioc3_priv_data *ipd;
    569	struct ioc3 __iomem *regs;
    570	int ret;
    571
    572	ret = pci_enable_device(pdev);
    573	if (ret)
    574		return ret;
    575
    576	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, IOC3_LATENCY);
    577	pci_set_master(pdev);
    578
    579	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
    580	if (ret) {
    581		pr_err("%s: No usable DMA configuration, aborting.\n",
    582		       pci_name(pdev));
    583		goto out_disable_device;
    584	}
    585
    586	/* Set up per-IOC3 data */
    587	ipd = devm_kzalloc(&pdev->dev, sizeof(struct ioc3_priv_data),
    588			   GFP_KERNEL);
    589	if (!ipd) {
    590		ret = -ENOMEM;
    591		goto out_disable_device;
    592	}
    593	ipd->pdev = pdev;
    594
    595	/*
    596	 * Map all IOC3 registers.  These are shared between subdevices
    597	 * so the main IOC3 module manages them.
    598	 */
    599	regs = pci_ioremap_bar(pdev, 0);
    600	if (!regs) {
    601		dev_warn(&pdev->dev, "ioc3: Unable to remap PCI BAR for %s.\n",
    602			 pci_name(pdev));
    603		ret = -ENOMEM;
    604		goto out_disable_device;
    605	}
    606	ipd->regs = regs;
    607
    608	/* Track PCI-device specific data */
    609	pci_set_drvdata(pdev, ipd);
    610
    611	ret = ioc3_setup(ipd);
    612	if (ret) {
    613		/* Remove all already added MFD devices */
    614		mfd_remove_devices(&ipd->pdev->dev);
    615		if (ipd->domain) {
    616			struct fwnode_handle *fn = ipd->domain->fwnode;
    617
    618			irq_domain_remove(ipd->domain);
    619			irq_domain_free_fwnode(fn);
    620			free_irq(ipd->domain_irq, (void *)ipd);
    621		}
    622		pci_iounmap(pdev, regs);
    623		goto out_disable_device;
    624	}
    625
    626	return 0;
    627
    628out_disable_device:
    629	pci_disable_device(pdev);
    630	return ret;
    631}
    632
    633static void ioc3_mfd_remove(struct pci_dev *pdev)
    634{
    635	struct ioc3_priv_data *ipd;
    636
    637	ipd = pci_get_drvdata(pdev);
    638
    639	/* Clear and disable all IRQs */
    640	writel(~0, &ipd->regs->sio_iec);
    641	writel(~0, &ipd->regs->sio_ir);
    642
    643	/* Release resources */
    644	mfd_remove_devices(&ipd->pdev->dev);
    645	if (ipd->domain) {
    646		struct fwnode_handle *fn = ipd->domain->fwnode;
    647
    648		irq_domain_remove(ipd->domain);
    649		irq_domain_free_fwnode(fn);
    650		free_irq(ipd->domain_irq, (void *)ipd);
    651	}
    652	pci_iounmap(pdev, ipd->regs);
    653	pci_disable_device(pdev);
    654}
    655
    656static struct pci_device_id ioc3_mfd_id_table[] = {
    657	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
    658	{ 0, },
    659};
    660MODULE_DEVICE_TABLE(pci, ioc3_mfd_id_table);
    661
    662static struct pci_driver ioc3_mfd_driver = {
    663	.name = "IOC3",
    664	.id_table = ioc3_mfd_id_table,
    665	.probe = ioc3_mfd_probe,
    666	.remove = ioc3_mfd_remove,
    667};
    668
    669module_pci_driver(ioc3_mfd_driver);
    670
    671MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
    672MODULE_DESCRIPTION("SGI IOC3 MFD driver");
    673MODULE_LICENSE("GPL v2");