aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 12:02:26 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 12:02:26 -0500
commit37969581301e50872a1ae84dc73962b5f7ee6b76 (patch)
tree35bbd6a07f903f248f4bd209b8d194a922415fe0 /drivers
parent80ff8a805113850a3ffafcc8e6eaa1fdd51b02f3 (diff)
parent24f1a849614ba1805e26a05da7cc8c6bd67490ea (diff)
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (69 commits) [POWERPC] Add SPE registers to core dumps [POWERPC] Use regset code for compat PTRACE_*REGS* calls [POWERPC] Use generic compat_sys_ptrace [POWERPC] Use generic compat_ptrace_request [POWERPC] Use generic ptrace peekdata/pokedata [POWERPC] Use regset code for PTRACE_*REGS* requests [POWERPC] Switch to generic compat_binfmt_elf code [POWERPC] Switch to using user_regset-based core dumps [POWERPC] Add user_regset compat support [POWERPC] Add user_regset_view definitions [POWERPC] Use user_regset accessors for GPRs [POWERPC] ptrace accessors for special regs MSR and TRAP [POWERPC] Use user_regset accessors for SPE regs [POWERPC] Use user_regset accessors for altivec regs [POWERPC] Use user_regset accessors for FP regs [POWERPC] mpc52xx: fix compile error introduce when rebasing patch [POWERPC] 4xx: PCIe indirect DCR spinlock fix. [POWERPC] Add missing native dcr dcr_ind_lock spinlock [POWERPC] 4xx: Fix offset value on Warp board [POWERPC] 4xx: Add 440EPx Sequoia ehci dts entry ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/xsysace.c6
-rw-r--r--drivers/cdrom/viocd.c2
-rw-r--r--drivers/char/Kconfig10
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/xilinx_hwicap/Makefile7
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.c380
-rw-r--r--drivers/char/xilinx_hwicap/buffer_icap.h57
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.c381
-rw-r--r--drivers/char/xilinx_hwicap/fifo_icap.h62
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c904
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.h193
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/cpmac.c55
-rw-r--r--drivers/of/base.c25
-rw-r--r--drivers/of/platform.c10
-rw-r--r--drivers/serial/Kconfig12
-rw-r--r--drivers/serial/mpc52xx_uart.c424
-rw-r--r--drivers/serial/uartlite.c53
-rw-r--r--drivers/video/xilinxfb.c4
19 files changed, 2430 insertions, 160 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 78ebfffc77e3..4a7a059ebaf7 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -1202,8 +1202,10 @@ static int __devexit ace_of_remove(struct of_device *op)
1202} 1202}
1203 1203
1204/* Match table for of_platform binding */ 1204/* Match table for of_platform binding */
1205static struct of_device_id __devinit ace_of_match[] = { 1205static struct of_device_id ace_of_match[] __devinitdata = {
1206 { .compatible = "xilinx,xsysace", }, 1206 { .compatible = "xlnx,opb-sysace-1.00.b", },
1207 { .compatible = "xlnx,opb-sysace-1.00.c", },
1208 { .compatible = "xlnx,xps-sysace-1.00.a", },
1207 {}, 1209 {},
1208}; 1210};
1209MODULE_DEVICE_TABLE(of, ace_of_match); 1211MODULE_DEVICE_TABLE(of, ace_of_match);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 8473b9f1da96..cac06bc1754b 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -558,7 +558,7 @@ static struct cdrom_device_ops viocd_dops = {
558 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM 558 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
559}; 559};
560 560
561static int __init find_capability(const char *type) 561static int find_capability(const char *type)
562{ 562{
563 struct capability_entry *entry; 563 struct capability_entry *entry;
564 564
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7927fd0faca3..f01ac9a07bf5 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -830,6 +830,16 @@ config DTLK
830 To compile this driver as a module, choose M here: the 830 To compile this driver as a module, choose M here: the
831 module will be called dtlk. 831 module will be called dtlk.
832 832
833config XILINX_HWICAP
834 tristate "Xilinx HWICAP Support"
835 depends on XILINX_VIRTEX
836 help
837 This option enables support for Xilinx Internal Configuration
838 Access Port (ICAP) driver. The ICAP is used on Xilinx Virtex
839 FPGA platforms to partially reconfigure the FPGA at runtime.
840
841 If unsure, say N.
842
833config R3964 843config R3964
834 tristate "Siemens R3964 line discipline" 844 tristate "Siemens R3964 line discipline"
835 ---help--- 845 ---help---
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 4396e37b3d0f..5407b7615614 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_EFI_RTC) += efirtc.o
76obj-$(CONFIG_SGI_DS1286) += ds1286.o 76obj-$(CONFIG_SGI_DS1286) += ds1286.o
77obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o 77obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
78obj-$(CONFIG_DS1302) += ds1302.o 78obj-$(CONFIG_DS1302) += ds1302.o
79obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/
79ifeq ($(CONFIG_GENERIC_NVRAM),y) 80ifeq ($(CONFIG_GENERIC_NVRAM),y)
80 obj-$(CONFIG_NVRAM) += generic_nvram.o 81 obj-$(CONFIG_NVRAM) += generic_nvram.o
81else 82else
diff --git a/drivers/char/xilinx_hwicap/Makefile b/drivers/char/xilinx_hwicap/Makefile
new file mode 100644
index 000000000000..5491cbc42f43
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Xilinx OPB hwicap driver
3#
4
5obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap_m.o
6
7xilinx_hwicap_m-y := xilinx_hwicap.o fifo_icap.o buffer_icap.o
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c
new file mode 100644
index 000000000000..dfea2bde162b
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/buffer_icap.c
@@ -0,0 +1,380 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2003-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#include "buffer_icap.h"
37
38/* Indicates how many bytes will fit in a buffer. (1 BRAM) */
39#define XHI_MAX_BUFFER_BYTES 2048
40#define XHI_MAX_BUFFER_INTS (XHI_MAX_BUFFER_BYTES >> 2)
41
42/* File access and error constants */
43#define XHI_DEVICE_READ_ERROR -1
44#define XHI_DEVICE_WRITE_ERROR -2
45#define XHI_BUFFER_OVERFLOW_ERROR -3
46
47#define XHI_DEVICE_READ 0x1
48#define XHI_DEVICE_WRITE 0x0
49
50/* Constants for checking transfer status */
51#define XHI_CYCLE_DONE 0
52#define XHI_CYCLE_EXECUTING 1
53
54/* buffer_icap register offsets */
55
56/* Size of transfer, read & write */
57#define XHI_SIZE_REG_OFFSET 0x800L
58/* offset into bram, read & write */
59#define XHI_BRAM_OFFSET_REG_OFFSET 0x804L
60/* Read not Configure, direction of transfer. Write only */
61#define XHI_RNC_REG_OFFSET 0x808L
62/* Indicates transfer complete. Read only */
63#define XHI_STATUS_REG_OFFSET 0x80CL
64
65/* Constants for setting the RNC register */
66#define XHI_CONFIGURE 0x0UL
67#define XHI_READBACK 0x1UL
68
69/* Constants for the Done register */
70#define XHI_NOT_FINISHED 0x0UL
71#define XHI_FINISHED 0x1UL
72
73#define XHI_BUFFER_START 0
74
75/**
76 * buffer_icap_get_status: Get the contents of the status register.
77 * @parameter base_address: is the base address of the device
78 *
79 * The status register contains the ICAP status and the done bit.
80 *
81 * D8 - cfgerr
82 * D7 - dalign
83 * D6 - rip
84 * D5 - in_abort_l
85 * D4 - Always 1
86 * D3 - Always 1
87 * D2 - Always 1
88 * D1 - Always 1
89 * D0 - Done bit
90 **/
91static inline u32 buffer_icap_get_status(void __iomem *base_address)
92{
93 return in_be32(base_address + XHI_STATUS_REG_OFFSET);
94}
95
96/**
97 * buffer_icap_get_bram: Reads data from the storage buffer bram.
98 * @parameter base_address: contains the base address of the component.
99 * @parameter offset: The word offset from which the data should be read.
100 *
101 * A bram is used as a configuration memory cache. One frame of data can
102 * be stored in this "storage buffer".
103 **/
104static inline u32 buffer_icap_get_bram(void __iomem *base_address,
105 u32 offset)
106{
107 return in_be32(base_address + (offset << 2));
108}
109
110/**
111 * buffer_icap_busy: Return true if the icap device is busy
112 * @parameter base_address: is the base address of the device
113 *
114 * The queries the low order bit of the status register, which
115 * indicates whether the current configuration or readback operation
116 * has completed.
117 **/
118static inline bool buffer_icap_busy(void __iomem *base_address)
119{
120 return (buffer_icap_get_status(base_address) & 1) == XHI_NOT_FINISHED;
121}
122
123/**
124 * buffer_icap_busy: Return true if the icap device is not busy
125 * @parameter base_address: is the base address of the device
126 *
127 * The queries the low order bit of the status register, which
128 * indicates whether the current configuration or readback operation
129 * has completed.
130 **/
131static inline bool buffer_icap_done(void __iomem *base_address)
132{
133 return (buffer_icap_get_status(base_address) & 1) == XHI_FINISHED;
134}
135
136/**
137 * buffer_icap_set_size: Set the size register.
138 * @parameter base_address: is the base address of the device
139 * @parameter data: The size in bytes.
140 *
141 * The size register holds the number of 8 bit bytes to transfer between
142 * bram and the icap (or icap to bram).
143 **/
144static inline void buffer_icap_set_size(void __iomem *base_address,
145 u32 data)
146{
147 out_be32(base_address + XHI_SIZE_REG_OFFSET, data);
148}
149
150/**
151 * buffer_icap_mSetoffsetReg: Set the bram offset register.
152 * @parameter base_address: contains the base address of the device.
153 * @parameter data: is the value to be written to the data register.
154 *
155 * The bram offset register holds the starting bram address to transfer
156 * data from during configuration or write data to during readback.
157 **/
158static inline void buffer_icap_set_offset(void __iomem *base_address,
159 u32 data)
160{
161 out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data);
162}
163
164/**
165 * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register.
166 * @parameter base_address: contains the base address of the device.
167 * @parameter data: is the value to be written to the data register.
168 *
169 * The RNC register determines the direction of the data transfer. It
170 * controls whether a configuration or readback take place. Writing to
171 * this register initiates the transfer. A value of 1 initiates a
172 * readback while writing a value of 0 initiates a configuration.
173 **/
174static inline void buffer_icap_set_rnc(void __iomem *base_address,
175 u32 data)
176{
177 out_be32(base_address + XHI_RNC_REG_OFFSET, data);
178}
179
180/**
181 * buffer_icap_set_bram: Write data to the storage buffer bram.
182 * @parameter base_address: contains the base address of the component.
183 * @parameter offset: The word offset at which the data should be written.
184 * @parameter data: The value to be written to the bram offset.
185 *
186 * A bram is used as a configuration memory cache. One frame of data can
187 * be stored in this "storage buffer".
188 **/
189static inline void buffer_icap_set_bram(void __iomem *base_address,
190 u32 offset, u32 data)
191{
192 out_be32(base_address + (offset << 2), data);
193}
194
195/**
196 * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer.
197 * @parameter drvdata: a pointer to the drvdata.
198 * @parameter offset: The storage buffer start address.
199 * @parameter count: The number of words (32 bit) to read from the
200 * device (ICAP).
201 **/
202static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
203 u32 offset, u32 count)
204{
205
206 s32 retries = 0;
207 void __iomem *base_address = drvdata->base_address;
208
209 if (buffer_icap_busy(base_address))
210 return -EBUSY;
211
212 if ((offset + count) > XHI_MAX_BUFFER_INTS)
213 return -EINVAL;
214
215 /* setSize count*4 to get bytes. */
216 buffer_icap_set_size(base_address, (count << 2));
217 buffer_icap_set_offset(base_address, offset);
218 buffer_icap_set_rnc(base_address, XHI_READBACK);
219
220 while (buffer_icap_busy(base_address)) {
221 retries++;
222 if (retries > XHI_MAX_RETRIES)
223 return -EBUSY;
224 }
225 return 0;
226
227};
228
229/**
230 * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer.
231 * @parameter drvdata: a pointer to the drvdata.
232 * @parameter offset: The storage buffer start address.
233 * @parameter count: The number of words (32 bit) to read from the
234 * device (ICAP).
235 **/
236static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
237 u32 offset, u32 count)
238{
239
240 s32 retries = 0;
241 void __iomem *base_address = drvdata->base_address;
242
243 if (buffer_icap_busy(base_address))
244 return -EBUSY;
245
246 if ((offset + count) > XHI_MAX_BUFFER_INTS)
247 return -EINVAL;
248
249 /* setSize count*4 to get bytes. */
250 buffer_icap_set_size(base_address, count << 2);
251 buffer_icap_set_offset(base_address, offset);
252 buffer_icap_set_rnc(base_address, XHI_CONFIGURE);
253
254 while (buffer_icap_busy(base_address)) {
255 retries++;
256 if (retries > XHI_MAX_RETRIES)
257 return -EBUSY;
258 }
259 return 0;
260
261};
262
263/**
264 * buffer_icap_reset: Reset the logic of the icap device.
265 * @parameter drvdata: a pointer to the drvdata.
266 *
267 * Writing to the status register resets the ICAP logic in an internal
268 * version of the core. For the version of the core published in EDK,
269 * this is a noop.
270 **/
271void buffer_icap_reset(struct hwicap_drvdata *drvdata)
272{
273 out_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET, 0xFEFE);
274}
275
276/**
277 * buffer_icap_set_configuration: Load a partial bitstream from system memory.
278 * @parameter drvdata: a pointer to the drvdata.
279 * @parameter data: Kernel address of the partial bitstream.
280 * @parameter size: the size of the partial bitstream in 32 bit words.
281 **/
282int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
283 u32 size)
284{
285 int status;
286 s32 buffer_count = 0;
287 s32 num_writes = 0;
288 bool dirty = 0;
289 u32 i;
290 void __iomem *base_address = drvdata->base_address;
291
292 /* Loop through all the data */
293 for (i = 0, buffer_count = 0; i < size; i++) {
294
295 /* Copy data to bram */
296 buffer_icap_set_bram(base_address, buffer_count, data[i]);
297 dirty = 1;
298
299 if (buffer_count < XHI_MAX_BUFFER_INTS - 1) {
300 buffer_count++;
301 continue;
302 }
303
304 /* Write data to ICAP */
305 status = buffer_icap_device_write(
306 drvdata,
307 XHI_BUFFER_START,
308 XHI_MAX_BUFFER_INTS);
309 if (status != 0) {
310 /* abort. */
311 buffer_icap_reset(drvdata);
312 return status;
313 }
314
315 buffer_count = 0;
316 num_writes++;
317 dirty = 0;
318 }
319
320 /* Write unwritten data to ICAP */
321 if (dirty) {
322 /* Write data to ICAP */
323 status = buffer_icap_device_write(drvdata, XHI_BUFFER_START,
324 buffer_count);
325 if (status != 0) {
326 /* abort. */
327 buffer_icap_reset(drvdata);
328 }
329 return status;
330 }
331
332 return 0;
333};
334
335/**
336 * buffer_icap_get_configuration: Read configuration data from the device.
337 * @parameter drvdata: a pointer to the drvdata.
338 * @parameter data: Address of the data representing the partial bitstream
339 * @parameter size: the size of the partial bitstream in 32 bit words.
340 **/
341int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
342 u32 size)
343{
344 int status;
345 s32 buffer_count = 0;
346 s32 read_count = 0;
347 u32 i;
348 void __iomem *base_address = drvdata->base_address;
349
350 /* Loop through all the data */
351 for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i < size; i++) {
352 if (buffer_count == XHI_MAX_BUFFER_INTS) {
353 u32 words_remaining = size - i;
354 u32 words_to_read =
355 words_remaining <
356 XHI_MAX_BUFFER_INTS ? words_remaining :
357 XHI_MAX_BUFFER_INTS;
358
359 /* Read data from ICAP */
360 status = buffer_icap_device_read(
361 drvdata,
362 XHI_BUFFER_START,
363 words_to_read);
364 if (status != 0) {
365 /* abort. */
366 buffer_icap_reset(drvdata);
367 return status;
368 }
369
370 buffer_count = 0;
371 read_count++;
372 }
373
374 /* Copy data from bram */
375 data[i] = buffer_icap_get_bram(base_address, buffer_count);
376 buffer_count++;
377 }
378
379 return 0;
380};
diff --git a/drivers/char/xilinx_hwicap/buffer_icap.h b/drivers/char/xilinx_hwicap/buffer_icap.h
new file mode 100644
index 000000000000..03184959fa00
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/buffer_icap.h
@@ -0,0 +1,57 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2003-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#ifndef XILINX_BUFFER_ICAP_H_ /* prevent circular inclusions */
37#define XILINX_BUFFER_ICAP_H_ /* by using protection macros */
38
39#include <linux/types.h>
40#include <linux/cdev.h>
41#include <linux/version.h>
42#include <linux/platform_device.h>
43
44#include <asm/io.h>
45#include "xilinx_hwicap.h"
46
47void buffer_icap_reset(struct hwicap_drvdata *drvdata);
48
49/* Loads a partial bitstream from system memory. */
50int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
51 u32 Size);
52
53/* Loads a partial bitstream from system memory. */
54int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
55 u32 Size);
56
57#endif
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c
new file mode 100644
index 000000000000..0988314694a6
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/fifo_icap.c
@@ -0,0 +1,381 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2007-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#include "fifo_icap.h"
37
38/* Register offsets for the XHwIcap device. */
39#define XHI_GIER_OFFSET 0x1C /* Device Global Interrupt Enable Reg */
40#define XHI_IPISR_OFFSET 0x20 /* Interrupt Status Register */
41#define XHI_IPIER_OFFSET 0x28 /* Interrupt Enable Register */
42#define XHI_WF_OFFSET 0x100 /* Write FIFO */
43#define XHI_RF_OFFSET 0x104 /* Read FIFO */
44#define XHI_SZ_OFFSET 0x108 /* Size Register */
45#define XHI_CR_OFFSET 0x10C /* Control Register */
46#define XHI_SR_OFFSET 0x110 /* Status Register */
47#define XHI_WFV_OFFSET 0x114 /* Write FIFO Vacancy Register */
48#define XHI_RFO_OFFSET 0x118 /* Read FIFO Occupancy Register */
49
50/* Device Global Interrupt Enable Register (GIER) bit definitions */
51
52#define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */
53
54/**
55 * HwIcap Device Interrupt Status/Enable Registers
56 *
57 * Interrupt Status Register (IPISR) : This register holds the
58 * interrupt status flags for the device. These bits are toggle on
59 * write.
60 *
61 * Interrupt Enable Register (IPIER) : This register is used to enable
62 * interrupt sources for the device.
63 * Writing a '1' to a bit enables the corresponding interrupt.
64 * Writing a '0' to a bit disables the corresponding interrupt.
65 *
66 * IPISR/IPIER registers have the same bit definitions and are only defined
67 * once.
68 */
69#define XHI_IPIXR_RFULL_MASK 0x00000008 /* Read FIFO Full */
70#define XHI_IPIXR_WEMPTY_MASK 0x00000004 /* Write FIFO Empty */
71#define XHI_IPIXR_RDP_MASK 0x00000002 /* Read FIFO half full */
72#define XHI_IPIXR_WRP_MASK 0x00000001 /* Write FIFO half full */
73#define XHI_IPIXR_ALL_MASK 0x0000000F /* Mask of all interrupts */
74
75/* Control Register (CR) */
76#define XHI_CR_SW_RESET_MASK 0x00000008 /* SW Reset Mask */
77#define XHI_CR_FIFO_CLR_MASK 0x00000004 /* FIFO Clear Mask */
78#define XHI_CR_READ_MASK 0x00000002 /* Read from ICAP to FIFO */
79#define XHI_CR_WRITE_MASK 0x00000001 /* Write from FIFO to ICAP */
80
81/* Status Register (SR) */
82#define XHI_SR_CFGERR_N_MASK 0x00000100 /* Config Error Mask */
83#define XHI_SR_DALIGN_MASK 0x00000080 /* Data Alignment Mask */
84#define XHI_SR_RIP_MASK 0x00000040 /* Read back Mask */
85#define XHI_SR_IN_ABORT_N_MASK 0x00000020 /* Select Map Abort Mask */
86#define XHI_SR_DONE_MASK 0x00000001 /* Done bit Mask */
87
88
89#define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */
90#define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */
91/* The maximum amount we can request from fifo_icap_get_configuration
92 at once, in bytes. */
93#define XHI_MAX_READ_TRANSACTION_WORDS 0xFFF
94
95
96/**
97 * fifo_icap_fifo_write: Write data to the write FIFO.
98 * @parameter drvdata: a pointer to the drvdata.
99 * @parameter data: the 32-bit value to be written to the FIFO.
100 *
101 * This function will silently fail if the fifo is full.
102 **/
103static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
104 u32 data)
105{
106 dev_dbg(drvdata->dev, "fifo_write: %x\n", data);
107 out_be32(drvdata->base_address + XHI_WF_OFFSET, data);
108}
109
110/**
111 * fifo_icap_fifo_read: Read data from the Read FIFO.
112 * @parameter drvdata: a pointer to the drvdata.
113 *
114 * This function will silently fail if the fifo is empty.
115 **/
116static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
117{
118 u32 data = in_be32(drvdata->base_address + XHI_RF_OFFSET);
119 dev_dbg(drvdata->dev, "fifo_read: %x\n", data);
120 return data;
121}
122
123/**
124 * fifo_icap_set_read_size: Set the the size register.
125 * @parameter drvdata: a pointer to the drvdata.
126 * @parameter data: the size of the following read transaction, in words.
127 **/
128static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
129 u32 data)
130{
131 out_be32(drvdata->base_address + XHI_SZ_OFFSET, data);
132}
133
134/**
135 * fifo_icap_start_config: Initiate a configuration (write) to the device.
136 * @parameter drvdata: a pointer to the drvdata.
137 **/
138static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
139{
140 out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_WRITE_MASK);
141 dev_dbg(drvdata->dev, "configuration started\n");
142}
143
144/**
145 * fifo_icap_start_readback: Initiate a readback from the device.
146 * @parameter drvdata: a pointer to the drvdata.
147 **/
148static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
149{
150 out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_READ_MASK);
151 dev_dbg(drvdata->dev, "readback started\n");
152}
153
154/**
155 * fifo_icap_busy: Return true if the ICAP is still processing a transaction.
156 * @parameter drvdata: a pointer to the drvdata.
157 **/
158static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
159{
160 u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET);
161 dev_dbg(drvdata->dev, "Getting status = %x\n", status);
162 return (status & XHI_SR_DONE_MASK) ? 0 : 1;
163}
164
165/**
166 * fifo_icap_write_fifo_vacancy: Query the write fifo available space.
167 * @parameter drvdata: a pointer to the drvdata.
168 *
169 * Return the number of words that can be safely pushed into the write fifo.
170 **/
171static inline u32 fifo_icap_write_fifo_vacancy(
172 struct hwicap_drvdata *drvdata)
173{
174 return in_be32(drvdata->base_address + XHI_WFV_OFFSET);
175}
176
177/**
178 * fifo_icap_read_fifo_occupancy: Query the read fifo available data.
179 * @parameter drvdata: a pointer to the drvdata.
180 *
181 * Return the number of words that can be safely read from the read fifo.
182 **/
183static inline u32 fifo_icap_read_fifo_occupancy(
184 struct hwicap_drvdata *drvdata)
185{
186 return in_be32(drvdata->base_address + XHI_RFO_OFFSET);
187}
188
189/**
190 * fifo_icap_set_configuration: Send configuration data to the ICAP.
191 * @parameter drvdata: a pointer to the drvdata.
192 * @parameter frame_buffer: a pointer to the data to be written to the
193 * ICAP device.
194 * @parameter num_words: the number of words (32 bit) to write to the ICAP
195 * device.
196
197 * This function writes the given user data to the Write FIFO in
198 * polled mode and starts the transfer of the data to
199 * the ICAP device.
200 **/
201int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
202 u32 *frame_buffer, u32 num_words)
203{
204
205 u32 write_fifo_vacancy = 0;
206 u32 retries = 0;
207 u32 remaining_words;
208
209 dev_dbg(drvdata->dev, "fifo_set_configuration\n");
210
211 /*
212 * Check if the ICAP device is Busy with the last Read/Write
213 */
214 if (fifo_icap_busy(drvdata))
215 return -EBUSY;
216
217 /*
218 * Set up the buffer pointer and the words to be transferred.
219 */
220 remaining_words = num_words;
221
222 while (remaining_words > 0) {
223 /*
224 * Wait until we have some data in the fifo.
225 */
226 while (write_fifo_vacancy == 0) {
227 write_fifo_vacancy =
228 fifo_icap_write_fifo_vacancy(drvdata);
229 retries++;
230 if (retries > XHI_MAX_RETRIES)
231 return -EIO;
232 }
233
234 /*
235 * Write data into the Write FIFO.
236 */
237 while ((write_fifo_vacancy != 0) &&
238 (remaining_words > 0)) {
239 fifo_icap_fifo_write(drvdata, *frame_buffer);
240
241 remaining_words--;
242 write_fifo_vacancy--;
243 frame_buffer++;
244 }
245 /* Start pushing whatever is in the FIFO into the ICAP. */
246 fifo_icap_start_config(drvdata);
247 }
248
249 /* Wait until the write has finished. */
250 while (fifo_icap_busy(drvdata)) {
251 retries++;
252 if (retries > XHI_MAX_RETRIES)
253 break;
254 }
255
256 dev_dbg(drvdata->dev, "done fifo_set_configuration\n");
257
258 /*
259 * If the requested number of words have not been read from
260 * the device then indicate failure.
261 */
262 if (remaining_words != 0)
263 return -EIO;
264
265 return 0;
266}
267
268/**
269 * fifo_icap_get_configuration: Read configuration data from the device.
270 * @parameter drvdata: a pointer to the drvdata.
271 * @parameter data: Address of the data representing the partial bitstream
272 * @parameter size: the size of the partial bitstream in 32 bit words.
273 *
274 * This function reads the specified number of words from the ICAP device in
275 * the polled mode.
276 */
277int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
278 u32 *frame_buffer, u32 num_words)
279{
280
281 u32 read_fifo_occupancy = 0;
282 u32 retries = 0;
283 u32 *data = frame_buffer;
284 u32 remaining_words;
285 u32 words_to_read;
286
287 dev_dbg(drvdata->dev, "fifo_get_configuration\n");
288
289 /*
290 * Check if the ICAP device is Busy with the last Write/Read
291 */
292 if (fifo_icap_busy(drvdata))
293 return -EBUSY;
294
295 remaining_words = num_words;
296
297 while (remaining_words > 0) {
298 words_to_read = remaining_words;
299 /* The hardware has a limit on the number of words
300 that can be read at one time. */
301 if (words_to_read > XHI_MAX_READ_TRANSACTION_WORDS)
302 words_to_read = XHI_MAX_READ_TRANSACTION_WORDS;
303
304 remaining_words -= words_to_read;
305
306 fifo_icap_set_read_size(drvdata, words_to_read);
307 fifo_icap_start_readback(drvdata);
308
309 while (words_to_read > 0) {
310 /* Wait until we have some data in the fifo. */
311 while (read_fifo_occupancy == 0) {
312 read_fifo_occupancy =
313 fifo_icap_read_fifo_occupancy(drvdata);
314 retries++;
315 if (retries > XHI_MAX_RETRIES)
316 return -EIO;
317 }
318
319 if (read_fifo_occupancy > words_to_read)
320 read_fifo_occupancy = words_to_read;
321
322 words_to_read -= read_fifo_occupancy;
323
324 /* Read the data from the Read FIFO. */
325 while (read_fifo_occupancy != 0) {
326 *data++ = fifo_icap_fifo_read(drvdata);
327 read_fifo_occupancy--;
328 }
329 }
330 }
331
332 dev_dbg(drvdata->dev, "done fifo_get_configuration\n");
333
334 return 0;
335}
336
337/**
338 * buffer_icap_reset: Reset the logic of the icap device.
339 * @parameter drvdata: a pointer to the drvdata.
340 *
341 * This function forces the software reset of the complete HWICAP device.
342 * All the registers will return to the default value and the FIFO is also
343 * flushed as a part of this software reset.
344 */
345void fifo_icap_reset(struct hwicap_drvdata *drvdata)
346{
347 u32 reg_data;
348 /*
349 * Reset the device by setting/clearing the RESET bit in the
350 * Control Register.
351 */
352 reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET);
353
354 out_be32(drvdata->base_address + XHI_CR_OFFSET,
355 reg_data | XHI_CR_SW_RESET_MASK);
356
357 out_be32(drvdata->base_address + XHI_CR_OFFSET,
358 reg_data & (~XHI_CR_SW_RESET_MASK));
359
360}
361
362/**
363 * fifo_icap_flush_fifo: This function flushes the FIFOs in the device.
364 * @parameter drvdata: a pointer to the drvdata.
365 */
366void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
367{
368 u32 reg_data;
369 /*
370 * Flush the FIFO by setting/clearing the FIFO Clear bit in the
371 * Control Register.
372 */
373 reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET);
374
375 out_be32(drvdata->base_address + XHI_CR_OFFSET,
376 reg_data | XHI_CR_FIFO_CLR_MASK);
377
378 out_be32(drvdata->base_address + XHI_CR_OFFSET,
379 reg_data & (~XHI_CR_FIFO_CLR_MASK));
380}
381
diff --git a/drivers/char/xilinx_hwicap/fifo_icap.h b/drivers/char/xilinx_hwicap/fifo_icap.h
new file mode 100644
index 000000000000..4d3068dd0405
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/fifo_icap.h
@@ -0,0 +1,62 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2007-2008 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#ifndef XILINX_FIFO_ICAP_H_ /* prevent circular inclusions */
37#define XILINX_FIFO_ICAP_H_ /* by using protection macros */
38
39#include <linux/types.h>
40#include <linux/cdev.h>
41#include <linux/version.h>
42#include <linux/platform_device.h>
43
44#include <asm/io.h>
45#include "xilinx_hwicap.h"
46
47/* Reads integers from the device into the storage buffer. */
48int fifo_icap_get_configuration(
49 struct hwicap_drvdata *drvdata,
50 u32 *FrameBuffer,
51 u32 NumWords);
52
53/* Writes integers to the device from the storage buffer. */
54int fifo_icap_set_configuration(
55 struct hwicap_drvdata *drvdata,
56 u32 *FrameBuffer,
57 u32 NumWords);
58
59void fifo_icap_reset(struct hwicap_drvdata *drvdata);
60void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata);
61
62#endif
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
new file mode 100644
index 000000000000..24f6aef0fd3c
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -0,0 +1,904 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2002 Xilinx Inc., Systems Engineering Group
28 * (c) Copyright 2004 Xilinx Inc., Systems Engineering Group
29 * (c) Copyright 2007-2008 Xilinx Inc.
30 * All rights reserved.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 *
36 *****************************************************************************/
37
38/*
39 * This is the code behind /dev/xilinx_icap -- it allows a user-space
40 * application to use the Xilinx ICAP subsystem.
41 *
42 * The following operations are possible:
43 *
44 * open open the port and initialize for access.
45 * release release port
46 * write Write a bitstream to the configuration processor.
47 * read Read a data stream from the configuration processor.
48 *
49 * After being opened, the port is initialized and accessed to avoid a
50 * corrupted first read which may occur with some hardware. The port
51 * is left in a desynched state, requiring that a synch sequence be
52 * transmitted before any valid configuration data. A user will have
53 * exclusive access to the device while it remains open, and the state
54 * of the ICAP cannot be guaranteed after the device is closed. Note
55 * that a complete reset of the core and the state of the ICAP cannot
56 * be performed on many versions of the cores, hence users of this
57 * device should avoid making inconsistent accesses to the device. In
58 * particular, accessing the read interface, without first generating
59 * a write containing a readback packet can leave the ICAP in an
60 * inaccessible state.
61 *
62 * Note that in order to use the read interface, it is first necessary
63 * to write a request packet to the write interface. i.e., it is not
64 * possible to simply readback the bitstream (or any configuration
65 * bits) from a device without specifically requesting them first.
66 * The code to craft such packets is intended to be part of the
67 * user-space application code that uses this device. The simplest
68 * way to use this interface is simply:
69 *
70 * cp foo.bit /dev/xilinx_icap
71 *
72 * Note that unless foo.bit is an appropriately constructed partial
73 * bitstream, this has a high likelyhood of overwriting the design
74 * currently programmed in the FPGA.
75 */
76
77#include <linux/version.h>
78#include <linux/module.h>
79#include <linux/kernel.h>
80#include <linux/types.h>
81#include <linux/ioport.h>
82#include <linux/interrupt.h>
83#include <linux/fcntl.h>
84#include <linux/init.h>
85#include <linux/poll.h>
86#include <linux/proc_fs.h>
87#include <asm/semaphore.h>
88#include <linux/sysctl.h>
89#include <linux/version.h>
90#include <linux/fs.h>
91#include <linux/cdev.h>
92#include <linux/platform_device.h>
93
94#include <asm/io.h>
95#include <asm/uaccess.h>
96#include <asm/system.h>
97
98#ifdef CONFIG_OF
99/* For open firmware. */
100#include <linux/of_device.h>
101#include <linux/of_platform.h>
102#endif
103
104#include "xilinx_hwicap.h"
105#include "buffer_icap.h"
106#include "fifo_icap.h"
107
108#define DRIVER_NAME "xilinx_icap"
109
110#define HWICAP_REGS (0x10000)
111
112/* dynamically allocate device number */
113static int xhwicap_major;
114static int xhwicap_minor;
115#define HWICAP_DEVICES 1
116
117module_param(xhwicap_major, int, S_IRUGO);
118module_param(xhwicap_minor, int, S_IRUGO);
119
120/* An array, which is set to true when the device is registered. */
121static bool probed_devices[HWICAP_DEVICES];
122
123static struct class *icap_class;
124
125#define UNIMPLEMENTED 0xFFFF
126
127static const struct config_registers v2_config_registers = {
128 .CRC = 0,
129 .FAR = 1,
130 .FDRI = 2,
131 .FDRO = 3,
132 .CMD = 4,
133 .CTL = 5,
134 .MASK = 6,
135 .STAT = 7,
136 .LOUT = 8,
137 .COR = 9,
138 .MFWR = 10,
139 .FLR = 11,
140 .KEY = 12,
141 .CBC = 13,
142 .IDCODE = 14,
143 .AXSS = UNIMPLEMENTED,
144 .C0R_1 = UNIMPLEMENTED,
145 .CSOB = UNIMPLEMENTED,
146 .WBSTAR = UNIMPLEMENTED,
147 .TIMER = UNIMPLEMENTED,
148 .BOOTSTS = UNIMPLEMENTED,
149 .CTL_1 = UNIMPLEMENTED,
150};
151
152static const struct config_registers v4_config_registers = {
153 .CRC = 0,
154 .FAR = 1,
155 .FDRI = 2,
156 .FDRO = 3,
157 .CMD = 4,
158 .CTL = 5,
159 .MASK = 6,
160 .STAT = 7,
161 .LOUT = 8,
162 .COR = 9,
163 .MFWR = 10,
164 .FLR = UNIMPLEMENTED,
165 .KEY = UNIMPLEMENTED,
166 .CBC = 11,
167 .IDCODE = 12,
168 .AXSS = 13,
169 .C0R_1 = UNIMPLEMENTED,
170 .CSOB = UNIMPLEMENTED,
171 .WBSTAR = UNIMPLEMENTED,
172 .TIMER = UNIMPLEMENTED,
173 .BOOTSTS = UNIMPLEMENTED,
174 .CTL_1 = UNIMPLEMENTED,
175};
176static const struct config_registers v5_config_registers = {
177 .CRC = 0,
178 .FAR = 1,
179 .FDRI = 2,
180 .FDRO = 3,
181 .CMD = 4,
182 .CTL = 5,
183 .MASK = 6,
184 .STAT = 7,
185 .LOUT = 8,
186 .COR = 9,
187 .MFWR = 10,
188 .FLR = UNIMPLEMENTED,
189 .KEY = UNIMPLEMENTED,
190 .CBC = 11,
191 .IDCODE = 12,
192 .AXSS = 13,
193 .C0R_1 = 14,
194 .CSOB = 15,
195 .WBSTAR = 16,
196 .TIMER = 17,
197 .BOOTSTS = 18,
198 .CTL_1 = 19,
199};
200
201/**
202 * hwicap_command_desync: Send a DESYNC command to the ICAP port.
203 * @parameter drvdata: a pointer to the drvdata.
204 *
205 * This command desynchronizes the ICAP After this command, a
206 * bitstream containing a NULL packet, followed by a SYNCH packet is
207 * required before the ICAP will recognize commands.
208 */
209int hwicap_command_desync(struct hwicap_drvdata *drvdata)
210{
211 u32 buffer[4];
212 u32 index = 0;
213
214 /*
215 * Create the data to be written to the ICAP.
216 */
217 buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
218 buffer[index++] = XHI_CMD_DESYNCH;
219 buffer[index++] = XHI_NOOP_PACKET;
220 buffer[index++] = XHI_NOOP_PACKET;
221
222 /*
223 * Write the data to the FIFO and intiate the transfer of data present
224 * in the FIFO to the ICAP device.
225 */
226 return drvdata->config->set_configuration(drvdata,
227 &buffer[0], index);
228}
229
230/**
231 * hwicap_command_capture: Send a CAPTURE command to the ICAP port.
232 * @parameter drvdata: a pointer to the drvdata.
233 *
234 * This command captures all of the flip flop states so they will be
235 * available during readback. One can use this command instead of
236 * enabling the CAPTURE block in the design.
237 */
238int hwicap_command_capture(struct hwicap_drvdata *drvdata)
239{
240 u32 buffer[7];
241 u32 index = 0;
242
243 /*
244 * Create the data to be written to the ICAP.
245 */
246 buffer[index++] = XHI_DUMMY_PACKET;
247 buffer[index++] = XHI_SYNC_PACKET;
248 buffer[index++] = XHI_NOOP_PACKET;
249 buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
250 buffer[index++] = XHI_CMD_GCAPTURE;
251 buffer[index++] = XHI_DUMMY_PACKET;
252 buffer[index++] = XHI_DUMMY_PACKET;
253
254 /*
255 * Write the data to the FIFO and intiate the transfer of data
256 * present in the FIFO to the ICAP device.
257 */
258 return drvdata->config->set_configuration(drvdata,
259 &buffer[0], index);
260
261}
262
263/**
264 * hwicap_get_configuration_register: Query a configuration register.
265 * @parameter drvdata: a pointer to the drvdata.
266 * @parameter reg: a constant which represents the configuration
267 * register value to be returned.
268 * Examples: XHI_IDCODE, XHI_FLR.
269 * @parameter RegData: returns the value of the register.
270 *
271 * Sends a query packet to the ICAP and then receives the response.
272 * The icap is left in Synched state.
273 */
274int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
275 u32 reg, u32 *RegData)
276{
277 int status;
278 u32 buffer[6];
279 u32 index = 0;
280
281 /*
282 * Create the data to be written to the ICAP.
283 */
284 buffer[index++] = XHI_DUMMY_PACKET;
285 buffer[index++] = XHI_SYNC_PACKET;
286 buffer[index++] = XHI_NOOP_PACKET;
287 buffer[index++] = hwicap_type_1_read(reg) | 1;
288 buffer[index++] = XHI_NOOP_PACKET;
289 buffer[index++] = XHI_NOOP_PACKET;
290
291 /*
292 * Write the data to the FIFO and intiate the transfer of data present
293 * in the FIFO to the ICAP device.
294 */
295 status = drvdata->config->set_configuration(drvdata,
296 &buffer[0], index);
297 if (status)
298 return status;
299
300 /*
301 * Read the configuration register
302 */
303 status = drvdata->config->get_configuration(drvdata, RegData, 1);
304 if (status)
305 return status;
306
307 return 0;
308}
309
310int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
311{
312 int status;
313 u32 idcode;
314
315 dev_dbg(drvdata->dev, "initializing\n");
316
317 /* Abort any current transaction, to make sure we have the
318 * ICAP in a good state. */
319 dev_dbg(drvdata->dev, "Reset...\n");
320 drvdata->config->reset(drvdata);
321
322 dev_dbg(drvdata->dev, "Desync...\n");
323 status = hwicap_command_desync(drvdata);
324 if (status)
325 return status;
326
327 /* Attempt to read the IDCODE from ICAP. This
328 * may not be returned correctly, due to the design of the
329 * hardware.
330 */
331 dev_dbg(drvdata->dev, "Reading IDCODE...\n");
332 status = hwicap_get_configuration_register(
333 drvdata, drvdata->config_regs->IDCODE, &idcode);
334 dev_dbg(drvdata->dev, "IDCODE = %x\n", idcode);
335 if (status)
336 return status;
337
338 dev_dbg(drvdata->dev, "Desync...\n");
339 status = hwicap_command_desync(drvdata);
340 if (status)
341 return status;
342
343 return 0;
344}
345
346static ssize_t
347hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
348{
349 struct hwicap_drvdata *drvdata = file->private_data;
350 ssize_t bytes_to_read = 0;
351 u32 *kbuf;
352 u32 words;
353 u32 bytes_remaining;
354 int status;
355
356 if (down_interruptible(&drvdata->sem))
357 return -ERESTARTSYS;
358
359 if (drvdata->read_buffer_in_use) {
360 /* If there are leftover bytes in the buffer, just */
361 /* return them and don't try to read more from the */
362 /* ICAP device. */
363 bytes_to_read =
364 (count < drvdata->read_buffer_in_use) ? count :
365 drvdata->read_buffer_in_use;
366
367 /* Return the data currently in the read buffer. */
368 if (copy_to_user(buf, drvdata->read_buffer, bytes_to_read)) {
369 status = -EFAULT;
370 goto error;
371 }
372 drvdata->read_buffer_in_use -= bytes_to_read;
373 memcpy(drvdata->read_buffer + bytes_to_read,
374 drvdata->read_buffer, 4 - bytes_to_read);
375 } else {
376 /* Get new data from the ICAP, and return was was requested. */
377 kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
378 if (!kbuf) {
379 status = -ENOMEM;
380 goto error;
381 }
382
383 /* The ICAP device is only able to read complete */
384 /* words. If a number of bytes that do not correspond */
385 /* to complete words is requested, then we read enough */
386 /* words to get the required number of bytes, and then */
387 /* save the remaining bytes for the next read. */
388
389 /* Determine the number of words to read, rounding up */
390 /* if necessary. */
391 words = ((count + 3) >> 2);
392 bytes_to_read = words << 2;
393
394 if (bytes_to_read > PAGE_SIZE)
395 bytes_to_read = PAGE_SIZE;
396
397 /* Ensure we only read a complete number of words. */
398 bytes_remaining = bytes_to_read & 3;
399 bytes_to_read &= ~3;
400 words = bytes_to_read >> 2;
401
402 status = drvdata->config->get_configuration(drvdata,
403 kbuf, words);
404
405 /* If we didn't read correctly, then bail out. */
406 if (status) {
407 free_page((unsigned long)kbuf);
408 goto error;
409 }
410
411 /* If we fail to return the data to the user, then bail out. */
412 if (copy_to_user(buf, kbuf, bytes_to_read)) {
413 free_page((unsigned long)kbuf);
414 status = -EFAULT;
415 goto error;
416 }
417 memcpy(kbuf, drvdata->read_buffer, bytes_remaining);
418 drvdata->read_buffer_in_use = bytes_remaining;
419 free_page((unsigned long)kbuf);
420 }
421 status = bytes_to_read;
422 error:
423 up(&drvdata->sem);
424 return status;
425}
426
427static ssize_t
428hwicap_write(struct file *file, const char *buf,
429 size_t count, loff_t *ppos)
430{
431 struct hwicap_drvdata *drvdata = file->private_data;
432 ssize_t written = 0;
433 ssize_t left = count;
434 u32 *kbuf;
435 ssize_t len;
436 ssize_t status;
437
438 if (down_interruptible(&drvdata->sem))
439 return -ERESTARTSYS;
440
441 left += drvdata->write_buffer_in_use;
442
443 /* Only write multiples of 4 bytes. */
444 if (left < 4) {
445 status = 0;
446 goto error;
447 }
448
449 kbuf = (u32 *) __get_free_page(GFP_KERNEL);
450 if (!kbuf) {
451 status = -ENOMEM;
452 goto error;
453 }
454
455 while (left > 3) {
456 /* only write multiples of 4 bytes, so there might */
457 /* be as many as 3 bytes left (at the end). */
458 len = left;
459
460 if (len > PAGE_SIZE)
461 len = PAGE_SIZE;
462 len &= ~3;
463
464 if (drvdata->write_buffer_in_use) {
465 memcpy(kbuf, drvdata->write_buffer,
466 drvdata->write_buffer_in_use);
467 if (copy_from_user(
468 (((char *)kbuf) + (drvdata->write_buffer_in_use)),
469 buf + written,
470 len - (drvdata->write_buffer_in_use))) {
471 free_page((unsigned long)kbuf);
472 status = -EFAULT;
473 goto error;
474 }
475 } else {
476 if (copy_from_user(kbuf, buf + written, len)) {
477 free_page((unsigned long)kbuf);
478 status = -EFAULT;
479 goto error;
480 }
481 }
482
483 status = drvdata->config->set_configuration(drvdata,
484 kbuf, len >> 2);
485
486 if (status) {
487 free_page((unsigned long)kbuf);
488 status = -EFAULT;
489 goto error;
490 }
491 if (drvdata->write_buffer_in_use) {
492 len -= drvdata->write_buffer_in_use;
493 left -= drvdata->write_buffer_in_use;
494 drvdata->write_buffer_in_use = 0;
495 }
496 written += len;
497 left -= len;
498 }
499 if ((left > 0) && (left < 4)) {
500 if (!copy_from_user(drvdata->write_buffer,
501 buf + written, left)) {
502 drvdata->write_buffer_in_use = left;
503 written += left;
504 left = 0;
505 }
506 }
507
508 free_page((unsigned long)kbuf);
509 status = written;
510 error:
511 up(&drvdata->sem);
512 return status;
513}
514
515static int hwicap_open(struct inode *inode, struct file *file)
516{
517 struct hwicap_drvdata *drvdata;
518 int status;
519
520 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
521
522 if (down_interruptible(&drvdata->sem))
523 return -ERESTARTSYS;
524
525 if (drvdata->is_open) {
526 status = -EBUSY;
527 goto error;
528 }
529
530 status = hwicap_initialize_hwicap(drvdata);
531 if (status) {
532 dev_err(drvdata->dev, "Failed to open file");
533 goto error;
534 }
535
536 file->private_data = drvdata;
537 drvdata->write_buffer_in_use = 0;
538 drvdata->read_buffer_in_use = 0;
539 drvdata->is_open = 1;
540
541 error:
542 up(&drvdata->sem);
543 return status;
544}
545
546static int hwicap_release(struct inode *inode, struct file *file)
547{
548 struct hwicap_drvdata *drvdata = file->private_data;
549 int i;
550 int status = 0;
551
552 if (down_interruptible(&drvdata->sem))
553 return -ERESTARTSYS;
554
555 if (drvdata->write_buffer_in_use) {
556 /* Flush write buffer. */
557 for (i = drvdata->write_buffer_in_use; i < 4; i++)
558 drvdata->write_buffer[i] = 0;
559
560 status = drvdata->config->set_configuration(drvdata,
561 (u32 *) drvdata->write_buffer, 1);
562 if (status)
563 goto error;
564 }
565
566 status = hwicap_command_desync(drvdata);
567 if (status)
568 goto error;
569
570 error:
571 drvdata->is_open = 0;
572 up(&drvdata->sem);
573 return status;
574}
575
576static struct file_operations hwicap_fops = {
577 .owner = THIS_MODULE,
578 .write = hwicap_write,
579 .read = hwicap_read,
580 .open = hwicap_open,
581 .release = hwicap_release,
582};
583
584static int __devinit hwicap_setup(struct device *dev, int id,
585 const struct resource *regs_res,
586 const struct hwicap_driver_config *config,
587 const struct config_registers *config_regs)
588{
589 dev_t devt;
590 struct hwicap_drvdata *drvdata = NULL;
591 int retval = 0;
592
593 dev_info(dev, "Xilinx icap port driver\n");
594
595 if (id < 0) {
596 for (id = 0; id < HWICAP_DEVICES; id++)
597 if (!probed_devices[id])
598 break;
599 }
600 if (id < 0 || id >= HWICAP_DEVICES) {
601 dev_err(dev, "%s%i too large\n", DRIVER_NAME, id);
602 return -EINVAL;
603 }
604 if (probed_devices[id]) {
605 dev_err(dev, "cannot assign to %s%i; it is already in use\n",
606 DRIVER_NAME, id);
607 return -EBUSY;
608 }
609
610 probed_devices[id] = 1;
611
612 devt = MKDEV(xhwicap_major, xhwicap_minor + id);
613
614 drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
615 if (!drvdata) {
616 dev_err(dev, "Couldn't allocate device private record\n");
617 return -ENOMEM;
618 }
619 memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));
620 dev_set_drvdata(dev, (void *)drvdata);
621
622 if (!regs_res) {
623 dev_err(dev, "Couldn't get registers resource\n");
624 retval = -EFAULT;
625 goto failed1;
626 }
627
628 drvdata->mem_start = regs_res->start;
629 drvdata->mem_end = regs_res->end;
630 drvdata->mem_size = regs_res->end - regs_res->start + 1;
631
632 if (!request_mem_region(drvdata->mem_start,
633 drvdata->mem_size, DRIVER_NAME)) {
634 dev_err(dev, "Couldn't lock memory region at %p\n",
635 (void *)regs_res->start);
636 retval = -EBUSY;
637 goto failed1;
638 }
639
640 drvdata->devt = devt;
641 drvdata->dev = dev;
642 drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size);
643 if (!drvdata->base_address) {
644 dev_err(dev, "ioremap() failed\n");
645 goto failed2;
646 }
647
648 drvdata->config = config;
649 drvdata->config_regs = config_regs;
650
651 init_MUTEX(&drvdata->sem);
652 drvdata->is_open = 0;
653
654 dev_info(dev, "ioremap %lx to %p with size %x\n",
655 (unsigned long int)drvdata->mem_start,
656 drvdata->base_address, drvdata->mem_size);
657
658 cdev_init(&drvdata->cdev, &hwicap_fops);
659 drvdata->cdev.owner = THIS_MODULE;
660 retval = cdev_add(&drvdata->cdev, devt, 1);
661 if (retval) {
662 dev_err(dev, "cdev_add() failed\n");
663 goto failed3;
664 }
665 /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
666 class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME);
667 return 0; /* success */
668
669 failed3:
670 iounmap(drvdata->base_address);
671
672 failed2:
673 release_mem_region(regs_res->start, drvdata->mem_size);
674
675 failed1:
676 kfree(drvdata);
677
678 return retval;
679}
680
681static struct hwicap_driver_config buffer_icap_config = {
682 .get_configuration = buffer_icap_get_configuration,
683 .set_configuration = buffer_icap_set_configuration,
684 .reset = buffer_icap_reset,
685};
686
687static struct hwicap_driver_config fifo_icap_config = {
688 .get_configuration = fifo_icap_get_configuration,
689 .set_configuration = fifo_icap_set_configuration,
690 .reset = fifo_icap_reset,
691};
692
693static int __devexit hwicap_remove(struct device *dev)
694{
695 struct hwicap_drvdata *drvdata;
696
697 drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev);
698
699 if (!drvdata)
700 return 0;
701
702 class_device_destroy(icap_class, drvdata->devt);
703 cdev_del(&drvdata->cdev);
704 iounmap(drvdata->base_address);
705 release_mem_region(drvdata->mem_start, drvdata->mem_size);
706 kfree(drvdata);
707 dev_set_drvdata(dev, NULL);
708 probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
709
710 return 0; /* success */
711}
712
713static int __devinit hwicap_drv_probe(struct platform_device *pdev)
714{
715 struct resource *res;
716 const struct config_registers *regs;
717 const char *family;
718
719 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
720 if (!res)
721 return -ENODEV;
722
723 /* It's most likely that we're using V4, if the family is not
724 specified */
725 regs = &v4_config_registers;
726 family = pdev->dev.platform_data;
727
728 if (family) {
729 if (!strcmp(family, "virtex2p")) {
730 regs = &v2_config_registers;
731 } else if (!strcmp(family, "virtex4")) {
732 regs = &v4_config_registers;
733 } else if (!strcmp(family, "virtex5")) {
734 regs = &v5_config_registers;
735 }
736 }
737
738 return hwicap_setup(&pdev->dev, pdev->id, res,
739 &buffer_icap_config, regs);
740}
741
742static int __devexit hwicap_drv_remove(struct platform_device *pdev)
743{
744 return hwicap_remove(&pdev->dev);
745}
746
747static struct platform_driver hwicap_platform_driver = {
748 .probe = hwicap_drv_probe,
749 .remove = hwicap_drv_remove,
750 .driver = {
751 .owner = THIS_MODULE,
752 .name = DRIVER_NAME,
753 },
754};
755
756/* ---------------------------------------------------------------------
757 * OF bus binding
758 */
759
760#if defined(CONFIG_OF)
761static int __devinit
762hwicap_of_probe(struct of_device *op, const struct of_device_id *match)
763{
764 struct resource res;
765 const unsigned int *id;
766 const char *family;
767 int rc;
768 const struct hwicap_driver_config *config = match->data;
769 const struct config_registers *regs;
770
771 dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match);
772
773 rc = of_address_to_resource(op->node, 0, &res);
774 if (rc) {
775 dev_err(&op->dev, "invalid address\n");
776 return rc;
777 }
778
779 id = of_get_property(op->node, "port-number", NULL);
780
781 /* It's most likely that we're using V4, if the family is not
782 specified */
783 regs = &v4_config_registers;
784 family = of_get_property(op->node, "xlnx,family", NULL);
785
786 if (family) {
787 if (!strcmp(family, "virtex2p")) {
788 regs = &v2_config_registers;
789 } else if (!strcmp(family, "virtex4")) {
790 regs = &v4_config_registers;
791 } else if (!strcmp(family, "virtex5")) {
792 regs = &v5_config_registers;
793 }
794 }
795 return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
796 regs);
797}
798
799static int __devexit hwicap_of_remove(struct of_device *op)
800{
801 return hwicap_remove(&op->dev);
802}
803
804/* Match table for of_platform binding */
805static const struct of_device_id __devinit hwicap_of_match[] = {
806 { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config},
807 { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config},
808 {},
809};
810MODULE_DEVICE_TABLE(of, hwicap_of_match);
811
812static struct of_platform_driver hwicap_of_driver = {
813 .owner = THIS_MODULE,
814 .name = DRIVER_NAME,
815 .match_table = hwicap_of_match,
816 .probe = hwicap_of_probe,
817 .remove = __devexit_p(hwicap_of_remove),
818 .driver = {
819 .name = DRIVER_NAME,
820 },
821};
822
823/* Registration helpers to keep the number of #ifdefs to a minimum */
824static inline int __devinit hwicap_of_register(void)
825{
826 pr_debug("hwicap: calling of_register_platform_driver()\n");
827 return of_register_platform_driver(&hwicap_of_driver);
828}
829
830static inline void __devexit hwicap_of_unregister(void)
831{
832 of_unregister_platform_driver(&hwicap_of_driver);
833}
834#else /* CONFIG_OF */
835/* CONFIG_OF not enabled; do nothing helpers */
836static inline int __devinit hwicap_of_register(void) { return 0; }
837static inline void __devexit hwicap_of_unregister(void) { }
838#endif /* CONFIG_OF */
839
840static int __devinit hwicap_module_init(void)
841{
842 dev_t devt;
843 int retval;
844
845 icap_class = class_create(THIS_MODULE, "xilinx_config");
846
847 if (xhwicap_major) {
848 devt = MKDEV(xhwicap_major, xhwicap_minor);
849 retval = register_chrdev_region(
850 devt,
851 HWICAP_DEVICES,
852 DRIVER_NAME);
853 if (retval < 0)
854 return retval;
855 } else {
856 retval = alloc_chrdev_region(&devt,
857 xhwicap_minor,
858 HWICAP_DEVICES,
859 DRIVER_NAME);
860 if (retval < 0)
861 return retval;
862 xhwicap_major = MAJOR(devt);
863 }
864
865 retval = platform_driver_register(&hwicap_platform_driver);
866
867 if (retval)
868 goto failed1;
869
870 retval = hwicap_of_register();
871
872 if (retval)
873 goto failed2;
874
875 return retval;
876
877 failed2:
878 platform_driver_unregister(&hwicap_platform_driver);
879
880 failed1:
881 unregister_chrdev_region(devt, HWICAP_DEVICES);
882
883 return retval;
884}
885
886static void __devexit hwicap_module_cleanup(void)
887{
888 dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);
889
890 class_destroy(icap_class);
891
892 platform_driver_unregister(&hwicap_platform_driver);
893
894 hwicap_of_unregister();
895
896 unregister_chrdev_region(devt, HWICAP_DEVICES);
897}
898
899module_init(hwicap_module_init);
900module_exit(hwicap_module_cleanup);
901
902MODULE_AUTHOR("Xilinx, Inc; Xilinx Research Labs Group");
903MODULE_DESCRIPTION("Xilinx ICAP Port Driver");
904MODULE_LICENSE("GPL");
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
new file mode 100644
index 000000000000..ae771cac1629
--- /dev/null
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -0,0 +1,193 @@
1/*****************************************************************************
2 *
3 * Author: Xilinx, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE.
23 *
24 * Xilinx products are not intended for use in life support appliances,
25 * devices, or systems. Use in such applications is expressly prohibited.
26 *
27 * (c) Copyright 2003-2007 Xilinx Inc.
28 * All rights reserved.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 *
34 *****************************************************************************/
35
36#ifndef XILINX_HWICAP_H_ /* prevent circular inclusions */
37#define XILINX_HWICAP_H_ /* by using protection macros */
38
39#include <linux/types.h>
40#include <linux/cdev.h>
41#include <linux/version.h>
42#include <linux/platform_device.h>
43
44#include <asm/io.h>
45
46struct hwicap_drvdata {
47 u32 write_buffer_in_use; /* Always in [0,3] */
48 u8 write_buffer[4];
49 u32 read_buffer_in_use; /* Always in [0,3] */
50 u8 read_buffer[4];
51 u32 mem_start; /* phys. address of the control registers */
52 u32 mem_end; /* phys. address of the control registers */
53 u32 mem_size;
54 void __iomem *base_address;/* virt. address of the control registers */
55
56 struct device *dev;
57 struct cdev cdev; /* Char device structure */
58 dev_t devt;
59
60 const struct hwicap_driver_config *config;
61 const struct config_registers *config_regs;
62 void *private_data;
63 bool is_open;
64 struct semaphore sem;
65};
66
67struct hwicap_driver_config {
68 int (*get_configuration)(struct hwicap_drvdata *drvdata, u32 *data,
69 u32 size);
70 int (*set_configuration)(struct hwicap_drvdata *drvdata, u32 *data,
71 u32 size);
72 void (*reset)(struct hwicap_drvdata *drvdata);
73};
74
75/* Number of times to poll the done regsiter */
76#define XHI_MAX_RETRIES 10
77
78/************ Constant Definitions *************/
79
80#define XHI_PAD_FRAMES 0x1
81
82/* Mask for calculating configuration packet headers */
83#define XHI_WORD_COUNT_MASK_TYPE_1 0x7FFUL
84#define XHI_WORD_COUNT_MASK_TYPE_2 0x1FFFFFUL
85#define XHI_TYPE_MASK 0x7
86#define XHI_REGISTER_MASK 0xF
87#define XHI_OP_MASK 0x3
88
89#define XHI_TYPE_SHIFT 29
90#define XHI_REGISTER_SHIFT 13
91#define XHI_OP_SHIFT 27
92
93#define XHI_TYPE_1 1
94#define XHI_TYPE_2 2
95#define XHI_OP_WRITE 2
96#define XHI_OP_READ 1
97
98/* Address Block Types */
99#define XHI_FAR_CLB_BLOCK 0
100#define XHI_FAR_BRAM_BLOCK 1
101#define XHI_FAR_BRAM_INT_BLOCK 2
102
103struct config_registers {
104 u32 CRC;
105 u32 FAR;
106 u32 FDRI;
107 u32 FDRO;
108 u32 CMD;
109 u32 CTL;
110 u32 MASK;
111 u32 STAT;
112 u32 LOUT;
113 u32 COR;
114 u32 MFWR;
115 u32 FLR;
116 u32 KEY;
117 u32 CBC;
118 u32 IDCODE;
119 u32 AXSS;
120 u32 C0R_1;
121 u32 CSOB;
122 u32 WBSTAR;
123 u32 TIMER;
124 u32 BOOTSTS;
125 u32 CTL_1;
126};
127
128/* Configuration Commands */
129#define XHI_CMD_NULL 0
130#define XHI_CMD_WCFG 1
131#define XHI_CMD_MFW 2
132#define XHI_CMD_DGHIGH 3
133#define XHI_CMD_RCFG 4
134#define XHI_CMD_START 5
135#define XHI_CMD_RCAP 6
136#define XHI_CMD_RCRC 7
137#define XHI_CMD_AGHIGH 8
138#define XHI_CMD_SWITCH 9
139#define XHI_CMD_GRESTORE 10
140#define XHI_CMD_SHUTDOWN 11
141#define XHI_CMD_GCAPTURE 12
142#define XHI_CMD_DESYNCH 13
143#define XHI_CMD_IPROG 15 /* Only in Virtex5 */
144#define XHI_CMD_CRCC 16 /* Only in Virtex5 */
145#define XHI_CMD_LTIMER 17 /* Only in Virtex5 */
146
147/* Packet constants */
148#define XHI_SYNC_PACKET 0xAA995566UL
149#define XHI_DUMMY_PACKET 0xFFFFFFFFUL
150#define XHI_NOOP_PACKET (XHI_TYPE_1 << XHI_TYPE_SHIFT)
151#define XHI_TYPE_2_READ ((XHI_TYPE_2 << XHI_TYPE_SHIFT) | \
152 (XHI_OP_READ << XHI_OP_SHIFT))
153
154#define XHI_TYPE_2_WRITE ((XHI_TYPE_2 << XHI_TYPE_SHIFT) | \
155 (XHI_OP_WRITE << XHI_OP_SHIFT))
156
157#define XHI_TYPE2_CNT_MASK 0x07FFFFFF
158
159#define XHI_TYPE_1_PACKET_MAX_WORDS 2047UL
160#define XHI_TYPE_1_HEADER_BYTES 4
161#define XHI_TYPE_2_HEADER_BYTES 8
162
163/* Constant to use for CRC check when CRC has been disabled */
164#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL
165
166/**
167 * hwicap_type_1_read: Generates a Type 1 read packet header.
168 * @parameter: Register is the address of the register to be read back.
169 *
170 * Generates a Type 1 read packet header, which is used to indirectly
171 * read registers in the configuration logic. This packet must then
172 * be sent through the icap device, and a return packet received with
173 * the information.
174 **/
175static inline u32 hwicap_type_1_read(u32 Register)
176{
177 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
178 (Register << XHI_REGISTER_SHIFT) |
179 (XHI_OP_READ << XHI_OP_SHIFT);
180}
181
182/**
183 * hwicap_type_1_write: Generates a Type 1 write packet header
184 * @parameter: Register is the address of the register to be read back.
185 **/
186static inline u32 hwicap_type_1_write(u32 Register)
187{
188 return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
189 (Register << XHI_REGISTER_SHIFT) |
190 (XHI_OP_WRITE << XHI_OP_SHIFT);
191}
192
193#endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7d170cd381c3..9cc25fd80b60 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1737,10 +1737,8 @@ config SC92031
1737 1737
1738config CPMAC 1738config CPMAC
1739 tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)" 1739 tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
1740 depends on NET_ETHERNET && EXPERIMENTAL && AR7 1740 depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN
1741 select PHYLIB 1741 select PHYLIB
1742 select FIXED_PHY
1743 select FIXED_MII_100_FDX
1744 help 1742 help
1745 TI AR7 CPMAC Ethernet support 1743 TI AR7 CPMAC Ethernet support
1746 1744
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 6ccebb830ff9..c85194f2cd2d 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -845,15 +845,6 @@ static void cpmac_adjust_link(struct net_device *dev)
845 spin_unlock(&priv->lock); 845 spin_unlock(&priv->lock);
846} 846}
847 847
848static int cpmac_link_update(struct net_device *dev,
849 struct fixed_phy_status *status)
850{
851 status->link = 1;
852 status->speed = 100;
853 status->duplex = 1;
854 return 0;
855}
856
857static int cpmac_open(struct net_device *dev) 848static int cpmac_open(struct net_device *dev)
858{ 849{
859 int i, size, res; 850 int i, size, res;
@@ -996,11 +987,11 @@ static int external_switch;
996static int __devinit cpmac_probe(struct platform_device *pdev) 987static int __devinit cpmac_probe(struct platform_device *pdev)
997{ 988{
998 int rc, phy_id, i; 989 int rc, phy_id, i;
990 int mdio_bus_id = cpmac_mii.id;
999 struct resource *mem; 991 struct resource *mem;
1000 struct cpmac_priv *priv; 992 struct cpmac_priv *priv;
1001 struct net_device *dev; 993 struct net_device *dev;
1002 struct plat_cpmac_data *pdata; 994 struct plat_cpmac_data *pdata;
1003 struct fixed_info *fixed_phy;
1004 DECLARE_MAC_BUF(mac); 995 DECLARE_MAC_BUF(mac);
1005 996
1006 pdata = pdev->dev.platform_data; 997 pdata = pdev->dev.platform_data;
@@ -1014,9 +1005,23 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
1014 } 1005 }
1015 1006
1016 if (phy_id == PHY_MAX_ADDR) { 1007 if (phy_id == PHY_MAX_ADDR) {
1017 if (external_switch || dumb_switch) 1008 if (external_switch || dumb_switch) {
1009 struct fixed_phy_status status = {};
1010
1011 mdio_bus_id = 0;
1012
1013 /*
1014 * FIXME: this should be in the platform code!
1015 * Since there is not platform code at all (that is,
1016 * no mainline users of that driver), place it here
1017 * for now.
1018 */
1018 phy_id = 0; 1019 phy_id = 0;
1019 else { 1020 status.link = 1;
1021 status.duplex = 1;
1022 status.speed = 100;
1023 fixed_phy_add(PHY_POLL, phy_id, &status);
1024 } else {
1020 printk(KERN_ERR "cpmac: no PHY present\n"); 1025 printk(KERN_ERR "cpmac: no PHY present\n");
1021 return -ENODEV; 1026 return -ENODEV;
1022 } 1027 }
@@ -1060,32 +1065,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
1060 priv->msg_enable = netif_msg_init(debug_level, 0xff); 1065 priv->msg_enable = netif_msg_init(debug_level, 0xff);
1061 memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); 1066 memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
1062 1067
1063 if (phy_id == 31) { 1068 snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
1064 snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, cpmac_mii.id,
1065 phy_id);
1066 } else {
1067 /* Let's try to get a free fixed phy... */
1068 for (i = 0; i < MAX_PHY_AMNT; i++) {
1069 fixed_phy = fixed_mdio_get_phydev(i);
1070 if (!fixed_phy)
1071 continue;
1072 if (!fixed_phy->phydev->attached_dev) {
1073 strncpy(priv->phy_name,
1074 fixed_phy->phydev->dev.bus_id,
1075 BUS_ID_SIZE);
1076 fixed_mdio_set_link_update(fixed_phy->phydev,
1077 &cpmac_link_update);
1078 goto phy_found;
1079 }
1080 }
1081 if (netif_msg_drv(priv))
1082 printk(KERN_ERR "%s: Could not find fixed PHY\n",
1083 dev->name);
1084 rc = -ENODEV;
1085 goto fail;
1086 }
1087 1069
1088phy_found:
1089 priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, 1070 priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
1090 PHY_INTERFACE_MODE_MII); 1071 PHY_INTERFACE_MODE_MII);
1091 if (IS_ERR(priv->phy)) { 1072 if (IS_ERR(priv->phy)) {
diff --git a/drivers/of/base.c b/drivers/of/base.c
index b306fef1ac41..80c9deca5f35 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -138,6 +138,31 @@ struct device_node *of_get_parent(const struct device_node *node)
138EXPORT_SYMBOL(of_get_parent); 138EXPORT_SYMBOL(of_get_parent);
139 139
140/** 140/**
141 * of_get_next_parent - Iterate to a node's parent
142 * @node: Node to get parent of
143 *
144 * This is like of_get_parent() except that it drops the
145 * refcount on the passed node, making it suitable for iterating
146 * through a node's parents.
147 *
148 * Returns a node pointer with refcount incremented, use
149 * of_node_put() on it when done.
150 */
151struct device_node *of_get_next_parent(struct device_node *node)
152{
153 struct device_node *parent;
154
155 if (!node)
156 return NULL;
157
158 read_lock(&devtree_lock);
159 parent = of_node_get(node->parent);
160 of_node_put(node);
161 read_unlock(&devtree_lock);
162 return parent;
163}
164
165/**
141 * of_get_next_child - Iterate a node childs 166 * of_get_next_child - Iterate a node childs
142 * @node: parent node 167 * @node: parent node
143 * @prev: previous child of the parent node, or NULL to get first 168 * @prev: previous child of the parent node, or NULL to get first
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index b47bb2d7476a..ca09a63a64db 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -85,6 +85,15 @@ static int of_platform_device_resume(struct device * dev)
85 return error; 85 return error;
86} 86}
87 87
88static void of_platform_device_shutdown(struct device *dev)
89{
90 struct of_device *of_dev = to_of_device(dev);
91 struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
92
93 if (dev->driver && drv->shutdown)
94 drv->shutdown(of_dev);
95}
96
88int of_bus_type_init(struct bus_type *bus, const char *name) 97int of_bus_type_init(struct bus_type *bus, const char *name)
89{ 98{
90 bus->name = name; 99 bus->name = name;
@@ -93,6 +102,7 @@ int of_bus_type_init(struct bus_type *bus, const char *name)
93 bus->remove = of_platform_device_remove; 102 bus->remove = of_platform_device_remove;
94 bus->suspend = of_platform_device_suspend; 103 bus->suspend = of_platform_device_suspend;
95 bus->resume = of_platform_device_resume; 104 bus->resume = of_platform_device_resume;
105 bus->shutdown = of_platform_device_shutdown;
96 return bus_register(bus); 106 return bus_register(bus);
97} 107}
98 108
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 50d6e2214ddf..84a054d7e986 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1142,17 +1142,17 @@ config SERIAL_SGI_L1_CONSOLE
1142 say Y. Otherwise, say N. 1142 say Y. Otherwise, say N.
1143 1143
1144config SERIAL_MPC52xx 1144config SERIAL_MPC52xx
1145 tristate "Freescale MPC52xx family PSC serial support" 1145 tristate "Freescale MPC52xx/MPC512x family PSC serial support"
1146 depends on PPC_MPC52xx 1146 depends on PPC_MPC52xx || PPC_MPC512x
1147 select SERIAL_CORE 1147 select SERIAL_CORE
1148 help 1148 help
1149 This drivers support the MPC52xx PSC serial ports. If you would 1149 This driver supports MPC52xx and MPC512x PSC serial ports. If you would
1150 like to use them, you must answer Y or M to this option. Not that 1150 like to use them, you must answer Y or M to this option. Note that
1151 for use as console, it must be included in kernel and not as a 1151 for use as console, it must be included in kernel and not as a
1152 module. 1152 module.
1153 1153
1154config SERIAL_MPC52xx_CONSOLE 1154config SERIAL_MPC52xx_CONSOLE
1155 bool "Console on a Freescale MPC52xx family PSC serial port" 1155 bool "Console on a Freescale MPC52xx/MPC512x family PSC serial port"
1156 depends on SERIAL_MPC52xx=y 1156 depends on SERIAL_MPC52xx=y
1157 select SERIAL_CORE_CONSOLE 1157 select SERIAL_CORE_CONSOLE
1158 help 1158 help
@@ -1160,7 +1160,7 @@ config SERIAL_MPC52xx_CONSOLE
1160 of the Freescale MPC52xx family as a console. 1160 of the Freescale MPC52xx family as a console.
1161 1161
1162config SERIAL_MPC52xx_CONSOLE_BAUD 1162config SERIAL_MPC52xx_CONSOLE_BAUD
1163 int "Freescale MPC52xx family PSC serial port baud" 1163 int "Freescale MPC52xx/MPC512x family PSC serial port baud"
1164 depends on SERIAL_MPC52xx_CONSOLE=y 1164 depends on SERIAL_MPC52xx_CONSOLE=y
1165 default "9600" 1165 default "9600"
1166 help 1166 help
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 3c4d29e59b2c..a638f23c6c61 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -16,6 +16,9 @@
16 * Some of the code has been inspired/copied from the 2.4 code written 16 * Some of the code has been inspired/copied from the 2.4 code written
17 * by Dale Farnsworth <dfarnsworth@mvista.com>. 17 * by Dale Farnsworth <dfarnsworth@mvista.com>.
18 * 18 *
19 * Copyright (C) 2008 Freescale Semiconductor Inc.
20 * John Rigby <jrigby@gmail.com>
21 * Added support for MPC5121
19 * Copyright (C) 2006 Secret Lab Technologies Ltd. 22 * Copyright (C) 2006 Secret Lab Technologies Ltd.
20 * Grant Likely <grant.likely@secretlab.ca> 23 * Grant Likely <grant.likely@secretlab.ca>
21 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com> 24 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com>
@@ -67,7 +70,6 @@
67#include <linux/serial.h> 70#include <linux/serial.h>
68#include <linux/sysrq.h> 71#include <linux/sysrq.h>
69#include <linux/console.h> 72#include <linux/console.h>
70
71#include <linux/delay.h> 73#include <linux/delay.h>
72#include <linux/io.h> 74#include <linux/io.h>
73 75
@@ -79,6 +81,7 @@
79#endif 81#endif
80 82
81#include <asm/mpc52xx.h> 83#include <asm/mpc52xx.h>
84#include <asm/mpc512x.h>
82#include <asm/mpc52xx_psc.h> 85#include <asm/mpc52xx_psc.h>
83 86
84#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 87#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -111,8 +114,8 @@ static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM];
111static void mpc52xx_uart_of_enumerate(void); 114static void mpc52xx_uart_of_enumerate(void);
112#endif 115#endif
113 116
117
114#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) 118#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
115#define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
116 119
117 120
118/* Forward declaration of the interruption handling routine */ 121/* Forward declaration of the interruption handling routine */
@@ -128,15 +131,301 @@ static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
128#define uart_console(port) (0) 131#define uart_console(port) (0)
129#endif 132#endif
130 133
134/* ======================================================================== */
135/* PSC fifo operations for isolating differences between 52xx and 512x */
136/* ======================================================================== */
137
138struct psc_ops {
139 void (*fifo_init)(struct uart_port *port);
140 int (*raw_rx_rdy)(struct uart_port *port);
141 int (*raw_tx_rdy)(struct uart_port *port);
142 int (*rx_rdy)(struct uart_port *port);
143 int (*tx_rdy)(struct uart_port *port);
144 int (*tx_empty)(struct uart_port *port);
145 void (*stop_rx)(struct uart_port *port);
146 void (*start_tx)(struct uart_port *port);
147 void (*stop_tx)(struct uart_port *port);
148 void (*rx_clr_irq)(struct uart_port *port);
149 void (*tx_clr_irq)(struct uart_port *port);
150 void (*write_char)(struct uart_port *port, unsigned char c);
151 unsigned char (*read_char)(struct uart_port *port);
152 void (*cw_disable_ints)(struct uart_port *port);
153 void (*cw_restore_ints)(struct uart_port *port);
154 unsigned long (*getuartclk)(void *p);
155};
156
157#ifdef CONFIG_PPC_MPC52xx
158#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
159static void mpc52xx_psc_fifo_init(struct uart_port *port)
160{
161 struct mpc52xx_psc __iomem *psc = PSC(port);
162 struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port);
163
164 /* /32 prescaler */
165 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
166
167 out_8(&fifo->rfcntl, 0x00);
168 out_be16(&fifo->rfalarm, 0x1ff);
169 out_8(&fifo->tfcntl, 0x07);
170 out_be16(&fifo->tfalarm, 0x80);
171
172 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
173 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
174}
175
176static int mpc52xx_psc_raw_rx_rdy(struct uart_port *port)
177{
178 return in_be16(&PSC(port)->mpc52xx_psc_status)
179 & MPC52xx_PSC_SR_RXRDY;
180}
181
182static int mpc52xx_psc_raw_tx_rdy(struct uart_port *port)
183{
184 return in_be16(&PSC(port)->mpc52xx_psc_status)
185 & MPC52xx_PSC_SR_TXRDY;
186}
187
188
189static int mpc52xx_psc_rx_rdy(struct uart_port *port)
190{
191 return in_be16(&PSC(port)->mpc52xx_psc_isr)
192 & port->read_status_mask
193 & MPC52xx_PSC_IMR_RXRDY;
194}
195
196static int mpc52xx_psc_tx_rdy(struct uart_port *port)
197{
198 return in_be16(&PSC(port)->mpc52xx_psc_isr)
199 & port->read_status_mask
200 & MPC52xx_PSC_IMR_TXRDY;
201}
202
203static int mpc52xx_psc_tx_empty(struct uart_port *port)
204{
205 return in_be16(&PSC(port)->mpc52xx_psc_status)
206 & MPC52xx_PSC_SR_TXEMP;
207}
208
209static void mpc52xx_psc_start_tx(struct uart_port *port)
210{
211 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
212 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
213}
214
215static void mpc52xx_psc_stop_tx(struct uart_port *port)
216{
217 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY;
218 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
219}
220
221static void mpc52xx_psc_stop_rx(struct uart_port *port)
222{
223 port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY;
224 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
225}
226
227static void mpc52xx_psc_rx_clr_irq(struct uart_port *port)
228{
229}
230
231static void mpc52xx_psc_tx_clr_irq(struct uart_port *port)
232{
233}
234
235static void mpc52xx_psc_write_char(struct uart_port *port, unsigned char c)
236{
237 out_8(&PSC(port)->mpc52xx_psc_buffer_8, c);
238}
239
240static unsigned char mpc52xx_psc_read_char(struct uart_port *port)
241{
242 return in_8(&PSC(port)->mpc52xx_psc_buffer_8);
243}
244
245static void mpc52xx_psc_cw_disable_ints(struct uart_port *port)
246{
247 out_be16(&PSC(port)->mpc52xx_psc_imr, 0);
248}
249
250static void mpc52xx_psc_cw_restore_ints(struct uart_port *port)
251{
252 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
253}
254
255/* Search for bus-frequency property in this node or a parent */
256static unsigned long mpc52xx_getuartclk(void *p)
257{
131#if defined(CONFIG_PPC_MERGE) 258#if defined(CONFIG_PPC_MERGE)
132static struct of_device_id mpc52xx_uart_of_match[] = { 259 /*
133 { .type = "serial", .compatible = "fsl,mpc5200-psc-uart", }, 260 * 5200 UARTs have a / 32 prescaler
134 { .type = "serial", .compatible = "mpc5200-psc-uart", }, /* lite5200 */ 261 * but the generic serial code assumes 16
135 { .type = "serial", .compatible = "mpc5200-serial", }, /* efika */ 262 * so return ipb freq / 2
136 {}, 263 */
264 return mpc52xx_find_ipb_freq(p) / 2;
265#else
266 pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n");
267 return NULL;
268#endif
269}
270
271static struct psc_ops mpc52xx_psc_ops = {
272 .fifo_init = mpc52xx_psc_fifo_init,
273 .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy,
274 .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy,
275 .rx_rdy = mpc52xx_psc_rx_rdy,
276 .tx_rdy = mpc52xx_psc_tx_rdy,
277 .tx_empty = mpc52xx_psc_tx_empty,
278 .stop_rx = mpc52xx_psc_stop_rx,
279 .start_tx = mpc52xx_psc_start_tx,
280 .stop_tx = mpc52xx_psc_stop_tx,
281 .rx_clr_irq = mpc52xx_psc_rx_clr_irq,
282 .tx_clr_irq = mpc52xx_psc_tx_clr_irq,
283 .write_char = mpc52xx_psc_write_char,
284 .read_char = mpc52xx_psc_read_char,
285 .cw_disable_ints = mpc52xx_psc_cw_disable_ints,
286 .cw_restore_ints = mpc52xx_psc_cw_restore_ints,
287 .getuartclk = mpc52xx_getuartclk,
288};
289
290#endif /* CONFIG_MPC52xx */
291
292#ifdef CONFIG_PPC_MPC512x
293#define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1))
294static void mpc512x_psc_fifo_init(struct uart_port *port)
295{
296 out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
297 out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
298 out_be32(&FIFO_512x(port)->txalarm, 1);
299 out_be32(&FIFO_512x(port)->tximr, 0);
300
301 out_be32(&FIFO_512x(port)->rxcmd, MPC512x_PSC_FIFO_RESET_SLICE);
302 out_be32(&FIFO_512x(port)->rxcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
303 out_be32(&FIFO_512x(port)->rxalarm, 1);
304 out_be32(&FIFO_512x(port)->rximr, 0);
305
306 out_be32(&FIFO_512x(port)->tximr, MPC512x_PSC_FIFO_ALARM);
307 out_be32(&FIFO_512x(port)->rximr, MPC512x_PSC_FIFO_ALARM);
308}
309
310static int mpc512x_psc_raw_rx_rdy(struct uart_port *port)
311{
312 return !(in_be32(&FIFO_512x(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY);
313}
314
315static int mpc512x_psc_raw_tx_rdy(struct uart_port *port)
316{
317 return !(in_be32(&FIFO_512x(port)->txsr) & MPC512x_PSC_FIFO_FULL);
318}
319
320static int mpc512x_psc_rx_rdy(struct uart_port *port)
321{
322 return in_be32(&FIFO_512x(port)->rxsr)
323 & in_be32(&FIFO_512x(port)->rximr)
324 & MPC512x_PSC_FIFO_ALARM;
325}
326
327static int mpc512x_psc_tx_rdy(struct uart_port *port)
328{
329 return in_be32(&FIFO_512x(port)->txsr)
330 & in_be32(&FIFO_512x(port)->tximr)
331 & MPC512x_PSC_FIFO_ALARM;
332}
333
334static int mpc512x_psc_tx_empty(struct uart_port *port)
335{
336 return in_be32(&FIFO_512x(port)->txsr)
337 & MPC512x_PSC_FIFO_EMPTY;
338}
339
340static void mpc512x_psc_stop_rx(struct uart_port *port)
341{
342 unsigned long rx_fifo_imr;
343
344 rx_fifo_imr = in_be32(&FIFO_512x(port)->rximr);
345 rx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
346 out_be32(&FIFO_512x(port)->rximr, rx_fifo_imr);
347}
348
349static void mpc512x_psc_start_tx(struct uart_port *port)
350{
351 unsigned long tx_fifo_imr;
352
353 tx_fifo_imr = in_be32(&FIFO_512x(port)->tximr);
354 tx_fifo_imr |= MPC512x_PSC_FIFO_ALARM;
355 out_be32(&FIFO_512x(port)->tximr, tx_fifo_imr);
356}
357
358static void mpc512x_psc_stop_tx(struct uart_port *port)
359{
360 unsigned long tx_fifo_imr;
361
362 tx_fifo_imr = in_be32(&FIFO_512x(port)->tximr);
363 tx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
364 out_be32(&FIFO_512x(port)->tximr, tx_fifo_imr);
365}
366
367static void mpc512x_psc_rx_clr_irq(struct uart_port *port)
368{
369 out_be32(&FIFO_512x(port)->rxisr, in_be32(&FIFO_512x(port)->rxisr));
370}
371
372static void mpc512x_psc_tx_clr_irq(struct uart_port *port)
373{
374 out_be32(&FIFO_512x(port)->txisr, in_be32(&FIFO_512x(port)->txisr));
375}
376
377static void mpc512x_psc_write_char(struct uart_port *port, unsigned char c)
378{
379 out_8(&FIFO_512x(port)->txdata_8, c);
380}
381
382static unsigned char mpc512x_psc_read_char(struct uart_port *port)
383{
384 return in_8(&FIFO_512x(port)->rxdata_8);
385}
386
387static void mpc512x_psc_cw_disable_ints(struct uart_port *port)
388{
389 port->read_status_mask =
390 in_be32(&FIFO_512x(port)->tximr) << 16 |
391 in_be32(&FIFO_512x(port)->rximr);
392 out_be32(&FIFO_512x(port)->tximr, 0);
393 out_be32(&FIFO_512x(port)->rximr, 0);
394}
395
396static void mpc512x_psc_cw_restore_ints(struct uart_port *port)
397{
398 out_be32(&FIFO_512x(port)->tximr,
399 (port->read_status_mask >> 16) & 0x7f);
400 out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f);
401}
402
403static unsigned long mpc512x_getuartclk(void *p)
404{
405 return mpc512x_find_ips_freq(p);
406}
407
408static struct psc_ops mpc512x_psc_ops = {
409 .fifo_init = mpc512x_psc_fifo_init,
410 .raw_rx_rdy = mpc512x_psc_raw_rx_rdy,
411 .raw_tx_rdy = mpc512x_psc_raw_tx_rdy,
412 .rx_rdy = mpc512x_psc_rx_rdy,
413 .tx_rdy = mpc512x_psc_tx_rdy,
414 .tx_empty = mpc512x_psc_tx_empty,
415 .stop_rx = mpc512x_psc_stop_rx,
416 .start_tx = mpc512x_psc_start_tx,
417 .stop_tx = mpc512x_psc_stop_tx,
418 .rx_clr_irq = mpc512x_psc_rx_clr_irq,
419 .tx_clr_irq = mpc512x_psc_tx_clr_irq,
420 .write_char = mpc512x_psc_write_char,
421 .read_char = mpc512x_psc_read_char,
422 .cw_disable_ints = mpc512x_psc_cw_disable_ints,
423 .cw_restore_ints = mpc512x_psc_cw_restore_ints,
424 .getuartclk = mpc512x_getuartclk,
137}; 425};
138#endif 426#endif
139 427
428static struct psc_ops *psc_ops;
140 429
141/* ======================================================================== */ 430/* ======================================================================== */
142/* UART operations */ 431/* UART operations */
@@ -145,8 +434,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
145static unsigned int 434static unsigned int
146mpc52xx_uart_tx_empty(struct uart_port *port) 435mpc52xx_uart_tx_empty(struct uart_port *port)
147{ 436{
148 int status = in_be16(&PSC(port)->mpc52xx_psc_status); 437 return psc_ops->tx_empty(port) ? TIOCSER_TEMT : 0;
149 return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;
150} 438}
151 439
152static void 440static void
@@ -166,16 +454,14 @@ static void
166mpc52xx_uart_stop_tx(struct uart_port *port) 454mpc52xx_uart_stop_tx(struct uart_port *port)
167{ 455{
168 /* port->lock taken by caller */ 456 /* port->lock taken by caller */
169 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; 457 psc_ops->stop_tx(port);
170 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
171} 458}
172 459
173static void 460static void
174mpc52xx_uart_start_tx(struct uart_port *port) 461mpc52xx_uart_start_tx(struct uart_port *port)
175{ 462{
176 /* port->lock taken by caller */ 463 /* port->lock taken by caller */
177 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 464 psc_ops->start_tx(port);
178 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
179} 465}
180 466
181static void 467static void
@@ -188,8 +474,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
188 if (ch) { 474 if (ch) {
189 /* Make sure tx interrupts are on */ 475 /* Make sure tx interrupts are on */
190 /* Truly necessary ??? They should be anyway */ 476 /* Truly necessary ??? They should be anyway */
191 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 477 psc_ops->start_tx(port);
192 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
193 } 478 }
194 479
195 spin_unlock_irqrestore(&port->lock, flags); 480 spin_unlock_irqrestore(&port->lock, flags);
@@ -199,8 +484,7 @@ static void
199mpc52xx_uart_stop_rx(struct uart_port *port) 484mpc52xx_uart_stop_rx(struct uart_port *port)
200{ 485{
201 /* port->lock taken by caller */ 486 /* port->lock taken by caller */
202 port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; 487 psc_ops->stop_rx(port);
203 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
204} 488}
205 489
206static void 490static void
@@ -227,12 +511,12 @@ static int
227mpc52xx_uart_startup(struct uart_port *port) 511mpc52xx_uart_startup(struct uart_port *port)
228{ 512{
229 struct mpc52xx_psc __iomem *psc = PSC(port); 513 struct mpc52xx_psc __iomem *psc = PSC(port);
230 struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port);
231 int ret; 514 int ret;
232 515
233 /* Request IRQ */ 516 /* Request IRQ */
234 ret = request_irq(port->irq, mpc52xx_uart_int, 517 ret = request_irq(port->irq, mpc52xx_uart_int,
235 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "mpc52xx_psc_uart", port); 518 IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED,
519 "mpc52xx_psc_uart", port);
236 if (ret) 520 if (ret)
237 return ret; 521 return ret;
238 522
@@ -242,15 +526,7 @@ mpc52xx_uart_startup(struct uart_port *port)
242 526
243 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ 527 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */
244 528
245 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ 529 psc_ops->fifo_init(port);
246
247 out_8(&fifo->rfcntl, 0x00);
248 out_be16(&fifo->rfalarm, 0x1ff);
249 out_8(&fifo->tfcntl, 0x07);
250 out_be16(&fifo->tfalarm, 0x80);
251
252 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
253 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
254 530
255 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 531 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
256 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 532 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
@@ -333,8 +609,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
333 * boot for the console, all stuff is not yet ready to receive at that 609 * boot for the console, all stuff is not yet ready to receive at that
334 * time and that just makes the kernel oops */ 610 * time and that just makes the kernel oops */
335 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ 611 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */
336 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 612 while (!mpc52xx_uart_tx_empty(port) && --j)
337 --j)
338 udelay(1); 613 udelay(1);
339 614
340 if (!j) 615 if (!j)
@@ -462,11 +737,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
462 unsigned short status; 737 unsigned short status;
463 738
464 /* While we can read, do so ! */ 739 /* While we can read, do so ! */
465 while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & 740 while (psc_ops->raw_rx_rdy(port)) {
466 MPC52xx_PSC_SR_RXRDY) {
467
468 /* Get the char */ 741 /* Get the char */
469 ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); 742 ch = psc_ops->read_char(port);
470 743
471 /* Handle sysreq char */ 744 /* Handle sysreq char */
472#ifdef SUPPORT_SYSRQ 745#ifdef SUPPORT_SYSRQ
@@ -481,6 +754,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
481 flag = TTY_NORMAL; 754 flag = TTY_NORMAL;
482 port->icount.rx++; 755 port->icount.rx++;
483 756
757 status = in_be16(&PSC(port)->mpc52xx_psc_status);
758
484 if (status & (MPC52xx_PSC_SR_PE | 759 if (status & (MPC52xx_PSC_SR_PE |
485 MPC52xx_PSC_SR_FE | 760 MPC52xx_PSC_SR_FE |
486 MPC52xx_PSC_SR_RB)) { 761 MPC52xx_PSC_SR_RB)) {
@@ -510,7 +785,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
510 785
511 tty_flip_buffer_push(tty); 786 tty_flip_buffer_push(tty);
512 787
513 return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; 788 return psc_ops->raw_rx_rdy(port);
514} 789}
515 790
516static inline int 791static inline int
@@ -520,7 +795,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
520 795
521 /* Process out of band chars */ 796 /* Process out of band chars */
522 if (port->x_char) { 797 if (port->x_char) {
523 out_8(&PSC(port)->mpc52xx_psc_buffer_8, port->x_char); 798 psc_ops->write_char(port, port->x_char);
524 port->icount.tx++; 799 port->icount.tx++;
525 port->x_char = 0; 800 port->x_char = 0;
526 return 1; 801 return 1;
@@ -533,8 +808,8 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
533 } 808 }
534 809
535 /* Send chars */ 810 /* Send chars */
536 while (in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXRDY) { 811 while (psc_ops->raw_tx_rdy(port)) {
537 out_8(&PSC(port)->mpc52xx_psc_buffer_8, xmit->buf[xmit->tail]); 812 psc_ops->write_char(port, xmit->buf[xmit->tail]);
538 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 813 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
539 port->icount.tx++; 814 port->icount.tx++;
540 if (uart_circ_empty(xmit)) 815 if (uart_circ_empty(xmit))
@@ -560,7 +835,6 @@ mpc52xx_uart_int(int irq, void *dev_id)
560 struct uart_port *port = dev_id; 835 struct uart_port *port = dev_id;
561 unsigned long pass = ISR_PASS_LIMIT; 836 unsigned long pass = ISR_PASS_LIMIT;
562 unsigned int keepgoing; 837 unsigned int keepgoing;
563 unsigned short status;
564 838
565 spin_lock(&port->lock); 839 spin_lock(&port->lock);
566 840
@@ -569,18 +843,12 @@ mpc52xx_uart_int(int irq, void *dev_id)
569 /* If we don't find anything to do, we stop */ 843 /* If we don't find anything to do, we stop */
570 keepgoing = 0; 844 keepgoing = 0;
571 845
572 /* Read status */ 846 psc_ops->rx_clr_irq(port);
573 status = in_be16(&PSC(port)->mpc52xx_psc_isr); 847 if (psc_ops->rx_rdy(port))
574 status &= port->read_status_mask;
575
576 /* Do we need to receive chars ? */
577 /* For this RX interrupts must be on and some chars waiting */
578 if (status & MPC52xx_PSC_IMR_RXRDY)
579 keepgoing |= mpc52xx_uart_int_rx_chars(port); 848 keepgoing |= mpc52xx_uart_int_rx_chars(port);
580 849
581 /* Do we need to send chars ? */ 850 psc_ops->tx_clr_irq(port);
582 /* For this, TX must be ready and TX interrupt enabled */ 851 if (psc_ops->tx_rdy(port))
583 if (status & MPC52xx_PSC_IMR_TXRDY)
584 keepgoing |= mpc52xx_uart_int_tx_chars(port); 852 keepgoing |= mpc52xx_uart_int_tx_chars(port);
585 853
586 /* Limit number of iteration */ 854 /* Limit number of iteration */
@@ -647,36 +915,33 @@ static void
647mpc52xx_console_write(struct console *co, const char *s, unsigned int count) 915mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
648{ 916{
649 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 917 struct uart_port *port = &mpc52xx_uart_ports[co->index];
650 struct mpc52xx_psc __iomem *psc = PSC(port);
651 unsigned int i, j; 918 unsigned int i, j;
652 919
653 /* Disable interrupts */ 920 /* Disable interrupts */
654 out_be16(&psc->mpc52xx_psc_imr, 0); 921 psc_ops->cw_disable_ints(port);
655 922
656 /* Wait the TX buffer to be empty */ 923 /* Wait the TX buffer to be empty */
657 j = 5000000; /* Maximum wait */ 924 j = 5000000; /* Maximum wait */
658 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 925 while (!mpc52xx_uart_tx_empty(port) && --j)
659 --j)
660 udelay(1); 926 udelay(1);
661 927
662 /* Write all the chars */ 928 /* Write all the chars */
663 for (i = 0; i < count; i++, s++) { 929 for (i = 0; i < count; i++, s++) {
664 /* Line return handling */ 930 /* Line return handling */
665 if (*s == '\n') 931 if (*s == '\n')
666 out_8(&psc->mpc52xx_psc_buffer_8, '\r'); 932 psc_ops->write_char(port, '\r');
667 933
668 /* Send the char */ 934 /* Send the char */
669 out_8(&psc->mpc52xx_psc_buffer_8, *s); 935 psc_ops->write_char(port, *s);
670 936
671 /* Wait the TX buffer to be empty */ 937 /* Wait the TX buffer to be empty */
672 j = 20000; /* Maximum wait */ 938 j = 20000; /* Maximum wait */
673 while (!(in_be16(&psc->mpc52xx_psc_status) & 939 while (!mpc52xx_uart_tx_empty(port) && --j)
674 MPC52xx_PSC_SR_TXEMP) && --j)
675 udelay(1); 940 udelay(1);
676 } 941 }
677 942
678 /* Restore interrupt state */ 943 /* Restore interrupt state */
679 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); 944 psc_ops->cw_restore_ints(port);
680} 945}
681 946
682#if !defined(CONFIG_PPC_MERGE) 947#if !defined(CONFIG_PPC_MERGE)
@@ -721,7 +986,7 @@ mpc52xx_console_setup(struct console *co, char *options)
721{ 986{
722 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 987 struct uart_port *port = &mpc52xx_uart_ports[co->index];
723 struct device_node *np = mpc52xx_uart_nodes[co->index]; 988 struct device_node *np = mpc52xx_uart_nodes[co->index];
724 unsigned int ipb_freq; 989 unsigned int uartclk;
725 struct resource res; 990 struct resource res;
726 int ret; 991 int ret;
727 992
@@ -753,17 +1018,16 @@ mpc52xx_console_setup(struct console *co, char *options)
753 return ret; 1018 return ret;
754 } 1019 }
755 1020
756 /* Search for bus-frequency property in this node or a parent */ 1021 uartclk = psc_ops->getuartclk(np);
757 ipb_freq = mpc52xx_find_ipb_freq(np); 1022 if (uartclk == 0) {
758 if (ipb_freq == 0) { 1023 pr_debug("Could not find uart clock frequency!\n");
759 pr_debug("Could not find IPB bus frequency!\n");
760 return -EINVAL; 1024 return -EINVAL;
761 } 1025 }
762 1026
763 /* Basic port init. Needed since we use some uart_??? func before 1027 /* Basic port init. Needed since we use some uart_??? func before
764 * real init for early access */ 1028 * real init for early access */
765 spin_lock_init(&port->lock); 1029 spin_lock_init(&port->lock);
766 port->uartclk = ipb_freq / 2; 1030 port->uartclk = uartclk;
767 port->ops = &mpc52xx_uart_ops; 1031 port->ops = &mpc52xx_uart_ops;
768 port->mapbase = res.start; 1032 port->mapbase = res.start;
769 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc)); 1033 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
@@ -945,11 +1209,25 @@ static struct platform_driver mpc52xx_uart_platform_driver = {
945/* OF Platform Driver */ 1209/* OF Platform Driver */
946/* ======================================================================== */ 1210/* ======================================================================== */
947 1211
1212static struct of_device_id mpc52xx_uart_of_match[] = {
1213#ifdef CONFIG_PPC_MPC52xx
1214 { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
1215 /* binding used by old lite5200 device trees: */
1216 { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
1217 /* binding used by efika: */
1218 { .compatible = "mpc5200-serial", .data = &mpc52xx_psc_ops, },
1219#endif
1220#ifdef CONFIG_PPC_MPC512x
1221 { .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
1222 {},
1223#endif
1224};
1225
948static int __devinit 1226static int __devinit
949mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) 1227mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
950{ 1228{
951 int idx = -1; 1229 int idx = -1;
952 unsigned int ipb_freq; 1230 unsigned int uartclk;
953 struct uart_port *port = NULL; 1231 struct uart_port *port = NULL;
954 struct resource res; 1232 struct resource res;
955 int ret; 1233 int ret;
@@ -965,10 +1243,9 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
965 pr_debug("Found %s assigned to ttyPSC%x\n", 1243 pr_debug("Found %s assigned to ttyPSC%x\n",
966 mpc52xx_uart_nodes[idx]->full_name, idx); 1244 mpc52xx_uart_nodes[idx]->full_name, idx);
967 1245
968 /* Search for bus-frequency property in this node or a parent */ 1246 uartclk = psc_ops->getuartclk(op->node);
969 ipb_freq = mpc52xx_find_ipb_freq(op->node); 1247 if (uartclk == 0) {
970 if (ipb_freq == 0) { 1248 dev_dbg(&op->dev, "Could not find uart clock frequency!\n");
971 dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");
972 return -EINVAL; 1249 return -EINVAL;
973 } 1250 }
974 1251
@@ -976,7 +1253,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
976 port = &mpc52xx_uart_ports[idx]; 1253 port = &mpc52xx_uart_ports[idx];
977 1254
978 spin_lock_init(&port->lock); 1255 spin_lock_init(&port->lock);
979 port->uartclk = ipb_freq / 2; 1256 port->uartclk = uartclk;
980 port->fifosize = 512; 1257 port->fifosize = 512;
981 port->iotype = UPIO_MEM; 1258 port->iotype = UPIO_MEM;
982 port->flags = UPF_BOOT_AUTOCONF | 1259 port->flags = UPF_BOOT_AUTOCONF |
@@ -1080,15 +1357,19 @@ mpc52xx_uart_of_enumerate(void)
1080 static int enum_done; 1357 static int enum_done;
1081 struct device_node *np; 1358 struct device_node *np;
1082 const unsigned int *devno; 1359 const unsigned int *devno;
1360 const struct of_device_id *match;
1083 int i; 1361 int i;
1084 1362
1085 if (enum_done) 1363 if (enum_done)
1086 return; 1364 return;
1087 1365
1088 for_each_node_by_type(np, "serial") { 1366 for_each_node_by_type(np, "serial") {
1089 if (!of_match_node(mpc52xx_uart_of_match, np)) 1367 match = of_match_node(mpc52xx_uart_of_match, np);
1368 if (!match)
1090 continue; 1369 continue;
1091 1370
1371 psc_ops = match->data;
1372
1092 /* Is a particular device number requested? */ 1373 /* Is a particular device number requested? */
1093 devno = of_get_property(np, "port-number", NULL); 1374 devno = of_get_property(np, "port-number", NULL);
1094 mpc52xx_uart_of_assign(np, devno ? *devno : -1); 1375 mpc52xx_uart_of_assign(np, devno ? *devno : -1);
@@ -1149,6 +1430,7 @@ mpc52xx_uart_init(void)
1149 return ret; 1430 return ret;
1150 } 1431 }
1151#else 1432#else
1433 psc_ops = &mpc52xx_psc_ops;
1152 ret = platform_driver_register(&mpc52xx_uart_platform_driver); 1434 ret = platform_driver_register(&mpc52xx_uart_platform_driver);
1153 if (ret) { 1435 if (ret) {
1154 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", 1436 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index bacf68dca01a..4e06ab6bcb6e 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -17,10 +17,21 @@
17#include <linux/tty.h> 17#include <linux/tty.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/init.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#if defined(CONFIG_OF) 22#if defined(CONFIG_OF)
23#include <linux/of.h>
22#include <linux/of_device.h> 24#include <linux/of_device.h>
23#include <linux/of_platform.h> 25#include <linux/of_platform.h>
26
27/* Match table for of_platform binding */
28static struct of_device_id ulite_of_match[] __devinitdata = {
29 { .compatible = "xlnx,opb-uartlite-1.00.b", },
30 { .compatible = "xlnx,xps-uartlite-1.00.a", },
31 {}
32};
33MODULE_DEVICE_TABLE(of, ulite_of_match);
34
24#endif 35#endif
25 36
26#define ULITE_NAME "ttyUL" 37#define ULITE_NAME "ttyUL"
@@ -275,6 +286,9 @@ static void ulite_release_port(struct uart_port *port)
275 286
276static int ulite_request_port(struct uart_port *port) 287static int ulite_request_port(struct uart_port *port)
277{ 288{
289 pr_debug("ulite console: port=%p; port->mapbase=%x\n",
290 port, port->mapbase);
291
278 if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) { 292 if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) {
279 dev_err(port->dev, "Memory region busy\n"); 293 dev_err(port->dev, "Memory region busy\n");
280 return -EBUSY; 294 return -EBUSY;
@@ -375,32 +389,6 @@ static void ulite_console_write(struct console *co, const char *s,
375 spin_unlock_irqrestore(&port->lock, flags); 389 spin_unlock_irqrestore(&port->lock, flags);
376} 390}
377 391
378#if defined(CONFIG_OF)
379static inline void __init ulite_console_of_find_device(int id)
380{
381 struct device_node *np;
382 struct resource res;
383 const unsigned int *of_id;
384 int rc;
385
386 for_each_compatible_node(np, NULL, "xilinx,uartlite") {
387 of_id = of_get_property(np, "port-number", NULL);
388 if ((!of_id) || (*of_id != id))
389 continue;
390
391 rc = of_address_to_resource(np, 0, &res);
392 if (rc)
393 continue;
394
395 ulite_ports[id].mapbase = res.start;
396 of_node_put(np);
397 return;
398 }
399}
400#else /* CONFIG_OF */
401static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ }
402#endif /* CONFIG_OF */
403
404static int __init ulite_console_setup(struct console *co, char *options) 392static int __init ulite_console_setup(struct console *co, char *options)
405{ 393{
406 struct uart_port *port; 394 struct uart_port *port;
@@ -414,11 +402,7 @@ static int __init ulite_console_setup(struct console *co, char *options)
414 402
415 port = &ulite_ports[co->index]; 403 port = &ulite_ports[co->index];
416 404
417 /* Check if it is an OF device */ 405 /* Has the device been initialized yet? */
418 if (!port->mapbase)
419 ulite_console_of_find_device(co->index);
420
421 /* Do we have a device now? */
422 if (!port->mapbase) { 406 if (!port->mapbase) {
423 pr_debug("console on ttyUL%i not present\n", co->index); 407 pr_debug("console on ttyUL%i not present\n", co->index);
424 return -ENODEV; 408 return -ENODEV;
@@ -617,13 +601,6 @@ static int __devexit ulite_of_remove(struct of_device *op)
617 return ulite_release(&op->dev); 601 return ulite_release(&op->dev);
618} 602}
619 603
620/* Match table for of_platform binding */
621static struct of_device_id __devinit ulite_of_match[] = {
622 { .type = "serial", .compatible = "xilinx,uartlite", },
623 {},
624};
625MODULE_DEVICE_TABLE(of, ulite_of_match);
626
627static struct of_platform_driver ulite_of_driver = { 604static struct of_platform_driver ulite_of_driver = {
628 .owner = THIS_MODULE, 605 .owner = THIS_MODULE,
629 .name = "uartlite", 606 .name = "uartlite",
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index e38d3b7c3ad7..7b3a8423f485 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -459,8 +459,8 @@ static int __devexit xilinxfb_of_remove(struct of_device *op)
459} 459}
460 460
461/* Match table for of_platform binding */ 461/* Match table for of_platform binding */
462static struct of_device_id __devinit xilinxfb_of_match[] = { 462static struct of_device_id xilinxfb_of_match[] __devinitdata = {
463 { .compatible = "xilinx,ml300-fb", }, 463 { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
464 {}, 464 {},
465}; 465};
466MODULE_DEVICE_TABLE(of, xilinxfb_of_match); 466MODULE_DEVICE_TABLE(of, xilinxfb_of_match);