// SPDX-License-Identifier: GPL-2.0+
/*
 * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget
 *
 * hub.c - virtual hub handling
 *
 * Copyright 2017 IBM Corporation
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/prefetch.h>
#include <linux/clk.h>
#include <linux/usb/gadget.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/dma-mapping.h>
#include <linux/bcd.h>
#include <linux/version.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>

#include "vhub.h"

/* usb 2.0 hub device descriptor
 *
 * A few things we may want to improve here:
 *
 *    - We may need to indicate TT support
 *    - We may need a device qualifier descriptor
 *	as devices can pretend to be usb1 or 2
 *    - Make vid/did overridable
 *    - make it look like usb1 if usb1 mode forced
 */
#define KERNEL_REL	bin2bcd(LINUX_VERSION_MAJOR)
#define KERNEL_VER	bin2bcd(LINUX_VERSION_PATCHLEVEL)

enum {
	AST_VHUB_STR_INDEX_MAX = 4,
	AST_VHUB_STR_MANUF = 3,
	AST_VHUB_STR_PRODUCT = 2,
	AST_VHUB_STR_SERIAL = 1,
};

static const struct usb_device_descriptor ast_vhub_dev_desc = {
	.bLength		= USB_DT_DEVICE_SIZE,
	.bDescriptorType	= USB_DT_DEVICE,
	.bcdUSB			= cpu_to_le16(0x0200),
	.bDeviceClass		= USB_CLASS_HUB,
	.bDeviceSubClass	= 0,
	.bDeviceProtocol	= 1,
	.bMaxPacketSize0	= 64,
	.idVendor		= cpu_to_le16(0x1d6b),
	.idProduct		= cpu_to_le16(0x0107),
	.bcdDevice		= cpu_to_le16(0x0100),
	.iManufacturer		= AST_VHUB_STR_MANUF,
	.iProduct		= AST_VHUB_STR_PRODUCT,
	.iSerialNumber		= AST_VHUB_STR_SERIAL,
	.bNumConfigurations	= 1,
};

/*
 * Configuration descriptor: same comments as above
 * regarding handling USB1 mode.
 */

/*
 * We don't use sizeof() as Linux definition of
 * struct usb_endpoint_descriptor contains 2
 * extra bytes
 */
#define AST_VHUB_CONF_DESC_SIZE	(USB_DT_CONFIG_SIZE + \
				 USB_DT_INTERFACE_SIZE + \
				 USB_DT_ENDPOINT_SIZE)

static const struct ast_vhub_full_cdesc ast_vhub_conf_desc = {
	.cfg = {
		.bLength		= USB_DT_CONFIG_SIZE,
		.bDescriptorType	= USB_DT_CONFIG,
		.wTotalLength		= cpu_to_le16(AST_VHUB_CONF_DESC_SIZE),
		.bNumInterfaces		= 1,
		.bConfigurationValue	= 1,
		.iConfiguration		= 0,
		.bmAttributes		= USB_CONFIG_ATT_ONE |
					  USB_CONFIG_ATT_SELFPOWER |
					  USB_CONFIG_ATT_WAKEUP,
		.bMaxPower		= 0,
	},
	.intf = {
		.bLength		= USB_DT_INTERFACE_SIZE,
		.bDescriptorType	= USB_DT_INTERFACE,
		.bInterfaceNumber	= 0,
		.bAlternateSetting	= 0,
		.bNumEndpoints		= 1,
		.bInterfaceClass	= USB_CLASS_HUB,
		.bInterfaceSubClass	= 0,
		.bInterfaceProtocol	= 0,
		.iInterface		= 0,
	},
	.ep = {
		.bLength		= USB_DT_ENDPOINT_SIZE,
		.bDescriptorType	= USB_DT_ENDPOINT,
		.bEndpointAddress	= 0x81,
		.bmAttributes		= USB_ENDPOINT_XFER_INT,
		.wMaxPacketSize		= cpu_to_le16(1),
		.bInterval		= 0x0c,
	},
};

#define AST_VHUB_HUB_DESC_SIZE	(USB_DT_HUB_NONVAR_SIZE + 2)

static const struct usb_hub_descriptor ast_vhub_hub_desc = {
	.bDescLength			= AST_VHUB_HUB_DESC_SIZE,
	.bDescriptorType		= USB_DT_HUB,
	.bNbrPorts			= AST_VHUB_NUM_PORTS,
	.wHubCharacteristics		= cpu_to_le16(HUB_CHAR_NO_LPSM),
	.bPwrOn2PwrGood			= 10,
	.bHubContrCurrent		= 0,
	.u.hs.DeviceRemovable[0]	= 0,
	.u.hs.DeviceRemovable[1]	= 0xff,
};

/*
 * These strings converted to UTF-16 must be smaller than
 * our EP0 buffer.
 */
static const struct usb_string ast_vhub_str_array[] = {
	{
		.id = AST_VHUB_STR_SERIAL,
		.s = "00000000"
	},
	{
		.id = AST_VHUB_STR_PRODUCT,
		.s = "USB Virtual Hub"
	},
	{
		.id = AST_VHUB_STR_MANUF,
		.s = "Aspeed"
	},
	{ }
};

static const struct usb_gadget_strings ast_vhub_strings = {
	.language = 0x0409,
	.strings = (struct usb_string *)ast_vhub_str_array
};

static int ast_vhub_hub_dev_status(struct ast_vhub_ep *ep,
				   u16 wIndex, u16 wValue)
{
	u8 st0;

	EPDBG(ep, "GET_STATUS(dev)\n");

	/*
	 * Mark it as self-powered, I doubt the BMC is powered off
	 * the USB bus ...
	 */
	st0 = 1 << USB_DEVICE_SELF_POWERED;

	/*
	 * Need to double check how remote wakeup actually works
	 * on that chip and what triggers it.
	 */
	if (ep->vhub->wakeup_en)
		st0 |= 1 << USB_DEVICE_REMOTE_WAKEUP;

	return ast_vhub_simple_reply(ep, st0, 0);
}

static int ast_vhub_hub_ep_status(struct ast_vhub_ep *ep,
				  u16 wIndex, u16 wValue)
{
	int ep_num;
	u8 st0 = 0;

	ep_num = wIndex & USB_ENDPOINT_NUMBER_MASK;
	EPDBG(ep, "GET_STATUS(ep%d)\n", ep_num);

	/* On the hub we have only EP 0 and 1 */
	if (ep_num == 1) {
		if (ep->vhub->ep1_stalled)
			st0 |= 1 << USB_ENDPOINT_HALT;
	} else if (ep_num != 0)
		return std_req_stall;

	return ast_vhub_simple_reply(ep, st0, 0);
}

static int ast_vhub_hub_dev_feature(struct ast_vhub_ep *ep,
				    u16 wIndex, u16 wValue,
				    bool is_set)
{
	EPDBG(ep, "%s_FEATURE(dev val=%02x)\n",
	      is_set ? "SET" : "CLEAR", wValue);

	if (wValue != USB_DEVICE_REMOTE_WAKEUP)
		return std_req_stall;

	ep->vhub->wakeup_en = is_set;
	EPDBG(ep, "Hub remote wakeup %s\n",
	      is_set ? "enabled" : "disabled");

	return std_req_complete;
}

static int ast_vhub_hub_ep_feature(struct ast_vhub_ep *ep,
				   u16 wIndex, u16 wValue,
				   bool is_set)
{
	int ep_num;
	u32 reg;

	ep_num = wIndex & USB_ENDPOINT_NUMBER_MASK;
	EPDBG(ep, "%s_FEATURE(ep%d val=%02x)\n",
	      is_set ? "SET" : "CLEAR", ep_num, wValue);

	if (ep_num > 1)
		return std_req_stall;
	if (wValue != USB_ENDPOINT_HALT)
		return std_req_stall;
	if (ep_num == 0)
		return std_req_complete;

	EPDBG(ep, "%s stall on EP 1\n",
	      is_set ? "setting" : "clearing");

	ep->vhub->ep1_stalled = is_set;
	reg = readl(ep->vhub->regs + AST_VHUB_EP1_CTRL);
	if (is_set) {
		reg |= VHUB_EP1_CTRL_STALL;
	} else {
		reg &= ~VHUB_EP1_CTRL_STALL;
		reg |= VHUB_EP1_CTRL_RESET_TOGGLE;
	}
	writel(reg, ep->vhub->regs + AST_VHUB_EP1_CTRL);

	return std_req_complete;
}

static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
			     u8 desc_type, u16 len)
{
	size_t dsize;
	struct ast_vhub *vhub = ep->vhub;

	EPDBG(ep, "GET_DESCRIPTOR(type:%d)\n", desc_type);

	/*
	 * Copy first to EP buffer and send from there, so
	 * we can do some in-place patching if needed. We know
	 * the EP buffer is big enough but ensure that doesn't
	 * change. We do that now rather than later after we
	 * have checked sizes etc... to avoid a gcc bug where
	 * it thinks len is constant and barfs about read
	 * overflows in memcpy.
	 */
	switch(desc_type) {
	case USB_DT_DEVICE:
		dsize = USB_DT_DEVICE_SIZE;
		memcpy(ep->buf, &vhub->vhub_dev_desc, dsize);
		BUILD_BUG_ON(dsize > sizeof(vhub->vhub_dev_desc));
		BUILD_BUG_ON(USB_DT_DEVICE_SIZE >= AST_VHUB_EP0_MAX_PACKET);
		break;
	case USB_DT_CONFIG:
		dsize = AST_VHUB_CONF_DESC_SIZE;
		memcpy(ep->buf, &vhub->vhub_conf_desc, dsize);
		BUILD_BUG_ON(dsize > sizeof(vhub->vhub_conf_desc));
		BUILD_BUG_ON(AST_VHUB_CONF_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
		break;
	case USB_DT_HUB:
		dsize = AST_VHUB_HUB_DESC_SIZE;
		memcpy(ep->buf, &vhub->vhub_hub_desc, dsize);
		BUILD_BUG_ON(dsize > sizeof(vhub->vhub_hub_desc));
		BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
		break;
	default:
		return std_req_stall;
	}

	/* Crop requested length */
	if (len > dsize)
		len = dsize;

	/* Shoot it from the EP buffer */
	return ast_vhub_reply(ep, NULL, len);
}

static struct usb_gadget_strings*
ast_vhub_str_of_container(struct usb_gadget_string_container *container)
{
	return (struct usb_gadget_strings *)container->stash;
}

static int ast_vhub_collect_languages(struct ast_vhub *vhub, void *buf,
				      size_t size)
{
	int rc, hdr_len, nlangs, max_langs;
	struct usb_gadget_strings *lang_str;
	struct usb_gadget_string_container *container;
	struct usb_string_descriptor *sdesc = buf;

	nlangs = 0;
	hdr_len = sizeof(struct usb_descriptor_header);
	max_langs = (size - hdr_len) / sizeof(sdesc->wData[0]);
	list_for_each_entry(container, &vhub->vhub_str_desc, list) {
		if (nlangs >= max_langs)
			break;

		lang_str = ast_vhub_str_of_container(container);
		sdesc->wData[nlangs++] = cpu_to_le16(lang_str->language);
	}

	rc = hdr_len + nlangs * sizeof(sdesc->wData[0]);
	sdesc->bLength = rc;
	sdesc->bDescriptorType = USB_DT_STRING;

	return rc;
}

static struct usb_gadget_strings *ast_vhub_lookup_string(struct ast_vhub *vhub,
							 u16 lang_id)
{
	struct usb_gadget_strings *lang_str;
	struct usb_gadget_string_container *container;

	list_for_each_entry(container, &vhub->vhub_str_desc, list) {
		lang_str = ast_vhub_str_of_container(container);
		if (lang_str->language == lang_id)
			return lang_str;
	}

	return NULL;
}

static int ast_vhub_rep_string(struct ast_vhub_ep *ep,
			       u8 string_id, u16 lang_id,
			       u16 len)
{
	int rc;
	u8 buf[256];
	struct ast_vhub *vhub = ep->vhub;
	struct usb_gadget_strings *lang_str;

	if (string_id == 0) {
		rc = ast_vhub_collect_languages(vhub, buf, sizeof(buf));
	} else {
		lang_str = ast_vhub_lookup_string(vhub, lang_id);
		if (!lang_str)
			return std_req_stall;

		rc = usb_gadget_get_string(lang_str, string_id, buf);
	}

	if (rc < 0 || rc >= AST_VHUB_EP0_MAX_PACKET)
		return std_req_stall;

	/* Shoot it from the EP buffer */
	memcpy(ep->buf, buf, rc);
	return ast_vhub_reply(ep, NULL, min_t(u16, rc, len));
}

enum std_req_rc ast_vhub_std_hub_request(struct ast_vhub_ep *ep,
					 struct usb_ctrlrequest *crq)
{
	struct ast_vhub *vhub = ep->vhub;
	u16 wValue, wIndex, wLength;

	wValue = le16_to_cpu(crq->wValue);
	wIndex = le16_to_cpu(crq->wIndex);
	wLength = le16_to_cpu(crq->wLength);

	/* First packet, grab speed */
	if (vhub->speed == USB_SPEED_UNKNOWN) {
		u32 ustat = readl(vhub->regs + AST_VHUB_USBSTS);
		if (ustat & VHUB_USBSTS_HISPEED)
			vhub->speed = USB_SPEED_HIGH;
		else
			vhub->speed = USB_SPEED_FULL;
		UDCDBG(vhub, "USB status=%08x speed=%s\n", ustat,
		       vhub->speed == USB_SPEED_HIGH ? "high" : "full");
	}

	switch ((crq->bRequestType << 8) | crq->bRequest) {
		/* SET_ADDRESS */
	case DeviceOutRequest | USB_REQ_SET_ADDRESS:
		EPDBG(ep, "SET_ADDRESS: Got address %x\n", wValue);
		writel(wValue, vhub->regs + AST_VHUB_CONF);
		return std_req_complete;

		/* GET_STATUS */
	case DeviceRequest | USB_REQ_GET_STATUS:
		return ast_vhub_hub_dev_status(ep, wIndex, wValue);
	case InterfaceRequest | USB_REQ_GET_STATUS:
		return ast_vhub_simple_reply(ep, 0, 0);
	case EndpointRequest | USB_REQ_GET_STATUS:
		return ast_vhub_hub_ep_status(ep, wIndex, wValue);

		/* SET/CLEAR_FEATURE */
	case DeviceOutRequest | USB_REQ_SET_FEATURE:
		return ast_vhub_hub_dev_feature(ep, wIndex, wValue, true);
	case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
		return ast_vhub_hub_dev_feature(ep, wIndex, wValue, false);
	case EndpointOutRequest | USB_REQ_SET_FEATURE:
		return ast_vhub_hub_ep_feature(ep, wIndex, wValue, true);
	case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
		return ast_vhub_hub_ep_feature(ep, wIndex, wValue, false);

		/* GET/SET_CONFIGURATION */
	case DeviceRequest | USB_REQ_GET_CONFIGURATION:
		return ast_vhub_simple_reply(ep, 1);
	case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
		if (wValue != 1)
			return std_req_stall;
		return std_req_complete;

		/* GET_DESCRIPTOR */
	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
		switch (wValue >> 8) {
		case USB_DT_DEVICE:
		case USB_DT_CONFIG:
			return ast_vhub_rep_desc(ep, wValue >> 8,
						 wLength);
		case USB_DT_STRING:
			return ast_vhub_rep_string(ep, wValue & 0xff,
						   wIndex, wLength);
		}
		return std_req_stall;

		/* GET/SET_INTERFACE */
	case DeviceRequest | USB_REQ_GET_INTERFACE:
		return ast_vhub_simple_reply(ep, 0);
	case DeviceOutRequest | USB_REQ_SET_INTERFACE:
		if (wValue != 0 || wIndex != 0)
			return std_req_stall;
		return std_req_complete;
	}
	return std_req_stall;
}

static void ast_vhub_update_hub_ep1(struct ast_vhub *vhub,
				    unsigned int port)
{
	/* Update HW EP1 response */
	u32 reg = readl(vhub->regs + AST_VHUB_EP1_STS_CHG);
	u32 pmask = (1 << (port + 1));
	if (vhub->ports[port].change)
		reg |= pmask;
	else
		reg &= ~pmask;
	writel(reg, vhub->regs + AST_VHUB_EP1_STS_CHG);
}

static void ast_vhub_change_port_stat(struct ast_vhub *vhub,
				      unsigned int port,
				      u16 clr_flags,
				      u16 set_flags,
				      bool set_c)
{
	struct ast_vhub_port *p = &vhub->ports[port];
	u16 prev;

	/* Update port status */
	prev = p->status;
	p->status = (prev & ~clr_flags) | set_flags;
	DDBG(&p->dev, "port %d status %04x -> %04x (C=%d)\n",
	     port + 1, prev, p->status, set_c);

	/* Update change bits if needed */
	if (set_c) {
		u16 chg = p->status ^ prev;

		/* Only these are relevant for change */
		chg &= USB_PORT_STAT_C_CONNECTION |
		       USB_PORT_STAT_C_ENABLE |
		       USB_PORT_STAT_C_SUSPEND |
		       USB_PORT_STAT_C_OVERCURRENT |
		       USB_PORT_STAT_C_RESET |
		       USB_PORT_STAT_C_L1;

		/*
		 * We only set USB_PORT_STAT_C_ENABLE if we are disabling
		 * the port as per USB spec, otherwise MacOS gets upset
		 */
		if (p->status & USB_PORT_STAT_ENABLE)
			chg &= ~USB_PORT_STAT_C_ENABLE;

		p->change = chg;
		ast_vhub_update_hub_ep1(vhub, port);
	}
}

static void ast_vhub_send_host_wakeup(struct ast_vhub *vhub)
{
	u32 reg = readl(vhub->regs + AST_VHUB_CTRL);
	UDCDBG(vhub, "Waking up host !\n");
	reg |= VHUB_CTRL_MANUAL_REMOTE_WAKEUP;
	writel(reg, vhub->regs + AST_VHUB_CTRL);
}

void ast_vhub_device_connect(struct ast_vhub *vhub,
			     unsigned int port, bool on)
{
	if (on)
		ast_vhub_change_port_stat(vhub, port, 0,
					  USB_PORT_STAT_CONNECTION, true);
	else
		ast_vhub_change_port_stat(vhub, port,
					  USB_PORT_STAT_CONNECTION |
					  USB_PORT_STAT_ENABLE,
					  0, true);

	/*
	 * If the hub is set to wakup the host on connection events
	 * then send a wakeup.
	 */
	if (vhub->wakeup_en)
		ast_vhub_send_host_wakeup(vhub);
}

static void ast_vhub_wake_work(struct work_struct *work)
{
	struct ast_vhub *vhub = container_of(work,
					     struct ast_vhub,
					     wake_work);
	unsigned long flags;
	unsigned int i;

	/*
	 * Wake all sleeping ports. If a port is suspended by
	 * the host suspend (without explicit state suspend),
	 * we let the normal host wake path deal with it later.
	 */
	spin_lock_irqsave(&vhub->lock, flags);
	for (i = 0; i < vhub->max_ports; i++) {
		struct ast_vhub_port *p = &vhub->ports[i];

		if (!(p->status & USB_PORT_STAT_SUSPEND))
			continue;
		ast_vhub_change_port_stat(vhub, i,
					  USB_PORT_STAT_SUSPEND,
					  0, true);
		ast_vhub_dev_resume(&p->dev);
	}
	ast_vhub_send_host_wakeup(vhub);
	spin_unlock_irqrestore(&vhub->lock, flags);
}

void ast_vhub_hub_wake_all(struct ast_vhub *vhub)
{
	/*
	 * A device is trying to wake the world, because this
	 * can recurse into the device, we break the call chain
	 * using a work queue
	 */
	schedule_work(&vhub->wake_work);
}

static void ast_vhub_port_reset(struct ast_vhub *vhub, u8 port)
{
	struct ast_vhub_port *p = &vhub->ports[port];
	u16 set, clr, speed;

	/* First mark disabled */
	ast_vhub_change_port_stat(vhub, port,
				  USB_PORT_STAT_ENABLE |
				  USB_PORT_STAT_SUSPEND,
				  USB_PORT_STAT_RESET,
				  false);

	if (!p->dev.driver)
		return;

	/*
	 * This will either "start" the port or reset the
	 * device if already started...
	 */
	ast_vhub_dev_reset(&p->dev);

	/* Grab the right speed */
	speed = p->dev.driver->max_speed;
	if (speed == USB_SPEED_UNKNOWN || speed > vhub->speed)
		speed = vhub->speed;

	switch (speed) {
	case USB_SPEED_LOW:
		set = USB_PORT_STAT_LOW_SPEED;
		clr = USB_PORT_STAT_HIGH_SPEED;
		break;
	case USB_SPEED_FULL:
		set = 0;
		clr = USB_PORT_STAT_LOW_SPEED |
			USB_PORT_STAT_HIGH_SPEED;
		break;
	case USB_SPEED_HIGH:
		set = USB_PORT_STAT_HIGH_SPEED;
		clr = USB_PORT_STAT_LOW_SPEED;
		break;
	default:
		UDCDBG(vhub, "Unsupported speed %d when"
		       " connecting device\n",
		       speed);
		return;
	}
	clr |= USB_PORT_STAT_RESET;
	set |= USB_PORT_STAT_ENABLE;

	/* This should ideally be delayed ... */
	ast_vhub_change_port_stat(vhub, port, clr, set, true);
}

static enum std_req_rc ast_vhub_set_port_feature(struct ast_vhub_ep *ep,
						 u8 port, u16 feat)
{
	struct ast_vhub *vhub = ep->vhub;
	struct ast_vhub_port *p;

	if (port == 0 || port > vhub->max_ports)
		return std_req_stall;
	port--;
	p = &vhub->ports[port];

	switch(feat) {
	case USB_PORT_FEAT_SUSPEND:
		if (!(p->status & USB_PORT_STAT_ENABLE))
			return std_req_complete;
		ast_vhub_change_port_stat(vhub, port,
					  0, USB_PORT_STAT_SUSPEND,
					  false);
		ast_vhub_dev_suspend(&p->dev);
		return std_req_complete;
	case USB_PORT_FEAT_RESET:
		EPDBG(ep, "Port reset !\n");
		ast_vhub_port_reset(vhub, port);
		return std_req_complete;
	case USB_PORT_FEAT_POWER:
		/*
		 * On Power-on, we mark the connected flag changed,
		 * if there's a connected device, some hosts will
		 * otherwise fail to detect it.
		 */
		if (p->status & USB_PORT_STAT_CONNECTION) {
			p->change |= USB_PORT_STAT_C_CONNECTION;
			ast_vhub_update_hub_ep1(vhub, port);
		}
		return std_req_complete;
	case USB_PORT_FEAT_TEST:
	case USB_PORT_FEAT_INDICATOR:
		/* We don't do anything with these */
		return std_req_complete;
	}
	return std_req_stall;
}

static enum std_req_rc ast_vhub_clr_port_feature(struct ast_vhub_ep *ep,
						 u8 port, u16 feat)
{
	struct ast_vhub *vhub = ep->vhub;
	struct ast_vhub_port *p;

	if (port == 0 || port > vhub->max_ports)
		return std_req_stall;
	port--;
	p = &vhub->ports[port];

	switch(feat) {
	case USB_PORT_FEAT_ENABLE:
		ast_vhub_change_port_stat(vhub, port,
					  USB_PORT_STAT_ENABLE |
					  USB_PORT_STAT_SUSPEND, 0,
					  false);
		ast_vhub_dev_suspend(&p->dev);
		return std_req_complete;
	case USB_PORT_FEAT_SUSPEND:
		if (!(p->status & USB_PORT_STAT_SUSPEND))
			return std_req_complete;
		ast_vhub_change_port_stat(vhub, port,
					  USB_PORT_STAT_SUSPEND, 0,
					  false);
		ast_vhub_dev_resume(&p->dev);
		return std_req_complete;
	case USB_PORT_FEAT_POWER:
		/* We don't do power control */
		return std_req_complete;
	case USB_PORT_FEAT_INDICATOR:
		/* We don't have indicators */
		return std_req_complete;
	case USB_PORT_FEAT_C_CONNECTION:
	case USB_PORT_FEAT_C_ENABLE:
	case USB_PORT_FEAT_C_SUSPEND:
	case USB_PORT_FEAT_C_OVER_CURRENT:
	case USB_PORT_FEAT_C_RESET:
		/* Clear state-change feature */
		p->change &= ~(1u << (feat - 16));
		ast_vhub_update_hub_ep1(vhub, port);
		return std_req_complete;
	}
	return std_req_stall;
}

static enum std_req_rc ast_vhub_get_port_stat(struct ast_vhub_ep *ep,
					      u8 port)
{
	struct ast_vhub *vhub = ep->vhub;
	u16 stat, chg;

	if (port == 0 || port > vhub->max_ports)
		return std_req_stall;
	port--;

	stat = vhub->ports[port].status;
	chg = vhub->ports[port].change;

	/* We always have power */
	stat |= USB_PORT_STAT_POWER;

	EPDBG(ep, " port status=%04x change=%04x\n", stat, chg);

	return ast_vhub_simple_reply(ep,
				     stat & 0xff,
				     stat >> 8,
				     chg & 0xff,
				     chg >> 8);
}

enum std_req_rc ast_vhub_class_hub_request(struct ast_vhub_ep *ep,
					   struct usb_ctrlrequest *crq)
{
	u16 wValue, wIndex, wLength;

	wValue = le16_to_cpu(crq->wValue);
	wIndex = le16_to_cpu(crq->wIndex);
	wLength = le16_to_cpu(crq->wLength);

	switch ((crq->bRequestType << 8) | crq->bRequest) {
	case GetHubStatus:
		EPDBG(ep, "GetHubStatus\n");
		return ast_vhub_simple_reply(ep, 0, 0, 0, 0);
	case GetPortStatus:
		EPDBG(ep, "GetPortStatus(%d)\n", wIndex & 0xff);
		return ast_vhub_get_port_stat(ep, wIndex & 0xf);
	case GetHubDescriptor:
		if (wValue != (USB_DT_HUB << 8))
			return std_req_stall;
		EPDBG(ep, "GetHubDescriptor(%d)\n", wIndex & 0xff);
		return ast_vhub_rep_desc(ep, USB_DT_HUB, wLength);
	case SetHubFeature:
	case ClearHubFeature:
		EPDBG(ep, "Get/SetHubFeature(%d)\n", wValue);
		/* No feature, just complete the requests */
		if (wValue == C_HUB_LOCAL_POWER ||
		    wValue == C_HUB_OVER_CURRENT)
			return std_req_complete;
		return std_req_stall;
	case SetPortFeature:
		EPDBG(ep, "SetPortFeature(%d,%d)\n", wIndex & 0xf, wValue);
		return ast_vhub_set_port_feature(ep, wIndex & 0xf, wValue);
	case ClearPortFeature:
		EPDBG(ep, "ClearPortFeature(%d,%d)\n", wIndex & 0xf, wValue);
		return ast_vhub_clr_port_feature(ep, wIndex & 0xf, wValue);
	case ClearTTBuffer:
	case ResetTT:
	case StopTT:
		return std_req_complete;
	case GetTTState:
		return ast_vhub_simple_reply(ep, 0, 0, 0, 0);
	default:
		EPDBG(ep, "Unknown class request\n");
	}
	return std_req_stall;
}

void ast_vhub_hub_suspend(struct ast_vhub *vhub)
{
	unsigned int i;

	UDCDBG(vhub, "USB bus suspend\n");

	if (vhub->suspended)
		return;

	vhub->suspended = true;

	/*
	 * Forward to unsuspended ports without changing
	 * their connection status.
	 */
	for (i = 0; i < vhub->max_ports; i++) {
		struct ast_vhub_port *p = &vhub->ports[i];

		if (!(p->status & USB_PORT_STAT_SUSPEND))
			ast_vhub_dev_suspend(&p->dev);
	}
}

void ast_vhub_hub_resume(struct ast_vhub *vhub)
{
	unsigned int i;

	UDCDBG(vhub, "USB bus resume\n");

	if (!vhub->suspended)
		return;

	vhub->suspended = false;

	/*
	 * Forward to unsuspended ports without changing
	 * their connection status.
	 */
	for (i = 0; i < vhub->max_ports; i++) {
		struct ast_vhub_port *p = &vhub->ports[i];

		if (!(p->status & USB_PORT_STAT_SUSPEND))
			ast_vhub_dev_resume(&p->dev);
	}
}

void ast_vhub_hub_reset(struct ast_vhub *vhub)
{
	unsigned int i;

	UDCDBG(vhub, "USB bus reset\n");

	/*
	 * Is the speed known ? If not we don't care, we aren't
	 * initialized yet and ports haven't been enabled.
	 */
	if (vhub->speed == USB_SPEED_UNKNOWN)
		return;

	/* We aren't suspended anymore obviously */
	vhub->suspended = false;

	/* No speed set */
	vhub->speed = USB_SPEED_UNKNOWN;

	/* Wakeup not enabled anymore */
	vhub->wakeup_en = false;

	/*
	 * Clear all port status, disable gadgets and "suspend"
	 * them. They will be woken up by a port reset.
	 */
	for (i = 0; i < vhub->max_ports; i++) {
		struct ast_vhub_port *p = &vhub->ports[i];

		/* Only keep the connected flag */
		p->status &= USB_PORT_STAT_CONNECTION;
		p->change = 0;

		/* Suspend the gadget if any */
		ast_vhub_dev_suspend(&p->dev);
	}

	/* Cleanup HW */
	writel(0, vhub->regs + AST_VHUB_CONF);
	writel(0, vhub->regs + AST_VHUB_EP0_CTRL);
	writel(VHUB_EP1_CTRL_RESET_TOGGLE |
	       VHUB_EP1_CTRL_ENABLE,
	       vhub->regs + AST_VHUB_EP1_CTRL);
	writel(0, vhub->regs + AST_VHUB_EP1_STS_CHG);
}

static void ast_vhub_of_parse_dev_desc(struct ast_vhub *vhub,
				       const struct device_node *vhub_np)
{
	u16 id;
	u32 data;

	if (!of_property_read_u32(vhub_np, "vhub-vendor-id", &data)) {
		id = (u16)data;
		vhub->vhub_dev_desc.idVendor = cpu_to_le16(id);
	}
	if (!of_property_read_u32(vhub_np, "vhub-product-id", &data)) {
		id = (u16)data;
		vhub->vhub_dev_desc.idProduct = cpu_to_le16(id);
	}
	if (!of_property_read_u32(vhub_np, "vhub-device-revision", &data)) {
		id = (u16)data;
		vhub->vhub_dev_desc.bcdDevice = cpu_to_le16(id);
	}
}

static void ast_vhub_fixup_usb1_dev_desc(struct ast_vhub *vhub)
{
	vhub->vhub_dev_desc.bcdUSB = cpu_to_le16(0x0100);
	vhub->vhub_dev_desc.bDeviceProtocol = 0;
}

static struct usb_gadget_string_container*
ast_vhub_str_container_alloc(struct ast_vhub *vhub)
{
	unsigned int size;
	struct usb_string *str_array;
	struct usb_gadget_strings *lang_str;
	struct usb_gadget_string_container *container;

	size = sizeof(*container);
	size += sizeof(struct usb_gadget_strings);
	size += sizeof(struct usb_string) * AST_VHUB_STR_INDEX_MAX;
	container = devm_kzalloc(&vhub->pdev->dev, size, GFP_KERNEL);
	if (!container)
		return ERR_PTR(-ENOMEM);

	lang_str = ast_vhub_str_of_container(container);
	str_array = (struct usb_string *)(lang_str + 1);
	lang_str->strings = str_array;
	return container;
}

static void ast_vhub_str_deep_copy(struct usb_gadget_strings *dest,
				   const struct usb_gadget_strings *src)
{
	struct usb_string *src_array = src->strings;
	struct usb_string *dest_array = dest->strings;

	dest->language = src->language;
	if (src_array && dest_array) {
		do {
			*dest_array = *src_array;
			dest_array++;
			src_array++;
		} while (src_array->s);
	}
}

static int ast_vhub_str_alloc_add(struct ast_vhub *vhub,
				  const struct usb_gadget_strings *src_str)
{
	struct usb_gadget_strings *dest_str;
	struct usb_gadget_string_container *container;

	container = ast_vhub_str_container_alloc(vhub);
	if (IS_ERR(container))
		return PTR_ERR(container);

	dest_str = ast_vhub_str_of_container(container);
	ast_vhub_str_deep_copy(dest_str, src_str);
	list_add_tail(&container->list, &vhub->vhub_str_desc);

	return 0;
}

static const struct {
	const char *name;
	u8 id;
} str_id_map[] = {
	{"manufacturer",	AST_VHUB_STR_MANUF},
	{"product",		AST_VHUB_STR_PRODUCT},
	{"serial-number",	AST_VHUB_STR_SERIAL},
	{},
};

static int ast_vhub_of_parse_str_desc(struct ast_vhub *vhub,
				      const struct device_node *desc_np)
{
	u32 langid;
	int ret = 0;
	int i, offset;
	const char *str;
	struct device_node *child;
	struct usb_string str_array[AST_VHUB_STR_INDEX_MAX];
	struct usb_gadget_strings lang_str = {
		.strings = (struct usb_string *)str_array,
	};

	for_each_child_of_node(desc_np, child) {
		if (of_property_read_u32(child, "reg", &langid))
			continue; /* no language identifier specified */

		if (!usb_validate_langid(langid))
			continue; /* invalid language identifier */

		lang_str.language = langid;
		for (i = offset = 0; str_id_map[i].name; i++) {
			str = of_get_property(child, str_id_map[i].name, NULL);
			if (str) {
				str_array[offset].s = str;
				str_array[offset].id = str_id_map[i].id;
				offset++;
			}
		}
		str_array[offset].id = 0;
		str_array[offset].s = NULL;

		ret = ast_vhub_str_alloc_add(vhub, &lang_str);
		if (ret) {
			of_node_put(child);
			break;
		}
	}

	return ret;
}

static int ast_vhub_init_desc(struct ast_vhub *vhub)
{
	int ret;
	struct device_node *desc_np;
	const struct device_node *vhub_np = vhub->pdev->dev.of_node;

	/* Initialize vhub Device Descriptor. */
	memcpy(&vhub->vhub_dev_desc, &ast_vhub_dev_desc,
		sizeof(vhub->vhub_dev_desc));
	ast_vhub_of_parse_dev_desc(vhub, vhub_np);
	if (vhub->force_usb1)
		ast_vhub_fixup_usb1_dev_desc(vhub);

	/* Initialize vhub Configuration Descriptor. */
	memcpy(&vhub->vhub_conf_desc, &ast_vhub_conf_desc,
		sizeof(vhub->vhub_conf_desc));

	/* Initialize vhub Hub Descriptor. */
	memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
		sizeof(vhub->vhub_hub_desc));
	vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports;

	/* Initialize vhub String Descriptors. */
	INIT_LIST_HEAD(&vhub->vhub_str_desc);
	desc_np = of_get_child_by_name(vhub_np, "vhub-strings");
	if (desc_np)
		ret = ast_vhub_of_parse_str_desc(vhub, desc_np);
	else
		ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings);

	return ret;
}

int ast_vhub_init_hub(struct ast_vhub *vhub)
{
	vhub->speed = USB_SPEED_UNKNOWN;
	INIT_WORK(&vhub->wake_work, ast_vhub_wake_work);

	return ast_vhub_init_desc(vhub);
}
