aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-05-01 10:51:38 -0400
committerChris Ball <cjb@laptop.org>2012-07-21 00:02:17 -0400
commita7d1a1ebd8f5858a812ac3d5fbbc178b4959a63b (patch)
treeb96e8522469e2b228a265db89a9d2bc8f0b5e390 /drivers
parentbefe4048d8d20483a62636e20f3dbffebf85a1c1 (diff)
mmc: core: convert slot functions to managed allocation
This prepares for the addition of further slot functions. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/host.c2
-rw-r--r--drivers/mmc/core/slot-gpio.c51
2 files changed, 40 insertions, 13 deletions
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b8c5290571f1..74cf29a504f4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -32,6 +32,7 @@
32static void mmc_host_classdev_release(struct device *dev) 32static void mmc_host_classdev_release(struct device *dev)
33{ 33{
34 struct mmc_host *host = cls_dev_to_mmc_host(dev); 34 struct mmc_host *host = cls_dev_to_mmc_host(dev);
35 mutex_destroy(&host->slot.lock);
35 kfree(host); 36 kfree(host);
36} 37}
37 38
@@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
327 328
328 mmc_host_clk_init(host); 329 mmc_host_clk_init(host);
329 330
331 mutex_init(&host->slot.lock);
330 host->slot.cd_irq = -EINVAL; 332 host->slot.cd_irq = -EINVAL;
331 333
332 spin_lock_init(&host->lock); 334 spin_lock_init(&host->lock);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 92cba02c04be..41689da14b8d 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,34 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
29 return IRQ_HANDLED; 29 return IRQ_HANDLED;
30} 30}
31 31
32static int mmc_gpio_alloc(struct mmc_host *host)
33{
34 size_t len = strlen(dev_name(host->parent)) + 4;
35 struct mmc_gpio *ctx;
36
37 mutex_lock(&host->slot.lock);
38
39 ctx = host->slot.handler_priv;
40 if (!ctx) {
41 /*
42 * devm_kzalloc() can be called after device_initialize(), even
43 * before device_add(), i.e., between mmc_alloc_host() and
44 * mmc_add_host()
45 */
46 ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
47 GFP_KERNEL);
48 if (ctx) {
49 snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
50 ctx->cd_gpio = -EINVAL;
51 host->slot.handler_priv = ctx;
52 }
53 }
54
55 mutex_unlock(&host->slot.lock);
56
57 return ctx ? 0 : -ENOMEM;
58}
59
32int mmc_gpio_get_cd(struct mmc_host *host) 60int mmc_gpio_get_cd(struct mmc_host *host)
33{ 61{
34 struct mmc_gpio *ctx = host->slot.handler_priv; 62 struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -43,20 +71,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd);
43 71
44int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) 72int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
45{ 73{
46 size_t len = strlen(dev_name(host->parent)) + 4;
47 struct mmc_gpio *ctx; 74 struct mmc_gpio *ctx;
48 int irq = gpio_to_irq(gpio); 75 int irq = gpio_to_irq(gpio);
49 int ret; 76 int ret;
50 77
51 ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL); 78 ret = mmc_gpio_alloc(host);
52 if (!ctx) 79 if (ret < 0)
53 return -ENOMEM; 80 return ret;
54 81
55 snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); 82 ctx = host->slot.handler_priv;
56 83
57 ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label); 84 ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
58 if (ret < 0) 85 if (ret < 0)
59 goto egpioreq; 86 /*
87 * don't bother freeing memory. It might still get used by other
88 * slot functions, in any case it will be freed, when the device
89 * is destroyed.
90 */
91 return ret;
60 92
61 /* 93 /*
62 * Even if gpio_to_irq() returns a valid IRQ number, the platform might 94 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
@@ -80,13 +112,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
80 host->caps |= MMC_CAP_NEEDS_POLL; 112 host->caps |= MMC_CAP_NEEDS_POLL;
81 113
82 ctx->cd_gpio = gpio; 114 ctx->cd_gpio = gpio;
83 host->slot.handler_priv = ctx;
84 115
85 return 0; 116 return 0;
86
87egpioreq:
88 kfree(ctx);
89 return ret;
90} 117}
91EXPORT_SYMBOL(mmc_gpio_request_cd); 118EXPORT_SYMBOL(mmc_gpio_request_cd);
92 119
@@ -107,7 +134,5 @@ void mmc_gpio_free_cd(struct mmc_host *host)
107 ctx->cd_gpio = -EINVAL; 134 ctx->cd_gpio = -EINVAL;
108 135
109 gpio_free(gpio); 136 gpio_free(gpio);
110 host->slot.handler_priv = NULL;
111 kfree(ctx);
112} 137}
113EXPORT_SYMBOL(mmc_gpio_free_cd); 138EXPORT_SYMBOL(mmc_gpio_free_cd);