static int usb_hcd_nxp_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); usb_remove_hcd(hcd); nxp_stop_hc(); usb_put_hcd(hcd); clk_disable(usb_pll_clk); clk_put(usb_pll_clk); clk_disable(usb_dev_clk); clk_put(usb_dev_clk); i2c_unregister_device(isp1301_i2c_client); isp1301_i2c_client = NULL; return 0; }
static int usb_hcd_nxp_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); usb_remove_hcd(hcd); nxp_stop_hc(); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); nxp_unset_usb_bits(); clk_disable(usb_clk); clk_put(usb_clk); i2c_unregister_device(isp1301_i2c_client); isp1301_i2c_client = NULL; platform_set_drvdata(pdev, NULL); return 0; }
static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) { struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; const struct hc_driver *driver = &ohci_nxp_hc_driver; struct i2c_adapter *i2c_adap; struct i2c_board_info i2c_info; int ret = 0, irq; dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name); if (usb_disabled()) { err("USB is disabled"); ret = -ENODEV; goto out; } if (pdev->num_resources != 2 || pdev->resource[0].flags != IORESOURCE_MEM || pdev->resource[1].flags != IORESOURCE_IRQ) { err("Invalid resource configuration"); ret = -ENODEV; goto out; } /* Enable AHB slave USB clock, needed for further USB clock control */ __raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL); ret = i2c_add_driver(&isp1301_driver); if (ret < 0) { err("failed to add ISP1301 driver"); goto out; } i2c_adap = i2c_get_adapter(2); memset(&i2c_info, 0, sizeof(struct i2c_board_info)); strlcpy(i2c_info.type, "isp1301_nxp", I2C_NAME_SIZE); isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info, normal_i2c, NULL); i2c_put_adapter(i2c_adap); if (!isp1301_i2c_client) { err("failed to connect I2C to ISP1301 USB Transceiver"); ret = -ENODEV; goto out_i2c_driver; } isp1301_configure(); /* Enable USB PLL */ usb_clk = clk_get(&pdev->dev, "ck_pll5"); if (IS_ERR(usb_clk)) { err("failed to acquire USB PLL"); ret = PTR_ERR(usb_clk); goto out1; } ret = clk_enable(usb_clk); if (ret < 0) { err("failed to start USB PLL"); goto out2; } ret = clk_set_rate(usb_clk, 48000); if (ret < 0) { err("failed to set USB clock rate"); goto out3; } __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); /* Set to enable all needed USB clocks */ __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != USB_CLOCK_MASK) ; hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { err("Failed to allocate HC buffer"); ret = -ENOMEM; goto out3; } /* Set all USB bits in the Start Enable register */ nxp_set_usb_bits(); hcd->rsrc_start = pdev->resource[0].start; hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); ret = -ENOMEM; goto out4; } hcd->regs = (void __iomem *)pdev->resource[0].start; irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENXIO; goto out4; } nxp_start_hc(); platform_set_drvdata(pdev, hcd); ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq); ret = usb_add_hcd(hcd, irq, 0); if (ret == 0) return ret; nxp_stop_hc(); out4: nxp_unset_usb_bits(); usb_put_hcd(hcd); out3: clk_disable(usb_clk); out2: clk_put(usb_clk); out1: i2c_unregister_device(isp1301_i2c_client); isp1301_i2c_client = NULL; out_i2c_driver: i2c_del_driver(&isp1301_driver); out: return ret; }
static int usb_hcd_nxp_probe(struct platform_device *pdev) { struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; const struct hc_driver *driver = &ohci_nxp_hc_driver; struct resource *res; int ret = 0, irq; struct device_node *isp1301_node; if (pdev->dev.of_node) { isp1301_node = of_parse_phandle(pdev->dev.of_node, "transceiver", 0); } else { isp1301_node = NULL; } isp1301_i2c_client = isp1301_get_client(isp1301_node); if (!isp1301_i2c_client) { ret = -EPROBE_DEFER; goto out; } pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name); if (usb_disabled()) { dev_err(&pdev->dev, "USB is disabled\n"); ret = -ENODEV; goto out; } /* Enable AHB slave USB clock, needed for further USB clock control */ __raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL); /* Enable USB PLL */ usb_pll_clk = clk_get(&pdev->dev, "ck_pll5"); if (IS_ERR(usb_pll_clk)) { dev_err(&pdev->dev, "failed to acquire USB PLL\n"); ret = PTR_ERR(usb_pll_clk); goto out1; } ret = clk_enable(usb_pll_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB PLL\n"); goto out2; } ret = clk_set_rate(usb_pll_clk, 48000); if (ret < 0) { dev_err(&pdev->dev, "failed to set USB clock rate\n"); goto out3; } /* Enable USB device clock */ usb_dev_clk = clk_get(&pdev->dev, "ck_usbd"); if (IS_ERR(usb_dev_clk)) { dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); ret = PTR_ERR(usb_dev_clk); goto out4; } ret = clk_enable(usb_dev_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); goto out5; } /* Enable USB otg clocks */ usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); if (IS_ERR(usb_otg_clk)) { dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); ret = PTR_ERR(usb_otg_clk); goto out6; } __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); ret = clk_enable(usb_otg_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); goto out7; } isp1301_configure(); hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); ret = -ENOMEM; goto out8; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto out8; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENXIO; goto out8; } nxp_start_hc(); platform_set_drvdata(pdev, hcd); ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq); ret = usb_add_hcd(hcd, irq, 0); if (ret == 0) return ret; nxp_stop_hc(); out8: usb_put_hcd(hcd); out7: clk_disable(usb_otg_clk); out6: clk_put(usb_otg_clk); out5: clk_disable(usb_dev_clk); out4: clk_put(usb_dev_clk); out3: clk_disable(usb_pll_clk); out2: clk_put(usb_pll_clk); out1: isp1301_i2c_client = NULL; out: return ret; }