--- d/ar6000/hif/hif2.c	2009-03-30 01:11:04.000000000 +0400
+++ e/ar6000//hif/hif2.c	2009-03-30 01:33:03.000000000 +0400
@@ -98,6 +98,13 @@
 	struct sdio_func *func;
 
 	/*
+	 * SDIO irq process handle, for prevent claim/relese in irq call.
+	 * we must try not permit send any, not IRQ process necessary data,
+	 * while IRQ not completed.
+	 */
+	struct task_struct *irq_task;
+
+	/*
 	 * @@@ our sweet little bit of bogosity - the mechanism that lets us
 	 * use the SDIO stack from softirqs. This really wants to use skbs.
 	 */
@@ -202,7 +209,9 @@
 
 	hif = sdio_get_drvdata(func);
 
-	sdio_claim_host(func);
+	/* prevent claim in irq */
+	if (hif->irq_task != current)
+		sdio_claim_host(func);
 
 #ifdef _GTA02_
 	while (!s3c2410_gpio_getpin(S3C2410_GPE7)) {
@@ -212,7 +221,9 @@
 
 	mmc_wait_for_req(host, &req.mrq);
 
-	sdio_release_host(func);
+	/* prevent relese in irq */
+	if (hif->irq_task != current)
+		sdio_release_host(func);
 
 	if ((req.cmd.error) || (req.data.error))
 		return A_ERROR;
@@ -420,9 +431,10 @@
 	 *
 	 * Solution 2) is probably the best for now. Will try it later.
 	 */
-	sdio_release_host(func);
+	hif->irq_task = current;
 	ar6000_do_irq(func);
-	sdio_claim_host(func);
+	hif->irq_task = NULL;
+
 	in_interrupt = 0;
 }
 
@@ -515,8 +527,13 @@
 			mbs_cfg[i] = HIF_MBOX_START_ADDR(i);
 		break;
 	case HIF_DEVICE_GET_IRQ_PROC_MODE:
-		*ipm_cfg = HIF_DEVICE_IRQ_SYNC_ONLY;
-//		*ipm_cfg = HIF_DEVICE_IRQ_ASYNC_SYNC;
+		/*
+		 * WARN:
+		 * HIF_DEVICE_IRQ_ASYNC_SYNC in BUG list, but I not have it problem.
+		 * Need additional testing on different boards.
+		 */
+//		*ipm_cfg = HIF_DEVICE_IRQ_SYNC_ONLY;
+		*ipm_cfg = HIF_DEVICE_IRQ_ASYNC_SYNC;
 		break;
 	default:
 		return A_ERROR;
@@ -574,7 +591,6 @@
 	return 0;
 }
 
-
 /* ----- Device probe and removal (Linux side) ----------------------------- */
 
 
