linux/drivers/rapidio/devices/tsi721.c
<<
>>
Prefs
   1/*
   2 * RapidIO mport driver for Tsi721 PCIExpress-to-SRIO bridge
   3 *
   4 * Copyright 2011 Integrated Device Technology, Inc.
   5 * Alexandre Bounine <alexandre.bounine@idt.com>
   6 * Chul Kim <chul.kim@idt.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License as published by the Free
  10 * Software Foundation; either version 2 of the License, or (at your option)
  11 * any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful, but WITHOUT
  14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  16 * more details.
  17 *
  18 * You should have received a copy of the GNU General Public License along with
  19 * this program; if not, write to the Free Software Foundation, Inc., 59
  20 * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21 */
  22
  23#include <linux/io.h>
  24#include <linux/errno.h>
  25#include <linux/init.h>
  26#include <linux/ioport.h>
  27#include <linux/kernel.h>
  28#include <linux/module.h>
  29#include <linux/pci.h>
  30#include <linux/rio.h>
  31#include <linux/rio_drv.h>
  32#include <linux/dma-mapping.h>
  33#include <linux/interrupt.h>
  34#include <linux/kfifo.h>
  35#include <linux/delay.h>
  36
  37#include "tsi721.h"
  38
  39#define DEBUG_PW        /* Inbound Port-Write debugging */
  40
  41static void tsi721_omsg_handler(struct tsi721_device *priv, int ch);
  42static void tsi721_imsg_handler(struct tsi721_device *priv, int ch);
  43
  44/**
  45 * tsi721_lcread - read from local SREP config space
  46 * @mport: RapidIO master port info
  47 * @index: ID of RapdiIO interface
  48 * @offset: Offset into configuration space
  49 * @len: Length (in bytes) of the maintenance transaction
  50 * @data: Value to be read into
  51 *
  52 * Generates a local SREP space read. Returns %0 on
  53 * success or %-EINVAL on failure.
  54 */
  55static int tsi721_lcread(struct rio_mport *mport, int index, u32 offset,
  56                         int len, u32 *data)
  57{
  58        struct tsi721_device *priv = mport->priv;
  59
  60        if (len != sizeof(u32))
  61                return -EINVAL; /* only 32-bit access is supported */
  62
  63        *data = ioread32(priv->regs + offset);
  64
  65        return 0;
  66}
  67
  68/**
  69 * tsi721_lcwrite - write into local SREP config space
  70 * @mport: RapidIO master port info
  71 * @index: ID of RapdiIO interface
  72 * @offset: Offset into configuration space
  73 * @len: Length (in bytes) of the maintenance transaction
  74 * @data: Value to be written
  75 *
  76 * Generates a local write into SREP configuration space. Returns %0 on
  77 * success or %-EINVAL on failure.
  78 */
  79static int tsi721_lcwrite(struct rio_mport *mport, int index, u32 offset,
  80                          int len, u32 data)
  81{
  82        struct tsi721_device *priv = mport->priv;
  83
  84        if (len != sizeof(u32))
  85                return -EINVAL; /* only 32-bit access is supported */
  86
  87        iowrite32(data, priv->regs + offset);
  88
  89        return 0;
  90}
  91
  92/**
  93 * tsi721_maint_dma - Helper function to generate RapidIO maintenance
  94 *                    transactions using designated Tsi721 DMA channel.
  95 * @priv: pointer to tsi721 private data
  96 * @sys_size: RapdiIO transport system size
  97 * @destid: Destination ID of transaction
  98 * @hopcount: Number of hops to target device
  99 * @offset: Offset into configuration space
 100 * @len: Length (in bytes) of the maintenance transaction
 101 * @data: Location to be read from or write into
 102 * @do_wr: Operation flag (1 == MAINT_WR)
 103 *
 104 * Generates a RapidIO maintenance transaction (Read or Write).
 105 * Returns %0 on success and %-EINVAL or %-EFAULT on failure.
 106 */
 107static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size,
 108                        u16 destid, u8 hopcount, u32 offset, int len,
 109                        u32 *data, int do_wr)
 110{
 111        void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id);
 112        struct tsi721_dma_desc *bd_ptr;
 113        u32 rd_count, swr_ptr, ch_stat;
 114        int i, err = 0;
 115        u32 op = do_wr ? MAINT_WR : MAINT_RD;
 116
 117        if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32)))
 118                return -EINVAL;
 119
 120        bd_ptr = priv->mdma.bd_base;
 121
 122        rd_count = ioread32(regs + TSI721_DMAC_DRDCNT);
 123
 124        /* Initialize DMA descriptor */
 125        bd_ptr[0].type_id = cpu_to_le32((DTYPE2 << 29) | (op << 19) | destid);
 126        bd_ptr[0].bcount = cpu_to_le32((sys_size << 26) | 0x04);
 127        bd_ptr[0].raddr_lo = cpu_to_le32((hopcount << 24) | offset);
 128        bd_ptr[0].raddr_hi = 0;
 129        if (do_wr)
 130                bd_ptr[0].data[0] = cpu_to_be32p(data);
 131        else
 132                bd_ptr[0].data[0] = 0xffffffff;
 133
 134        mb();
 135
 136        /* Start DMA operation */
 137        iowrite32(rd_count + 2, regs + TSI721_DMAC_DWRCNT);
 138        ioread32(regs + TSI721_DMAC_DWRCNT);
 139        i = 0;
 140
 141        /* Wait until DMA transfer is finished */
 142        while ((ch_stat = ioread32(regs + TSI721_DMAC_STS))
 143                                                        & TSI721_DMAC_STS_RUN) {
 144                udelay(1);
 145                if (++i >= 5000000) {
 146                        dev_dbg(&priv->pdev->dev,
 147                                "%s : DMA[%d] read timeout ch_status=%x\n",
 148                                __func__, priv->mdma.ch_id, ch_stat);
 149                        if (!do_wr)
 150                                *data = 0xffffffff;
 151                        err = -EIO;
 152                        goto err_out;
 153                }
 154        }
 155
 156        if (ch_stat & TSI721_DMAC_STS_ABORT) {
 157                /* If DMA operation aborted due to error,
 158                 * reinitialize DMA channel
 159                 */
 160                dev_dbg(&priv->pdev->dev, "%s : DMA ABORT ch_stat=%x\n",
 161                        __func__, ch_stat);
 162                dev_dbg(&priv->pdev->dev, "OP=%d : destid=%x hc=%x off=%x\n",
 163                        do_wr ? MAINT_WR : MAINT_RD, destid, hopcount, offset);
 164                iowrite32(TSI721_DMAC_INT_ALL, regs + TSI721_DMAC_INT);
 165                iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL);
 166                udelay(10);
 167                iowrite32(0, regs + TSI721_DMAC_DWRCNT);
 168                udelay(1);
 169                if (!do_wr)
 170                        *data = 0xffffffff;
 171                err = -EIO;
 172                goto err_out;
 173        }
 174
 175        if (!do_wr)
 176                *data = be32_to_cpu(bd_ptr[0].data[0]);
 177
 178        /*
 179         * Update descriptor status FIFO RD pointer.
 180         * NOTE: Skipping check and clear FIFO entries because we are waiting
 181         * for transfer to be completed.
 182         */
 183        swr_ptr = ioread32(regs + TSI721_DMAC_DSWP);
 184        iowrite32(swr_ptr, regs + TSI721_DMAC_DSRP);
 185err_out:
 186
 187        return err;
 188}
 189
 190/**
 191 * tsi721_cread_dma - Generate a RapidIO maintenance read transaction
 192 *                    using Tsi721 BDMA engine.
 193 * @mport: RapidIO master port control structure
 194 * @index: ID of RapdiIO interface
 195 * @destid: Destination ID of transaction
 196 * @hopcount: Number of hops to target device
 197 * @offset: Offset into configuration space
 198 * @len: Length (in bytes) of the maintenance transaction
 199 * @val: Location to be read into
 200 *
 201 * Generates a RapidIO maintenance read transaction.
 202 * Returns %0 on success and %-EINVAL or %-EFAULT on failure.
 203 */
 204static int tsi721_cread_dma(struct rio_mport *mport, int index, u16 destid,
 205                        u8 hopcount, u32 offset, int len, u32 *data)
 206{
 207        struct tsi721_device *priv = mport->priv;
 208
 209        return tsi721_maint_dma(priv, mport->sys_size, destid, hopcount,
 210                                offset, len, data, 0);
 211}
 212
 213/**
 214 * tsi721_cwrite_dma - Generate a RapidIO maintenance write transaction
 215 *                     using Tsi721 BDMA engine
 216 * @mport: RapidIO master port control structure
 217 * @index: ID of RapdiIO interface
 218 * @destid: Destination ID of transaction
 219 * @hopcount: Number of hops to target device
 220 * @offset: Offset into configuration space
 221 * @len: Length (in bytes) of the maintenance transaction
 222 * @val: Value to be written
 223 *
 224 * Generates a RapidIO maintenance write transaction.
 225 * Returns %0 on success and %-EINVAL or %-EFAULT on failure.
 226 */
 227static int tsi721_cwrite_dma(struct rio_mport *mport, int index, u16 destid,
 228                         u8 hopcount, u32 offset, int len, u32 data)
 229{
 230        struct tsi721_device *priv = mport->priv;
 231        u32 temp = data;
 232
 233        return tsi721_maint_dma(priv, mport->sys_size, destid, hopcount,
 234                                offset, len, &temp, 1);
 235}
 236
 237/**
 238 * tsi721_pw_handler - Tsi721 inbound port-write interrupt handler
 239 * @mport: RapidIO master port structure
 240 *
 241 * Handles inbound port-write interrupts. Copies PW message from an internal
 242 * buffer into PW message FIFO and schedules deferred routine to process
 243 * queued messages.
 244 */
 245static int
 246tsi721_pw_handler(struct rio_mport *mport)
 247{
 248        struct tsi721_device *priv = mport->priv;
 249        u32 pw_stat;
 250        u32 pw_buf[TSI721_RIO_PW_MSG_SIZE/sizeof(u32)];
 251
 252
 253        pw_stat = ioread32(priv->regs + TSI721_RIO_PW_RX_STAT);
 254
 255        if (pw_stat & TSI721_RIO_PW_RX_STAT_PW_VAL) {
 256                pw_buf[0] = ioread32(priv->regs + TSI721_RIO_PW_RX_CAPT(0));
 257                pw_buf[1] = ioread32(priv->regs + TSI721_RIO_PW_RX_CAPT(1));
 258                pw_buf[2] = ioread32(priv->regs + TSI721_RIO_PW_RX_CAPT(2));
 259                pw_buf[3] = ioread32(priv->regs + TSI721_RIO_PW_RX_CAPT(3));
 260
 261                /* Queue PW message (if there is room in FIFO),
 262                 * otherwise discard it.
 263                 */
 264                spin_lock(&priv->pw_fifo_lock);
 265                if (kfifo_avail(&priv->pw_fifo) >= TSI721_RIO_PW_MSG_SIZE)
 266                        kfifo_in(&priv->pw_fifo, pw_buf,
 267                                                TSI721_RIO_PW_MSG_SIZE);
 268                else
 269                        priv->pw_discard_count++;
 270                spin_unlock(&priv->pw_fifo_lock);
 271        }
 272
 273        /* Clear pending PW interrupts */
 274        iowrite32(TSI721_RIO_PW_RX_STAT_PW_DISC | TSI721_RIO_PW_RX_STAT_PW_VAL,
 275                  priv->regs + TSI721_RIO_PW_RX_STAT);
 276
 277        schedule_work(&priv->pw_work);
 278
 279        return 0;
 280}
 281
 282static void tsi721_pw_dpc(struct work_struct *work)
 283{
 284        struct tsi721_device *priv = container_of(work, struct tsi721_device,
 285                                                    pw_work);
 286        u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)]; /* Use full size PW message
 287                                                        buffer for RIO layer */
 288
 289        /*
 290         * Process port-write messages
 291         */
 292        while (kfifo_out_spinlocked(&priv->pw_fifo, (unsigned char *)msg_buffer,
 293                         TSI721_RIO_PW_MSG_SIZE, &priv->pw_fifo_lock)) {
 294                /* Process one message */
 295#ifdef DEBUG_PW
 296                {
 297                u32 i;
 298                pr_debug("%s : Port-Write Message:", __func__);
 299                for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32); ) {
 300                        pr_debug("0x%02x: %08x %08x %08x %08x", i*4,
 301                                msg_buffer[i], msg_buffer[i + 1],
 302                                msg_buffer[i + 2], msg_buffer[i + 3]);
 303                        i += 4;
 304                }
 305                pr_debug("\n");
 306                }
 307#endif
 308                /* Pass the port-write message to RIO core for processing */
 309                rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer);
 310        }
 311}
 312
 313/**
 314 * tsi721_pw_enable - enable/disable port-write interface init
 315 * @mport: Master port implementing the port write unit
 316 * @enable:    1=enable; 0=disable port-write message handling
 317 */
 318static int tsi721_pw_enable(struct rio_mport *mport, int enable)
 319{
 320        struct tsi721_device *priv = mport->priv;
 321        u32 rval;
 322
 323        rval = ioread32(priv->regs + TSI721_RIO_EM_INT_ENABLE);
 324
 325        if (enable)
 326                rval |= TSI721_RIO_EM_INT_ENABLE_PW_RX;
 327        else
 328                rval &= ~TSI721_RIO_EM_INT_ENABLE_PW_RX;
 329
 330        /* Clear pending PW interrupts */
 331        iowrite32(TSI721_RIO_PW_RX_STAT_PW_DISC | TSI721_RIO_PW_RX_STAT_PW_VAL,
 332                  priv->regs + TSI721_RIO_PW_RX_STAT);
 333        /* Update enable bits */
 334        iowrite32(rval, priv->regs + TSI721_RIO_EM_INT_ENABLE);
 335
 336        return 0;
 337}
 338
 339/**
 340 * tsi721_dsend - Send a RapidIO doorbell
 341 * @mport: RapidIO master port info
 342 * @index: ID of RapidIO interface
 343 * @destid: Destination ID of target device
 344 * @data: 16-bit info field of RapidIO doorbell
 345 *
 346 * Sends a RapidIO doorbell message. Always returns %0.
 347 */
 348static int tsi721_dsend(struct rio_mport *mport, int index,
 349                        u16 destid, u16 data)
 350{
 351        struct tsi721_device *priv = mport->priv;
 352        u32 offset;
 353
 354        offset = (((mport->sys_size) ? RIO_TT_CODE_16 : RIO_TT_CODE_8) << 18) |
 355                 (destid << 2);
 356
 357        dev_dbg(&priv->pdev->dev,
 358                "Send Doorbell 0x%04x to destID 0x%x\n", data, destid);
 359        iowrite16be(data, priv->odb_base + offset);
 360
 361        return 0;
 362}
 363
 364/**
 365 * tsi721_dbell_handler - Tsi721 doorbell interrupt handler
 366 * @mport: RapidIO master port structure
 367 *
 368 * Handles inbound doorbell interrupts. Copies doorbell entry from an internal
 369 * buffer into DB message FIFO and schedules deferred  routine to process
 370 * queued DBs.
 371 */
 372static int
 373tsi721_dbell_handler(struct rio_mport *mport)
 374{
 375        struct tsi721_device *priv = mport->priv;
 376        u32 regval;
 377
 378        /* Disable IDB interrupts */
 379        regval = ioread32(priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
 380        regval &= ~TSI721_SR_CHINT_IDBQRCV;
 381        iowrite32(regval,
 382                priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
 383
 384        schedule_work(&priv->idb_work);
 385
 386        return 0;
 387}
 388
 389static void tsi721_db_dpc(struct work_struct *work)
 390{
 391        struct tsi721_device *priv = container_of(work, struct tsi721_device,
 392                                                    idb_work);
 393        struct rio_mport *mport;
 394        struct rio_dbell *dbell;
 395        int found = 0;
 396        u32 wr_ptr, rd_ptr;
 397        u64 *idb_entry;
 398        u32 regval;
 399        union {
 400                u64 msg;
 401                u8  bytes[8];
 402        } idb;
 403
 404        /*
 405         * Process queued inbound doorbells
 406         */
 407        mport = priv->mport;
 408
 409        wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
 410        rd_ptr = ioread32(priv->regs + TSI721_IDQ_RP(IDB_QUEUE)) % IDB_QSIZE;
 411
 412        while (wr_ptr != rd_ptr) {
 413                idb_entry = (u64 *)(priv->idb_base +
 414                                        (TSI721_IDB_ENTRY_SIZE * rd_ptr));
 415                rd_ptr++;
 416                rd_ptr %= IDB_QSIZE;
 417                idb.msg = *idb_entry;
 418                *idb_entry = 0;
 419
 420                /* Process one doorbell */
 421                list_for_each_entry(dbell, &mport->dbells, node) {
 422                        if ((dbell->res->start <= DBELL_INF(idb.bytes)) &&
 423                            (dbell->res->end >= DBELL_INF(idb.bytes))) {
 424                                found = 1;
 425                                break;
 426                        }
 427                }
 428
 429                if (found) {
 430                        dbell->dinb(mport, dbell->dev_id, DBELL_SID(idb.bytes),
 431                                    DBELL_TID(idb.bytes), DBELL_INF(idb.bytes));
 432                } else {
 433                        dev_dbg(&priv->pdev->dev,
 434                                "spurious inb doorbell, sid %2.2x tid %2.2x"
 435                                " info %4.4x\n", DBELL_SID(idb.bytes),
 436                                DBELL_TID(idb.bytes), DBELL_INF(idb.bytes));
 437                }
 438
 439                wr_ptr = ioread32(priv->regs +
 440                                  TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
 441        }
 442
 443        iowrite32(rd_ptr & (IDB_QSIZE - 1),
 444                priv->regs + TSI721_IDQ_RP(IDB_QUEUE));
 445
 446        /* Re-enable IDB interrupts */
 447        regval = ioread32(priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
 448        regval |= TSI721_SR_CHINT_IDBQRCV;
 449        iowrite32(regval,
 450                priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
 451
 452        wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
 453        if (wr_ptr != rd_ptr)
 454                schedule_work(&priv->idb_work);
 455}
 456
 457/**
 458 * tsi721_irqhandler - Tsi721 interrupt handler
 459 * @irq: Linux interrupt number
 460 * @ptr: Pointer to interrupt-specific data (mport structure)
 461 *
 462 * Handles Tsi721 interrupts signaled using MSI and INTA. Checks reported
 463 * interrupt events and calls an event-specific handler(s).
 464 */
 465static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
 466{
 467        struct rio_mport *mport = (struct rio_mport *)ptr;
 468        struct tsi721_device *priv = mport->priv;
 469        u32 dev_int;
 470        u32 dev_ch_int;
 471        u32 intval;
 472        u32 ch_inte;
 473
 474        /* For MSI mode disable all device-level interrupts */
 475        if (priv->flags & TSI721_USING_MSI)
 476                iowrite32(0, priv->regs + TSI721_DEV_INTE);
 477
 478        dev_int = ioread32(priv->regs + TSI721_DEV_INT);
 479        if (!dev_int)
 480                return IRQ_NONE;
 481
 482        dev_ch_int = ioread32(priv->regs + TSI721_DEV_CHAN_INT);
 483
 484        if (dev_int & TSI721_DEV_INT_SR2PC_CH) {
 485                /* Service SR2PC Channel interrupts */
 486                if (dev_ch_int & TSI721_INT_SR2PC_CHAN(IDB_QUEUE)) {
 487                        /* Service Inbound Doorbell interrupt */
 488                        intval = ioread32(priv->regs +
 489                                                TSI721_SR_CHINT(IDB_QUEUE));
 490                        if (intval & TSI721_SR_CHINT_IDBQRCV)
 491                                tsi721_dbell_handler(mport);
 492                        else
 493                                dev_info(&priv->pdev->dev,
 494                                        "Unsupported SR_CH_INT %x\n", intval);
 495
 496                        /* Clear interrupts */
 497                        iowrite32(intval,
 498                                priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 499                        ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 500                }
 501        }
 502
 503        if (dev_int & TSI721_DEV_INT_SMSG_CH) {
 504                int ch;
 505
 506                /*
 507                 * Service channel interrupts from Messaging Engine
 508                 */
 509
 510                if (dev_ch_int & TSI721_INT_IMSG_CHAN_M) { /* Inbound Msg */
 511                        /* Disable signaled OB MSG Channel interrupts */
 512                        ch_inte = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
 513                        ch_inte &= ~(dev_ch_int & TSI721_INT_IMSG_CHAN_M);
 514                        iowrite32(ch_inte, priv->regs + TSI721_DEV_CHAN_INTE);
 515
 516                        /*
 517                         * Process Inbound Message interrupt for each MBOX
 518                         */
 519                        for (ch = 4; ch < RIO_MAX_MBOX + 4; ch++) {
 520                                if (!(dev_ch_int & TSI721_INT_IMSG_CHAN(ch)))
 521                                        continue;
 522                                tsi721_imsg_handler(priv, ch);
 523                        }
 524                }
 525
 526                if (dev_ch_int & TSI721_INT_OMSG_CHAN_M) { /* Outbound Msg */
 527                        /* Disable signaled OB MSG Channel interrupts */
 528                        ch_inte = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
 529                        ch_inte &= ~(dev_ch_int & TSI721_INT_OMSG_CHAN_M);
 530                        iowrite32(ch_inte, priv->regs + TSI721_DEV_CHAN_INTE);
 531
 532                        /*
 533                         * Process Outbound Message interrupts for each MBOX
 534                         */
 535
 536                        for (ch = 0; ch < RIO_MAX_MBOX; ch++) {
 537                                if (!(dev_ch_int & TSI721_INT_OMSG_CHAN(ch)))
 538                                        continue;
 539                                tsi721_omsg_handler(priv, ch);
 540                        }
 541                }
 542        }
 543
 544        if (dev_int & TSI721_DEV_INT_SRIO) {
 545                /* Service SRIO MAC interrupts */
 546                intval = ioread32(priv->regs + TSI721_RIO_EM_INT_STAT);
 547                if (intval & TSI721_RIO_EM_INT_STAT_PW_RX)
 548                        tsi721_pw_handler(mport);
 549        }
 550
 551#ifdef CONFIG_RAPIDIO_DMA_ENGINE
 552        if (dev_int & TSI721_DEV_INT_BDMA_CH) {
 553                int ch;
 554
 555                if (dev_ch_int & TSI721_INT_BDMA_CHAN_M) {
 556                        dev_dbg(&priv->pdev->dev,
 557                                "IRQ from DMA channel 0x%08x\n", dev_ch_int);
 558
 559                        for (ch = 0; ch < TSI721_DMA_MAXCH; ch++) {
 560                                if (!(dev_ch_int & TSI721_INT_BDMA_CHAN(ch)))
 561                                        continue;
 562                                tsi721_bdma_handler(&priv->bdma[ch]);
 563                        }
 564                }
 565        }
 566#endif
 567
 568        /* For MSI mode re-enable device-level interrupts */
 569        if (priv->flags & TSI721_USING_MSI) {
 570                dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
 571                        TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH;
 572                iowrite32(dev_int, priv->regs + TSI721_DEV_INTE);
 573        }
 574
 575        return IRQ_HANDLED;
 576}
 577
 578static void tsi721_interrupts_init(struct tsi721_device *priv)
 579{
 580        u32 intr;
 581
 582        /* Enable IDB interrupts */
 583        iowrite32(TSI721_SR_CHINT_ALL,
 584                priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 585        iowrite32(TSI721_SR_CHINT_IDBQRCV,
 586                priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
 587
 588        /* Enable SRIO MAC interrupts */
 589        iowrite32(TSI721_RIO_EM_DEV_INT_EN_INT,
 590                priv->regs + TSI721_RIO_EM_DEV_INT_EN);
 591
 592        /* Enable interrupts from channels in use */
 593#ifdef CONFIG_RAPIDIO_DMA_ENGINE
 594        intr = TSI721_INT_SR2PC_CHAN(IDB_QUEUE) |
 595                (TSI721_INT_BDMA_CHAN_M &
 596                 ~TSI721_INT_BDMA_CHAN(TSI721_DMACH_MAINT));
 597#else
 598        intr = TSI721_INT_SR2PC_CHAN(IDB_QUEUE);
 599#endif
 600        iowrite32(intr, priv->regs + TSI721_DEV_CHAN_INTE);
 601
 602        if (priv->flags & TSI721_USING_MSIX)
 603                intr = TSI721_DEV_INT_SRIO;
 604        else
 605                intr = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO |
 606                        TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH;
 607
 608        iowrite32(intr, priv->regs + TSI721_DEV_INTE);
 609        ioread32(priv->regs + TSI721_DEV_INTE);
 610}
 611
 612#ifdef CONFIG_PCI_MSI
 613/**
 614 * tsi721_omsg_msix - MSI-X interrupt handler for outbound messaging
 615 * @irq: Linux interrupt number
 616 * @ptr: Pointer to interrupt-specific data (mport structure)
 617 *
 618 * Handles outbound messaging interrupts signaled using MSI-X.
 619 */
 620static irqreturn_t tsi721_omsg_msix(int irq, void *ptr)
 621{
 622        struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
 623        int mbox;
 624
 625        mbox = (irq - priv->msix[TSI721_VECT_OMB0_DONE].vector) % RIO_MAX_MBOX;
 626        tsi721_omsg_handler(priv, mbox);
 627        return IRQ_HANDLED;
 628}
 629
 630/**
 631 * tsi721_imsg_msix - MSI-X interrupt handler for inbound messaging
 632 * @irq: Linux interrupt number
 633 * @ptr: Pointer to interrupt-specific data (mport structure)
 634 *
 635 * Handles inbound messaging interrupts signaled using MSI-X.
 636 */
 637static irqreturn_t tsi721_imsg_msix(int irq, void *ptr)
 638{
 639        struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
 640        int mbox;
 641
 642        mbox = (irq - priv->msix[TSI721_VECT_IMB0_RCV].vector) % RIO_MAX_MBOX;
 643        tsi721_imsg_handler(priv, mbox + 4);
 644        return IRQ_HANDLED;
 645}
 646
 647/**
 648 * tsi721_srio_msix - Tsi721 MSI-X SRIO MAC interrupt handler
 649 * @irq: Linux interrupt number
 650 * @ptr: Pointer to interrupt-specific data (mport structure)
 651 *
 652 * Handles Tsi721 interrupts from SRIO MAC.
 653 */
 654static irqreturn_t tsi721_srio_msix(int irq, void *ptr)
 655{
 656        struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
 657        u32 srio_int;
 658
 659        /* Service SRIO MAC interrupts */
 660        srio_int = ioread32(priv->regs + TSI721_RIO_EM_INT_STAT);
 661        if (srio_int & TSI721_RIO_EM_INT_STAT_PW_RX)
 662                tsi721_pw_handler((struct rio_mport *)ptr);
 663
 664        return IRQ_HANDLED;
 665}
 666
 667/**
 668 * tsi721_sr2pc_ch_msix - Tsi721 MSI-X SR2PC Channel interrupt handler
 669 * @irq: Linux interrupt number
 670 * @ptr: Pointer to interrupt-specific data (mport structure)
 671 *
 672 * Handles Tsi721 interrupts from SR2PC Channel.
 673 * NOTE: At this moment services only one SR2PC channel associated with inbound
 674 * doorbells.
 675 */
 676static irqreturn_t tsi721_sr2pc_ch_msix(int irq, void *ptr)
 677{
 678        struct tsi721_device *priv = ((struct rio_mport *)ptr)->priv;
 679        u32 sr_ch_int;
 680
 681        /* Service Inbound DB interrupt from SR2PC channel */
 682        sr_ch_int = ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 683        if (sr_ch_int & TSI721_SR_CHINT_IDBQRCV)
 684                tsi721_dbell_handler((struct rio_mport *)ptr);
 685
 686        /* Clear interrupts */
 687        iowrite32(sr_ch_int, priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 688        /* Read back to ensure that interrupt was cleared */
 689        sr_ch_int = ioread32(priv->regs + TSI721_SR_CHINT(IDB_QUEUE));
 690
 691        return IRQ_HANDLED;
 692}
 693
 694/**
 695 * tsi721_request_msix - register interrupt service for MSI-X mode.
 696 * @mport: RapidIO master port structure
 697 *
 698 * Registers MSI-X interrupt service routines for interrupts that are active
 699 * immediately after mport initialization. Messaging interrupt service routines
 700 * should be registered during corresponding open requests.
 701 */
 702static int tsi721_request_msix(struct rio_mport *mport)
 703{
 704        struct tsi721_device *priv = mport->priv;
 705        int err = 0;
 706
 707        err = request_irq(priv->msix[TSI721_VECT_IDB].vector,
 708                        tsi721_sr2pc_ch_msix, 0,
 709                        priv->msix[TSI721_VECT_IDB].irq_name, (void *)mport);
 710        if (err)
 711                goto out;
 712
 713        err = request_irq(priv->msix[TSI721_VECT_PWRX].vector,
 714                        tsi721_srio_msix, 0,
 715                        priv->msix[TSI721_VECT_PWRX].irq_name, (void *)mport);
 716        if (err)
 717                free_irq(
 718                        priv->msix[TSI721_VECT_IDB].vector,
 719                        (void *)mport);
 720out:
 721        return err;
 722}
 723
 724/**
 725 * tsi721_enable_msix - Attempts to enable MSI-X support for Tsi721.
 726 * @priv: pointer to tsi721 private data
 727 *
 728 * Configures MSI-X support for Tsi721. Supports only an exact number
 729 * of requested vectors.
 730 */
 731static int tsi721_enable_msix(struct tsi721_device *priv)
 732{
 733        struct msix_entry entries[TSI721_VECT_MAX];
 734        int err;
 735        int i;
 736
 737        entries[TSI721_VECT_IDB].entry = TSI721_MSIX_SR2PC_IDBQ_RCV(IDB_QUEUE);
 738        entries[TSI721_VECT_PWRX].entry = TSI721_MSIX_SRIO_MAC_INT;
 739
 740        /*
 741         * Initialize MSI-X entries for Messaging Engine:
 742         * this driver supports four RIO mailboxes (inbound and outbound)
 743         * NOTE: Inbound message MBOX 0...4 use IB channels 4...7. Therefore
 744         * offset +4 is added to IB MBOX number.
 745         */
 746        for (i = 0; i < RIO_MAX_MBOX; i++) {
 747                entries[TSI721_VECT_IMB0_RCV + i].entry =
 748                                        TSI721_MSIX_IMSG_DQ_RCV(i + 4);
 749                entries[TSI721_VECT_IMB0_INT + i].entry =
 750                                        TSI721_MSIX_IMSG_INT(i + 4);
 751                entries[TSI721_VECT_OMB0_DONE + i].entry =
 752                                        TSI721_MSIX_OMSG_DONE(i);
 753                entries[TSI721_VECT_OMB0_INT + i].entry =
 754                                        TSI721_MSIX_OMSG_INT(i);
 755        }
 756
 757#ifdef CONFIG_RAPIDIO_DMA_ENGINE
 758        /*
 759         * Initialize MSI-X entries for Block DMA Engine:
 760         * this driver supports XXX DMA channels
 761         * (one is reserved for SRIO maintenance transactions)
 762         */
 763        for (i = 0; i < TSI721_DMA_CHNUM; i++) {
 764                entries[TSI721_VECT_DMA0_DONE + i].entry =
 765                                        TSI721_MSIX_DMACH_DONE(i);
 766                entries[TSI721_VECT_DMA0_INT + i].entry =
 767                                        TSI721_MSIX_DMACH_INT(i);
 768        }
 769#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
 770
 771        err = pci_enable_msix_exact(priv->pdev, entries, ARRAY_SIZE(entries));
 772        if (err) {
 773                dev_err(&priv->pdev->dev,
 774                        "Failed to enable MSI-X (err=%d)\n", err);
 775                return err;
 776        }
 777
 778        /*
 779         * Copy MSI-X vector information into tsi721 private structure
 780         */
 781        priv->msix[TSI721_VECT_IDB].vector = entries[TSI721_VECT_IDB].vector;
 782        snprintf(priv->msix[TSI721_VECT_IDB].irq_name, IRQ_DEVICE_NAME_MAX,
 783                 DRV_NAME "-idb@pci:%s", pci_name(priv->pdev));
 784        priv->msix[TSI721_VECT_PWRX].vector = entries[TSI721_VECT_PWRX].vector;
 785        snprintf(priv->msix[TSI721_VECT_PWRX].irq_name, IRQ_DEVICE_NAME_MAX,
 786                 DRV_NAME "-pwrx@pci:%s", pci_name(priv->pdev));
 787
 788        for (i = 0; i < RIO_MAX_MBOX; i++) {
 789                priv->msix[TSI721_VECT_IMB0_RCV + i].vector =
 790                                entries[TSI721_VECT_IMB0_RCV + i].vector;
 791                snprintf(priv->msix[TSI721_VECT_IMB0_RCV + i].irq_name,
 792                         IRQ_DEVICE_NAME_MAX, DRV_NAME "-imbr%d@pci:%s",
 793                         i, pci_name(priv->pdev));
 794
 795                priv->msix[TSI721_VECT_IMB0_INT + i].vector =
 796                                entries[TSI721_VECT_IMB0_INT + i].vector;
 797                snprintf(priv->msix[TSI721_VECT_IMB0_INT + i].irq_name,
 798                         IRQ_DEVICE_NAME_MAX, DRV_NAME "-imbi%d@pci:%s",
 799                         i, pci_name(priv->pdev));
 800
 801                priv->msix[TSI721_VECT_OMB0_DONE + i].vector =
 802                                entries[TSI721_VECT_OMB0_DONE + i].vector;
 803                snprintf(priv->msix[TSI721_VECT_OMB0_DONE + i].irq_name,
 804                         IRQ_DEVICE_NAME_MAX, DRV_NAME "-ombd%d@pci:%s",
 805                         i, pci_name(priv->pdev));
 806
 807                priv->msix[TSI721_VECT_OMB0_INT + i].vector =
 808                                entries[TSI721_VECT_OMB0_INT + i].vector;
 809                snprintf(priv->msix[TSI721_VECT_OMB0_INT + i].irq_name,
 810                         IRQ_DEVICE_NAME_MAX, DRV_NAME "-ombi%d@pci:%s",
 811                         i, pci_name(priv->pdev));
 812        }
 813
 814#ifdef CONFIG_RAPIDIO_DMA_ENGINE
 815        for (i = 0; i < TSI721_DMA_CHNUM; i++) {
 816                priv->msix[TSI721_VECT_DMA0_DONE + i].vector =
 817                                entries[TSI721_VECT_DMA0_DONE + i].vector;
 818                snprintf(priv->msix[TSI721_VECT_DMA0_DONE + i].irq_name,
 819                         IRQ_DEVICE_NAME_MAX, DRV_NAME "-dmad%d@pci:%s",
 820                         i, pci_name(priv->pdev));
 821
 822                priv->msix[TSI721_VECT_DMA0_INT + i].vector =
 823                                entries[TSI721_VECT_DMA0_INT + i].vector;
 824                snprintf(priv->msix[TSI721_VECT_DMA0_INT + i].irq_name,
 825                         IRQ_DEVICE_NAME_MAX, DRV_NAME "-dmai%d@pci:%s",
 826                         i, pci_name(priv->pdev));
 827        }
 828#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
 829
 830        return 0;
 831}
 832#endif /* CONFIG_PCI_MSI */
 833
 834static int tsi721_request_irq(struct rio_mport *mport)
 835{
 836        struct tsi721_device *priv = mport->priv;
 837        int err;
 838
 839#ifdef CONFIG_PCI_MSI
 840        if (priv->flags & TSI721_USING_MSIX)
 841                err = tsi721_request_msix(mport);
 842        else
 843#endif
 844                err = request_irq(priv->pdev->irq, tsi721_irqhandler,
 845                          (priv->flags & TSI721_USING_MSI) ? 0 : IRQF_SHARED,
 846                          DRV_NAME, (void *)mport);
 847
 848        if (err)
 849                dev_err(&priv->pdev->dev,
 850                        "Unable to allocate interrupt, Error: %d\n", err);
 851
 852        return err;
 853}
 854
 855/**
 856 * tsi721_init_pc2sr_mapping - initializes outbound (PCIe->SRIO)
 857 * translation regions.
 858 * @priv: pointer to tsi721 private data
 859 *
 860 * Disables SREP translation regions.
 861 */
 862static void tsi721_init_pc2sr_mapping(struct tsi721_device *priv)
 863{
 864        int i;
 865
 866        /* Disable all PC2SR translation windows */
 867        for (i = 0; i < TSI721_OBWIN_NUM; i++)
 868                iowrite32(0, priv->regs + TSI721_OBWINLB(i));
 869}
 870
 871/**
 872 * tsi721_rio_map_inb_mem -- Mapping inbound memory region.
 873 * @mport: RapidIO master port
 874 * @lstart: Local memory space start address.
 875 * @rstart: RapidIO space start address.
 876 * @size: The mapping region size.
 877 * @flags: Flags for mapping. 0 for using default flags.
 878 *
 879 * Return: 0 -- Success.
 880 *
 881 * This function will create the inbound mapping
 882 * from rstart to lstart.
 883 */
 884static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
 885                u64 rstart, u32 size, u32 flags)
 886{
 887        struct tsi721_device *priv = mport->priv;
 888        int i;
 889        u32 regval;
 890
 891        if (!is_power_of_2(size) || size < 0x1000 ||
 892            ((u64)lstart & (size - 1)) || (rstart & (size - 1)))
 893                return -EINVAL;
 894
 895        /* Search for free inbound translation window */
 896        for (i = 0; i < TSI721_IBWIN_NUM; i++) {
 897                regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
 898                if (!(regval & TSI721_IBWIN_LB_WEN))
 899                        break;
 900        }
 901
 902        if (i >= TSI721_IBWIN_NUM) {
 903                dev_err(&priv->pdev->dev,
 904                        "Unable to find free inbound window\n");
 905                return -EBUSY;
 906        }
 907
 908        iowrite32(TSI721_IBWIN_SIZE(size) << 8,
 909                        priv->regs + TSI721_IBWIN_SZ(i));
 910
 911        iowrite32(((u64)lstart >> 32), priv->regs + TSI721_IBWIN_TUA(i));
 912        iowrite32(((u64)lstart & TSI721_IBWIN_TLA_ADD),
 913                  priv->regs + TSI721_IBWIN_TLA(i));
 914
 915        iowrite32(rstart >> 32, priv->regs + TSI721_IBWIN_UB(i));
 916        iowrite32((rstart & TSI721_IBWIN_LB_BA) | TSI721_IBWIN_LB_WEN,
 917                priv->regs + TSI721_IBWIN_LB(i));
 918        dev_dbg(&priv->pdev->dev,
 919                "Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n",
 920                i, rstart, (unsigned long long)lstart);
 921
 922        return 0;
 923}
 924
 925/**
 926 * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region.
 927 * @mport: RapidIO master port
 928 * @lstart: Local memory space start address.
 929 */
 930static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport,
 931                                dma_addr_t lstart)
 932{
 933        struct tsi721_device *priv = mport->priv;
 934        int i;
 935        u64 addr;
 936        u32 regval;
 937
 938        /* Search for matching active inbound translation window */
 939        for (i = 0; i < TSI721_IBWIN_NUM; i++) {
 940                regval = ioread32(priv->regs + TSI721_IBWIN_LB(i));
 941                if (regval & TSI721_IBWIN_LB_WEN) {
 942                        regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i));
 943                        addr = (u64)regval << 32;
 944                        regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i));
 945                        addr |= regval & TSI721_IBWIN_TLA_ADD;
 946
 947                        if (addr == (u64)lstart) {
 948                                iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
 949                                break;
 950                        }
 951                }
 952        }
 953}
 954
 955/**
 956 * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe)
 957 * translation regions.
 958 * @priv: pointer to tsi721 private data
 959 *
 960 * Disables inbound windows.
 961 */
 962static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv)
 963{
 964        int i;
 965
 966        /* Disable all SR2PC inbound windows */
 967        for (i = 0; i < TSI721_IBWIN_NUM; i++)
 968                iowrite32(0, priv->regs + TSI721_IBWIN_LB(i));
 969}
 970
 971/**
 972 * tsi721_port_write_init - Inbound port write interface init
 973 * @priv: pointer to tsi721 private data
 974 *
 975 * Initializes inbound port write handler.
 976 * Returns %0 on success or %-ENOMEM on failure.
 977 */
 978static int tsi721_port_write_init(struct tsi721_device *priv)
 979{
 980        priv->pw_discard_count = 0;
 981        INIT_WORK(&priv->pw_work, tsi721_pw_dpc);
 982        spin_lock_init(&priv->pw_fifo_lock);
 983        if (kfifo_alloc(&priv->pw_fifo,
 984                        TSI721_RIO_PW_MSG_SIZE * 32, GFP_KERNEL)) {
 985                dev_err(&priv->pdev->dev, "PW FIFO allocation failed\n");
 986                return -ENOMEM;
 987        }
 988
 989        /* Use reliable port-write capture mode */
 990        iowrite32(TSI721_RIO_PW_CTL_PWC_REL, priv->regs + TSI721_RIO_PW_CTL);
 991        return 0;
 992}
 993
 994static int tsi721_doorbell_init(struct tsi721_device *priv)
 995{
 996        /* Outbound Doorbells do not require any setup.
 997         * Tsi721 uses dedicated PCI BAR1 to generate doorbells.
 998         * That BAR1 was mapped during the probe routine.
 999         */
1000
1001        /* Initialize Inbound Doorbell processing DPC and queue */
1002        priv->db_discard_count = 0;
1003        INIT_WORK(&priv->idb_work, tsi721_db_dpc);
1004
1005        /* Allocate buffer for inbound doorbells queue */
1006        priv->idb_base = dma_zalloc_coherent(&priv->pdev->dev,
1007                                IDB_QSIZE * TSI721_IDB_ENTRY_SIZE,
1008                                &priv->idb_dma, GFP_KERNEL);
1009        if (!priv->idb_base)
1010                return -ENOMEM;
1011
1012        dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n",
1013                priv->idb_base, (unsigned long long)priv->idb_dma);
1014
1015        iowrite32(TSI721_IDQ_SIZE_VAL(IDB_QSIZE),
1016                priv->regs + TSI721_IDQ_SIZE(IDB_QUEUE));
1017        iowrite32(((u64)priv->idb_dma >> 32),
1018                priv->regs + TSI721_IDQ_BASEU(IDB_QUEUE));
1019        iowrite32(((u64)priv->idb_dma & TSI721_IDQ_BASEL_ADDR),
1020                priv->regs + TSI721_IDQ_BASEL(IDB_QUEUE));
1021        /* Enable accepting all inbound doorbells */
1022        iowrite32(0, priv->regs + TSI721_IDQ_MASK(IDB_QUEUE));
1023
1024        iowrite32(TSI721_IDQ_INIT, priv->regs + TSI721_IDQ_CTL(IDB_QUEUE));
1025
1026        iowrite32(0, priv->regs + TSI721_IDQ_RP(IDB_QUEUE));
1027
1028        return 0;
1029}
1030
1031static void tsi721_doorbell_free(struct tsi721_device *priv)
1032{
1033        if (priv->idb_base == NULL)
1034                return;
1035
1036        /* Free buffer allocated for inbound doorbell queue */
1037        dma_free_coherent(&priv->pdev->dev, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE,
1038                          priv->idb_base, priv->idb_dma);
1039        priv->idb_base = NULL;
1040}
1041
1042/**
1043 * tsi721_bdma_maint_init - Initialize maintenance request BDMA channel.
1044 * @priv: pointer to tsi721 private data
1045 *
1046 * Initialize BDMA channel allocated for RapidIO maintenance read/write
1047 * request generation
1048 * Returns %0 on success or %-ENOMEM on failure.
1049 */
1050static int tsi721_bdma_maint_init(struct tsi721_device *priv)
1051{
1052        struct tsi721_dma_desc *bd_ptr;
1053        u64             *sts_ptr;
1054        dma_addr_t      bd_phys, sts_phys;
1055        int             sts_size;
1056        int             bd_num = 2;
1057        void __iomem    *regs;
1058
1059        dev_dbg(&priv->pdev->dev,
1060                "Init Block DMA Engine for Maintenance requests, CH%d\n",
1061                TSI721_DMACH_MAINT);
1062
1063        /*
1064         * Initialize DMA channel for maintenance requests
1065         */
1066
1067        priv->mdma.ch_id = TSI721_DMACH_MAINT;
1068        regs = priv->regs + TSI721_DMAC_BASE(TSI721_DMACH_MAINT);
1069
1070        /* Allocate space for DMA descriptors */
1071        bd_ptr = dma_zalloc_coherent(&priv->pdev->dev,
1072                                        bd_num * sizeof(struct tsi721_dma_desc),
1073                                        &bd_phys, GFP_KERNEL);
1074        if (!bd_ptr)
1075                return -ENOMEM;
1076
1077        priv->mdma.bd_num = bd_num;
1078        priv->mdma.bd_phys = bd_phys;
1079        priv->mdma.bd_base = bd_ptr;
1080
1081        dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n",
1082                bd_ptr, (unsigned long long)bd_phys);
1083
1084        /* Allocate space for descriptor status FIFO */
1085        sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ?
1086                                        bd_num : TSI721_DMA_MINSTSSZ;
1087        sts_size = roundup_pow_of_two(sts_size);
1088        sts_ptr = dma_zalloc_coherent(&priv->pdev->dev,
1089                                     sts_size * sizeof(struct tsi721_dma_sts),
1090                                     &sts_phys, GFP_KERNEL);
1091        if (!sts_ptr) {
1092                /* Free space allocated for DMA descriptors */
1093                dma_free_coherent(&priv->pdev->dev,
1094                                  bd_num * sizeof(struct tsi721_dma_desc),
1095                                  bd_ptr, bd_phys);
1096                priv->mdma.bd_base = NULL;
1097                return -ENOMEM;
1098        }
1099
1100        priv->mdma.sts_phys = sts_phys;
1101        priv->mdma.sts_base = sts_ptr;
1102        priv->mdma.sts_size = sts_size;
1103
1104        dev_dbg(&priv->pdev->dev,
1105                "desc status FIFO @ %p (phys = %llx) size=0x%x\n",
1106                sts_ptr, (unsigned long long)sts_phys, sts_size);
1107
1108        /* Initialize DMA descriptors ring */
1109        bd_ptr[bd_num - 1].type_id = cpu_to_le32(DTYPE3 << 29);
1110        bd_ptr[bd_num - 1].next_lo = cpu_to_le32((u64)bd_phys &
1111                                                 TSI721_DMAC_DPTRL_MASK);
1112        bd_ptr[bd_num - 1].next_hi = cpu_to_le32((u64)bd_phys >> 32);
1113
1114        /* Setup DMA descriptor pointers */
1115        iowrite32(((u64)bd_phys >> 32), regs + TSI721_DMAC_DPTRH);
1116        iowrite32(((u64)bd_phys & TSI721_DMAC_DPTRL_MASK),
1117                regs + TSI721_DMAC_DPTRL);
1118
1119        /* Setup descriptor status FIFO */
1120        iowrite32(((u64)sts_phys >> 32), regs + TSI721_DMAC_DSBH);
1121        iowrite32(((u64)sts_phys & TSI721_DMAC_DSBL_MASK),
1122                regs + TSI721_DMAC_DSBL);
1123        iowrite32(TSI721_DMAC_DSSZ_SIZE(sts_size),
1124                regs + TSI721_DMAC_DSSZ);
1125
1126        /* Clear interrupt bits */
1127        iowrite32(TSI721_DMAC_INT_ALL, regs + TSI721_DMAC_INT);
1128
1129        ioread32(regs + TSI721_DMAC_INT);
1130
1131        /* Toggle DMA channel initialization */
1132        iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL);
1133        ioread32(regs + TSI721_DMAC_CTL);
1134        udelay(10);
1135
1136        return 0;
1137}
1138
1139static int tsi721_bdma_maint_free(struct tsi721_device *priv)
1140{
1141        u32 ch_stat;
1142        struct tsi721_bdma_maint *mdma = &priv->mdma;
1143        void __iomem *regs = priv->regs + TSI721_DMAC_BASE(mdma->ch_id);
1144
1145        if (mdma->bd_base == NULL)
1146                return 0;
1147
1148        /* Check if DMA channel still running */
1149        ch_stat = ioread32(regs + TSI721_DMAC_STS);
1150        if (ch_stat & TSI721_DMAC_STS_RUN)
1151                return -EFAULT;
1152
1153        /* Put DMA channel into init state */
1154        iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL);
1155
1156        /* Free space allocated for DMA descriptors */
1157        dma_free_coherent(&priv->pdev->dev,
1158                mdma->bd_num * sizeof(struct tsi721_dma_desc),
1159                mdma->bd_base, mdma->bd_phys);
1160        mdma->bd_base = NULL;
1161
1162        /* Free space allocated for status FIFO */
1163        dma_free_coherent(&priv->pdev->dev,
1164                mdma->sts_size * sizeof(struct tsi721_dma_sts),
1165                mdma->sts_base, mdma->sts_phys);
1166        mdma->sts_base = NULL;
1167        return 0;
1168}
1169
1170/* Enable Inbound Messaging Interrupts */
1171static void
1172tsi721_imsg_interrupt_enable(struct tsi721_device *priv, int ch,
1173                                  u32 inte_mask)
1174{
1175        u32 rval;
1176
1177        if (!inte_mask)
1178                return;
1179
1180        /* Clear pending Inbound Messaging interrupts */
1181        iowrite32(inte_mask, priv->regs + TSI721_IBDMAC_INT(ch));
1182
1183        /* Enable Inbound Messaging interrupts */
1184        rval = ioread32(priv->regs + TSI721_IBDMAC_INTE(ch));
1185        iowrite32(rval | inte_mask, priv->regs + TSI721_IBDMAC_INTE(ch));
1186
1187        if (priv->flags & TSI721_USING_MSIX)
1188                return; /* Finished if we are in MSI-X mode */
1189
1190        /*
1191         * For MSI and INTA interrupt signalling we need to enable next levels
1192         */
1193
1194        /* Enable Device Channel Interrupt */
1195        rval = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
1196        iowrite32(rval | TSI721_INT_IMSG_CHAN(ch),
1197                  priv->regs + TSI721_DEV_CHAN_INTE);
1198}
1199
1200/* Disable Inbound Messaging Interrupts */
1201static void
1202tsi721_imsg_interrupt_disable(struct tsi721_device *priv, int ch,
1203                                   u32 inte_mask)
1204{
1205        u32 rval;
1206
1207        if (!inte_mask)
1208                return;
1209
1210        /* Clear pending Inbound Messaging interrupts */
1211        iowrite32(inte_mask, priv->regs + TSI721_IBDMAC_INT(ch));
1212
1213        /* Disable Inbound Messaging interrupts */
1214        rval = ioread32(priv->regs + TSI721_IBDMAC_INTE(ch));
1215        rval &= ~inte_mask;
1216        iowrite32(rval, priv->regs + TSI721_IBDMAC_INTE(ch));
1217
1218        if (priv->flags & TSI721_USING_MSIX)
1219                return; /* Finished if we are in MSI-X mode */
1220
1221        /*
1222         * For MSI and INTA interrupt signalling we need to disable next levels
1223         */
1224
1225        /* Disable Device Channel Interrupt */
1226        rval = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
1227        rval &= ~TSI721_INT_IMSG_CHAN(ch);
1228        iowrite32(rval, priv->regs + TSI721_DEV_CHAN_INTE);
1229}
1230
1231/* Enable Outbound Messaging interrupts */
1232static void
1233tsi721_omsg_interrupt_enable(struct tsi721_device *priv, int ch,
1234                                  u32 inte_mask)
1235{
1236        u32 rval;
1237
1238        if (!inte_mask)
1239                return;
1240
1241        /* Clear pending Outbound Messaging interrupts */
1242        iowrite32(inte_mask, priv->regs + TSI721_OBDMAC_INT(ch));
1243
1244        /* Enable Outbound Messaging channel interrupts */
1245        rval = ioread32(priv->regs + TSI721_OBDMAC_INTE(ch));
1246        iowrite32(rval | inte_mask, priv->regs + TSI721_OBDMAC_INTE(ch));
1247
1248        if (priv->flags & TSI721_USING_MSIX)
1249                return; /* Finished if we are in MSI-X mode */
1250
1251        /*
1252         * For MSI and INTA interrupt signalling we need to enable next levels
1253         */
1254
1255        /* Enable Device Channel Interrupt */
1256        rval = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
1257        iowrite32(rval | TSI721_INT_OMSG_CHAN(ch),
1258                  priv->regs + TSI721_DEV_CHAN_INTE);
1259}
1260
1261/* Disable Outbound Messaging interrupts */
1262static void
1263tsi721_omsg_interrupt_disable(struct tsi721_device *priv, int ch,
1264                                   u32 inte_mask)
1265{
1266        u32 rval;
1267
1268        if (!inte_mask)
1269                return;
1270
1271        /* Clear pending Outbound Messaging interrupts */
1272        iowrite32(inte_mask, priv->regs + TSI721_OBDMAC_INT(ch));
1273
1274        /* Disable Outbound Messaging interrupts */
1275        rval = ioread32(priv->regs + TSI721_OBDMAC_INTE(ch));
1276        rval &= ~inte_mask;
1277        iowrite32(rval, priv->regs + TSI721_OBDMAC_INTE(ch));
1278
1279        if (priv->flags & TSI721_USING_MSIX)
1280                return; /* Finished if we are in MSI-X mode */
1281
1282        /*
1283         * For MSI and INTA interrupt signalling we need to disable next levels
1284         */
1285
1286        /* Disable Device Channel Interrupt */
1287        rval = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
1288        rval &= ~TSI721_INT_OMSG_CHAN(ch);
1289        iowrite32(rval, priv->regs + TSI721_DEV_CHAN_INTE);
1290}
1291
1292/**
1293 * tsi721_add_outb_message - Add message to the Tsi721 outbound message queue
1294 * @mport: Master port with outbound message queue
1295 * @rdev: Target of outbound message
1296 * @mbox: Outbound mailbox
1297 * @buffer: Message to add to outbound queue
1298 * @len: Length of message
1299 */
1300static int
1301tsi721_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
1302                        void *buffer, size_t len)
1303{
1304        struct tsi721_device *priv = mport->priv;
1305        struct tsi721_omsg_desc *desc;
1306        u32 tx_slot;
1307
1308        if (!priv->omsg_init[mbox] ||
1309            len > TSI721_MSG_MAX_SIZE || len < 8)
1310                return -EINVAL;
1311
1312        tx_slot = priv->omsg_ring[mbox].tx_slot;
1313
1314        /* Copy copy message into transfer buffer */
1315        memcpy(priv->omsg_ring[mbox].omq_base[tx_slot], buffer, len);
1316
1317        if (len & 0x7)
1318                len += 8;
1319
1320        /* Build descriptor associated with buffer */
1321        desc = priv->omsg_ring[mbox].omd_base;
1322        desc[tx_slot].type_id = cpu_to_le32((DTYPE4 << 29) | rdev->destid);
1323        if (tx_slot % 4 == 0)
1324                desc[tx_slot].type_id |= cpu_to_le32(TSI721_OMD_IOF);
1325
1326        desc[tx_slot].msg_info =
1327                cpu_to_le32((mport->sys_size << 26) | (mbox << 22) |
1328                            (0xe << 12) | (len & 0xff8));
1329        desc[tx_slot].bufptr_lo =
1330                cpu_to_le32((u64)priv->omsg_ring[mbox].omq_phys[tx_slot] &
1331                            0xffffffff);
1332        desc[tx_slot].bufptr_hi =
1333                cpu_to_le32((u64)priv->omsg_ring[mbox].omq_phys[tx_slot] >> 32);
1334
1335        priv->omsg_ring[mbox].wr_count++;
1336
1337        /* Go to next descriptor */
1338        if (++priv->omsg_ring[mbox].tx_slot == priv->omsg_ring[mbox].size) {
1339                priv->omsg_ring[mbox].tx_slot = 0;
1340                /* Move through the ring link descriptor at the end */
1341                priv->omsg_ring[mbox].wr_count++;
1342        }
1343
1344        mb();
1345
1346        /* Set new write count value */
1347        iowrite32(priv->omsg_ring[mbox].wr_count,
1348                priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
1349        ioread32(priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
1350
1351        return 0;
1352}
1353
1354/**
1355 * tsi721_omsg_handler - Outbound Message Interrupt Handler
1356 * @priv: pointer to tsi721 private data
1357 * @ch:   number of OB MSG channel to service
1358 *
1359 * Services channel interrupts from outbound messaging engine.
1360 */
1361static void tsi721_omsg_handler(struct tsi721_device *priv, int ch)
1362{
1363        u32 omsg_int;
1364
1365        spin_lock(&priv->omsg_ring[ch].lock);
1366
1367        omsg_int = ioread32(priv->regs + TSI721_OBDMAC_INT(ch));
1368
1369        if (omsg_int & TSI721_OBDMAC_INT_ST_FULL)
1370                dev_info(&priv->pdev->dev,
1371                        "OB MBOX%d: Status FIFO is full\n", ch);
1372
1373        if (omsg_int & (TSI721_OBDMAC_INT_DONE | TSI721_OBDMAC_INT_IOF_DONE)) {
1374                u32 srd_ptr;
1375                u64 *sts_ptr, last_ptr = 0, prev_ptr = 0;
1376                int i, j;
1377                u32 tx_slot;
1378
1379                /*
1380                 * Find last successfully processed descriptor
1381                 */
1382
1383                /* Check and clear descriptor status FIFO entries */
1384                srd_ptr = priv->omsg_ring[ch].sts_rdptr;
1385                sts_ptr = priv->omsg_ring[ch].sts_base;
1386                j = srd_ptr * 8;
1387                while (sts_ptr[j]) {
1388                        for (i = 0; i < 8 && sts_ptr[j]; i++, j++) {
1389                                prev_ptr = last_ptr;
1390                                last_ptr = le64_to_cpu(sts_ptr[j]);
1391                                sts_ptr[j] = 0;
1392                        }
1393
1394                        ++srd_ptr;
1395                        srd_ptr %= priv->omsg_ring[ch].sts_size;
1396                        j = srd_ptr * 8;
1397                }
1398
1399                if (last_ptr == 0)
1400                        goto no_sts_update;
1401
1402                priv->omsg_ring[ch].sts_rdptr = srd_ptr;
1403                iowrite32(srd_ptr, priv->regs + TSI721_OBDMAC_DSRP(ch));
1404
1405                if (!priv->mport->outb_msg[ch].mcback)
1406                        goto no_sts_update;
1407
1408                /* Inform upper layer about transfer completion */
1409
1410                tx_slot = (last_ptr - (u64)priv->omsg_ring[ch].omd_phys)/
1411                                                sizeof(struct tsi721_omsg_desc);
1412
1413                /*
1414                 * Check if this is a Link Descriptor (LD).
1415                 * If yes, ignore LD and use descriptor processed
1416                 * before LD.
1417                 */
1418                if (tx_slot == priv->omsg_ring[ch].size) {
1419                        if (prev_ptr)
1420                                tx_slot = (prev_ptr -
1421                                        (u64)priv->omsg_ring[ch].omd_phys)/
1422                                                sizeof(struct tsi721_omsg_desc);
1423                        else
1424                                goto no_sts_update;
1425                }
1426
1427                /* Move slot index to the next message to be sent */
1428                ++tx_slot;
1429                if (tx_slot == priv->omsg_ring[ch].size)
1430                        tx_slot = 0;
1431                BUG_ON(tx_slot >= priv->omsg_ring[ch].size);
1432                priv->mport->outb_msg[ch].mcback(priv->mport,
1433                                priv->omsg_ring[ch].dev_id, ch,
1434                                tx_slot);
1435        }
1436
1437no_sts_update:
1438
1439        if (omsg_int & TSI721_OBDMAC_INT_ERROR) {
1440                /*
1441                * Outbound message operation aborted due to error,
1442                * reinitialize OB MSG channel
1443                */
1444
1445                dev_dbg(&priv->pdev->dev, "OB MSG ABORT ch_stat=%x\n",
1446                        ioread32(priv->regs + TSI721_OBDMAC_STS(ch)));
1447
1448                iowrite32(TSI721_OBDMAC_INT_ERROR,
1449                                priv->regs + TSI721_OBDMAC_INT(ch));
1450                iowrite32(TSI721_OBDMAC_CTL_INIT,
1451                                priv->regs + TSI721_OBDMAC_CTL(ch));
1452                ioread32(priv->regs + TSI721_OBDMAC_CTL(ch));
1453
1454                /* Inform upper level to clear all pending tx slots */
1455                if (priv->mport->outb_msg[ch].mcback)
1456                        priv->mport->outb_msg[ch].mcback(priv->mport,
1457                                        priv->omsg_ring[ch].dev_id, ch,
1458                                        priv->omsg_ring[ch].tx_slot);
1459                /* Synch tx_slot tracking */
1460                iowrite32(priv->omsg_ring[ch].tx_slot,
1461                        priv->regs + TSI721_OBDMAC_DRDCNT(ch));
1462                ioread32(priv->regs + TSI721_OBDMAC_DRDCNT(ch));
1463                priv->omsg_ring[ch].wr_count = priv->omsg_ring[ch].tx_slot;
1464                priv->omsg_ring[ch].sts_rdptr = 0;
1465        }
1466
1467        /* Clear channel interrupts */
1468        iowrite32(omsg_int, priv->regs + TSI721_OBDMAC_INT(ch));
1469
1470        if (!(priv->flags & TSI721_USING_MSIX)) {
1471                u32 ch_inte;
1472
1473                /* Re-enable channel interrupts */
1474                ch_inte = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
1475                ch_inte |= TSI721_INT_OMSG_CHAN(ch);
1476                iowrite32(ch_inte, priv->regs + TSI721_DEV_CHAN_INTE);
1477        }
1478
1479        spin_unlock(&priv->omsg_ring[ch].lock);
1480}
1481
1482/**
1483 * tsi721_open_outb_mbox - Initialize Tsi721 outbound mailbox
1484 * @mport: Master port implementing Outbound Messaging Engine
1485 * @dev_id: Device specific pointer to pass on event
1486 * @mbox: Mailbox to open
1487 * @entries: Number of entries in the outbound mailbox ring
1488 */
1489static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
1490                                 int mbox, int entries)
1491{
1492        struct tsi721_device *priv = mport->priv;
1493        struct tsi721_omsg_desc *bd_ptr;
1494        int i, rc = 0;
1495
1496        if ((entries < TSI721_OMSGD_MIN_RING_SIZE) ||
1497            (entries > (TSI721_OMSGD_RING_SIZE)) ||
1498            (!is_power_of_2(entries)) || mbox >= RIO_MAX_MBOX) {
1499                rc = -EINVAL;
1500                goto out;
1501        }
1502
1503        priv->omsg_ring[mbox].dev_id = dev_id;
1504        priv->omsg_ring[mbox].size = entries;
1505        priv->omsg_ring[mbox].sts_rdptr = 0;
1506        spin_lock_init(&priv->omsg_ring[mbox].lock);
1507
1508        /* Outbound Msg Buffer allocation based on
1509           the number of maximum descriptor entries */
1510        for (i = 0; i < entries; i++) {
1511                priv->omsg_ring[mbox].omq_base[i] =
1512                        dma_alloc_coherent(
1513                                &priv->pdev->dev, TSI721_MSG_BUFFER_SIZE,
1514                                &priv->omsg_ring[mbox].omq_phys[i],
1515                                GFP_KERNEL);
1516                if (priv->omsg_ring[mbox].omq_base[i] == NULL) {
1517                        dev_dbg(&priv->pdev->dev,
1518                                "Unable to allocate OB MSG data buffer for"
1519                                " MBOX%d\n", mbox);
1520                        rc = -ENOMEM;
1521                        goto out_buf;
1522                }
1523        }
1524
1525        /* Outbound message descriptor allocation */
1526        priv->omsg_ring[mbox].omd_base = dma_alloc_coherent(
1527                                &priv->pdev->dev,
1528                                (entries + 1) * sizeof(struct tsi721_omsg_desc),
1529                                &priv->omsg_ring[mbox].omd_phys, GFP_KERNEL);
1530        if (priv->omsg_ring[mbox].omd_base == NULL) {
1531                dev_dbg(&priv->pdev->dev,
1532                        "Unable to allocate OB MSG descriptor memory "
1533                        "for MBOX%d\n", mbox);
1534                rc = -ENOMEM;
1535                goto out_buf;
1536        }
1537
1538        priv->omsg_ring[mbox].tx_slot = 0;
1539
1540        /* Outbound message descriptor status FIFO allocation */
1541        priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1);
1542        priv->omsg_ring[mbox].sts_base = dma_zalloc_coherent(&priv->pdev->dev,
1543                        priv->omsg_ring[mbox].sts_size *
1544                                                sizeof(struct tsi721_dma_sts),
1545                        &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL);
1546        if (priv->omsg_ring[mbox].sts_base == NULL) {
1547                dev_dbg(&priv->pdev->dev,
1548                        "Unable to allocate OB MSG descriptor status FIFO "
1549                        "for MBOX%d\n", mbox);
1550                rc = -ENOMEM;
1551                goto out_desc;
1552        }
1553
1554        /*
1555         * Configure Outbound Messaging Engine
1556         */
1557
1558        /* Setup Outbound Message descriptor pointer */
1559        iowrite32(((u64)priv->omsg_ring[mbox].omd_phys >> 32),
1560                        priv->regs + TSI721_OBDMAC_DPTRH(mbox));
1561        iowrite32(((u64)priv->omsg_ring[mbox].omd_phys &
1562                                        TSI721_OBDMAC_DPTRL_MASK),
1563                        priv->regs + TSI721_OBDMAC_DPTRL(mbox));
1564
1565        /* Setup Outbound Message descriptor status FIFO */
1566        iowrite32(((u64)priv->omsg_ring[mbox].sts_phys >> 32),
1567                        priv->regs + TSI721_OBDMAC_DSBH(mbox));
1568        iowrite32(((u64)priv->omsg_ring[mbox].sts_phys &
1569                                        TSI721_OBDMAC_DSBL_MASK),
1570                        priv->regs + TSI721_OBDMAC_DSBL(mbox));
1571        iowrite32(TSI721_DMAC_DSSZ_SIZE(priv->omsg_ring[mbox].sts_size),
1572                priv->regs + (u32)TSI721_OBDMAC_DSSZ(mbox));
1573
1574        /* Enable interrupts */
1575
1576#ifdef CONFIG_PCI_MSI
1577        if (priv->flags & TSI721_USING_MSIX) {
1578                /* Request interrupt service if we are in MSI-X mode */
1579                rc = request_irq(
1580                        priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
1581                        tsi721_omsg_msix, 0,
1582                        priv->msix[TSI721_VECT_OMB0_DONE + mbox].irq_name,
1583                        (void *)mport);
1584
1585                if (rc) {
1586                        dev_dbg(&priv->pdev->dev,
1587                                "Unable to allocate MSI-X interrupt for "
1588                                "OBOX%d-DONE\n", mbox);
1589                        goto out_stat;
1590                }
1591
1592                rc = request_irq(priv->msix[TSI721_VECT_OMB0_INT + mbox].vector,
1593                        tsi721_omsg_msix, 0,
1594                        priv->msix[TSI721_VECT_OMB0_INT + mbox].irq_name,
1595                        (void *)mport);
1596
1597                if (rc) {
1598                        dev_dbg(&priv->pdev->dev,
1599                                "Unable to allocate MSI-X interrupt for "
1600                                "MBOX%d-INT\n", mbox);
1601                        free_irq(
1602                                priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
1603                                (void *)mport);
1604                        goto out_stat;
1605                }
1606        }
1607#endif /* CONFIG_PCI_MSI */
1608
1609        tsi721_omsg_interrupt_enable(priv, mbox, TSI721_OBDMAC_INT_ALL);
1610
1611        /* Initialize Outbound Message descriptors ring */
1612        bd_ptr = priv->omsg_ring[mbox].omd_base;
1613        bd_ptr[entries].type_id = cpu_to_le32(DTYPE5 << 29);
1614        bd_ptr[entries].msg_info = 0;
1615        bd_ptr[entries].next_lo =
1616                cpu_to_le32((u64)priv->omsg_ring[mbox].omd_phys &
1617                TSI721_OBDMAC_DPTRL_MASK);
1618        bd_ptr[entries].next_hi =
1619                cpu_to_le32((u64)priv->omsg_ring[mbox].omd_phys >> 32);
1620        priv->omsg_ring[mbox].wr_count = 0;
1621        mb();
1622
1623        /* Initialize Outbound Message engine */
1624        iowrite32(TSI721_OBDMAC_CTL_INIT, priv->regs + TSI721_OBDMAC_CTL(mbox));
1625        ioread32(priv->regs + TSI721_OBDMAC_DWRCNT(mbox));
1626        udelay(10);
1627
1628        priv->omsg_init[mbox] = 1;
1629
1630        return 0;
1631
1632#ifdef CONFIG_PCI_MSI
1633out_stat:
1634        dma_free_coherent(&priv->pdev->dev,
1635                priv->omsg_ring[mbox].sts_size * sizeof(struct tsi721_dma_sts),
1636                priv->omsg_ring[mbox].sts_base,
1637                priv->omsg_ring[mbox].sts_phys);
1638
1639        priv->omsg_ring[mbox].sts_base = NULL;
1640#endif /* CONFIG_PCI_MSI */
1641
1642out_desc:
1643        dma_free_coherent(&priv->pdev->dev,
1644                (entries + 1) * sizeof(struct tsi721_omsg_desc),
1645                priv->omsg_ring[mbox].omd_base,
1646                priv->omsg_ring[mbox].omd_phys);
1647
1648        priv->omsg_ring[mbox].omd_base = NULL;
1649
1650out_buf:
1651        for (i = 0; i < priv->omsg_ring[mbox].size; i++) {
1652                if (priv->omsg_ring[mbox].omq_base[i]) {
1653                        dma_free_coherent(&priv->pdev->dev,
1654                                TSI721_MSG_BUFFER_SIZE,
1655                                priv->omsg_ring[mbox].omq_base[i],
1656                                priv->omsg_ring[mbox].omq_phys[i]);
1657
1658                        priv->omsg_ring[mbox].omq_base[i] = NULL;
1659                }
1660        }
1661
1662out:
1663        return rc;
1664}
1665
1666/**
1667 * tsi721_close_outb_mbox - Close Tsi721 outbound mailbox
1668 * @mport: Master port implementing the outbound message unit
1669 * @mbox: Mailbox to close
1670 */
1671static void tsi721_close_outb_mbox(struct rio_mport *mport, int mbox)
1672{
1673        struct tsi721_device *priv = mport->priv;
1674        u32 i;
1675
1676        if (!priv->omsg_init[mbox])
1677                return;
1678        priv->omsg_init[mbox] = 0;
1679
1680        /* Disable Interrupts */
1681
1682        tsi721_omsg_interrupt_disable(priv, mbox, TSI721_OBDMAC_INT_ALL);
1683
1684#ifdef CONFIG_PCI_MSI
1685        if (priv->flags & TSI721_USING_MSIX) {
1686                free_irq(priv->msix[TSI721_VECT_OMB0_DONE + mbox].vector,
1687                         (void *)mport);
1688                free_irq(priv->msix[TSI721_VECT_OMB0_INT + mbox].vector,
1689                         (void *)mport);
1690        }
1691#endif /* CONFIG_PCI_MSI */
1692
1693        /* Free OMSG Descriptor Status FIFO */
1694        dma_free_coherent(&priv->pdev->dev,
1695                priv->omsg_ring[mbox].sts_size * sizeof(struct tsi721_dma_sts),
1696                priv->omsg_ring[mbox].sts_base,
1697                priv->omsg_ring[mbox].sts_phys);
1698
1699        priv->omsg_ring[mbox].sts_base = NULL;
1700
1701        /* Free OMSG descriptors */
1702        dma_free_coherent(&priv->pdev->dev,
1703                (priv->omsg_ring[mbox].size + 1) *
1704                        sizeof(struct tsi721_omsg_desc),
1705                priv->omsg_ring[mbox].omd_base,
1706                priv->omsg_ring[mbox].omd_phys);
1707
1708        priv->omsg_ring[mbox].omd_base = NULL;
1709
1710        /* Free message buffers */
1711        for (i = 0; i < priv->omsg_ring[mbox].size; i++) {
1712                if (priv->omsg_ring[mbox].omq_base[i]) {
1713                        dma_free_coherent(&priv->pdev->dev,
1714                                TSI721_MSG_BUFFER_SIZE,
1715                                priv->omsg_ring[mbox].omq_base[i],
1716                                priv->omsg_ring[mbox].omq_phys[i]);
1717
1718                        priv->omsg_ring[mbox].omq_base[i] = NULL;
1719                }
1720        }
1721}
1722
1723/**
1724 * tsi721_imsg_handler - Inbound Message Interrupt Handler
1725 * @priv: pointer to tsi721 private data
1726 * @ch: inbound message channel number to service
1727 *
1728 * Services channel interrupts from inbound messaging engine.
1729 */
1730static void tsi721_imsg_handler(struct tsi721_device *priv, int ch)
1731{
1732        u32 mbox = ch - 4;
1733        u32 imsg_int;
1734
1735        spin_lock(&priv->imsg_ring[mbox].lock);
1736
1737        imsg_int = ioread32(priv->regs + TSI721_IBDMAC_INT(ch));
1738
1739        if (imsg_int & TSI721_IBDMAC_INT_SRTO)
1740                dev_info(&priv->pdev->dev, "IB MBOX%d SRIO timeout\n",
1741                        mbox);
1742
1743        if (imsg_int & TSI721_IBDMAC_INT_PC_ERROR)
1744                dev_info(&priv->pdev->dev, "IB MBOX%d PCIe error\n",
1745                        mbox);
1746
1747        if (imsg_int & TSI721_IBDMAC_INT_FQ_LOW)
1748                dev_info(&priv->pdev->dev,
1749                        "IB MBOX%d IB free queue low\n", mbox);
1750
1751        /* Clear IB channel interrupts */
1752        iowrite32(imsg_int, priv->regs + TSI721_IBDMAC_INT(ch));
1753
1754        /* If an IB Msg is received notify the upper layer */
1755        if (imsg_int & TSI721_IBDMAC_INT_DQ_RCV &&
1756                priv->mport->inb_msg[mbox].mcback)
1757                priv->mport->inb_msg[mbox].mcback(priv->mport,
1758                                priv->imsg_ring[mbox].dev_id, mbox, -1);
1759
1760        if (!(priv->flags & TSI721_USING_MSIX)) {
1761                u32 ch_inte;
1762
1763                /* Re-enable channel interrupts */
1764                ch_inte = ioread32(priv->regs + TSI721_DEV_CHAN_INTE);
1765                ch_inte |= TSI721_INT_IMSG_CHAN(ch);
1766                iowrite32(ch_inte, priv->regs + TSI721_DEV_CHAN_INTE);
1767        }
1768
1769        spin_unlock(&priv->imsg_ring[mbox].lock);
1770}
1771
1772/**
1773 * tsi721_open_inb_mbox - Initialize Tsi721 inbound mailbox
1774 * @mport: Master port implementing the Inbound Messaging Engine
1775 * @dev_id: Device specific pointer to pass on event
1776 * @mbox: Mailbox to open
1777 * @entries: Number of entries in the inbound mailbox ring
1778 */
1779static int tsi721_open_inb_mbox(struct rio_mport *mport, void *dev_id,
1780                                int mbox, int entries)
1781{
1782        struct tsi721_device *priv = mport->priv;
1783        int ch = mbox + 4;
1784        int i;
1785        u64 *free_ptr;
1786        int rc = 0;
1787
1788        if ((entries < TSI721_IMSGD_MIN_RING_SIZE) ||
1789            (entries > TSI721_IMSGD_RING_SIZE) ||
1790            (!is_power_of_2(entries)) || mbox >= RIO_MAX_MBOX) {
1791                rc = -EINVAL;
1792                goto out;
1793        }
1794
1795        /* Initialize IB Messaging Ring */
1796        priv->imsg_ring[mbox].dev_id = dev_id;
1797        priv->imsg_ring[mbox].size = entries;
1798        priv->imsg_ring[mbox].rx_slot = 0;
1799        priv->imsg_ring[mbox].desc_rdptr = 0;
1800        priv->imsg_ring[mbox].fq_wrptr = 0;
1801        for (i = 0; i < priv->imsg_ring[mbox].size; i++)
1802                priv->imsg_ring[mbox].imq_base[i] = NULL;
1803        spin_lock_init(&priv->imsg_ring[mbox].lock);
1804
1805        /* Allocate buffers for incoming messages */
1806        priv->imsg_ring[mbox].buf_base =
1807                dma_alloc_coherent(&priv->pdev->dev,
1808                                   entries * TSI721_MSG_BUFFER_SIZE,
1809                                   &priv->imsg_ring[mbox].buf_phys,
1810                                   GFP_KERNEL);
1811
1812        if (priv->imsg_ring[mbox].buf_base == NULL) {
1813                dev_err(&priv->pdev->dev,
1814                        "Failed to allocate buffers for IB MBOX%d\n", mbox);
1815                rc = -ENOMEM;
1816                goto out;
1817        }
1818
1819        /* Allocate memory for circular free list */
1820        priv->imsg_ring[mbox].imfq_base =
1821                dma_alloc_coherent(&priv->pdev->dev,
1822                                   entries * 8,
1823                                   &priv->imsg_ring[mbox].imfq_phys,
1824                                   GFP_KERNEL);
1825
1826        if (priv->imsg_ring[mbox].imfq_base == NULL) {
1827                dev_err(&priv->pdev->dev,
1828                        "Failed to allocate free queue for IB MBOX%d\n", mbox);
1829                rc = -ENOMEM;
1830                goto out_buf;
1831        }
1832
1833        /* Allocate memory for Inbound message descriptors */
1834        priv->imsg_ring[mbox].imd_base =
1835                dma_alloc_coherent(&priv->pdev->dev,
1836                                   entries * sizeof(struct tsi721_imsg_desc),
1837                                   &priv->imsg_ring[mbox].imd_phys, GFP_KERNEL);
1838
1839        if (priv->imsg_ring[mbox].imd_base == NULL) {
1840                dev_err(&priv->pdev->dev,
1841                        "Failed to allocate descriptor memory for IB MBOX%d\n",
1842                        mbox);
1843                rc = -ENOMEM;
1844                goto out_dma;
1845        }
1846
1847        /* Fill free buffer pointer list */
1848        free_ptr = priv->imsg_ring[mbox].imfq_base;
1849        for (i = 0; i < entries; i++)
1850                free_ptr[i] = cpu_to_le64(
1851                                (u64)(priv->imsg_ring[mbox].buf_phys) +
1852                                i * 0x1000);
1853
1854        mb();
1855
1856        /*
1857         * For mapping of inbound SRIO Messages into appropriate queues we need
1858         * to set Inbound Device ID register in the messaging engine. We do it
1859         * once when first inbound mailbox is requested.
1860         */
1861        if (!(priv->flags & TSI721_IMSGID_SET)) {
1862                iowrite32((u32)priv->mport->host_deviceid,
1863                        priv->regs + TSI721_IB_DEVID);
1864                priv->flags |= TSI721_IMSGID_SET;
1865        }
1866
1867        /*
1868         * Configure Inbound Messaging channel (ch = mbox + 4)
1869         */
1870
1871        /* Setup Inbound Message free queue */
1872        iowrite32(((u64)priv->imsg_ring[mbox].imfq_phys >> 32),
1873                priv->regs + TSI721_IBDMAC_FQBH(ch));
1874        iowrite32(((u64)priv->imsg_ring[mbox].imfq_phys &
1875                        TSI721_IBDMAC_FQBL_MASK),
1876                priv->regs+TSI721_IBDMAC_FQBL(ch));
1877        iowrite32(TSI721_DMAC_DSSZ_SIZE(entries),
1878                priv->regs + TSI721_IBDMAC_FQSZ(ch));
1879
1880        /* Setup Inbound Message descriptor queue */
1881        iowrite32(((u64)priv->imsg_ring[mbox].imd_phys >> 32),
1882                priv->regs + TSI721_IBDMAC_DQBH(ch));
1883        iowrite32(((u32)priv->imsg_ring[mbox].imd_phys &
1884                   (u32)TSI721_IBDMAC_DQBL_MASK),
1885                priv->regs+TSI721_IBDMAC_DQBL(ch));
1886        iowrite32(TSI721_DMAC_DSSZ_SIZE(entries),
1887                priv->regs + TSI721_IBDMAC_DQSZ(ch));
1888
1889        /* Enable interrupts */
1890
1891#ifdef CONFIG_PCI_MSI
1892        if (priv->flags & TSI721_USING_MSIX) {
1893                /* Request interrupt service if we are in MSI-X mode */
1894                rc = request_irq(priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
1895                        tsi721_imsg_msix, 0,
1896                        priv->msix[TSI721_VECT_IMB0_RCV + mbox].irq_name,
1897                        (void *)mport);
1898
1899                if (rc) {
1900                        dev_dbg(&priv->pdev->dev,
1901                                "Unable to allocate MSI-X interrupt for "
1902                                "IBOX%d-DONE\n", mbox);
1903                        goto out_desc;
1904                }
1905
1906                rc = request_irq(priv->msix[TSI721_VECT_IMB0_INT + mbox].vector,
1907                        tsi721_imsg_msix, 0,
1908                        priv->msix[TSI721_VECT_IMB0_INT + mbox].irq_name,
1909                        (void *)mport);
1910
1911                if (rc) {
1912                        dev_dbg(&priv->pdev->dev,
1913                                "Unable to allocate MSI-X interrupt for "
1914                                "IBOX%d-INT\n", mbox);
1915                        free_irq(
1916                                priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
1917                                (void *)mport);
1918                        goto out_desc;
1919                }
1920        }
1921#endif /* CONFIG_PCI_MSI */
1922
1923        tsi721_imsg_interrupt_enable(priv, ch, TSI721_IBDMAC_INT_ALL);
1924
1925        /* Initialize Inbound Message Engine */
1926        iowrite32(TSI721_IBDMAC_CTL_INIT, priv->regs + TSI721_IBDMAC_CTL(ch));
1927        ioread32(priv->regs + TSI721_IBDMAC_CTL(ch));
1928        udelay(10);
1929        priv->imsg_ring[mbox].fq_wrptr = entries - 1;
1930        iowrite32(entries - 1, priv->regs + TSI721_IBDMAC_FQWP(ch));
1931
1932        priv->imsg_init[mbox] = 1;
1933        return 0;
1934
1935#ifdef CONFIG_PCI_MSI
1936out_desc:
1937        dma_free_coherent(&priv->pdev->dev,
1938                priv->imsg_ring[mbox].size * sizeof(struct tsi721_imsg_desc),
1939                priv->imsg_ring[mbox].imd_base,
1940                priv->imsg_ring[mbox].imd_phys);
1941
1942        priv->imsg_ring[mbox].imd_base = NULL;
1943#endif /* CONFIG_PCI_MSI */
1944
1945out_dma:
1946        dma_free_coherent(&priv->pdev->dev,
1947                priv->imsg_ring[mbox].size * 8,
1948                priv->imsg_ring[mbox].imfq_base,
1949                priv->imsg_ring[mbox].imfq_phys);
1950
1951        priv->imsg_ring[mbox].imfq_base = NULL;
1952
1953out_buf:
1954        dma_free_coherent(&priv->pdev->dev,
1955                priv->imsg_ring[mbox].size * TSI721_MSG_BUFFER_SIZE,
1956                priv->imsg_ring[mbox].buf_base,
1957                priv->imsg_ring[mbox].buf_phys);
1958
1959        priv->imsg_ring[mbox].buf_base = NULL;
1960
1961out:
1962        return rc;
1963}
1964
1965/**
1966 * tsi721_close_inb_mbox - Shut down Tsi721 inbound mailbox
1967 * @mport: Master port implementing the Inbound Messaging Engine
1968 * @mbox: Mailbox to close
1969 */
1970static void tsi721_close_inb_mbox(struct rio_mport *mport, int mbox)
1971{
1972        struct tsi721_device *priv = mport->priv;
1973        u32 rx_slot;
1974        int ch = mbox + 4;
1975
1976        if (!priv->imsg_init[mbox]) /* mbox isn't initialized yet */
1977                return;
1978        priv->imsg_init[mbox] = 0;
1979
1980        /* Disable Inbound Messaging Engine */
1981
1982        /* Disable Interrupts */
1983        tsi721_imsg_interrupt_disable(priv, ch, TSI721_OBDMAC_INT_MASK);
1984
1985#ifdef CONFIG_PCI_MSI
1986        if (priv->flags & TSI721_USING_MSIX) {
1987                free_irq(priv->msix[TSI721_VECT_IMB0_RCV + mbox].vector,
1988                                (void *)mport);
1989                free_irq(priv->msix[TSI721_VECT_IMB0_INT + mbox].vector,
1990                                (void *)mport);
1991        }
1992#endif /* CONFIG_PCI_MSI */
1993
1994        /* Clear Inbound Buffer Queue */
1995        for (rx_slot = 0; rx_slot < priv->imsg_ring[mbox].size; rx_slot++)
1996                priv->imsg_ring[mbox].imq_base[rx_slot] = NULL;
1997
1998        /* Free memory allocated for message buffers */
1999        dma_free_coherent(&priv->pdev->dev,
2000                priv->imsg_ring[mbox].size * TSI721_MSG_BUFFER_SIZE,
2001                priv->imsg_ring[mbox].buf_base,
2002                priv->imsg_ring[mbox].buf_phys);
2003
2004        priv->imsg_ring[mbox].buf_base = NULL;
2005
2006        /* Free memory allocated for free pointr list */
2007        dma_free_coherent(&priv->pdev->dev,
2008                priv->imsg_ring[mbox].size * 8,
2009                priv->imsg_ring[mbox].imfq_base,
2010                priv->imsg_ring[mbox].imfq_phys);
2011
2012        priv->imsg_ring[mbox].imfq_base = NULL;
2013
2014        /* Free memory allocated for RX descriptors */
2015        dma_free_coherent(&priv->pdev->dev,
2016                priv->imsg_ring[mbox].size * sizeof(struct tsi721_imsg_desc),
2017                priv->imsg_ring[mbox].imd_base,
2018                priv->imsg_ring[mbox].imd_phys);
2019
2020        priv->imsg_ring[mbox].imd_base = NULL;
2021}
2022
2023/**
2024 * tsi721_add_inb_buffer - Add buffer to the Tsi721 inbound message queue
2025 * @mport: Master port implementing the Inbound Messaging Engine
2026 * @mbox: Inbound mailbox number
2027 * @buf: Buffer to add to inbound queue
2028 */
2029static int tsi721_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
2030{
2031        struct tsi721_device *priv = mport->priv;
2032        u32 rx_slot;
2033        int rc = 0;
2034
2035        rx_slot = priv->imsg_ring[mbox].rx_slot;
2036        if (priv->imsg_ring[mbox].imq_base[rx_slot]) {
2037                dev_err(&priv->pdev->dev,
2038                        "Error adding inbound buffer %d, buffer exists\n",
2039                        rx_slot);
2040                rc = -EINVAL;
2041                goto out;
2042        }
2043
2044        priv->imsg_ring[mbox].imq_base[rx_slot] = buf;
2045
2046        if (++priv->imsg_ring[mbox].rx_slot == priv->imsg_ring[mbox].size)
2047                priv->imsg_ring[mbox].rx_slot = 0;
2048
2049out:
2050        return rc;
2051}
2052
2053/**
2054 * tsi721_get_inb_message - Fetch inbound message from the Tsi721 MSG Queue
2055 * @mport: Master port implementing the Inbound Messaging Engine
2056 * @mbox: Inbound mailbox number
2057 *
2058 * Returns pointer to the message on success or NULL on failure.
2059 */
2060static void *tsi721_get_inb_message(struct rio_mport *mport, int mbox)
2061{
2062        struct tsi721_device *priv = mport->priv;
2063        struct tsi721_imsg_desc *desc;
2064        u32 rx_slot;
2065        void *rx_virt = NULL;
2066        u64 rx_phys;
2067        void *buf = NULL;
2068        u64 *free_ptr;
2069        int ch = mbox + 4;
2070        int msg_size;
2071
2072        if (!priv->imsg_init[mbox])
2073                return NULL;
2074
2075        desc = priv->imsg_ring[mbox].imd_base;
2076        desc += priv->imsg_ring[mbox].desc_rdptr;
2077
2078        if (!(le32_to_cpu(desc->msg_info) & TSI721_IMD_HO))
2079                goto out;
2080
2081        rx_slot = priv->imsg_ring[mbox].rx_slot;
2082        while (priv->imsg_ring[mbox].imq_base[rx_slot] == NULL) {
2083                if (++rx_slot == priv->imsg_ring[mbox].size)
2084                        rx_slot = 0;
2085        }
2086
2087        rx_phys = ((u64)le32_to_cpu(desc->bufptr_hi) << 32) |
2088                        le32_to_cpu(desc->bufptr_lo);
2089
2090        rx_virt = priv->imsg_ring[mbox].buf_base +
2091                  (rx_phys - (u64)priv->imsg_ring[mbox].buf_phys);
2092
2093        buf = priv->imsg_ring[mbox].imq_base[rx_slot];
2094        msg_size = le32_to_cpu(desc->msg_info) & TSI721_IMD_BCOUNT;
2095        if (msg_size == 0)
2096                msg_size = RIO_MAX_MSG_SIZE;
2097
2098        memcpy(buf, rx_virt, msg_size);
2099        priv->imsg_ring[mbox].imq_base[rx_slot] = NULL;
2100
2101        desc->msg_info &= cpu_to_le32(~TSI721_IMD_HO);
2102        if (++priv->imsg_ring[mbox].desc_rdptr == priv->imsg_ring[mbox].size)
2103                priv->imsg_ring[mbox].desc_rdptr = 0;
2104
2105        iowrite32(priv->imsg_ring[mbox].desc_rdptr,
2106                priv->regs + TSI721_IBDMAC_DQRP(ch));
2107
2108        /* Return free buffer into the pointer list */
2109        free_ptr = priv->imsg_ring[mbox].imfq_base;
2110        free_ptr[priv->imsg_ring[mbox].fq_wrptr] = cpu_to_le64(rx_phys);
2111
2112        if (++priv->imsg_ring[mbox].fq_wrptr == priv->imsg_ring[mbox].size)
2113                priv->imsg_ring[mbox].fq_wrptr = 0;
2114
2115        iowrite32(priv->imsg_ring[mbox].fq_wrptr,
2116                priv->regs + TSI721_IBDMAC_FQWP(ch));
2117out:
2118        return buf;
2119}
2120
2121/**
2122 * tsi721_messages_init - Initialization of Messaging Engine
2123 * @priv: pointer to tsi721 private data
2124 *
2125 * Configures Tsi721 messaging engine.
2126 */
2127static int tsi721_messages_init(struct tsi721_device *priv)
2128{
2129        int     ch;
2130
2131        iowrite32(0, priv->regs + TSI721_SMSG_ECC_LOG);
2132        iowrite32(0, priv->regs + TSI721_RETRY_GEN_CNT);
2133        iowrite32(0, priv->regs + TSI721_RETRY_RX_CNT);
2134
2135        /* Set SRIO Message Request/Response Timeout */
2136        iowrite32(TSI721_RQRPTO_VAL, priv->regs + TSI721_RQRPTO);
2137
2138        /* Initialize Inbound Messaging Engine Registers */
2139        for (ch = 0; ch < TSI721_IMSG_CHNUM; ch++) {
2140                /* Clear interrupt bits */
2141                iowrite32(TSI721_IBDMAC_INT_MASK,
2142                        priv->regs + TSI721_IBDMAC_INT(ch));
2143                /* Clear Status */
2144                iowrite32(0, priv->regs + TSI721_IBDMAC_STS(ch));
2145
2146                iowrite32(TSI721_SMSG_ECC_COR_LOG_MASK,
2147                                priv->regs + TSI721_SMSG_ECC_COR_LOG(ch));
2148                iowrite32(TSI721_SMSG_ECC_NCOR_MASK,
2149                                priv->regs + TSI721_SMSG_ECC_NCOR(ch));
2150        }
2151
2152        return 0;
2153}
2154
2155/**
2156 * tsi721_disable_ints - disables all device interrupts
2157 * @priv: pointer to tsi721 private data
2158 */
2159static void tsi721_disable_ints(struct tsi721_device *priv)
2160{
2161        int ch;
2162
2163        /* Disable all device level interrupts */
2164        iowrite32(0, priv->regs + TSI721_DEV_INTE);
2165
2166        /* Disable all Device Channel interrupts */
2167        iowrite32(0, priv->regs + TSI721_DEV_CHAN_INTE);
2168
2169        /* Disable all Inbound Msg Channel interrupts */
2170        for (ch = 0; ch < TSI721_IMSG_CHNUM; ch++)
2171                iowrite32(0, priv->regs + TSI721_IBDMAC_INTE(ch));
2172
2173        /* Disable all Outbound Msg Channel interrupts */
2174        for (ch = 0; ch < TSI721_OMSG_CHNUM; ch++)
2175                iowrite32(0, priv->regs + TSI721_OBDMAC_INTE(ch));
2176
2177        /* Disable all general messaging interrupts */
2178        iowrite32(0, priv->regs + TSI721_SMSG_INTE);
2179
2180        /* Disable all BDMA Channel interrupts */
2181        for (ch = 0; ch < TSI721_DMA_MAXCH; ch++)
2182                iowrite32(0,
2183                        priv->regs + TSI721_DMAC_BASE(ch) + TSI721_DMAC_INTE);
2184
2185        /* Disable all general BDMA interrupts */
2186        iowrite32(0, priv->regs + TSI721_BDMA_INTE);
2187
2188        /* Disable all SRIO Channel interrupts */
2189        for (ch = 0; ch < TSI721_SRIO_MAXCH; ch++)
2190                iowrite32(0, priv->regs + TSI721_SR_CHINTE(ch));
2191
2192        /* Disable all general SR2PC interrupts */
2193        iowrite32(0, priv->regs + TSI721_SR2PC_GEN_INTE);
2194
2195        /* Disable all PC2SR interrupts */
2196        iowrite32(0, priv->regs + TSI721_PC2SR_INTE);
2197
2198        /* Disable all I2C interrupts */
2199        iowrite32(0, priv->regs + TSI721_I2C_INT_ENABLE);
2200
2201        /* Disable SRIO MAC interrupts */
2202        iowrite32(0, priv->regs + TSI721_RIO_EM_INT_ENABLE);
2203        iowrite32(0, priv->regs + TSI721_RIO_EM_DEV_INT_EN);
2204}
2205
2206/**
2207 * tsi721_setup_mport - Setup Tsi721 as RapidIO subsystem master port
2208 * @priv: pointer to tsi721 private data
2209 *
2210 * Configures Tsi721 as RapidIO master port.
2211 */
2212static int tsi721_setup_mport(struct tsi721_device *priv)
2213{
2214        struct pci_dev *pdev = priv->pdev;
2215        int err = 0;
2216        struct rio_ops *ops;
2217
2218        struct rio_mport *mport;
2219
2220        ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL);
2221        if (!ops) {
2222                dev_dbg(&pdev->dev, "Unable to allocate memory for rio_ops\n");
2223                return -ENOMEM;
2224        }
2225
2226        ops->lcread = tsi721_lcread;
2227        ops->lcwrite = tsi721_lcwrite;
2228        ops->cread = tsi721_cread_dma;
2229        ops->cwrite = tsi721_cwrite_dma;
2230        ops->dsend = tsi721_dsend;
2231        ops->open_inb_mbox = tsi721_open_inb_mbox;
2232        ops->close_inb_mbox = tsi721_close_inb_mbox;
2233        ops->open_outb_mbox = tsi721_open_outb_mbox;
2234        ops->close_outb_mbox = tsi721_close_outb_mbox;
2235        ops->add_outb_message = tsi721_add_outb_message;
2236        ops->add_inb_buffer = tsi721_add_inb_buffer;
2237        ops->get_inb_message = tsi721_get_inb_message;
2238        ops->map_inb = tsi721_rio_map_inb_mem;
2239        ops->unmap_inb = tsi721_rio_unmap_inb_mem;
2240
2241        mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
2242        if (!mport) {
2243                kfree(ops);
2244                dev_dbg(&pdev->dev, "Unable to allocate memory for mport\n");
2245                return -ENOMEM;
2246        }
2247
2248        mport->ops = ops;
2249        mport->index = 0;
2250        mport->sys_size = 0; /* small system */
2251        mport->phy_type = RIO_PHY_SERIAL;
2252        mport->priv = (void *)priv;
2253        mport->phys_efptr = 0x100;
2254        mport->dev.parent = &pdev->dev;
2255        priv->mport = mport;
2256
2257        INIT_LIST_HEAD(&mport->dbells);
2258
2259        rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
2260        rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3);
2261        rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3);
2262        snprintf(mport->name, RIO_MAX_MPORT_NAME, "%s(%s)",
2263                 dev_driver_string(&pdev->dev), dev_name(&pdev->dev));
2264
2265        /* Hook up interrupt handler */
2266
2267#ifdef CONFIG_PCI_MSI
2268        if (!tsi721_enable_msix(priv))
2269                priv->flags |= TSI721_USING_MSIX;
2270        else if (!pci_enable_msi(pdev))
2271                priv->flags |= TSI721_USING_MSI;
2272        else
2273                dev_info(&pdev->dev,
2274                         "MSI/MSI-X is not available. Using legacy INTx.\n");
2275#endif /* CONFIG_PCI_MSI */
2276
2277        err = tsi721_request_irq(mport);
2278
2279        if (!err) {
2280                tsi721_interrupts_init(priv);
2281                ops->pwenable = tsi721_pw_enable;
2282        } else {
2283                dev_err(&pdev->dev, "Unable to get assigned PCI IRQ "
2284                        "vector %02X err=0x%x\n", pdev->irq, err);
2285                goto err_exit;
2286        }
2287
2288#ifdef CONFIG_RAPIDIO_DMA_ENGINE
2289        tsi721_register_dma(priv);
2290#endif
2291        /* Enable SRIO link */
2292        iowrite32(ioread32(priv->regs + TSI721_DEVCTL) |
2293                  TSI721_DEVCTL_SRBOOT_CMPL,
2294                  priv->regs + TSI721_DEVCTL);
2295
2296        rio_register_mport(mport);
2297
2298        if (mport->host_deviceid >= 0)
2299                iowrite32(RIO_PORT_GEN_HOST | RIO_PORT_GEN_MASTER |
2300                          RIO_PORT_GEN_DISCOVERED,
2301                          priv->regs + (0x100 + RIO_PORT_GEN_CTL_CSR));
2302        else
2303                iowrite32(0, priv->regs + (0x100 + RIO_PORT_GEN_CTL_CSR));
2304
2305        return 0;
2306
2307err_exit:
2308        kfree(mport);
2309        kfree(ops);
2310        return err;
2311}
2312
2313static int tsi721_probe(struct pci_dev *pdev,
2314                                  const struct pci_device_id *id)
2315{
2316        struct tsi721_device *priv;
2317        int err;
2318
2319        priv = kzalloc(sizeof(struct tsi721_device), GFP_KERNEL);
2320        if (priv == NULL) {
2321                dev_err(&pdev->dev, "Failed to allocate memory for device\n");
2322                err = -ENOMEM;
2323                goto err_exit;
2324        }
2325
2326        err = pci_enable_device(pdev);
2327        if (err) {
2328                dev_err(&pdev->dev, "Failed to enable PCI device\n");
2329                goto err_clean;
2330        }
2331
2332        priv->pdev = pdev;
2333
2334#ifdef DEBUG
2335        {
2336        int i;
2337        for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
2338                dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n",
2339                        i, (unsigned long long)pci_resource_start(pdev, i),
2340                        (unsigned long)pci_resource_len(pdev, i),
2341                        pci_resource_flags(pdev, i));
2342        }
2343        }
2344#endif
2345        /*
2346         * Verify BAR configuration
2347         */
2348
2349        /* BAR_0 (registers) must be 512KB+ in 32-bit address space */
2350        if (!(pci_resource_flags(pdev, BAR_0) & IORESOURCE_MEM) ||
2351            pci_resource_flags(pdev, BAR_0) & IORESOURCE_MEM_64 ||
2352            pci_resource_len(pdev, BAR_0) < TSI721_REG_SPACE_SIZE) {
2353                dev_err(&pdev->dev,
2354                        "Missing or misconfigured CSR BAR0, aborting.\n");
2355                err = -ENODEV;
2356                goto err_disable_pdev;
2357        }
2358
2359        /* BAR_1 (outbound doorbells) must be 16MB+ in 32-bit address space */
2360        if (!(pci_resource_flags(pdev, BAR_1) & IORESOURCE_MEM) ||
2361            pci_resource_flags(pdev, BAR_1) & IORESOURCE_MEM_64 ||
2362            pci_resource_len(pdev, BAR_1) < TSI721_DB_WIN_SIZE) {
2363                dev_err(&pdev->dev,
2364                        "Missing or misconfigured Doorbell BAR1, aborting.\n");
2365                err = -ENODEV;
2366                goto err_disable_pdev;
2367        }
2368
2369        /*
2370         * BAR_2 and BAR_4 (outbound translation) must be in 64-bit PCIe address
2371         * space.
2372         * NOTE: BAR_2 and BAR_4 are not used by this version of driver.
2373         * It may be a good idea to keep them disabled using HW configuration
2374         * to save PCI memory space.
2375         */
2376        if ((pci_resource_flags(pdev, BAR_2) & IORESOURCE_MEM) &&
2377            (pci_resource_flags(pdev, BAR_2) & IORESOURCE_MEM_64)) {
2378                dev_info(&pdev->dev, "Outbound BAR2 is not used but enabled.\n");
2379        }
2380
2381        if ((pci_resource_flags(pdev, BAR_4) & IORESOURCE_MEM) &&
2382            (pci_resource_flags(pdev, BAR_4) & IORESOURCE_MEM_64)) {
2383                dev_info(&pdev->dev, "Outbound BAR4 is not used but enabled.\n");
2384        }
2385
2386        err = pci_request_regions(pdev, DRV_NAME);
2387        if (err) {
2388                dev_err(&pdev->dev, "Cannot obtain PCI resources, "
2389                        "aborting.\n");
2390                goto err_disable_pdev;
2391        }
2392
2393        pci_set_master(pdev);
2394
2395        priv->regs = pci_ioremap_bar(pdev, BAR_0);
2396        if (!priv->regs) {
2397                dev_err(&pdev->dev,
2398                        "Unable to map device registers space, aborting\n");
2399                err = -ENOMEM;
2400                goto err_free_res;
2401        }
2402
2403        priv->odb_base = pci_ioremap_bar(pdev, BAR_1);
2404        if (!priv->odb_base) {
2405                dev_err(&pdev->dev,
2406                        "Unable to map outbound doorbells space, aborting\n");
2407                err = -ENOMEM;
2408                goto err_unmap_bars;
2409        }
2410
2411        /* Configure DMA attributes. */
2412        if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
2413                err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2414                if (err) {
2415                        dev_info(&pdev->dev, "Unable to set DMA mask\n");
2416                        goto err_unmap_bars;
2417                }
2418
2419                if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
2420                        dev_info(&pdev->dev, "Unable to set consistent DMA mask\n");
2421        } else {
2422                err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
2423                if (err)
2424                        dev_info(&pdev->dev, "Unable to set consistent DMA mask\n");
2425        }
2426
2427        BUG_ON(!pci_is_pcie(pdev));
2428
2429        /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
2430        pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL,
2431                PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
2432                PCI_EXP_DEVCTL_NOSNOOP_EN,
2433                0x2 << MAX_READ_REQUEST_SZ_SHIFT);
2434
2435        /* Adjust PCIe completion timeout. */
2436        pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2);
2437
2438        /*
2439         * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block
2440         */
2441        pci_write_config_dword(pdev, TSI721_PCIECFG_EPCTL, 0x01);
2442        pci_write_config_dword(pdev, TSI721_PCIECFG_MSIXTBL,
2443                                                TSI721_MSIXTBL_OFFSET);
2444        pci_write_config_dword(pdev, TSI721_PCIECFG_MSIXPBA,
2445                                                TSI721_MSIXPBA_OFFSET);
2446        pci_write_config_dword(pdev, TSI721_PCIECFG_EPCTL, 0);
2447        /* End of FIXUP */
2448
2449        tsi721_disable_ints(priv);
2450
2451        tsi721_init_pc2sr_mapping(priv);
2452        tsi721_init_sr2pc_mapping(priv);
2453
2454        if (tsi721_bdma_maint_init(priv)) {
2455                dev_err(&pdev->dev, "BDMA initialization failed, aborting\n");
2456                err = -ENOMEM;
2457                goto err_unmap_bars;
2458        }
2459
2460        err = tsi721_doorbell_init(priv);
2461        if (err)
2462                goto err_free_bdma;
2463
2464        tsi721_port_write_init(priv);
2465
2466        err = tsi721_messages_init(priv);
2467        if (err)
2468                goto err_free_consistent;
2469
2470        err = tsi721_setup_mport(priv);
2471        if (err)
2472                goto err_free_consistent;
2473
2474        return 0;
2475
2476err_free_consistent:
2477        tsi721_doorbell_free(priv);
2478err_free_bdma:
2479        tsi721_bdma_maint_free(priv);
2480err_unmap_bars:
2481        if (priv->regs)
2482                iounmap(priv->regs);
2483        if (priv->odb_base)
2484                iounmap(priv->odb_base);
2485err_free_res:
2486        pci_release_regions(pdev);
2487        pci_clear_master(pdev);
2488err_disable_pdev:
2489        pci_disable_device(pdev);
2490err_clean:
2491        kfree(priv);
2492err_exit:
2493        return err;
2494}
2495
2496static DEFINE_PCI_DEVICE_TABLE(tsi721_pci_tbl) = {
2497        { PCI_DEVICE(PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_TSI721) },
2498        { 0, }  /* terminate list */
2499};
2500
2501MODULE_DEVICE_TABLE(pci, tsi721_pci_tbl);
2502
2503static struct pci_driver tsi721_driver = {
2504        .name           = "tsi721",
2505        .id_table       = tsi721_pci_tbl,
2506        .probe          = tsi721_probe,
2507};
2508
2509static int __init tsi721_init(void)
2510{
2511        return pci_register_driver(&tsi721_driver);
2512}
2513
2514device_initcall(tsi721_init);
2515
2516MODULE_DESCRIPTION("IDT Tsi721 PCIExpress-to-SRIO bridge driver");
2517MODULE_AUTHOR("Integrated Device Technology, Inc.");
2518MODULE_LICENSE("GPL");
2519