| From e9d1edae3f34367442cab71753a0d1e55cbc439b Mon Sep 17 00:00:00 2001 |
| From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
| Date: Sun, 25 Dec 2011 21:36:02 +0100 |
| Subject: mmc: add a generic GPIO card-detect helper |
| |
| This patch adds a primitive helper to support card hotplug detection on |
| platforms, where a GPIO, capable of producing interrupts, is used for |
| detection of card-insertion and -removal events. |
| |
| Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
| Signed-off-by: Chris Ball <cjb@laptop.org> |
| (cherry picked from commit 349ab52446772a359bc7e7699cae3880d48fa5c9) |
| |
| Conflicts: |
| |
| drivers/mmc/core/Makefile |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| drivers/mmc/core/Makefile | 1 + |
| drivers/mmc/core/cd-gpio.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ |
| include/linux/mmc/cd-gpio.h | 19 ++++++++++++ |
| 3 files changed, 94 insertions(+) |
| create mode 100644 drivers/mmc/core/cd-gpio.c |
| create mode 100644 include/linux/mmc/cd-gpio.h |
| |
| diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile |
| index 6395019..274b67c 100644 |
| --- a/drivers/mmc/core/Makefile |
| +++ b/drivers/mmc/core/Makefile |
| @@ -9,4 +9,5 @@ mmc_core-y := core.o bus.o host.o \ |
| sdio_cis.o sdio_io.o sdio_irq.o \ |
| quirks.o |
| |
| +mmc_core-$(CONFIG_GPIOLIB) += cd-gpio.o |
| mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o |
| diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c |
| new file mode 100644 |
| index 0000000..082202a |
| --- /dev/null |
| +++ b/drivers/mmc/core/cd-gpio.c |
| @@ -0,0 +1,74 @@ |
| +/* |
| + * Generic GPIO card-detect helper |
| + * |
| + * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
| + * |
| + * This program is free software; you can redistribute it and/or modify |
| + * it under the terms of the GNU General Public License version 2 as |
| + * published by the Free Software Foundation. |
| + */ |
| + |
| +#include <linux/err.h> |
| +#include <linux/gpio.h> |
| +#include <linux/interrupt.h> |
| +#include <linux/jiffies.h> |
| +#include <linux/mmc/host.h> |
| +#include <linux/module.h> |
| +#include <linux/slab.h> |
| + |
| +struct mmc_cd_gpio { |
| + unsigned int gpio; |
| + char label[0]; |
| +}; |
| + |
| +static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id) |
| +{ |
| + /* Schedule a card detection after a debounce timeout */ |
| + mmc_detect_change(dev_id, msecs_to_jiffies(100)); |
| + return IRQ_HANDLED; |
| +} |
| + |
| +int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio, |
| + unsigned int irq, unsigned long flags) |
| +{ |
| + size_t len = strlen(dev_name(host->parent)) + 4; |
| + struct mmc_cd_gpio *cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL); |
| + int ret; |
| + |
| + if (!cd) |
| + return -ENOMEM; |
| + |
| + snprintf(cd->label, len, "%s cd", dev_name(host->parent)); |
| + |
| + ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label); |
| + if (ret < 0) |
| + goto egpioreq; |
| + |
| + ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt, |
| + flags, cd->label, host); |
| + if (ret < 0) |
| + goto eirqreq; |
| + |
| + cd->gpio = gpio; |
| + host->hotplug.irq = irq; |
| + host->hotplug.handler_priv = cd; |
| + |
| + return 0; |
| + |
| +eirqreq: |
| + gpio_free(gpio); |
| +egpioreq: |
| + kfree(cd); |
| + return ret; |
| +} |
| +EXPORT_SYMBOL(mmc_cd_gpio_request); |
| + |
| +void mmc_cd_gpio_free(struct mmc_host *host) |
| +{ |
| + struct mmc_cd_gpio *cd = host->hotplug.handler_priv; |
| + |
| + free_irq(host->hotplug.irq, host); |
| + gpio_free(cd->gpio); |
| + kfree(cd); |
| +} |
| +EXPORT_SYMBOL(mmc_cd_gpio_free); |
| diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/cd-gpio.h |
| new file mode 100644 |
| index 0000000..a8e4697 |
| --- /dev/null |
| +++ b/include/linux/mmc/cd-gpio.h |
| @@ -0,0 +1,19 @@ |
| +/* |
| + * Generic GPIO card-detect helper header |
| + * |
| + * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> |
| + * |
| + * This program is free software; you can redistribute it and/or modify |
| + * it under the terms of the GNU General Public License version 2 as |
| + * published by the Free Software Foundation. |
| + */ |
| + |
| +#ifndef MMC_CD_GPIO_H |
| +#define MMC_CD_GPIO_H |
| + |
| +struct mmc_host; |
| +int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio, |
| + unsigned int irq, unsigned long flags); |
| +void mmc_cd_gpio_free(struct mmc_host *host); |
| + |
| +#endif |
| -- |
| 1.7.10.2.565.gbd578b5 |
| |