USB OTG host + client dynamic configuration


We have a OMAP3-based custom board on which we want to use the USB OTG
features (both host and client modes). Unfortunately, our hardware
engineers only brought out the first 4 USB pins to the external world;
we don't have the 5th ID pin hooked up to the external world.
However, that 5th ID pin is internally wired to a FPGA control
register which our software can control. Hence, the USB OTG driver
(musb_hdrc) is unable to "dynamically" sense the ID pin via the
external USB interface (like the BeagleBoard) to decide whether to
configure as host or client mode. Our application software has to set
or clear the FPGA control register before the kernel loads. So the
problem we're having is that our application software runs "after" the
kernel loads so it's too late to set/clear the FPGA control register
before the USB OTG driver loads. I tried configuring kernel such that
the USB OTG driver (musb_hdrc) is a module so that our application
software can set/clear the FPGA control register before we attempt to
load the module (musb_hdrc) but it's crashing (see below). It runs
fine if not compiled as part of the kernel, though. If the USB OTG
driver loads as host mode, is there any way to tell it to dynamically
switch to client mode and vice versa (of course, I will set the FPGA
control register accordingly)?

The only other alternative solution I have is to somehow set/clear the
FPGA control register in u-boot before the kernel loads (the FPGA is
configured/loaded in u-boot) but I need to know what mode the Linux
user application wants it to be during u-boot time. I was thinking of
creating a small partition (beside x-loader, u-boot, kernel, fs) that
the application can "mark" the USB mode to use and u-boot can attempt
to decipher that partition to determine what USB mode it should set
via the FPGA control register.

Any advice/suggestions/recommendations? I was hoping to get the USB
OTG driver load as a module. Thanks!


# modprobe musb_hdrc
musb_hdrc: version 6.0, musb-dma, otg (peripheral+host), debug=0
Unhandled fault: external abort on non-linefetch (0x1028) at
Internal error: : 1028 [#1] PREEMPT
Modules linked in: modem_driver hmi cmemk dsplinkk lpm_omap3530
CPU: 0 Not tainted ( #1)
PC is at musb_platform_init+0x94/0x12c [musb_hdrc]
LR is at omap2_clk_enable+0x114/0x184
pc : [<bf057e7c>] lr : [<c0030be4>] psr: 40000013
sp : c62cfcf0 ip : 00000001 fp : c62cfd04
r10: 00016338 r9 : c628d150 r8 : c0392bf0
r7 : c6c2e4a0 r6 : c628d0d0 r5 : 00000000 r4 : c628d0d0
r3 : d80ab000 r2 : 00000000 r1 : 00000000 r0 : 00000000
Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c5387d Table: 85be4019 DAC: 00000015
Process modprobe (pid: 968, stack limit = 0xc62ce2e0)
Stack: (0xc62cfcf0 to 0xc62d0000)
fce0: c0378220 00000000 c62cfde4
fd00: bf0573f8 bf057df4 c62ce000 c6c573f8 c6c08800 c6c573f8 c0378180
fd20: c0378118 0000005c d80ab000 c03780f4 c628d000 c0182c84 c62cfd50
fd40: c62cfd8c c62cfd50 c00e4220 c00b0ad4 386d43cb 1709226b c621a7e8
fd60: c62cfd90 c6c573f8 00000000 c621a788 c62cfd90 c6c573f8 00000001
fd80: c62cfdc4 c62cfd90 c00e4dbc c00e41c8 c6c573f8 c6879740 00000000
fda0: c00e4598 c0378118 00000000 c037815c c6c2e4a0 c0392bf0 c62cfdd4
fdc0: c0378118 bf054bd4 c6c2e4a0 c0392bf0 c62ce000 00016338 c62cfdf4
fde0: c01b1540 bf0571b8 c62cfe14 c62cfdf8 c01b0730 c01b152c c0378118
fe00: bf054bd4 c6c2e4a0 c62cfe34 c62cfe18 c01b0844 c01b0668 00000000
fe20: bf054bd4 c6c2e4a0 c62cfe5c c62cfe38 c01aff70 c01b07e8 c6c034d8
fe40: c0184350 00000000 bf054bb8 bf054bd4 c62cfe6c c62cfe60 c01b0574
fe60: c62cfe9c c62cfe70 c01af84c c01b0560 bf04f1de bf054bb8 bf054bd4
fe80: bf054bb8 bf054bd4 bf057000 00000000 c62cfec4 c62cfea0 c01b0a68
fea0: 0001410e bf054bb8 4014c000 bf057000 00000000 c62ce000 c62cfed4
fec0: c01b19e8 c01b09dc c62cfef4 c62cfed8 c01b1a1c c01b1988 0001410e
fee0: 4014c000 bf057000 c62cff04 c62cfef8 bf05703c c01b1a10 c62cff7c
ff00: c0026334 bf05700c c62cff34 bf054c9c 4014c000 bf0537e8 c78b4828
ff20: 00000022 c78b4850 bf051620 00000002 00000000 00000000 00000000
ff40: c035a3e0 0001410e bf054c54 4014c000 00000000 c0026fc4 c62cff7c
ff60: bf054c54 4014c000 00000000 c0026fc4 c62cffa4 c62cff80 c0072050
ff80: 00000003 00000000 00000000 00000000 00000000 00000080 00000000
ffa0: c0026e40 c0071fcc 00000000 00000000 4014c000 0001410e 00016140
ffc0: 00000000 00000000 00000000 00000080 00000000 00016344 00016338
ffe0: bed98f17 bed989b4 0000b11c 400e9824 60000010 4014c000 00000000
[<bf057de8>] (musb_platform_init+0x0/0x12c [musb_hdrc]) from
[<bf0573f8>] (musb_probe+0x24c/0xc3c [musb_hdrc])
r5:00000000 r4:c0378220
[<bf0571ac>] (musb_probe+0x0/0xc3c [musb_hdrc]) from [<c01b1540>]
[<c01b1520>] (platform_drv_probe+0x0/0x24) from [<c01b0730>]
[<c01b065c>] (driver_probe_device+0x0/0x180) from [<c01b0844>]
r7:c6c2e4a0 r6:bf054bd4 r5:c03781a0 r4:c0378118
[<c01b07dc>] (__driver_attach+0x0/0x8c) from [<c01aff70>]
r7:c6c2e4a0 r6:bf054bd4 r5:c01b07dc r4:00000000
[<c01aff24>] (bus_for_each_dev+0x0/0x80) from [<c01b0574>]
r6:bf054bd4 r5:bf054bb8 r4:00000000
[<c01b0554>] (driver_attach+0x0/0x28) from [<c01af84c>] (bus_add_driver
[<c01af7a4>] (bus_add_driver+0x0/0x210) from [<c01b0a68>]
r8:00000000 r7:bf057000 r6:bf054bd4 r5:bf054bb8 r4:0001410e
[<c01b09d0>] (driver_register+0x0/0x11c) from [<c01b19e8>]
r9:c62ce000 r8:00000000 r7:bf057000 r6:4014c000 r5:bf054bb8
[<c01b197c>] (platform_driver_register+0x0/0x88) from [<c01b1a1c>]
[<c01b1a04>] (platform_driver_probe+0x0/0xac) from [<bf05703c>]
(musb_init+0x3c/0x54 [musb_hdrc])
r7:bf057000 r6:4014c000 r5:bf054c54 r4:0001410e
[<bf057000>] (musb_init+0x0/0x54 [musb_hdrc]) from [<c0026334>]
[<c00262d8>] (do_one_initcall+0x0/0x19c) from [<c0072050>]
r8:c0026fc4 r7:00000000 r6:4014c000 r5:bf054c54 r4:0001410e
[<c0071fc0>] (sys_init_module+0x0/0x190) from [<c0026e40>]
r7:00000080 r6:00000000 r5:00000000 r4:00000000
Code: ea000001 e5940000 eb3f7d28 e59f3080 (e5932404)
---[ end trace f4d6d13ee598be6c ]---