-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Guennadi Liakhovetski
authored and
Chris Ball
committed
Jan 12, 2012
1 parent
b67e198
commit 349ab52
Showing
3 changed files
with
94 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |