aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v10/lib/usercopy.c14
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig8
-rw-r--r--arch/cris/arch-v32/drivers/Makefile1
-rw-r--r--arch/cris/arch-v32/drivers/i2c.h1
-rw-r--r--arch/cris/arch-v32/drivers/sync_serial.c1430
-rw-r--r--arch/cris/arch-v32/kernel/debugport.c82
-rw-r--r--arch/cris/arch-v32/kernel/time.c29
-rw-r--r--arch/cris/arch-v32/lib/usercopy.c15
-rw-r--r--arch/cris/arch-v32/mach-fs/pinmux.c152
-rw-r--r--arch/cris/include/arch-v32/mach-fs/mach/pinmux.h2
-rw-r--r--arch/cris/include/asm/Kbuild4
-rw-r--r--arch/cris/include/uapi/asm/Kbuild4
-rw-r--r--arch/cris/kernel/crisksyms.c9
-rw-r--r--arch/cris/kernel/module.c2
-rw-r--r--arch/cris/kernel/traps.c61
-rw-r--r--arch/cris/mm/init.c38
-rw-r--r--arch/cris/mm/ioremap.c3
17 files changed, 1040 insertions, 815 deletions
diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c
index b0a608da7bd1..b964c667aced 100644
--- a/arch/cris/arch-v10/lib/usercopy.c
+++ b/arch/cris/arch-v10/lib/usercopy.c
@@ -30,8 +30,7 @@
30/* Copy to userspace. This is based on the memcpy used for 30/* Copy to userspace. This is based on the memcpy used for
31 kernel-to-kernel copying; see "string.c". */ 31 kernel-to-kernel copying; see "string.c". */
32 32
33unsigned long 33unsigned long __copy_user(void __user *pdst, const void *psrc, unsigned long pn)
34__copy_user (void __user *pdst, const void *psrc, unsigned long pn)
35{ 34{
36 /* We want the parameters put in special registers. 35 /* We want the parameters put in special registers.
37 Make sure the compiler is able to make something useful of this. 36 Make sure the compiler is able to make something useful of this.
@@ -187,13 +186,14 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
187 186
188 return retn; 187 return retn;
189} 188}
189EXPORT_SYMBOL(__copy_user);
190 190
191/* Copy from user to kernel, zeroing the bytes that were inaccessible in 191/* Copy from user to kernel, zeroing the bytes that were inaccessible in
192 userland. The return-value is the number of bytes that were 192 userland. The return-value is the number of bytes that were
193 inaccessible. */ 193 inaccessible. */
194 194
195unsigned long 195unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
196__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn) 196 unsigned long pn)
197{ 197{
198 /* We want the parameters put in special registers. 198 /* We want the parameters put in special registers.
199 Make sure the compiler is able to make something useful of this. 199 Make sure the compiler is able to make something useful of this.
@@ -369,11 +369,10 @@ copy_exception_bytes:
369 369
370 return retn + n; 370 return retn + n;
371} 371}
372EXPORT_SYMBOL(__copy_user_zeroing);
372 373
373/* Zero userspace. */ 374/* Zero userspace. */
374 375unsigned long __do_clear_user(void __user *pto, unsigned long pn)
375unsigned long
376__do_clear_user (void __user *pto, unsigned long pn)
377{ 376{
378 /* We want the parameters put in special registers. 377 /* We want the parameters put in special registers.
379 Make sure the compiler is able to make something useful of this. 378 Make sure the compiler is able to make something useful of this.
@@ -521,3 +520,4 @@ __do_clear_user (void __user *pto, unsigned long pn)
521 520
522 return retn; 521 return retn;
523} 522}
523EXPORT_SYMBOL(__do_clear_user);
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index 15a9ed1d579c..4fc16b44fff2 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -108,6 +108,7 @@ config ETRAX_AXISFLASHMAP
108 select MTD_JEDECPROBE 108 select MTD_JEDECPROBE
109 select MTD_BLOCK 109 select MTD_BLOCK
110 select MTD_COMPLEX_MAPPINGS 110 select MTD_COMPLEX_MAPPINGS
111 select MTD_MTDRAM
111 help 112 help
112 This option enables MTD mapping of flash devices. Needed to use 113 This option enables MTD mapping of flash devices. Needed to use
113 flash memories. If unsure, say Y. 114 flash memories. If unsure, say Y.
@@ -358,13 +359,6 @@ config ETRAX_SPI_MMC
358 default MMC 359 default MMC
359 select SPI 360 select SPI
360 select MMC_SPI 361 select MMC_SPI
361 select ETRAX_SPI_MMC_BOARD
362
363# For the parts that can't be a module (due to restrictions in
364# framework elsewhere).
365config ETRAX_SPI_MMC_BOARD
366 boolean
367 default n
368 362
369# While the board info is MMC_SPI only, the drivers are written to be 363# While the board info is MMC_SPI only, the drivers are written to be
370# independent of MMC_SPI, so we'll keep SPI non-dependent on the 364# independent of MMC_SPI, so we'll keep SPI non-dependent on the
diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile
index 39aa3c117a86..15fbfefced2c 100644
--- a/arch/cris/arch-v32/drivers/Makefile
+++ b/arch/cris/arch-v32/drivers/Makefile
@@ -10,4 +10,3 @@ obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o
10obj-$(CONFIG_ETRAX_I2C) += i2c.o 10obj-$(CONFIG_ETRAX_I2C) += i2c.o
11obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o 11obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
12obj-$(CONFIG_PCI) += pci/ 12obj-$(CONFIG_PCI) += pci/
13obj-$(CONFIG_ETRAX_SPI_MMC_BOARD) += board_mmcspi.o
diff --git a/arch/cris/arch-v32/drivers/i2c.h b/arch/cris/arch-v32/drivers/i2c.h
index c073cf4ba016..d9cc856f89fb 100644
--- a/arch/cris/arch-v32/drivers/i2c.h
+++ b/arch/cris/arch-v32/drivers/i2c.h
@@ -2,7 +2,6 @@
2#include <linux/init.h> 2#include <linux/init.h>
3 3
4/* High level I2C actions */ 4/* High level I2C actions */
5int __init i2c_init(void);
6int i2c_write(unsigned char theSlave, void *data, size_t nbytes); 5int i2c_write(unsigned char theSlave, void *data, size_t nbytes);
7int i2c_read(unsigned char theSlave, void *data, size_t nbytes); 6int i2c_read(unsigned char theSlave, void *data, size_t nbytes);
8int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); 7int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
index 5a149134cfb5..08a313fc2241 100644
--- a/arch/cris/arch-v32/drivers/sync_serial.c
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -1,8 +1,7 @@
1/* 1/*
2 * Simple synchronous serial port driver for ETRAX FS and Artpec-3. 2 * Simple synchronous serial port driver for ETRAX FS and ARTPEC-3.
3 *
4 * Copyright (c) 2005 Axis Communications AB
5 * 3 *
4 * Copyright (c) 2005, 2008 Axis Communications AB
6 * Author: Mikael Starvik 5 * Author: Mikael Starvik
7 * 6 *
8 */ 7 */
@@ -16,16 +15,17 @@
16#include <linux/mutex.h> 15#include <linux/mutex.h>
17#include <linux/interrupt.h> 16#include <linux/interrupt.h>
18#include <linux/poll.h> 17#include <linux/poll.h>
19#include <linux/init.h> 18#include <linux/fs.h>
20#include <linux/timer.h> 19#include <linux/cdev.h>
21#include <linux/spinlock.h> 20#include <linux/device.h>
22#include <linux/wait.h> 21#include <linux/wait.h>
23 22
24#include <asm/io.h> 23#include <asm/io.h>
25#include <dma.h> 24#include <mach/dma.h>
26#include <pinmux.h> 25#include <pinmux.h>
27#include <hwregs/reg_rdwr.h> 26#include <hwregs/reg_rdwr.h>
28#include <hwregs/sser_defs.h> 27#include <hwregs/sser_defs.h>
28#include <hwregs/timer_defs.h>
29#include <hwregs/dma_defs.h> 29#include <hwregs/dma_defs.h>
30#include <hwregs/dma.h> 30#include <hwregs/dma.h>
31#include <hwregs/intr_vect_defs.h> 31#include <hwregs/intr_vect_defs.h>
@@ -59,22 +59,23 @@
59/* the rest of the data pointed out by Descr1 and set readp to the start */ 59/* the rest of the data pointed out by Descr1 and set readp to the start */
60/* of Descr2 */ 60/* of Descr2 */
61 61
62#define SYNC_SERIAL_MAJOR 125
63
64/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */ 62/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
65/* words can be handled */ 63/* words can be handled */
66#define IN_BUFFER_SIZE 12288 64#define IN_DESCR_SIZE SSP_INPUT_CHUNK_SIZE
67#define IN_DESCR_SIZE 256 65#define NBR_IN_DESCR (8*6)
68#define NBR_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE) 66#define IN_BUFFER_SIZE (IN_DESCR_SIZE * NBR_IN_DESCR)
69 67
70#define OUT_BUFFER_SIZE 1024*8
71#define NBR_OUT_DESCR 8 68#define NBR_OUT_DESCR 8
69#define OUT_BUFFER_SIZE (1024 * NBR_OUT_DESCR)
72 70
73#define DEFAULT_FRAME_RATE 0 71#define DEFAULT_FRAME_RATE 0
74#define DEFAULT_WORD_RATE 7 72#define DEFAULT_WORD_RATE 7
75 73
74/* To be removed when we move to pure udev. */
75#define SYNC_SERIAL_MAJOR 125
76
76/* NOTE: Enabling some debug will likely cause overrun or underrun, 77/* NOTE: Enabling some debug will likely cause overrun or underrun,
77 * especially if manual mode is use. 78 * especially if manual mode is used.
78 */ 79 */
79#define DEBUG(x) 80#define DEBUG(x)
80#define DEBUGREAD(x) 81#define DEBUGREAD(x)
@@ -85,11 +86,28 @@
85#define DEBUGTRDMA(x) 86#define DEBUGTRDMA(x)
86#define DEBUGOUTBUF(x) 87#define DEBUGOUTBUF(x)
87 88
88typedef struct sync_port 89enum syncser_irq_setup {
89{ 90 no_irq_setup = 0,
90 reg_scope_instances regi_sser; 91 dma_irq_setup = 1,
91 reg_scope_instances regi_dmain; 92 manual_irq_setup = 2,
92 reg_scope_instances regi_dmaout; 93};
94
95struct sync_port {
96 unsigned long regi_sser;
97 unsigned long regi_dmain;
98 unsigned long regi_dmaout;
99
100 /* Interrupt vectors. */
101 unsigned long dma_in_intr_vect; /* Used for DMA in. */
102 unsigned long dma_out_intr_vect; /* Used for DMA out. */
103 unsigned long syncser_intr_vect; /* Used when no DMA. */
104
105 /* DMA number for in and out. */
106 unsigned int dma_in_nbr;
107 unsigned int dma_out_nbr;
108
109 /* DMA owner. */
110 enum dma_owner req_dma;
93 111
94 char started; /* 1 if port has been started */ 112 char started; /* 1 if port has been started */
95 char port_nbr; /* Port 0 or 1 */ 113 char port_nbr; /* Port 0 or 1 */
@@ -99,22 +117,29 @@ typedef struct sync_port
99 char use_dma; /* 1 if port uses dma */ 117 char use_dma; /* 1 if port uses dma */
100 char tr_running; 118 char tr_running;
101 119
102 char init_irqs; 120 enum syncser_irq_setup init_irqs;
103 int output; 121 int output;
104 int input; 122 int input;
105 123
106 /* Next byte to be read by application */ 124 /* Next byte to be read by application */
107 volatile unsigned char *volatile readp; 125 unsigned char *readp;
108 /* Next byte to be written by etrax */ 126 /* Next byte to be written by etrax */
109 volatile unsigned char *volatile writep; 127 unsigned char *writep;
110 128
111 unsigned int in_buffer_size; 129 unsigned int in_buffer_size;
130 unsigned int in_buffer_len;
112 unsigned int inbufchunk; 131 unsigned int inbufchunk;
113 unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32))); 132 /* Data buffers for in and output. */
114 unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32))); 133 unsigned char out_buffer[OUT_BUFFER_SIZE] __aligned(32);
115 unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32))); 134 unsigned char in_buffer[IN_BUFFER_SIZE] __aligned(32);
116 struct dma_descr_data* next_rx_desc; 135 unsigned char flip[IN_BUFFER_SIZE] __aligned(32);
117 struct dma_descr_data* prev_rx_desc; 136 struct timespec timestamp[NBR_IN_DESCR];
137 struct dma_descr_data *next_rx_desc;
138 struct dma_descr_data *prev_rx_desc;
139
140 struct timeval last_timestamp;
141 int read_ts_idx;
142 int write_ts_idx;
118 143
119 /* Pointer to the first available descriptor in the ring, 144 /* Pointer to the first available descriptor in the ring,
120 * unless active_tr_descr == catch_tr_descr and a dma 145 * unless active_tr_descr == catch_tr_descr and a dma
@@ -135,114 +160,138 @@ typedef struct sync_port
135 /* Number of bytes currently locked for being read by DMA */ 160 /* Number of bytes currently locked for being read by DMA */
136 int out_buf_count; 161 int out_buf_count;
137 162
138 dma_descr_data in_descr[NBR_IN_DESCR] __attribute__ ((__aligned__(16))); 163 dma_descr_context in_context __aligned(32);
139 dma_descr_context in_context __attribute__ ((__aligned__(32))); 164 dma_descr_context out_context __aligned(32);
140 dma_descr_data out_descr[NBR_OUT_DESCR] 165 dma_descr_data in_descr[NBR_IN_DESCR] __aligned(16);
141 __attribute__ ((__aligned__(16))); 166 dma_descr_data out_descr[NBR_OUT_DESCR] __aligned(16);
142 dma_descr_context out_context __attribute__ ((__aligned__(32))); 167
143 wait_queue_head_t out_wait_q; 168 wait_queue_head_t out_wait_q;
144 wait_queue_head_t in_wait_q; 169 wait_queue_head_t in_wait_q;
145 170
146 spinlock_t lock; 171 spinlock_t lock;
147} sync_port; 172};
148 173
149static DEFINE_MUTEX(sync_serial_mutex); 174static DEFINE_MUTEX(sync_serial_mutex);
150static int etrax_sync_serial_init(void); 175static int etrax_sync_serial_init(void);
151static void initialize_port(int portnbr); 176static void initialize_port(int portnbr);
152static inline int sync_data_avail(struct sync_port *port); 177static inline int sync_data_avail(struct sync_port *port);
153 178
154static int sync_serial_open(struct inode *, struct file*); 179static int sync_serial_open(struct inode *, struct file *);
155static int sync_serial_release(struct inode*, struct file*); 180static int sync_serial_release(struct inode *, struct file *);
156static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); 181static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
157 182
158static int sync_serial_ioctl(struct file *, 183static long sync_serial_ioctl(struct file *file,
159 unsigned int cmd, unsigned long arg); 184 unsigned int cmd, unsigned long arg);
160static ssize_t sync_serial_write(struct file * file, const char * buf, 185static int sync_serial_ioctl_unlocked(struct file *file,
186 unsigned int cmd, unsigned long arg);
187static ssize_t sync_serial_write(struct file *file, const char __user *buf,
161 size_t count, loff_t *ppos); 188 size_t count, loff_t *ppos);
162static ssize_t sync_serial_read(struct file *file, char *buf, 189static ssize_t sync_serial_read(struct file *file, char __user *buf,
163 size_t count, loff_t *ppos); 190 size_t count, loff_t *ppos);
164 191
165#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \ 192#if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
166 defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \ 193 defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
167 (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \ 194 (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
168 defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)) 195 defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)))
169#define SYNC_SER_DMA 196#define SYNC_SER_DMA
197#else
198#define SYNC_SER_MANUAL
170#endif 199#endif
171 200
172static void send_word(sync_port* port);
173static void start_dma_out(struct sync_port *port, const char *data, int count);
174static void start_dma_in(sync_port* port);
175#ifdef SYNC_SER_DMA 201#ifdef SYNC_SER_DMA
202static void start_dma_out(struct sync_port *port, const char *data, int count);
203static void start_dma_in(struct sync_port *port);
176static irqreturn_t tr_interrupt(int irq, void *dev_id); 204static irqreturn_t tr_interrupt(int irq, void *dev_id);
177static irqreturn_t rx_interrupt(int irq, void *dev_id); 205static irqreturn_t rx_interrupt(int irq, void *dev_id);
178#endif 206#endif
179
180#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
181 !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
182 (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
183 !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
184#define SYNC_SER_MANUAL
185#endif
186#ifdef SYNC_SER_MANUAL 207#ifdef SYNC_SER_MANUAL
208static void send_word(struct sync_port *port);
187static irqreturn_t manual_interrupt(int irq, void *dev_id); 209static irqreturn_t manual_interrupt(int irq, void *dev_id);
188#endif 210#endif
189 211
190#ifdef CONFIG_ETRAXFS /* ETRAX FS */ 212#define artpec_pinmux_alloc_fixed crisv32_pinmux_alloc_fixed
191#define OUT_DMA_NBR 4 213#define artpec_request_dma crisv32_request_dma
192#define IN_DMA_NBR 5 214#define artpec_free_dma crisv32_free_dma
193#define PINMUX_SSER pinmux_sser0 215
194#define SYNCSER_INST regi_sser0 216#ifdef CONFIG_ETRAXFS
195#define SYNCSER_INTR_VECT SSER0_INTR_VECT 217/* ETRAX FS */
196#define OUT_DMA_INST regi_dma4 218#define DMA_OUT_NBR0 SYNC_SER0_TX_DMA_NBR
197#define IN_DMA_INST regi_dma5 219#define DMA_IN_NBR0 SYNC_SER0_RX_DMA_NBR
198#define DMA_OUT_INTR_VECT DMA4_INTR_VECT 220#define DMA_OUT_NBR1 SYNC_SER1_TX_DMA_NBR
199#define DMA_IN_INTR_VECT DMA5_INTR_VECT 221#define DMA_IN_NBR1 SYNC_SER1_RX_DMA_NBR
200#define REQ_DMA_SYNCSER dma_sser0 222#define PINMUX_SSER0 pinmux_sser0
201#else /* Artpec-3 */ 223#define PINMUX_SSER1 pinmux_sser1
202#define OUT_DMA_NBR 6 224#define SYNCSER_INST0 regi_sser0
203#define IN_DMA_NBR 7 225#define SYNCSER_INST1 regi_sser1
204#define PINMUX_SSER pinmux_sser 226#define SYNCSER_INTR_VECT0 SSER0_INTR_VECT
205#define SYNCSER_INST regi_sser 227#define SYNCSER_INTR_VECT1 SSER1_INTR_VECT
206#define SYNCSER_INTR_VECT SSER_INTR_VECT 228#define OUT_DMA_INST0 regi_dma4
207#define OUT_DMA_INST regi_dma6 229#define IN_DMA_INST0 regi_dma5
208#define IN_DMA_INST regi_dma7 230#define DMA_OUT_INTR_VECT0 DMA4_INTR_VECT
209#define DMA_OUT_INTR_VECT DMA6_INTR_VECT 231#define DMA_OUT_INTR_VECT1 DMA7_INTR_VECT
210#define DMA_IN_INTR_VECT DMA7_INTR_VECT 232#define DMA_IN_INTR_VECT0 DMA5_INTR_VECT
211#define REQ_DMA_SYNCSER dma_sser 233#define DMA_IN_INTR_VECT1 DMA6_INTR_VECT
234#define REQ_DMA_SYNCSER0 dma_sser0
235#define REQ_DMA_SYNCSER1 dma_sser1
236#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
237#define PORT1_DMA 1
238#else
239#define PORT1_DMA 0
240#endif
241#elif defined(CONFIG_CRIS_MACH_ARTPEC3)
242/* ARTPEC-3 */
243#define DMA_OUT_NBR0 SYNC_SER_TX_DMA_NBR
244#define DMA_IN_NBR0 SYNC_SER_RX_DMA_NBR
245#define PINMUX_SSER0 pinmux_sser
246#define SYNCSER_INST0 regi_sser
247#define SYNCSER_INTR_VECT0 SSER_INTR_VECT
248#define OUT_DMA_INST0 regi_dma6
249#define IN_DMA_INST0 regi_dma7
250#define DMA_OUT_INTR_VECT0 DMA6_INTR_VECT
251#define DMA_IN_INTR_VECT0 DMA7_INTR_VECT
252#define REQ_DMA_SYNCSER0 dma_sser
253#define REQ_DMA_SYNCSER1 dma_sser
212#endif 254#endif
213 255
214/* The ports */
215static struct sync_port ports[]=
216{
217 {
218 .regi_sser = SYNCSER_INST,
219 .regi_dmaout = OUT_DMA_INST,
220 .regi_dmain = IN_DMA_INST,
221#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA) 256#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
222 .use_dma = 1, 257#define PORT0_DMA 1
223#else 258#else
224 .use_dma = 0, 259#define PORT0_DMA 0
225#endif 260#endif
226 }
227#ifdef CONFIG_ETRAXFS
228 ,
229 261
262/* The ports */
263static struct sync_port ports[] = {
230 { 264 {
231 .regi_sser = regi_sser1, 265 .regi_sser = SYNCSER_INST0,
232 .regi_dmaout = regi_dma6, 266 .regi_dmaout = OUT_DMA_INST0,
233 .regi_dmain = regi_dma7, 267 .regi_dmain = IN_DMA_INST0,
234#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA) 268 .use_dma = PORT0_DMA,
235 .use_dma = 1, 269 .dma_in_intr_vect = DMA_IN_INTR_VECT0,
236#else 270 .dma_out_intr_vect = DMA_OUT_INTR_VECT0,
237 .use_dma = 0, 271 .dma_in_nbr = DMA_IN_NBR0,
238#endif 272 .dma_out_nbr = DMA_OUT_NBR0,
239 } 273 .req_dma = REQ_DMA_SYNCSER0,
274 .syncser_intr_vect = SYNCSER_INTR_VECT0,
275 },
276#ifdef CONFIG_ETRAXFS
277 {
278 .regi_sser = SYNCSER_INST1,
279 .regi_dmaout = regi_dma6,
280 .regi_dmain = regi_dma7,
281 .use_dma = PORT1_DMA,
282 .dma_in_intr_vect = DMA_IN_INTR_VECT1,
283 .dma_out_intr_vect = DMA_OUT_INTR_VECT1,
284 .dma_in_nbr = DMA_IN_NBR1,
285 .dma_out_nbr = DMA_OUT_NBR1,
286 .req_dma = REQ_DMA_SYNCSER1,
287 .syncser_intr_vect = SYNCSER_INTR_VECT1,
288 },
240#endif 289#endif
241}; 290};
242 291
243#define NBR_PORTS ARRAY_SIZE(ports) 292#define NBR_PORTS ARRAY_SIZE(ports)
244 293
245static const struct file_operations sync_serial_fops = { 294static const struct file_operations syncser_fops = {
246 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
247 .write = sync_serial_write, 296 .write = sync_serial_write,
248 .read = sync_serial_read, 297 .read = sync_serial_read,
@@ -253,61 +302,40 @@ static const struct file_operations sync_serial_fops = {
253 .llseek = noop_llseek, 302 .llseek = noop_llseek,
254}; 303};
255 304
256static int __init etrax_sync_serial_init(void) 305static dev_t syncser_first;
257{ 306static int minor_count = NBR_PORTS;
258 ports[0].enabled = 0; 307#define SYNCSER_NAME "syncser"
259#ifdef CONFIG_ETRAXFS 308static struct cdev *syncser_cdev;
260 ports[1].enabled = 0; 309static struct class *syncser_class;
261#endif
262 if (register_chrdev(SYNC_SERIAL_MAJOR, "sync serial",
263 &sync_serial_fops) < 0) {
264 printk(KERN_WARNING
265 "Unable to get major for synchronous serial port\n");
266 return -EBUSY;
267 }
268
269 /* Initialize Ports */
270#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
271 if (crisv32_pinmux_alloc_fixed(PINMUX_SSER)) {
272 printk(KERN_WARNING
273 "Unable to alloc pins for synchronous serial port 0\n");
274 return -EIO;
275 }
276 ports[0].enabled = 1;
277 initialize_port(0);
278#endif
279
280#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
281 if (crisv32_pinmux_alloc_fixed(pinmux_sser1)) {
282 printk(KERN_WARNING
283 "Unable to alloc pins for synchronous serial port 0\n");
284 return -EIO;
285 }
286 ports[1].enabled = 1;
287 initialize_port(1);
288#endif
289 310
290#ifdef CONFIG_ETRAXFS 311static void sync_serial_start_port(struct sync_port *port)
291 printk(KERN_INFO "ETRAX FS synchronous serial port driver\n"); 312{
292#else 313 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
293 printk(KERN_INFO "Artpec-3 synchronous serial port driver\n"); 314 reg_sser_rw_tr_cfg tr_cfg =
294#endif 315 REG_RD(sser, port->regi_sser, rw_tr_cfg);
295 return 0; 316 reg_sser_rw_rec_cfg rec_cfg =
317 REG_RD(sser, port->regi_sser, rw_rec_cfg);
318 cfg.en = regk_sser_yes;
319 tr_cfg.tr_en = regk_sser_yes;
320 rec_cfg.rec_en = regk_sser_yes;
321 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
322 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
323 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
324 port->started = 1;
296} 325}
297 326
298static void __init initialize_port(int portnbr) 327static void __init initialize_port(int portnbr)
299{ 328{
300 int __attribute__((unused)) i;
301 struct sync_port *port = &ports[portnbr]; 329 struct sync_port *port = &ports[portnbr];
302 reg_sser_rw_cfg cfg = {0}; 330 reg_sser_rw_cfg cfg = { 0 };
303 reg_sser_rw_frm_cfg frm_cfg = {0}; 331 reg_sser_rw_frm_cfg frm_cfg = { 0 };
304 reg_sser_rw_tr_cfg tr_cfg = {0}; 332 reg_sser_rw_tr_cfg tr_cfg = { 0 };
305 reg_sser_rw_rec_cfg rec_cfg = {0}; 333 reg_sser_rw_rec_cfg rec_cfg = { 0 };
306 334
307 DEBUG(printk(KERN_DEBUG "Init sync serial port %d\n", portnbr)); 335 DEBUG(pr_info("Init sync serial port %d\n", portnbr));
308 336
309 port->port_nbr = portnbr; 337 port->port_nbr = portnbr;
310 port->init_irqs = 1; 338 port->init_irqs = no_irq_setup;
311 339
312 port->out_rd_ptr = port->out_buffer; 340 port->out_rd_ptr = port->out_buffer;
313 port->out_buf_count = 0; 341 port->out_buf_count = 0;
@@ -318,10 +346,11 @@ static void __init initialize_port(int portnbr)
318 port->readp = port->flip; 346 port->readp = port->flip;
319 port->writep = port->flip; 347 port->writep = port->flip;
320 port->in_buffer_size = IN_BUFFER_SIZE; 348 port->in_buffer_size = IN_BUFFER_SIZE;
349 port->in_buffer_len = 0;
321 port->inbufchunk = IN_DESCR_SIZE; 350 port->inbufchunk = IN_DESCR_SIZE;
322 port->next_rx_desc = &port->in_descr[0]; 351
323 port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR-1]; 352 port->read_ts_idx = 0;
324 port->prev_rx_desc->eol = 1; 353 port->write_ts_idx = 0;
325 354
326 init_waitqueue_head(&port->out_wait_q); 355 init_waitqueue_head(&port->out_wait_q);
327 init_waitqueue_head(&port->in_wait_q); 356 init_waitqueue_head(&port->in_wait_q);
@@ -368,14 +397,18 @@ static void __init initialize_port(int portnbr)
368 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg); 397 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
369 398
370#ifdef SYNC_SER_DMA 399#ifdef SYNC_SER_DMA
371 /* Setup the descriptor ring for dma out/transmit. */ 400 {
372 for (i = 0; i < NBR_OUT_DESCR; i++) { 401 int i;
373 port->out_descr[i].wait = 0; 402 /* Setup the descriptor ring for dma out/transmit. */
374 port->out_descr[i].intr = 1; 403 for (i = 0; i < NBR_OUT_DESCR; i++) {
375 port->out_descr[i].eol = 0; 404 dma_descr_data *descr = &port->out_descr[i];
376 port->out_descr[i].out_eop = 0; 405 descr->wait = 0;
377 port->out_descr[i].next = 406 descr->intr = 1;
378 (dma_descr_data *)virt_to_phys(&port->out_descr[i+1]); 407 descr->eol = 0;
408 descr->out_eop = 0;
409 descr->next =
410 (dma_descr_data *)virt_to_phys(&descr[i+1]);
411 }
379 } 412 }
380 413
381 /* Create a ring from the list. */ 414 /* Create a ring from the list. */
@@ -391,201 +424,116 @@ static void __init initialize_port(int portnbr)
391 424
392static inline int sync_data_avail(struct sync_port *port) 425static inline int sync_data_avail(struct sync_port *port)
393{ 426{
394 int avail; 427 return port->in_buffer_len;
395 unsigned char *start;
396 unsigned char *end;
397
398 start = (unsigned char*)port->readp; /* cast away volatile */
399 end = (unsigned char*)port->writep; /* cast away volatile */
400 /* 0123456789 0123456789
401 * ----- - -----
402 * ^rp ^wp ^wp ^rp
403 */
404
405 if (end >= start)
406 avail = end - start;
407 else
408 avail = port->in_buffer_size - (start - end);
409 return avail;
410}
411
412static inline int sync_data_avail_to_end(struct sync_port *port)
413{
414 int avail;
415 unsigned char *start;
416 unsigned char *end;
417
418 start = (unsigned char*)port->readp; /* cast away volatile */
419 end = (unsigned char*)port->writep; /* cast away volatile */
420 /* 0123456789 0123456789
421 * ----- -----
422 * ^rp ^wp ^wp ^rp
423 */
424
425 if (end >= start)
426 avail = end - start;
427 else
428 avail = port->flip + port->in_buffer_size - start;
429 return avail;
430} 428}
431 429
432static int sync_serial_open(struct inode *inode, struct file *file) 430static int sync_serial_open(struct inode *inode, struct file *file)
433{ 431{
432 int ret = 0;
434 int dev = iminor(inode); 433 int dev = iminor(inode);
435 int ret = -EBUSY; 434 struct sync_port *port;
436 sync_port *port; 435#ifdef SYNC_SER_DMA
437 reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; 436 reg_dma_rw_cfg cfg = { .en = regk_dma_yes };
438 reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes}; 437 reg_dma_rw_intr_mask intr_mask = { .data = regk_dma_yes };
438#endif
439 439
440 mutex_lock(&sync_serial_mutex); 440 DEBUG(pr_debug("Open sync serial port %d\n", dev));
441 DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
442 441
443 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) 442 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
444 { 443 DEBUG(pr_info("Invalid minor %d\n", dev));
445 DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev)); 444 return -ENODEV;
446 ret = -ENODEV;
447 goto out;
448 } 445 }
449 port = &ports[dev]; 446 port = &ports[dev];
450 /* Allow open this device twice (assuming one reader and one writer) */ 447 /* Allow open this device twice (assuming one reader and one writer) */
451 if (port->busy == 2) 448 if (port->busy == 2) {
452 { 449 DEBUG(pr_info("syncser%d is busy\n", dev));
453 DEBUG(printk(KERN_DEBUG "Device is busy.. \n")); 450 return -EBUSY;
454 goto out;
455 } 451 }
456 452
453 mutex_lock(&sync_serial_mutex);
457 454
458 if (port->init_irqs) { 455 /* Clear any stale date left in the flip buffer */
459 if (port->use_dma) { 456 port->readp = port->writep = port->flip;
460 if (port == &ports[0]) { 457 port->in_buffer_len = 0;
461#ifdef SYNC_SER_DMA 458 port->read_ts_idx = 0;
462 if (request_irq(DMA_OUT_INTR_VECT, 459 port->write_ts_idx = 0;
463 tr_interrupt, 460
464 0, 461 if (port->init_irqs != no_irq_setup) {
465 "synchronous serial 0 dma tr", 462 /* Init only on first call. */
466 &ports[0])) { 463 port->busy++;
467 printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ"); 464 mutex_unlock(&sync_serial_mutex);
468 goto out; 465 return 0;
469 } else if (request_irq(DMA_IN_INTR_VECT, 466 }
470 rx_interrupt, 467 if (port->use_dma) {
471 0,
472 "synchronous serial 1 dma rx",
473 &ports[0])) {
474 free_irq(DMA_OUT_INTR_VECT, &port[0]);
475 printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
476 goto out;
477 } else if (crisv32_request_dma(OUT_DMA_NBR,
478 "synchronous serial 0 dma tr",
479 DMA_VERBOSE_ON_ERROR,
480 0,
481 REQ_DMA_SYNCSER)) {
482 free_irq(DMA_OUT_INTR_VECT, &port[0]);
483 free_irq(DMA_IN_INTR_VECT, &port[0]);
484 printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel");
485 goto out;
486 } else if (crisv32_request_dma(IN_DMA_NBR,
487 "synchronous serial 0 dma rec",
488 DMA_VERBOSE_ON_ERROR,
489 0,
490 REQ_DMA_SYNCSER)) {
491 crisv32_free_dma(OUT_DMA_NBR);
492 free_irq(DMA_OUT_INTR_VECT, &port[0]);
493 free_irq(DMA_IN_INTR_VECT, &port[0]);
494 printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel");
495 goto out;
496 }
497#endif
498 }
499#ifdef CONFIG_ETRAXFS
500 else if (port == &ports[1]) {
501#ifdef SYNC_SER_DMA 468#ifdef SYNC_SER_DMA
502 if (request_irq(DMA6_INTR_VECT, 469 const char *tmp;
503 tr_interrupt, 470 DEBUG(pr_info("Using DMA for syncser%d\n", dev));
504 0, 471
505 "synchronous serial 1 dma tr", 472 tmp = dev == 0 ? "syncser0 tx" : "syncser1 tx";
506 &ports[1])) { 473 if (request_irq(port->dma_out_intr_vect, tr_interrupt, 0,
507 printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ"); 474 tmp, port)) {
508 goto out; 475 pr_err("Can't alloc syncser%d TX IRQ", dev);
509 } else if (request_irq(DMA7_INTR_VECT, 476 ret = -EBUSY;
510 rx_interrupt, 477 goto unlock_and_exit;
511 0, 478 }
512 "synchronous serial 1 dma rx", 479 if (artpec_request_dma(port->dma_out_nbr, tmp,
513 &ports[1])) { 480 DMA_VERBOSE_ON_ERROR, 0, port->req_dma)) {
514 free_irq(DMA6_INTR_VECT, &ports[1]); 481 free_irq(port->dma_out_intr_vect, port);
515 printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ"); 482 pr_err("Can't alloc syncser%d TX DMA", dev);
516 goto out; 483 ret = -EBUSY;
517 } else if (crisv32_request_dma( 484 goto unlock_and_exit;
518 SYNC_SER1_TX_DMA_NBR, 485 }
519 "synchronous serial 1 dma tr", 486 tmp = dev == 0 ? "syncser0 rx" : "syncser1 rx";
520 DMA_VERBOSE_ON_ERROR, 487 if (request_irq(port->dma_in_intr_vect, rx_interrupt, 0,
521 0, 488 tmp, port)) {
522 dma_sser1)) { 489 artpec_free_dma(port->dma_out_nbr);
523 free_irq(DMA6_INTR_VECT, &ports[1]); 490 free_irq(port->dma_out_intr_vect, port);
524 free_irq(DMA7_INTR_VECT, &ports[1]); 491 pr_err("Can't alloc syncser%d RX IRQ", dev);
525 printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel"); 492 ret = -EBUSY;
526 goto out; 493 goto unlock_and_exit;
527 } else if (crisv32_request_dma( 494 }
528 SYNC_SER1_RX_DMA_NBR, 495 if (artpec_request_dma(port->dma_in_nbr, tmp,
529 "synchronous serial 3 dma rec", 496 DMA_VERBOSE_ON_ERROR, 0, port->req_dma)) {
530 DMA_VERBOSE_ON_ERROR, 497 artpec_free_dma(port->dma_out_nbr);
531 0, 498 free_irq(port->dma_out_intr_vect, port);
532 dma_sser1)) { 499 free_irq(port->dma_in_intr_vect, port);
533 crisv32_free_dma(SYNC_SER1_TX_DMA_NBR); 500 pr_err("Can't alloc syncser%d RX DMA", dev);
534 free_irq(DMA6_INTR_VECT, &ports[1]); 501 ret = -EBUSY;
535 free_irq(DMA7_INTR_VECT, &ports[1]); 502 goto unlock_and_exit;
536 printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel"); 503 }
537 goto out; 504 /* Enable DMAs */
538 } 505 REG_WR(dma, port->regi_dmain, rw_cfg, cfg);
539#endif 506 REG_WR(dma, port->regi_dmaout, rw_cfg, cfg);
540 } 507 /* Enable DMA IRQs */
508 REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask);
509 REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask);
510 /* Set up wordsize = 1 for DMAs. */
511 DMA_WR_CMD(port->regi_dmain, regk_dma_set_w_size1);
512 DMA_WR_CMD(port->regi_dmaout, regk_dma_set_w_size1);
513
514 start_dma_in(port);
515 port->init_irqs = dma_irq_setup;
541#endif 516#endif
542 /* Enable DMAs */ 517 } else { /* !port->use_dma */
543 REG_WR(dma, port->regi_dmain, rw_cfg, cfg);
544 REG_WR(dma, port->regi_dmaout, rw_cfg, cfg);
545 /* Enable DMA IRQs */
546 REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask);
547 REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask);
548 /* Set up wordsize = 1 for DMAs. */
549 DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1);
550 DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1);
551
552 start_dma_in(port);
553 port->init_irqs = 0;
554 } else { /* !port->use_dma */
555#ifdef SYNC_SER_MANUAL 518#ifdef SYNC_SER_MANUAL
556 if (port == &ports[0]) { 519 const char *tmp = dev == 0 ? "syncser0 manual irq" :
557 if (request_irq(SYNCSER_INTR_VECT, 520 "syncser1 manual irq";
558 manual_interrupt, 521 if (request_irq(port->syncser_intr_vect, manual_interrupt,
559 0, 522 0, tmp, port)) {
560 "synchronous serial manual irq", 523 pr_err("Can't alloc syncser%d manual irq",
561 &ports[0])) { 524 dev);
562 printk("Can't allocate sync serial manual irq"); 525 ret = -EBUSY;
563 goto out; 526 goto unlock_and_exit;
564 } 527 }
565 } 528 port->init_irqs = manual_irq_setup;
566#ifdef CONFIG_ETRAXFS
567 else if (port == &ports[1]) {
568 if (request_irq(SSER1_INTR_VECT,
569 manual_interrupt,
570 0,
571 "synchronous serial manual irq",
572 &ports[1])) {
573 printk(KERN_CRIT "Can't allocate sync serial manual irq");
574 goto out;
575 }
576 }
577#endif
578 port->init_irqs = 0;
579#else 529#else
580 panic("sync_serial: Manual mode not supported.\n"); 530 panic("sync_serial: Manual mode not supported\n");
581#endif /* SYNC_SER_MANUAL */ 531#endif /* SYNC_SER_MANUAL */
582 } 532 }
583
584 } /* port->init_irqs */
585
586 port->busy++; 533 port->busy++;
587 ret = 0; 534 ret = 0;
588out: 535
536unlock_and_exit:
589 mutex_unlock(&sync_serial_mutex); 537 mutex_unlock(&sync_serial_mutex);
590 return ret; 538 return ret;
591} 539}
@@ -593,18 +541,17 @@ out:
593static int sync_serial_release(struct inode *inode, struct file *file) 541static int sync_serial_release(struct inode *inode, struct file *file)
594{ 542{
595 int dev = iminor(inode); 543 int dev = iminor(inode);
596 sync_port *port; 544 struct sync_port *port;
597 545
598 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) 546 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
599 { 547 DEBUG(pr_info("Invalid minor %d\n", dev));
600 DEBUG(printk("Invalid minor %d\n", dev));
601 return -ENODEV; 548 return -ENODEV;
602 } 549 }
603 port = &ports[dev]; 550 port = &ports[dev];
604 if (port->busy) 551 if (port->busy)
605 port->busy--; 552 port->busy--;
606 if (!port->busy) 553 if (!port->busy)
607 /* XXX */ ; 554 /* XXX */;
608 return 0; 555 return 0;
609} 556}
610 557
@@ -612,21 +559,15 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
612{ 559{
613 int dev = iminor(file_inode(file)); 560 int dev = iminor(file_inode(file));
614 unsigned int mask = 0; 561 unsigned int mask = 0;
615 sync_port *port; 562 struct sync_port *port;
616 DEBUGPOLL( static unsigned int prev_mask = 0; ); 563 DEBUGPOLL(
564 static unsigned int prev_mask;
565 );
617 566
618 port = &ports[dev]; 567 port = &ports[dev];
619 568
620 if (!port->started) { 569 if (!port->started)
621 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg); 570 sync_serial_start_port(port);
622 reg_sser_rw_rec_cfg rec_cfg =
623 REG_RD(sser, port->regi_sser, rw_rec_cfg);
624 cfg.en = regk_sser_yes;
625 rec_cfg.rec_en = port->input;
626 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
627 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
628 port->started = 1;
629 }
630 571
631 poll_wait(file, &port->out_wait_q, wait); 572 poll_wait(file, &port->out_wait_q, wait);
632 poll_wait(file, &port->in_wait_q, wait); 573 poll_wait(file, &port->in_wait_q, wait);
@@ -645,33 +586,175 @@ static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
645 if (port->input && sync_data_avail(port) >= port->inbufchunk) 586 if (port->input && sync_data_avail(port) >= port->inbufchunk)
646 mask |= POLLIN | POLLRDNORM; 587 mask |= POLLIN | POLLRDNORM;
647 588
648 DEBUGPOLL(if (mask != prev_mask) 589 DEBUGPOLL(
649 printk("sync_serial_poll: mask 0x%08X %s %s\n", mask, 590 if (mask != prev_mask)
650 mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":""); 591 pr_info("sync_serial_poll: mask 0x%08X %s %s\n",
651 prev_mask = mask; 592 mask,
652 ); 593 mask & POLLOUT ? "POLLOUT" : "",
594 mask & POLLIN ? "POLLIN" : "");
595 prev_mask = mask;
596 );
653 return mask; 597 return mask;
654} 598}
655 599
656static int sync_serial_ioctl(struct file *file, 600static ssize_t __sync_serial_read(struct file *file,
657 unsigned int cmd, unsigned long arg) 601 char __user *buf,
602 size_t count,
603 loff_t *ppos,
604 struct timespec *ts)
605{
606 unsigned long flags;
607 int dev = MINOR(file->f_dentry->d_inode->i_rdev);
608 int avail;
609 struct sync_port *port;
610 unsigned char *start;
611 unsigned char *end;
612
613 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
614 DEBUG(pr_info("Invalid minor %d\n", dev));
615 return -ENODEV;
616 }
617 port = &ports[dev];
618
619 if (!port->started)
620 sync_serial_start_port(port);
621
622 /* Calculate number of available bytes */
623 /* Save pointers to avoid that they are modified by interrupt */
624 spin_lock_irqsave(&port->lock, flags);
625 start = port->readp;
626 end = port->writep;
627 spin_unlock_irqrestore(&port->lock, flags);
628
629 while ((start == end) && !port->in_buffer_len) {
630 if (file->f_flags & O_NONBLOCK)
631 return -EAGAIN;
632
633 wait_event_interruptible(port->in_wait_q,
634 !(start == end && !port->full));
635
636 if (signal_pending(current))
637 return -EINTR;
638
639 spin_lock_irqsave(&port->lock, flags);
640 start = port->readp;
641 end = port->writep;
642 spin_unlock_irqrestore(&port->lock, flags);
643 }
644
645 DEBUGREAD(pr_info("R%d c %d ri %u wi %u /%u\n",
646 dev, count,
647 start - port->flip, end - port->flip,
648 port->in_buffer_size));
649
650 /* Lazy read, never return wrapped data. */
651 if (end > start)
652 avail = end - start;
653 else
654 avail = port->flip + port->in_buffer_size - start;
655
656 count = count > avail ? avail : count;
657 if (copy_to_user(buf, start, count))
658 return -EFAULT;
659
660 /* If timestamp requested, find timestamp of first returned byte
661 * and copy it.
662 * N.B: Applications that request timstamps MUST read data in
663 * chunks that are multiples of IN_DESCR_SIZE.
664 * Otherwise the timestamps will not be aligned to the data read.
665 */
666 if (ts != NULL) {
667 int idx = port->read_ts_idx;
668 memcpy(ts, &port->timestamp[idx], sizeof(struct timespec));
669 port->read_ts_idx += count / IN_DESCR_SIZE;
670 if (port->read_ts_idx >= NBR_IN_DESCR)
671 port->read_ts_idx = 0;
672 }
673
674 spin_lock_irqsave(&port->lock, flags);
675 port->readp += count;
676 /* Check for wrap */
677 if (port->readp >= port->flip + port->in_buffer_size)
678 port->readp = port->flip;
679 port->in_buffer_len -= count;
680 port->full = 0;
681 spin_unlock_irqrestore(&port->lock, flags);
682
683 DEBUGREAD(pr_info("r %d\n", count));
684
685 return count;
686}
687
688static ssize_t sync_serial_input(struct file *file, unsigned long arg)
689{
690 struct ssp_request req;
691 int count;
692 int ret;
693
694 /* Copy the request structure from user-mode. */
695 ret = copy_from_user(&req, (struct ssp_request __user *)arg,
696 sizeof(struct ssp_request));
697
698 if (ret) {
699 DEBUG(pr_info("sync_serial_input copy from user failed\n"));
700 return -EFAULT;
701 }
702
703 /* To get the timestamps aligned, make sure that 'len'
704 * is a multiple of IN_DESCR_SIZE.
705 */
706 if ((req.len % IN_DESCR_SIZE) != 0) {
707 DEBUG(pr_info("sync_serial: req.len %x, IN_DESCR_SIZE %x\n",
708 req.len, IN_DESCR_SIZE));
709 return -EFAULT;
710 }
711
712 /* Do the actual read. */
713 /* Note that req.buf is actually a pointer to user space. */
714 count = __sync_serial_read(file, req.buf, req.len,
715 NULL, &req.ts);
716
717 if (count < 0) {
718 DEBUG(pr_info("sync_serial_input read failed\n"));
719 return count;
720 }
721
722 /* Copy the request back to user-mode. */
723 ret = copy_to_user((struct ssp_request __user *)arg, &req,
724 sizeof(struct ssp_request));
725
726 if (ret) {
727 DEBUG(pr_info("syncser input copy2user failed\n"));
728 return -EFAULT;
729 }
730
731 /* Return the number of bytes read. */
732 return count;
733}
734
735
736static int sync_serial_ioctl_unlocked(struct file *file,
737 unsigned int cmd, unsigned long arg)
658{ 738{
659 int return_val = 0; 739 int return_val = 0;
660 int dma_w_size = regk_dma_set_w_size1; 740 int dma_w_size = regk_dma_set_w_size1;
661 int dev = iminor(file_inode(file)); 741 int dev = iminor(file_inode(file));
662 sync_port *port; 742 struct sync_port *port;
663 reg_sser_rw_tr_cfg tr_cfg; 743 reg_sser_rw_tr_cfg tr_cfg;
664 reg_sser_rw_rec_cfg rec_cfg; 744 reg_sser_rw_rec_cfg rec_cfg;
665 reg_sser_rw_frm_cfg frm_cfg; 745 reg_sser_rw_frm_cfg frm_cfg;
666 reg_sser_rw_cfg gen_cfg; 746 reg_sser_rw_cfg gen_cfg;
667 reg_sser_rw_intr_mask intr_mask; 747 reg_sser_rw_intr_mask intr_mask;
668 748
669 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) 749 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
670 { 750 DEBUG(pr_info("Invalid minor %d\n", dev));
671 DEBUG(printk("Invalid minor %d\n", dev));
672 return -1; 751 return -1;
673 } 752 }
674 port = &ports[dev]; 753
754 if (cmd == SSP_INPUT)
755 return sync_serial_input(file, arg);
756
757 port = &ports[dev];
675 spin_lock_irq(&port->lock); 758 spin_lock_irq(&port->lock);
676 759
677 tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg); 760 tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
@@ -680,11 +763,9 @@ static int sync_serial_ioctl(struct file *file,
680 gen_cfg = REG_RD(sser, port->regi_sser, rw_cfg); 763 gen_cfg = REG_RD(sser, port->regi_sser, rw_cfg);
681 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); 764 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
682 765
683 switch(cmd) 766 switch (cmd) {
684 {
685 case SSP_SPEED: 767 case SSP_SPEED:
686 if (GET_SPEED(arg) == CODEC) 768 if (GET_SPEED(arg) == CODEC) {
687 {
688 unsigned int freq; 769 unsigned int freq;
689 770
690 gen_cfg.base_freq = regk_sser_f32; 771 gen_cfg.base_freq = regk_sser_f32;
@@ -701,15 +782,25 @@ static int sync_serial_ioctl(struct file *file,
701 case FREQ_256kHz: 782 case FREQ_256kHz:
702 gen_cfg.clk_div = 125 * 783 gen_cfg.clk_div = 125 *
703 (1 << (freq - FREQ_256kHz)) - 1; 784 (1 << (freq - FREQ_256kHz)) - 1;
704 break; 785 break;
705 case FREQ_512kHz: 786 case FREQ_512kHz:
706 gen_cfg.clk_div = 62; 787 gen_cfg.clk_div = 62;
707 break; 788 break;
708 case FREQ_1MHz: 789 case FREQ_1MHz:
709 case FREQ_2MHz: 790 case FREQ_2MHz:
710 case FREQ_4MHz: 791 case FREQ_4MHz:
711 gen_cfg.clk_div = 8 * (1 << freq) - 1; 792 gen_cfg.clk_div = 8 * (1 << freq) - 1;
712 break; 793 break;
794 }
795 } else if (GET_SPEED(arg) == CODEC_f32768) {
796 gen_cfg.base_freq = regk_sser_f32_768;
797 switch (GET_FREQ(arg)) {
798 case FREQ_4096kHz:
799 gen_cfg.clk_div = 7;
800 break;
801 default:
802 spin_unlock_irq(&port->lock);
803 return -EINVAL;
713 } 804 }
714 } else { 805 } else {
715 gen_cfg.base_freq = regk_sser_f29_493; 806 gen_cfg.base_freq = regk_sser_f29_493;
@@ -767,62 +858,64 @@ static int sync_serial_ioctl(struct file *file,
767 858
768 break; 859 break;
769 case SSP_MODE: 860 case SSP_MODE:
770 switch(arg) 861 switch (arg) {
771 { 862 case MASTER_OUTPUT:
772 case MASTER_OUTPUT: 863 port->output = 1;
773 port->output = 1; 864 port->input = 0;
774 port->input = 0; 865 frm_cfg.out_on = regk_sser_tr;
775 frm_cfg.out_on = regk_sser_tr; 866 frm_cfg.frame_pin_dir = regk_sser_out;
776 frm_cfg.frame_pin_dir = regk_sser_out; 867 gen_cfg.clk_dir = regk_sser_out;
777 gen_cfg.clk_dir = regk_sser_out; 868 break;
778 break; 869 case SLAVE_OUTPUT:
779 case SLAVE_OUTPUT: 870 port->output = 1;
780 port->output = 1; 871 port->input = 0;
781 port->input = 0; 872 frm_cfg.frame_pin_dir = regk_sser_in;
782 frm_cfg.frame_pin_dir = regk_sser_in; 873 gen_cfg.clk_dir = regk_sser_in;
783 gen_cfg.clk_dir = regk_sser_in; 874 break;
784 break; 875 case MASTER_INPUT:
785 case MASTER_INPUT: 876 port->output = 0;
786 port->output = 0; 877 port->input = 1;
787 port->input = 1; 878 frm_cfg.frame_pin_dir = regk_sser_out;
788 frm_cfg.frame_pin_dir = regk_sser_out; 879 frm_cfg.out_on = regk_sser_intern_tb;
789 frm_cfg.out_on = regk_sser_intern_tb; 880 gen_cfg.clk_dir = regk_sser_out;
790 gen_cfg.clk_dir = regk_sser_out; 881 break;
791 break; 882 case SLAVE_INPUT:
792 case SLAVE_INPUT: 883 port->output = 0;
793 port->output = 0; 884 port->input = 1;
794 port->input = 1; 885 frm_cfg.frame_pin_dir = regk_sser_in;
795 frm_cfg.frame_pin_dir = regk_sser_in; 886 gen_cfg.clk_dir = regk_sser_in;
796 gen_cfg.clk_dir = regk_sser_in; 887 break;
797 break; 888 case MASTER_BIDIR:
798 case MASTER_BIDIR: 889 port->output = 1;
799 port->output = 1; 890 port->input = 1;
800 port->input = 1; 891 frm_cfg.frame_pin_dir = regk_sser_out;
801 frm_cfg.frame_pin_dir = regk_sser_out; 892 frm_cfg.out_on = regk_sser_intern_tb;
802 frm_cfg.out_on = regk_sser_intern_tb; 893 gen_cfg.clk_dir = regk_sser_out;
803 gen_cfg.clk_dir = regk_sser_out; 894 break;
804 break; 895 case SLAVE_BIDIR:
805 case SLAVE_BIDIR: 896 port->output = 1;
806 port->output = 1; 897 port->input = 1;
807 port->input = 1; 898 frm_cfg.frame_pin_dir = regk_sser_in;
808 frm_cfg.frame_pin_dir = regk_sser_in; 899 gen_cfg.clk_dir = regk_sser_in;
809 gen_cfg.clk_dir = regk_sser_in; 900 break;
810 break; 901 default:
811 default: 902 spin_unlock_irq(&port->lock);
812 spin_unlock_irq(&port->lock); 903 return -EINVAL;
813 return -EINVAL;
814 } 904 }
815 if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT)) 905 if (!port->use_dma || arg == MASTER_OUTPUT ||
906 arg == SLAVE_OUTPUT)
816 intr_mask.rdav = regk_sser_yes; 907 intr_mask.rdav = regk_sser_yes;
817 break; 908 break;
818 case SSP_FRAME_SYNC: 909 case SSP_FRAME_SYNC:
819 if (arg & NORMAL_SYNC) { 910 if (arg & NORMAL_SYNC) {
820 frm_cfg.rec_delay = 1; 911 frm_cfg.rec_delay = 1;
821 frm_cfg.tr_delay = 1; 912 frm_cfg.tr_delay = 1;
822 } 913 } else if (arg & EARLY_SYNC)
823 else if (arg & EARLY_SYNC)
824 frm_cfg.rec_delay = frm_cfg.tr_delay = 0; 914 frm_cfg.rec_delay = frm_cfg.tr_delay = 0;
825 else if (arg & SECOND_WORD_SYNC) { 915 else if (arg & LATE_SYNC) {
916 frm_cfg.tr_delay = 2;
917 frm_cfg.rec_delay = 2;
918 } else if (arg & SECOND_WORD_SYNC) {
826 frm_cfg.rec_delay = 7; 919 frm_cfg.rec_delay = 7;
827 frm_cfg.tr_delay = 1; 920 frm_cfg.tr_delay = 1;
828 } 921 }
@@ -914,15 +1007,12 @@ static int sync_serial_ioctl(struct file *file,
914 frm_cfg.type = regk_sser_level; 1007 frm_cfg.type = regk_sser_level;
915 frm_cfg.tr_delay = 1; 1008 frm_cfg.tr_delay = 1;
916 frm_cfg.level = regk_sser_neg_lo; 1009 frm_cfg.level = regk_sser_neg_lo;
917 if (arg & SPI_SLAVE) 1010 if (arg & SPI_SLAVE) {
918 {
919 rec_cfg.clk_pol = regk_sser_neg; 1011 rec_cfg.clk_pol = regk_sser_neg;
920 gen_cfg.clk_dir = regk_sser_in; 1012 gen_cfg.clk_dir = regk_sser_in;
921 port->input = 1; 1013 port->input = 1;
922 port->output = 0; 1014 port->output = 0;
923 } 1015 } else {
924 else
925 {
926 gen_cfg.out_clk_pol = regk_sser_pos; 1016 gen_cfg.out_clk_pol = regk_sser_pos;
927 port->input = 0; 1017 port->input = 0;
928 port->output = 1; 1018 port->output = 1;
@@ -965,19 +1055,19 @@ static int sync_serial_ioctl(struct file *file,
965} 1055}
966 1056
967static long sync_serial_ioctl(struct file *file, 1057static long sync_serial_ioctl(struct file *file,
968 unsigned int cmd, unsigned long arg) 1058 unsigned int cmd, unsigned long arg)
969{ 1059{
970 long ret; 1060 long ret;
971 1061
972 mutex_lock(&sync_serial_mutex); 1062 mutex_lock(&sync_serial_mutex);
973 ret = sync_serial_ioctl_unlocked(file, cmd, arg); 1063 ret = sync_serial_ioctl_unlocked(file, cmd, arg);
974 mutex_unlock(&sync_serial_mutex); 1064 mutex_unlock(&sync_serial_mutex);
975 1065
976 return ret; 1066 return ret;
977} 1067}
978 1068
979/* NOTE: sync_serial_write does not support concurrency */ 1069/* NOTE: sync_serial_write does not support concurrency */
980static ssize_t sync_serial_write(struct file *file, const char *buf, 1070static ssize_t sync_serial_write(struct file *file, const char __user *buf,
981 size_t count, loff_t *ppos) 1071 size_t count, loff_t *ppos)
982{ 1072{
983 int dev = iminor(file_inode(file)); 1073 int dev = iminor(file_inode(file));
@@ -993,7 +1083,7 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
993 unsigned char *buf_stop_ptr; /* Last byte + 1 */ 1083 unsigned char *buf_stop_ptr; /* Last byte + 1 */
994 1084
995 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) { 1085 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
996 DEBUG(printk("Invalid minor %d\n", dev)); 1086 DEBUG(pr_info("Invalid minor %d\n", dev));
997 return -ENODEV; 1087 return -ENODEV;
998 } 1088 }
999 port = &ports[dev]; 1089 port = &ports[dev];
@@ -1006,9 +1096,9 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
1006 * |_________|___________________|________________________| 1096 * |_________|___________________|________________________|
1007 * ^ rd_ptr ^ wr_ptr 1097 * ^ rd_ptr ^ wr_ptr
1008 */ 1098 */
1009 DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu a: %p c: %p\n", 1099 DEBUGWRITE(pr_info("W d%d c %u a: %p c: %p\n",
1010 port->port_nbr, count, port->active_tr_descr, 1100 port->port_nbr, count, port->active_tr_descr,
1011 port->catch_tr_descr)); 1101 port->catch_tr_descr));
1012 1102
1013 /* Read variables that may be updated by interrupts */ 1103 /* Read variables that may be updated by interrupts */
1014 spin_lock_irqsave(&port->lock, flags); 1104 spin_lock_irqsave(&port->lock, flags);
@@ -1020,7 +1110,7 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
1020 if (port->tr_running && 1110 if (port->tr_running &&
1021 ((port->use_dma && port->active_tr_descr == port->catch_tr_descr) || 1111 ((port->use_dma && port->active_tr_descr == port->catch_tr_descr) ||
1022 out_buf_count >= OUT_BUFFER_SIZE)) { 1112 out_buf_count >= OUT_BUFFER_SIZE)) {
1023 DEBUGWRITE(printk(KERN_DEBUG "sser%d full\n", dev)); 1113 DEBUGWRITE(pr_info("sser%d full\n", dev));
1024 return -EAGAIN; 1114 return -EAGAIN;
1025 } 1115 }
1026 1116
@@ -1043,15 +1133,16 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
1043 if (copy_from_user(wr_ptr, buf, trunc_count)) 1133 if (copy_from_user(wr_ptr, buf, trunc_count))
1044 return -EFAULT; 1134 return -EFAULT;
1045 1135
1046 DEBUGOUTBUF(printk(KERN_DEBUG "%-4d + %-4d = %-4d %p %p %p\n", 1136 DEBUGOUTBUF(pr_info("%-4d + %-4d = %-4d %p %p %p\n",
1047 out_buf_count, trunc_count, 1137 out_buf_count, trunc_count,
1048 port->out_buf_count, port->out_buffer, 1138 port->out_buf_count, port->out_buffer,
1049 wr_ptr, buf_stop_ptr)); 1139 wr_ptr, buf_stop_ptr));
1050 1140
1051 /* Make sure transmitter/receiver is running */ 1141 /* Make sure transmitter/receiver is running */
1052 if (!port->started) { 1142 if (!port->started) {
1053 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg); 1143 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
1054 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg); 1144 reg_sser_rw_rec_cfg rec_cfg =
1145 REG_RD(sser, port->regi_sser, rw_rec_cfg);
1055 cfg.en = regk_sser_yes; 1146 cfg.en = regk_sser_yes;
1056 rec_cfg.rec_en = port->input; 1147 rec_cfg.rec_en = port->input;
1057 REG_WR(sser, port->regi_sser, rw_cfg, cfg); 1148 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
@@ -1068,8 +1159,11 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
1068 spin_lock_irqsave(&port->lock, flags); 1159 spin_lock_irqsave(&port->lock, flags);
1069 port->out_buf_count += trunc_count; 1160 port->out_buf_count += trunc_count;
1070 if (port->use_dma) { 1161 if (port->use_dma) {
1162#ifdef SYNC_SER_DMA
1071 start_dma_out(port, wr_ptr, trunc_count); 1163 start_dma_out(port, wr_ptr, trunc_count);
1164#endif
1072 } else if (!port->tr_running) { 1165 } else if (!port->tr_running) {
1166#ifdef SYNC_SER_MANUAL
1073 reg_sser_rw_intr_mask intr_mask; 1167 reg_sser_rw_intr_mask intr_mask;
1074 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); 1168 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
1075 /* Start sender by writing data */ 1169 /* Start sender by writing data */
@@ -1077,14 +1171,15 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
1077 /* and enable transmitter ready IRQ */ 1171 /* and enable transmitter ready IRQ */
1078 intr_mask.trdy = 1; 1172 intr_mask.trdy = 1;
1079 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); 1173 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
1174#endif
1080 } 1175 }
1081 spin_unlock_irqrestore(&port->lock, flags); 1176 spin_unlock_irqrestore(&port->lock, flags);
1082 1177
1083 /* Exit if non blocking */ 1178 /* Exit if non blocking */
1084 if (file->f_flags & O_NONBLOCK) { 1179 if (file->f_flags & O_NONBLOCK) {
1085 DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu %08x\n", 1180 DEBUGWRITE(pr_info("w d%d c %u %08x\n",
1086 port->port_nbr, trunc_count, 1181 port->port_nbr, trunc_count,
1087 REG_RD_INT(dma, port->regi_dmaout, r_intr))); 1182 REG_RD_INT(dma, port->regi_dmaout, r_intr)));
1088 return trunc_count; 1183 return trunc_count;
1089 } 1184 }
1090 1185
@@ -1094,105 +1189,32 @@ static ssize_t sync_serial_write(struct file *file, const char *buf,
1094 if (signal_pending(current)) 1189 if (signal_pending(current))
1095 return -EINTR; 1190 return -EINTR;
1096 1191
1097 DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n", 1192 DEBUGWRITE(pr_info("w d%d c %u\n", port->port_nbr, trunc_count));
1098 port->port_nbr, trunc_count));
1099 return trunc_count; 1193 return trunc_count;
1100} 1194}
1101 1195
1102static ssize_t sync_serial_read(struct file * file, char * buf, 1196static ssize_t sync_serial_read(struct file *file, char __user *buf,
1103 size_t count, loff_t *ppos) 1197 size_t count, loff_t *ppos)
1104{ 1198{
1105 int dev = iminor(file_inode(file)); 1199 return __sync_serial_read(file, buf, count, ppos, NULL);
1106 int avail;
1107 sync_port *port;
1108 unsigned char* start;
1109 unsigned char* end;
1110 unsigned long flags;
1111
1112 if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
1113 {
1114 DEBUG(printk("Invalid minor %d\n", dev));
1115 return -ENODEV;
1116 }
1117 port = &ports[dev];
1118
1119 DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->flip, port->writep - port->flip, port->in_buffer_size));
1120
1121 if (!port->started)
1122 {
1123 reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
1124 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
1125 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
1126 cfg.en = regk_sser_yes;
1127 tr_cfg.tr_en = regk_sser_yes;
1128 rec_cfg.rec_en = regk_sser_yes;
1129 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
1130 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
1131 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
1132 port->started = 1;
1133 }
1134
1135 /* Calculate number of available bytes */
1136 /* Save pointers to avoid that they are modified by interrupt */
1137 spin_lock_irqsave(&port->lock, flags);
1138 start = (unsigned char*)port->readp; /* cast away volatile */
1139 end = (unsigned char*)port->writep; /* cast away volatile */
1140 spin_unlock_irqrestore(&port->lock, flags);
1141 while ((start == end) && !port->full) /* No data */
1142 {
1143 DEBUGREAD(printk(KERN_DEBUG "&"));
1144 if (file->f_flags & O_NONBLOCK)
1145 return -EAGAIN;
1146
1147 wait_event_interruptible(port->in_wait_q,
1148 !(start == end && !port->full));
1149 if (signal_pending(current))
1150 return -EINTR;
1151
1152 spin_lock_irqsave(&port->lock, flags);
1153 start = (unsigned char*)port->readp; /* cast away volatile */
1154 end = (unsigned char*)port->writep; /* cast away volatile */
1155 spin_unlock_irqrestore(&port->lock, flags);
1156 }
1157
1158 /* Lazy read, never return wrapped data. */
1159 if (port->full)
1160 avail = port->in_buffer_size;
1161 else if (end > start)
1162 avail = end - start;
1163 else
1164 avail = port->flip + port->in_buffer_size - start;
1165
1166 count = count > avail ? avail : count;
1167 if (copy_to_user(buf, start, count))
1168 return -EFAULT;
1169 /* Disable interrupts while updating readp */
1170 spin_lock_irqsave(&port->lock, flags);
1171 port->readp += count;
1172 if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
1173 port->readp = port->flip;
1174 port->full = 0;
1175 spin_unlock_irqrestore(&port->lock, flags);
1176 DEBUGREAD(printk("r %d\n", count));
1177 return count;
1178} 1200}
1179 1201
1180static void send_word(sync_port* port) 1202#ifdef SYNC_SER_MANUAL
1203static void send_word(struct sync_port *port)
1181{ 1204{
1182 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg); 1205 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
1183 reg_sser_rw_tr_data tr_data = {0}; 1206 reg_sser_rw_tr_data tr_data = {0};
1184 1207
1185 switch(tr_cfg.sample_size) 1208 switch (tr_cfg.sample_size) {
1209 case 8:
1210 port->out_buf_count--;
1211 tr_data.data = *port->out_rd_ptr++;
1212 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1213 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1214 port->out_rd_ptr = port->out_buffer;
1215 break;
1216 case 12:
1186 { 1217 {
1187 case 8:
1188 port->out_buf_count--;
1189 tr_data.data = *port->out_rd_ptr++;
1190 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1191 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1192 port->out_rd_ptr = port->out_buffer;
1193 break;
1194 case 12:
1195 {
1196 int data = (*port->out_rd_ptr++) << 8; 1218 int data = (*port->out_rd_ptr++) << 8;
1197 data |= *port->out_rd_ptr++; 1219 data |= *port->out_rd_ptr++;
1198 port->out_buf_count -= 2; 1220 port->out_buf_count -= 2;
@@ -1200,8 +1222,8 @@ static void send_word(sync_port* port)
1200 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data); 1222 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1201 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE) 1223 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1202 port->out_rd_ptr = port->out_buffer; 1224 port->out_rd_ptr = port->out_buffer;
1225 break;
1203 } 1226 }
1204 break;
1205 case 16: 1227 case 16:
1206 port->out_buf_count -= 2; 1228 port->out_buf_count -= 2;
1207 tr_data.data = *(unsigned short *)port->out_rd_ptr; 1229 tr_data.data = *(unsigned short *)port->out_rd_ptr;
@@ -1233,27 +1255,28 @@ static void send_word(sync_port* port)
1233 break; 1255 break;
1234 } 1256 }
1235} 1257}
1258#endif
1236 1259
1237static void start_dma_out(struct sync_port *port, 1260#ifdef SYNC_SER_DMA
1238 const char *data, int count) 1261static void start_dma_out(struct sync_port *port, const char *data, int count)
1239{ 1262{
1240 port->active_tr_descr->buf = (char *) virt_to_phys((char *) data); 1263 port->active_tr_descr->buf = (char *)virt_to_phys((char *)data);
1241 port->active_tr_descr->after = port->active_tr_descr->buf + count; 1264 port->active_tr_descr->after = port->active_tr_descr->buf + count;
1242 port->active_tr_descr->intr = 1; 1265 port->active_tr_descr->intr = 1;
1243 1266
1244 port->active_tr_descr->eol = 1; 1267 port->active_tr_descr->eol = 1;
1245 port->prev_tr_descr->eol = 0; 1268 port->prev_tr_descr->eol = 0;
1246 1269
1247 DEBUGTRDMA(printk(KERN_DEBUG "Inserting eolr:%p eol@:%p\n", 1270 DEBUGTRDMA(pr_info("Inserting eolr:%p eol@:%p\n",
1248 port->prev_tr_descr, port->active_tr_descr)); 1271 port->prev_tr_descr, port->active_tr_descr));
1249 port->prev_tr_descr = port->active_tr_descr; 1272 port->prev_tr_descr = port->active_tr_descr;
1250 port->active_tr_descr = phys_to_virt((int) port->active_tr_descr->next); 1273 port->active_tr_descr = phys_to_virt((int)port->active_tr_descr->next);
1251 1274
1252 if (!port->tr_running) { 1275 if (!port->tr_running) {
1253 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, 1276 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser,
1254 rw_tr_cfg); 1277 rw_tr_cfg);
1255 1278
1256 port->out_context.next = 0; 1279 port->out_context.next = NULL;
1257 port->out_context.saved_data = 1280 port->out_context.saved_data =
1258 (dma_descr_data *)virt_to_phys(port->prev_tr_descr); 1281 (dma_descr_data *)virt_to_phys(port->prev_tr_descr);
1259 port->out_context.saved_data_buf = port->prev_tr_descr->buf; 1282 port->out_context.saved_data_buf = port->prev_tr_descr->buf;
@@ -1263,57 +1286,58 @@ static void start_dma_out(struct sync_port *port,
1263 1286
1264 tr_cfg.tr_en = regk_sser_yes; 1287 tr_cfg.tr_en = regk_sser_yes;
1265 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg); 1288 REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
1266 DEBUGTRDMA(printk(KERN_DEBUG "dma s\n");); 1289 DEBUGTRDMA(pr_info(KERN_INFO "dma s\n"););
1267 } else { 1290 } else {
1268 DMA_CONTINUE_DATA(port->regi_dmaout); 1291 DMA_CONTINUE_DATA(port->regi_dmaout);
1269 DEBUGTRDMA(printk(KERN_DEBUG "dma c\n");); 1292 DEBUGTRDMA(pr_info("dma c\n"););
1270 } 1293 }
1271 1294
1272 port->tr_running = 1; 1295 port->tr_running = 1;
1273} 1296}
1274 1297
1275static void start_dma_in(sync_port *port) 1298static void start_dma_in(struct sync_port *port)
1276{ 1299{
1277 int i; 1300 int i;
1278 char *buf; 1301 char *buf;
1302 unsigned long flags;
1303 spin_lock_irqsave(&port->lock, flags);
1279 port->writep = port->flip; 1304 port->writep = port->flip;
1305 spin_unlock_irqrestore(&port->lock, flags);
1280 1306
1281 if (port->writep > port->flip + port->in_buffer_size) { 1307 buf = (char *)virt_to_phys(port->in_buffer);
1282 panic("Offset too large in sync serial driver\n");
1283 return;
1284 }
1285 buf = (char*)virt_to_phys(port->in_buffer);
1286 for (i = 0; i < NBR_IN_DESCR; i++) { 1308 for (i = 0; i < NBR_IN_DESCR; i++) {
1287 port->in_descr[i].buf = buf; 1309 port->in_descr[i].buf = buf;
1288 port->in_descr[i].after = buf + port->inbufchunk; 1310 port->in_descr[i].after = buf + port->inbufchunk;
1289 port->in_descr[i].intr = 1; 1311 port->in_descr[i].intr = 1;
1290 port->in_descr[i].next = (dma_descr_data*)virt_to_phys(&port->in_descr[i+1]); 1312 port->in_descr[i].next =
1313 (dma_descr_data *)virt_to_phys(&port->in_descr[i+1]);
1291 port->in_descr[i].buf = buf; 1314 port->in_descr[i].buf = buf;
1292 buf += port->inbufchunk; 1315 buf += port->inbufchunk;
1293 } 1316 }
1294 /* Link the last descriptor to the first */ 1317 /* Link the last descriptor to the first */
1295 port->in_descr[i-1].next = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); 1318 port->in_descr[i-1].next =
1319 (dma_descr_data *)virt_to_phys(&port->in_descr[0]);
1296 port->in_descr[i-1].eol = regk_sser_yes; 1320 port->in_descr[i-1].eol = regk_sser_yes;
1297 port->next_rx_desc = &port->in_descr[0]; 1321 port->next_rx_desc = &port->in_descr[0];
1298 port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR - 1]; 1322 port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR - 1];
1299 port->in_context.saved_data = (dma_descr_data*)virt_to_phys(&port->in_descr[0]); 1323 port->in_context.saved_data =
1324 (dma_descr_data *)virt_to_phys(&port->in_descr[0]);
1300 port->in_context.saved_data_buf = port->in_descr[0].buf; 1325 port->in_context.saved_data_buf = port->in_descr[0].buf;
1301 DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context)); 1326 DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context));
1302} 1327}
1303 1328
1304#ifdef SYNC_SER_DMA
1305static irqreturn_t tr_interrupt(int irq, void *dev_id) 1329static irqreturn_t tr_interrupt(int irq, void *dev_id)
1306{ 1330{
1307 reg_dma_r_masked_intr masked; 1331 reg_dma_r_masked_intr masked;
1308 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes}; 1332 reg_dma_rw_ack_intr ack_intr = { .data = regk_dma_yes };
1309 reg_dma_rw_stat stat; 1333 reg_dma_rw_stat stat;
1310 int i; 1334 int i;
1311 int found = 0; 1335 int found = 0;
1312 int stop_sser = 0; 1336 int stop_sser = 0;
1313 1337
1314 for (i = 0; i < NBR_PORTS; i++) { 1338 for (i = 0; i < NBR_PORTS; i++) {
1315 sync_port *port = &ports[i]; 1339 struct sync_port *port = &ports[i];
1316 if (!port->enabled || !port->use_dma) 1340 if (!port->enabled || !port->use_dma)
1317 continue; 1341 continue;
1318 1342
1319 /* IRQ active for the port? */ 1343 /* IRQ active for the port? */
@@ -1338,19 +1362,20 @@ static irqreturn_t tr_interrupt(int irq, void *dev_id)
1338 int sent; 1362 int sent;
1339 sent = port->catch_tr_descr->after - 1363 sent = port->catch_tr_descr->after -
1340 port->catch_tr_descr->buf; 1364 port->catch_tr_descr->buf;
1341 DEBUGTXINT(printk(KERN_DEBUG "%-4d - %-4d = %-4d\t" 1365 DEBUGTXINT(pr_info("%-4d - %-4d = %-4d\t"
1342 "in descr %p (ac: %p)\n", 1366 "in descr %p (ac: %p)\n",
1343 port->out_buf_count, sent, 1367 port->out_buf_count, sent,
1344 port->out_buf_count - sent, 1368 port->out_buf_count - sent,
1345 port->catch_tr_descr, 1369 port->catch_tr_descr,
1346 port->active_tr_descr);); 1370 port->active_tr_descr););
1347 port->out_buf_count -= sent; 1371 port->out_buf_count -= sent;
1348 port->catch_tr_descr = 1372 port->catch_tr_descr =
1349 phys_to_virt((int) port->catch_tr_descr->next); 1373 phys_to_virt((int) port->catch_tr_descr->next);
1350 port->out_rd_ptr = 1374 port->out_rd_ptr =
1351 phys_to_virt((int) port->catch_tr_descr->buf); 1375 phys_to_virt((int) port->catch_tr_descr->buf);
1352 } else { 1376 } else {
1353 int i, sent; 1377 reg_sser_rw_tr_cfg tr_cfg;
1378 int j, sent;
1354 /* EOL handler. 1379 /* EOL handler.
1355 * Note that if an EOL was encountered during the irq 1380 * Note that if an EOL was encountered during the irq
1356 * locked section of sync_ser_write the DMA will be 1381 * locked section of sync_ser_write the DMA will be
@@ -1358,11 +1383,11 @@ static irqreturn_t tr_interrupt(int irq, void *dev_id)
1358 * The remaining descriptors will be traversed by 1383 * The remaining descriptors will be traversed by
1359 * the descriptor interrupts as usual. 1384 * the descriptor interrupts as usual.
1360 */ 1385 */
1361 i = 0; 1386 j = 0;
1362 while (!port->catch_tr_descr->eol) { 1387 while (!port->catch_tr_descr->eol) {
1363 sent = port->catch_tr_descr->after - 1388 sent = port->catch_tr_descr->after -
1364 port->catch_tr_descr->buf; 1389 port->catch_tr_descr->buf;
1365 DEBUGOUTBUF(printk(KERN_DEBUG 1390 DEBUGOUTBUF(pr_info(
1366 "traversing descr %p -%d (%d)\n", 1391 "traversing descr %p -%d (%d)\n",
1367 port->catch_tr_descr, 1392 port->catch_tr_descr,
1368 sent, 1393 sent,
@@ -1370,16 +1395,15 @@ static irqreturn_t tr_interrupt(int irq, void *dev_id)
1370 port->out_buf_count -= sent; 1395 port->out_buf_count -= sent;
1371 port->catch_tr_descr = phys_to_virt( 1396 port->catch_tr_descr = phys_to_virt(
1372 (int)port->catch_tr_descr->next); 1397 (int)port->catch_tr_descr->next);
1373 i++; 1398 j++;
1374 if (i >= NBR_OUT_DESCR) { 1399 if (j >= NBR_OUT_DESCR) {
1375 /* TODO: Reset and recover */ 1400 /* TODO: Reset and recover */
1376 panic("sync_serial: missing eol"); 1401 panic("sync_serial: missing eol");
1377 } 1402 }
1378 } 1403 }
1379 sent = port->catch_tr_descr->after - 1404 sent = port->catch_tr_descr->after -
1380 port->catch_tr_descr->buf; 1405 port->catch_tr_descr->buf;
1381 DEBUGOUTBUF(printk(KERN_DEBUG 1406 DEBUGOUTBUF(pr_info("eol at descr %p -%d (%d)\n",
1382 "eol at descr %p -%d (%d)\n",
1383 port->catch_tr_descr, 1407 port->catch_tr_descr,
1384 sent, 1408 sent,
1385 port->out_buf_count)); 1409 port->out_buf_count));
@@ -1394,15 +1418,13 @@ static irqreturn_t tr_interrupt(int irq, void *dev_id)
1394 OUT_BUFFER_SIZE) 1418 OUT_BUFFER_SIZE)
1395 port->out_rd_ptr = port->out_buffer; 1419 port->out_rd_ptr = port->out_buffer;
1396 1420
1397 reg_sser_rw_tr_cfg tr_cfg = 1421 tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
1398 REG_RD(sser, port->regi_sser, rw_tr_cfg); 1422 DEBUGTXINT(pr_info(
1399 DEBUGTXINT(printk(KERN_DEBUG
1400 "tr_int DMA stop %d, set catch @ %p\n", 1423 "tr_int DMA stop %d, set catch @ %p\n",
1401 port->out_buf_count, 1424 port->out_buf_count,
1402 port->active_tr_descr)); 1425 port->active_tr_descr));
1403 if (port->out_buf_count != 0) 1426 if (port->out_buf_count != 0)
1404 printk(KERN_CRIT "sync_ser: buffer not " 1427 pr_err("sync_ser: buf not empty after eol\n");
1405 "empty after eol.\n");
1406 port->catch_tr_descr = port->active_tr_descr; 1428 port->catch_tr_descr = port->active_tr_descr;
1407 port->tr_running = 0; 1429 port->tr_running = 0;
1408 tr_cfg.tr_en = regk_sser_no; 1430 tr_cfg.tr_en = regk_sser_no;
@@ -1414,62 +1436,79 @@ static irqreturn_t tr_interrupt(int irq, void *dev_id)
1414 return IRQ_RETVAL(found); 1436 return IRQ_RETVAL(found);
1415} /* tr_interrupt */ 1437} /* tr_interrupt */
1416 1438
1439
1440static inline void handle_rx_packet(struct sync_port *port)
1441{
1442 int idx;
1443 reg_dma_rw_ack_intr ack_intr = { .data = regk_dma_yes };
1444 unsigned long flags;
1445
1446 DEBUGRXINT(pr_info(KERN_INFO "!"));
1447 spin_lock_irqsave(&port->lock, flags);
1448
1449 /* If we overrun the user experience is crap regardless if we
1450 * drop new or old data. Its much easier to get it right when
1451 * dropping new data so lets do that.
1452 */
1453 if ((port->writep + port->inbufchunk <=
1454 port->flip + port->in_buffer_size) &&
1455 (port->in_buffer_len + port->inbufchunk < IN_BUFFER_SIZE)) {
1456 memcpy(port->writep,
1457 phys_to_virt((unsigned)port->next_rx_desc->buf),
1458 port->inbufchunk);
1459 port->writep += port->inbufchunk;
1460 if (port->writep >= port->flip + port->in_buffer_size)
1461 port->writep = port->flip;
1462
1463 /* Timestamp the new data chunk. */
1464 if (port->write_ts_idx == NBR_IN_DESCR)
1465 port->write_ts_idx = 0;
1466 idx = port->write_ts_idx++;
1467 do_posix_clock_monotonic_gettime(&port->timestamp[idx]);
1468 port->in_buffer_len += port->inbufchunk;
1469 }
1470 spin_unlock_irqrestore(&port->lock, flags);
1471
1472 port->next_rx_desc->eol = 1;
1473 port->prev_rx_desc->eol = 0;
1474 /* Cache bug workaround */
1475 flush_dma_descr(port->prev_rx_desc, 0);
1476 port->prev_rx_desc = port->next_rx_desc;
1477 port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
1478 /* Cache bug workaround */
1479 flush_dma_descr(port->prev_rx_desc, 1);
1480 /* wake up the waiting process */
1481 wake_up_interruptible(&port->in_wait_q);
1482 DMA_CONTINUE(port->regi_dmain);
1483 REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr);
1484
1485}
1486
1417static irqreturn_t rx_interrupt(int irq, void *dev_id) 1487static irqreturn_t rx_interrupt(int irq, void *dev_id)
1418{ 1488{
1419 reg_dma_r_masked_intr masked; 1489 reg_dma_r_masked_intr masked;
1420 reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
1421 1490
1422 int i; 1491 int i;
1423 int found = 0; 1492 int found = 0;
1424 1493
1425 for (i = 0; i < NBR_PORTS; i++) 1494 DEBUG(pr_info("rx_interrupt\n"));
1426 { 1495
1427 sync_port *port = &ports[i]; 1496 for (i = 0; i < NBR_PORTS; i++) {
1497 struct sync_port *port = &ports[i];
1428 1498
1429 if (!port->enabled || !port->use_dma ) 1499 if (!port->enabled || !port->use_dma)
1430 continue; 1500 continue;
1431 1501
1432 masked = REG_RD(dma, port->regi_dmain, r_masked_intr); 1502 masked = REG_RD(dma, port->regi_dmain, r_masked_intr);
1433 1503
1434 if (masked.data) /* Descriptor interrupt */ 1504 if (!masked.data)
1435 { 1505 continue;
1436 found = 1;
1437 while (REG_RD(dma, port->regi_dmain, rw_data) !=
1438 virt_to_phys(port->next_rx_desc)) {
1439 DEBUGRXINT(printk(KERN_DEBUG "!"));
1440 if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
1441 int first_size = port->flip + port->in_buffer_size - port->writep;
1442 memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size);
1443 memcpy(port->flip, phys_to_virt((unsigned)port->next_rx_desc->buf+first_size), port->inbufchunk - first_size);
1444 port->writep = port->flip + port->inbufchunk - first_size;
1445 } else {
1446 memcpy((char*)port->writep,
1447 phys_to_virt((unsigned)port->next_rx_desc->buf),
1448 port->inbufchunk);
1449 port->writep += port->inbufchunk;
1450 if (port->writep >= port->flip + port->in_buffer_size)
1451 port->writep = port->flip;
1452 }
1453 if (port->writep == port->readp)
1454 {
1455 port->full = 1;
1456 }
1457
1458 port->next_rx_desc->eol = 1;
1459 port->prev_rx_desc->eol = 0;
1460 /* Cache bug workaround */
1461 flush_dma_descr(port->prev_rx_desc, 0);
1462 port->prev_rx_desc = port->next_rx_desc;
1463 port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
1464 /* Cache bug workaround */
1465 flush_dma_descr(port->prev_rx_desc, 1);
1466 /* wake up the waiting process */
1467 wake_up_interruptible(&port->in_wait_q);
1468 DMA_CONTINUE(port->regi_dmain);
1469 REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr);
1470 1506
1471 } 1507 /* Descriptor interrupt */
1472 } 1508 found = 1;
1509 while (REG_RD(dma, port->regi_dmain, rw_data) !=
1510 virt_to_phys(port->next_rx_desc))
1511 handle_rx_packet(port);
1473 } 1512 }
1474 return IRQ_RETVAL(found); 1513 return IRQ_RETVAL(found);
1475} /* rx_interrupt */ 1514} /* rx_interrupt */
@@ -1478,75 +1517,83 @@ static irqreturn_t rx_interrupt(int irq, void *dev_id)
1478#ifdef SYNC_SER_MANUAL 1517#ifdef SYNC_SER_MANUAL
1479static irqreturn_t manual_interrupt(int irq, void *dev_id) 1518static irqreturn_t manual_interrupt(int irq, void *dev_id)
1480{ 1519{
1520 unsigned long flags;
1481 int i; 1521 int i;
1482 int found = 0; 1522 int found = 0;
1483 reg_sser_r_masked_intr masked; 1523 reg_sser_r_masked_intr masked;
1484 1524
1485 for (i = 0; i < NBR_PORTS; i++) 1525 for (i = 0; i < NBR_PORTS; i++) {
1486 { 1526 struct sync_port *port = &ports[i];
1487 sync_port *port = &ports[i];
1488 1527
1489 if (!port->enabled || port->use_dma) 1528 if (!port->enabled || port->use_dma)
1490 {
1491 continue; 1529 continue;
1492 }
1493 1530
1494 masked = REG_RD(sser, port->regi_sser, r_masked_intr); 1531 masked = REG_RD(sser, port->regi_sser, r_masked_intr);
1495 if (masked.rdav) /* Data received? */ 1532 /* Data received? */
1496 { 1533 if (masked.rdav) {
1497 reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg); 1534 reg_sser_rw_rec_cfg rec_cfg =
1498 reg_sser_r_rec_data data = REG_RD(sser, port->regi_sser, r_rec_data); 1535 REG_RD(sser, port->regi_sser, rw_rec_cfg);
1536 reg_sser_r_rec_data data = REG_RD(sser,
1537 port->regi_sser, r_rec_data);
1499 found = 1; 1538 found = 1;
1500 /* Read data */ 1539 /* Read data */
1501 switch(rec_cfg.sample_size) 1540 spin_lock_irqsave(&port->lock, flags);
1502 { 1541 switch (rec_cfg.sample_size) {
1503 case 8: 1542 case 8:
1504 *port->writep++ = data.data & 0xff; 1543 *port->writep++ = data.data & 0xff;
1505 break; 1544 break;
1506 case 12: 1545 case 12:
1507 *port->writep = (data.data & 0x0ff0) >> 4; 1546 *port->writep = (data.data & 0x0ff0) >> 4;
1508 *(port->writep + 1) = data.data & 0x0f; 1547 *(port->writep + 1) = data.data & 0x0f;
1509 port->writep+=2; 1548 port->writep += 2;
1510 break; 1549 break;
1511 case 16: 1550 case 16:
1512 *(unsigned short*)port->writep = data.data; 1551 *(unsigned short *)port->writep = data.data;
1513 port->writep+=2; 1552 port->writep += 2;
1514 break; 1553 break;
1515 case 24: 1554 case 24:
1516 *(unsigned int*)port->writep = data.data; 1555 *(unsigned int *)port->writep = data.data;
1517 port->writep+=3; 1556 port->writep += 3;
1518 break; 1557 break;
1519 case 32: 1558 case 32:
1520 *(unsigned int*)port->writep = data.data; 1559 *(unsigned int *)port->writep = data.data;
1521 port->writep+=4; 1560 port->writep += 4;
1522 break; 1561 break;
1523 } 1562 }
1524 1563
1525 if (port->writep >= port->flip + port->in_buffer_size) /* Wrap? */ 1564 /* Wrap? */
1565 if (port->writep >= port->flip + port->in_buffer_size)
1526 port->writep = port->flip; 1566 port->writep = port->flip;
1527 if (port->writep == port->readp) { 1567 if (port->writep == port->readp) {
1528 /* receive buffer overrun, discard oldest data 1568 /* Receive buf overrun, discard oldest data */
1529 */
1530 port->readp++; 1569 port->readp++;
1531 if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */ 1570 /* Wrap? */
1571 if (port->readp >= port->flip +
1572 port->in_buffer_size)
1532 port->readp = port->flip; 1573 port->readp = port->flip;
1533 } 1574 }
1575 spin_unlock_irqrestore(&port->lock, flags);
1534 if (sync_data_avail(port) >= port->inbufchunk) 1576 if (sync_data_avail(port) >= port->inbufchunk)
1535 wake_up_interruptible(&port->in_wait_q); /* Wake up application */ 1577 /* Wake up application */
1578 wake_up_interruptible(&port->in_wait_q);
1536 } 1579 }
1537 1580
1538 if (masked.trdy) /* Transmitter ready? */ 1581 /* Transmitter ready? */
1539 { 1582 if (masked.trdy) {
1540 found = 1; 1583 found = 1;
1541 if (port->out_buf_count > 0) /* More data to send */ 1584 /* More data to send */
1585 if (port->out_buf_count > 0)
1542 send_word(port); 1586 send_word(port);
1543 else /* transmission finished */ 1587 else {
1544 { 1588 /* Transmission finished */
1545 reg_sser_rw_intr_mask intr_mask; 1589 reg_sser_rw_intr_mask intr_mask;
1546 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask); 1590 intr_mask = REG_RD(sser, port->regi_sser,
1591 rw_intr_mask);
1547 intr_mask.trdy = 0; 1592 intr_mask.trdy = 0;
1548 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask); 1593 REG_WR(sser, port->regi_sser,
1549 wake_up_interruptible(&port->out_wait_q); /* Wake up application */ 1594 rw_intr_mask, intr_mask);
1595 /* Wake up application */
1596 wake_up_interruptible(&port->out_wait_q);
1550 } 1597 }
1551 } 1598 }
1552 } 1599 }
@@ -1554,4 +1601,109 @@ static irqreturn_t manual_interrupt(int irq, void *dev_id)
1554} 1601}
1555#endif 1602#endif
1556 1603
1604static int __init etrax_sync_serial_init(void)
1605{
1606#if 1
1607 /* This code will be removed when we move to udev for all devices. */
1608 syncser_first = MKDEV(SYNC_SERIAL_MAJOR, 0);
1609 if (register_chrdev_region(syncser_first, minor_count, SYNCSER_NAME)) {
1610 pr_err("Failed to register major %d\n", SYNC_SERIAL_MAJOR);
1611 return -1;
1612 }
1613#else
1614 /* Allocate dynamic major number. */
1615 if (alloc_chrdev_region(&syncser_first, 0, minor_count, SYNCSER_NAME)) {
1616 pr_err("Failed to allocate character device region\n");
1617 return -1;
1618 }
1619#endif
1620 syncser_cdev = cdev_alloc();
1621 if (!syncser_cdev) {
1622 pr_err("Failed to allocate cdev for syncser\n");
1623 unregister_chrdev_region(syncser_first, minor_count);
1624 return -1;
1625 }
1626 cdev_init(syncser_cdev, &syncser_fops);
1627
1628 /* Create a sysfs class for syncser */
1629 syncser_class = class_create(THIS_MODULE, "syncser_class");
1630
1631 /* Initialize Ports */
1632#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
1633 if (artpec_pinmux_alloc_fixed(PINMUX_SSER0)) {
1634 pr_warn("Unable to alloc pins for synchronous serial port 0\n");
1635 unregister_chrdev_region(syncser_first, minor_count);
1636 return -EIO;
1637 }
1638 initialize_port(0);
1639 ports[0].enabled = 1;
1640 /* Register with sysfs so udev can pick it up. */
1641 device_create(syncser_class, NULL, syncser_first, NULL,
1642 "%s%d", SYNCSER_NAME, 0);
1643#endif
1644
1645#if defined(CONFIG_ETRAXFS) && defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
1646 if (artpec_pinmux_alloc_fixed(PINMUX_SSER1)) {
1647 pr_warn("Unable to alloc pins for synchronous serial port 1\n");
1648 unregister_chrdev_region(syncser_first, minor_count);
1649 class_destroy(syncser_class);
1650 return -EIO;
1651 }
1652 initialize_port(1);
1653 ports[1].enabled = 1;
1654 /* Register with sysfs so udev can pick it up. */
1655 device_create(syncser_class, NULL, syncser_first, NULL,
1656 "%s%d", SYNCSER_NAME, 0);
1657#endif
1658
1659 /* Add it to system */
1660 if (cdev_add(syncser_cdev, syncser_first, minor_count) < 0) {
1661 pr_err("Failed to add syncser as char device\n");
1662 device_destroy(syncser_class, syncser_first);
1663 class_destroy(syncser_class);
1664 cdev_del(syncser_cdev);
1665 unregister_chrdev_region(syncser_first, minor_count);
1666 return -1;
1667 }
1668
1669
1670 pr_info("ARTPEC synchronous serial port (%s: %d, %d)\n",
1671 SYNCSER_NAME, MAJOR(syncser_first), MINOR(syncser_first));
1672
1673 return 0;
1674}
1675
1676static void __exit etrax_sync_serial_exit(void)
1677{
1678 int i;
1679 device_destroy(syncser_class, syncser_first);
1680 class_destroy(syncser_class);
1681
1682 if (syncser_cdev) {
1683 cdev_del(syncser_cdev);
1684 unregister_chrdev_region(syncser_first, minor_count);
1685 }
1686 for (i = 0; i < NBR_PORTS; i++) {
1687 struct sync_port *port = &ports[i];
1688 if (port->init_irqs == dma_irq_setup) {
1689 /* Free dma irqs and dma channels. */
1690#ifdef SYNC_SER_DMA
1691 artpec_free_dma(port->dma_in_nbr);
1692 artpec_free_dma(port->dma_out_nbr);
1693 free_irq(port->dma_out_intr_vect, port);
1694 free_irq(port->dma_in_intr_vect, port);
1695#endif
1696 } else if (port->init_irqs == manual_irq_setup) {
1697 /* Free manual irq. */
1698 free_irq(port->syncser_intr_vect, port);
1699 }
1700 }
1701
1702 pr_info("ARTPEC synchronous serial port unregistered\n");
1703}
1704
1557module_init(etrax_sync_serial_init); 1705module_init(etrax_sync_serial_init);
1706module_exit(etrax_sync_serial_exit);
1707
1708MODULE_LICENSE("GPL");
1709
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c
index 610909b003f6..02e33ebe51ec 100644
--- a/arch/cris/arch-v32/kernel/debugport.c
+++ b/arch/cris/arch-v32/kernel/debugport.c
@@ -3,7 +3,9 @@
3 */ 3 */
4 4
5#include <linux/console.h> 5#include <linux/console.h>
6#include <linux/kernel.h>
6#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/string.h>
7#include <hwregs/reg_rdwr.h> 9#include <hwregs/reg_rdwr.h>
8#include <hwregs/reg_map.h> 10#include <hwregs/reg_map.h>
9#include <hwregs/ser_defs.h> 11#include <hwregs/ser_defs.h>
@@ -65,6 +67,7 @@ struct dbg_port ports[] =
65 }, 67 },
66#endif 68#endif
67}; 69};
70
68static struct dbg_port *port = 71static struct dbg_port *port =
69#if defined(CONFIG_ETRAX_DEBUG_PORT0) 72#if defined(CONFIG_ETRAX_DEBUG_PORT0)
70 &ports[0]; 73 &ports[0];
@@ -97,14 +100,19 @@ static struct dbg_port *kgdb_port =
97#endif 100#endif
98#endif 101#endif
99 102
100static void 103static void start_port(struct dbg_port *p)
101start_port(struct dbg_port* p)
102{ 104{
103 if (!p) 105 /* Set up serial port registers */
104 return; 106 reg_ser_rw_tr_ctrl tr_ctrl = {0};
107 reg_ser_rw_tr_dma_en tr_dma_en = {0};
105 108
106 if (p->started) 109 reg_ser_rw_rec_ctrl rec_ctrl = {0};
110 reg_ser_rw_tr_baud_div tr_baud_div = {0};
111 reg_ser_rw_rec_baud_div rec_baud_div = {0};
112
113 if (!p || p->started)
107 return; 114 return;
115
108 p->started = 1; 116 p->started = 1;
109 117
110 if (p->nbr == 1) 118 if (p->nbr == 1)
@@ -118,36 +126,24 @@ start_port(struct dbg_port* p)
118 crisv32_pinmux_alloc_fixed(pinmux_ser4); 126 crisv32_pinmux_alloc_fixed(pinmux_ser4);
119#endif 127#endif
120 128
121 /* Set up serial port registers */
122 reg_ser_rw_tr_ctrl tr_ctrl = {0};
123 reg_ser_rw_tr_dma_en tr_dma_en = {0};
124
125 reg_ser_rw_rec_ctrl rec_ctrl = {0};
126 reg_ser_rw_tr_baud_div tr_baud_div = {0};
127 reg_ser_rw_rec_baud_div rec_baud_div = {0};
128
129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493; 129 tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no; 130 tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8; 131 tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
132 tr_ctrl.en = rec_ctrl.en = 1; 132 tr_ctrl.en = rec_ctrl.en = 1;
133 133
134 if (p->parity == 'O') 134 if (p->parity == 'O') {
135 {
136 tr_ctrl.par_en = regk_ser_yes; 135 tr_ctrl.par_en = regk_ser_yes;
137 tr_ctrl.par = regk_ser_odd; 136 tr_ctrl.par = regk_ser_odd;
138 rec_ctrl.par_en = regk_ser_yes; 137 rec_ctrl.par_en = regk_ser_yes;
139 rec_ctrl.par = regk_ser_odd; 138 rec_ctrl.par = regk_ser_odd;
140 } 139 } else if (p->parity == 'E') {
141 else if (p->parity == 'E')
142 {
143 tr_ctrl.par_en = regk_ser_yes; 140 tr_ctrl.par_en = regk_ser_yes;
144 tr_ctrl.par = regk_ser_even; 141 tr_ctrl.par = regk_ser_even;
145 rec_ctrl.par_en = regk_ser_yes; 142 rec_ctrl.par_en = regk_ser_yes;
146 rec_ctrl.par = regk_ser_odd; 143 rec_ctrl.par = regk_ser_odd;
147 } 144 }
148 145
149 if (p->bits == 7) 146 if (p->bits == 7) {
150 {
151 tr_ctrl.data_bits = regk_ser_bits7; 147 tr_ctrl.data_bits = regk_ser_bits7;
152 rec_ctrl.data_bits = regk_ser_bits7; 148 rec_ctrl.data_bits = regk_ser_bits7;
153 } 149 }
@@ -161,8 +157,7 @@ start_port(struct dbg_port* p)
161 157
162#ifdef CONFIG_ETRAX_KGDB 158#ifdef CONFIG_ETRAX_KGDB
163/* Use polling to get a single character from the kernel debug port */ 159/* Use polling to get a single character from the kernel debug port */
164int 160int getDebugChar(void)
165getDebugChar(void)
166{ 161{
167 reg_ser_rs_stat_din stat; 162 reg_ser_rs_stat_din stat;
168 reg_ser_rw_ack_intr ack_intr = { 0 }; 163 reg_ser_rw_ack_intr ack_intr = { 0 };
@@ -179,8 +174,7 @@ getDebugChar(void)
179} 174}
180 175
181/* Use polling to put a single character to the kernel debug port */ 176/* Use polling to put a single character to the kernel debug port */
182void 177void putDebugChar(int val)
183putDebugChar(int val)
184{ 178{
185 reg_ser_r_stat_din stat; 179 reg_ser_r_stat_din stat;
186 do { 180 do {
@@ -190,12 +184,48 @@ putDebugChar(int val)
190} 184}
191#endif /* CONFIG_ETRAX_KGDB */ 185#endif /* CONFIG_ETRAX_KGDB */
192 186
187static void __init early_putch(int c)
188{
189 reg_ser_r_stat_din stat;
190 /* Wait until transmitter is ready and send. */
191 do
192 stat = REG_RD(ser, port->instance, r_stat_din);
193 while (!stat.tr_rdy);
194 REG_WR_INT(ser, port->instance, rw_dout, c);
195}
196
197static void __init
198early_console_write(struct console *con, const char *s, unsigned n)
199{
200 extern void reset_watchdog(void);
201 int i;
202
203 /* Send data. */
204 for (i = 0; i < n; i++) {
205 /* TODO: the '\n' -> '\n\r' translation should be done at the
206 receiver. Remove it when the serial driver removes it. */
207 if (s[i] == '\n')
208 early_putch('\r');
209 early_putch(s[i]);
210 reset_watchdog();
211 }
212}
213
214static struct console early_console_dev __initdata = {
215 .name = "early",
216 .write = early_console_write,
217 .flags = CON_PRINTBUFFER | CON_BOOT,
218 .index = -1
219};
220
193/* Register console for printk's, etc. */ 221/* Register console for printk's, etc. */
194int __init 222int __init init_etrax_debug(void)
195init_etrax_debug(void)
196{ 223{
197 start_port(port); 224 start_port(port);
198 225
226 /* Register an early console if a debug port was chosen. */
227 register_console(&early_console_dev);
228
199#ifdef CONFIG_ETRAX_KGDB 229#ifdef CONFIG_ETRAX_KGDB
200 start_port(kgdb_port); 230 start_port(kgdb_port);
201#endif /* CONFIG_ETRAX_KGDB */ 231#endif /* CONFIG_ETRAX_KGDB */
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index ee66866538f8..eb74dabbeb96 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -14,6 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/threads.h> 15#include <linux/threads.h>
16#include <linux/cpufreq.h> 16#include <linux/cpufreq.h>
17#include <linux/mm.h>
17#include <asm/types.h> 18#include <asm/types.h>
18#include <asm/signal.h> 19#include <asm/signal.h>
19#include <asm/io.h> 20#include <asm/io.h>
@@ -56,7 +57,6 @@ static int __init etrax_init_cont_rotime(void)
56} 57}
57arch_initcall(etrax_init_cont_rotime); 58arch_initcall(etrax_init_cont_rotime);
58 59
59
60unsigned long timer_regs[NR_CPUS] = 60unsigned long timer_regs[NR_CPUS] =
61{ 61{
62 regi_timer0, 62 regi_timer0,
@@ -68,9 +68,8 @@ unsigned long timer_regs[NR_CPUS] =
68extern int set_rtc_mmss(unsigned long nowtime); 68extern int set_rtc_mmss(unsigned long nowtime);
69 69
70#ifdef CONFIG_CPU_FREQ 70#ifdef CONFIG_CPU_FREQ
71static int 71static int cris_time_freq_notifier(struct notifier_block *nb,
72cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, 72 unsigned long val, void *data);
73 void *data);
74 73
75static struct notifier_block cris_time_freq_notifier_block = { 74static struct notifier_block cris_time_freq_notifier_block = {
76 .notifier_call = cris_time_freq_notifier, 75 .notifier_call = cris_time_freq_notifier,
@@ -87,7 +86,6 @@ unsigned long get_ns_in_jiffie(void)
87 return ns; 86 return ns;
88} 87}
89 88
90
91/* From timer MDS describing the hardware watchdog: 89/* From timer MDS describing the hardware watchdog:
92 * 4.3.1 Watchdog Operation 90 * 4.3.1 Watchdog Operation
93 * The watchdog timer is an 8-bit timer with a configurable start value. 91 * The watchdog timer is an 8-bit timer with a configurable start value.
@@ -109,11 +107,18 @@ static short int watchdog_key = 42; /* arbitrary 7 bit number */
109 * is used though, so set this really low. */ 107 * is used though, so set this really low. */
110#define WATCHDOG_MIN_FREE_PAGES 8 108#define WATCHDOG_MIN_FREE_PAGES 8
111 109
110/* for reliable NICE_DOGGY behaviour */
111static int bite_in_progress;
112
112void reset_watchdog(void) 113void reset_watchdog(void)
113{ 114{
114#if defined(CONFIG_ETRAX_WATCHDOG) 115#if defined(CONFIG_ETRAX_WATCHDOG)
115 reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; 116 reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
116 117
118#if defined(CONFIG_ETRAX_WATCHDOG_NICE_DOGGY)
119 if (unlikely(bite_in_progress))
120 return;
121#endif
117 /* Only keep watchdog happy as long as we have memory left! */ 122 /* Only keep watchdog happy as long as we have memory left! */
118 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) { 123 if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
119 /* Reset the watchdog with the inverse of the old key */ 124 /* Reset the watchdog with the inverse of the old key */
@@ -148,7 +153,9 @@ void handle_watchdog_bite(struct pt_regs *regs)
148#if defined(CONFIG_ETRAX_WATCHDOG) 153#if defined(CONFIG_ETRAX_WATCHDOG)
149 extern int cause_of_death; 154 extern int cause_of_death;
150 155
156 nmi_enter();
151 oops_in_progress = 1; 157 oops_in_progress = 1;
158 bite_in_progress = 1;
152 printk(KERN_WARNING "Watchdog bite\n"); 159 printk(KERN_WARNING "Watchdog bite\n");
153 160
154 /* Check if forced restart or unexpected watchdog */ 161 /* Check if forced restart or unexpected watchdog */
@@ -170,6 +177,7 @@ void handle_watchdog_bite(struct pt_regs *regs)
170 printk(KERN_WARNING "Oops: bitten by watchdog\n"); 177 printk(KERN_WARNING "Oops: bitten by watchdog\n");
171 show_registers(regs); 178 show_registers(regs);
172 oops_in_progress = 0; 179 oops_in_progress = 0;
180 printk("\n"); /* Flush mtdoops. */
173#ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 181#ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
174 reset_watchdog(); 182 reset_watchdog();
175#endif 183#endif
@@ -202,7 +210,7 @@ static inline irqreturn_t timer_interrupt(int irq, void *dev_id)
202 /* Reset watchdog otherwise it resets us! */ 210 /* Reset watchdog otherwise it resets us! */
203 reset_watchdog(); 211 reset_watchdog();
204 212
205 /* Update statistics. */ 213 /* Update statistics. */
206 update_process_times(user_mode(regs)); 214 update_process_times(user_mode(regs));
207 215
208 cris_do_profile(regs); /* Save profiling information */ 216 cris_do_profile(regs); /* Save profiling information */
@@ -213,7 +221,7 @@ static inline irqreturn_t timer_interrupt(int irq, void *dev_id)
213 221
214 /* Call the real timer interrupt handler */ 222 /* Call the real timer interrupt handler */
215 xtime_update(1); 223 xtime_update(1);
216 return IRQ_HANDLED; 224 return IRQ_HANDLED;
217} 225}
218 226
219/* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. */ 227/* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. */
@@ -293,14 +301,13 @@ void __init time_init(void)
293 301
294#ifdef CONFIG_CPU_FREQ 302#ifdef CONFIG_CPU_FREQ
295 cpufreq_register_notifier(&cris_time_freq_notifier_block, 303 cpufreq_register_notifier(&cris_time_freq_notifier_block,
296 CPUFREQ_TRANSITION_NOTIFIER); 304 CPUFREQ_TRANSITION_NOTIFIER);
297#endif 305#endif
298} 306}
299 307
300#ifdef CONFIG_CPU_FREQ 308#ifdef CONFIG_CPU_FREQ
301static int 309static int cris_time_freq_notifier(struct notifier_block *nb,
302cris_time_freq_notifier(struct notifier_block *nb, unsigned long val, 310 unsigned long val, void *data)
303 void *data)
304{ 311{
305 struct cpufreq_freqs *freqs = data; 312 struct cpufreq_freqs *freqs = data;
306 if (val == CPUFREQ_POSTCHANGE) { 313 if (val == CPUFREQ_POSTCHANGE) {
diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c
index 0b5b70d5f58a..f0f335d8aa79 100644
--- a/arch/cris/arch-v32/lib/usercopy.c
+++ b/arch/cris/arch-v32/lib/usercopy.c
@@ -26,8 +26,7 @@
26/* Copy to userspace. This is based on the memcpy used for 26/* Copy to userspace. This is based on the memcpy used for
27 kernel-to-kernel copying; see "string.c". */ 27 kernel-to-kernel copying; see "string.c". */
28 28
29unsigned long 29unsigned long __copy_user(void __user *pdst, const void *psrc, unsigned long pn)
30__copy_user (void __user *pdst, const void *psrc, unsigned long pn)
31{ 30{
32 /* We want the parameters put in special registers. 31 /* We want the parameters put in special registers.
33 Make sure the compiler is able to make something useful of this. 32 Make sure the compiler is able to make something useful of this.
@@ -155,13 +154,13 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
155 154
156 return retn; 155 return retn;
157} 156}
157EXPORT_SYMBOL(__copy_user);
158 158
159/* Copy from user to kernel, zeroing the bytes that were inaccessible in 159/* Copy from user to kernel, zeroing the bytes that were inaccessible in
160 userland. The return-value is the number of bytes that were 160 userland. The return-value is the number of bytes that were
161 inaccessible. */ 161 inaccessible. */
162 162unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
163unsigned long 163 unsigned long pn)
164__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn)
165{ 164{
166 /* We want the parameters put in special registers. 165 /* We want the parameters put in special registers.
167 Make sure the compiler is able to make something useful of this. 166 Make sure the compiler is able to make something useful of this.
@@ -321,11 +320,10 @@ copy_exception_bytes:
321 320
322 return retn + n; 321 return retn + n;
323} 322}
323EXPORT_SYMBOL(__copy_user_zeroing);
324 324
325/* Zero userspace. */ 325/* Zero userspace. */
326 326unsigned long __do_clear_user(void __user *pto, unsigned long pn)
327unsigned long
328__do_clear_user (void __user *pto, unsigned long pn)
329{ 327{
330 /* We want the parameters put in special registers. 328 /* We want the parameters put in special registers.
331 Make sure the compiler is able to make something useful of this. 329 Make sure the compiler is able to make something useful of this.
@@ -468,3 +466,4 @@ __do_clear_user (void __user *pto, unsigned long pn)
468 466
469 return retn; 467 return retn;
470} 468}
469EXPORT_SYMBOL(__do_clear_user);
diff --git a/arch/cris/arch-v32/mach-fs/pinmux.c b/arch/cris/arch-v32/mach-fs/pinmux.c
index 38f29eec14a6..05a04708b8eb 100644
--- a/arch/cris/arch-v32/mach-fs/pinmux.c
+++ b/arch/cris/arch-v32/mach-fs/pinmux.c
@@ -26,7 +26,29 @@ static DEFINE_SPINLOCK(pinmux_lock);
26 26
27static void crisv32_pinmux_set(int port); 27static void crisv32_pinmux_set(int port);
28 28
29int crisv32_pinmux_init(void) 29static int __crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
30 enum pin_mode mode)
31{
32 int i;
33
34 for (i = first_pin; i <= last_pin; i++) {
35 if ((pins[port][i] != pinmux_none)
36 && (pins[port][i] != pinmux_gpio)
37 && (pins[port][i] != mode)) {
38#ifdef DEBUG
39 panic("Pinmux alloc failed!\n");
40#endif
41 return -EPERM;
42 }
43 }
44
45 for (i = first_pin; i <= last_pin; i++)
46 pins[port][i] = mode;
47
48 crisv32_pinmux_set(port);
49}
50
51static int crisv32_pinmux_init(void)
30{ 52{
31 static int initialized; 53 static int initialized;
32 54
@@ -37,20 +59,20 @@ int crisv32_pinmux_init(void)
37 pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 = 59 pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
38 pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes; 60 pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
39 REG_WR(pinmux, regi_pinmux, rw_pa, pa); 61 REG_WR(pinmux, regi_pinmux, rw_pa, pa);
40 crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio); 62 __crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
41 crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio); 63 __crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
42 crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio); 64 __crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio);
43 crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio); 65 __crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio);
44 } 66 }
45 67
46 return 0; 68 return 0;
47} 69}
48 70
49int 71int crisv32_pinmux_alloc(int port, int first_pin, int last_pin,
50crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode) 72 enum pin_mode mode)
51{ 73{
52 int i;
53 unsigned long flags; 74 unsigned long flags;
75 int ret;
54 76
55 crisv32_pinmux_init(); 77 crisv32_pinmux_init();
56 78
@@ -59,26 +81,11 @@ crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
59 81
60 spin_lock_irqsave(&pinmux_lock, flags); 82 spin_lock_irqsave(&pinmux_lock, flags);
61 83
62 for (i = first_pin; i <= last_pin; i++) { 84 ret = __crisv32_pinmux_alloc(port, first_pin, last_pin, mode);
63 if ((pins[port][i] != pinmux_none)
64 && (pins[port][i] != pinmux_gpio)
65 && (pins[port][i] != mode)) {
66 spin_unlock_irqrestore(&pinmux_lock, flags);
67#ifdef DEBUG
68 panic("Pinmux alloc failed!\n");
69#endif
70 return -EPERM;
71 }
72 }
73
74 for (i = first_pin; i <= last_pin; i++)
75 pins[port][i] = mode;
76
77 crisv32_pinmux_set(port);
78 85
79 spin_unlock_irqrestore(&pinmux_lock, flags); 86 spin_unlock_irqrestore(&pinmux_lock, flags);
80 87
81 return 0; 88 return ret;
82} 89}
83 90
84int crisv32_pinmux_alloc_fixed(enum fixed_function function) 91int crisv32_pinmux_alloc_fixed(enum fixed_function function)
@@ -98,58 +105,58 @@ int crisv32_pinmux_alloc_fixed(enum fixed_function function)
98 105
99 switch (function) { 106 switch (function) {
100 case pinmux_ser1: 107 case pinmux_ser1:
101 ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed); 108 ret = __crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
102 hwprot.ser1 = regk_pinmux_yes; 109 hwprot.ser1 = regk_pinmux_yes;
103 break; 110 break;
104 case pinmux_ser2: 111 case pinmux_ser2:
105 ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed); 112 ret = __crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
106 hwprot.ser2 = regk_pinmux_yes; 113 hwprot.ser2 = regk_pinmux_yes;
107 break; 114 break;
108 case pinmux_ser3: 115 case pinmux_ser3:
109 ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed); 116 ret = __crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
110 hwprot.ser3 = regk_pinmux_yes; 117 hwprot.ser3 = regk_pinmux_yes;
111 break; 118 break;
112 case pinmux_sser0: 119 case pinmux_sser0:
113 ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed); 120 ret = __crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
114 ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed); 121 ret |= __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
115 hwprot.sser0 = regk_pinmux_yes; 122 hwprot.sser0 = regk_pinmux_yes;
116 break; 123 break;
117 case pinmux_sser1: 124 case pinmux_sser1:
118 ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed); 125 ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
119 hwprot.sser1 = regk_pinmux_yes; 126 hwprot.sser1 = regk_pinmux_yes;
120 break; 127 break;
121 case pinmux_ata0: 128 case pinmux_ata0:
122 ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed); 129 ret = __crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
123 ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed); 130 ret |= __crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
124 hwprot.ata0 = regk_pinmux_yes; 131 hwprot.ata0 = regk_pinmux_yes;
125 break; 132 break;
126 case pinmux_ata1: 133 case pinmux_ata1:
127 ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed); 134 ret = __crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
128 ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed); 135 ret |= __crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
129 hwprot.ata1 = regk_pinmux_yes; 136 hwprot.ata1 = regk_pinmux_yes;
130 break; 137 break;
131 case pinmux_ata2: 138 case pinmux_ata2:
132 ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed); 139 ret = __crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
133 ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed); 140 ret |= __crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
134 hwprot.ata2 = regk_pinmux_yes; 141 hwprot.ata2 = regk_pinmux_yes;
135 break; 142 break;
136 case pinmux_ata3: 143 case pinmux_ata3:
137 ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed); 144 ret = __crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
138 ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed); 145 ret |= __crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
139 hwprot.ata2 = regk_pinmux_yes; 146 hwprot.ata2 = regk_pinmux_yes;
140 break; 147 break;
141 case pinmux_ata: 148 case pinmux_ata:
142 ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed); 149 ret = __crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
143 ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed); 150 ret |= __crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
144 hwprot.ata = regk_pinmux_yes; 151 hwprot.ata = regk_pinmux_yes;
145 break; 152 break;
146 case pinmux_eth1: 153 case pinmux_eth1:
147 ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed); 154 ret = __crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
148 hwprot.eth1 = regk_pinmux_yes; 155 hwprot.eth1 = regk_pinmux_yes;
149 hwprot.eth1_mgm = regk_pinmux_yes; 156 hwprot.eth1_mgm = regk_pinmux_yes;
150 break; 157 break;
151 case pinmux_timer: 158 case pinmux_timer:
152 ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed); 159 ret = __crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
153 hwprot.timer = regk_pinmux_yes; 160 hwprot.timer = regk_pinmux_yes;
154 spin_unlock_irqrestore(&pinmux_lock, flags); 161 spin_unlock_irqrestore(&pinmux_lock, flags);
155 return ret; 162 return ret;
@@ -188,9 +195,19 @@ void crisv32_pinmux_set(int port)
188#endif 195#endif
189} 196}
190 197
191int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin) 198static int __crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
192{ 199{
193 int i; 200 int i;
201
202 for (i = first_pin; i <= last_pin; i++)
203 pins[port][i] = pinmux_none;
204
205 crisv32_pinmux_set(port);
206 return 0;
207}
208
209int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
210{
194 unsigned long flags; 211 unsigned long flags;
195 212
196 crisv32_pinmux_init(); 213 crisv32_pinmux_init();
@@ -199,11 +216,7 @@ int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
199 return -EINVAL; 216 return -EINVAL;
200 217
201 spin_lock_irqsave(&pinmux_lock, flags); 218 spin_lock_irqsave(&pinmux_lock, flags);
202 219 __crisv32_pinmux_dealloc(port, first_pin, last_pin);
203 for (i = first_pin; i <= last_pin; i++)
204 pins[port][i] = pinmux_none;
205
206 crisv32_pinmux_set(port);
207 spin_unlock_irqrestore(&pinmux_lock, flags); 220 spin_unlock_irqrestore(&pinmux_lock, flags);
208 221
209 return 0; 222 return 0;
@@ -226,58 +239,58 @@ int crisv32_pinmux_dealloc_fixed(enum fixed_function function)
226 239
227 switch (function) { 240 switch (function) {
228 case pinmux_ser1: 241 case pinmux_ser1:
229 ret = crisv32_pinmux_dealloc(PORT_C, 4, 7); 242 ret = __crisv32_pinmux_dealloc(PORT_C, 4, 7);
230 hwprot.ser1 = regk_pinmux_no; 243 hwprot.ser1 = regk_pinmux_no;
231 break; 244 break;
232 case pinmux_ser2: 245 case pinmux_ser2:
233 ret = crisv32_pinmux_dealloc(PORT_C, 8, 11); 246 ret = __crisv32_pinmux_dealloc(PORT_C, 8, 11);
234 hwprot.ser2 = regk_pinmux_no; 247 hwprot.ser2 = regk_pinmux_no;
235 break; 248 break;
236 case pinmux_ser3: 249 case pinmux_ser3:
237 ret = crisv32_pinmux_dealloc(PORT_C, 12, 15); 250 ret = __crisv32_pinmux_dealloc(PORT_C, 12, 15);
238 hwprot.ser3 = regk_pinmux_no; 251 hwprot.ser3 = regk_pinmux_no;
239 break; 252 break;
240 case pinmux_sser0: 253 case pinmux_sser0:
241 ret = crisv32_pinmux_dealloc(PORT_C, 0, 3); 254 ret = __crisv32_pinmux_dealloc(PORT_C, 0, 3);
242 ret |= crisv32_pinmux_dealloc(PORT_C, 16, 16); 255 ret |= __crisv32_pinmux_dealloc(PORT_C, 16, 16);
243 hwprot.sser0 = regk_pinmux_no; 256 hwprot.sser0 = regk_pinmux_no;
244 break; 257 break;
245 case pinmux_sser1: 258 case pinmux_sser1:
246 ret = crisv32_pinmux_dealloc(PORT_D, 0, 4); 259 ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
247 hwprot.sser1 = regk_pinmux_no; 260 hwprot.sser1 = regk_pinmux_no;
248 break; 261 break;
249 case pinmux_ata0: 262 case pinmux_ata0:
250 ret = crisv32_pinmux_dealloc(PORT_D, 5, 7); 263 ret = __crisv32_pinmux_dealloc(PORT_D, 5, 7);
251 ret |= crisv32_pinmux_dealloc(PORT_D, 15, 17); 264 ret |= __crisv32_pinmux_dealloc(PORT_D, 15, 17);
252 hwprot.ata0 = regk_pinmux_no; 265 hwprot.ata0 = regk_pinmux_no;
253 break; 266 break;
254 case pinmux_ata1: 267 case pinmux_ata1:
255 ret = crisv32_pinmux_dealloc(PORT_D, 0, 4); 268 ret = __crisv32_pinmux_dealloc(PORT_D, 0, 4);
256 ret |= crisv32_pinmux_dealloc(PORT_E, 17, 17); 269 ret |= __crisv32_pinmux_dealloc(PORT_E, 17, 17);
257 hwprot.ata1 = regk_pinmux_no; 270 hwprot.ata1 = regk_pinmux_no;
258 break; 271 break;
259 case pinmux_ata2: 272 case pinmux_ata2:
260 ret = crisv32_pinmux_dealloc(PORT_C, 11, 15); 273 ret = __crisv32_pinmux_dealloc(PORT_C, 11, 15);
261 ret |= crisv32_pinmux_dealloc(PORT_E, 3, 3); 274 ret |= __crisv32_pinmux_dealloc(PORT_E, 3, 3);
262 hwprot.ata2 = regk_pinmux_no; 275 hwprot.ata2 = regk_pinmux_no;
263 break; 276 break;
264 case pinmux_ata3: 277 case pinmux_ata3:
265 ret = crisv32_pinmux_dealloc(PORT_C, 8, 10); 278 ret = __crisv32_pinmux_dealloc(PORT_C, 8, 10);
266 ret |= crisv32_pinmux_dealloc(PORT_C, 0, 2); 279 ret |= __crisv32_pinmux_dealloc(PORT_C, 0, 2);
267 hwprot.ata2 = regk_pinmux_no; 280 hwprot.ata2 = regk_pinmux_no;
268 break; 281 break;
269 case pinmux_ata: 282 case pinmux_ata:
270 ret = crisv32_pinmux_dealloc(PORT_B, 0, 15); 283 ret = __crisv32_pinmux_dealloc(PORT_B, 0, 15);
271 ret |= crisv32_pinmux_dealloc(PORT_D, 8, 15); 284 ret |= __crisv32_pinmux_dealloc(PORT_D, 8, 15);
272 hwprot.ata = regk_pinmux_no; 285 hwprot.ata = regk_pinmux_no;
273 break; 286 break;
274 case pinmux_eth1: 287 case pinmux_eth1:
275 ret = crisv32_pinmux_dealloc(PORT_E, 0, 17); 288 ret = __crisv32_pinmux_dealloc(PORT_E, 0, 17);
276 hwprot.eth1 = regk_pinmux_no; 289 hwprot.eth1 = regk_pinmux_no;
277 hwprot.eth1_mgm = regk_pinmux_no; 290 hwprot.eth1_mgm = regk_pinmux_no;
278 break; 291 break;
279 case pinmux_timer: 292 case pinmux_timer:
280 ret = crisv32_pinmux_dealloc(PORT_C, 16, 16); 293 ret = __crisv32_pinmux_dealloc(PORT_C, 16, 16);
281 hwprot.timer = regk_pinmux_no; 294 hwprot.timer = regk_pinmux_no;
282 spin_unlock_irqrestore(&pinmux_lock, flags); 295 spin_unlock_irqrestore(&pinmux_lock, flags);
283 return ret; 296 return ret;
@@ -293,7 +306,8 @@ int crisv32_pinmux_dealloc_fixed(enum fixed_function function)
293 return ret; 306 return ret;
294} 307}
295 308
296void crisv32_pinmux_dump(void) 309#ifdef DEBUG
310static void crisv32_pinmux_dump(void)
297{ 311{
298 int i, j; 312 int i, j;
299 313
@@ -305,5 +319,5 @@ void crisv32_pinmux_dump(void)
305 printk(KERN_DEBUG " Pin %d = %d\n", j, pins[i][j]); 319 printk(KERN_DEBUG " Pin %d = %d\n", j, pins[i][j]);
306 } 320 }
307} 321}
308 322#endif
309__initcall(crisv32_pinmux_init); 323__initcall(crisv32_pinmux_init);
diff --git a/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h b/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h
index c2b3036779df..09bf0c90d2d3 100644
--- a/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h
+++ b/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h
@@ -28,11 +28,9 @@ enum fixed_function {
28 pinmux_timer 28 pinmux_timer
29}; 29};
30 30
31int crisv32_pinmux_init(void);
32int crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode); 31int crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode);
33int crisv32_pinmux_alloc_fixed(enum fixed_function function); 32int crisv32_pinmux_alloc_fixed(enum fixed_function function);
34int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin); 33int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin);
35int crisv32_pinmux_dealloc_fixed(enum fixed_function function); 34int crisv32_pinmux_dealloc_fixed(enum fixed_function function);
36void crisv32_pinmux_dump(void);
37 35
38#endif 36#endif
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index d5f124832fd1..889f2de050a3 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -1,8 +1,4 @@
1 1
2header-y += arch-v10/
3header-y += arch-v32/
4
5
6generic-y += barrier.h 2generic-y += barrier.h
7generic-y += clkdev.h 3generic-y += clkdev.h
8generic-y += cputime.h 4generic-y += cputime.h
diff --git a/arch/cris/include/uapi/asm/Kbuild b/arch/cris/include/uapi/asm/Kbuild
index 7d47b366ad82..01f66b8f15e5 100644
--- a/arch/cris/include/uapi/asm/Kbuild
+++ b/arch/cris/include/uapi/asm/Kbuild
@@ -1,8 +1,8 @@
1# UAPI Header export list 1# UAPI Header export list
2include include/uapi/asm-generic/Kbuild.asm 2include include/uapi/asm-generic/Kbuild.asm
3 3
4header-y += arch-v10/ 4header-y += ../arch-v10/arch/
5header-y += arch-v32/ 5header-y += ../arch-v32/arch/
6header-y += auxvec.h 6header-y += auxvec.h
7header-y += bitsperlong.h 7header-y += bitsperlong.h
8header-y += byteorder.h 8header-y += byteorder.h
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
index 5868cee20ebd..3908b942fd4c 100644
--- a/arch/cris/kernel/crisksyms.c
+++ b/arch/cris/kernel/crisksyms.c
@@ -47,16 +47,16 @@ EXPORT_SYMBOL(__negdi2);
47EXPORT_SYMBOL(__ioremap); 47EXPORT_SYMBOL(__ioremap);
48EXPORT_SYMBOL(iounmap); 48EXPORT_SYMBOL(iounmap);
49 49
50/* Userspace access functions */
51EXPORT_SYMBOL(__copy_user_zeroing);
52EXPORT_SYMBOL(__copy_user);
53
54#undef memcpy 50#undef memcpy
55#undef memset 51#undef memset
56extern void * memset(void *, int, __kernel_size_t); 52extern void * memset(void *, int, __kernel_size_t);
57extern void * memcpy(void *, const void *, __kernel_size_t); 53extern void * memcpy(void *, const void *, __kernel_size_t);
58EXPORT_SYMBOL(memcpy); 54EXPORT_SYMBOL(memcpy);
59EXPORT_SYMBOL(memset); 55EXPORT_SYMBOL(memset);
56#ifdef CONFIG_ETRAX_ARCH_V32
57#undef strcmp
58EXPORT_SYMBOL(strcmp);
59#endif
60 60
61#ifdef CONFIG_ETRAX_FAST_TIMER 61#ifdef CONFIG_ETRAX_FAST_TIMER
62/* Fast timer functions */ 62/* Fast timer functions */
@@ -66,3 +66,4 @@ EXPORT_SYMBOL(del_fast_timer);
66EXPORT_SYMBOL(schedule_usleep); 66EXPORT_SYMBOL(schedule_usleep);
67#endif 67#endif
68EXPORT_SYMBOL(csum_partial); 68EXPORT_SYMBOL(csum_partial);
69EXPORT_SYMBOL(csum_partial_copy_from_user);
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
index 51123f985eb5..af04cb6b6dc9 100644
--- a/arch/cris/kernel/module.c
+++ b/arch/cris/kernel/module.c
@@ -36,7 +36,7 @@ void *module_alloc(unsigned long size)
36} 36}
37 37
38/* Free memory returned from module_alloc */ 38/* Free memory returned from module_alloc */
39void module_free(struct module *mod, void *module_region) 39void module_memfree(void *module_region)
40{ 40{
41 kfree(module_region); 41 kfree(module_region);
42} 42}
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c
index 0ffda73734f5..da4c72401e27 100644
--- a/arch/cris/kernel/traps.c
+++ b/arch/cris/kernel/traps.c
@@ -14,6 +14,10 @@
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/utsname.h>
18#ifdef CONFIG_KALLSYMS
19#include <linux/kallsyms.h>
20#endif
17 21
18#include <asm/pgtable.h> 22#include <asm/pgtable.h>
19#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -34,25 +38,24 @@ static int kstack_depth_to_print = 24;
34 38
35void (*nmi_handler)(struct pt_regs *); 39void (*nmi_handler)(struct pt_regs *);
36 40
37void 41void show_trace(unsigned long *stack)
38show_trace(unsigned long *stack)
39{ 42{
40 unsigned long addr, module_start, module_end; 43 unsigned long addr, module_start, module_end;
41 extern char _stext, _etext; 44 extern char _stext, _etext;
42 int i; 45 int i;
43 46
44 printk("\nCall Trace: "); 47 pr_err("\nCall Trace: ");
45 48
46 i = 1; 49 i = 1;
47 module_start = VMALLOC_START; 50 module_start = VMALLOC_START;
48 module_end = VMALLOC_END; 51 module_end = VMALLOC_END;
49 52
50 while (((long)stack & (THREAD_SIZE-1)) != 0) { 53 while (((long)stack & (THREAD_SIZE - 1)) != 0) {
51 if (__get_user(addr, stack)) { 54 if (__get_user(addr, stack)) {
52 /* This message matches "failing address" marked 55 /* This message matches "failing address" marked
53 s390 in ksymoops, so lines containing it will 56 s390 in ksymoops, so lines containing it will
54 not be filtered out by ksymoops. */ 57 not be filtered out by ksymoops. */
55 printk("Failing address 0x%lx\n", (unsigned long)stack); 58 pr_err("Failing address 0x%lx\n", (unsigned long)stack);
56 break; 59 break;
57 } 60 }
58 stack++; 61 stack++;
@@ -68,10 +71,14 @@ show_trace(unsigned long *stack)
68 if (((addr >= (unsigned long)&_stext) && 71 if (((addr >= (unsigned long)&_stext) &&
69 (addr <= (unsigned long)&_etext)) || 72 (addr <= (unsigned long)&_etext)) ||
70 ((addr >= module_start) && (addr <= module_end))) { 73 ((addr >= module_start) && (addr <= module_end))) {
74#ifdef CONFIG_KALLSYMS
75 print_ip_sym(addr);
76#else
71 if (i && ((i % 8) == 0)) 77 if (i && ((i % 8) == 0))
72 printk("\n "); 78 pr_err("\n ");
73 printk("[<%08lx>] ", addr); 79 pr_err("[<%08lx>] ", addr);
74 i++; 80 i++;
81#endif
75 } 82 }
76 } 83 }
77} 84}
@@ -111,21 +118,21 @@ show_stack(struct task_struct *task, unsigned long *sp)
111 118
112 stack = sp; 119 stack = sp;
113 120
114 printk("\nStack from %08lx:\n ", (unsigned long)stack); 121 pr_err("\nStack from %08lx:\n ", (unsigned long)stack);
115 for (i = 0; i < kstack_depth_to_print; i++) { 122 for (i = 0; i < kstack_depth_to_print; i++) {
116 if (((long)stack & (THREAD_SIZE-1)) == 0) 123 if (((long)stack & (THREAD_SIZE-1)) == 0)
117 break; 124 break;
118 if (i && ((i % 8) == 0)) 125 if (i && ((i % 8) == 0))
119 printk("\n "); 126 pr_err("\n ");
120 if (__get_user(addr, stack)) { 127 if (__get_user(addr, stack)) {
121 /* This message matches "failing address" marked 128 /* This message matches "failing address" marked
122 s390 in ksymoops, so lines containing it will 129 s390 in ksymoops, so lines containing it will
123 not be filtered out by ksymoops. */ 130 not be filtered out by ksymoops. */
124 printk("Failing address 0x%lx\n", (unsigned long)stack); 131 pr_err("Failing address 0x%lx\n", (unsigned long)stack);
125 break; 132 break;
126 } 133 }
127 stack++; 134 stack++;
128 printk("%08lx ", addr); 135 pr_err("%08lx ", addr);
129 } 136 }
130 show_trace(sp); 137 show_trace(sp);
131} 138}
@@ -139,33 +146,32 @@ show_stack(void)
139 unsigned long *sp = (unsigned long *)rdusp(); 146 unsigned long *sp = (unsigned long *)rdusp();
140 int i; 147 int i;
141 148
142 printk("Stack dump [0x%08lx]:\n", (unsigned long)sp); 149 pr_err("Stack dump [0x%08lx]:\n", (unsigned long)sp);
143 for (i = 0; i < 16; i++) 150 for (i = 0; i < 16; i++)
144 printk("sp + %d: 0x%08lx\n", i*4, sp[i]); 151 pr_err("sp + %d: 0x%08lx\n", i*4, sp[i]);
145 return 0; 152 return 0;
146} 153}
147#endif 154#endif
148 155
149void 156void set_nmi_handler(void (*handler)(struct pt_regs *))
150set_nmi_handler(void (*handler)(struct pt_regs *))
151{ 157{
152 nmi_handler = handler; 158 nmi_handler = handler;
153 arch_enable_nmi(); 159 arch_enable_nmi();
154} 160}
155 161
156#ifdef CONFIG_DEBUG_NMI_OOPS 162#ifdef CONFIG_DEBUG_NMI_OOPS
157void 163void oops_nmi_handler(struct pt_regs *regs)
158oops_nmi_handler(struct pt_regs *regs)
159{ 164{
160 stop_watchdog(); 165 stop_watchdog();
161 oops_in_progress = 1; 166 oops_in_progress = 1;
162 printk("NMI!\n"); 167 pr_err("NMI!\n");
163 show_registers(regs); 168 show_registers(regs);
164 oops_in_progress = 0; 169 oops_in_progress = 0;
170 oops_exit();
171 pr_err("\n"); /* Flush mtdoops. */
165} 172}
166 173
167static int __init 174static int __init oops_nmi_register(void)
168oops_nmi_register(void)
169{ 175{
170 set_nmi_handler(oops_nmi_handler); 176 set_nmi_handler(oops_nmi_handler);
171 return 0; 177 return 0;
@@ -180,8 +186,7 @@ __initcall(oops_nmi_register);
180 * similar to an Oops dump, and if the kernel is configured to be a nice 186 * similar to an Oops dump, and if the kernel is configured to be a nice
181 * doggy, then halt instead of reboot. 187 * doggy, then halt instead of reboot.
182 */ 188 */
183void 189void watchdog_bite_hook(struct pt_regs *regs)
184watchdog_bite_hook(struct pt_regs *regs)
185{ 190{
186#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 191#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
187 local_irq_disable(); 192 local_irq_disable();
@@ -196,8 +201,7 @@ watchdog_bite_hook(struct pt_regs *regs)
196} 201}
197 202
198/* This is normally the Oops function. */ 203/* This is normally the Oops function. */
199void 204void die_if_kernel(const char *str, struct pt_regs *regs, long err)
200die_if_kernel(const char *str, struct pt_regs *regs, long err)
201{ 205{
202 if (user_mode(regs)) 206 if (user_mode(regs))
203 return; 207 return;
@@ -211,13 +215,17 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err)
211 stop_watchdog(); 215 stop_watchdog();
212#endif 216#endif
213 217
218 oops_enter();
214 handle_BUG(regs); 219 handle_BUG(regs);
215 220
216 printk("%s: %04lx\n", str, err & 0xffff); 221 pr_err("Linux %s %s\n", utsname()->release, utsname()->version);
222 pr_err("%s: %04lx\n", str, err & 0xffff);
217 223
218 show_registers(regs); 224 show_registers(regs);
219 225
226 oops_exit();
220 oops_in_progress = 0; 227 oops_in_progress = 0;
228 pr_err("\n"); /* Flush mtdoops. */
221 229
222#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY 230#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
223 reset_watchdog(); 231 reset_watchdog();
@@ -225,8 +233,7 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err)
225 do_exit(SIGSEGV); 233 do_exit(SIGSEGV);
226} 234}
227 235
228void __init 236void __init trap_init(void)
229trap_init(void)
230{ 237{
231 /* Nothing needs to be done */ 238 /* Nothing needs to be done */
232} 239}
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index c81af5bd9167..1e7fd45b60f8 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -11,13 +11,15 @@
11#include <linux/gfp.h> 11#include <linux/gfp.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/proc_fs.h>
15#include <linux/kcore.h>
14#include <asm/tlb.h> 16#include <asm/tlb.h>
15#include <asm/sections.h> 17#include <asm/sections.h>
16 18
17unsigned long empty_zero_page; 19unsigned long empty_zero_page;
20EXPORT_SYMBOL(empty_zero_page);
18 21
19void __init 22void __init mem_init(void)
20mem_init(void)
21{ 23{
22 BUG_ON(!mem_map); 24 BUG_ON(!mem_map);
23 25
@@ -31,10 +33,36 @@ mem_init(void)
31 mem_init_print_info(NULL); 33 mem_init_print_info(NULL);
32} 34}
33 35
34/* free the pages occupied by initialization code */ 36/* Free a range of init pages. Virtual addresses. */
35 37
36void 38void free_init_pages(const char *what, unsigned long begin, unsigned long end)
37free_initmem(void) 39{
40 unsigned long addr;
41
42 for (addr = begin; addr < end; addr += PAGE_SIZE) {
43 ClearPageReserved(virt_to_page(addr));
44 init_page_count(virt_to_page(addr));
45 free_page(addr);
46 totalram_pages++;
47 }
48
49 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
50}
51
52/* Free the pages occupied by initialization code. */
53
54void free_initmem(void)
38{ 55{
39 free_initmem_default(-1); 56 free_initmem_default(-1);
40} 57}
58
59/* Free the pages occupied by initrd code. */
60
61#ifdef CONFIG_BLK_DEV_INITRD
62void free_initrd_mem(unsigned long start, unsigned long end)
63{
64 free_init_pages("initrd memory",
65 start,
66 end);
67}
68#endif
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index f9ca44bdea20..80fdb995a8ce 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -76,10 +76,11 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
76 * Must be freed with iounmap. 76 * Must be freed with iounmap.
77 */ 77 */
78 78
79void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) 79void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
80{ 80{
81 return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0); 81 return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0);
82} 82}
83EXPORT_SYMBOL(ioremap_nocache);
83 84
84void iounmap(volatile void __iomem *addr) 85void iounmap(volatile void __iomem *addr)
85{ 86{