Loading drivers/mmc/core/host.c +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); mutex_destroy(&host->slot.lock); kfree(host); } Loading Loading @@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) mmc_host_clk_init(host); mutex_init(&host->slot.lock); host->slot.cd_irq = -EINVAL; spin_lock_init(&host->lock); Loading drivers/mmc/core/slot-gpio.c +38 −13 Original line number Diff line number Diff line Loading @@ -29,6 +29,34 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) return IRQ_HANDLED; } static int mmc_gpio_alloc(struct mmc_host *host) { size_t len = strlen(dev_name(host->parent)) + 4; struct mmc_gpio *ctx; mutex_lock(&host->slot.lock); ctx = host->slot.handler_priv; if (!ctx) { /* * devm_kzalloc() can be called after device_initialize(), even * before device_add(), i.e., between mmc_alloc_host() and * mmc_add_host() */ ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len, GFP_KERNEL); if (ctx) { snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); ctx->cd_gpio = -EINVAL; host->slot.handler_priv = ctx; } } mutex_unlock(&host->slot.lock); return ctx ? 0 : -ENOMEM; } int mmc_gpio_get_cd(struct mmc_host *host) { struct mmc_gpio *ctx = host->slot.handler_priv; Loading @@ -43,20 +71,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd); int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) { size_t len = strlen(dev_name(host->parent)) + 4; struct mmc_gpio *ctx; int irq = gpio_to_irq(gpio); int ret; ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL); if (!ctx) return -ENOMEM; ret = mmc_gpio_alloc(host); if (ret < 0) return ret; snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); ctx = host->slot.handler_priv; ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label); if (ret < 0) goto egpioreq; /* * don't bother freeing memory. It might still get used by other * slot functions, in any case it will be freed, when the device * is destroyed. */ return ret; /* * Even if gpio_to_irq() returns a valid IRQ number, the platform might Loading @@ -80,13 +112,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) host->caps |= MMC_CAP_NEEDS_POLL; ctx->cd_gpio = gpio; host->slot.handler_priv = ctx; return 0; egpioreq: kfree(ctx); return ret; } EXPORT_SYMBOL(mmc_gpio_request_cd); Loading @@ -107,7 +134,5 @@ void mmc_gpio_free_cd(struct mmc_host *host) ctx->cd_gpio = -EINVAL; gpio_free(gpio); host->slot.handler_priv = NULL; kfree(ctx); } EXPORT_SYMBOL(mmc_gpio_free_cd); include/linux/mmc/host.h +3 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ #define LINUX_MMC_HOST_H #include <linux/leds.h> #include <linux/mutex.h> #include <linux/sched.h> #include <linux/device.h> #include <linux/fault-inject.h> Loading Loading @@ -154,6 +155,7 @@ struct mmc_async_req { * struct mmc_slot - MMC slot functions * * @cd_irq: MMC/SD-card slot hotplug detection IRQ or -EINVAL * @lock: protect the @handler_priv pointer * @handler_priv: MMC/SD-card slot context * * Some MMC/SD host controllers implement slot-functions like card and Loading @@ -163,6 +165,7 @@ struct mmc_async_req { */ struct mmc_slot { int cd_irq; struct mutex lock; void *handler_priv; }; Loading Loading
drivers/mmc/core/host.c +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); mutex_destroy(&host->slot.lock); kfree(host); } Loading Loading @@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) mmc_host_clk_init(host); mutex_init(&host->slot.lock); host->slot.cd_irq = -EINVAL; spin_lock_init(&host->lock); Loading
drivers/mmc/core/slot-gpio.c +38 −13 Original line number Diff line number Diff line Loading @@ -29,6 +29,34 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) return IRQ_HANDLED; } static int mmc_gpio_alloc(struct mmc_host *host) { size_t len = strlen(dev_name(host->parent)) + 4; struct mmc_gpio *ctx; mutex_lock(&host->slot.lock); ctx = host->slot.handler_priv; if (!ctx) { /* * devm_kzalloc() can be called after device_initialize(), even * before device_add(), i.e., between mmc_alloc_host() and * mmc_add_host() */ ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len, GFP_KERNEL); if (ctx) { snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); ctx->cd_gpio = -EINVAL; host->slot.handler_priv = ctx; } } mutex_unlock(&host->slot.lock); return ctx ? 0 : -ENOMEM; } int mmc_gpio_get_cd(struct mmc_host *host) { struct mmc_gpio *ctx = host->slot.handler_priv; Loading @@ -43,20 +71,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd); int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) { size_t len = strlen(dev_name(host->parent)) + 4; struct mmc_gpio *ctx; int irq = gpio_to_irq(gpio); int ret; ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL); if (!ctx) return -ENOMEM; ret = mmc_gpio_alloc(host); if (ret < 0) return ret; snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); ctx = host->slot.handler_priv; ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label); if (ret < 0) goto egpioreq; /* * don't bother freeing memory. It might still get used by other * slot functions, in any case it will be freed, when the device * is destroyed. */ return ret; /* * Even if gpio_to_irq() returns a valid IRQ number, the platform might Loading @@ -80,13 +112,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) host->caps |= MMC_CAP_NEEDS_POLL; ctx->cd_gpio = gpio; host->slot.handler_priv = ctx; return 0; egpioreq: kfree(ctx); return ret; } EXPORT_SYMBOL(mmc_gpio_request_cd); Loading @@ -107,7 +134,5 @@ void mmc_gpio_free_cd(struct mmc_host *host) ctx->cd_gpio = -EINVAL; gpio_free(gpio); host->slot.handler_priv = NULL; kfree(ctx); } EXPORT_SYMBOL(mmc_gpio_free_cd);
include/linux/mmc/host.h +3 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ #define LINUX_MMC_HOST_H #include <linux/leds.h> #include <linux/mutex.h> #include <linux/sched.h> #include <linux/device.h> #include <linux/fault-inject.h> Loading Loading @@ -154,6 +155,7 @@ struct mmc_async_req { * struct mmc_slot - MMC slot functions * * @cd_irq: MMC/SD-card slot hotplug detection IRQ or -EINVAL * @lock: protect the @handler_priv pointer * @handler_priv: MMC/SD-card slot context * * Some MMC/SD host controllers implement slot-functions like card and Loading @@ -163,6 +165,7 @@ struct mmc_async_req { */ struct mmc_slot { int cd_irq; struct mutex lock; void *handler_priv; }; Loading