aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/sparc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-27 22:59:48 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 05:15:25 -0400
commit0c0db98b50ed1217c0dbf4051722034ba314d06e (patch)
tree7fb374211bafe47cbd513b06bb36990869f463ea /Documentation/sparc
parent7eb1aae555663118f8d81bb26dca896d9cd8166c (diff)
sparc: Remove Documentation/sparc/sbus_drivers.txt
None of the text in this document is relevant any more. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'Documentation/sparc')
-rw-r--r--Documentation/sparc/sbus_drivers.txt309
1 files changed, 0 insertions, 309 deletions
diff --git a/Documentation/sparc/sbus_drivers.txt b/Documentation/sparc/sbus_drivers.txt
deleted file mode 100644
index eb1e28ad8822..000000000000
--- a/Documentation/sparc/sbus_drivers.txt
+++ /dev/null
@@ -1,309 +0,0 @@
1
2 Writing SBUS Drivers
3
4 David S. Miller (davem@redhat.com)
5
6 The SBUS driver interfaces of the Linux kernel have been
7revamped completely for 2.4.x for several reasons. Foremost were
8performance and complexity concerns. This document details these
9new interfaces and how they are used to write an SBUS device driver.
10
11 SBUS drivers need to include <asm/sbus.h> to get access
12to functions and structures described here.
13
14 Probing and Detection
15
16 Each SBUS device inside the machine is described by a
17structure called "struct sbus_dev". Likewise, each SBUS bus
18found in the system is described by a "struct sbus_bus". For
19each SBUS bus, the devices underneath are hung in a tree-like
20fashion off of the bus structure.
21
22 The SBUS device structure contains enough information
23for you to implement your device probing algorithm and obtain
24the bits necessary to run your device. The most commonly
25used members of this structure, and their typical usage,
26will be detailed below.
27
28 Here is a piece of skeleton code for performing a device
29probe in an SBUS driver under Linux:
30
31 static int __devinit mydevice_probe_one(struct sbus_dev *sdev)
32 {
33 struct mysdevice *mp = kzalloc(sizeof(*mp), GFP_KERNEL);
34
35 if (!mp)
36 return -ENODEV;
37
38 ...
39 dev_set_drvdata(&sdev->ofdev.dev, mp);
40 return 0;
41 ...
42 }
43
44 static int __devinit mydevice_probe(struct of_device *dev,
45 const struct of_device_id *match)
46 {
47 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
48
49 return mydevice_probe_one(sdev);
50 }
51
52 static int __devexit mydevice_remove(struct of_device *dev)
53 {
54 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
55 struct mydevice *mp = dev_get_drvdata(&dev->dev);
56
57 return mydevice_remove_one(sdev, mp);
58 }
59
60 static struct of_device_id mydevice_match[] = {
61 {
62 .name = "mydevice",
63 },
64 {},
65 };
66
67 MODULE_DEVICE_TABLE(of, mydevice_match);
68
69 static struct of_platform_driver mydevice_driver = {
70 .match_table = mydevice_match,
71 .probe = mydevice_probe,
72 .remove = __devexit_p(mydevice_remove),
73 .driver = {
74 .name = "mydevice",
75 },
76 };
77
78 static int __init mydevice_init(void)
79 {
80 return of_register_driver(&mydevice_driver, &sbus_bus_type);
81 }
82
83 static void __exit mydevice_exit(void)
84 {
85 of_unregister_driver(&mydevice_driver);
86 }
87
88 module_init(mydevice_init);
89 module_exit(mydevice_exit);
90
91 The mydevice_match table is a series of entries which
92describes what SBUS devices your driver is meant for. In the
93simplest case you specify a string for the 'name' field. Every
94SBUS device with a 'name' property matching your string will
95be passed one-by-one to your .probe method.
96
97 You should store away your device private state structure
98pointer in the drvdata area so that you can retrieve it later on
99in your .remove method.
100
101 Any memory allocated, registers mapped, IRQs registered,
102etc. must be undone by your .remove method so that all resources
103of your device are released by the time it returns.
104
105 You should _NOT_ use the for_each_sbus(), for_each_sbusdev(),
106and for_all_sbusdev() interfaces. They are deprecated, will be
107removed, and no new driver should reference them ever.
108
109 Mapping and Accessing I/O Registers
110
111 Each SBUS device structure contains an array of descriptors
112which describe each register set. We abuse struct resource for that.
113They each correspond to the "reg" properties provided by the OBP firmware.
114
115 Before you can access your device's registers you must map
116them. And later if you wish to shutdown your driver (for module
117unload or similar) you must unmap them. You must treat them as
118a resource, which you allocate (map) before using and free up
119(unmap) when you are done with it.
120
121 The mapping information is stored in an opaque value
122typed as an "unsigned long". This is the type of the return value
123of the mapping interface, and the arguments to the unmapping
124interface. Let's say you want to map the first set of registers.
125Perhaps part of your driver software state structure looks like:
126
127 struct mydevice {
128 unsigned long control_regs;
129 ...
130 struct sbus_dev *sdev;
131 ...
132 };
133
134 At initialization time you then use the sbus_ioremap
135interface to map in your registers, like so:
136
137 static void init_one_mydevice(struct sbus_dev *sdev)
138 {
139 struct mydevice *mp;
140 ...
141
142 mp->control_regs = sbus_ioremap(&sdev->resource[0], 0,
143 CONTROL_REGS_SIZE, "mydevice regs");
144 if (!mp->control_regs) {
145 /* Failure, cleanup and return. */
146 }
147 }
148
149 Second argument to sbus_ioremap is an offset for
150cranky devices with broken OBP PROM. The sbus_ioremap uses only
151a start address and flags from the resource structure.
152Therefore it is possible to use the same resource to map
153several sets of registers or even to fabricate a resource
154structure if driver gets physical address from some private place.
155This practice is discouraged though. Use whatever OBP PROM
156provided to you.
157
158 And here is how you might unmap these registers later at
159driver shutdown or module unload time, using the sbus_iounmap
160interface:
161
162 static void mydevice_unmap_regs(struct mydevice *mp)
163 {
164 sbus_iounmap(mp->control_regs, CONTROL_REGS_SIZE);
165 }
166
167 Finally, to actually access your registers there are 6
168interface routines at your disposal. Accesses are byte (8 bit),
169word (16 bit), or longword (32 bit) sized. Here they are:
170
171 u8 sbus_readb(unsigned long reg) /* read byte */
172 u16 sbus_readw(unsigned long reg) /* read word */
173 u32 sbus_readl(unsigned long reg) /* read longword */
174 void sbus_writeb(u8 value, unsigned long reg) /* write byte */
175 void sbus_writew(u16 value, unsigned long reg) /* write word */
176 void sbus_writel(u32 value, unsigned long reg) /* write longword */
177
178 So, let's say your device has a control register of some sort
179at offset zero. The following might implement resetting your device:
180
181 #define CONTROL 0x00UL
182
183 #define CONTROL_RESET 0x00000001 /* Reset hardware */
184
185 static void mydevice_reset(struct mydevice *mp)
186 {
187 sbus_writel(CONTROL_RESET, mp->regs + CONTROL);
188 }
189
190 Or perhaps there is a data port register at an offset of
19116 bytes which allows you to read bytes from a fifo in the device:
192
193 #define DATA 0x10UL
194
195 static u8 mydevice_get_byte(struct mydevice *mp)
196 {
197 return sbus_readb(mp->regs + DATA);
198 }
199
200 It's pretty straightforward, and clueful readers may have
201noticed that these interfaces mimick the PCI interfaces of the
202Linux kernel. This was not by accident.
203
204 WARNING:
205
206 DO NOT try to treat these opaque register mapping
207 values as a memory mapped pointer to some structure
208 which you can dereference.
209
210 It may be memory mapped, it may not be. In fact it
211 could be a physical address, or it could be the time
212 of day xor'd with 0xdeadbeef. :-)
213
214 Whatever it is, it's an implementation detail. The
215 interface was done this way to shield the driver
216 author from such complexities.
217
218 Doing DVMA
219
220 SBUS devices can perform DMA transactions in a way similar
221to PCI but dissimilar to ISA, e.g. DMA masters supply address.
222In contrast to PCI, however, that address (a bus address) is
223translated by IOMMU before a memory access is performed and therefore
224it is virtual. Sun calls this procedure DVMA.
225
226 Linux supports two styles of using SBUS DVMA: "consistent memory"
227and "streaming DVMA". CPU view of consistent memory chunk is, well,
228consistent with a view of a device. Think of it as an uncached memory.
229Typically this way of doing DVMA is not very fast and drivers use it
230mostly for control blocks or queues. On some CPUs we cannot flush or
231invalidate individual pages or cache lines and doing explicit flushing
232over ever little byte in every control block would be wasteful.
233
234Streaming DVMA is a preferred way to transfer large amounts of data.
235This process works in the following way:
2361. a CPU stops accessing a certain part of memory,
237 flushes its caches covering that memory;
2382. a device does DVMA accesses, then posts an interrupt;
2393. CPU invalidates its caches and starts to access the memory.
240
241A single streaming DVMA operation can touch several discontiguous
242regions of a virtual bus address space. This is called a scatter-gather
243DVMA.
244
245[TBD: Why do not we neither Solaris attempt to map disjoint pages
246into a single virtual chunk with the help of IOMMU, so that non SG
247DVMA masters would do SG? It'd be very helpful for RAID.]
248
249 In order to perform a consistent DVMA a driver does something
250like the following:
251
252 char *mem; /* Address in the CPU space */
253 u32 busa; /* Address in the SBus space */
254
255 mem = (char *) sbus_alloc_consistent(sdev, MYMEMSIZE, &busa);
256
257 Then mem is used when CPU accesses this memory and u32
258is fed to the device so that it can do DVMA. This is typically
259done with an sbus_writel() into some device register.
260
261 Do not forget to free the DVMA resources once you are done:
262
263 sbus_free_consistent(sdev, MYMEMSIZE, mem, busa);
264
265 Streaming DVMA is more interesting. First you allocate some
266memory suitable for it or pin down some user pages. Then it all works
267like this:
268
269 char *mem = argumen1;
270 unsigned int size = argument2;
271 u32 busa; /* Address in the SBus space */
272
273 *mem = 1; /* CPU can access */
274 busa = sbus_map_single(sdev, mem, size);
275 if (busa == 0) .......
276
277 /* Tell the device to use busa here */
278 /* CPU cannot access the memory without sbus_dma_sync_single() */
279
280 sbus_unmap_single(sdev, busa, size);
281 if (*mem == 0) .... /* CPU can access again */
282
283 It is possible to retain mappings and ask the device to
284access data again and again without calling sbus_unmap_single.
285However, CPU caches must be invalidated with sbus_dma_sync_single
286before such access.
287
288[TBD but what about writeback caches here... do we have any?]
289
290 There is an equivalent set of functions doing the same thing
291only with several memory segments at once for devices capable of
292scatter-gather transfers. Use the Source, Luke.
293
294 Examples
295
296 drivers/net/sunhme.c
297 This is a complicated driver which illustrates many concepts
298discussed above and plus it handles both PCI and SBUS boards.
299
300 drivers/scsi/esp.c
301 Check it out for scatter-gather DVMA.
302
303 drivers/sbus/char/bpp.c
304 A non-DVMA device.
305
306 drivers/net/sunlance.c
307 Lance driver abuses consistent mappings for data transfer.
308It is a nifty trick which we do not particularly recommend...
309Just check it out and know that it's legal.