USB: ehci-fsl: Fix kernel crash on mpc5121e

Since commit 28c56ea143
(powerpc/usb: fix bug of kernel hang when initializing usb)
the kernel crashes on mpc5121e. mpc5121e doesn't have system interface
registers, accessing this register address space cause the machine check
exception and a kernel crash:
...
[    1.294596] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.316491] fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller
[    1.337334] fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1
[    1.358548] Machine check in kernel mode.
[    1.375917] Caused by (from SRR1=49030): Transfer error ack signal
[    1.395505] Oops: Machine check, sig: 7 [#1]
[    1.413113] MPC5121 ADS
[    1.428718] Modules linked in:
[    1.444841] NIP: c026efc4 LR: c0278b50 CTR: 00000000
[    1.463342] REGS: df837ba0 TRAP: 0200   Not tainted  (3.3.0-08839-gb5174fa)
[    1.484083] MSR: 00049030 <EE,ME,IR,DR>  CR: 42042022  XER: 20000000
[    1.504099] TASK = df834000[1] 'swapper' THREAD: df836000
[    1.509667] GPR00: 1c000000 df837c50 df834000 df9d74e0 00000003 00000010 00000000 00000000
[    1.531650] GPR08: 00000020 00000000 c037cdd8 e1088000 22042028 1001a69c 00000000 00000000
[    1.553762] GPR16: 1ffbce70 00000000 1fef5b28 1fef3e08 00000000 00000000 1ffcbc7c c045b264
[    1.575824] GPR24: 0000008b 00000002 c04a7dd0 e1088000 df33c960 df9d74e0 00000000 df9d7400
[    1.612295] NIP [c026efc4] ehci_fsl_setup_phy+0x110/0x124
[    1.632454] LR [c0278b50] ehci_fsl_setup+0x29c/0x304
[    1.652065] Call Trace:
[    1.668923] [df837c50] [c0278a40] ehci_fsl_setup+0x18c/0x304 (unreliable)
[    1.690332] [df837c70] [c025cba4] usb_add_hcd+0x1f0/0x66c
[    1.710377] [df837cb0] [c0277ab8] ehci_fsl_drv_probe+0x180/0x308
[    1.731322] [df837ce0] [c01fc7a8] platform_drv_probe+0x20/0x30
[    1.752202] [df837cf0] [c01fb0ac] driver_probe_device+0x8c/0x214
[    1.773491] [df837d10] [c01f956c] bus_for_each_drv+0x6c/0xa8
[    1.794279] [df837d40] [c01fafdc] device_attach+0xb4/0xd8
[    1.814574] [df837d60] [c01fa44c] bus_probe_device+0xa4/0xb4
[    1.835343] [df837d80] [c01f87a8] device_add+0x52c/0x5dc
[    1.855462] [df837dd0] [c01fcd58] platform_device_add+0x124/0x1d0
[    1.876558] [df837df0] [c036dcec] fsl_usb2_device_register+0xa0/0xd4
[    1.897512] [df837e10] [c036df28] fsl_usb2_mph_dr_of_probe+0x208/0x264
[    1.918253] [df837e90] [c01fc7a8] platform_drv_probe+0x20/0x30
[    1.938300] [df837ea0] [c01fb0ac] driver_probe_device+0x8c/0x214
[    1.958511] [df837ec0] [c01fb2f0] __driver_attach+0xbc/0xc0
[    1.978088] [df837ee0] [c01f9608] bus_for_each_dev+0x60/0x9c
[    1.997589] [df837f10] [c01fab88] driver_attach+0x24/0x34
[    2.016757] [df837f20] [c01fa744] bus_add_driver+0x1ac/0x274
[    2.036339] [df837f50] [c01fb898] driver_register+0x88/0x150
[    2.056052] [df837f70] [c01fcabc] platform_driver_register+0x68/0x78
[    2.076650] [df837f80] [c0446500] fsl_usb2_mph_dr_driver_init+0x18/0x28
[    2.097734] [df837f90] [c0003988] do_one_initcall+0x148/0x1b0
[    2.117934] [df837fc0] [c042d89c] kernel_init+0xfc/0x190
[    2.137667] [df837ff0] [c000d2c4] kernel_thread+0x4c/0x68
[    2.157240] Instruction dump:
[    2.174119] 90050004 4e800020 2f840003 419e0014 2f840004 409eff64 6400c000 4bffff5c
[    2.196000] 64001000 7c0004ac 812b0500 0c090000 <4c00012c> 61290200 7c0004ac 912b0500
[    2.218100] ---[ end trace 21659aedb84ad816 ]---
[    2.237089]
[    3.232940] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007
[    3.232954]
[    3.271575] Rebooting in 1 seconds..

Check pdata->have_sysif_regs flag before accessing system interface
registers.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Anatolij Gustschin 2012-04-10 10:48:11 +02:00 committed by Greg Kroah-Hartman
parent 5bd7b419ef
commit f941f69225

View File

@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
u32 portsc;
struct usb_hcd *hcd = ehci_to_hcd(ehci);
void __iomem *non_ehci = hcd->regs;
struct fsl_usb2_platform_data *pdata;
pdata = hcd->self.controller->platform_data;
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
/* fall through */
case FSL_USB2_PHY_UTMI:
/* enable UTMI PHY */
setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
if (pdata->have_sysif_regs)
setbits32(non_ehci + FSL_SOC_USB_CTRL,
CTRL_UTMI_PHY_EN);
portsc |= PORT_PTS_UTMI;
break;
case FSL_USB2_PHY_NONE: