platform.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. * platform.c - DesignWare HS OTG Controller platform driver
  3. *
  4. * Copyright (C) Matthijs Kooijman <matthijs@stdin.nl>
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions, and the following disclaimer,
  11. * without modification.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. The names of the above-listed copyright holders may not be used
  16. * to endorse or promote products derived from this software without
  17. * specific prior written permission.
  18. *
  19. * ALTERNATIVELY, this software may be distributed under the terms of the
  20. * GNU General Public License ("GPL") as published by the Free Software
  21. * Foundation; either version 2 of the License, or (at your option) any
  22. * later version.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  25. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  26. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  27. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  28. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  29. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  30. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  31. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  32. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  33. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. #include <linux/kernel.h>
  37. #include <linux/module.h>
  38. #include <linux/slab.h>
  39. #include <linux/clk.h>
  40. #include <linux/device.h>
  41. #include <linux/dma-mapping.h>
  42. #include <linux/of_device.h>
  43. #include <linux/mutex.h>
  44. #include <linux/platform_device.h>
  45. #include <linux/phy/phy.h>
  46. #include <linux/platform_data/s3c-hsotg.h>
  47. #include <linux/usb/of.h>
  48. #include "core.h"
  49. #include "hcd.h"
  50. #include "debug.h"
  51. static const char dwc2_driver_name[] = "dwc2";
  52. static const struct dwc2_core_params params_hi6220 = {
  53. .otg_cap = 2, /* No HNP/SRP capable */
  54. .otg_ver = 0, /* 1.3 */
  55. .dma_enable = 1,
  56. .dma_desc_enable = 0,
  57. .dma_desc_fs_enable = 0,
  58. .speed = 0, /* High Speed */
  59. .enable_dynamic_fifo = 1,
  60. .en_multiple_tx_fifo = 1,
  61. .host_rx_fifo_size = 512,
  62. .host_nperio_tx_fifo_size = 512,
  63. .host_perio_tx_fifo_size = 512,
  64. .max_transfer_size = 65535,
  65. .max_packet_count = 511,
  66. .host_channels = 16,
  67. .phy_type = 1, /* UTMI */
  68. .phy_utmi_width = 8,
  69. .phy_ulpi_ddr = 0, /* Single */
  70. .phy_ulpi_ext_vbus = 0,
  71. .i2c_enable = 0,
  72. .ulpi_fs_ls = 0,
  73. .host_support_fs_ls_low_power = 0,
  74. .host_ls_low_power_phy_clk = 0, /* 48 MHz */
  75. .ts_dline = 0,
  76. .reload_ctl = 0,
  77. .ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
  78. GAHBCFG_HBSTLEN_SHIFT,
  79. .uframe_sched = 0,
  80. .external_id_pin_ctl = -1,
  81. .hibernation = -1,
  82. };
  83. static const struct dwc2_core_params params_bcm2835 = {
  84. .otg_cap = 0, /* HNP/SRP capable */
  85. .otg_ver = 0, /* 1.3 */
  86. .dma_enable = 1,
  87. .dma_desc_enable = 0,
  88. .dma_desc_fs_enable = 0,
  89. .speed = 0, /* High Speed */
  90. .enable_dynamic_fifo = 1,
  91. .en_multiple_tx_fifo = 1,
  92. .host_rx_fifo_size = 774, /* 774 DWORDs */
  93. .host_nperio_tx_fifo_size = 256, /* 256 DWORDs */
  94. .host_perio_tx_fifo_size = 512, /* 512 DWORDs */
  95. .max_transfer_size = 65535,
  96. .max_packet_count = 511,
  97. .host_channels = 8,
  98. .phy_type = 1, /* UTMI */
  99. .phy_utmi_width = 8, /* 8 bits */
  100. .phy_ulpi_ddr = 0, /* Single */
  101. .phy_ulpi_ext_vbus = 0,
  102. .i2c_enable = 0,
  103. .ulpi_fs_ls = 0,
  104. .host_support_fs_ls_low_power = 0,
  105. .host_ls_low_power_phy_clk = 0, /* 48 MHz */
  106. .ts_dline = 0,
  107. .reload_ctl = 0,
  108. .ahbcfg = 0x10,
  109. .uframe_sched = 0,
  110. .external_id_pin_ctl = -1,
  111. .hibernation = -1,
  112. };
  113. static const struct dwc2_core_params params_rk3066 = {
  114. .otg_cap = 2, /* non-HNP/non-SRP */
  115. .otg_ver = -1,
  116. .dma_enable = -1,
  117. .dma_desc_enable = 0,
  118. .dma_desc_fs_enable = 0,
  119. .speed = -1,
  120. .enable_dynamic_fifo = 1,
  121. .en_multiple_tx_fifo = -1,
  122. .host_rx_fifo_size = 525, /* 525 DWORDs */
  123. .host_nperio_tx_fifo_size = 128, /* 128 DWORDs */
  124. .host_perio_tx_fifo_size = 256, /* 256 DWORDs */
  125. .max_transfer_size = -1,
  126. .max_packet_count = -1,
  127. .host_channels = -1,
  128. .phy_type = -1,
  129. .phy_utmi_width = -1,
  130. .phy_ulpi_ddr = -1,
  131. .phy_ulpi_ext_vbus = -1,
  132. .i2c_enable = -1,
  133. .ulpi_fs_ls = -1,
  134. .host_support_fs_ls_low_power = -1,
  135. .host_ls_low_power_phy_clk = -1,
  136. .ts_dline = -1,
  137. .reload_ctl = -1,
  138. .ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
  139. GAHBCFG_HBSTLEN_SHIFT,
  140. .uframe_sched = -1,
  141. .external_id_pin_ctl = -1,
  142. .hibernation = -1,
  143. };
  144. /*
  145. * Check the dr_mode against the module configuration and hardware
  146. * capabilities.
  147. *
  148. * The hardware, module, and dr_mode, can each be set to host, device,
  149. * or otg. Check that all these values are compatible and adjust the
  150. * value of dr_mode if possible.
  151. *
  152. * actual
  153. * HW MOD dr_mode dr_mode
  154. * ------------------------------
  155. * HST HST any : HST
  156. * HST DEV any : ---
  157. * HST OTG any : HST
  158. *
  159. * DEV HST any : ---
  160. * DEV DEV any : DEV
  161. * DEV OTG any : DEV
  162. *
  163. * OTG HST any : HST
  164. * OTG DEV any : DEV
  165. * OTG OTG any : dr_mode
  166. */
  167. static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
  168. {
  169. enum usb_dr_mode mode;
  170. hsotg->dr_mode = usb_get_dr_mode(hsotg->dev);
  171. if (hsotg->dr_mode == USB_DR_MODE_UNKNOWN)
  172. hsotg->dr_mode = USB_DR_MODE_OTG;
  173. mode = hsotg->dr_mode;
  174. if (dwc2_hw_is_device(hsotg)) {
  175. if (IS_ENABLED(CONFIG_USB_DWC2_HOST)) {
  176. dev_err(hsotg->dev,
  177. "Controller does not support host mode.\n");
  178. return -EINVAL;
  179. }
  180. mode = USB_DR_MODE_PERIPHERAL;
  181. } else if (dwc2_hw_is_host(hsotg)) {
  182. if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL)) {
  183. dev_err(hsotg->dev,
  184. "Controller does not support device mode.\n");
  185. return -EINVAL;
  186. }
  187. mode = USB_DR_MODE_HOST;
  188. } else {
  189. if (IS_ENABLED(CONFIG_USB_DWC2_HOST))
  190. mode = USB_DR_MODE_HOST;
  191. else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL))
  192. mode = USB_DR_MODE_PERIPHERAL;
  193. }
  194. if (mode != hsotg->dr_mode) {
  195. dev_warn(hsotg->dev,
  196. "Configuration mismatch. dr_mode forced to %s\n",
  197. mode == USB_DR_MODE_HOST ? "host" : "device");
  198. hsotg->dr_mode = mode;
  199. }
  200. return 0;
  201. }
  202. static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
  203. {
  204. struct platform_device *pdev = to_platform_device(hsotg->dev);
  205. int ret;
  206. ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
  207. hsotg->supplies);
  208. if (ret)
  209. return ret;
  210. if (hsotg->clk) {
  211. ret = clk_prepare_enable(hsotg->clk);
  212. if (ret)
  213. return ret;
  214. }
  215. if (hsotg->uphy)
  216. ret = usb_phy_init(hsotg->uphy);
  217. else if (hsotg->plat && hsotg->plat->phy_init)
  218. ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
  219. else {
  220. ret = phy_power_on(hsotg->phy);
  221. if (ret == 0)
  222. ret = phy_init(hsotg->phy);
  223. }
  224. return ret;
  225. }
  226. /**
  227. * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources
  228. * @hsotg: The driver state
  229. *
  230. * A wrapper for platform code responsible for controlling
  231. * low-level USB platform resources (phy, clock, regulators)
  232. */
  233. int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
  234. {
  235. int ret = __dwc2_lowlevel_hw_enable(hsotg);
  236. if (ret == 0)
  237. hsotg->ll_hw_enabled = true;
  238. return ret;
  239. }
  240. static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
  241. {
  242. struct platform_device *pdev = to_platform_device(hsotg->dev);
  243. int ret = 0;
  244. if (hsotg->uphy)
  245. usb_phy_shutdown(hsotg->uphy);
  246. else if (hsotg->plat && hsotg->plat->phy_exit)
  247. ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
  248. else {
  249. ret = phy_exit(hsotg->phy);
  250. if (ret == 0)
  251. ret = phy_power_off(hsotg->phy);
  252. }
  253. if (ret)
  254. return ret;
  255. if (hsotg->clk)
  256. clk_disable_unprepare(hsotg->clk);
  257. ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
  258. hsotg->supplies);
  259. return ret;
  260. }
  261. /**
  262. * dwc2_lowlevel_hw_disable - disable platform lowlevel hw resources
  263. * @hsotg: The driver state
  264. *
  265. * A wrapper for platform code responsible for controlling
  266. * low-level USB platform resources (phy, clock, regulators)
  267. */
  268. int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
  269. {
  270. int ret = __dwc2_lowlevel_hw_disable(hsotg);
  271. if (ret == 0)
  272. hsotg->ll_hw_enabled = false;
  273. return ret;
  274. }
  275. static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
  276. {
  277. int i, ret;
  278. /* Set default UTMI width */
  279. hsotg->phyif = GUSBCFG_PHYIF16;
  280. /*
  281. * Attempt to find a generic PHY, then look for an old style
  282. * USB PHY and then fall back to pdata
  283. */
  284. hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
  285. if (IS_ERR(hsotg->phy)) {
  286. ret = PTR_ERR(hsotg->phy);
  287. switch (ret) {
  288. case -ENODEV:
  289. case -ENOSYS:
  290. hsotg->phy = NULL;
  291. break;
  292. case -EPROBE_DEFER:
  293. return ret;
  294. default:
  295. dev_err(hsotg->dev, "error getting phy %d\n", ret);
  296. return ret;
  297. }
  298. }
  299. if (!hsotg->phy) {
  300. hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
  301. if (IS_ERR(hsotg->uphy)) {
  302. ret = PTR_ERR(hsotg->uphy);
  303. switch (ret) {
  304. case -ENODEV:
  305. case -ENXIO:
  306. hsotg->uphy = NULL;
  307. break;
  308. case -EPROBE_DEFER:
  309. return ret;
  310. default:
  311. dev_err(hsotg->dev, "error getting usb phy %d\n",
  312. ret);
  313. return ret;
  314. }
  315. }
  316. }
  317. hsotg->plat = dev_get_platdata(hsotg->dev);
  318. if (hsotg->phy) {
  319. /*
  320. * If using the generic PHY framework, check if the PHY bus
  321. * width is 8-bit and set the phyif appropriately.
  322. */
  323. if (phy_get_bus_width(hsotg->phy) == 8)
  324. hsotg->phyif = GUSBCFG_PHYIF8;
  325. }
  326. /* Clock */
  327. hsotg->clk = devm_clk_get(hsotg->dev, "otg");
  328. if (IS_ERR(hsotg->clk)) {
  329. hsotg->clk = NULL;
  330. dev_dbg(hsotg->dev, "cannot get otg clock\n");
  331. }
  332. /* Regulators */
  333. for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
  334. hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
  335. ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies),
  336. hsotg->supplies);
  337. if (ret) {
  338. dev_err(hsotg->dev, "failed to request supplies: %d\n", ret);
  339. return ret;
  340. }
  341. return 0;
  342. }
  343. /**
  344. * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
  345. * DWC_otg driver
  346. *
  347. * @dev: Platform device
  348. *
  349. * This routine is called, for example, when the rmmod command is executed. The
  350. * device may or may not be electrically present. If it is present, the driver
  351. * stops device processing. Any resources used on behalf of this device are
  352. * freed.
  353. */
  354. static int dwc2_driver_remove(struct platform_device *dev)
  355. {
  356. struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
  357. dwc2_debugfs_exit(hsotg);
  358. if (hsotg->hcd_enabled)
  359. dwc2_hcd_remove(hsotg);
  360. if (hsotg->gadget_enabled)
  361. dwc2_hsotg_remove(hsotg);
  362. if (hsotg->ll_hw_enabled)
  363. dwc2_lowlevel_hw_disable(hsotg);
  364. return 0;
  365. }
  366. /**
  367. * dwc2_driver_shutdown() - Called on device shutdown
  368. *
  369. * @dev: Platform device
  370. *
  371. * In specific conditions (involving usb hubs) dwc2 devices can create a
  372. * lot of interrupts, even to the point of overwhelming devices running
  373. * at low frequencies. Some devices need to do special clock handling
  374. * at shutdown-time which may bring the system clock below the threshold
  375. * of being able to handle the dwc2 interrupts. Disabling dwc2-irqs
  376. * prevents reboots/poweroffs from getting stuck in such cases.
  377. */
  378. static void dwc2_driver_shutdown(struct platform_device *dev)
  379. {
  380. struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
  381. disable_irq(hsotg->irq);
  382. }
  383. static const struct of_device_id dwc2_of_match_table[] = {
  384. { .compatible = "brcm,bcm2835-usb", .data = &params_bcm2835 },
  385. { .compatible = "hisilicon,hi6220-usb", .data = &params_hi6220 },
  386. { .compatible = "rockchip,rk3066-usb", .data = &params_rk3066 },
  387. { .compatible = "snps,dwc2", .data = NULL },
  388. { .compatible = "samsung,s3c6400-hsotg", .data = NULL},
  389. {},
  390. };
  391. MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
  392. /**
  393. * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg
  394. * driver
  395. *
  396. * @dev: Platform device
  397. *
  398. * This routine creates the driver components required to control the device
  399. * (core, HCD, and PCD) and initializes the device. The driver components are
  400. * stored in a dwc2_hsotg structure. A reference to the dwc2_hsotg is saved
  401. * in the device private data. This allows the driver to access the dwc2_hsotg
  402. * structure on subsequent calls to driver methods for this device.
  403. */
  404. static int dwc2_driver_probe(struct platform_device *dev)
  405. {
  406. const struct of_device_id *match;
  407. const struct dwc2_core_params *params;
  408. struct dwc2_core_params defparams;
  409. struct dwc2_hsotg *hsotg;
  410. struct resource *res;
  411. int retval;
  412. match = of_match_device(dwc2_of_match_table, &dev->dev);
  413. if (match && match->data) {
  414. params = match->data;
  415. } else {
  416. /* Default all params to autodetect */
  417. dwc2_set_all_params(&defparams, -1);
  418. params = &defparams;
  419. /*
  420. * Disable descriptor dma mode by default as the HW can support
  421. * it, but does not support it for SPLIT transactions.
  422. * Disable it for FS devices as well.
  423. */
  424. defparams.dma_desc_enable = 0;
  425. defparams.dma_desc_fs_enable = 0;
  426. }
  427. hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
  428. if (!hsotg)
  429. return -ENOMEM;
  430. hsotg->dev = &dev->dev;
  431. /*
  432. * Use reasonable defaults so platforms don't have to provide these.
  433. */
  434. if (!dev->dev.dma_mask)
  435. dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
  436. retval = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
  437. if (retval)
  438. return retval;
  439. res = platform_get_resource(dev, IORESOURCE_MEM, 0);
  440. hsotg->regs = devm_ioremap_resource(&dev->dev, res);
  441. if (IS_ERR(hsotg->regs))
  442. return PTR_ERR(hsotg->regs);
  443. dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
  444. (unsigned long)res->start, hsotg->regs);
  445. retval = dwc2_lowlevel_hw_init(hsotg);
  446. if (retval)
  447. return retval;
  448. spin_lock_init(&hsotg->lock);
  449. hsotg->core_params = devm_kzalloc(&dev->dev,
  450. sizeof(*hsotg->core_params), GFP_KERNEL);
  451. if (!hsotg->core_params)
  452. return -ENOMEM;
  453. dwc2_set_all_params(hsotg->core_params, -1);
  454. hsotg->irq = platform_get_irq(dev, 0);
  455. if (hsotg->irq < 0) {
  456. dev_err(&dev->dev, "missing IRQ resource\n");
  457. return hsotg->irq;
  458. }
  459. dev_dbg(hsotg->dev, "registering common handler for irq%d\n",
  460. hsotg->irq);
  461. retval = devm_request_irq(hsotg->dev, hsotg->irq,
  462. dwc2_handle_common_intr, IRQF_SHARED,
  463. dev_name(hsotg->dev), hsotg);
  464. if (retval)
  465. return retval;
  466. retval = dwc2_lowlevel_hw_enable(hsotg);
  467. if (retval)
  468. return retval;
  469. retval = dwc2_get_dr_mode(hsotg);
  470. if (retval)
  471. return retval;
  472. /*
  473. * Reset before dwc2_get_hwparams() then it could get power-on real
  474. * reset value form registers.
  475. */
  476. dwc2_core_reset_and_force_dr_mode(hsotg);
  477. /* Detect config values from hardware */
  478. retval = dwc2_get_hwparams(hsotg);
  479. if (retval)
  480. goto error;
  481. /* Validate parameter values */
  482. dwc2_set_parameters(hsotg, params);
  483. dwc2_force_dr_mode(hsotg);
  484. if (hsotg->dr_mode != USB_DR_MODE_HOST) {
  485. retval = dwc2_gadget_init(hsotg, hsotg->irq);
  486. if (retval)
  487. goto error;
  488. hsotg->gadget_enabled = 1;
  489. }
  490. if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
  491. retval = dwc2_hcd_init(hsotg, hsotg->irq);
  492. if (retval) {
  493. if (hsotg->gadget_enabled)
  494. dwc2_hsotg_remove(hsotg);
  495. goto error;
  496. }
  497. hsotg->hcd_enabled = 1;
  498. }
  499. platform_set_drvdata(dev, hsotg);
  500. dwc2_debugfs_init(hsotg);
  501. /* Gadget code manages lowlevel hw on its own */
  502. if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
  503. dwc2_lowlevel_hw_disable(hsotg);
  504. return 0;
  505. error:
  506. dwc2_lowlevel_hw_disable(hsotg);
  507. return retval;
  508. }
  509. static int __maybe_unused dwc2_suspend(struct device *dev)
  510. {
  511. struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
  512. int ret = 0;
  513. if (dwc2_is_device_mode(dwc2))
  514. dwc2_hsotg_suspend(dwc2);
  515. if (dwc2->ll_hw_enabled)
  516. ret = __dwc2_lowlevel_hw_disable(dwc2);
  517. return ret;
  518. }
  519. static int __maybe_unused dwc2_resume(struct device *dev)
  520. {
  521. struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
  522. int ret = 0;
  523. if (dwc2->ll_hw_enabled) {
  524. ret = __dwc2_lowlevel_hw_enable(dwc2);
  525. if (ret)
  526. return ret;
  527. }
  528. if (dwc2_is_device_mode(dwc2))
  529. ret = dwc2_hsotg_resume(dwc2);
  530. return ret;
  531. }
  532. static const struct dev_pm_ops dwc2_dev_pm_ops = {
  533. SET_SYSTEM_SLEEP_PM_OPS(dwc2_suspend, dwc2_resume)
  534. };
  535. static struct platform_driver dwc2_platform_driver = {
  536. .driver = {
  537. .name = dwc2_driver_name,
  538. .of_match_table = dwc2_of_match_table,
  539. .pm = &dwc2_dev_pm_ops,
  540. },
  541. .probe = dwc2_driver_probe,
  542. .remove = dwc2_driver_remove,
  543. .shutdown = dwc2_driver_shutdown,
  544. };
  545. module_platform_driver(dwc2_platform_driver);
  546. MODULE_DESCRIPTION("DESIGNWARE HS OTG Platform Glue");
  547. MODULE_AUTHOR("Matthijs Kooijman <matthijs@stdin.nl>");
  548. MODULE_LICENSE("Dual BSD/GPL");