/*
 * mtu3_gadget_ep0.c - MediaTek USB3 DRD peripheral driver ep0 handling
 *
 * Copyright (c) 2016 MediaTek Inc.
 *
 * Author:  Chunfeng.Yun <chunfeng.yun@mediatek.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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 for more details.
 *
 */

#include <linux/usb/composite.h>

#include "mtu3.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)
		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 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;
		/* superspeed only */
		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:
		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;

	switch (le16_to_cpu(setup->wIndex) >> 8) {
	case TEST_J:
		dev_dbg(mtu->dev, "TEST_J\n");
		mtu->test_mode_nr = TEST_J_MODE;
		break;
	case TEST_K:
		dev_dbg(mtu->dev, "TEST_K\n");
		mtu->test_mode_nr = TEST_K_MODE;
		break;
	case TEST_SE0_NAK:
		dev_dbg(mtu->dev, "TEST_SE0_NAK\n");
		mtu->test_mode_nr = TEST_SE0_NAK_MODE;
		break;
	case TEST_PACKET:
		dev_dbg(mtu->dev, "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);

	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 because function drivers
			 * should handle it
			 */
			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->wedged)
			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;
	u8 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;
	void __iomem *mbase = mtu->mac_base;
	int handled = 0;

	ep0_read_setup(mtu, &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) {
		/* handle the delay STATUS phase till receive ep_queue on ep0 */
		mtu->delayed_status = true;
	} else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */

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

		/* 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))
		return IRQ_NONE;

	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));

	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) {
		u32 csr;

		mtu->delayed_status = false;
		csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
		csr |= EP0_SETUPPKTRDY | EP0_DATAEND;
		mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
		/* 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,
};
