static int usbhsh_stop(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct device *dev = usbhs_priv_to_dev(priv); /* * disable irq callback */ mod->irq_attch = NULL; mod->irq_dtch = NULL; mod->irq_sack = NULL; mod->irq_sign = NULL; usbhs_irq_callback_update(priv, mod); usb_remove_hcd(hcd); /* disable sys */ usbhs_sys_host_ctrl(priv, 0); dev_dbg(dev, "quit host\n"); return 0; }
static int usbhsh_irq_dtch(struct usbhs_priv *priv, struct usbhs_irq_state *irq_state) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct device *dev = usbhs_priv_to_dev(priv); dev_dbg(dev, "device detached\n"); usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); /* * enable attch interrupt again * * usbhsh_is_running() becomes invalid * according to this process. * see * usbhsh_is_running() * usbhsh_urb_enqueue() */ hpriv->mod.irq_attch = usbhsh_irq_attch; usbhs_irq_callback_update(priv, &hpriv->mod); /* * usbhsh_queue_force_pop_all() should be called * after usbhsh_is_running() becomes invalid. */ usbhsh_queue_force_pop_all(priv); return 0; }
/* * interrupt functions */ static int usbhsh_irq_attch(struct usbhs_priv *priv, struct usbhs_irq_state *irq_state) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct device *dev = usbhs_priv_to_dev(priv); dev_dbg(dev, "device attached\n"); usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); /* * attch interrupt might happen infinitely on some device * (on self power USB hub ?) * disable it here. * * usbhsh_is_running() becomes effective * according to this process. * see * usbhsh_is_running() * usbhsh_urb_enqueue() */ hpriv->mod.irq_attch = NULL; usbhs_irq_callback_update(priv, &hpriv->mod); return 0; }
/* * usb module start/end */ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct device *dev = usbhs_priv_to_dev(priv); unsigned long flags; int ret = 0; /******************** spin lock ********************/ usbhs_lock(priv, flags); usbhsg_status_set(gpriv, status); if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) ret = -1; /* not ready */ usbhs_unlock(priv, flags); /******************** spin unlock ********************/ if (ret < 0) return 0; /* not ready is not error */ /* * enable interrupt and systems if ready */ dev_dbg(dev, "start gadget\n"); /* * pipe initialize and enable DCP */ usbhs_pipe_init(priv, usbhsg_queue_done, usbhsg_dma_map_ctrl); usbhs_fifo_init(priv); usbhsg_uep_init(gpriv); /* dcp init */ dcp->pipe = usbhs_dcp_malloc(priv); dcp->pipe->mod_private = dcp; /* * system config enble * - HI speed * - function * - usb module */ usbhs_sys_hispeed_ctrl(priv, 1); usbhs_sys_function_ctrl(priv, 1); usbhs_sys_usb_ctrl(priv, 1); /* * enable irq callback */ mod->irq_dev_state = usbhsg_irq_dev_state; mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; usbhs_irq_callback_update(priv, mod); return 0; }
void usbhs_mod_autonomy_mode(struct usbhs_priv *priv) { struct usbhs_mod_info *info = usbhs_priv_to_modinfo(priv); info->irq_vbus = usbhsm_autonomy_irq_vbus; priv->pfunc.get_vbus = usbhsm_autonomy_get_vbus; usbhs_irq_callback_update(priv, NULL); }
static void usbhs_mod_phy_mode(struct usbhs_priv *priv) { struct usbhs_mod_info *info = &priv->mod_info; info->irq_vbus = NULL; priv->pfunc.get_vbus = usbhsm_phy_get_vbus; usbhs_irq_callback_update(priv, NULL); }
/* * usb module start/end */ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct device *dev = usbhs_priv_to_dev(priv); spinlock_t *lock; unsigned long flags; /******************** spin lock ********************/ lock = usbhsg_trylock(gpriv, &flags); /* * enable interrupt and systems if ready */ usbhsg_status_set(gpriv, status); if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) goto usbhsg_try_start_unlock; dev_dbg(dev, "start gadget\n"); /* * pipe initialize and enable DCP */ usbhs_pipe_init(priv); usbhsg_uep_init(gpriv); usbhsg_dcp_enable(dcp); /* * system config enble * - HI speed * - function * - usb module */ usbhs_sys_hispeed_ctrl(priv, 1); usbhs_sys_function_ctrl(priv, 1); usbhs_sys_usb_ctrl(priv, 1); /* * enable irq callback */ mod->irq_dev_state = usbhsg_irq_dev_state; mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; mod->irq_empty = usbhsg_irq_empty; mod->irq_ready = usbhsg_irq_ready; mod->irq_bempsts = 0; mod->irq_brdysts = 0; usbhs_irq_callback_update(priv, mod); usbhsg_try_start_unlock: usbhsg_unlock(lock, &flags); /******************** spin unlock ********************/ return 0; }
static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); struct device *dev = usbhs_priv_to_dev(priv); spinlock_t *lock; unsigned long flags; /******************** spin lock ********************/ lock = usbhsg_trylock(gpriv, &flags); /* * disable interrupt and systems if 1st try */ usbhsg_status_clr(gpriv, status); if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) goto usbhsg_try_stop_unlock; /* disable all irq */ mod->irq_dev_state = NULL; mod->irq_ctrl_stage = NULL; mod->irq_empty = NULL; mod->irq_ready = NULL; mod->irq_bempsts = 0; mod->irq_brdysts = 0; usbhs_irq_callback_update(priv, mod); usbhsg_dcp_disable(dcp); gpriv->gadget.speed = USB_SPEED_UNKNOWN; /* disable sys */ usbhs_sys_hispeed_ctrl(priv, 0); usbhs_sys_function_ctrl(priv, 0); usbhs_sys_usb_ctrl(priv, 0); usbhsg_unlock(lock, &flags); /******************** spin unlock ********************/ if (gpriv->driver && gpriv->driver->disconnect) gpriv->driver->disconnect(&gpriv->gadget); dev_dbg(dev, "stop gadget\n"); return 0; usbhsg_try_stop_unlock: usbhsg_unlock(lock, &flags); return 0; }
static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); struct device *dev = usbhs_priv_to_dev(priv); unsigned long flags; int ret = 0; /******************** spin lock ********************/ usbhs_lock(priv, flags); usbhsg_status_clr(gpriv, status); if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) ret = -1; /* already done */ usbhs_unlock(priv, flags); /******************** spin unlock ********************/ if (ret < 0) return 0; /* already done is not error */ /* * disable interrupt and systems if 1st try */ usbhs_fifo_quit(priv); /* disable all irq */ mod->irq_dev_state = NULL; mod->irq_ctrl_stage = NULL; usbhs_irq_callback_update(priv, mod); gpriv->gadget.speed = USB_SPEED_UNKNOWN; /* disable sys */ usbhs_sys_hispeed_ctrl(priv, 0); usbhs_sys_function_ctrl(priv, 0); usbhs_sys_usb_ctrl(priv, 0); usbhsg_pipe_disable(dcp); if (gpriv->driver && gpriv->driver->disconnect) gpriv->driver->disconnect(&gpriv->gadget); dev_dbg(dev, "stop gadget\n"); return 0; }
static int usbhsh_start(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct device *dev = usbhs_priv_to_dev(priv); int ret; /* add hcd */ ret = usb_add_hcd(hcd, 0, 0); if (ret < 0) return 0; device_wakeup_enable(hcd->self.controller); /* * pipe initialize and enable DCP */ usbhs_fifo_init(priv); usbhs_pipe_init(priv, usbhsh_dma_map_ctrl); usbhsh_pipe_init_for_host(priv); /* * system config enble * - HI speed * - host * - usb module */ usbhs_sys_host_ctrl(priv, 1); /* * enable irq callback */ mod->irq_attch = usbhsh_irq_attch; mod->irq_dtch = usbhsh_irq_dtch; mod->irq_sack = usbhsh_irq_setup_ack; mod->irq_sign = usbhsh_irq_setup_err; usbhs_irq_callback_update(priv, mod); dev_dbg(dev, "start host\n"); return ret; }