mmc: fix sdhci-dove probe/removal

1. Never ever publish a device in the system before it has been setup
to a usable state.
2. Unregister the device _BEFORE_ taking away any resources it may be
using.
3. Don't check clks against NULL.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by

Russell King - ARM Linux and committed by
Chris Ball
ee3298a2 a0d28ba0

+20 -18
+20 -18
drivers/mmc/host/sdhci-dove.c
··· 19 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 20 */ 21 21 22 + #include <linux/err.h> 22 23 #include <linux/io.h> 23 24 #include <linux/clk.h> 24 25 #include <linux/err.h> ··· 85 84 struct sdhci_dove_priv *priv; 86 85 int ret; 87 86 88 - ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); 89 - if (ret) 90 - goto sdhci_dove_register_fail; 91 - 92 87 priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), 93 88 GFP_KERNEL); 94 89 if (!priv) { 95 90 dev_err(&pdev->dev, "unable to allocate private data"); 96 - ret = -ENOMEM; 97 - goto sdhci_dove_allocate_fail; 91 + return -ENOMEM; 98 92 } 93 + 94 + priv->clk = clk_get(&pdev->dev, NULL); 95 + if (!IS_ERR(priv->clk)) 96 + clk_prepare_enable(priv->clk); 97 + 98 + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); 99 + if (ret) 100 + goto sdhci_dove_register_fail; 99 101 100 102 host = platform_get_drvdata(pdev); 101 103 pltfm_host = sdhci_priv(host); 102 104 pltfm_host->priv = priv; 103 105 104 - priv->clk = clk_get(&pdev->dev, NULL); 105 - if (!IS_ERR(priv->clk)) 106 - clk_prepare_enable(priv->clk); 107 106 return 0; 108 107 109 - sdhci_dove_allocate_fail: 110 - sdhci_pltfm_unregister(pdev); 111 108 sdhci_dove_register_fail: 109 + if (!IS_ERR(priv->clk)) { 110 + clk_disable_unprepare(priv->clk); 111 + clk_put(priv->clk); 112 + } 112 113 return ret; 113 114 } 114 115 ··· 120 117 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 121 118 struct sdhci_dove_priv *priv = pltfm_host->priv; 122 119 123 - if (priv->clk) { 124 - if (!IS_ERR(priv->clk)) { 125 - clk_disable_unprepare(priv->clk); 126 - clk_put(priv->clk); 127 - } 128 - devm_kfree(&pdev->dev, priv->clk); 120 + sdhci_pltfm_unregister(pdev); 121 + 122 + if (!IS_ERR(priv->clk)) { 123 + clk_disable_unprepare(priv->clk); 124 + clk_put(priv->clk); 129 125 } 130 - return sdhci_pltfm_unregister(pdev); 126 + return 0; 131 127 } 132 128 133 129 static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {