/** * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * */ int usb_hcd_s3c2410_probe (const struct hc_driver *driver, struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) return -ENOMEM; hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed"); retval = -EBUSY; goto err0; } clk = clk_get(NULL, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = -ENOENT; goto err1; } clk_use(clk); s3c2410_start_hc(dev, hcd); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; goto err2; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); if (retval != 0) goto err2; return 0; err2: s3c2410_stop_hc(dev); iounmap(hcd->regs); clk_unuse(clk); clk_put(clk); err1: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err0: usb_put_hcd(hcd); return retval; }
/** * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * */ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) return -ENOMEM; hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = resource_size(&dev->resource[0]); hcd->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]); if (!hcd->regs) { dev_err(&dev->dev, "devm_request_and_ioremap failed\n"); retval = -ENOMEM; goto err_put; } clk = devm_clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = PTR_ERR(clk); goto err_put; } usb_clk = devm_clk_get(&dev->dev, "usb-bus-host"); if (IS_ERR(usb_clk)) { dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); retval = PTR_ERR(usb_clk); goto err_put; } s3c2410_start_hc(dev, hcd); ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, 0); if (retval != 0) goto err_ioremap; return 0; err_ioremap: s3c2410_stop_hc(dev); err_put: usb_put_hcd(hcd); return retval; }
static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) { struct s3c2410_hcd_port *port; struct usb_hcd *hcd; unsigned long flags; int portno; if (info == NULL) return; port = &info->port[0]; hcd = info->hcd; local_irq_save(flags); for (portno = 0; portno < 2; port++, portno++) { if (port_oc & (1<<portno) && port->flags & S3C_HCDFLG_USED) { port->oc_status = 1; port->oc_changed = 1; /* ok, once over-current is detected, the port needs to be powered down */ s3c2410_usb_set_power(info, portno+1, 0); } } local_irq_restore(flags); }
static int ohci_s3c2410_hub_control ( struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); struct usb_hub_descriptor *desc; int ret = -EINVAL; u32 *data = (u32 *)buf; dev_dbg(hcd->self.controller, "s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", hcd, typeReq, wValue, wIndex, buf, wLength); /* if we are only an humble host without any special capabilities * process the request straight away and exit */ if (info == NULL) { ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); goto out; } /* check the request to see if it needs handling */ switch (typeReq) { case SetPortFeature: if (wValue == USB_PORT_FEAT_POWER) { dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); s3c2410_usb_set_power(info, wIndex, 1); goto out; } break; case ClearPortFeature: switch (wValue) { case USB_PORT_FEAT_C_OVER_CURRENT: dev_dbg(hcd->self.controller, "ClearPortFeature: C_OVER_CURRENT\n"); if (valid_port(wIndex)) { info->port[wIndex-1].oc_changed = 0; info->port[wIndex-1].oc_status = 0; } goto out; case USB_PORT_FEAT_OVER_CURRENT: dev_dbg(hcd->self.controller, "ClearPortFeature: OVER_CURRENT\n"); if (valid_port(wIndex)) { info->port[wIndex-1].oc_status = 0; } goto out; case USB_PORT_FEAT_POWER: dev_dbg(hcd->self.controller, "ClearPortFeature: POWER\n"); if (valid_port(wIndex)) { s3c2410_usb_set_power(info, wIndex, 0); return 0; } } break; } ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); if (ret) goto out; switch (typeReq) { case GetHubDescriptor: /* update the hub's descriptor */ desc = (struct usb_hub_descriptor *)buf; if (info->power_control == NULL) return ret; dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n", desc->wHubCharacteristics); /* remove the old configurations for power-switching, and * over-current protection, and insert our new configuration */ desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); desc->wHubCharacteristics |= cpu_to_le16(0x0001); if (info->enable_oc) { desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); } dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", desc->wHubCharacteristics); return ret; case GetPortStatus: /* check port status */ dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); if (valid_port(wIndex)) { if (info->port[wIndex-1].oc_changed) { *data |= cpu_to_le32(RH_PS_OCIC); } if (info->port[wIndex-1].oc_status) { *data |= cpu_to_le32(RH_PS_POCI); } } } out: return ret; }
/** * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * */ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; #if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416) /* USB host Power enable */ s3c2410_gpio_cfgpin(S3C2410_GPB4, S3C2410_GPB4_OUTP); s3c2410_gpio_pullup(S3C2410_GPB4, 0); s3c2410_gpio_setpin(S3C2410_GPB4, 1); #if (USB_HOST_PORT2_EN == 1) usb20_phy_init(); #endif #endif #if (USB_HOST_PORT2_EN == 1) && (CONFIG_PLAT_S3C64XX == 1) /* set USB_SIG_MASK */ __raw_writel( __raw_readl(S3C_OTHERS)|(1<<16), S3C_OTHERS); /* Initializes OTG PHY */ __raw_writel(0x0, S3C_USBOTG_PHYPWR); __raw_writel(0x60, S3C_USBOTG_PHYCLK); __raw_writel(0x1, S3C_USBOTG_RSTCON); udelay(20); __raw_writel(0x0, S3C_USBOTG_RSTCON); udelay(20); #endif s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) return -ENOMEM; hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed"); retval = -EBUSY; goto err_put; } clk = clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = -ENOENT; goto err_mem; } #if (USB_HOST_PORT2_EN == 1) && (CONFIG_PLAT_S3C64XX == 1) otg_clk = clk_get(&dev->dev, "otg"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get otg clock\n"); retval = -ENOENT; goto err_mem; } #endif #if !defined(CONFIG_CPU_S3C6400) && !defined(CONFIG_CPU_S3C6410) usb_clk = clk_get(&dev->dev, "usb-bus-host"); if (IS_ERR(usb_clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = -ENOENT; goto err_clk; } #endif s3c2410_start_hc(dev, hcd); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; goto err_ioremap; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); if (retval != 0) goto err_ioremap; return 0; err_ioremap: s3c2410_stop_hc(dev); iounmap(hcd->regs); clk_put(usb_clk); #if !defined(CONFIG_CPU_S3C6400) && !defined(CONFIG_CPU_S3C6410) err_clk: clk_put(clk); #endif err_mem: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put: usb_put_hcd(hcd); return retval; }
/** * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * */ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; #ifdef CONFIG_EmbedSky_TWO_USB_HOST unsigned long reg_misccr; reg_misccr = 0; reg_misccr = readl(S3C2410_MISCCR); reg_misccr = reg_misccr | S3C2410_MISCCR_USBHOST; writel(reg_misccr,S3C2410_MISCCR); printk("Initial EmbedSky TWO USB HOST Driver!\n"); #endif s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) return -ENOMEM; hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = resource_size(&dev->resource[0]); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed\n"); retval = -EBUSY; goto err_put; } clk = clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = PTR_ERR(clk); goto err_mem; } usb_clk = clk_get(&dev->dev, "usb-bus-host"); if (IS_ERR(usb_clk)) { dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); retval = PTR_ERR(usb_clk); goto err_clk; } s3c2410_start_hc(dev, hcd); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; goto err_ioremap; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); if (retval != 0) goto err_ioremap; return 0; err_ioremap: s3c2410_stop_hc(dev); iounmap(hcd->regs); clk_put(usb_clk); err_clk: clk_put(clk); err_mem: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put: usb_put_hcd(hcd); return retval; }
/** * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * */ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) return -ENOMEM; hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = resource_size(&dev->resource[0]); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed\n"); retval = -EBUSY; goto err_put; } clk = clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = PTR_ERR(clk); goto err_mem; } usb_clk = clk_get(&dev->dev, "usb-bus-host"); if (IS_ERR(usb_clk)) { dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); retval = PTR_ERR(usb_clk); goto err_clk; } s3c2410_start_hc(dev, hcd); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; goto err_ioremap; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); if (retval != 0) goto err_ioremap; return 0; err_ioremap: s3c2410_stop_hc(dev); iounmap(hcd->regs); clk_put(usb_clk); err_clk: clk_put(clk); err_mem: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put: usb_put_hcd(hcd); return retval; }
static int ohci_s3c2410_hub_control( struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); struct usb_hub_descriptor *desc; int ret = -EINVAL; u32 *data = (u32 *)buf; dev_dbg(hcd->self.controller, "s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", hcd, typeReq, wValue, wIndex, buf, wLength); /* */ if (info == NULL) { ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); goto out; } /* */ switch (typeReq) { case SetPortFeature: if (wValue == USB_PORT_FEAT_POWER) { dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); s3c2410_usb_set_power(info, wIndex, 1); goto out; } break; case ClearPortFeature: switch (wValue) { case USB_PORT_FEAT_C_OVER_CURRENT: dev_dbg(hcd->self.controller, "ClearPortFeature: C_OVER_CURRENT\n"); if (valid_port(wIndex)) { info->port[wIndex-1].oc_changed = 0; info->port[wIndex-1].oc_status = 0; } goto out; case USB_PORT_FEAT_OVER_CURRENT: dev_dbg(hcd->self.controller, "ClearPortFeature: OVER_CURRENT\n"); if (valid_port(wIndex)) info->port[wIndex-1].oc_status = 0; goto out; case USB_PORT_FEAT_POWER: dev_dbg(hcd->self.controller, "ClearPortFeature: POWER\n"); if (valid_port(wIndex)) { s3c2410_usb_set_power(info, wIndex, 0); return 0; } } break; } ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); if (ret) goto out; switch (typeReq) { case GetHubDescriptor: /* */ desc = (struct usb_hub_descriptor *)buf; if (info->power_control == NULL) return ret; dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n", desc->wHubCharacteristics); /* */ desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); desc->wHubCharacteristics |= cpu_to_le16(0x0001); if (info->enable_oc) { desc->wHubCharacteristics &= ~cpu_to_le16( HUB_CHAR_OCPM); desc->wHubCharacteristics |= cpu_to_le16( 0x0008 | 0x0001); } dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", desc->wHubCharacteristics); return ret; case GetPortStatus: /* */ dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); if (valid_port(wIndex)) { if (info->port[wIndex-1].oc_changed) *data |= cpu_to_le32(RH_PS_OCIC); if (info->port[wIndex-1].oc_status) *data |= cpu_to_le32(RH_PS_POCI); } } out: return ret; }
/** * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * */ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, struct platform_device *dev) { struct usb_hcd *hcd = NULL; int retval; struct clk *otg_clk; otg_clk = clk_get(NULL, "otg"); clk_enable(otg_clk); writel(readl(S3C_CLK_SRC)& ~S3C6400_CLKSRC_UHOST_MASK, S3C_CLK_SRC); writel(readl(S3C_OTHERS)|S3C_OTHERS_USB_SIG_MASK, S3C_OTHERS); writel(0x0, S3C_USBOTG_PHYPWR); /* Power up */ writel(OTGH_PHY_CLK_VALUE, S3C_USBOTG_PHYCLK); writel(0x1, S3C_USBOTG_RSTCON); udelay(50); writel(0x0, S3C_USBOTG_RSTCON); udelay(50); /* USB host colock divider ratio is 1 */ writel(readl(S3C_CLK_DIV1)& ~S3C6400_CLKDIV1_UHOST_MASK, S3C_CLK_DIV1); writel(readl(S3C_HCLK_GATE)|S3C_CLKCON_HCLK_UHOST|S3C_CLKCON_HCLK_SECUR, S3C_HCLK_GATE); writel(readl(S3C_SCLK_GATE)|S3C_CLKCON_SCLK_UHOST, S3C_SCLK_GATE); s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); s3c2410_usb_set_power(dev->dev.platform_data, 2, 1); hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); if (hcd == NULL) return -ENOMEM; hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_err(&dev->dev, "request_mem_region failed\n"); retval = -EBUSY; goto err_put; } clk = clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = -ENOENT; goto err_mem; } #if defined(CONFIG_ARCH_2410) usb_clk = clk_get(&dev->dev, "usb-bus-host"); if (IS_ERR(usb_clk)) { dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); retval = -ENOENT; goto err_clk; } #endif s3c2410_start_hc(dev, hcd); hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(&dev->dev, "ioremap failed\n"); retval = -ENOMEM; goto err_ioremap; } ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); if (retval != 0) goto err_ioremap; return 0; err_ioremap: s3c2410_stop_hc(dev); iounmap(hcd->regs); #if defined(CONFIG_ARCH_2410) clk_put(usb_clk); err_clk: clk_put(clk); #endif err_mem: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put: usb_put_hcd(hcd); return retval; }