aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-3.2/024-brcm47xx-add-common-interface-for-sflash.patch
blob: 1cf4ee64149d03492719594f5118f53fa52d029b (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
--- a/arch/mips/bcm47xx/Makefile
+++ b/arch/mips/bcm47xx/Makefile
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
+obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o bus.o
 obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o
--- /dev/null
+++ b/arch/mips/bcm47xx/bus.c
@@ -0,0 +1,82 @@
+/*
+ * BCM947xx nvram variable access
+ *
+ * Copyright (C) 2011 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <bus.h>
+
+static int bcm47xx_sflash_bcma_read(struct bcm47xx_sflash *dev, u32 offset, u32 len, u8 *buf)
+{
+	return bcma_sflash_read(dev->bcc, offset, len, buf);
+}
+
+static int bcm47xx_sflash_bcma_poll(struct bcm47xx_sflash *dev, u32 offset)
+{
+	return bcma_sflash_poll(dev->bcc, offset);
+}
+
+static int bcm47xx_sflash_bcma_write(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf)
+{
+	return bcma_sflash_write(dev->bcc, offset, len, buf);
+}
+
+static int bcm47xx_sflash_bcma_erase(struct bcm47xx_sflash *dev, u32 offset)
+{
+	return bcma_sflash_erase(dev->bcc, offset);
+}
+
+void bcm47xx_sflash_struct_bcma_init(struct bcm47xx_sflash *sflash, struct bcma_drv_cc *bcc)
+{
+	sflash->sflash_type = BCM47XX_BUS_TYPE_BCMA;
+	sflash->bcc = bcc;
+
+	sflash->read = bcm47xx_sflash_bcma_read;
+	sflash->poll = bcm47xx_sflash_bcma_poll;
+	sflash->write = bcm47xx_sflash_bcma_write;
+	sflash->erase = bcm47xx_sflash_bcma_erase;
+
+	sflash->blocksize = bcc->sflash.blocksize;
+	sflash->numblocks = bcc->sflash.numblocks;
+	sflash->size = bcc->sflash.size;
+}
+
+static int bcm47xx_sflash_ssb_read(struct bcm47xx_sflash *dev, u32 offset, u32 len, u8 *buf)
+{
+	return ssb_sflash_read(dev->scc, offset, len, buf);
+}
+
+static int bcm47xx_sflash_ssb_poll(struct bcm47xx_sflash *dev, u32 offset)
+{
+	return ssb_sflash_poll(dev->scc, offset);
+}
+
+static int bcm47xx_sflash_ssb_write(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf)
+{
+	return ssb_sflash_write(dev->scc, offset, len, buf);
+}
+
+static int bcm47xx_sflash_ssb_erase(struct bcm47xx_sflash *dev, u32 offset)
+{
+	return ssb_sflash_erase(dev->scc, offset);
+}
+
+void bcm47xx_sflash_struct_ssb_init(struct bcm47xx_sflash *sflash, struct ssb_chipcommon *scc)
+{
+	sflash->sflash_type = BCM47XX_BUS_TYPE_SSB;
+	sflash->scc = scc;
+
+	sflash->read = bcm47xx_sflash_ssb_read;
+	sflash->poll = bcm47xx_sflash_ssb_poll;
+	sflash->write = bcm47xx_sflash_ssb_write;
+	sflash->erase = bcm47xx_sflash_ssb_erase;
+
+	sflash->blocksize = scc->sflash.blocksize;
+	sflash->numblocks = scc->sflash.numblocks;
+	sflash->size = scc->sflash.size;
+}
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -43,6 +43,8 @@ EXPORT_SYMBOL(bcm47xx_bus);
 enum bcm47xx_bus_type bcm47xx_bus_type;
 EXPORT_SYMBOL(bcm47xx_bus_type);
 
+struct bcm47xx_sflash bcm47xx_sflash;
+
 static void bcm47xx_machine_restart(char *command)
 {
 	printk(KERN_ALERT "Please stand by while rebooting the system...\n");
@@ -291,6 +293,9 @@ static void __init bcm47xx_register_ssb(
 	if (err)
 		panic("Failed to initialize SSB bus (err %d)\n", err);
 
+	if (bcm47xx_bus.ssb.chipco.flash_type == SSB_SFLASH)
+		bcm47xx_sflash_struct_ssb_init(&bcm47xx_sflash, &bcm47xx_bus.ssb.chipco);
+
 	mcore = &bcm47xx_bus.ssb.mipscore;
 	if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
 		if (strstr(buf, "console=ttyS1")) {
@@ -315,6 +320,9 @@ static void __init bcm47xx_register_bcma
 	err = bcma_host_soc_register(&bcm47xx_bus.bcma);
 	if (err)
 		panic("Failed to initialize BCMA bus (err %d)\n", err);
+
+	if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH)
+		bcm47xx_sflash_struct_bcma_init(&bcm47xx_sflash, &bcm47xx_bus.bcma.bus.drv_cc);
 }
 #endif
 
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm47xx/bus.h
@@ -0,0 +1,36 @@
+/*
+ * BCM947xx nvram variable access
+ *
+ * Copyright (C) 2011 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
+#include <bcm47xx.h>
+
+struct bcm47xx_sflash {
+	enum bcm47xx_bus_type sflash_type;
+	union {
+		struct ssb_chipcommon *scc;
+		struct bcma_drv_cc *bcc;
+	};
+
+	int (*read)(struct bcm47xx_sflash *dev, u32 offset, u32 len, u8 *buf);
+	int (*poll)(struct bcm47xx_sflash *dev, u32 offset);
+	int (*write)(struct bcm47xx_sflash *dev, u32 offset, u32 len, const u8 *buf);
+	int (*erase)(struct bcm47xx_sflash *dev, u32 offset);
+
+	u32 blocksize;		/* Block size */
+	u32 numblocks;		/* Number of blocks */
+	u32 size;		/* Total size in bytes */
+};
+
+void bcm47xx_sflash_struct_bcma_init(struct bcm47xx_sflash *sflash, struct bcma_drv_cc *bcc);
+void bcm47xx_sflash_struct_ssb_init(struct bcm47xx_sflash *sflash, struct ssb_chipcommon *scc);
+
+extern struct bcm47xx_sflash bcm47xx_sflash;