diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2010-03-25 07:14:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-04-30 12:25:09 -0400 |
commit | 34e2beb2c883e0ea1b6135ad6f7713f7574a01aa (patch) | |
tree | ef01380e3d4149f5ad25adf9fa13980069f0e6d8 /drivers | |
parent | c6a39eec9dcd5f205fd41a5c87a1f3e5d95ffaaa (diff) |
musb_core: fix musb_init_controller() error cleanup path
This function forgets to call usb_remove_hcd() or musb_gadget_cleanup() iff
sysfs_create_group() fails.
[ felipe.balbi@nokia.com : review the entire error path
not only when we fail hcd or gadget ]
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 508fd582973f..705cc4ad8737 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1878,8 +1878,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
1878 | */ | 1878 | */ |
1879 | if (!plat) { | 1879 | if (!plat) { |
1880 | dev_dbg(dev, "no platform_data?\n"); | 1880 | dev_dbg(dev, "no platform_data?\n"); |
1881 | return -ENODEV; | 1881 | status = -ENODEV; |
1882 | goto fail0; | ||
1882 | } | 1883 | } |
1884 | |||
1883 | switch (plat->mode) { | 1885 | switch (plat->mode) { |
1884 | case MUSB_HOST: | 1886 | case MUSB_HOST: |
1885 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1887 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
@@ -1901,13 +1903,16 @@ bad_config: | |||
1901 | #endif | 1903 | #endif |
1902 | default: | 1904 | default: |
1903 | dev_err(dev, "incompatible Kconfig role setting\n"); | 1905 | dev_err(dev, "incompatible Kconfig role setting\n"); |
1904 | return -EINVAL; | 1906 | status = -EINVAL; |
1907 | goto fail0; | ||
1905 | } | 1908 | } |
1906 | 1909 | ||
1907 | /* allocate */ | 1910 | /* allocate */ |
1908 | musb = allocate_instance(dev, plat->config, ctrl); | 1911 | musb = allocate_instance(dev, plat->config, ctrl); |
1909 | if (!musb) | 1912 | if (!musb) { |
1910 | return -ENOMEM; | 1913 | status = -ENOMEM; |
1914 | goto fail0; | ||
1915 | } | ||
1911 | 1916 | ||
1912 | spin_lock_init(&musb->lock); | 1917 | spin_lock_init(&musb->lock); |
1913 | musb->board_mode = plat->mode; | 1918 | musb->board_mode = plat->mode; |
@@ -1925,7 +1930,7 @@ bad_config: | |||
1925 | if (IS_ERR(musb->clock)) { | 1930 | if (IS_ERR(musb->clock)) { |
1926 | status = PTR_ERR(musb->clock); | 1931 | status = PTR_ERR(musb->clock); |
1927 | musb->clock = NULL; | 1932 | musb->clock = NULL; |
1928 | goto fail; | 1933 | goto fail1; |
1929 | } | 1934 | } |
1930 | } | 1935 | } |
1931 | 1936 | ||
@@ -1944,12 +1949,12 @@ bad_config: | |||
1944 | */ | 1949 | */ |
1945 | musb->isr = generic_interrupt; | 1950 | musb->isr = generic_interrupt; |
1946 | status = musb_platform_init(musb); | 1951 | status = musb_platform_init(musb); |
1947 | |||
1948 | if (status < 0) | 1952 | if (status < 0) |
1949 | goto fail; | 1953 | goto fail2; |
1954 | |||
1950 | if (!musb->isr) { | 1955 | if (!musb->isr) { |
1951 | status = -ENODEV; | 1956 | status = -ENODEV; |
1952 | goto fail2; | 1957 | goto fail3; |
1953 | } | 1958 | } |
1954 | 1959 | ||
1955 | #ifndef CONFIG_MUSB_PIO_ONLY | 1960 | #ifndef CONFIG_MUSB_PIO_ONLY |
@@ -1975,7 +1980,7 @@ bad_config: | |||
1975 | ? MUSB_CONTROLLER_MHDRC | 1980 | ? MUSB_CONTROLLER_MHDRC |
1976 | : MUSB_CONTROLLER_HDRC, musb); | 1981 | : MUSB_CONTROLLER_HDRC, musb); |
1977 | if (status < 0) | 1982 | if (status < 0) |
1978 | goto fail2; | 1983 | goto fail3; |
1979 | 1984 | ||
1980 | #ifdef CONFIG_USB_MUSB_OTG | 1985 | #ifdef CONFIG_USB_MUSB_OTG |
1981 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); | 1986 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); |
@@ -1988,7 +1993,7 @@ bad_config: | |||
1988 | if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { | 1993 | if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { |
1989 | dev_err(dev, "request_irq %d failed!\n", nIrq); | 1994 | dev_err(dev, "request_irq %d failed!\n", nIrq); |
1990 | status = -ENODEV; | 1995 | status = -ENODEV; |
1991 | goto fail2; | 1996 | goto fail3; |
1992 | } | 1997 | } |
1993 | musb->nIrq = nIrq; | 1998 | musb->nIrq = nIrq; |
1994 | /* FIXME this handles wakeup irqs wrong */ | 1999 | /* FIXME this handles wakeup irqs wrong */ |
@@ -2050,12 +2055,12 @@ bad_config: | |||
2050 | 2055 | ||
2051 | } | 2056 | } |
2052 | if (status < 0) | 2057 | if (status < 0) |
2053 | goto fail2; | 2058 | goto fail3; |
2054 | 2059 | ||
2055 | #ifdef CONFIG_SYSFS | 2060 | #ifdef CONFIG_SYSFS |
2056 | status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); | 2061 | status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); |
2057 | if (status) | 2062 | if (status) |
2058 | goto fail2; | 2063 | goto fail4; |
2059 | #endif | 2064 | #endif |
2060 | 2065 | ||
2061 | dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", | 2066 | dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", |
@@ -2072,17 +2077,29 @@ bad_config: | |||
2072 | 2077 | ||
2073 | return 0; | 2078 | return 0; |
2074 | 2079 | ||
2075 | fail2: | 2080 | fail4: |
2081 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) | ||
2082 | usb_remove_hcd(musb_to_hcd(musb)); | ||
2083 | else | ||
2084 | musb_gadget_cleanup(musb); | ||
2085 | |||
2086 | fail3: | ||
2087 | if (musb->irq_wake) | ||
2088 | device_init_wakeup(dev, 0); | ||
2076 | musb_platform_exit(musb); | 2089 | musb_platform_exit(musb); |
2077 | fail: | ||
2078 | dev_err(musb->controller, | ||
2079 | "musb_init_controller failed with status %d\n", status); | ||
2080 | 2090 | ||
2091 | fail2: | ||
2081 | if (musb->clock) | 2092 | if (musb->clock) |
2082 | clk_put(musb->clock); | 2093 | clk_put(musb->clock); |
2083 | device_init_wakeup(dev, 0); | 2094 | |
2095 | fail1: | ||
2096 | dev_err(musb->controller, | ||
2097 | "musb_init_controller failed with status %d\n", status); | ||
2098 | |||
2084 | musb_free(musb); | 2099 | musb_free(musb); |
2085 | 2100 | ||
2101 | fail0: | ||
2102 | |||
2086 | return status; | 2103 | return status; |
2087 | 2104 | ||
2088 | } | 2105 | } |