partially Revert "usb: musb: Set the DT node on the child device"
[linux-2.6-block.git] / drivers / usb / musb / omap2430.c
CommitLineData
5fd54ace 1// SPDX-License-Identifier: GPL-2.0
550a7375
FB
2/*
3 * Copyright (C) 2005-2007 by Texas Instruments
4 * Some code has been taken from tusb6010.c
5 * Copyrights for that are attributable to:
6 * Copyright (C) 2006 Nokia Corporation
550a7375
FB
7 * Tony Lindgren <tony@atomide.com>
8 *
9 * This file is part of the Inventra Controller Driver for Linux.
550a7375
FB
10 */
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
550a7375
FB
14#include <linux/init.h>
15#include <linux/list.h>
550a7375 16#include <linux/io.h>
00a0b1d5 17#include <linux/of.h>
dc09886b
FB
18#include <linux/platform_device.h>
19#include <linux/dma-mapping.h>
207b0e1f
HH
20#include <linux/pm_runtime.h>
21#include <linux/err.h>
12a19b5f 22#include <linux/delay.h>
8055555f 23#include <linux/usb/musb.h>
14da699b 24#include <linux/phy/omap_control_phy.h>
8934d3e4 25#include <linux/of_platform.h>
550a7375 26
550a7375
FB
27#include "musb_core.h"
28#include "omap2430.h"
29
a3cee12a
FB
30struct omap2430_glue {
31 struct device *dev;
32 struct platform_device *musb;
8055555f 33 enum musb_vbus_id_status status;
1e5acb8d 34 struct work_struct omap_musb_mailbox_work;
ca784be3 35 struct device *control_otghs;
62d472d8
TL
36 unsigned int is_runtime_suspended:1;
37 unsigned int needs_resume:1;
68d9f95d 38 unsigned int phy_suspended:1;
a3cee12a 39};
c20aebb9 40#define glue_to_musb(g) platform_get_drvdata(g->musb)
a3cee12a 41
4b58ed11 42static struct omap2430_glue *_glue;
c9721438 43
c20aebb9
FB
44static inline void omap2430_low_level_exit(struct musb *musb)
45{
46 u32 l;
47
48 /* in any role */
49 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
50 l |= ENABLEFORCE; /* enable MSTANDBY */
51 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
c20aebb9
FB
52}
53
54static inline void omap2430_low_level_init(struct musb *musb)
55{
56 u32 l;
57
c20aebb9
FB
58 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
59 l &= ~ENABLEFORCE; /* disable MSTANDBY */
60 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
61}
62
12b7db2b 63static int omap2430_musb_mailbox(enum musb_vbus_id_status status)
594632ef 64{
c9721438 65 struct omap2430_glue *glue = _glue;
712d8efa 66
f8c4b0e7
AK
67 if (!glue) {
68 pr_err("%s: musb core is not yet initialized\n", __func__);
12b7db2b 69 return -EPROBE_DEFER;
f8c4b0e7
AK
70 }
71 glue->status = status;
72
73 if (!glue_to_musb(glue)) {
80ab72e1 74 pr_err("%s: musb core is not yet ready\n", __func__);
12b7db2b 75 return -EPROBE_DEFER;
c9721438 76 }
712d8efa 77
c9721438 78 schedule_work(&glue->omap_musb_mailbox_work);
12b7db2b
TL
79
80 return 0;
712d8efa
VP
81}
82
98827105
TL
83/*
84 * HDRC controls CPEN, but beware current surges during device connect.
85 * They can trigger transient overcurrent conditions that must be ignored.
86 *
87 * Note that we're skipping A_WAIT_VFALL -> A_IDLE and jumping right to B_IDLE
88 * as set by musb_set_peripheral().
89 */
c9721438 90static void omap_musb_set_mailbox(struct omap2430_glue *glue)
712d8efa 91{
1e5acb8d 92 struct musb *musb = glue_to_musb(glue);
98827105 93 int error;
594632ef 94
ae909fe4 95 pm_runtime_get_sync(musb->controller);
98827105
TL
96
97 dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
98 usb_otg_state_string(musb->xceiv->otg->state),
99 musb_readb(musb->mregs, MUSB_DEVCTL));
100
c9721438 101 switch (glue->status) {
8055555f 102 case MUSB_ID_GROUND:
ae909fe4 103 dev_dbg(musb->controller, "ID GND\n");
15f1122f 104 switch (musb->xceiv->otg->state) {
98827105
TL
105 case OTG_STATE_A_IDLE:
106 error = musb_set_host(musb);
107 if (error)
108 break;
109 musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
df561f66 110 fallthrough;
15f1122f
TL
111 case OTG_STATE_A_WAIT_VRISE:
112 case OTG_STATE_A_WAIT_BCON:
113 case OTG_STATE_A_HOST:
15f1122f
TL
114 /*
115 * On multiple ID ground interrupts just keep enabling
116 * VBUS. At least cpcap VBUS shuts down otherwise.
117 */
98827105 118 otg_set_vbus(musb->xceiv->otg, 1);
15f1122f
TL
119 break;
120 default:
121 musb->xceiv->otg->state = OTG_STATE_A_IDLE;
122 musb->xceiv->last_event = USB_EVENT_ID;
123 if (musb->gadget_driver) {
124 omap_control_usb_set_mode(glue->control_otghs,
125 USB_MODE_HOST);
98827105 126 otg_set_vbus(musb->xceiv->otg, 1);
15f1122f
TL
127 }
128 break;
594632ef
HH
129 }
130 break;
131
8055555f 132 case MUSB_VBUS_VALID:
ae909fe4 133 dev_dbg(musb->controller, "VBUS Connect\n");
594632ef 134
e47d9254 135 musb->xceiv->otg->state = OTG_STATE_B_IDLE;
c9721438 136 musb->xceiv->last_event = USB_EVENT_VBUS;
ca784be3 137 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
594632ef
HH
138 break;
139
8055555f
TL
140 case MUSB_ID_FLOAT:
141 case MUSB_VBUS_OFF:
ae909fe4 142 dev_dbg(musb->controller, "VBUS Disconnect\n");
594632ef 143
c9721438 144 musb->xceiv->last_event = USB_EVENT_NONE;
98827105
TL
145 musb_set_peripheral(musb);
146 otg_set_vbus(musb->xceiv->otg, 0);
ca784be3
KVA
147 omap_control_usb_set_mode(glue->control_otghs,
148 USB_MODE_DISCONNECT);
594632ef
HH
149 break;
150 default:
ae909fe4 151 dev_dbg(musb->controller, "ID float\n");
594632ef 152 }
ae909fe4
TL
153 pm_runtime_mark_last_busy(musb->controller);
154 pm_runtime_put_autosuspend(musb->controller);
6fa7178c
PR
155 atomic_notifier_call_chain(&musb->xceiv->notifier,
156 musb->xceiv->last_event, NULL);
594632ef
HH
157}
158
c9721438
KVA
159
160static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
161{
162 struct omap2430_glue *glue = container_of(mailbox_work,
163 struct omap2430_glue, omap_musb_mailbox_work);
8b2bc2c9 164
c9721438
KVA
165 omap_musb_set_mailbox(glue);
166}
167
baef653a
PDS
168static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci)
169{
170 unsigned long flags;
171 irqreturn_t retval = IRQ_NONE;
172 struct musb *musb = __hci;
173
174 spin_lock_irqsave(&musb->lock, flags);
175
176 musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
177 musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
178 musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
179
180 if (musb->int_usb || musb->int_tx || musb->int_rx)
181 retval = musb_interrupt(musb);
182
183 spin_unlock_irqrestore(&musb->lock, flags);
184
185 return retval;
186}
187
743411b3 188static int omap2430_musb_init(struct musb *musb)
550a7375 189{
ad579699
S
190 u32 l;
191 int status = 0;
ea65df57 192 struct device *dev = musb->controller;
c1a7d67c 193 struct musb_hdrc_platform_data *plat = dev_get_platdata(dev);
ea65df57 194 struct omap_musb_board_data *data = plat->board_data;
550a7375 195
84e250ff
DB
196 /* We require some kind of external transceiver, hooked
197 * up through ULPI. TWL4030-family PMICs include one,
198 * which needs a driver, drivers aren't always needed.
199 */
5ee1787e
JH
200 musb->phy = devm_phy_get(dev->parent, "usb2-phy");
201
202 /* We can't totally remove musb->xceiv as of now because
203 * musb core uses xceiv.state and xceiv.otg. Once we have
204 * a separate state machine to handle otg, these can be moved
205 * out of xceiv and then we can start using the generic PHY
206 * framework
207 */
208 musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
b16604f2 209
a90199bb
FB
210 if (IS_ERR(musb->xceiv)) {
211 status = PTR_ERR(musb->xceiv);
212
213 if (status == -ENXIO)
214 return status;
215
dc66ba8d 216 dev_dbg(dev, "HS USB OTG: no transceiver configured\n");
25736e0c 217 return -EPROBE_DEFER;
84e250ff
DB
218 }
219
3e3101d5 220 if (IS_ERR(musb->phy)) {
71127a79 221 dev_err(dev, "HS USB OTG: no PHY configured\n");
3e3101d5
KVA
222 return PTR_ERR(musb->phy);
223 }
baef653a 224 musb->isr = omap2430_musb_interrupt;
a83e17d0 225 phy_init(musb->phy);
d8e5f0ec 226 phy_power_on(musb->phy);
baef653a 227
8573e6a6 228 l = musb_readl(musb->mregs, OTG_INTERFSEL);
de2e1b0c
MM
229
230 if (data->interface_type == MUSB_INTERFACE_UTMI) {
231 /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */
232 l &= ~ULPI_12PIN; /* Disable ULPI */
233 l |= UTMI_8BIT; /* Enable UTMI */
234 } else {
235 l |= ULPI_12PIN;
236 }
237
8573e6a6 238 musb_writel(musb->mregs, OTG_INTERFSEL, l);
550a7375 239
71127a79 240 dev_dbg(dev, "HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
550a7375 241 "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
8573e6a6
FB
242 musb_readl(musb->mregs, OTG_REVISION),
243 musb_readl(musb->mregs, OTG_SYSCONFIG),
244 musb_readl(musb->mregs, OTG_SYSSTATUS),
245 musb_readl(musb->mregs, OTG_INTERFSEL),
246 musb_readl(musb->mregs, OTG_SIMENABLE));
550a7375 247
550a7375
FB
248 return 0;
249}
250
002eda13
HH
251static void omap2430_musb_enable(struct musb *musb)
252{
002eda13 253 struct device *dev = musb->controller;
c9721438 254 struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
a83e17d0 255
8b359cbc
TL
256 if (glue->status == MUSB_UNKNOWN)
257 glue->status = MUSB_VBUS_OFF;
258 omap_musb_set_mailbox(glue);
002eda13
HH
259}
260
261static void omap2430_musb_disable(struct musb *musb)
262{
c9721438
KVA
263 struct device *dev = musb->controller;
264 struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
265
8055555f 266 if (glue->status != MUSB_UNKNOWN)
ca784be3
KVA
267 omap_control_usb_set_mode(glue->control_otghs,
268 USB_MODE_DISCONNECT);
550a7375
FB
269}
270
743411b3 271static int omap2430_musb_exit(struct musb *musb)
550a7375 272{
a83e17d0
TL
273 struct device *dev = musb->controller;
274 struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
550a7375 275
c20aebb9 276 omap2430_low_level_exit(musb);
d8e5f0ec 277 phy_power_off(musb->phy);
3e3101d5 278 phy_exit(musb->phy);
a83e17d0
TL
279 musb->phy = NULL;
280 cancel_work_sync(&glue->omap_musb_mailbox_work);
c20aebb9 281
550a7375
FB
282 return 0;
283}
743411b3 284
f7ec9437 285static const struct musb_platform_ops omap2430_ops = {
f8e9f34f 286 .quirks = MUSB_DMA_INVENTRA,
7f6283ed
TL
287#ifdef CONFIG_USB_INVENTRA_DMA
288 .dma_init = musbhs_dma_controller_create,
289 .dma_exit = musbhs_dma_controller_destroy,
290#endif
743411b3
FB
291 .init = omap2430_musb_init,
292 .exit = omap2430_musb_exit,
293
002eda13
HH
294 .enable = omap2430_musb_enable,
295 .disable = omap2430_musb_disable,
8055555f
TL
296
297 .phy_callback = omap2430_musb_mailbox,
743411b3 298};
dc09886b
FB
299
300static u64 omap2430_dmamask = DMA_BIT_MASK(32);
301
41ac7b3a 302static int omap2430_probe(struct platform_device *pdev)
dc09886b 303{
c1a7d67c 304 struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
00a0b1d5 305 struct omap_musb_board_data *data;
dc09886b 306 struct platform_device *musb;
a3cee12a 307 struct omap2430_glue *glue;
00a0b1d5
KVA
308 struct device_node *np = pdev->dev.of_node;
309 struct musb_hdrc_config *config;
5ee1787e
JH
310 struct device_node *control_node;
311 struct platform_device *control_pdev;
606bf4d5 312 int ret = -ENOMEM, val;
dc09886b 313
5ee1787e
JH
314 if (!np)
315 return -ENODEV;
316
b1183c24 317 glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
af1bdfc9 318 if (!glue)
a3cee12a 319 goto err0;
a3cee12a 320
2f771164 321 musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
dc09886b
FB
322 if (!musb) {
323 dev_err(&pdev->dev, "failed to allocate musb device\n");
2f771164 324 goto err0;
dc09886b
FB
325 }
326
327 musb->dev.parent = &pdev->dev;
328 musb->dev.dma_mask = &omap2430_dmamask;
329 musb->dev.coherent_dma_mask = omap2430_dmamask;
330
a3cee12a
FB
331 glue->dev = &pdev->dev;
332 glue->musb = musb;
8055555f 333 glue->status = MUSB_UNKNOWN;
8934d3e4 334 glue->control_otghs = ERR_PTR(-ENODEV);
a3cee12a 335
5ee1787e
JH
336 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
337 if (!pdata)
338 goto err2;
339
340 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
341 if (!data)
342 goto err2;
343
344 config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
345 if (!config)
346 goto err2;
347
348 of_property_read_u32(np, "mode", (u32 *)&pdata->mode);
349 of_property_read_u32(np, "interface-type",
350 (u32 *)&data->interface_type);
351 of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
352 of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
353 of_property_read_u32(np, "power", (u32 *)&pdata->power);
354
355 ret = of_property_read_u32(np, "multipoint", &val);
356 if (!ret && val)
357 config->multipoint = true;
358
359 pdata->board_data = data;
360 pdata->config = config;
361
362 control_node = of_parse_phandle(np, "ctrl-module", 0);
363 if (control_node) {
364 control_pdev = of_find_device_by_node(control_node);
365 if (!control_pdev) {
366 dev_err(&pdev->dev, "Failed to get control device\n");
367 ret = -EINVAL;
2f771164 368 goto err2;
ca784be3 369 }
5ee1787e 370 glue->control_otghs = &control_pdev->dev;
ca784be3 371 }
5ee1787e 372
f7ec9437
FB
373 pdata->platform_ops = &omap2430_ops;
374
a3cee12a 375 platform_set_drvdata(pdev, glue);
dc09886b 376
c9721438
KVA
377 /*
378 * REVISIT if we ever have two instances of the wrapper, we will be
379 * in big trouble
380 */
381 _glue = glue;
382
1e5acb8d
KVA
383 INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
384
9879c81b 385 ret = platform_device_add_resources(musb, pdev->resource, pdev->num_resources);
dc09886b
FB
386 if (ret) {
387 dev_err(&pdev->dev, "failed to add resources\n");
65b3d52d 388 goto err2;
dc09886b
FB
389 }
390
391 ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
392 if (ret) {
393 dev_err(&pdev->dev, "failed to add platform_data\n");
65b3d52d 394 goto err2;
dc09886b
FB
395 }
396
87326e85 397 pm_runtime_enable(glue->dev);
3006dc8c 398
dc09886b
FB
399 ret = platform_device_add(musb);
400 if (ret) {
401 dev_err(&pdev->dev, "failed to register musb device\n");
536d599d 402 goto err3;
dc09886b
FB
403 }
404
207b0e1f 405 return 0;
03491761 406
536d599d
TL
407err3:
408 pm_runtime_disable(glue->dev);
409
65b3d52d 410err2:
b1183c24 411 platform_device_put(musb);
a3cee12a 412
dc09886b
FB
413err0:
414 return ret;
415}
416
fb4e98ab 417static int omap2430_remove(struct platform_device *pdev)
dc09886b 418{
21f77bee 419 struct omap2430_glue *glue = platform_get_drvdata(pdev);
dc09886b 420
f039df58 421 platform_device_unregister(glue->musb);
03e43528 422 pm_runtime_disable(glue->dev);
dc09886b
FB
423
424 return 0;
425}
426
c20aebb9 427#ifdef CONFIG_PM
c20aebb9 428
7acc6197 429static int omap2430_runtime_suspend(struct device *dev)
c20aebb9
FB
430{
431 struct omap2430_glue *glue = dev_get_drvdata(dev);
432 struct musb *musb = glue_to_musb(glue);
433
a83e17d0
TL
434 if (!musb)
435 return 0;
e25bec16 436
a83e17d0
TL
437 musb->context.otg_interfsel = musb_readl(musb->mregs,
438 OTG_INTERFSEL);
439
440 omap2430_low_level_exit(musb);
c20aebb9 441
68d9f95d
TL
442 if (!glue->phy_suspended) {
443 phy_power_off(musb->phy);
444 phy_exit(musb->phy);
445 }
10ac7e77 446
62d472d8
TL
447 glue->is_runtime_suspended = 1;
448
c20aebb9
FB
449 return 0;
450}
451
7acc6197 452static int omap2430_runtime_resume(struct device *dev)
c20aebb9
FB
453{
454 struct omap2430_glue *glue = dev_get_drvdata(dev);
455 struct musb *musb = glue_to_musb(glue);
c20aebb9 456
8f2279d5 457 if (!musb)
a83e17d0 458 return 0;
8f2279d5 459
68d9f95d
TL
460 if (!glue->phy_suspended) {
461 phy_init(musb->phy);
462 phy_power_on(musb->phy);
463 }
10ac7e77 464
8f2279d5
TL
465 omap2430_low_level_init(musb);
466 musb_writel(musb->mregs, OTG_INTERFSEL,
467 musb->context.otg_interfsel);
c20aebb9 468
ce3ab650
TL
469 /* Wait for musb to get oriented. Otherwise we can get babble */
470 usleep_range(200000, 250000);
471
62d472d8
TL
472 glue->is_runtime_suspended = 0;
473
c20aebb9
FB
474 return 0;
475}
476
68d9f95d 477/* I2C and SPI PHYs need to be suspended before the glue layer */
62d472d8 478static int omap2430_suspend(struct device *dev)
68d9f95d
TL
479{
480 struct omap2430_glue *glue = dev_get_drvdata(dev);
481 struct musb *musb = glue_to_musb(glue);
482
483 phy_power_off(musb->phy);
484 phy_exit(musb->phy);
485 glue->phy_suspended = 1;
486
487 return 0;
488}
489
490/* Glue layer needs to be suspended after musb_suspend() */
491static int omap2430_suspend_late(struct device *dev)
62d472d8
TL
492{
493 struct omap2430_glue *glue = dev_get_drvdata(dev);
494
495 if (glue->is_runtime_suspended)
496 return 0;
497
498 glue->needs_resume = 1;
499
500 return omap2430_runtime_suspend(dev);
501}
502
68d9f95d 503static int omap2430_resume_early(struct device *dev)
62d472d8
TL
504{
505 struct omap2430_glue *glue = dev_get_drvdata(dev);
506
507 if (!glue->needs_resume)
508 return 0;
509
510 glue->needs_resume = 0;
511
512 return omap2430_runtime_resume(dev);
513}
514
68d9f95d
TL
515static int omap2430_resume(struct device *dev)
516{
517 struct omap2430_glue *glue = dev_get_drvdata(dev);
518 struct musb *musb = glue_to_musb(glue);
519
520 phy_init(musb->phy);
521 phy_power_on(musb->phy);
522 glue->phy_suspended = 0;
523
524 return 0;
525}
526
c0927fea 527static const struct dev_pm_ops omap2430_pm_ops = {
7acc6197
HH
528 .runtime_suspend = omap2430_runtime_suspend,
529 .runtime_resume = omap2430_runtime_resume,
62d472d8 530 .suspend = omap2430_suspend,
68d9f95d
TL
531 .suspend_late = omap2430_suspend_late,
532 .resume_early = omap2430_resume_early,
62d472d8 533 .resume = omap2430_resume,
c20aebb9
FB
534};
535
536#define DEV_PM_OPS (&omap2430_pm_ops)
537#else
538#define DEV_PM_OPS NULL
539#endif
540
00a0b1d5
KVA
541#ifdef CONFIG_OF
542static const struct of_device_id omap2430_id_table[] = {
543 {
544 .compatible = "ti,omap4-musb"
545 },
546 {
547 .compatible = "ti,omap3-musb"
548 },
549 {},
550};
551MODULE_DEVICE_TABLE(of, omap2430_id_table);
552#endif
553
dc09886b 554static struct platform_driver omap2430_driver = {
e9e8c85e 555 .probe = omap2430_probe,
7690417d 556 .remove = omap2430_remove,
dc09886b
FB
557 .driver = {
558 .name = "musb-omap2430",
c20aebb9 559 .pm = DEV_PM_OPS,
00a0b1d5 560 .of_match_table = of_match_ptr(omap2430_id_table),
dc09886b
FB
561 },
562};
563
aec373c1
TL
564module_platform_driver(omap2430_driver);
565
dc09886b
FB
566MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
567MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
568MODULE_LICENSE("GPL v2");