/* * irq functions * * it will be called from usbhs_interrupt */ static int usbhsg_irq_dev_state(struct usbhs_priv *priv, struct usbhs_irq_state *irq_state) { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); struct device *dev = usbhsg_gpriv_to_dev(gpriv); gpriv->gadget.speed = usbhs_bus_get_speed(priv); dev_dbg(dev, "state = %x : speed : %d\n", usbhs_status_get_device_state(irq_state), gpriv->gadget.speed); return 0; }
static int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct device *dev = usbhs_priv_to_dev(priv); int enable = (typeReq == SetPortFeature); int speed, i, timeout = 128; int roothub_id = 1; /* only 1 root hub */ /* common error */ if (wIndex > roothub_id || wLength != 0) return -EPIPE; /* check wValue */ switch (wValue) { case USB_PORT_FEAT_POWER: usbhs_vbus_ctrl(priv, enable); dev_dbg(dev, "%s :: USB_PORT_FEAT_POWER\n", __func__); break; case USB_PORT_FEAT_ENABLE: case USB_PORT_FEAT_SUSPEND: case USB_PORT_FEAT_C_ENABLE: case USB_PORT_FEAT_C_SUSPEND: case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_OVER_CURRENT: case USB_PORT_FEAT_C_RESET: dev_dbg(dev, "%s :: USB_PORT_FEAT_xxx\n", __func__); break; case USB_PORT_FEAT_RESET: if (!enable) break; usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_HIGH_SPEED | USB_PORT_STAT_LOW_SPEED); usbhsh_queue_force_pop_all(priv); usbhs_bus_send_reset(priv); msleep(20); usbhs_bus_send_sof_enable(priv); for (i = 0; i < timeout ; i++) { switch (usbhs_bus_get_speed(priv)) { case USB_SPEED_LOW: speed = USB_PORT_STAT_LOW_SPEED; goto got_usb_bus_speed; case USB_SPEED_HIGH: speed = USB_PORT_STAT_HIGH_SPEED; goto got_usb_bus_speed; case USB_SPEED_FULL: speed = 0; goto got_usb_bus_speed; } msleep(20); } return -EPIPE; got_usb_bus_speed: usbhsh_port_stat_set(hpriv, speed); usbhsh_port_stat_set(hpriv, USB_PORT_STAT_ENABLE); dev_dbg(dev, "%s :: USB_PORT_FEAT_RESET (speed = %d)\n", __func__, speed); /* status change is not needed */ return 0; default: return -EPIPE; } /* set/clear status */ if (enable) usbhsh_port_stat_set(hpriv, (1 << wValue)); else usbhsh_port_stat_clear(hpriv, (1 << wValue)); return 0; }