Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: Fix omap usbhs crash when rmmoding ehci or ohci

The disabling of clocks and freeing GPIO are changed
to fix the occurrence of the crash of rmmod of ehci and ohci
drivers. The GPIOs should be freed after the spin locks are
unlocked.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Cc: stable@kernel.org
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Keshava Munegowda and committed by
Samuel Ortiz
6eb6fbbf 13ca4f66

+19 -8
+19 -8
drivers/mfd/omap-usb-host.c
··· 994 994 dev_dbg(dev, "operation timed out\n"); 995 995 } 996 996 997 + if (is_omap_usbhs_rev2(omap)) { 998 + if (is_ehci_tll_mode(pdata->port_mode[0])) 999 + clk_enable(omap->usbtll_p1_fck); 1000 + if (is_ehci_tll_mode(pdata->port_mode[1])) 1001 + clk_enable(omap->usbtll_p2_fck); 1002 + clk_disable(omap->utmi_p2_fck); 1003 + clk_disable(omap->utmi_p1_fck); 1004 + } 1005 + 1006 + clk_disable(omap->usbtll_ick); 1007 + clk_disable(omap->usbtll_fck); 1008 + clk_disable(omap->usbhost_fs_fck); 1009 + clk_disable(omap->usbhost_hs_fck); 1010 + clk_disable(omap->usbhost_ick); 1011 + 1012 + /* The gpio_free migh sleep; so unlock the spinlock */ 1013 + spin_unlock_irqrestore(&omap->lock, flags); 1014 + 997 1015 if (pdata->ehci_data->phy_reset) { 998 1016 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 999 1017 gpio_free(pdata->ehci_data->reset_gpio_port[0]); ··· 1019 1001 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 1020 1002 gpio_free(pdata->ehci_data->reset_gpio_port[1]); 1021 1003 } 1022 - 1023 - clk_disable(omap->utmi_p2_fck); 1024 - clk_disable(omap->utmi_p1_fck); 1025 - clk_disable(omap->usbtll_ick); 1026 - clk_disable(omap->usbtll_fck); 1027 - clk_disable(omap->usbhost_fs_fck); 1028 - clk_disable(omap->usbhost_hs_fck); 1029 - clk_disable(omap->usbhost_ick); 1004 + return; 1030 1005 1031 1006 end_disble: 1032 1007 spin_unlock_irqrestore(&omap->lock, flags);