
From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

I received report that transmission of Realtek 8139 doesn't work.  The
cause of this problem was CLKRUN protocols of laptop's TI 12xx CardBus
bridge.

CLKRUN is used for controlling the PCI clock by PCI devices (for power saving).
 If device has bug, probably it becomes the cause of stopping the PCI clock at
an unexpected timing.

In the problem of realtek 8139 case, the TX packet which the driver set to the
device was not sent out (still pending state in device).

If "disable_clkrun" is enabled, the problem of TX stopped occurring.  So, I
thought the cause is CLKRUN, and is hardware bug of Cardbus or realtek 8139. 
(8139 seems only can control by rewriting EEPROM)

And looks like also
 http://support.microsoft.com/default.aspx?scid=kb;en-us;q294465
 http://support.microsoft.com/default.aspx?scid=kb;en-us;182591
has the problem of CLKRUN.

And I remember that this problem had happened on Thinkpad before.  In the
case, problem seems solved by similar workaround of sound/oss/cs46xx.c.

This patch adds "disable_clkrun" option as workaround of problem to
yenta_socket.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/pcmcia/ti113x.h       |   11 ++++++++---
 25-akpm/drivers/pcmcia/yenta_socket.c |    3 +++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff -puN drivers/pcmcia/ti113x.h~pcmcia-add-disable_clkrun-option drivers/pcmcia/ti113x.h
--- 25/drivers/pcmcia/ti113x.h~pcmcia-add-disable_clkrun-option	2004-12-03 18:44:53.933584048 -0800
+++ 25-akpm/drivers/pcmcia/ti113x.h	2004-12-03 18:44:53.939583136 -0800
@@ -592,15 +592,20 @@ out:
 
 static int ti12xx_override(struct yenta_socket *socket)
 {
-	u32 val;
+	u32 val, val_orig;
 
 	/* make sure that memory burst is active */
-	val = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	val_orig = val = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	if (disable_clkrun && PCI_FUNC(socket->dev->devfn) == 0) {
+		printk(KERN_INFO "Yenta: Disabling CLKRUN feature\n");
+		val |= TI113X_SCR_KEEPCLK;
+	}
 	if (!(val & TI122X_SCR_MRBURSTUP)) {
 		printk(KERN_INFO "Yenta: Enabling burst memory read transactions\n");
 		val |= TI122X_SCR_MRBURSTUP;
-		config_writel(socket, TI113X_SYSTEM_CONTROL, val);
 	}
+	if (val_orig != val)
+		config_writel(socket, TI113X_SYSTEM_CONTROL, val);
 
 	/*
 	 * for EnE bridges only: clear testbit TLTEnable. this makes the
diff -puN drivers/pcmcia/yenta_socket.c~pcmcia-add-disable_clkrun-option drivers/pcmcia/yenta_socket.c
--- 25/drivers/pcmcia/yenta_socket.c~pcmcia-add-disable_clkrun-option	2004-12-03 18:44:53.935583744 -0800
+++ 25-akpm/drivers/pcmcia/yenta_socket.c	2004-12-03 18:44:53.940582984 -0800
@@ -28,6 +28,9 @@
 #include "yenta_socket.h"
 #include "i82365.h"
 
+static int disable_clkrun;
+module_param(disable_clkrun, bool, 0444);
+MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
 
 #if 0
 #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
_
