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

		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;
	u32 value;

	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;
	case OTG_SRP_REQD:
		dev_dbg(mtu->dev, "OTG_SRP_REQD\n");
		mtu->ssusb->otg_srp_reqd = 1;
		break;
	case OTG_HNP_REQD:
		dev_dbg(mtu->dev, "OTG_HNP_REQD\n");
		mtu->ssusb->otg_hnp_reqd = 1;
		break;
	default:
		handled = -EINVAL;
		goto out;
	}

	if (mtu->ssusb->otg_srp_reqd || mtu->ssusb->otg_hnp_reqd) {
		mtu->ep0_state = MU3D_EP0_STATE_SETUP;
		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. */
	value = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
	mtu3_writel(mbase, U3D_EP0CSR, value | EP0_SETUPPKTRDY | EP0_DATAEND);

	/* 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 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;
	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;
	void __iomem *mbase = mtu->mac_base;
	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) {
		/* 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 | 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) {
		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,
};
