// SPDX-License-Identifier: GPL-2.0
/*
 * mtu3_gadget_ep0.c - MediaTek USB3 DRD peripheral driver ep0 handling
 *
 * Copyright (c) 2016 MediaTek Inc.
 *
 * Author:  Chunfeng.Yun <chunfeng.yun@mediatek.com>
 */

#include <linux/iopoll.h>
#include <linux/usb/composite.h>

#include "mtu3.h"
#include "mtu3_debug.h"
#include "mtu3_trace.h"

/* ep0 is always mtu3->in_eps[0] */
#define	next_ep0_request(mtu)	next_request((mtu)->ep0)

/* for high speed test mode; see USB 2.0 spec 7.1.20 */
static const u8 mtu3_test_packet[53] = {
	/* implicit SYNC then DATA0 to start */

	/* JKJKJKJK x9 */
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	/* JJKKJJKK x8 */
	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
	/* JJJJKKKK x8 */
	0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
	/* JJJJJJJKKKKKKK x8 */
	0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	/* JJJJJJJK x8 */
	0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
	/* JKKKKKKK x10, JK */
	0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e,
	/* implicit CRC16 then EOP to end */
};

static char *decode_ep0_state(struct mtu3 *mtu)
{
	switch (mtu->ep0_state) {
	case MU3D_EP0_STATE_SETUP:
		return "SETUP";
	case MU3D_EP0_STATE_TX:
		return "IN";
	case MU3D_EP0_STATE_RX:
		return "OUT";
	case MU3D_EP0_STATE_TX_END:
		return "TX-END";
	case MU3D_EP0_STATE_STALL:
		return "STALL";
	default:
		return "??";
	}
}

static void ep0_req_giveback(struct mtu3 *mtu, struct usb_request *req)
{
	mtu3_req_complete(mtu->ep0, req, 0);
}

static int
forward_to_driver(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
__releases(mtu->lock)
__acquires(mtu->lock)
{
	int ret;

	if (!mtu->gadget_driver || !mtu->async_callbacks)
		return -EOPNOTSUPP;

	spin_unlock(&mtu->lock);
	ret = mtu->gadget_driver->setup(&mtu->g, setup);
	spin_lock(&mtu->lock);

	dev_dbg(mtu->dev, "%s ret %d\n", __func__, ret);
	return ret;
}

static void ep0_write_fifo(struct mtu3_ep *mep, const u8 *src, u16 len)
{
	void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
	u16 index = 0;

	dev_dbg(mep->mtu->dev, "%s: ep%din, len=%d, buf=%p\n",
		__func__, mep->epnum, len, src);

	if (len >= 4) {
		iowrite32_rep(fifo, src, len >> 2);
		index = len & ~0x03;
	}
	if (len & 0x02) {
		writew(*(u16 *)&src[index], fifo);
		index += 2;
	}
	if (len & 0x01)
		writeb(src[index], fifo);
}

static void ep0_read_fifo(struct mtu3_ep *mep, u8 *dst, u16 len)
{
	void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
	u32 value;
	u16 index = 0;

	dev_dbg(mep->mtu->dev, "%s: ep%dout len=%d buf=%p\n",
		 __func__, mep->epnum, len, dst);

	if (len >= 4) {
		ioread32_rep(fifo, dst, len >> 2);
		index = len & ~0x03;
	}
	if (len & 0x3) {
		value = readl(fifo);
		memcpy(&dst[index], &value, len & 0x3);
	}

}

static void ep0_load_test_packet(struct mtu3 *mtu)
{
	/*
	 * because the length of test packet is less than max packet of HS ep0,
	 * write it into fifo directly.
	 */
	ep0_write_fifo(mtu->ep0, mtu3_test_packet, sizeof(mtu3_test_packet));
}

/*
 * A. send STALL for setup transfer without data stage:
 *		set SENDSTALL and SETUPPKTRDY at the same time;
 * B. send STALL for other cases:
 *		set SENDSTALL only.
 */
static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy)
{
	struct mtu3 *mtu = mep0->mtu;
	void __iomem *mbase = mtu->mac_base;
	u32 csr;

	/* EP0_SENTSTALL is W1C */
	csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
	if (set)
		csr |= EP0_SENDSTALL | pktrdy;
	else
		csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL;
	mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);

	mtu->delayed_status = false;
	mtu->ep0_state = MU3D_EP0_STATE_SETUP;

	dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n",
		set ? "SEND" : "CLEAR", decode_ep0_state(mtu));
}

static void ep0_do_status_stage(struct mtu3 *mtu)
{
	void __iomem *mbase = mtu->mac_base;
	u32 value;

	value = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
	mtu3_writel(mbase, U3D_EP0CSR, value | EP0_SETUPPKTRDY | EP0_DATAEND);
}

static int ep0_queue(struct mtu3_ep *mep0, struct mtu3_request *mreq);

static void ep0_dummy_complete(struct usb_ep *ep, struct usb_request *req)
{}

static void ep0_set_sel_complete(struct usb_ep *ep, struct usb_request *req)
{
	struct mtu3_request *mreq;
	struct mtu3 *mtu;
	struct usb_set_sel_req sel;

	memcpy(&sel, req->buf, sizeof(sel));

	mreq = to_mtu3_request(req);
	mtu = mreq->mtu;
	dev_dbg(mtu->dev, "u1sel:%d, u1pel:%d, u2sel:%d, u2pel:%d\n",
		sel.u1_sel, sel.u1_pel, sel.u2_sel, sel.u2_pel);
}

/* queue data stage to handle 6 byte SET_SEL request */
static int ep0_set_sel(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
{
	int ret;
	u16 length = le16_to_cpu(setup->wLength);

	if (unlikely(length != 6)) {
		dev_err(mtu->dev, "%s wrong wLength:%d\n",
			__func__, length);
		return -EINVAL;
	}

	mtu->ep0_req.mep = mtu->ep0;
	mtu->ep0_req.request.length = 6;
	mtu->ep0_req.request.buf = mtu->setup_buf;
	mtu->ep0_req.request.complete = ep0_set_sel_complete;
	ret = ep0_queue(mtu->ep0, &mtu->ep0_req);

	return ret < 0 ? ret : 1;
}

static int
ep0_get_status(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
{
	struct mtu3_ep *mep = NULL;
	int handled = 1;
	u8 result[2] = {0, 0};
	u8 epnum = 0;
	int is_in;

	switch (setup->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED;
		result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;

		if (mtu->g.speed >= USB_SPEED_SUPER) {
			result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED;
			result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED;
		}

		dev_dbg(mtu->dev, "%s result=%x, U1=%x, U2=%x\n", __func__,
			result[0], mtu->u1_enable, mtu->u2_enable);

		break;
	case USB_RECIP_INTERFACE:
		/* status of function remote wakeup, forward request */
		handled = 0;
		break;
	case USB_RECIP_ENDPOINT:
		epnum = (u8) le16_to_cpu(setup->wIndex);
		is_in = epnum & USB_DIR_IN;
		epnum &= USB_ENDPOINT_NUMBER_MASK;

		if (epnum >= mtu->num_eps) {
			handled = -EINVAL;
			break;
		}
		if (!epnum)
			break;

		mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
		if (!mep->desc) {
			handled = -EINVAL;
			break;
		}
		if (mep->flags & MTU3_EP_STALL)
			result[0] |= 1 << USB_ENDPOINT_HALT;

		break;
	default:
		/* class, vendor, etc ... delegate */
		handled = 0;
		break;
	}

	if (handled > 0) {
		int ret;

		/* prepare a data stage for GET_STATUS */
		dev_dbg(mtu->dev, "get_status=%x\n", *(u16 *)result);
		memcpy(mtu->setup_buf, result, sizeof(result));
		mtu->ep0_req.mep = mtu->ep0;
		mtu->ep0_req.request.length = 2;
		mtu->ep0_req.request.buf = &mtu->setup_buf;
		mtu->ep0_req.request.complete = ep0_dummy_complete;
		ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
		if (ret < 0)
			handled = ret;
	}
	return handled;
}

static int handle_test_mode(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
{
	void __iomem *mbase = mtu->mac_base;
	int handled = 1;
	u32 value;

	switch (le16_to_cpu(setup->wIndex) >> 8) {
	case USB_TEST_J:
		dev_dbg(mtu->dev, "USB_TEST_J\n");
		mtu->test_mode_nr = TEST_J_MODE;
		break;
	case USB_TEST_K:
		dev_dbg(mtu->dev, "USB_TEST_K\n");
		mtu->test_mode_nr = TEST_K_MODE;
		break;
	case USB_TEST_SE0_NAK:
		dev_dbg(mtu->dev, "USB_TEST_SE0_NAK\n");
		mtu->test_mode_nr = TEST_SE0_NAK_MODE;
		break;
	case USB_TEST_PACKET:
		dev_dbg(mtu->dev, "USB_TEST_PACKET\n");
		mtu->test_mode_nr = TEST_PACKET_MODE;
		break;
	default:
		handled = -EINVAL;
		goto out;
	}

	mtu->test_mode = true;

	/* no TX completion interrupt, and need restart platform after test */
	if (mtu->test_mode_nr == TEST_PACKET_MODE)
		ep0_load_test_packet(mtu);

	/* send status before entering test mode. */
	ep0_do_status_stage(mtu);

	/* wait for ACK status sent by host */
	readl_poll_timeout_atomic(mbase + U3D_EP0CSR, value,
			!(value & EP0_DATAEND), 100, 5000);

	mtu3_writel(mbase, U3D_USB2_TEST_MODE, mtu->test_mode_nr);

	mtu->ep0_state = MU3D_EP0_STATE_SETUP;

out:
	return handled;
}

static int ep0_handle_feature_dev(struct mtu3 *mtu,
		struct usb_ctrlrequest *setup, bool set)
{
	void __iomem *mbase = mtu->mac_base;
	int handled = -EINVAL;
	u32 lpc;

	switch (le16_to_cpu(setup->wValue)) {
	case USB_DEVICE_REMOTE_WAKEUP:
		mtu->may_wakeup = !!set;
		handled = 1;
		break;
	case USB_DEVICE_TEST_MODE:
		if (!set || (mtu->g.speed != USB_SPEED_HIGH) ||
			(le16_to_cpu(setup->wIndex) & 0xff))
			break;

		handled = handle_test_mode(mtu, setup);
		break;
	case USB_DEVICE_U1_ENABLE:
		if (mtu->g.speed < USB_SPEED_SUPER ||
		    mtu->g.state != USB_STATE_CONFIGURED)
			break;

		lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
		if (set)
			lpc |= SW_U1_REQUEST_ENABLE;
		else
			lpc &= ~SW_U1_REQUEST_ENABLE;
		mtu3_writel(mbase, U3D_LINK_POWER_CONTROL, lpc);

		mtu->u1_enable = !!set;
		handled = 1;
		break;
	case USB_DEVICE_U2_ENABLE:
		if (mtu->g.speed < USB_SPEED_SUPER ||
		    mtu->g.state != USB_STATE_CONFIGURED)
			break;

		lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
		if (set)
			lpc |= SW_U2_REQUEST_ENABLE;
		else
			lpc &= ~SW_U2_REQUEST_ENABLE;
		mtu3_writel(mbase, U3D_LINK_POWER_CONTROL, lpc);

		mtu->u2_enable = !!set;
		handled = 1;
		break;
	default:
		handled = -EINVAL;
		break;
	}
	return handled;
}

static int ep0_handle_feature(struct mtu3 *mtu,
		struct usb_ctrlrequest *setup, bool set)
{
	struct mtu3_ep *mep;
	int handled = -EINVAL;
	int is_in;
	u16 value;
	u16 index;
	u8 epnum;

	value = le16_to_cpu(setup->wValue);
	index = le16_to_cpu(setup->wIndex);

	switch (setup->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		handled = ep0_handle_feature_dev(mtu, setup, set);
		break;
	case USB_RECIP_INTERFACE:
		/* superspeed only */
		if (value == USB_INTRF_FUNC_SUSPEND &&
		    mtu->g.speed >= USB_SPEED_SUPER) {
			/* forward the request for function suspend */
			mtu->may_wakeup = !!(index & USB_INTRF_FUNC_SUSPEND_RW);
			handled = 0;
		}
		break;
	case USB_RECIP_ENDPOINT:
		epnum = index & USB_ENDPOINT_NUMBER_MASK;
		if (epnum == 0 || epnum >= mtu->num_eps ||
			value != USB_ENDPOINT_HALT)
			break;

		is_in = index & USB_DIR_IN;
		mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
		if (!mep->desc)
			break;

		handled = 1;
		/* ignore request if endpoint is wedged */
		if (mep->flags & MTU3_EP_WEDGE)
			break;

		mtu3_ep_stall_set(mep, set);
		break;
	default:
		/* class, vendor, etc ... delegate */
		handled = 0;
		break;
	}
	return handled;
}

/*
 * handle all control requests can be handled
 * returns:
 *	negative errno - error happened
 *	zero - need delegate SETUP to gadget driver
 *	positive - already handled
 */
static int handle_standard_request(struct mtu3 *mtu,
			  struct usb_ctrlrequest *setup)
{
	void __iomem *mbase = mtu->mac_base;
	enum usb_device_state state = mtu->g.state;
	int handled = -EINVAL;
	u32 dev_conf;
	u16 value;

	value = le16_to_cpu(setup->wValue);

	/* the gadget driver handles everything except what we must handle */
	switch (setup->bRequest) {
	case USB_REQ_SET_ADDRESS:
		/* change it after the status stage */
		mtu->address = (u8) (value & 0x7f);
		dev_dbg(mtu->dev, "set address to 0x%x\n", mtu->address);

		dev_conf = mtu3_readl(mbase, U3D_DEVICE_CONF);
		dev_conf &= ~DEV_ADDR_MSK;
		dev_conf |= DEV_ADDR(mtu->address);
		mtu3_writel(mbase, U3D_DEVICE_CONF, dev_conf);

		if (mtu->address)
			usb_gadget_set_state(&mtu->g, USB_STATE_ADDRESS);
		else
			usb_gadget_set_state(&mtu->g, USB_STATE_DEFAULT);

		handled = 1;
		break;
	case USB_REQ_SET_CONFIGURATION:
		if (state == USB_STATE_ADDRESS) {
			usb_gadget_set_state(&mtu->g,
					USB_STATE_CONFIGURED);
		} else if (state == USB_STATE_CONFIGURED) {
			/*
			 * USB2 spec sec 9.4.7, if wValue is 0 then dev
			 * is moved to addressed state
			 */
			if (!value)
				usb_gadget_set_state(&mtu->g,
						USB_STATE_ADDRESS);
		}
		handled = 0;
		break;
	case USB_REQ_CLEAR_FEATURE:
		handled = ep0_handle_feature(mtu, setup, 0);
		break;
	case USB_REQ_SET_FEATURE:
		handled = ep0_handle_feature(mtu, setup, 1);
		break;
	case USB_REQ_GET_STATUS:
		handled = ep0_get_status(mtu, setup);
		break;
	case USB_REQ_SET_SEL:
		handled = ep0_set_sel(mtu, setup);
		break;
	case USB_REQ_SET_ISOCH_DELAY:
		handled = 1;
		break;
	default:
		/* delegate SET_CONFIGURATION, etc */
		handled = 0;
	}

	return handled;
}

/* receive an data packet (OUT) */
static void ep0_rx_state(struct mtu3 *mtu)
{
	struct mtu3_request *mreq;
	struct usb_request *req;
	void __iomem *mbase = mtu->mac_base;
	u32 maxp;
	u32 csr;
	u16 count = 0;

	dev_dbg(mtu->dev, "%s\n", __func__);

	csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
	mreq = next_ep0_request(mtu);
	req = &mreq->request;

	/* read packet and ack; or stall because of gadget driver bug */
	if (req) {
		void *buf = req->buf + req->actual;
		unsigned int len = req->length - req->actual;

		/* read the buffer */
		count = mtu3_readl(mbase, U3D_RXCOUNT0);
		if (count > len) {
			req->status = -EOVERFLOW;
			count = len;
		}
		ep0_read_fifo(mtu->ep0, buf, count);
		req->actual += count;
		csr |= EP0_RXPKTRDY;

		maxp = mtu->g.ep0->maxpacket;
		if (count < maxp || req->actual == req->length) {
			mtu->ep0_state = MU3D_EP0_STATE_SETUP;
			dev_dbg(mtu->dev, "ep0 state: %s\n",
				decode_ep0_state(mtu));

			csr |= EP0_DATAEND;
		} else {
			req = NULL;
		}
	} else {
		csr |= EP0_RXPKTRDY | EP0_SENDSTALL;
		dev_dbg(mtu->dev, "%s: SENDSTALL\n", __func__);
	}

	mtu3_writel(mbase, U3D_EP0CSR, csr);

	/* give back the request if have received all data */
	if (req)
		ep0_req_giveback(mtu, req);

}

/* transmitting to the host (IN) */
static void ep0_tx_state(struct mtu3 *mtu)
{
	struct mtu3_request *mreq = next_ep0_request(mtu);
	struct usb_request *req;
	u32 csr;
	u8 *src;
	u32 count;
	u32 maxp;

	dev_dbg(mtu->dev, "%s\n", __func__);

	if (!mreq)
		return;

	maxp = mtu->g.ep0->maxpacket;
	req = &mreq->request;

	/* load the data */
	src = (u8 *)req->buf + req->actual;
	count = min(maxp, req->length - req->actual);
	if (count)
		ep0_write_fifo(mtu->ep0, src, count);

	dev_dbg(mtu->dev, "%s act=%d, len=%d, cnt=%d, maxp=%d zero=%d\n",
		 __func__, req->actual, req->length, count, maxp, req->zero);

	req->actual += count;

	if ((count < maxp)
		|| ((req->actual == req->length) && !req->zero))
		mtu->ep0_state = MU3D_EP0_STATE_TX_END;

	/* send it out, triggering a "txpktrdy cleared" irq */
	csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
	mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr | EP0_TXPKTRDY);

	dev_dbg(mtu->dev, "%s ep0csr=0x%x\n", __func__,
		mtu3_readl(mtu->mac_base, U3D_EP0CSR));
}

static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
{
	struct mtu3_request *mreq;
	u32 count;
	u32 csr;

	csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
	count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);

	ep0_read_fifo(mtu->ep0, (u8 *)setup, count);

	dev_dbg(mtu->dev, "SETUP req%02x.%02x v%04x i%04x l%04x\n",
		 setup->bRequestType, setup->bRequest,
		 le16_to_cpu(setup->wValue), le16_to_cpu(setup->wIndex),
		 le16_to_cpu(setup->wLength));

	/* clean up any leftover transfers */
	mreq = next_ep0_request(mtu);
	if (mreq)
		ep0_req_giveback(mtu, &mreq->request);

	if (le16_to_cpu(setup->wLength) == 0) {
		;	/* no data stage, nothing to do */
	} else if (setup->bRequestType & USB_DIR_IN) {
		mtu3_writel(mtu->mac_base, U3D_EP0CSR,
			csr | EP0_SETUPPKTRDY | EP0_DPHTX);
		mtu->ep0_state = MU3D_EP0_STATE_TX;
	} else {
		mtu3_writel(mtu->mac_base, U3D_EP0CSR,
			(csr | EP0_SETUPPKTRDY) & (~EP0_DPHTX));
		mtu->ep0_state = MU3D_EP0_STATE_RX;
	}
}

static int ep0_handle_setup(struct mtu3 *mtu)
__releases(mtu->lock)
__acquires(mtu->lock)
{
	struct usb_ctrlrequest setup;
	struct mtu3_request *mreq;
	int handled = 0;

	ep0_read_setup(mtu, &setup);
	trace_mtu3_handle_setup(&setup);

	if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
		handled = handle_standard_request(mtu, &setup);

	dev_dbg(mtu->dev, "handled %d, ep0_state: %s\n",
		 handled, decode_ep0_state(mtu));

	if (handled < 0)
		goto stall;
	else if (handled > 0)
		goto finish;

	handled = forward_to_driver(mtu, &setup);
	if (handled < 0) {
stall:
		dev_dbg(mtu->dev, "%s stall (%d)\n", __func__, handled);

		ep0_stall_set(mtu->ep0, true,
			le16_to_cpu(setup.wLength) ? 0 : EP0_SETUPPKTRDY);

		return 0;
	}

finish:
	if (mtu->test_mode) {
		;	/* nothing to do */
	} else if (handled == USB_GADGET_DELAYED_STATUS) {

		mreq = next_ep0_request(mtu);
		if (mreq) {
			/* already asked us to continue delayed status */
			ep0_do_status_stage(mtu);
			ep0_req_giveback(mtu, &mreq->request);
		} else {
			/* do delayed STATUS stage till receive ep0_queue */
			mtu->delayed_status = true;
		}
	} else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */

		ep0_do_status_stage(mtu);
		/* complete zlp request directly */
		mreq = next_ep0_request(mtu);
		if (mreq && !mreq->request.length)
			ep0_req_giveback(mtu, &mreq->request);
	}

	return 0;
}

irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
{
	void __iomem *mbase = mtu->mac_base;
	struct mtu3_request *mreq;
	u32 int_status;
	irqreturn_t ret = IRQ_NONE;
	u32 csr;
	u32 len;

	int_status = mtu3_readl(mbase, U3D_EPISR);
	int_status &= mtu3_readl(mbase, U3D_EPIER);
	mtu3_writel(mbase, U3D_EPISR, int_status); /* W1C */

	/* only handle ep0's */
	if (!(int_status & (EP0ISR | SETUPENDISR)))
		return IRQ_NONE;

	/* abort current SETUP, and process new one */
	if (int_status & SETUPENDISR)
		mtu->ep0_state = MU3D_EP0_STATE_SETUP;

	csr = mtu3_readl(mbase, U3D_EP0CSR);

	dev_dbg(mtu->dev, "%s csr=0x%x\n", __func__, csr);

	/* we sent a stall.. need to clear it now.. */
	if (csr & EP0_SENTSTALL) {
		ep0_stall_set(mtu->ep0, false, 0);
		csr = mtu3_readl(mbase, U3D_EP0CSR);
		ret = IRQ_HANDLED;
	}
	dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
	mtu3_dbg_trace(mtu->dev, "ep0_state %s", decode_ep0_state(mtu));

	switch (mtu->ep0_state) {
	case MU3D_EP0_STATE_TX:
		/* irq on clearing txpktrdy */
		if ((csr & EP0_FIFOFULL) == 0) {
			ep0_tx_state(mtu);
			ret = IRQ_HANDLED;
		}
		break;
	case MU3D_EP0_STATE_RX:
		/* irq on set rxpktrdy */
		if (csr & EP0_RXPKTRDY) {
			ep0_rx_state(mtu);
			ret = IRQ_HANDLED;
		}
		break;
	case MU3D_EP0_STATE_TX_END:
		mtu3_writel(mbase, U3D_EP0CSR,
			(csr & EP0_W1C_BITS) | EP0_DATAEND);

		mreq = next_ep0_request(mtu);
		if (mreq)
			ep0_req_giveback(mtu, &mreq->request);

		mtu->ep0_state = MU3D_EP0_STATE_SETUP;
		ret = IRQ_HANDLED;
		dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
		break;
	case MU3D_EP0_STATE_SETUP:
		if (!(csr & EP0_SETUPPKTRDY))
			break;

		len = mtu3_readl(mbase, U3D_RXCOUNT0);
		if (len != 8) {
			dev_err(mtu->dev, "SETUP packet len %d != 8 ?\n", len);
			break;
		}

		ep0_handle_setup(mtu);
		ret = IRQ_HANDLED;
		break;
	default:
		/* can't happen */
		ep0_stall_set(mtu->ep0, true, 0);
		WARN_ON(1);
		break;
	}

	return ret;
}


static int mtu3_ep0_enable(struct usb_ep *ep,
	const struct usb_endpoint_descriptor *desc)
{
	/* always enabled */
	return -EINVAL;
}

static int mtu3_ep0_disable(struct usb_ep *ep)
{
	/* always enabled */
	return -EINVAL;
}

static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
{
	struct mtu3 *mtu = mep->mtu;

	mreq->mtu = mtu;
	mreq->request.actual = 0;
	mreq->request.status = -EINPROGRESS;

	dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__,
		mep->name, decode_ep0_state(mtu), mreq->request.length);

	switch (mtu->ep0_state) {
	case MU3D_EP0_STATE_SETUP:
	case MU3D_EP0_STATE_RX:	/* control-OUT data */
	case MU3D_EP0_STATE_TX:	/* control-IN data */
		break;
	default:
		dev_err(mtu->dev, "%s, error in ep0 state %s\n", __func__,
			decode_ep0_state(mtu));
		return -EINVAL;
	}

	if (mtu->delayed_status) {

		mtu->delayed_status = false;
		ep0_do_status_stage(mtu);
		/* needn't giveback the request for handling delay STATUS */
		return 0;
	}

	if (!list_empty(&mep->req_list))
		return -EBUSY;

	list_add_tail(&mreq->list, &mep->req_list);

	/* sequence #1, IN ... start writing the data */
	if (mtu->ep0_state == MU3D_EP0_STATE_TX)
		ep0_tx_state(mtu);

	return 0;
}

static int mtu3_ep0_queue(struct usb_ep *ep,
	struct usb_request *req, gfp_t gfp)
{
	struct mtu3_ep *mep;
	struct mtu3_request *mreq;
	struct mtu3 *mtu;
	unsigned long flags;
	int ret = 0;

	if (!ep || !req)
		return -EINVAL;

	mep = to_mtu3_ep(ep);
	mtu = mep->mtu;
	mreq = to_mtu3_request(req);

	spin_lock_irqsave(&mtu->lock, flags);
	ret = ep0_queue(mep, mreq);
	spin_unlock_irqrestore(&mtu->lock, flags);
	return ret;
}

static int mtu3_ep0_dequeue(struct usb_ep *ep, struct usb_request *req)
{
	/* we just won't support this */
	return -EINVAL;
}

static int mtu3_ep0_halt(struct usb_ep *ep, int value)
{
	struct mtu3_ep *mep;
	struct mtu3 *mtu;
	unsigned long flags;
	int ret = 0;

	if (!ep || !value)
		return -EINVAL;

	mep = to_mtu3_ep(ep);
	mtu = mep->mtu;

	dev_dbg(mtu->dev, "%s\n", __func__);

	spin_lock_irqsave(&mtu->lock, flags);

	if (!list_empty(&mep->req_list)) {
		ret = -EBUSY;
		goto cleanup;
	}

	switch (mtu->ep0_state) {
	/*
	 * stalls are usually issued after parsing SETUP packet, either
	 * directly in irq context from setup() or else later.
	 */
	case MU3D_EP0_STATE_TX:
	case MU3D_EP0_STATE_TX_END:
	case MU3D_EP0_STATE_RX:
	case MU3D_EP0_STATE_SETUP:
		ep0_stall_set(mtu->ep0, true, 0);
		break;
	default:
		dev_dbg(mtu->dev, "ep0 can't halt in state %s\n",
			decode_ep0_state(mtu));
		ret = -EINVAL;
	}

cleanup:
	spin_unlock_irqrestore(&mtu->lock, flags);
	return ret;
}

const struct usb_ep_ops mtu3_ep0_ops = {
	.enable = mtu3_ep0_enable,
	.disable = mtu3_ep0_disable,
	.alloc_request = mtu3_alloc_request,
	.free_request = mtu3_free_request,
	.queue = mtu3_ep0_queue,
	.dequeue = mtu3_ep0_dequeue,
	.set_halt = mtu3_ep0_halt,
};
