linux/drivers/mfd/ioc3.c
<<
>>
Prefs
   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");
 674