162194244cf871aec73b5854077f1c527416ccd7bJingoo Han/* 262194244cf871aec73b5854077f1c527416ccd7bJingoo Han * SAMSUNG EXYNOS USB HOST OHCI Controller 362194244cf871aec73b5854077f1c527416ccd7bJingoo Han * 462194244cf871aec73b5854077f1c527416ccd7bJingoo Han * Copyright (C) 2011 Samsung Electronics Co.Ltd 562194244cf871aec73b5854077f1c527416ccd7bJingoo Han * Author: Jingoo Han <jg1.han@samsung.com> 662194244cf871aec73b5854077f1c527416ccd7bJingoo Han * 762194244cf871aec73b5854077f1c527416ccd7bJingoo Han * This program is free software; you can redistribute it and/or modify it 862194244cf871aec73b5854077f1c527416ccd7bJingoo Han * under the terms of the GNU General Public License as published by the 962194244cf871aec73b5854077f1c527416ccd7bJingoo Han * Free Software Foundation; either version 2 of the License, or (at your 1062194244cf871aec73b5854077f1c527416ccd7bJingoo Han * option) any later version. 1162194244cf871aec73b5854077f1c527416ccd7bJingoo Han * 1262194244cf871aec73b5854077f1c527416ccd7bJingoo Han */ 1362194244cf871aec73b5854077f1c527416ccd7bJingoo Han 1462194244cf871aec73b5854077f1c527416ccd7bJingoo Han#include <linux/clk.h> 1562194244cf871aec73b5854077f1c527416ccd7bJingoo Han#include <linux/platform_device.h> 1662194244cf871aec73b5854077f1c527416ccd7bJingoo Han#include <mach/ohci.h> 1762194244cf871aec73b5854077f1c527416ccd7bJingoo Han#include <plat/usb-phy.h> 1862194244cf871aec73b5854077f1c527416ccd7bJingoo Han 1962194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstruct exynos_ohci_hcd { 2062194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct device *dev; 2162194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct usb_hcd *hcd; 2262194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct clk *clk; 2362194244cf871aec73b5854077f1c527416ccd7bJingoo Han}; 2462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 2562194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic int ohci_exynos_start(struct usb_hcd *hcd) 2662194244cf871aec73b5854077f1c527416ccd7bJingoo Han{ 2762194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct ohci_hcd *ohci = hcd_to_ohci(hcd); 2862194244cf871aec73b5854077f1c527416ccd7bJingoo Han int ret; 2962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 3062194244cf871aec73b5854077f1c527416ccd7bJingoo Han ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci); 3162194244cf871aec73b5854077f1c527416ccd7bJingoo Han 3262194244cf871aec73b5854077f1c527416ccd7bJingoo Han ret = ohci_init(ohci); 3362194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (ret < 0) 3462194244cf871aec73b5854077f1c527416ccd7bJingoo Han return ret; 3562194244cf871aec73b5854077f1c527416ccd7bJingoo Han 3662194244cf871aec73b5854077f1c527416ccd7bJingoo Han ret = ohci_run(ohci); 3762194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (ret < 0) { 3862194244cf871aec73b5854077f1c527416ccd7bJingoo Han err("can't start %s", hcd->self.bus_name); 3962194244cf871aec73b5854077f1c527416ccd7bJingoo Han ohci_stop(hcd); 4062194244cf871aec73b5854077f1c527416ccd7bJingoo Han return ret; 4162194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 4262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 4362194244cf871aec73b5854077f1c527416ccd7bJingoo Han return 0; 4462194244cf871aec73b5854077f1c527416ccd7bJingoo Han} 4562194244cf871aec73b5854077f1c527416ccd7bJingoo Han 4662194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic const struct hc_driver exynos_ohci_hc_driver = { 4762194244cf871aec73b5854077f1c527416ccd7bJingoo Han .description = hcd_name, 4862194244cf871aec73b5854077f1c527416ccd7bJingoo Han .product_desc = "EXYNOS OHCI Host Controller", 4962194244cf871aec73b5854077f1c527416ccd7bJingoo Han .hcd_priv_size = sizeof(struct ohci_hcd), 5062194244cf871aec73b5854077f1c527416ccd7bJingoo Han 5162194244cf871aec73b5854077f1c527416ccd7bJingoo Han .irq = ohci_irq, 5262194244cf871aec73b5854077f1c527416ccd7bJingoo Han .flags = HCD_MEMORY|HCD_USB11, 5362194244cf871aec73b5854077f1c527416ccd7bJingoo Han 5462194244cf871aec73b5854077f1c527416ccd7bJingoo Han .start = ohci_exynos_start, 5562194244cf871aec73b5854077f1c527416ccd7bJingoo Han .stop = ohci_stop, 5662194244cf871aec73b5854077f1c527416ccd7bJingoo Han .shutdown = ohci_shutdown, 5762194244cf871aec73b5854077f1c527416ccd7bJingoo Han 5862194244cf871aec73b5854077f1c527416ccd7bJingoo Han .get_frame_number = ohci_get_frame, 5962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 6062194244cf871aec73b5854077f1c527416ccd7bJingoo Han .urb_enqueue = ohci_urb_enqueue, 6162194244cf871aec73b5854077f1c527416ccd7bJingoo Han .urb_dequeue = ohci_urb_dequeue, 6262194244cf871aec73b5854077f1c527416ccd7bJingoo Han .endpoint_disable = ohci_endpoint_disable, 6362194244cf871aec73b5854077f1c527416ccd7bJingoo Han 6462194244cf871aec73b5854077f1c527416ccd7bJingoo Han .hub_status_data = ohci_hub_status_data, 6562194244cf871aec73b5854077f1c527416ccd7bJingoo Han .hub_control = ohci_hub_control, 6662194244cf871aec73b5854077f1c527416ccd7bJingoo Han#ifdef CONFIG_PM 6762194244cf871aec73b5854077f1c527416ccd7bJingoo Han .bus_suspend = ohci_bus_suspend, 6862194244cf871aec73b5854077f1c527416ccd7bJingoo Han .bus_resume = ohci_bus_resume, 6962194244cf871aec73b5854077f1c527416ccd7bJingoo Han#endif 7062194244cf871aec73b5854077f1c527416ccd7bJingoo Han .start_port_reset = ohci_start_port_reset, 7162194244cf871aec73b5854077f1c527416ccd7bJingoo Han}; 7262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 7362194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic int __devinit exynos_ohci_probe(struct platform_device *pdev) 7462194244cf871aec73b5854077f1c527416ccd7bJingoo Han{ 7562194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos4_ohci_platdata *pdata; 7662194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos_ohci_hcd *exynos_ohci; 7762194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct usb_hcd *hcd; 7862194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct ohci_hcd *ohci; 7962194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct resource *res; 8062194244cf871aec73b5854077f1c527416ccd7bJingoo Han int irq; 8162194244cf871aec73b5854077f1c527416ccd7bJingoo Han int err; 8262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 8362194244cf871aec73b5854077f1c527416ccd7bJingoo Han pdata = pdev->dev.platform_data; 8462194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (!pdata) { 8562194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "No platform data defined\n"); 8662194244cf871aec73b5854077f1c527416ccd7bJingoo Han return -EINVAL; 8762194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 8862194244cf871aec73b5854077f1c527416ccd7bJingoo Han 8962194244cf871aec73b5854077f1c527416ccd7bJingoo Han exynos_ohci = kzalloc(sizeof(struct exynos_ohci_hcd), GFP_KERNEL); 9062194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (!exynos_ohci) 9162194244cf871aec73b5854077f1c527416ccd7bJingoo Han return -ENOMEM; 9262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 9362194244cf871aec73b5854077f1c527416ccd7bJingoo Han exynos_ohci->dev = &pdev->dev; 9462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 9562194244cf871aec73b5854077f1c527416ccd7bJingoo Han hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, 9662194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_name(&pdev->dev)); 9762194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (!hcd) { 9862194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "Unable to create HCD\n"); 9962194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = -ENOMEM; 10062194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail_hcd; 10162194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 10262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 10362194244cf871aec73b5854077f1c527416ccd7bJingoo Han exynos_ohci->hcd = hcd; 10462194244cf871aec73b5854077f1c527416ccd7bJingoo Han exynos_ohci->clk = clk_get(&pdev->dev, "usbhost"); 10562194244cf871aec73b5854077f1c527416ccd7bJingoo Han 10662194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (IS_ERR(exynos_ohci->clk)) { 10762194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "Failed to get usbhost clock\n"); 10862194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = PTR_ERR(exynos_ohci->clk); 10962194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail_clk; 11062194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 11162194244cf871aec73b5854077f1c527416ccd7bJingoo Han 11262194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = clk_enable(exynos_ohci->clk); 11362194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (err) 11462194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail_clken; 11562194244cf871aec73b5854077f1c527416ccd7bJingoo Han 11662194244cf871aec73b5854077f1c527416ccd7bJingoo Han res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 11762194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (!res) { 11862194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "Failed to get I/O memory\n"); 11962194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = -ENXIO; 12062194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail_io; 12162194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 12262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 12362194244cf871aec73b5854077f1c527416ccd7bJingoo Han hcd->rsrc_start = res->start; 12462194244cf871aec73b5854077f1c527416ccd7bJingoo Han hcd->rsrc_len = resource_size(res); 12562194244cf871aec73b5854077f1c527416ccd7bJingoo Han hcd->regs = ioremap(res->start, resource_size(res)); 12662194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (!hcd->regs) { 12762194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "Failed to remap I/O memory\n"); 12862194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = -ENOMEM; 12962194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail_io; 13062194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 13162194244cf871aec73b5854077f1c527416ccd7bJingoo Han 13262194244cf871aec73b5854077f1c527416ccd7bJingoo Han irq = platform_get_irq(pdev, 0); 13362194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (!irq) { 13462194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "Failed to get IRQ\n"); 13562194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = -ENODEV; 13662194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail; 13762194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 13862194244cf871aec73b5854077f1c527416ccd7bJingoo Han 13962194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (pdata->phy_init) 14062194244cf871aec73b5854077f1c527416ccd7bJingoo Han pdata->phy_init(pdev, S5P_USB_PHY_HOST); 14162194244cf871aec73b5854077f1c527416ccd7bJingoo Han 14262194244cf871aec73b5854077f1c527416ccd7bJingoo Han ohci = hcd_to_ohci(hcd); 14362194244cf871aec73b5854077f1c527416ccd7bJingoo Han ohci_hcd_init(ohci); 14462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 14562194244cf871aec73b5854077f1c527416ccd7bJingoo Han err = usb_add_hcd(hcd, irq, IRQF_SHARED); 14662194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (err) { 14762194244cf871aec73b5854077f1c527416ccd7bJingoo Han dev_err(&pdev->dev, "Failed to add USB HCD\n"); 14862194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail; 14962194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 15062194244cf871aec73b5854077f1c527416ccd7bJingoo Han 15162194244cf871aec73b5854077f1c527416ccd7bJingoo Han platform_set_drvdata(pdev, exynos_ohci); 15262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 15362194244cf871aec73b5854077f1c527416ccd7bJingoo Han return 0; 15462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 15562194244cf871aec73b5854077f1c527416ccd7bJingoo Hanfail: 15662194244cf871aec73b5854077f1c527416ccd7bJingoo Han iounmap(hcd->regs); 15762194244cf871aec73b5854077f1c527416ccd7bJingoo Hanfail_io: 15862194244cf871aec73b5854077f1c527416ccd7bJingoo Han clk_disable(exynos_ohci->clk); 15962194244cf871aec73b5854077f1c527416ccd7bJingoo Hanfail_clken: 16062194244cf871aec73b5854077f1c527416ccd7bJingoo Han clk_put(exynos_ohci->clk); 16162194244cf871aec73b5854077f1c527416ccd7bJingoo Hanfail_clk: 16262194244cf871aec73b5854077f1c527416ccd7bJingoo Han usb_put_hcd(hcd); 16362194244cf871aec73b5854077f1c527416ccd7bJingoo Hanfail_hcd: 16462194244cf871aec73b5854077f1c527416ccd7bJingoo Han kfree(exynos_ohci); 16562194244cf871aec73b5854077f1c527416ccd7bJingoo Han return err; 16662194244cf871aec73b5854077f1c527416ccd7bJingoo Han} 16762194244cf871aec73b5854077f1c527416ccd7bJingoo Han 16862194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic int __devexit exynos_ohci_remove(struct platform_device *pdev) 16962194244cf871aec73b5854077f1c527416ccd7bJingoo Han{ 17062194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; 17162194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); 17262194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct usb_hcd *hcd = exynos_ohci->hcd; 17362194244cf871aec73b5854077f1c527416ccd7bJingoo Han 17462194244cf871aec73b5854077f1c527416ccd7bJingoo Han usb_remove_hcd(hcd); 17562194244cf871aec73b5854077f1c527416ccd7bJingoo Han 17662194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (pdata && pdata->phy_exit) 17762194244cf871aec73b5854077f1c527416ccd7bJingoo Han pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 17862194244cf871aec73b5854077f1c527416ccd7bJingoo Han 17962194244cf871aec73b5854077f1c527416ccd7bJingoo Han iounmap(hcd->regs); 18062194244cf871aec73b5854077f1c527416ccd7bJingoo Han 18162194244cf871aec73b5854077f1c527416ccd7bJingoo Han clk_disable(exynos_ohci->clk); 18262194244cf871aec73b5854077f1c527416ccd7bJingoo Han clk_put(exynos_ohci->clk); 18362194244cf871aec73b5854077f1c527416ccd7bJingoo Han 18462194244cf871aec73b5854077f1c527416ccd7bJingoo Han usb_put_hcd(hcd); 18562194244cf871aec73b5854077f1c527416ccd7bJingoo Han kfree(exynos_ohci); 18662194244cf871aec73b5854077f1c527416ccd7bJingoo Han 18762194244cf871aec73b5854077f1c527416ccd7bJingoo Han return 0; 18862194244cf871aec73b5854077f1c527416ccd7bJingoo Han} 18962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 19062194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic void exynos_ohci_shutdown(struct platform_device *pdev) 19162194244cf871aec73b5854077f1c527416ccd7bJingoo Han{ 19262194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); 19362194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct usb_hcd *hcd = exynos_ohci->hcd; 19462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 19562194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (hcd->driver->shutdown) 19662194244cf871aec73b5854077f1c527416ccd7bJingoo Han hcd->driver->shutdown(hcd); 19762194244cf871aec73b5854077f1c527416ccd7bJingoo Han} 19862194244cf871aec73b5854077f1c527416ccd7bJingoo Han 19962194244cf871aec73b5854077f1c527416ccd7bJingoo Han#ifdef CONFIG_PM 20062194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic int exynos_ohci_suspend(struct device *dev) 20162194244cf871aec73b5854077f1c527416ccd7bJingoo Han{ 20262194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); 20362194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct usb_hcd *hcd = exynos_ohci->hcd; 20462194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct ohci_hcd *ohci = hcd_to_ohci(hcd); 20562194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct platform_device *pdev = to_platform_device(dev); 20662194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; 20762194244cf871aec73b5854077f1c527416ccd7bJingoo Han unsigned long flags; 20862194244cf871aec73b5854077f1c527416ccd7bJingoo Han int rc = 0; 20962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 21062194244cf871aec73b5854077f1c527416ccd7bJingoo Han /* 21162194244cf871aec73b5854077f1c527416ccd7bJingoo Han * Root hub was already suspended. Disable irq emission and 21262194244cf871aec73b5854077f1c527416ccd7bJingoo Han * mark HW unaccessible, bail out if RH has been resumed. Use 21362194244cf871aec73b5854077f1c527416ccd7bJingoo Han * the spinlock to properly synchronize with possible pending 21462194244cf871aec73b5854077f1c527416ccd7bJingoo Han * RH suspend or resume activity. 21562194244cf871aec73b5854077f1c527416ccd7bJingoo Han */ 21662194244cf871aec73b5854077f1c527416ccd7bJingoo Han spin_lock_irqsave(&ohci->lock, flags); 2172b4ffe31a2380de7c893e345659b0730d6dc62d3Jingoo Han if (ohci->rh_state != OHCI_RH_SUSPENDED && 2182b4ffe31a2380de7c893e345659b0730d6dc62d3Jingoo Han ohci->rh_state != OHCI_RH_HALTED) { 21962194244cf871aec73b5854077f1c527416ccd7bJingoo Han rc = -EINVAL; 22062194244cf871aec73b5854077f1c527416ccd7bJingoo Han goto fail; 22162194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 22262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 22362194244cf871aec73b5854077f1c527416ccd7bJingoo Han clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 22462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 22562194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (pdata && pdata->phy_exit) 22662194244cf871aec73b5854077f1c527416ccd7bJingoo Han pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 22762194244cf871aec73b5854077f1c527416ccd7bJingoo Hanfail: 22862194244cf871aec73b5854077f1c527416ccd7bJingoo Han spin_unlock_irqrestore(&ohci->lock, flags); 22962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 23062194244cf871aec73b5854077f1c527416ccd7bJingoo Han return rc; 23162194244cf871aec73b5854077f1c527416ccd7bJingoo Han} 23262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 23362194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic int exynos_ohci_resume(struct device *dev) 23462194244cf871aec73b5854077f1c527416ccd7bJingoo Han{ 23562194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); 23662194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct usb_hcd *hcd = exynos_ohci->hcd; 23762194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct platform_device *pdev = to_platform_device(dev); 23862194244cf871aec73b5854077f1c527416ccd7bJingoo Han struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; 23962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 24062194244cf871aec73b5854077f1c527416ccd7bJingoo Han if (pdata && pdata->phy_init) 24162194244cf871aec73b5854077f1c527416ccd7bJingoo Han pdata->phy_init(pdev, S5P_USB_PHY_HOST); 24262194244cf871aec73b5854077f1c527416ccd7bJingoo Han 24362194244cf871aec73b5854077f1c527416ccd7bJingoo Han /* Mark hardware accessible again as we are out of D3 state by now */ 24462194244cf871aec73b5854077f1c527416ccd7bJingoo Han set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 24562194244cf871aec73b5854077f1c527416ccd7bJingoo Han 24662194244cf871aec73b5854077f1c527416ccd7bJingoo Han ohci_finish_controller_resume(hcd); 24762194244cf871aec73b5854077f1c527416ccd7bJingoo Han 24862194244cf871aec73b5854077f1c527416ccd7bJingoo Han return 0; 24962194244cf871aec73b5854077f1c527416ccd7bJingoo Han} 25062194244cf871aec73b5854077f1c527416ccd7bJingoo Han#else 25162194244cf871aec73b5854077f1c527416ccd7bJingoo Han#define exynos_ohci_suspend NULL 25262194244cf871aec73b5854077f1c527416ccd7bJingoo Han#define exynos_ohci_resume NULL 25362194244cf871aec73b5854077f1c527416ccd7bJingoo Han#endif 25462194244cf871aec73b5854077f1c527416ccd7bJingoo Han 25562194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic const struct dev_pm_ops exynos_ohci_pm_ops = { 25662194244cf871aec73b5854077f1c527416ccd7bJingoo Han .suspend = exynos_ohci_suspend, 25762194244cf871aec73b5854077f1c527416ccd7bJingoo Han .resume = exynos_ohci_resume, 25862194244cf871aec73b5854077f1c527416ccd7bJingoo Han}; 25962194244cf871aec73b5854077f1c527416ccd7bJingoo Han 26062194244cf871aec73b5854077f1c527416ccd7bJingoo Hanstatic struct platform_driver exynos_ohci_driver = { 26162194244cf871aec73b5854077f1c527416ccd7bJingoo Han .probe = exynos_ohci_probe, 26262194244cf871aec73b5854077f1c527416ccd7bJingoo Han .remove = __devexit_p(exynos_ohci_remove), 26362194244cf871aec73b5854077f1c527416ccd7bJingoo Han .shutdown = exynos_ohci_shutdown, 26462194244cf871aec73b5854077f1c527416ccd7bJingoo Han .driver = { 26562194244cf871aec73b5854077f1c527416ccd7bJingoo Han .name = "exynos-ohci", 26662194244cf871aec73b5854077f1c527416ccd7bJingoo Han .owner = THIS_MODULE, 26762194244cf871aec73b5854077f1c527416ccd7bJingoo Han .pm = &exynos_ohci_pm_ops, 26862194244cf871aec73b5854077f1c527416ccd7bJingoo Han } 26962194244cf871aec73b5854077f1c527416ccd7bJingoo Han}; 27062194244cf871aec73b5854077f1c527416ccd7bJingoo Han 27162194244cf871aec73b5854077f1c527416ccd7bJingoo HanMODULE_ALIAS("platform:exynos-ohci"); 27262194244cf871aec73b5854077f1c527416ccd7bJingoo HanMODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); 273