aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2015-02-11 23:36:11 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2015-03-23 09:13:42 -0400
commit0f12a0ce4ce4a47d8a34399a3f22d4ce7fd2d908 (patch)
tree45881949b4b087be7de8c7527b3ae0ec31a11cbc /drivers/mmc/core
parentd34712d2e3db9b241d0484a6e3839c6b7ef9df78 (diff)
mmc: pwrseq: simplify alloc/free hooks
The alloc() and free() hooks required each pwrseq implementation to set host->pwrseq themselves. This is error-prone and could be done at a higher level if alloc() was changed to return a pointer to a struct mmc_pwrseq instead of an error code. This patch performs this change and moves the burden of maintaining host->pwrseq from the power sequence hooks to the pwrseq code. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/pwrseq.c16
-rw-r--r--drivers/mmc/core/pwrseq.h6
-rw-r--r--drivers/mmc/core/pwrseq_emmc.c11
-rw-r--r--drivers/mmc/core/pwrseq_simple.c11
4 files changed, 26 insertions, 18 deletions
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
index 862356123d78..ab2129781161 100644
--- a/drivers/mmc/core/pwrseq.c
+++ b/drivers/mmc/core/pwrseq.c
@@ -19,7 +19,7 @@
19 19
20struct mmc_pwrseq_match { 20struct mmc_pwrseq_match {
21 const char *compatible; 21 const char *compatible;
22 int (*alloc)(struct mmc_host *host, struct device *dev); 22 struct mmc_pwrseq *(*alloc)(struct mmc_host *host, struct device *dev);
23}; 23};
24 24
25static struct mmc_pwrseq_match pwrseq_match[] = { 25static struct mmc_pwrseq_match pwrseq_match[] = {
@@ -52,6 +52,7 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
52 struct platform_device *pdev; 52 struct platform_device *pdev;
53 struct device_node *np; 53 struct device_node *np;
54 struct mmc_pwrseq_match *match; 54 struct mmc_pwrseq_match *match;
55 struct mmc_pwrseq *pwrseq;
55 int ret = 0; 56 int ret = 0;
56 57
57 np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0); 58 np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0);
@@ -70,9 +71,14 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
70 goto err; 71 goto err;
71 } 72 }
72 73
73 ret = match->alloc(host, &pdev->dev); 74 pwrseq = match->alloc(host, &pdev->dev);
74 if (!ret) 75 if (IS_ERR(pwrseq)) {
75 dev_info(host->parent, "allocated mmc-pwrseq\n"); 76 ret = PTR_ERR(host->pwrseq);
77 goto err;
78 }
79
80 host->pwrseq = pwrseq;
81 dev_info(host->parent, "allocated mmc-pwrseq\n");
76 82
77err: 83err:
78 of_node_put(np); 84 of_node_put(np);
@@ -109,4 +115,6 @@ void mmc_pwrseq_free(struct mmc_host *host)
109 115
110 if (pwrseq && pwrseq->ops && pwrseq->ops->free) 116 if (pwrseq && pwrseq->ops && pwrseq->ops->free)
111 pwrseq->ops->free(host); 117 pwrseq->ops->free(host);
118
119 host->pwrseq = NULL;
112} 120}
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h
index aba3409e8d6e..096da48c6a7e 100644
--- a/drivers/mmc/core/pwrseq.h
+++ b/drivers/mmc/core/pwrseq.h
@@ -27,8 +27,10 @@ void mmc_pwrseq_post_power_on(struct mmc_host *host);
27void mmc_pwrseq_power_off(struct mmc_host *host); 27void mmc_pwrseq_power_off(struct mmc_host *host);
28void mmc_pwrseq_free(struct mmc_host *host); 28void mmc_pwrseq_free(struct mmc_host *host);
29 29
30int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev); 30struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
31int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev); 31 struct device *dev);
32struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
33 struct device *dev);
32 34
33#else 35#else
34 36
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index a2d545904fbf..9d6d2fb21796 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -49,7 +49,6 @@ static void mmc_pwrseq_emmc_free(struct mmc_host *host)
49 unregister_restart_handler(&pwrseq->reset_nb); 49 unregister_restart_handler(&pwrseq->reset_nb);
50 gpiod_put(pwrseq->reset_gpio); 50 gpiod_put(pwrseq->reset_gpio);
51 kfree(pwrseq); 51 kfree(pwrseq);
52 host->pwrseq = NULL;
53} 52}
54 53
55static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { 54static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
@@ -67,14 +66,15 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this,
67 return NOTIFY_DONE; 66 return NOTIFY_DONE;
68} 67}
69 68
70int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev) 69struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host,
70 struct device *dev)
71{ 71{
72 struct mmc_pwrseq_emmc *pwrseq; 72 struct mmc_pwrseq_emmc *pwrseq;
73 int ret = 0; 73 int ret = 0;
74 74
75 pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL); 75 pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL);
76 if (!pwrseq) 76 if (!pwrseq)
77 return -ENOMEM; 77 return ERR_PTR(-ENOMEM);
78 78
79 pwrseq->reset_gpio = gpiod_get_index(dev, "reset", 0, GPIOD_OUT_LOW); 79 pwrseq->reset_gpio = gpiod_get_index(dev, "reset", 0, GPIOD_OUT_LOW);
80 if (IS_ERR(pwrseq->reset_gpio)) { 80 if (IS_ERR(pwrseq->reset_gpio)) {
@@ -92,10 +92,9 @@ int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev)
92 register_restart_handler(&pwrseq->reset_nb); 92 register_restart_handler(&pwrseq->reset_nb);
93 93
94 pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; 94 pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops;
95 host->pwrseq = &pwrseq->pwrseq;
96 95
97 return 0; 96 return &pwrseq->pwrseq;
98free: 97free:
99 kfree(pwrseq); 98 kfree(pwrseq);
100 return ret; 99 return ERR_PTR(ret);
101} 100}
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index c53f14a7ce54..0b14b83a53d6 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -85,7 +85,6 @@ static void mmc_pwrseq_simple_free(struct mmc_host *host)
85 clk_put(pwrseq->ext_clk); 85 clk_put(pwrseq->ext_clk);
86 86
87 kfree(pwrseq); 87 kfree(pwrseq);
88 host->pwrseq = NULL;
89} 88}
90 89
91static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { 90static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
@@ -95,7 +94,8 @@ static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
95 .free = mmc_pwrseq_simple_free, 94 .free = mmc_pwrseq_simple_free,
96}; 95};
97 96
98int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev) 97struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host,
98 struct device *dev)
99{ 99{
100 struct mmc_pwrseq_simple *pwrseq; 100 struct mmc_pwrseq_simple *pwrseq;
101 int i, nr_gpios, ret = 0; 101 int i, nr_gpios, ret = 0;
@@ -107,7 +107,7 @@ int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev)
107 pwrseq = kzalloc(sizeof(struct mmc_pwrseq_simple) + nr_gpios * 107 pwrseq = kzalloc(sizeof(struct mmc_pwrseq_simple) + nr_gpios *
108 sizeof(struct gpio_desc *), GFP_KERNEL); 108 sizeof(struct gpio_desc *), GFP_KERNEL);
109 if (!pwrseq) 109 if (!pwrseq)
110 return -ENOMEM; 110 return ERR_PTR(-ENOMEM);
111 111
112 pwrseq->ext_clk = clk_get(dev, "ext_clock"); 112 pwrseq->ext_clk = clk_get(dev, "ext_clock");
113 if (IS_ERR(pwrseq->ext_clk) && 113 if (IS_ERR(pwrseq->ext_clk) &&
@@ -133,13 +133,12 @@ int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev)
133 133
134 pwrseq->nr_gpios = nr_gpios; 134 pwrseq->nr_gpios = nr_gpios;
135 pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; 135 pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
136 host->pwrseq = &pwrseq->pwrseq;
137 136
138 return 0; 137 return &pwrseq->pwrseq;
139clk_put: 138clk_put:
140 if (!IS_ERR(pwrseq->ext_clk)) 139 if (!IS_ERR(pwrseq->ext_clk))
141 clk_put(pwrseq->ext_clk); 140 clk_put(pwrseq->ext_clk);
142free: 141free:
143 kfree(pwrseq); 142 kfree(pwrseq);
144 return ret; 143 return ERR_PTR(ret);
145} 144}