From 0e49adfb9a60d31f30162c204de6131f484977c8 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 25 Dec 2011 21:36:02 +0100 Subject: [PATCH] --- yaml --- r: 284508 b: refs/heads/master c: 349ab52446772a359bc7e7699cae3880d48fa5c9 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/mmc/core/Makefile | 2 +- trunk/drivers/mmc/core/cd-gpio.c | 74 +++++++++++++++++++++++++++++++ trunk/include/linux/mmc/cd-gpio.h | 19 ++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 trunk/drivers/mmc/core/cd-gpio.c create mode 100644 trunk/include/linux/mmc/cd-gpio.h diff --git a/[refs] b/[refs] index cea1f7a20d69..098e2cfce875 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b67e198073b2d2f16572f5fa77553fec14775f69 +refs/heads/master: 349ab52446772a359bc7e7699cae3880d48fa5c9 diff --git a/trunk/drivers/mmc/core/Makefile b/trunk/drivers/mmc/core/Makefile index 639501970b41..dca4428380f1 100644 --- a/trunk/drivers/mmc/core/Makefile +++ b/trunk/drivers/mmc/core/Makefile @@ -7,6 +7,6 @@ mmc_core-y := core.o bus.o host.o \ mmc.o mmc_ops.o sd.o sd_ops.o \ sdio.o sdio_ops.o sdio_bus.o \ sdio_cis.o sdio_io.o sdio_irq.o \ - quirks.o + quirks.o cd-gpio.o mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/trunk/drivers/mmc/core/cd-gpio.c b/trunk/drivers/mmc/core/cd-gpio.c new file mode 100644 index 000000000000..082202ae4a03 --- /dev/null +++ b/trunk/drivers/mmc/core/cd-gpio.c @@ -0,0 +1,74 @@ +/* + * Generic GPIO card-detect helper + * + * Copyright (C) 2011, Guennadi Liakhovetski + * + * 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 +#include +#include +#include +#include +#include +#include + +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/trunk/include/linux/mmc/cd-gpio.h b/trunk/include/linux/mmc/cd-gpio.h new file mode 100644 index 000000000000..a8e469783318 --- /dev/null +++ b/trunk/include/linux/mmc/cd-gpio.h @@ -0,0 +1,19 @@ +/* + * Generic GPIO card-detect helper header + * + * Copyright (C) 2011, Guennadi Liakhovetski + * + * 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