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