static inline void sofirq_off(struct sl811 *sl811) { if (!(sl811->irq_enable & SL11H_INTMASK_SOFINTR)) return; dev_dbg(sl811_to_hcd(sl811)->self.controller, "sof irq off\n"); sl811->irq_enable &= ~SL11H_INTMASK_SOFINTR; }
static void port_power(struct sl811 *sl811, int is_on) { struct usb_hcd *hcd = sl811_to_hcd(sl811); /* hub is inactive unless the port is powered */ if (is_on) { if (sl811->port1 & (1 << USB_PORT_FEAT_POWER)) return; sl811->port1 = (1 << USB_PORT_FEAT_POWER); sl811->irq_enable = SL11H_INTMASK_INSRMV; hcd->self.controller->power.power_state = PMSG_ON; } else { sl811->port1 = 0; sl811->irq_enable = 0; hcd->state = HC_STATE_HALT; hcd->self.controller->power.power_state = PMSG_SUSPEND; } sl811->ctrl1 = 0; sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_IRQ_STATUS, ~0); if (sl811->board && sl811->board->port_power) { /* switch VBUS, at 500mA unless hub power budget gets set */ DBG("power %s\n", is_on ? "on" : "off"); sl811->board->port_power(hcd->self.controller, is_on); } /* reset as thoroughly as we can */ if (sl811->board && sl811->board->reset) sl811->board->reset(hcd->self.controller); else { sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); mdelay(20); } sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); sl811_write(sl811, SL811HS_CTLREG2, SL811HS_CTL2_INIT); sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); // if !is_on, put into lowpower mode now }
static void port_power(struct sl811 *sl811, int is_on) { struct usb_hcd *hcd = sl811_to_hcd(sl811); if (is_on) { if (sl811->port1 & USB_PORT_STAT_POWER) return; sl811->port1 = USB_PORT_STAT_POWER; sl811->irq_enable = SL11H_INTMASK_INSRMV; } else { sl811->port1 = 0; sl811->irq_enable = 0; hcd->state = HC_STATE_HALT; } sl811->ctrl1 = 0; sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_IRQ_STATUS, ~0); if (sl811->board && sl811->board->port_power) { DBG("power %s\n", is_on ? "on" : "off"); sl811->board->port_power(hcd->self.controller, is_on); } if (sl811->board && sl811->board->reset) sl811->board->reset(hcd->self.controller); else { sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); mdelay(20); } sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); sl811_write(sl811, SL811HS_CTLREG2, SL811HS_CTL2_INIT); sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); }