/*
 * Renesas USB DMA Controller Driver
 *
 * Copyright (C) 2015 Renesas Electronics Corporation
 *
 * based on rcar-dmac.c
 * Copyright (C) 2014 Renesas Electronics Inc.
 * Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include "../dmaengine.h"
#include "../virt-dma.h"

/*
 * struct usb_dmac_sg - Descriptor for a hardware transfer
 * @mem_addr: memory address
 * @size: transfer size in bytes
 */
struct usb_dmac_sg {
	dma_addr_t mem_addr;
	u32 size;
};

/*
 * struct usb_dmac_desc - USB DMA Transfer Descriptor
 * @vd: base virtual channel DMA transaction descriptor
 * @direction: direction of the DMA transfer
 * @sg_allocated_len: length of allocated sg
 * @sg_len: length of sg
 * @sg_index: index of sg
 * @residue: residue after the DMAC completed a transfer
 * @node: node for desc_got and desc_freed
 * @done_cookie: cookie after the DMAC completed a transfer
 * @sg: information for the transfer
 */
struct usb_dmac_desc {
	struct virt_dma_desc vd;
	enum dma_transfer_direction direction;
	unsigned int sg_allocated_len;
	unsigned int sg_len;
	unsigned int sg_index;
	u32 residue;
	struct list_head node;
	dma_cookie_t done_cookie;
	struct usb_dmac_sg sg[0];
};

#define to_usb_dmac_desc(vd)	container_of(vd, struct usb_dmac_desc, vd)

/*
 * struct usb_dmac_chan - USB DMA Controller Channel
 * @vc: base virtual DMA channel object
 * @iomem: channel I/O memory base
 * @index: index of this channel in the controller
 * @irq: irq number of this channel
 * @desc: the current descriptor
 * @descs_allocated: number of descriptors allocated
 * @desc_got: got descriptors
 * @desc_freed: freed descriptors after the DMAC completed a transfer
 */
struct usb_dmac_chan {
	struct virt_dma_chan vc;
	void __iomem *iomem;
	unsigned int index;
	int irq;
	struct usb_dmac_desc *desc;
	int descs_allocated;
	struct list_head desc_got;
	struct list_head desc_freed;
};

#define to_usb_dmac_chan(c) container_of(c, struct usb_dmac_chan, vc.chan)

/*
 * struct usb_dmac - USB DMA Controller
 * @engine: base DMA engine object
 * @dev: the hardware device
 * @iomem: remapped I/O memory base
 * @n_channels: number of available channels
 * @channels: array of DMAC channels
 */
struct usb_dmac {
	struct dma_device engine;
	struct device *dev;
	void __iomem *iomem;

	unsigned int n_channels;
	struct usb_dmac_chan *channels;
};

#define to_usb_dmac(d)		container_of(d, struct usb_dmac, engine)

/* -----------------------------------------------------------------------------
 * Registers
 */

#define USB_DMAC_CHAN_OFFSET(i)		(0x20 + 0x20 * (i))

#define USB_DMASWR			0x0008
#define USB_DMASWR_SWR			(1 << 0)
#define USB_DMAOR			0x0060
#define USB_DMAOR_AE			(1 << 2)
#define USB_DMAOR_DME			(1 << 0)

#define USB_DMASAR			0x0000
#define USB_DMADAR			0x0004
#define USB_DMATCR			0x0008
#define USB_DMATCR_MASK			0x00ffffff
#define USB_DMACHCR			0x0014
#define USB_DMACHCR_FTE			(1 << 24)
#define USB_DMACHCR_NULLE		(1 << 16)
#define USB_DMACHCR_NULL		(1 << 12)
#define USB_DMACHCR_TS_8B		((0 << 7) | (0 << 6))
#define USB_DMACHCR_TS_16B		((0 << 7) | (1 << 6))
#define USB_DMACHCR_TS_32B		((1 << 7) | (0 << 6))
#define USB_DMACHCR_IE			(1 << 5)
#define USB_DMACHCR_SP			(1 << 2)
#define USB_DMACHCR_TE			(1 << 1)
#define USB_DMACHCR_DE			(1 << 0)
#define USB_DMATEND			0x0018

/* Hardcode the xfer_shift to 5 (32bytes) */
#define USB_DMAC_XFER_SHIFT	5
#define USB_DMAC_XFER_SIZE	(1 << USB_DMAC_XFER_SHIFT)
#define USB_DMAC_CHCR_TS	USB_DMACHCR_TS_32B
#define USB_DMAC_SLAVE_BUSWIDTH	DMA_SLAVE_BUSWIDTH_32_BYTES

/* for descriptors */
#define USB_DMAC_INITIAL_NR_DESC	16
#define USB_DMAC_INITIAL_NR_SG		8

/* -----------------------------------------------------------------------------
 * Device access
 */

static void usb_dmac_write(struct usb_dmac *dmac, u32 reg, u32 data)
{
	writel(data, dmac->iomem + reg);
}

static u32 usb_dmac_read(struct usb_dmac *dmac, u32 reg)
{
	return readl(dmac->iomem + reg);
}

static u32 usb_dmac_chan_read(struct usb_dmac_chan *chan, u32 reg)
{
	return readl(chan->iomem + reg);
}

static void usb_dmac_chan_write(struct usb_dmac_chan *chan, u32 reg, u32 data)
{
	writel(data, chan->iomem + reg);
}

/* -----------------------------------------------------------------------------
 * Initialization and configuration
 */

static bool usb_dmac_chan_is_busy(struct usb_dmac_chan *chan)
{
	u32 chcr = usb_dmac_chan_read(chan, USB_DMACHCR);

	return (chcr & (USB_DMACHCR_DE | USB_DMACHCR_TE)) == USB_DMACHCR_DE;
}

static u32 usb_dmac_calc_tend(u32 size)
{
	/*
	 * Please refer to the Figure "Example of Final Transaction Valid
	 * Data Transfer Enable (EDTEN) Setting" in the data sheet.
	 */
	return 0xffffffff << (32 - (size % USB_DMAC_XFER_SIZE ?	:
						USB_DMAC_XFER_SIZE));
}

/* This function is already held by vc.lock */
static void usb_dmac_chan_start_sg(struct usb_dmac_chan *chan,
				   unsigned int index)
{
	struct usb_dmac_desc *desc = chan->desc;
	struct usb_dmac_sg *sg = desc->sg + index;
	dma_addr_t src_addr = 0, dst_addr = 0;

	WARN_ON_ONCE(usb_dmac_chan_is_busy(chan));

	if (desc->direction == DMA_DEV_TO_MEM)
		dst_addr = sg->mem_addr;
	else
		src_addr = sg->mem_addr;

	dev_dbg(chan->vc.chan.device->dev,
		"chan%u: queue sg %p: %u@%pad -> %pad\n",
		chan->index, sg, sg->size, &src_addr, &dst_addr);

	usb_dmac_chan_write(chan, USB_DMASAR, src_addr & 0xffffffff);
	usb_dmac_chan_write(chan, USB_DMADAR, dst_addr & 0xffffffff);
	usb_dmac_chan_write(chan, USB_DMATCR,
			    DIV_ROUND_UP(sg->size, USB_DMAC_XFER_SIZE));
	usb_dmac_chan_write(chan, USB_DMATEND, usb_dmac_calc_tend(sg->size));

	usb_dmac_chan_write(chan, USB_DMACHCR, USB_DMAC_CHCR_TS |
			USB_DMACHCR_NULLE | USB_DMACHCR_IE | USB_DMACHCR_DE);
}

/* This function is already held by vc.lock */
static void usb_dmac_chan_start_desc(struct usb_dmac_chan *chan)
{
	struct virt_dma_desc *vd;

	vd = vchan_next_desc(&chan->vc);
	if (!vd) {
		chan->desc = NULL;
		return;
	}

	/*
	 * Remove this request from vc->desc_issued. Otherwise, this driver
	 * will get the previous value from vchan_next_desc() after a transfer
	 * was completed.
	 */
	list_del(&vd->node);

	chan->desc = to_usb_dmac_desc(vd);
	chan->desc->sg_index = 0;
	usb_dmac_chan_start_sg(chan, 0);
}

static int usb_dmac_init(struct usb_dmac *dmac)
{
	u16 dmaor;

	/* Clear all channels and enable the DMAC globally. */
	usb_dmac_write(dmac, USB_DMAOR, USB_DMAOR_DME);

	dmaor = usb_dmac_read(dmac, USB_DMAOR);
	if ((dmaor & (USB_DMAOR_AE | USB_DMAOR_DME)) != USB_DMAOR_DME) {
		dev_warn(dmac->dev, "DMAOR initialization failed.\n");
		return -EIO;
	}

	return 0;
}

/* -----------------------------------------------------------------------------
 * Descriptors allocation and free
 */
static int usb_dmac_desc_alloc(struct usb_dmac_chan *chan, unsigned int sg_len,
			       gfp_t gfp)
{
	struct usb_dmac_desc *desc;
	unsigned long flags;

	desc = kzalloc(sizeof(*desc) + sg_len * sizeof(desc->sg[0]), gfp);
	if (!desc)
		return -ENOMEM;

	desc->sg_allocated_len = sg_len;
	INIT_LIST_HEAD(&desc->node);

	spin_lock_irqsave(&chan->vc.lock, flags);
	list_add_tail(&desc->node, &chan->desc_freed);
	spin_unlock_irqrestore(&chan->vc.lock, flags);

	return 0;
}

static void usb_dmac_desc_free(struct usb_dmac_chan *chan)
{
	struct usb_dmac_desc *desc, *_desc;
	LIST_HEAD(list);

	list_splice_init(&chan->desc_freed, &list);
	list_splice_init(&chan->desc_got, &list);

	list_for_each_entry_safe(desc, _desc, &list, node) {
		list_del(&desc->node);
		kfree(desc);
	}
	chan->descs_allocated = 0;
}

static struct usb_dmac_desc *usb_dmac_desc_get(struct usb_dmac_chan *chan,
					       unsigned int sg_len, gfp_t gfp)
{
	struct usb_dmac_desc *desc = NULL;
	unsigned long flags;

	/* Get a freed descritpor */
	spin_lock_irqsave(&chan->vc.lock, flags);
	list_for_each_entry(desc, &chan->desc_freed, node) {
		if (sg_len <= desc->sg_allocated_len) {
			list_move_tail(&desc->node, &chan->desc_got);
			spin_unlock_irqrestore(&chan->vc.lock, flags);
			return desc;
		}
	}
	spin_unlock_irqrestore(&chan->vc.lock, flags);

	/* Allocate a new descriptor */
	if (!usb_dmac_desc_alloc(chan, sg_len, gfp)) {
		/* If allocated the desc, it was added to tail of the list */
		spin_lock_irqsave(&chan->vc.lock, flags);
		desc = list_last_entry(&chan->desc_freed, struct usb_dmac_desc,
				       node);
		list_move_tail(&desc->node, &chan->desc_got);
		spin_unlock_irqrestore(&chan->vc.lock, flags);
		return desc;
	}

	return NULL;
}

static void usb_dmac_desc_put(struct usb_dmac_chan *chan,
			      struct usb_dmac_desc *desc)
{
	unsigned long flags;

	spin_lock_irqsave(&chan->vc.lock, flags);
	list_move_tail(&desc->node, &chan->desc_freed);
	spin_unlock_irqrestore(&chan->vc.lock, flags);
}

/* -----------------------------------------------------------------------------
 * Stop and reset
 */

static void usb_dmac_soft_reset(struct usb_dmac_chan *uchan)
{
	struct dma_chan *chan = &uchan->vc.chan;
	struct usb_dmac *dmac = to_usb_dmac(chan->device);
	int i;

	/* Don't issue soft reset if any one of channels is busy */
	for (i = 0; i < dmac->n_channels; ++i) {
		if (usb_dmac_chan_is_busy(uchan))
			return;
	}

	usb_dmac_write(dmac, USB_DMAOR, 0);
	usb_dmac_write(dmac, USB_DMASWR, USB_DMASWR_SWR);
	udelay(100);
	usb_dmac_write(dmac, USB_DMASWR, 0);
	usb_dmac_write(dmac, USB_DMAOR, 1);
}

static void usb_dmac_chan_halt(struct usb_dmac_chan *chan)
{
	u32 chcr = usb_dmac_chan_read(chan, USB_DMACHCR);

	chcr &= ~(USB_DMACHCR_IE | USB_DMACHCR_TE | USB_DMACHCR_DE);
	usb_dmac_chan_write(chan, USB_DMACHCR, chcr);

	usb_dmac_soft_reset(chan);
}

static void usb_dmac_stop(struct usb_dmac *dmac)
{
	usb_dmac_write(dmac, USB_DMAOR, 0);
}

/* -----------------------------------------------------------------------------
 * DMA engine operations
 */

static int usb_dmac_alloc_chan_resources(struct dma_chan *chan)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	int ret;

	while (uchan->descs_allocated < USB_DMAC_INITIAL_NR_DESC) {
		ret = usb_dmac_desc_alloc(uchan, USB_DMAC_INITIAL_NR_SG,
					  GFP_KERNEL);
		if (ret < 0) {
			usb_dmac_desc_free(uchan);
			return ret;
		}
		uchan->descs_allocated++;
	}

	return pm_runtime_get_sync(chan->device->dev);
}

static void usb_dmac_free_chan_resources(struct dma_chan *chan)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	unsigned long flags;

	/* Protect against ISR */
	spin_lock_irqsave(&uchan->vc.lock, flags);
	usb_dmac_chan_halt(uchan);
	spin_unlock_irqrestore(&uchan->vc.lock, flags);

	usb_dmac_desc_free(uchan);
	vchan_free_chan_resources(&uchan->vc);

	pm_runtime_put(chan->device->dev);
}

static struct dma_async_tx_descriptor *
usb_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
		       unsigned int sg_len, enum dma_transfer_direction dir,
		       unsigned long dma_flags, void *context)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	struct usb_dmac_desc *desc;
	struct scatterlist *sg;
	int i;

	if (!sg_len) {
		dev_warn(chan->device->dev,
			 "%s: bad parameter: len=%d\n", __func__, sg_len);
		return NULL;
	}

	desc = usb_dmac_desc_get(uchan, sg_len, GFP_NOWAIT);
	if (!desc)
		return NULL;

	desc->direction = dir;
	desc->sg_len = sg_len;
	for_each_sg(sgl, sg, sg_len, i) {
		desc->sg[i].mem_addr = sg_dma_address(sg);
		desc->sg[i].size = sg_dma_len(sg);
	}

	return vchan_tx_prep(&uchan->vc, &desc->vd, dma_flags);
}

static int usb_dmac_chan_terminate_all(struct dma_chan *chan)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	struct usb_dmac_desc *desc;
	unsigned long flags;
	LIST_HEAD(head);
	LIST_HEAD(list);

	spin_lock_irqsave(&uchan->vc.lock, flags);
	usb_dmac_chan_halt(uchan);
	vchan_get_all_descriptors(&uchan->vc, &head);
	if (uchan->desc)
		uchan->desc = NULL;
	list_splice_init(&uchan->desc_got, &list);
	list_for_each_entry(desc, &list, node)
		list_move_tail(&desc->node, &uchan->desc_freed);
	spin_unlock_irqrestore(&uchan->vc.lock, flags);
	vchan_dma_desc_free_list(&uchan->vc, &head);

	return 0;
}

static unsigned int usb_dmac_get_current_residue(struct usb_dmac_chan *chan,
						 struct usb_dmac_desc *desc,
						 int sg_index)
{
	struct usb_dmac_sg *sg = desc->sg + sg_index;
	u32 mem_addr = sg->mem_addr & 0xffffffff;
	unsigned int residue = sg->size;

	/*
	 * We cannot use USB_DMATCR to calculate residue because USB_DMATCR
	 * has unsuited value to calculate.
	 */
	if (desc->direction == DMA_DEV_TO_MEM)
		residue -= usb_dmac_chan_read(chan, USB_DMADAR) - mem_addr;
	else
		residue -= usb_dmac_chan_read(chan, USB_DMASAR) - mem_addr;

	return residue;
}

static u32 usb_dmac_chan_get_residue_if_complete(struct usb_dmac_chan *chan,
						 dma_cookie_t cookie)
{
	struct usb_dmac_desc *desc;
	u32 residue = 0;

	list_for_each_entry_reverse(desc, &chan->desc_freed, node) {
		if (desc->done_cookie == cookie) {
			residue = desc->residue;
			break;
		}
	}

	return residue;
}

static u32 usb_dmac_chan_get_residue(struct usb_dmac_chan *chan,
				     dma_cookie_t cookie)
{
	u32 residue = 0;
	struct virt_dma_desc *vd;
	struct usb_dmac_desc *desc = chan->desc;
	int i;

	if (!desc) {
		vd = vchan_find_desc(&chan->vc, cookie);
		if (!vd)
			return 0;
		desc = to_usb_dmac_desc(vd);
	}

	/* Compute the size of all usb_dmac_sg still to be transferred */
	for (i = desc->sg_index + 1; i < desc->sg_len; i++)
		residue += desc->sg[i].size;

	/* Add the residue for the current sg */
	residue += usb_dmac_get_current_residue(chan, desc, desc->sg_index);

	return residue;
}

static enum dma_status usb_dmac_tx_status(struct dma_chan *chan,
					  dma_cookie_t cookie,
					  struct dma_tx_state *txstate)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	enum dma_status status;
	unsigned int residue = 0;
	unsigned long flags;

	status = dma_cookie_status(chan, cookie, txstate);
	/* a client driver will get residue after DMA_COMPLETE */
	if (!txstate)
		return status;

	spin_lock_irqsave(&uchan->vc.lock, flags);
	if (status == DMA_COMPLETE)
		residue = usb_dmac_chan_get_residue_if_complete(uchan, cookie);
	else
		residue = usb_dmac_chan_get_residue(uchan, cookie);
	spin_unlock_irqrestore(&uchan->vc.lock, flags);

	dma_set_residue(txstate, residue);

	return status;
}

static void usb_dmac_issue_pending(struct dma_chan *chan)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	unsigned long flags;

	spin_lock_irqsave(&uchan->vc.lock, flags);
	if (vchan_issue_pending(&uchan->vc) && !uchan->desc)
		usb_dmac_chan_start_desc(uchan);
	spin_unlock_irqrestore(&uchan->vc.lock, flags);
}

static void usb_dmac_virt_desc_free(struct virt_dma_desc *vd)
{
	struct usb_dmac_desc *desc = to_usb_dmac_desc(vd);
	struct usb_dmac_chan *chan = to_usb_dmac_chan(vd->tx.chan);

	usb_dmac_desc_put(chan, desc);
}

/* -----------------------------------------------------------------------------
 * IRQ handling
 */

static void usb_dmac_isr_transfer_end(struct usb_dmac_chan *chan)
{
	struct usb_dmac_desc *desc = chan->desc;

	BUG_ON(!desc);

	if (++desc->sg_index < desc->sg_len) {
		usb_dmac_chan_start_sg(chan, desc->sg_index);
	} else {
		desc->residue = usb_dmac_get_current_residue(chan, desc,
							desc->sg_index - 1);
		desc->done_cookie = desc->vd.tx.cookie;
		vchan_cookie_complete(&desc->vd);

		/* Restart the next transfer if this driver has a next desc */
		usb_dmac_chan_start_desc(chan);
	}
}

static irqreturn_t usb_dmac_isr_channel(int irq, void *dev)
{
	struct usb_dmac_chan *chan = dev;
	irqreturn_t ret = IRQ_NONE;
	u32 mask = USB_DMACHCR_TE;
	u32 check_bits = USB_DMACHCR_TE | USB_DMACHCR_SP;
	u32 chcr;

	spin_lock(&chan->vc.lock);

	chcr = usb_dmac_chan_read(chan, USB_DMACHCR);
	if (chcr & check_bits)
		mask |= USB_DMACHCR_DE | check_bits;
	if (chcr & USB_DMACHCR_NULL) {
		/* An interruption of TE will happen after we set FTE */
		mask |= USB_DMACHCR_NULL;
		chcr |= USB_DMACHCR_FTE;
		ret |= IRQ_HANDLED;
	}
	usb_dmac_chan_write(chan, USB_DMACHCR, chcr & ~mask);

	if (chcr & check_bits) {
		usb_dmac_isr_transfer_end(chan);
		ret |= IRQ_HANDLED;
	}

	spin_unlock(&chan->vc.lock);

	return ret;
}

/* -----------------------------------------------------------------------------
 * OF xlate and channel filter
 */

static bool usb_dmac_chan_filter(struct dma_chan *chan, void *arg)
{
	struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan);
	struct of_phandle_args *dma_spec = arg;

	if (dma_spec->np != chan->device->dev->of_node)
		return false;

	/* USB-DMAC should be used with fixed usb controller's FIFO */
	if (uchan->index != dma_spec->args[0])
		return false;

	return true;
}

static struct dma_chan *usb_dmac_of_xlate(struct of_phandle_args *dma_spec,
					  struct of_dma *ofdma)
{
	struct usb_dmac_chan *uchan;
	struct dma_chan *chan;
	dma_cap_mask_t mask;

	if (dma_spec->args_count != 1)
		return NULL;

	/* Only slave DMA channels can be allocated via DT */
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	chan = dma_request_channel(mask, usb_dmac_chan_filter, dma_spec);
	if (!chan)
		return NULL;

	uchan = to_usb_dmac_chan(chan);

	return chan;
}

/* -----------------------------------------------------------------------------
 * Power management
 */

static int usb_dmac_runtime_suspend(struct device *dev)
{
	struct usb_dmac *dmac = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < dmac->n_channels; ++i)
		usb_dmac_chan_halt(&dmac->channels[i]);

	return 0;
}

static int usb_dmac_runtime_resume(struct device *dev)
{
	struct usb_dmac *dmac = dev_get_drvdata(dev);

	return usb_dmac_init(dmac);
}

static const struct dev_pm_ops usb_dmac_pm = {
	SET_RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume,
			   NULL)
};

/* -----------------------------------------------------------------------------
 * Probe and remove
 */

static int usb_dmac_chan_probe(struct usb_dmac *dmac,
			       struct usb_dmac_chan *uchan,
			       unsigned int index)
{
	struct platform_device *pdev = to_platform_device(dmac->dev);
	char pdev_irqname[5];
	char *irqname;
	int ret;

	uchan->index = index;
	uchan->iomem = dmac->iomem + USB_DMAC_CHAN_OFFSET(index);

	/* Request the channel interrupt. */
	sprintf(pdev_irqname, "ch%u", index);
	uchan->irq = platform_get_irq_byname(pdev, pdev_irqname);
	if (uchan->irq < 0) {
		dev_err(dmac->dev, "no IRQ specified for channel %u\n", index);
		return -ENODEV;
	}

	irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u",
				 dev_name(dmac->dev), index);
	if (!irqname)
		return -ENOMEM;

	ret = devm_request_irq(dmac->dev, uchan->irq, usb_dmac_isr_channel,
			       IRQF_SHARED, irqname, uchan);
	if (ret) {
		dev_err(dmac->dev, "failed to request IRQ %u (%d)\n",
			uchan->irq, ret);
		return ret;
	}

	uchan->vc.desc_free = usb_dmac_virt_desc_free;
	vchan_init(&uchan->vc, &dmac->engine);
	INIT_LIST_HEAD(&uchan->desc_freed);
	INIT_LIST_HEAD(&uchan->desc_got);

	return 0;
}

static int usb_dmac_parse_of(struct device *dev, struct usb_dmac *dmac)
{
	struct device_node *np = dev->of_node;
	int ret;

	ret = of_property_read_u32(np, "dma-channels", &dmac->n_channels);
	if (ret < 0) {
		dev_err(dev, "unable to read dma-channels property\n");
		return ret;
	}

	if (dmac->n_channels <= 0 || dmac->n_channels >= 100) {
		dev_err(dev, "invalid number of channels %u\n",
			dmac->n_channels);
		return -EINVAL;
	}

	return 0;
}

static int usb_dmac_probe(struct platform_device *pdev)
{
	const enum dma_slave_buswidth widths = USB_DMAC_SLAVE_BUSWIDTH;
	struct dma_device *engine;
	struct usb_dmac *dmac;
	struct resource *mem;
	unsigned int i;
	int ret;

	dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
	if (!dmac)
		return -ENOMEM;

	dmac->dev = &pdev->dev;
	platform_set_drvdata(pdev, dmac);

	ret = usb_dmac_parse_of(&pdev->dev, dmac);
	if (ret < 0)
		return ret;

	dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels,
				      sizeof(*dmac->channels), GFP_KERNEL);
	if (!dmac->channels)
		return -ENOMEM;

	/* Request resources. */
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dmac->iomem = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(dmac->iomem))
		return PTR_ERR(dmac->iomem);

	/* Enable runtime PM and initialize the device. */
	pm_runtime_enable(&pdev->dev);
	ret = pm_runtime_get_sync(&pdev->dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "runtime PM get sync failed (%d)\n", ret);
		return ret;
	}

	ret = usb_dmac_init(dmac);
	pm_runtime_put(&pdev->dev);

	if (ret) {
		dev_err(&pdev->dev, "failed to reset device\n");
		goto error;
	}

	/* Initialize the channels. */
	INIT_LIST_HEAD(&dmac->engine.channels);

	for (i = 0; i < dmac->n_channels; ++i) {
		ret = usb_dmac_chan_probe(dmac, &dmac->channels[i], i);
		if (ret < 0)
			goto error;
	}

	/* Register the DMAC as a DMA provider for DT. */
	ret = of_dma_controller_register(pdev->dev.of_node, usb_dmac_of_xlate,
					 NULL);
	if (ret < 0)
		goto error;

	/*
	 * Register the DMA engine device.
	 *
	 * Default transfer size of 32 bytes requires 32-byte alignment.
	 */
	engine = &dmac->engine;
	dma_cap_set(DMA_SLAVE, engine->cap_mask);

	engine->dev = &pdev->dev;

	engine->src_addr_widths = widths;
	engine->dst_addr_widths = widths;
	engine->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
	engine->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;

	engine->device_alloc_chan_resources = usb_dmac_alloc_chan_resources;
	engine->device_free_chan_resources = usb_dmac_free_chan_resources;
	engine->device_prep_slave_sg = usb_dmac_prep_slave_sg;
	engine->device_terminate_all = usb_dmac_chan_terminate_all;
	engine->device_tx_status = usb_dmac_tx_status;
	engine->device_issue_pending = usb_dmac_issue_pending;

	ret = dma_async_device_register(engine);
	if (ret < 0)
		goto error;

	return 0;

error:
	of_dma_controller_free(pdev->dev.of_node);
	pm_runtime_disable(&pdev->dev);
	return ret;
}

static void usb_dmac_chan_remove(struct usb_dmac *dmac,
				 struct usb_dmac_chan *uchan)
{
	usb_dmac_chan_halt(uchan);
	devm_free_irq(dmac->dev, uchan->irq, uchan);
}

static int usb_dmac_remove(struct platform_device *pdev)
{
	struct usb_dmac *dmac = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < dmac->n_channels; ++i)
		usb_dmac_chan_remove(dmac, &dmac->channels[i]);
	of_dma_controller_free(pdev->dev.of_node);
	dma_async_device_unregister(&dmac->engine);

	pm_runtime_disable(&pdev->dev);

	return 0;
}

static void usb_dmac_shutdown(struct platform_device *pdev)
{
	struct usb_dmac *dmac = platform_get_drvdata(pdev);

	usb_dmac_stop(dmac);
}

static const struct of_device_id usb_dmac_of_ids[] = {
	{ .compatible = "renesas,usb-dmac", },
	{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, usb_dmac_of_ids);

static struct platform_driver usb_dmac_driver = {
	.driver		= {
		.pm	= &usb_dmac_pm,
		.name	= "usb-dmac",
		.of_match_table = usb_dmac_of_ids,
	},
	.probe		= usb_dmac_probe,
	.remove		= usb_dmac_remove,
	.shutdown	= usb_dmac_shutdown,
};

module_platform_driver(usb_dmac_driver);

MODULE_DESCRIPTION("Renesas USB DMA Controller Driver");
MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
MODULE_LICENSE("GPL v2");
