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