|
@@ -344,28 +344,32 @@ static struct platform_device db1200_ide_dev = {
|
|
|
|
|
|
/* SD carddetects: they're supposed to be edge-triggered, but ack
|
|
|
* doesn't seem to work (CPLD Rev 2). Instead, the screaming one
|
|
|
- * is disabled and its counterpart enabled. The 500ms timeout is
|
|
|
- * because the carddetect isn't debounced in hardware.
|
|
|
+ * is disabled and its counterpart enabled. The 200ms timeout is
|
|
|
+ * because the carddetect usually triggers twice, after debounce.
|
|
|
*/
|
|
|
static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
|
|
|
{
|
|
|
- void(*mmc_cd)(struct mmc_host *, unsigned long);
|
|
|
+ disable_irq_nosync(irq);
|
|
|
+ return IRQ_WAKE_THREAD;
|
|
|
+}
|
|
|
|
|
|
- if (irq == DB1200_SD0_INSERT_INT) {
|
|
|
- disable_irq_nosync(DB1200_SD0_INSERT_INT);
|
|
|
- enable_irq(DB1200_SD0_EJECT_INT);
|
|
|
- } else {
|
|
|
- disable_irq_nosync(DB1200_SD0_EJECT_INT);
|
|
|
- enable_irq(DB1200_SD0_INSERT_INT);
|
|
|
- }
|
|
|
+static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr)
|
|
|
+{
|
|
|
+ void (*mmc_cd)(struct mmc_host *, unsigned long);
|
|
|
|
|
|
/* link against CONFIG_MMC=m */
|
|
|
mmc_cd = symbol_get(mmc_detect_change);
|
|
|
if (mmc_cd) {
|
|
|
- mmc_cd(ptr, msecs_to_jiffies(500));
|
|
|
+ mmc_cd(ptr, msecs_to_jiffies(200));
|
|
|
symbol_put(mmc_detect_change);
|
|
|
}
|
|
|
|
|
|
+ msleep(100); /* debounce */
|
|
|
+ if (irq == DB1200_SD0_INSERT_INT)
|
|
|
+ enable_irq(DB1200_SD0_EJECT_INT);
|
|
|
+ else
|
|
|
+ enable_irq(DB1200_SD0_INSERT_INT);
|
|
|
+
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
@@ -374,13 +378,13 @@ static int db1200_mmc_cd_setup(void *mmc_host, int en)
|
|
|
int ret;
|
|
|
|
|
|
if (en) {
|
|
|
- ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
|
|
|
- 0, "sd_insert", mmc_host);
|
|
|
+ ret = request_threaded_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
|
|
|
+ db1200_mmc_cdfn, 0, "sd_insert", mmc_host);
|
|
|
if (ret)
|
|
|
goto out;
|
|
|
|
|
|
- ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
|
|
|
- 0, "sd_eject", mmc_host);
|
|
|
+ ret = request_threaded_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
|
|
|
+ db1200_mmc_cdfn, 0, "sd_eject", mmc_host);
|
|
|
if (ret) {
|
|
|
free_irq(DB1200_SD0_INSERT_INT, mmc_host);
|
|
|
goto out;
|
|
@@ -436,23 +440,27 @@ static struct led_classdev db1200_mmc_led = {
|
|
|
|
|
|
static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr)
|
|
|
{
|
|
|
- void(*mmc_cd)(struct mmc_host *, unsigned long);
|
|
|
+ disable_irq_nosync(irq);
|
|
|
+ return IRQ_WAKE_THREAD;
|
|
|
+}
|
|
|
|
|
|
- if (irq == PB1200_SD1_INSERT_INT) {
|
|
|
- disable_irq_nosync(PB1200_SD1_INSERT_INT);
|
|
|
- enable_irq(PB1200_SD1_EJECT_INT);
|
|
|
- } else {
|
|
|
- disable_irq_nosync(PB1200_SD1_EJECT_INT);
|
|
|
- enable_irq(PB1200_SD1_INSERT_INT);
|
|
|
- }
|
|
|
+static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr)
|
|
|
+{
|
|
|
+ void (*mmc_cd)(struct mmc_host *, unsigned long);
|
|
|
|
|
|
/* link against CONFIG_MMC=m */
|
|
|
mmc_cd = symbol_get(mmc_detect_change);
|
|
|
if (mmc_cd) {
|
|
|
- mmc_cd(ptr, msecs_to_jiffies(500));
|
|
|
+ mmc_cd(ptr, msecs_to_jiffies(200));
|
|
|
symbol_put(mmc_detect_change);
|
|
|
}
|
|
|
|
|
|
+ msleep(100); /* debounce */
|
|
|
+ if (irq == PB1200_SD1_INSERT_INT)
|
|
|
+ enable_irq(PB1200_SD1_EJECT_INT);
|
|
|
+ else
|
|
|
+ enable_irq(PB1200_SD1_INSERT_INT);
|
|
|
+
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
@@ -461,13 +469,13 @@ static int pb1200_mmc1_cd_setup(void *mmc_host, int en)
|
|
|
int ret;
|
|
|
|
|
|
if (en) {
|
|
|
- ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0,
|
|
|
- "sd1_insert", mmc_host);
|
|
|
+ ret = request_threaded_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd,
|
|
|
+ pb1200_mmc1_cdfn, 0, "sd1_insert", mmc_host);
|
|
|
if (ret)
|
|
|
goto out;
|
|
|
|
|
|
- ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0,
|
|
|
- "sd1_eject", mmc_host);
|
|
|
+ ret = request_threaded_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd,
|
|
|
+ pb1200_mmc1_cdfn, 0, "sd1_eject", mmc_host);
|
|
|
if (ret) {
|
|
|
free_irq(PB1200_SD1_INSERT_INT, mmc_host);
|
|
|
goto out;
|