/*
 * Copyright 2016 Broadcom
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation (the "GPL").
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 (GPLv2) for more details.
 *
 * You should have received a copy of the GNU General Public License
 * version 2 (GPLv2) along with this source code.
 */

/*
 * Broadcom PDC Mailbox Driver
 * The PDC provides a ring based programming interface to one or more hardware
 * offload engines. For example, the PDC driver works with both SPU-M and SPU2
 * cryptographic offload hardware. In some chips the PDC is referred to as MDE.
 *
 * The PDC driver registers with the Linux mailbox framework as a mailbox
 * controller, once for each PDC instance. Ring 0 for each PDC is registered as
 * a mailbox channel. The PDC driver uses interrupts to determine when data
 * transfers to and from an offload engine are complete. The PDC driver uses
 * threaded IRQs so that response messages are handled outside of interrupt
 * context.
 *
 * The PDC driver allows multiple messages to be pending in the descriptor
 * rings. The tx_msg_start descriptor index indicates where the last message
 * starts. The txin_numd value at this index indicates how many descriptor
 * indexes make up the message. Similar state is kept on the receive side. When
 * an rx interrupt indicates a response is ready, the PDC driver processes numd
 * descriptors from the tx and rx ring, thus processing one response at a time.
 */

#include <linux/errno.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/mailbox_controller.h>
#include <linux/mailbox/brcm-message.h>
#include <linux/scatterlist.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>

#define PDC_SUCCESS  0

#define RING_ENTRY_SIZE   sizeof(struct dma64dd)

/* # entries in PDC dma ring */
#define PDC_RING_ENTRIES  128
#define PDC_RING_SIZE    (PDC_RING_ENTRIES * RING_ENTRY_SIZE)
/* Rings are 8k aligned */
#define RING_ALIGN_ORDER  13
#define RING_ALIGN        BIT(RING_ALIGN_ORDER)

#define RX_BUF_ALIGN_ORDER  5
#define RX_BUF_ALIGN	    BIT(RX_BUF_ALIGN_ORDER)

/* descriptor bumping macros */
#define XXD(x, max_mask)              ((x) & (max_mask))
#define TXD(x, max_mask)              XXD((x), (max_mask))
#define RXD(x, max_mask)              XXD((x), (max_mask))
#define NEXTTXD(i, max_mask)          TXD((i) + 1, (max_mask))
#define PREVTXD(i, max_mask)          TXD((i) - 1, (max_mask))
#define NEXTRXD(i, max_mask)          RXD((i) + 1, (max_mask))
#define PREVRXD(i, max_mask)          RXD((i) - 1, (max_mask))
#define NTXDACTIVE(h, t, max_mask)    TXD((t) - (h), (max_mask))
#define NRXDACTIVE(h, t, max_mask)    RXD((t) - (h), (max_mask))

/* Length of BCM header at start of SPU msg, in bytes */
#define BCM_HDR_LEN  8

/*
 * PDC driver reserves ringset 0 on each SPU for its own use. The driver does
 * not currently support use of multiple ringsets on a single PDC engine.
 */
#define PDC_RINGSET  0

/*
 * Interrupt mask and status definitions. Enable interrupts for tx and rx on
 * ring 0
 */
#define PDC_XMTINT_0         (24 + PDC_RINGSET)
#define PDC_RCVINT_0         (16 + PDC_RINGSET)
#define PDC_XMTINTEN_0       BIT(PDC_XMTINT_0)
#define PDC_RCVINTEN_0       BIT(PDC_RCVINT_0)
#define PDC_INTMASK  (PDC_XMTINTEN_0 | PDC_RCVINTEN_0)
#define PDC_LAZY_FRAMECOUNT  1
#define PDC_LAZY_TIMEOUT     10000
#define PDC_LAZY_INT  (PDC_LAZY_TIMEOUT | (PDC_LAZY_FRAMECOUNT << 24))
#define PDC_INTMASK_OFFSET   0x24
#define PDC_INTSTATUS_OFFSET 0x20
#define PDC_RCVLAZY0_OFFSET  (0x30 + 4 * PDC_RINGSET)

/*
 * For SPU2, configure MDE_CKSUM_CONTROL to write 17 bytes of metadata
 * before frame
 */
#define PDC_SPU2_RESP_HDR_LEN  17
#define PDC_CKSUM_CTRL         BIT(27)
#define PDC_CKSUM_CTRL_OFFSET  0x400

#define PDC_SPUM_RESP_HDR_LEN  32

/*
 * Sets the following bits for write to transmit control reg:
 *  0    - XmtEn - enable activity on the tx channel
 * 11    - PtyChkDisable - parity check is disabled
 * 20:18 - BurstLen = 3 -> 2^7 = 128 byte data reads from memory
 */
#define PDC_TX_CTL              0x000C0801

/*
 * Sets the following bits for write to receive control reg:
 * 0     - RcvEn - enable activity on the rx channel
 * 7:1   - RcvOffset - size in bytes of status region at start of rx frame buf
 * 9     - SepRxHdrDescEn - place start of new frames only in descriptors
 *                          that have StartOfFrame set
 * 10    - OflowContinue - on rx FIFO overflow, clear rx fifo, discard all
 *                         remaining bytes in current frame, report error
 *                         in rx frame status for current frame
 * 11    - PtyChkDisable - parity check is disabled
 * 20:18 - BurstLen = 3 -> 2^7 = 128 byte data reads from memory
 */
#define PDC_RX_CTL              0x000C0E01

#define CRYPTO_D64_RS0_CD_MASK   ((PDC_RING_ENTRIES * RING_ENTRY_SIZE) - 1)

/* descriptor flags */
#define D64_CTRL1_EOT   BIT(28)	/* end of descriptor table */
#define D64_CTRL1_IOC   BIT(29)	/* interrupt on complete */
#define D64_CTRL1_EOF   BIT(30)	/* end of frame */
#define D64_CTRL1_SOF   BIT(31)	/* start of frame */

#define RX_STATUS_OVERFLOW       0x00800000
#define RX_STATUS_LEN            0x0000FFFF

#define PDC_TXREGS_OFFSET  0x200
#define PDC_RXREGS_OFFSET  0x220

/* Maximum size buffer the DMA engine can handle */
#define PDC_DMA_BUF_MAX 16384

struct pdc_dma_map {
	void *ctx;          /* opaque context associated with frame */
};

/* dma descriptor */
struct dma64dd {
	u32 ctrl1;      /* misc control bits */
	u32 ctrl2;      /* buffer count and address extension */
	u32 addrlow;    /* memory address of the date buffer, bits 31:0 */
	u32 addrhigh;   /* memory address of the date buffer, bits 63:32 */
};

/* dma registers per channel(xmt or rcv) */
struct dma64_regs {
	u32  control;   /* enable, et al */
	u32  ptr;       /* last descriptor posted to chip */
	u32  addrlow;   /* descriptor ring base address low 32-bits */
	u32  addrhigh;  /* descriptor ring base address bits 63:32 */
	u32  status0;   /* last rx descriptor written by hw */
	u32  status1;   /* driver does not use */
};

/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line)  pad ## line
#define _XSTR(line)     _PADLINE(line)
#define PAD             _XSTR(__LINE__)
#endif  /* PAD */

/* dma registers. matches hw layout. */
struct dma64 {
	struct dma64_regs dmaxmt;  /* dma tx */
	u32          PAD[2];
	struct dma64_regs dmarcv;  /* dma rx */
	u32          PAD[2];
};

/* PDC registers */
struct pdc_regs {
	u32  devcontrol;             /* 0x000 */
	u32  devstatus;              /* 0x004 */
	u32  PAD;
	u32  biststatus;             /* 0x00c */
	u32  PAD[4];
	u32  intstatus;              /* 0x020 */
	u32  intmask;                /* 0x024 */
	u32  gptimer;                /* 0x028 */

	u32  PAD;
	u32  intrcvlazy_0;           /* 0x030 */
	u32  intrcvlazy_1;           /* 0x034 */
	u32  intrcvlazy_2;           /* 0x038 */
	u32  intrcvlazy_3;           /* 0x03c */

	u32  PAD[48];
	u32  removed_intrecvlazy;    /* 0x100 */
	u32  flowctlthresh;          /* 0x104 */
	u32  wrrthresh;              /* 0x108 */
	u32  gmac_idle_cnt_thresh;   /* 0x10c */

	u32  PAD[4];
	u32  ifioaccessaddr;         /* 0x120 */
	u32  ifioaccessbyte;         /* 0x124 */
	u32  ifioaccessdata;         /* 0x128 */

	u32  PAD[21];
	u32  phyaccess;              /* 0x180 */
	u32  PAD;
	u32  phycontrol;             /* 0x188 */
	u32  txqctl;                 /* 0x18c */
	u32  rxqctl;                 /* 0x190 */
	u32  gpioselect;             /* 0x194 */
	u32  gpio_output_en;         /* 0x198 */
	u32  PAD;                    /* 0x19c */
	u32  txq_rxq_mem_ctl;        /* 0x1a0 */
	u32  memory_ecc_status;      /* 0x1a4 */
	u32  serdes_ctl;             /* 0x1a8 */
	u32  serdes_status0;         /* 0x1ac */
	u32  serdes_status1;         /* 0x1b0 */
	u32  PAD[11];                /* 0x1b4-1dc */
	u32  clk_ctl_st;             /* 0x1e0 */
	u32  hw_war;                 /* 0x1e4 */
	u32  pwrctl;                 /* 0x1e8 */
	u32  PAD[5];

#define PDC_NUM_DMA_RINGS   4
	struct dma64 dmaregs[PDC_NUM_DMA_RINGS];  /* 0x0200 - 0x2fc */

	/* more registers follow, but we don't use them */
};

/* structure for allocating/freeing DMA rings */
struct pdc_ring_alloc {
	dma_addr_t  dmabase; /* DMA address of start of ring */
	void	   *vbase;   /* base kernel virtual address of ring */
	u32	    size;    /* ring allocation size in bytes */
};

/* PDC state structure */
struct pdc_state {
	/* synchronize access to this PDC state structure */
	spinlock_t pdc_lock;

	/* Index of the PDC whose state is in this structure instance */
	u8 pdc_idx;

	/* Platform device for this PDC instance */
	struct platform_device *pdev;

	/*
	 * Each PDC instance has a mailbox controller. PDC receives request
	 * messages through mailboxes, and sends response messages through the
	 * mailbox framework.
	 */
	struct mbox_controller mbc;

	unsigned int pdc_irq;

	/*
	 * Last interrupt status read from PDC device. Saved in interrupt
	 * handler so the handler can clear the interrupt in the device,
	 * and the interrupt thread called later can know which interrupt
	 * bits are active.
	 */
	unsigned long intstatus;

	/* Number of bytes of receive status prior to each rx frame */
	u32 rx_status_len;
	/* Whether a BCM header is prepended to each frame */
	bool use_bcm_hdr;
	/* Sum of length of BCM header and rx status header */
	u32 pdc_resp_hdr_len;

	/* The base virtual address of DMA hw registers */
	void __iomem *pdc_reg_vbase;

	/* Pool for allocation of DMA rings */
	struct dma_pool *ring_pool;

	/* Pool for allocation of metadata buffers for response messages */
	struct dma_pool *rx_buf_pool;

	/*
	 * The base virtual address of DMA tx/rx descriptor rings. Corresponding
	 * DMA address and size of ring allocation.
	 */
	struct pdc_ring_alloc tx_ring_alloc;
	struct pdc_ring_alloc rx_ring_alloc;

	struct pdc_regs *regs;    /* start of PDC registers */

	struct dma64_regs *txregs_64; /* dma tx engine registers */
	struct dma64_regs *rxregs_64; /* dma rx engine registers */

	/*
	 * Arrays of PDC_RING_ENTRIES descriptors
	 * To use multiple ringsets, this needs to be extended
	 */
	struct dma64dd   *txd_64;  /* tx descriptor ring */
	struct dma64dd   *rxd_64;  /* rx descriptor ring */

	/* descriptor ring sizes */
	u32      ntxd;       /* # tx descriptors */
	u32      nrxd;       /* # rx descriptors */
	u32      nrxpost;    /* # rx buffers to keep posted */
	u32      ntxpost;    /* max number of tx buffers that can be posted */

	/*
	 * Index of next tx descriptor to reclaim. That is, the descriptor
	 * index of the oldest tx buffer for which the host has yet to process
	 * the corresponding response.
	 */
	u32  txin;

	/*
	 * Index of the first receive descriptor for the sequence of
	 * message fragments currently under construction. Used to build up
	 * the rxin_numd count for a message. Updated to rxout when the host
	 * starts a new sequence of rx buffers for a new message.
	 */
	u32  tx_msg_start;

	/* Index of next tx descriptor to post. */
	u32  txout;

	/*
	 * Number of tx descriptors associated with the message that starts
	 * at this tx descriptor index.
	 */
	u32      txin_numd[PDC_RING_ENTRIES];

	/*
	 * Index of next rx descriptor to reclaim. This is the index of
	 * the next descriptor whose data has yet to be processed by the host.
	 */
	u32  rxin;

	/*
	 * Index of the first receive descriptor for the sequence of
	 * message fragments currently under construction. Used to build up
	 * the rxin_numd count for a message. Updated to rxout when the host
	 * starts a new sequence of rx buffers for a new message.
	 */
	u32  rx_msg_start;

	/*
	 * Saved value of current hardware rx descriptor index.
	 * The last rx buffer written by the hw is the index previous to
	 * this one.
	 */
	u32  last_rx_curr;

	/* Index of next rx descriptor to post. */
	u32  rxout;

	/*
	 * opaque context associated with frame that starts at each
	 * rx ring index.
	 */
	void *rxp_ctx[PDC_RING_ENTRIES];

	/*
	 * Scatterlists used to form request and reply frames beginning at a
	 * given ring index. Retained in order to unmap each sg after reply
	 * is processed
	 */
	struct scatterlist *src_sg[PDC_RING_ENTRIES];
	struct scatterlist *dst_sg[PDC_RING_ENTRIES];

	/*
	 * Number of rx descriptors associated with the message that starts
	 * at this descriptor index. Not set for every index. For example,
	 * if descriptor index i points to a scatterlist with 4 entries, then
	 * the next three descriptor indexes don't have a value set.
	 */
	u32  rxin_numd[PDC_RING_ENTRIES];

	void *resp_hdr[PDC_RING_ENTRIES];
	dma_addr_t resp_hdr_daddr[PDC_RING_ENTRIES];

	struct dentry *debugfs_stats;  /* debug FS stats file for this PDC */

	/* counters */
	u32  pdc_requests;    /* number of request messages submitted */
	u32  pdc_replies;     /* number of reply messages received */
	u32  txnobuf;         /* count of tx ring full */
	u32  rxnobuf;         /* count of rx ring full */
	u32  rx_oflow;        /* count of rx overflows */
};

/* Global variables */

struct pdc_globals {
	/* Actual number of SPUs in hardware, as reported by device tree */
	u32 num_spu;
};

static struct pdc_globals pdcg;

/* top level debug FS directory for PDC driver */
static struct dentry *debugfs_dir;

static ssize_t pdc_debugfs_read(struct file *filp, char __user *ubuf,
				size_t count, loff_t *offp)
{
	struct pdc_state *pdcs;
	char *buf;
	ssize_t ret, out_offset, out_count;

	out_count = 512;

	buf = kmalloc(out_count, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	pdcs = filp->private_data;
	out_offset = 0;
	out_offset += snprintf(buf + out_offset, out_count - out_offset,
			       "SPU %u stats:\n", pdcs->pdc_idx);
	out_offset += snprintf(buf + out_offset, out_count - out_offset,
			       "PDC requests............%u\n",
			       pdcs->pdc_requests);
	out_offset += snprintf(buf + out_offset, out_count - out_offset,
			       "PDC responses...........%u\n",
			       pdcs->pdc_replies);
	out_offset += snprintf(buf + out_offset, out_count - out_offset,
			       "Tx err ring full........%u\n",
			       pdcs->txnobuf);
	out_offset += snprintf(buf + out_offset, out_count - out_offset,
			       "Rx err ring full........%u\n",
			       pdcs->rxnobuf);
	out_offset += snprintf(buf + out_offset, out_count - out_offset,
			       "Receive overflow........%u\n",
			       pdcs->rx_oflow);

	if (out_offset > out_count)
		out_offset = out_count;

	ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset);
	kfree(buf);
	return ret;
}

static const struct file_operations pdc_debugfs_stats = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = pdc_debugfs_read,
};

/**
 * pdc_setup_debugfs() - Create the debug FS directories. If the top-level
 * directory has not yet been created, create it now. Create a stats file in
 * this directory for a SPU.
 * @pdcs: PDC state structure
 */
void pdc_setup_debugfs(struct pdc_state *pdcs)
{
	char spu_stats_name[16];

	if (!debugfs_initialized())
		return;

	snprintf(spu_stats_name, 16, "pdc%d_stats", pdcs->pdc_idx);
	if (!debugfs_dir)
		debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);

	pdcs->debugfs_stats = debugfs_create_file(spu_stats_name, S_IRUSR,
						  debugfs_dir, pdcs,
						  &pdc_debugfs_stats);
}

void pdc_free_debugfs(void)
{
	if (debugfs_dir && simple_empty(debugfs_dir)) {
		debugfs_remove_recursive(debugfs_dir);
		debugfs_dir = NULL;
	}
}

/**
 * pdc_build_rxd() - Build DMA descriptor to receive SPU result.
 * @pdcs:      PDC state for SPU that will generate result
 * @dma_addr:  DMA address of buffer that descriptor is being built for
 * @buf_len:   Length of the receive buffer, in bytes
 * @flags:     Flags to be stored in descriptor
 */
static inline void
pdc_build_rxd(struct pdc_state *pdcs, dma_addr_t dma_addr,
	      u32 buf_len, u32 flags)
{
	struct device *dev = &pdcs->pdev->dev;

	dev_dbg(dev,
		"Writing rx descriptor for PDC %u at index %u with length %u. flags %#x\n",
		pdcs->pdc_idx, pdcs->rxout, buf_len, flags);

	iowrite32(lower_32_bits(dma_addr),
		  (void *)&pdcs->rxd_64[pdcs->rxout].addrlow);
	iowrite32(upper_32_bits(dma_addr),
		  (void *)&pdcs->rxd_64[pdcs->rxout].addrhigh);
	iowrite32(flags, (void *)&pdcs->rxd_64[pdcs->rxout].ctrl1);
	iowrite32(buf_len, (void *)&pdcs->rxd_64[pdcs->rxout].ctrl2);
	/* bump ring index and return */
	pdcs->rxout = NEXTRXD(pdcs->rxout, pdcs->nrxpost);
}

/**
 * pdc_build_txd() - Build a DMA descriptor to transmit a SPU request to
 * hardware.
 * @pdcs:        PDC state for the SPU that will process this request
 * @dma_addr:    DMA address of packet to be transmitted
 * @buf_len:     Length of tx buffer, in bytes
 * @flags:       Flags to be stored in descriptor
 */
static inline void
pdc_build_txd(struct pdc_state *pdcs, dma_addr_t dma_addr, u32 buf_len,
	      u32 flags)
{
	struct device *dev = &pdcs->pdev->dev;

	dev_dbg(dev,
		"Writing tx descriptor for PDC %u at index %u with length %u, flags %#x\n",
		pdcs->pdc_idx, pdcs->txout, buf_len, flags);

	iowrite32(lower_32_bits(dma_addr),
		  (void *)&pdcs->txd_64[pdcs->txout].addrlow);
	iowrite32(upper_32_bits(dma_addr),
		  (void *)&pdcs->txd_64[pdcs->txout].addrhigh);
	iowrite32(flags, (void *)&pdcs->txd_64[pdcs->txout].ctrl1);
	iowrite32(buf_len, (void *)&pdcs->txd_64[pdcs->txout].ctrl2);

	/* bump ring index and return */
	pdcs->txout = NEXTTXD(pdcs->txout, pdcs->ntxpost);
}

/**
 * pdc_receive() - Receive a response message from a given SPU.
 * @pdcs:    PDC state for the SPU to receive from
 * @mssg:    mailbox message to be returned to client
 *
 * When the return code indicates success, the response message is available in
 * the receive buffers provided prior to submission of the request.
 *
 * Input:
 *   pdcs - PDC state structure for the SPU to be polled
 *   mssg - mailbox message to be returned to client. This function sets the
 *	    context pointer on the message to help the client associate the
 *	    response with a request.
 *
 * Return:  PDC_SUCCESS if one or more receive descriptors was processed
 *          -EAGAIN indicates that no response message is available
 *          -EIO an error occurred
 */
static int
pdc_receive(struct pdc_state *pdcs, struct brcm_message *mssg)
{
	struct device *dev = &pdcs->pdev->dev;
	u32 len, rx_status;
	u32 num_frags;
	int i;
	u8 *resp_hdr;    /* virtual addr of start of resp message DMA header */
	u32 frags_rdy;   /* number of fragments ready to read */
	u32 rx_idx;      /* ring index of start of receive frame */
	dma_addr_t resp_hdr_daddr;

	spin_lock(&pdcs->pdc_lock);

	/*
	 * return if a complete response message is not yet ready.
	 * rxin_numd[rxin] is the number of fragments in the next msg
	 * to read.
	 */
	frags_rdy = NRXDACTIVE(pdcs->rxin, pdcs->last_rx_curr, pdcs->nrxpost);
	if ((frags_rdy == 0) || (frags_rdy < pdcs->rxin_numd[pdcs->rxin])) {
		/* See if the hw has written more fragments than we know */
		pdcs->last_rx_curr =
		    (ioread32((void *)&pdcs->rxregs_64->status0) &
		     CRYPTO_D64_RS0_CD_MASK) / RING_ENTRY_SIZE;
		frags_rdy = NRXDACTIVE(pdcs->rxin, pdcs->last_rx_curr,
				       pdcs->nrxpost);
		if ((frags_rdy == 0) ||
		    (frags_rdy < pdcs->rxin_numd[pdcs->rxin])) {
			/* No response ready */
			spin_unlock(&pdcs->pdc_lock);
			return -EAGAIN;
		}
		/* can't read descriptors/data until write index is read */
		rmb();
	}

	num_frags = pdcs->txin_numd[pdcs->txin];
	dma_unmap_sg(dev, pdcs->src_sg[pdcs->txin],
		     sg_nents(pdcs->src_sg[pdcs->txin]), DMA_TO_DEVICE);

	for (i = 0; i < num_frags; i++)
		pdcs->txin = NEXTTXD(pdcs->txin, pdcs->ntxpost);

	dev_dbg(dev, "PDC %u reclaimed %d tx descriptors",
		pdcs->pdc_idx, num_frags);

	rx_idx = pdcs->rxin;
	num_frags = pdcs->rxin_numd[rx_idx];
	/* Return opaque context with result */
	mssg->ctx = pdcs->rxp_ctx[rx_idx];
	pdcs->rxp_ctx[rx_idx] = NULL;
	resp_hdr = pdcs->resp_hdr[rx_idx];
	resp_hdr_daddr = pdcs->resp_hdr_daddr[rx_idx];
	dma_unmap_sg(dev, pdcs->dst_sg[rx_idx],
		     sg_nents(pdcs->dst_sg[rx_idx]), DMA_FROM_DEVICE);

	for (i = 0; i < num_frags; i++)
		pdcs->rxin = NEXTRXD(pdcs->rxin, pdcs->nrxpost);

	spin_unlock(&pdcs->pdc_lock);

	dev_dbg(dev, "PDC %u reclaimed %d rx descriptors",
		pdcs->pdc_idx, num_frags);

	dev_dbg(dev,
		"PDC %u txin %u, txout %u, rxin %u, rxout %u, last_rx_curr %u\n",
		pdcs->pdc_idx, pdcs->txin, pdcs->txout, pdcs->rxin,
		pdcs->rxout, pdcs->last_rx_curr);

	if (pdcs->pdc_resp_hdr_len == PDC_SPUM_RESP_HDR_LEN) {
		/*
		 * For SPU-M, get length of response msg and rx overflow status.
		 */
		rx_status = *((u32 *)resp_hdr);
		len = rx_status & RX_STATUS_LEN;
		dev_dbg(dev,
			"SPU response length %u bytes", len);
		if (unlikely(((rx_status & RX_STATUS_OVERFLOW) || (!len)))) {
			if (rx_status & RX_STATUS_OVERFLOW) {
				dev_err_ratelimited(dev,
						    "crypto receive overflow");
				pdcs->rx_oflow++;
			} else {
				dev_info_ratelimited(dev, "crypto rx len = 0");
			}
			return -EIO;
		}
	}

	dma_pool_free(pdcs->rx_buf_pool, resp_hdr, resp_hdr_daddr);

	pdcs->pdc_replies++;
	/* if we read one or more rx descriptors, claim success */
	if (num_frags > 0)
		return PDC_SUCCESS;
	else
		return -EIO;
}

/**
 * pdc_tx_list_sg_add() - Add the buffers in a scatterlist to the transmit
 * descriptors for a given SPU. The scatterlist buffers contain the data for a
 * SPU request message.
 * @spu_idx:   The index of the SPU to submit the request to, [0, max_spu)
 * @sg:        Scatterlist whose buffers contain part of the SPU request
 *
 * If a scatterlist buffer is larger than PDC_DMA_BUF_MAX, multiple descriptors
 * are written for that buffer, each <= PDC_DMA_BUF_MAX byte in length.
 *
 * Return: PDC_SUCCESS if successful
 *         < 0 otherwise
 */
static int pdc_tx_list_sg_add(struct pdc_state *pdcs, struct scatterlist *sg)
{
	u32 flags = 0;
	u32 eot;
	u32 tx_avail;

	/*
	 * Num descriptors needed. Conservatively assume we need a descriptor
	 * for every entry in sg.
	 */
	u32 num_desc;
	u32 desc_w = 0;	/* Number of tx descriptors written */
	u32 bufcnt;	/* Number of bytes of buffer pointed to by descriptor */
	dma_addr_t databufptr;	/* DMA address to put in descriptor */

	num_desc = (u32)sg_nents(sg);

	/* check whether enough tx descriptors are available */
	tx_avail = pdcs->ntxpost - NTXDACTIVE(pdcs->txin, pdcs->txout,
					      pdcs->ntxpost);
	if (unlikely(num_desc > tx_avail)) {
		pdcs->txnobuf++;
		return -ENOSPC;
	}

	/* build tx descriptors */
	if (pdcs->tx_msg_start == pdcs->txout) {
		/* Start of frame */
		pdcs->txin_numd[pdcs->tx_msg_start] = 0;
		pdcs->src_sg[pdcs->txout] = sg;
		flags = D64_CTRL1_SOF;
	}

	while (sg) {
		if (unlikely(pdcs->txout == (pdcs->ntxd - 1)))
			eot = D64_CTRL1_EOT;
		else
			eot = 0;

		/*
		 * If sg buffer larger than PDC limit, split across
		 * multiple descriptors
		 */
		bufcnt = sg_dma_len(sg);
		databufptr = sg_dma_address(sg);
		while (bufcnt > PDC_DMA_BUF_MAX) {
			pdc_build_txd(pdcs, databufptr, PDC_DMA_BUF_MAX,
				      flags | eot);
			desc_w++;
			bufcnt -= PDC_DMA_BUF_MAX;
			databufptr += PDC_DMA_BUF_MAX;
			if (unlikely(pdcs->txout == (pdcs->ntxd - 1)))
				eot = D64_CTRL1_EOT;
			else
				eot = 0;
		}
		sg = sg_next(sg);
		if (!sg)
			/* Writing last descriptor for frame */
			flags |= (D64_CTRL1_EOF | D64_CTRL1_IOC);
		pdc_build_txd(pdcs, databufptr, bufcnt, flags | eot);
		desc_w++;
		/* Clear start of frame after first descriptor */
		flags &= ~D64_CTRL1_SOF;
	}
	pdcs->txin_numd[pdcs->tx_msg_start] += desc_w;

	return PDC_SUCCESS;
}

/**
 * pdc_tx_list_final() - Initiate DMA transfer of last frame written to tx
 * ring.
 * @pdcs:  PDC state for SPU to process the request
 *
 * Sets the index of the last descriptor written in both the rx and tx ring.
 *
 * Return: PDC_SUCCESS
 */
static int pdc_tx_list_final(struct pdc_state *pdcs)
{
	/*
	 * write barrier to ensure all register writes are complete
	 * before chip starts to process new request
	 */
	wmb();
	iowrite32(pdcs->rxout << 4, (void *)&pdcs->rxregs_64->ptr);
	iowrite32(pdcs->txout << 4, (void *)&pdcs->txregs_64->ptr);
	pdcs->pdc_requests++;

	return PDC_SUCCESS;
}

/**
 * pdc_rx_list_init() - Start a new receive descriptor list for a given PDC.
 * @pdcs:   PDC state for SPU handling request
 * @dst_sg: scatterlist providing rx buffers for response to be returned to
 *	    mailbox client
 * @ctx:    Opaque context for this request
 *
 * Posts a single receive descriptor to hold the metadata that precedes a
 * response. For example, with SPU-M, the metadata is a 32-byte DMA header and
 * an 8-byte BCM header. Moves the msg_start descriptor indexes for both tx and
 * rx to indicate the start of a new message.
 *
 * Return:  PDC_SUCCESS if successful
 *          < 0 if an error (e.g., rx ring is full)
 */
static int pdc_rx_list_init(struct pdc_state *pdcs, struct scatterlist *dst_sg,
			    void *ctx)
{
	u32 flags = 0;
	u32 rx_avail;
	u32 rx_pkt_cnt = 1;	/* Adding a single rx buffer */
	dma_addr_t daddr;
	void *vaddr;

	rx_avail = pdcs->nrxpost - NRXDACTIVE(pdcs->rxin, pdcs->rxout,
					      pdcs->nrxpost);
	if (unlikely(rx_pkt_cnt > rx_avail)) {
		pdcs->rxnobuf++;
		return -ENOSPC;
	}

	/* allocate a buffer for the dma rx status */
	vaddr = dma_pool_zalloc(pdcs->rx_buf_pool, GFP_ATOMIC, &daddr);
	if (!vaddr)
		return -ENOMEM;

	/*
	 * Update msg_start indexes for both tx and rx to indicate the start
	 * of a new sequence of descriptor indexes that contain the fragments
	 * of the same message.
	 */
	pdcs->rx_msg_start = pdcs->rxout;
	pdcs->tx_msg_start = pdcs->txout;

	/* This is always the first descriptor in the receive sequence */
	flags = D64_CTRL1_SOF;
	pdcs->rxin_numd[pdcs->rx_msg_start] = 1;

	if (unlikely(pdcs->rxout == (pdcs->nrxd - 1)))
		flags |= D64_CTRL1_EOT;

	pdcs->rxp_ctx[pdcs->rxout] = ctx;
	pdcs->dst_sg[pdcs->rxout] = dst_sg;
	pdcs->resp_hdr[pdcs->rxout] = vaddr;
	pdcs->resp_hdr_daddr[pdcs->rxout] = daddr;
	pdc_build_rxd(pdcs, daddr, pdcs->pdc_resp_hdr_len, flags);
	return PDC_SUCCESS;
}

/**
 * pdc_rx_list_sg_add() - Add the buffers in a scatterlist to the receive
 * descriptors for a given SPU. The caller must have already DMA mapped the
 * scatterlist.
 * @spu_idx:    Indicates which SPU the buffers are for
 * @sg:         Scatterlist whose buffers are added to the receive ring
 *
 * If a receive buffer in the scatterlist is larger than PDC_DMA_BUF_MAX,
 * multiple receive descriptors are written, each with a buffer <=
 * PDC_DMA_BUF_MAX.
 *
 * Return: PDC_SUCCESS if successful
 *         < 0 otherwise (e.g., receive ring is full)
 */
static int pdc_rx_list_sg_add(struct pdc_state *pdcs, struct scatterlist *sg)
{
	u32 flags = 0;
	u32 rx_avail;

	/*
	 * Num descriptors needed. Conservatively assume we need a descriptor
	 * for every entry from our starting point in the scatterlist.
	 */
	u32 num_desc;
	u32 desc_w = 0;	/* Number of tx descriptors written */
	u32 bufcnt;	/* Number of bytes of buffer pointed to by descriptor */
	dma_addr_t databufptr;	/* DMA address to put in descriptor */

	num_desc = (u32)sg_nents(sg);

	rx_avail = pdcs->nrxpost - NRXDACTIVE(pdcs->rxin, pdcs->rxout,
					      pdcs->nrxpost);
	if (unlikely(num_desc > rx_avail)) {
		pdcs->rxnobuf++;
		return -ENOSPC;
	}

	while (sg) {
		if (unlikely(pdcs->rxout == (pdcs->nrxd - 1)))
			flags = D64_CTRL1_EOT;
		else
			flags = 0;

		/*
		 * If sg buffer larger than PDC limit, split across
		 * multiple descriptors
		 */
		bufcnt = sg_dma_len(sg);
		databufptr = sg_dma_address(sg);
		while (bufcnt > PDC_DMA_BUF_MAX) {
			pdc_build_rxd(pdcs, databufptr, PDC_DMA_BUF_MAX, flags);
			desc_w++;
			bufcnt -= PDC_DMA_BUF_MAX;
			databufptr += PDC_DMA_BUF_MAX;
			if (unlikely(pdcs->rxout == (pdcs->nrxd - 1)))
				flags = D64_CTRL1_EOT;
			else
				flags = 0;
		}
		pdc_build_rxd(pdcs, databufptr, bufcnt, flags);
		desc_w++;
		sg = sg_next(sg);
	}
	pdcs->rxin_numd[pdcs->rx_msg_start] += desc_w;

	return PDC_SUCCESS;
}

/**
 * pdc_irq_handler() - Interrupt handler called in interrupt context.
 * @irq:      Interrupt number that has fired
 * @cookie:   PDC state for DMA engine that generated the interrupt
 *
 * We have to clear the device interrupt status flags here. So cache the
 * status for later use in the thread function. Other than that, just return
 * WAKE_THREAD to invoke the thread function.
 *
 * Return: IRQ_WAKE_THREAD if interrupt is ours
 *         IRQ_NONE otherwise
 */
static irqreturn_t pdc_irq_handler(int irq, void *cookie)
{
	struct pdc_state *pdcs = cookie;
	u32 intstatus = ioread32(pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);

	if (intstatus & PDC_XMTINTEN_0)
		set_bit(PDC_XMTINT_0, &pdcs->intstatus);
	if (intstatus & PDC_RCVINTEN_0)
		set_bit(PDC_RCVINT_0, &pdcs->intstatus);

	/* Clear interrupt flags in device */
	iowrite32(intstatus, pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);

	/* Wakeup IRQ thread */
	if (pdcs && (irq == pdcs->pdc_irq) && (intstatus & PDC_INTMASK))
		return IRQ_WAKE_THREAD;

	return IRQ_NONE;
}

/**
 * pdc_irq_thread() - Function invoked on deferred thread when a DMA tx has
 * completed or data is available to receive.
 * @irq:    Interrupt number
 * @cookie: PDC state for PDC that generated the interrupt
 *
 * On DMA tx complete, notify the mailbox client. On DMA rx complete, process
 * as many SPU response messages as are available and send each to the mailbox
 * client.
 *
 * Return: IRQ_HANDLED if we recognized and handled the interrupt
 *         IRQ_NONE otherwise
 */
static irqreturn_t pdc_irq_thread(int irq, void *cookie)
{
	struct pdc_state *pdcs = cookie;
	struct mbox_controller *mbc;
	struct mbox_chan *chan;
	bool tx_int;
	bool rx_int;
	int rx_status;
	struct brcm_message mssg;

	tx_int = test_and_clear_bit(PDC_XMTINT_0, &pdcs->intstatus);
	rx_int = test_and_clear_bit(PDC_RCVINT_0, &pdcs->intstatus);

	if (pdcs && (tx_int || rx_int)) {
		dev_dbg(&pdcs->pdev->dev,
			"%s() got irq %d with tx_int %s, rx_int %s",
			__func__, irq,
			tx_int ? "set" : "clear", rx_int ? "set" : "clear");

		mbc = &pdcs->mbc;
		chan = &mbc->chans[0];

		if (tx_int) {
			dev_dbg(&pdcs->pdev->dev, "%s(): tx done", __func__);
			/* only one frame in flight at a time */
			mbox_chan_txdone(chan, PDC_SUCCESS);
		}
		if (rx_int) {
			while (1) {
				/* Could be many frames ready */
				memset(&mssg, 0, sizeof(mssg));
				mssg.type = BRCM_MESSAGE_SPU;
				rx_status = pdc_receive(pdcs, &mssg);
				if (rx_status >= 0) {
					dev_dbg(&pdcs->pdev->dev,
						"%s(): invoking client rx cb",
						__func__);
					mbox_chan_received_data(chan, &mssg);
				} else {
					dev_dbg(&pdcs->pdev->dev,
						"%s(): no SPU response available",
						__func__);
					break;
				}
			}
		}
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

/**
 * pdc_ring_init() - Allocate DMA rings and initialize constant fields of
 * descriptors in one ringset.
 * @pdcs:    PDC instance state
 * @ringset: index of ringset being used
 *
 * Return: PDC_SUCCESS if ring initialized
 *         < 0 otherwise
 */
static int pdc_ring_init(struct pdc_state *pdcs, int ringset)
{
	int i;
	int err = PDC_SUCCESS;
	struct dma64 *dma_reg;
	struct device *dev = &pdcs->pdev->dev;
	struct pdc_ring_alloc tx;
	struct pdc_ring_alloc rx;

	/* Allocate tx ring */
	tx.vbase = dma_pool_zalloc(pdcs->ring_pool, GFP_KERNEL, &tx.dmabase);
	if (!tx.vbase) {
		err = -ENOMEM;
		goto done;
	}

	/* Allocate rx ring */
	rx.vbase = dma_pool_zalloc(pdcs->ring_pool, GFP_KERNEL, &rx.dmabase);
	if (!rx.vbase) {
		err = -ENOMEM;
		goto fail_dealloc;
	}

	dev_dbg(dev, " - base DMA addr of tx ring      %pad", &tx.dmabase);
	dev_dbg(dev, " - base virtual addr of tx ring  %p", tx.vbase);
	dev_dbg(dev, " - base DMA addr of rx ring      %pad", &rx.dmabase);
	dev_dbg(dev, " - base virtual addr of rx ring  %p", rx.vbase);

	/* lock after ring allocation to avoid scheduling while atomic */
	spin_lock(&pdcs->pdc_lock);

	memcpy(&pdcs->tx_ring_alloc, &tx, sizeof(tx));
	memcpy(&pdcs->rx_ring_alloc, &rx, sizeof(rx));

	pdcs->rxin = 0;
	pdcs->rx_msg_start = 0;
	pdcs->last_rx_curr = 0;
	pdcs->rxout = 0;
	pdcs->txin = 0;
	pdcs->tx_msg_start = 0;
	pdcs->txout = 0;

	/* Set descriptor array base addresses */
	pdcs->txd_64 = (struct dma64dd *)pdcs->tx_ring_alloc.vbase;
	pdcs->rxd_64 = (struct dma64dd *)pdcs->rx_ring_alloc.vbase;

	/* Tell device the base DMA address of each ring */
	dma_reg = &pdcs->regs->dmaregs[ringset];
	iowrite32(lower_32_bits(pdcs->tx_ring_alloc.dmabase),
		  (void *)&dma_reg->dmaxmt.addrlow);
	iowrite32(upper_32_bits(pdcs->tx_ring_alloc.dmabase),
		  (void *)&dma_reg->dmaxmt.addrhigh);

	iowrite32(lower_32_bits(pdcs->rx_ring_alloc.dmabase),
		  (void *)&dma_reg->dmarcv.addrlow);
	iowrite32(upper_32_bits(pdcs->rx_ring_alloc.dmabase),
		  (void *)&dma_reg->dmarcv.addrhigh);

	/* Initialize descriptors */
	for (i = 0; i < PDC_RING_ENTRIES; i++) {
		/* Every tx descriptor can be used for start of frame. */
		if (i != pdcs->ntxpost) {
			iowrite32(D64_CTRL1_SOF | D64_CTRL1_EOF,
				  (void *)&pdcs->txd_64[i].ctrl1);
		} else {
			/* Last descriptor in ringset. Set End of Table. */
			iowrite32(D64_CTRL1_SOF | D64_CTRL1_EOF |
				  D64_CTRL1_EOT,
				  (void *)&pdcs->txd_64[i].ctrl1);
		}

		/* Every rx descriptor can be used for start of frame */
		if (i != pdcs->nrxpost) {
			iowrite32(D64_CTRL1_SOF,
				  (void *)&pdcs->rxd_64[i].ctrl1);
		} else {
			/* Last descriptor in ringset. Set End of Table. */
			iowrite32(D64_CTRL1_SOF | D64_CTRL1_EOT,
				  (void *)&pdcs->rxd_64[i].ctrl1);
		}
	}
	spin_unlock(&pdcs->pdc_lock);
	return PDC_SUCCESS;

fail_dealloc:
	dma_pool_free(pdcs->ring_pool, tx.vbase, tx.dmabase);
done:
	return err;
}

static void pdc_ring_free(struct pdc_state *pdcs)
{
	if (pdcs->tx_ring_alloc.vbase) {
		dma_pool_free(pdcs->ring_pool, pdcs->tx_ring_alloc.vbase,
			      pdcs->tx_ring_alloc.dmabase);
		pdcs->tx_ring_alloc.vbase = NULL;
	}

	if (pdcs->rx_ring_alloc.vbase) {
		dma_pool_free(pdcs->ring_pool, pdcs->rx_ring_alloc.vbase,
			      pdcs->rx_ring_alloc.dmabase);
		pdcs->rx_ring_alloc.vbase = NULL;
	}
}

/**
 * pdc_send_data() - mailbox send_data function
 * @chan:	The mailbox channel on which the data is sent. The channel
 *              corresponds to a DMA ringset.
 * @data:	The mailbox message to be sent. The message must be a
 *              brcm_message structure.
 *
 * This function is registered as the send_data function for the mailbox
 * controller. From the destination scatterlist in the mailbox message, it
 * creates a sequence of receive descriptors in the rx ring. From the source
 * scatterlist, it creates a sequence of transmit descriptors in the tx ring.
 * After creating the descriptors, it writes the rx ptr and tx ptr registers to
 * initiate the DMA transfer.
 *
 * This function does the DMA map and unmap of the src and dst scatterlists in
 * the mailbox message.
 *
 * Return: 0 if successful
 *	   -ENOTSUPP if the mailbox message is a type this driver does not
 *			support
 *         < 0 if an error
 */
static int pdc_send_data(struct mbox_chan *chan, void *data)
{
	struct pdc_state *pdcs = chan->con_priv;
	struct device *dev = &pdcs->pdev->dev;
	struct brcm_message *mssg = data;
	int err = PDC_SUCCESS;
	int src_nent;
	int dst_nent;
	int nent;

	if (mssg->type != BRCM_MESSAGE_SPU)
		return -ENOTSUPP;

	src_nent = sg_nents(mssg->spu.src);
	if (src_nent) {
		nent = dma_map_sg(dev, mssg->spu.src, src_nent, DMA_TO_DEVICE);
		if (nent == 0)
			return -EIO;
	}

	dst_nent = sg_nents(mssg->spu.dst);
	if (dst_nent) {
		nent = dma_map_sg(dev, mssg->spu.dst, dst_nent,
				  DMA_FROM_DEVICE);
		if (nent == 0) {
			dma_unmap_sg(dev, mssg->spu.src, src_nent,
				     DMA_TO_DEVICE);
			return -EIO;
		}
	}

	spin_lock(&pdcs->pdc_lock);

	/* Create rx descriptors to SPU catch response */
	err = pdc_rx_list_init(pdcs, mssg->spu.dst, mssg->ctx);
	err |= pdc_rx_list_sg_add(pdcs, mssg->spu.dst);

	/* Create tx descriptors to submit SPU request */
	err |= pdc_tx_list_sg_add(pdcs, mssg->spu.src);
	err |= pdc_tx_list_final(pdcs);	/* initiate transfer */

	spin_unlock(&pdcs->pdc_lock);

	if (err)
		dev_err(&pdcs->pdev->dev,
			"%s failed with error %d", __func__, err);

	return err;
}

static int pdc_startup(struct mbox_chan *chan)
{
	return pdc_ring_init(chan->con_priv, PDC_RINGSET);
}

static void pdc_shutdown(struct mbox_chan *chan)
{
	struct pdc_state *pdcs = chan->con_priv;

	if (pdcs)
		dev_dbg(&pdcs->pdev->dev,
			"Shutdown mailbox channel for PDC %u", pdcs->pdc_idx);

	pdc_ring_free(pdcs);
}

/**
 * pdc_hw_init() - Use the given initialization parameters to initialize the
 * state for one of the PDCs.
 * @pdcs:  state of the PDC
 */
static
void pdc_hw_init(struct pdc_state *pdcs)
{
	struct platform_device *pdev;
	struct device *dev;
	struct dma64 *dma_reg;
	int ringset = PDC_RINGSET;

	pdev = pdcs->pdev;
	dev = &pdev->dev;

	dev_dbg(dev, "PDC %u initial values:", pdcs->pdc_idx);
	dev_dbg(dev, "state structure:                   %p",
		pdcs);
	dev_dbg(dev, " - base virtual addr of hw regs    %p",
		pdcs->pdc_reg_vbase);

	/* initialize data structures */
	pdcs->regs = (struct pdc_regs *)pdcs->pdc_reg_vbase;
	pdcs->txregs_64 = (struct dma64_regs *)
	    (void *)(((u8 *)pdcs->pdc_reg_vbase) +
		     PDC_TXREGS_OFFSET + (sizeof(struct dma64) * ringset));
	pdcs->rxregs_64 = (struct dma64_regs *)
	    (void *)(((u8 *)pdcs->pdc_reg_vbase) +
		     PDC_RXREGS_OFFSET + (sizeof(struct dma64) * ringset));

	pdcs->ntxd = PDC_RING_ENTRIES;
	pdcs->nrxd = PDC_RING_ENTRIES;
	pdcs->ntxpost = PDC_RING_ENTRIES - 1;
	pdcs->nrxpost = PDC_RING_ENTRIES - 1;
	pdcs->regs->intmask = 0;

	dma_reg = &pdcs->regs->dmaregs[ringset];
	iowrite32(0, (void *)&dma_reg->dmaxmt.ptr);
	iowrite32(0, (void *)&dma_reg->dmarcv.ptr);

	iowrite32(PDC_TX_CTL, (void *)&dma_reg->dmaxmt.control);

	iowrite32(PDC_RX_CTL + (pdcs->rx_status_len << 1),
		  (void *)&dma_reg->dmarcv.control);

	if (pdcs->pdc_resp_hdr_len == PDC_SPU2_RESP_HDR_LEN)
		iowrite32(PDC_CKSUM_CTRL,
			  pdcs->pdc_reg_vbase + PDC_CKSUM_CTRL_OFFSET);
}

/**
 * pdc_rx_buf_pool_create() - Pool of receive buffers used to catch the metadata
 * header returned with each response message.
 * @pdcs: PDC state structure
 *
 * The metadata is not returned to the mailbox client. So the PDC driver
 * manages these buffers.
 *
 * Return: PDC_SUCCESS
 *         -ENOMEM if pool creation fails
 */
static int pdc_rx_buf_pool_create(struct pdc_state *pdcs)
{
	struct platform_device *pdev;
	struct device *dev;

	pdev = pdcs->pdev;
	dev = &pdev->dev;

	pdcs->pdc_resp_hdr_len = pdcs->rx_status_len;
	if (pdcs->use_bcm_hdr)
		pdcs->pdc_resp_hdr_len += BCM_HDR_LEN;

	pdcs->rx_buf_pool = dma_pool_create("pdc rx bufs", dev,
					    pdcs->pdc_resp_hdr_len,
					    RX_BUF_ALIGN, 0);
	if (!pdcs->rx_buf_pool)
		return -ENOMEM;

	return PDC_SUCCESS;
}

/**
 * pdc_interrupts_init() - Initialize the interrupt configuration for a PDC and
 * specify a threaded IRQ handler for deferred handling of interrupts outside of
 * interrupt context.
 * @pdcs:   PDC state
 *
 * Set the interrupt mask for transmit and receive done.
 * Set the lazy interrupt frame count to generate an interrupt for just one pkt.
 *
 * Return:  PDC_SUCCESS
 *          <0 if threaded irq request fails
 */
static int pdc_interrupts_init(struct pdc_state *pdcs)
{
	struct platform_device *pdev = pdcs->pdev;
	struct device *dev = &pdev->dev;
	struct device_node *dn = pdev->dev.of_node;
	int err;

	pdcs->intstatus = 0;

	/* interrupt configuration */
	iowrite32(PDC_INTMASK, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET);
	iowrite32(PDC_LAZY_INT, pdcs->pdc_reg_vbase + PDC_RCVLAZY0_OFFSET);

	/* read irq from device tree */
	pdcs->pdc_irq = irq_of_parse_and_map(dn, 0);
	dev_dbg(dev, "pdc device %s irq %u for pdcs %p",
		dev_name(dev), pdcs->pdc_irq, pdcs);
	err = devm_request_threaded_irq(dev, pdcs->pdc_irq,
					pdc_irq_handler,
					pdc_irq_thread, 0, dev_name(dev), pdcs);
	if (err) {
		dev_err(dev, "threaded tx IRQ %u request failed with err %d\n",
			pdcs->pdc_irq, err);
		return err;
	}
	return PDC_SUCCESS;
}

static const struct mbox_chan_ops pdc_mbox_chan_ops = {
	.send_data = pdc_send_data,
	.startup = pdc_startup,
	.shutdown = pdc_shutdown
};

/**
 * pdc_mb_init() - Initialize the mailbox controller.
 * @pdcs:  PDC state
 *
 * Each PDC is a mailbox controller. Each ringset is a mailbox channel. Kernel
 * driver only uses one ringset and thus one mb channel. PDC uses the transmit
 * complete interrupt to determine when a mailbox message has successfully been
 * transmitted.
 *
 * Return: 0 on success
 *         < 0 if there is an allocation or registration failure
 */
static int pdc_mb_init(struct pdc_state *pdcs)
{
	struct device *dev = &pdcs->pdev->dev;
	struct mbox_controller *mbc;
	int chan_index;
	int err;

	mbc = &pdcs->mbc;
	mbc->dev = dev;
	mbc->ops = &pdc_mbox_chan_ops;
	mbc->num_chans = 1;
	mbc->chans = devm_kcalloc(dev, mbc->num_chans, sizeof(*mbc->chans),
				  GFP_KERNEL);
	if (!mbc->chans)
		return -ENOMEM;

	mbc->txdone_irq = true;
	mbc->txdone_poll = false;
	for (chan_index = 0; chan_index < mbc->num_chans; chan_index++)
		mbc->chans[chan_index].con_priv = pdcs;

	/* Register mailbox controller */
	err = mbox_controller_register(mbc);
	if (err) {
		dev_crit(dev,
			 "Failed to register PDC mailbox controller. Error %d.",
			 err);
		return err;
	}
	return 0;
}

/**
 * pdc_dt_read() - Read application-specific data from device tree.
 * @pdev:  Platform device
 * @pdcs:  PDC state
 *
 * Reads the number of bytes of receive status that precede each received frame.
 * Reads whether transmit and received frames should be preceded by an 8-byte
 * BCM header.
 *
 * Return: 0 if successful
 *         -ENODEV if device not available
 */
static int pdc_dt_read(struct platform_device *pdev, struct pdc_state *pdcs)
{
	struct device *dev = &pdev->dev;
	struct device_node *dn = pdev->dev.of_node;
	int err;

	err = of_property_read_u32(dn, "brcm,rx-status-len",
				   &pdcs->rx_status_len);
	if (err < 0)
		dev_err(dev,
			"%s failed to get DMA receive status length from device tree",
			__func__);

	pdcs->use_bcm_hdr = of_property_read_bool(dn, "brcm,use-bcm-hdr");

	return 0;
}

/**
 * pdc_probe() - Probe function for PDC driver.
 * @pdev:   PDC platform device
 *
 * Reserve and map register regions defined in device tree.
 * Allocate and initialize tx and rx DMA rings.
 * Initialize a mailbox controller for each PDC.
 *
 * Return: 0 if successful
 *         < 0 if an error
 */
static int pdc_probe(struct platform_device *pdev)
{
	int err = 0;
	struct device *dev = &pdev->dev;
	struct resource *pdc_regs;
	struct pdc_state *pdcs;

	/* PDC state for one SPU */
	pdcs = devm_kzalloc(dev, sizeof(*pdcs), GFP_KERNEL);
	if (!pdcs) {
		err = -ENOMEM;
		goto cleanup;
	}

	spin_lock_init(&pdcs->pdc_lock);
	pdcs->pdev = pdev;
	platform_set_drvdata(pdev, pdcs);
	pdcs->pdc_idx = pdcg.num_spu;
	pdcg.num_spu++;

	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
	if (err) {
		dev_warn(dev, "PDC device cannot perform DMA. Error %d.", err);
		goto cleanup;
	}

	/* Create DMA pool for tx ring */
	pdcs->ring_pool = dma_pool_create("pdc rings", dev, PDC_RING_SIZE,
					  RING_ALIGN, 0);
	if (!pdcs->ring_pool) {
		err = -ENOMEM;
		goto cleanup;
	}

	err = pdc_dt_read(pdev, pdcs);
	if (err)
		goto cleanup_ring_pool;

	pdc_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!pdc_regs) {
		err = -ENODEV;
		goto cleanup_ring_pool;
	}
	dev_dbg(dev, "PDC register region res.start = %pa, res.end = %pa",
		&pdc_regs->start, &pdc_regs->end);

	pdcs->pdc_reg_vbase = devm_ioremap_resource(&pdev->dev, pdc_regs);
	if (IS_ERR(pdcs->pdc_reg_vbase)) {
		err = PTR_ERR(pdcs->pdc_reg_vbase);
		dev_err(&pdev->dev, "Failed to map registers: %d\n", err);
		goto cleanup_ring_pool;
	}

	/* create rx buffer pool after dt read to know how big buffers are */
	err = pdc_rx_buf_pool_create(pdcs);
	if (err)
		goto cleanup_ring_pool;

	pdc_hw_init(pdcs);

	err = pdc_interrupts_init(pdcs);
	if (err)
		goto cleanup_buf_pool;

	/* Initialize mailbox controller */
	err = pdc_mb_init(pdcs);
	if (err)
		goto cleanup_buf_pool;

	pdcs->debugfs_stats = NULL;
	pdc_setup_debugfs(pdcs);

	dev_dbg(dev, "pdc_probe() successful");
	return PDC_SUCCESS;

cleanup_buf_pool:
	dma_pool_destroy(pdcs->rx_buf_pool);

cleanup_ring_pool:
	dma_pool_destroy(pdcs->ring_pool);

cleanup:
	return err;
}

static int pdc_remove(struct platform_device *pdev)
{
	struct pdc_state *pdcs = platform_get_drvdata(pdev);

	pdc_free_debugfs();

	mbox_controller_unregister(&pdcs->mbc);

	dma_pool_destroy(pdcs->rx_buf_pool);
	dma_pool_destroy(pdcs->ring_pool);
	return 0;
}

static const struct of_device_id pdc_mbox_of_match[] = {
	{.compatible = "brcm,iproc-pdc-mbox"},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pdc_mbox_of_match);

static struct platform_driver pdc_mbox_driver = {
	.probe = pdc_probe,
	.remove = pdc_remove,
	.driver = {
		   .name = "brcm-iproc-pdc-mbox",
		   .of_match_table = of_match_ptr(pdc_mbox_of_match),
		   },
};
module_platform_driver(pdc_mbox_driver);

MODULE_AUTHOR("Rob Rice <rob.rice@broadcom.com>");
MODULE_DESCRIPTION("Broadcom PDC mailbox driver");
MODULE_LICENSE("GPL v2");
