linux/drivers/ipack/carriers/tpci200.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * driver for the TEWS TPCI-200 device
   4 *
   5 * Copyright (C) 2009-2012 CERN (www.cern.ch)
   6 * Author: Nicolas Serafini, EIC2 SA
   7 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/slab.h>
  12#include "tpci200.h"
  13
  14static const u16 tpci200_status_timeout[] = {
  15        TPCI200_A_TIMEOUT,
  16        TPCI200_B_TIMEOUT,
  17        TPCI200_C_TIMEOUT,
  18        TPCI200_D_TIMEOUT,
  19};
  20
  21static const u16 tpci200_status_error[] = {
  22        TPCI200_A_ERROR,
  23        TPCI200_B_ERROR,
  24        TPCI200_C_ERROR,
  25        TPCI200_D_ERROR,
  26};
  27
  28static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
  29        [IPACK_IO_SPACE]    = TPCI200_IO_SPACE_SIZE,
  30        [IPACK_ID_SPACE]    = TPCI200_ID_SPACE_SIZE,
  31        [IPACK_INT_SPACE]   = TPCI200_INT_SPACE_SIZE,
  32        [IPACK_MEM8_SPACE]  = TPCI200_MEM8_SPACE_SIZE,
  33        [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
  34};
  35
  36static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
  37        [IPACK_IO_SPACE]    = TPCI200_IO_SPACE_INTERVAL,
  38        [IPACK_ID_SPACE]    = TPCI200_ID_SPACE_INTERVAL,
  39        [IPACK_INT_SPACE]   = TPCI200_INT_SPACE_INTERVAL,
  40        [IPACK_MEM8_SPACE]  = TPCI200_MEM8_SPACE_INTERVAL,
  41        [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
  42};
  43
  44static struct tpci200_board *check_slot(struct ipack_device *dev)
  45{
  46        struct tpci200_board *tpci200;
  47
  48        if (dev == NULL)
  49                return NULL;
  50
  51
  52        tpci200 = dev_get_drvdata(dev->bus->parent);
  53
  54        if (tpci200 == NULL) {
  55                dev_info(&dev->dev, "carrier board not found\n");
  56                return NULL;
  57        }
  58
  59        if (dev->slot >= TPCI200_NB_SLOT) {
  60                dev_info(&dev->dev,
  61                         "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
  62                         dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
  63                return NULL;
  64        }
  65
  66        return tpci200;
  67}
  68
  69static void tpci200_clear_mask(struct tpci200_board *tpci200,
  70                               __le16 __iomem *addr, u16 mask)
  71{
  72        unsigned long flags;
  73        spin_lock_irqsave(&tpci200->regs_lock, flags);
  74        iowrite16(ioread16(addr) & (~mask), addr);
  75        spin_unlock_irqrestore(&tpci200->regs_lock, flags);
  76}
  77
  78static void tpci200_set_mask(struct tpci200_board *tpci200,
  79                             __le16 __iomem *addr, u16 mask)
  80{
  81        unsigned long flags;
  82        spin_lock_irqsave(&tpci200->regs_lock, flags);
  83        iowrite16(ioread16(addr) | mask, addr);
  84        spin_unlock_irqrestore(&tpci200->regs_lock, flags);
  85}
  86
  87static void tpci200_unregister(struct tpci200_board *tpci200)
  88{
  89        free_irq(tpci200->info->pdev->irq, (void *) tpci200);
  90
  91        pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
  92
  93        pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
  94        pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
  95        pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
  96        pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
  97
  98        pci_disable_device(tpci200->info->pdev);
  99}
 100
 101static void tpci200_enable_irq(struct tpci200_board *tpci200,
 102                               int islot)
 103{
 104        tpci200_set_mask(tpci200,
 105                        &tpci200->info->interface_regs->control[islot],
 106                        TPCI200_INT0_EN | TPCI200_INT1_EN);
 107}
 108
 109static void tpci200_disable_irq(struct tpci200_board *tpci200,
 110                                int islot)
 111{
 112        tpci200_clear_mask(tpci200,
 113                        &tpci200->info->interface_regs->control[islot],
 114                        TPCI200_INT0_EN | TPCI200_INT1_EN);
 115}
 116
 117static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
 118{
 119        irqreturn_t ret;
 120
 121        if (!slot_irq)
 122                return -ENODEV;
 123        ret = slot_irq->handler(slot_irq->arg);
 124
 125        return ret;
 126}
 127
 128static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
 129{
 130        struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
 131        struct slot_irq *slot_irq;
 132        irqreturn_t ret;
 133        u16 status_reg;
 134        int i;
 135
 136        /* Read status register */
 137        status_reg = ioread16(&tpci200->info->interface_regs->status);
 138
 139        /* Did we cause the interrupt? */
 140        if (!(status_reg & TPCI200_SLOT_INT_MASK))
 141                return IRQ_NONE;
 142
 143        /* callback to the IRQ handler for the corresponding slot */
 144        rcu_read_lock();
 145        for (i = 0; i < TPCI200_NB_SLOT; i++) {
 146                if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
 147                        continue;
 148                slot_irq = rcu_dereference(tpci200->slots[i].irq);
 149                ret = tpci200_slot_irq(slot_irq);
 150                if (ret == -ENODEV) {
 151                        dev_info(&tpci200->info->pdev->dev,
 152                                 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
 153                                 tpci200->number, i);
 154                        tpci200_disable_irq(tpci200, i);
 155                }
 156        }
 157        rcu_read_unlock();
 158
 159        return IRQ_HANDLED;
 160}
 161
 162static int tpci200_free_irq(struct ipack_device *dev)
 163{
 164        struct slot_irq *slot_irq;
 165        struct tpci200_board *tpci200;
 166
 167        tpci200 = check_slot(dev);
 168        if (tpci200 == NULL)
 169                return -EINVAL;
 170
 171        if (mutex_lock_interruptible(&tpci200->mutex))
 172                return -ERESTARTSYS;
 173
 174        if (tpci200->slots[dev->slot].irq == NULL) {
 175                mutex_unlock(&tpci200->mutex);
 176                return -EINVAL;
 177        }
 178
 179        tpci200_disable_irq(tpci200, dev->slot);
 180        slot_irq = tpci200->slots[dev->slot].irq;
 181        /* uninstall handler */
 182        RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
 183        synchronize_rcu();
 184        kfree(slot_irq);
 185        mutex_unlock(&tpci200->mutex);
 186        return 0;
 187}
 188
 189static int tpci200_request_irq(struct ipack_device *dev,
 190                               irqreturn_t (*handler)(void *), void *arg)
 191{
 192        int res = 0;
 193        struct slot_irq *slot_irq;
 194        struct tpci200_board *tpci200;
 195
 196        tpci200 = check_slot(dev);
 197        if (tpci200 == NULL)
 198                return -EINVAL;
 199
 200        if (mutex_lock_interruptible(&tpci200->mutex))
 201                return -ERESTARTSYS;
 202
 203        if (tpci200->slots[dev->slot].irq != NULL) {
 204                dev_err(&dev->dev,
 205                        "Slot [%d:%d] IRQ already registered !\n",
 206                        dev->bus->bus_nr,
 207                        dev->slot);
 208                res = -EINVAL;
 209                goto out_unlock;
 210        }
 211
 212        slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
 213        if (slot_irq == NULL) {
 214                dev_err(&dev->dev,
 215                        "Slot [%d:%d] unable to allocate memory for IRQ !\n",
 216                        dev->bus->bus_nr, dev->slot);
 217                res = -ENOMEM;
 218                goto out_unlock;
 219        }
 220
 221        /*
 222         * WARNING: Setup Interrupt Vector in the IndustryPack device
 223         * before an IRQ request.
 224         * Read the User Manual of your IndustryPack device to know
 225         * where to write the vector in memory.
 226         */
 227        slot_irq->handler = handler;
 228        slot_irq->arg = arg;
 229        slot_irq->holder = dev;
 230
 231        rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
 232        tpci200_enable_irq(tpci200, dev->slot);
 233
 234out_unlock:
 235        mutex_unlock(&tpci200->mutex);
 236        return res;
 237}
 238
 239static int tpci200_register(struct tpci200_board *tpci200)
 240{
 241        int i;
 242        int res;
 243        phys_addr_t ioidint_base;
 244        unsigned short slot_ctrl;
 245
 246        if (pci_enable_device(tpci200->info->pdev) < 0)
 247                return -ENODEV;
 248
 249        /* Request IP interface register (Bar 2) */
 250        res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
 251                                 "Carrier IP interface registers");
 252        if (res) {
 253                dev_err(&tpci200->info->pdev->dev,
 254                        "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
 255                        tpci200->info->pdev->bus->number,
 256                        tpci200->info->pdev->devfn);
 257                goto err_disable_device;
 258        }
 259
 260        /* Request IO ID INT space (Bar 3) */
 261        res = pci_request_region(tpci200->info->pdev,
 262                                 TPCI200_IO_ID_INT_SPACES_BAR,
 263                                 "Carrier IO ID INT space");
 264        if (res) {
 265                dev_err(&tpci200->info->pdev->dev,
 266                        "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
 267                        tpci200->info->pdev->bus->number,
 268                        tpci200->info->pdev->devfn);
 269                goto err_ip_interface_bar;
 270        }
 271
 272        /* Request MEM8 space (Bar 5) */
 273        res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
 274                                 "Carrier MEM8 space");
 275        if (res) {
 276                dev_err(&tpci200->info->pdev->dev,
 277                        "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
 278                        tpci200->info->pdev->bus->number,
 279                        tpci200->info->pdev->devfn);
 280                goto err_io_id_int_spaces_bar;
 281        }
 282
 283        /* Request MEM16 space (Bar 4) */
 284        res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
 285                                 "Carrier MEM16 space");
 286        if (res) {
 287                dev_err(&tpci200->info->pdev->dev,
 288                        "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
 289                        tpci200->info->pdev->bus->number,
 290                        tpci200->info->pdev->devfn);
 291                goto err_mem8_space_bar;
 292        }
 293
 294        /* Map internal tpci200 driver user space */
 295        tpci200->info->interface_regs =
 296                ioremap(pci_resource_start(tpci200->info->pdev,
 297                                           TPCI200_IP_INTERFACE_BAR),
 298                        TPCI200_IFACE_SIZE);
 299        if (!tpci200->info->interface_regs) {
 300                dev_err(&tpci200->info->pdev->dev,
 301                        "(bn 0x%X, sn 0x%X) failed to map driver user space!",
 302                        tpci200->info->pdev->bus->number,
 303                        tpci200->info->pdev->devfn);
 304                res = -ENOMEM;
 305                goto err_mem16_space_bar;
 306        }
 307
 308        /* Initialize lock that protects interface_regs */
 309        spin_lock_init(&tpci200->regs_lock);
 310
 311        ioidint_base = pci_resource_start(tpci200->info->pdev,
 312                                          TPCI200_IO_ID_INT_SPACES_BAR);
 313        tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
 314        tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
 315        tpci200->mod_mem[IPACK_INT_SPACE] =
 316                ioidint_base + TPCI200_INT_SPACE_OFF;
 317        tpci200->mod_mem[IPACK_MEM8_SPACE] =
 318                pci_resource_start(tpci200->info->pdev,
 319                                   TPCI200_MEM8_SPACE_BAR);
 320        tpci200->mod_mem[IPACK_MEM16_SPACE] =
 321                pci_resource_start(tpci200->info->pdev,
 322                                   TPCI200_MEM16_SPACE_BAR);
 323
 324        /* Set the default parameters of the slot
 325         * INT0 disabled, level sensitive
 326         * INT1 disabled, level sensitive
 327         * error interrupt disabled
 328         * timeout interrupt disabled
 329         * recover time disabled
 330         * clock rate 8 MHz
 331         */
 332        slot_ctrl = 0;
 333        for (i = 0; i < TPCI200_NB_SLOT; i++)
 334                writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
 335
 336        res = request_irq(tpci200->info->pdev->irq,
 337                          tpci200_interrupt, IRQF_SHARED,
 338                          KBUILD_MODNAME, (void *) tpci200);
 339        if (res) {
 340                dev_err(&tpci200->info->pdev->dev,
 341                        "(bn 0x%X, sn 0x%X) unable to register IRQ !",
 342                        tpci200->info->pdev->bus->number,
 343                        tpci200->info->pdev->devfn);
 344                goto err_interface_regs;
 345        }
 346
 347        return 0;
 348
 349err_interface_regs:
 350        pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
 351err_mem16_space_bar:
 352        pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
 353err_mem8_space_bar:
 354        pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
 355err_io_id_int_spaces_bar:
 356        pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
 357err_ip_interface_bar:
 358        pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
 359err_disable_device:
 360        pci_disable_device(tpci200->info->pdev);
 361        return res;
 362}
 363
 364static int tpci200_get_clockrate(struct ipack_device *dev)
 365{
 366        struct tpci200_board *tpci200 = check_slot(dev);
 367        __le16 __iomem *addr;
 368
 369        if (!tpci200)
 370                return -ENODEV;
 371
 372        addr = &tpci200->info->interface_regs->control[dev->slot];
 373        return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8;
 374}
 375
 376static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
 377{
 378        struct tpci200_board *tpci200 = check_slot(dev);
 379        __le16 __iomem *addr;
 380
 381        if (!tpci200)
 382                return -ENODEV;
 383
 384        addr = &tpci200->info->interface_regs->control[dev->slot];
 385
 386        switch (mherz) {
 387        case 8:
 388                tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
 389                break;
 390        case 32:
 391                tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
 392                break;
 393        default:
 394                return -EINVAL;
 395        }
 396        return 0;
 397}
 398
 399static int tpci200_get_error(struct ipack_device *dev)
 400{
 401        struct tpci200_board *tpci200 = check_slot(dev);
 402        __le16 __iomem *addr;
 403        u16 mask;
 404
 405        if (!tpci200)
 406                return -ENODEV;
 407
 408        addr = &tpci200->info->interface_regs->status;
 409        mask = tpci200_status_error[dev->slot];
 410        return (ioread16(addr) & mask) ? 1 : 0;
 411}
 412
 413static int tpci200_get_timeout(struct ipack_device *dev)
 414{
 415        struct tpci200_board *tpci200 = check_slot(dev);
 416        __le16 __iomem *addr;
 417        u16 mask;
 418
 419        if (!tpci200)
 420                return -ENODEV;
 421
 422        addr = &tpci200->info->interface_regs->status;
 423        mask = tpci200_status_timeout[dev->slot];
 424
 425        return (ioread16(addr) & mask) ? 1 : 0;
 426}
 427
 428static int tpci200_reset_timeout(struct ipack_device *dev)
 429{
 430        struct tpci200_board *tpci200 = check_slot(dev);
 431        __le16 __iomem *addr;
 432        u16 mask;
 433
 434        if (!tpci200)
 435                return -ENODEV;
 436
 437        addr = &tpci200->info->interface_regs->status;
 438        mask = tpci200_status_timeout[dev->slot];
 439
 440        iowrite16(mask, addr);
 441        return 0;
 442}
 443
 444static void tpci200_uninstall(struct tpci200_board *tpci200)
 445{
 446        tpci200_unregister(tpci200);
 447        kfree(tpci200->slots);
 448}
 449
 450static const struct ipack_bus_ops tpci200_bus_ops = {
 451        .request_irq = tpci200_request_irq,
 452        .free_irq = tpci200_free_irq,
 453        .get_clockrate = tpci200_get_clockrate,
 454        .set_clockrate = tpci200_set_clockrate,
 455        .get_error     = tpci200_get_error,
 456        .get_timeout   = tpci200_get_timeout,
 457        .reset_timeout = tpci200_reset_timeout,
 458};
 459
 460static int tpci200_install(struct tpci200_board *tpci200)
 461{
 462        int res;
 463
 464        tpci200->slots = kcalloc(TPCI200_NB_SLOT, sizeof(struct tpci200_slot),
 465                                 GFP_KERNEL);
 466        if (tpci200->slots == NULL)
 467                return -ENOMEM;
 468
 469        res = tpci200_register(tpci200);
 470        if (res) {
 471                kfree(tpci200->slots);
 472                tpci200->slots = NULL;
 473                return res;
 474        }
 475
 476        mutex_init(&tpci200->mutex);
 477        return 0;
 478}
 479
 480static void tpci200_release_device(struct ipack_device *dev)
 481{
 482        kfree(dev);
 483}
 484
 485static int tpci200_create_device(struct tpci200_board *tpci200, int i)
 486{
 487        int ret;
 488        enum ipack_space space;
 489        struct ipack_device *dev =
 490                kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
 491        if (!dev)
 492                return -ENOMEM;
 493        dev->slot = i;
 494        dev->bus = tpci200->info->ipack_bus;
 495        dev->release = tpci200_release_device;
 496
 497        for (space = 0; space < IPACK_SPACE_COUNT; space++) {
 498                dev->region[space].start =
 499                        tpci200->mod_mem[space]
 500                        + tpci200_space_interval[space] * i;
 501                dev->region[space].size = tpci200_space_size[space];
 502        }
 503
 504        ret = ipack_device_init(dev);
 505        if (ret < 0) {
 506                ipack_put_device(dev);
 507                return ret;
 508        }
 509
 510        ret = ipack_device_add(dev);
 511        if (ret < 0)
 512                ipack_put_device(dev);
 513
 514        return ret;
 515}
 516
 517static int tpci200_pci_probe(struct pci_dev *pdev,
 518                             const struct pci_device_id *id)
 519{
 520        int ret, i;
 521        struct tpci200_board *tpci200;
 522        u32 reg32;
 523
 524        tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
 525        if (!tpci200)
 526                return -ENOMEM;
 527
 528        tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
 529        if (!tpci200->info) {
 530                ret = -ENOMEM;
 531                goto err_tpci200;
 532        }
 533
 534        pci_dev_get(pdev);
 535
 536        /* Obtain a mapping of the carrier's PCI configuration registers */
 537        ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
 538                                 KBUILD_MODNAME " Configuration Memory");
 539        if (ret) {
 540                dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
 541                ret = -EBUSY;
 542                goto err_tpci200_info;
 543        }
 544        tpci200->info->cfg_regs = ioremap(
 545                        pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
 546                        pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
 547        if (!tpci200->info->cfg_regs) {
 548                dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
 549                ret = -EFAULT;
 550                goto err_request_region;
 551        }
 552
 553        /* Disable byte swapping for 16 bit IP module access. This will ensure
 554         * that the Industrypack big endian byte order is preserved by the
 555         * carrier. */
 556        reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
 557        reg32 |= 1 << LAS_BIT_BIGENDIAN;
 558        iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
 559
 560        reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
 561        reg32 |= 1 << LAS_BIT_BIGENDIAN;
 562        iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
 563
 564        /* Save struct pci_dev pointer */
 565        tpci200->info->pdev = pdev;
 566        tpci200->info->id_table = (struct pci_device_id *)id;
 567
 568        /* register the device and initialize it */
 569        ret = tpci200_install(tpci200);
 570        if (ret) {
 571                dev_err(&pdev->dev, "error during tpci200 install\n");
 572                ret = -ENODEV;
 573                goto err_cfg_regs;
 574        }
 575
 576        /* Register the carrier in the industry pack bus driver */
 577        tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
 578                                                      TPCI200_NB_SLOT,
 579                                                      &tpci200_bus_ops,
 580                                                      THIS_MODULE);
 581        if (!tpci200->info->ipack_bus) {
 582                dev_err(&pdev->dev,
 583                        "error registering the carrier on ipack driver\n");
 584                ret = -EFAULT;
 585                goto err_tpci200_install;
 586        }
 587
 588        /* save the bus number given by ipack to logging purpose */
 589        tpci200->number = tpci200->info->ipack_bus->bus_nr;
 590        dev_set_drvdata(&pdev->dev, tpci200);
 591
 592        for (i = 0; i < TPCI200_NB_SLOT; i++)
 593                tpci200_create_device(tpci200, i);
 594        return 0;
 595
 596err_tpci200_install:
 597        tpci200_uninstall(tpci200);
 598err_cfg_regs:
 599        pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
 600err_request_region:
 601        pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
 602err_tpci200_info:
 603        kfree(tpci200->info);
 604        pci_dev_put(pdev);
 605err_tpci200:
 606        kfree(tpci200);
 607        return ret;
 608}
 609
 610static void __tpci200_pci_remove(struct tpci200_board *tpci200)
 611{
 612        ipack_bus_unregister(tpci200->info->ipack_bus);
 613        tpci200_uninstall(tpci200);
 614
 615        pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
 616
 617        pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
 618
 619        pci_dev_put(tpci200->info->pdev);
 620
 621        kfree(tpci200->info);
 622        kfree(tpci200);
 623}
 624
 625static void tpci200_pci_remove(struct pci_dev *dev)
 626{
 627        struct tpci200_board *tpci200 = pci_get_drvdata(dev);
 628
 629        __tpci200_pci_remove(tpci200);
 630}
 631
 632static const struct pci_device_id tpci200_idtable[] = {
 633        { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
 634          TPCI200_SUBDEVICE_ID },
 635        { 0, },
 636};
 637
 638MODULE_DEVICE_TABLE(pci, tpci200_idtable);
 639
 640static struct pci_driver tpci200_pci_drv = {
 641        .name = "tpci200",
 642        .id_table = tpci200_idtable,
 643        .probe = tpci200_pci_probe,
 644        .remove = tpci200_pci_remove,
 645};
 646
 647module_pci_driver(tpci200_pci_drv);
 648
 649MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
 650MODULE_LICENSE("GPL");
 651