summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm-2.4/patches/009-wrt54g3g_pcmcia.patch
blob: 81b5ee80c5ed74925676ea7b2a035ab5b5a2e4d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
--- a/drivers/pcmcia/yenta.c
+++ b/drivers/pcmcia/yenta.c
@@ -543,6 +543,9 @@ static unsigned int yenta_probe_irq(pci_
 	 * Probe for usable interrupts using the force
 	 * register to generate bogus card status events.
 	 */
+
+#ifndef CONFIG_BCM947XX
+	/* WRT54G3G does not like this */
 	cb_writel(socket, CB_SOCKET_EVENT, -1);
 	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
 	exca_writeb(socket, I365_CSCINT, 0);
@@ -557,7 +560,8 @@ static unsigned int yenta_probe_irq(pci_
 	}
 	cb_writel(socket, CB_SOCKET_MASK, 0);
 	exca_writeb(socket, I365_CSCINT, 0);
-	
+#endif
+
 	mask = probe_irq_mask(val) & 0xffff;
 
 	bridge_ctrl &= ~CB_BRIDGE_INTR;
@@ -578,6 +582,12 @@ static void yenta_get_socket_capabilitie
 	socket->cap.cb_dev = socket->dev;
 	socket->cap.bus = NULL;
 
+#ifdef CONFIG_BCM947XX
+	/* irq mask probing is broken for the WRT54G3G */
+	if (socket->cap.irq_mask == 0)
+		socket->cap.irq_mask = 0x6f8;
+#endif
+
 	printk(KERN_INFO "Yenta ISA IRQ mask 0x%04x, PCI irq %d\n",
 	       socket->cap.irq_mask, socket->cb_irq);
 }
@@ -609,6 +619,15 @@ static void yenta_open_bh(void * data)
 	printk(KERN_INFO "Socket status: %08x\n",
 	       cb_readl(socket, CB_SOCKET_STATE));
 
+	/* Generate an interrupt on card insert/remove */
+	config_writew(socket, CB_SOCKET_MASK, CB_CSTSMASK | CB_CDMASK);
+
+	/* Set up Multifunction Routing Status Register */
+	config_writew(socket, 0x8C, 0x1000 /* MFUNC3 to GPIO3 */ | 0x2 /* MFUNC0 to INTA */);
+	
+	/* Switch interrupts to parallelized */
+	config_writeb(socket, 0x92, 0x64);
+	
 	/* Register it with the pcmcia layer.. */
 	cardbus_register(socket);
 
@@ -731,7 +750,7 @@ static void yenta_allocate_res(pci_socke
 {
 	struct pci_bus *bus;
 	struct resource *root, *res;
-	u32 start, end;
+	u32 start = 0, end = 0;
 	u32 align, size, min, max;
 	unsigned offset;
 	unsigned mask;
@@ -750,6 +769,15 @@ static void yenta_allocate_res(pci_socke
 	res->end = 0;
 	root = pci_find_parent_resource(socket->dev, res);
 
+#ifdef CONFIG_BCM947XX
+	/* default mem resources are completely fscked up on the wrt54g3g */
+	/* bypass the entire resource allocation stuff below and just set it statically */
+	if (type & IORESOURCE_MEM) {
+		res->start = 0x40004000;
+		res->end = res->start + 0x3fff;
+	}
+
+#else
 	if (!root)
 		return;
 
@@ -794,6 +822,7 @@ static void yenta_allocate_res(pci_socke
 		res->start = res->end = 0;
 		return;
 	}
+#endif
 
 	config_writel(socket, offset, res->start);
 	config_writel(socket, offset+4, res->end);