Commit 3f10462f292e5d8f3bb2a19fa62f442bd8c4df5a

Authored by Jesper Nilsson
1 parent 80d6170a28

CRISv32: Rewrite of synchronous serial port driver

Make driver possible to load as a module and try to handle
locking better.

Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>

Showing 1 changed file with 791 additions and 639 deletions Side-by-side Diff

arch/cris/arch-v32/drivers/sync_serial.c
Changes suppressed. Click to show
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 3 *
4   - * Copyright (c) 2005 Axis Communications AB
5   - *
  4 + * Copyright (c) 2005, 2008 Axis Communications AB
6 5 * Author: Mikael Starvik
7 6 *
8 7 */
9 8  
10 9  
... ... @@ -16,16 +15,17 @@
16 15 #include <linux/mutex.h>
17 16 #include <linux/interrupt.h>
18 17 #include <linux/poll.h>
19   -#include <linux/init.h>
20   -#include <linux/timer.h>
21   -#include <linux/spinlock.h>
  18 +#include <linux/fs.h>
  19 +#include <linux/cdev.h>
  20 +#include <linux/device.h>
22 21 #include <linux/wait.h>
23 22  
24 23 #include <asm/io.h>
25   -#include <dma.h>
  24 +#include <mach/dma.h>
26 25 #include <pinmux.h>
27 26 #include <hwregs/reg_rdwr.h>
28 27 #include <hwregs/sser_defs.h>
  28 +#include <hwregs/timer_defs.h>
29 29 #include <hwregs/dma_defs.h>
30 30 #include <hwregs/dma.h>
31 31 #include <hwregs/intr_vect_defs.h>
32 32  
33 33  
34 34  
35 35  
36 36  
... ... @@ -59,22 +59,23 @@
59 59 /* the rest of the data pointed out by Descr1 and set readp to the start */
60 60 /* of Descr2 */
61 61  
62   -#define SYNC_SERIAL_MAJOR 125
63   -
64 62 /* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
65 63 /* words can be handled */
66   -#define IN_BUFFER_SIZE 12288
67   -#define IN_DESCR_SIZE 256
68   -#define NBR_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
  64 +#define IN_DESCR_SIZE SSP_INPUT_CHUNK_SIZE
  65 +#define NBR_IN_DESCR (8*6)
  66 +#define IN_BUFFER_SIZE (IN_DESCR_SIZE * NBR_IN_DESCR)
69 67  
70   -#define OUT_BUFFER_SIZE 1024*8
71 68 #define NBR_OUT_DESCR 8
  69 +#define OUT_BUFFER_SIZE (1024 * NBR_OUT_DESCR)
72 70  
73 71 #define DEFAULT_FRAME_RATE 0
74 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 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 80 #define DEBUG(x)
80 81 #define DEBUGREAD(x)
81 82  
... ... @@ -85,12 +86,29 @@
85 86 #define DEBUGTRDMA(x)
86 87 #define DEBUGOUTBUF(x)
87 88  
88   -typedef struct sync_port
89   -{
90   - reg_scope_instances regi_sser;
91   - reg_scope_instances regi_dmain;
92   - reg_scope_instances regi_dmaout;
  89 +enum syncser_irq_setup {
  90 + no_irq_setup = 0,
  91 + dma_irq_setup = 1,
  92 + manual_irq_setup = 2,
  93 +};
93 94  
  95 +struct 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;
  111 +
94 112 char started; /* 1 if port has been started */
95 113 char port_nbr; /* Port 0 or 1 */
96 114 char busy; /* 1 if port is busy */
97 115  
98 116  
99 117  
100 118  
101 119  
... ... @@ -99,23 +117,30 @@
99 117 char use_dma; /* 1 if port uses dma */
100 118 char tr_running;
101 119  
102   - char init_irqs;
  120 + enum syncser_irq_setup init_irqs;
103 121 int output;
104 122 int input;
105 123  
106 124 /* Next byte to be read by application */
107   - volatile unsigned char *volatile readp;
  125 + unsigned char *readp;
108 126 /* Next byte to be written by etrax */
109   - volatile unsigned char *volatile writep;
  127 + unsigned char *writep;
110 128  
111 129 unsigned int in_buffer_size;
  130 + unsigned int in_buffer_len;
112 131 unsigned int inbufchunk;
113   - unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
114   - unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32)));
115   - unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
116   - struct dma_descr_data* next_rx_desc;
117   - struct dma_descr_data* prev_rx_desc;
  132 + /* Data buffers for in and output. */
  133 + unsigned char out_buffer[OUT_BUFFER_SIZE] __aligned(32);
  134 + unsigned char in_buffer[IN_BUFFER_SIZE] __aligned(32);
  135 + unsigned char flip[IN_BUFFER_SIZE] __aligned(32);
  136 + struct timespec timestamp[NBR_IN_DESCR];
  137 + struct dma_descr_data *next_rx_desc;
  138 + struct dma_descr_data *prev_rx_desc;
118 139  
  140 + struct timeval last_timestamp;
  141 + int read_ts_idx;
  142 + int write_ts_idx;
  143 +
119 144 /* Pointer to the first available descriptor in the ring,
120 145 * unless active_tr_descr == catch_tr_descr and a dma
121 146 * transfer is active */
122 147  
123 148  
124 149  
125 150  
126 151  
127 152  
128 153  
129 154  
130 155  
131 156  
132 157  
133 158  
134 159  
135 160  
136 161  
137 162  
138 163  
139 164  
140 165  
141 166  
... ... @@ -135,114 +160,138 @@
135 160 /* Number of bytes currently locked for being read by DMA */
136 161 int out_buf_count;
137 162  
138   - dma_descr_data in_descr[NBR_IN_DESCR] __attribute__ ((__aligned__(16)));
139   - dma_descr_context in_context __attribute__ ((__aligned__(32)));
140   - dma_descr_data out_descr[NBR_OUT_DESCR]
141   - __attribute__ ((__aligned__(16)));
142   - dma_descr_context out_context __attribute__ ((__aligned__(32)));
  163 + dma_descr_context in_context __aligned(32);
  164 + dma_descr_context out_context __aligned(32);
  165 + dma_descr_data in_descr[NBR_IN_DESCR] __aligned(16);
  166 + dma_descr_data out_descr[NBR_OUT_DESCR] __aligned(16);
  167 +
143 168 wait_queue_head_t out_wait_q;
144 169 wait_queue_head_t in_wait_q;
145 170  
146 171 spinlock_t lock;
147   -} sync_port;
  172 +};
148 173  
149 174 static DEFINE_MUTEX(sync_serial_mutex);
150 175 static int etrax_sync_serial_init(void);
151 176 static void initialize_port(int portnbr);
152 177 static inline int sync_data_avail(struct sync_port *port);
153 178  
154   -static int sync_serial_open(struct inode *, struct file*);
155   -static int sync_serial_release(struct inode*, struct file*);
  179 +static int sync_serial_open(struct inode *, struct file *);
  180 +static int sync_serial_release(struct inode *, struct file *);
156 181 static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
157 182  
158   -static int sync_serial_ioctl(struct file *,
159   - unsigned int cmd, unsigned long arg);
160   -static ssize_t sync_serial_write(struct file * file, const char * buf,
  183 +static long sync_serial_ioctl(struct file *file,
  184 + unsigned int cmd, unsigned long arg);
  185 +static int sync_serial_ioctl_unlocked(struct file *file,
  186 + unsigned int cmd, unsigned long arg);
  187 +static ssize_t sync_serial_write(struct file *file, const char __user *buf,
161 188 size_t count, loff_t *ppos);
162   -static ssize_t sync_serial_read(struct file *file, char *buf,
  189 +static ssize_t sync_serial_read(struct file *file, char __user *buf,
163 190 size_t count, loff_t *ppos);
164 191  
165   -#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
166   - defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
167   - (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
168   - defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
  192 +#if ((defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
  193 + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
  194 + (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
  195 + defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)))
169 196 #define SYNC_SER_DMA
  197 +#else
  198 +#define SYNC_SER_MANUAL
170 199 #endif
171 200  
172   -static void send_word(sync_port* port);
173   -static void start_dma_out(struct sync_port *port, const char *data, int count);
174   -static void start_dma_in(sync_port* port);
175 201 #ifdef SYNC_SER_DMA
  202 +static void start_dma_out(struct sync_port *port, const char *data, int count);
  203 +static void start_dma_in(struct sync_port *port);
176 204 static irqreturn_t tr_interrupt(int irq, void *dev_id);
177 205 static irqreturn_t rx_interrupt(int irq, void *dev_id);
178 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 207 #ifdef SYNC_SER_MANUAL
  208 +static void send_word(struct sync_port *port);
187 209 static irqreturn_t manual_interrupt(int irq, void *dev_id);
188 210 #endif
189 211  
190   -#ifdef CONFIG_ETRAXFS /* ETRAX FS */
191   -#define OUT_DMA_NBR 4
192   -#define IN_DMA_NBR 5
193   -#define PINMUX_SSER pinmux_sser0
194   -#define SYNCSER_INST regi_sser0
195   -#define SYNCSER_INTR_VECT SSER0_INTR_VECT
196   -#define OUT_DMA_INST regi_dma4
197   -#define IN_DMA_INST regi_dma5
198   -#define DMA_OUT_INTR_VECT DMA4_INTR_VECT
199   -#define DMA_IN_INTR_VECT DMA5_INTR_VECT
200   -#define REQ_DMA_SYNCSER dma_sser0
201   -#else /* Artpec-3 */
202   -#define OUT_DMA_NBR 6
203   -#define IN_DMA_NBR 7
204   -#define PINMUX_SSER pinmux_sser
205   -#define SYNCSER_INST regi_sser
206   -#define SYNCSER_INTR_VECT SSER_INTR_VECT
207   -#define OUT_DMA_INST regi_dma6
208   -#define IN_DMA_INST regi_dma7
209   -#define DMA_OUT_INTR_VECT DMA6_INTR_VECT
210   -#define DMA_IN_INTR_VECT DMA7_INTR_VECT
211   -#define REQ_DMA_SYNCSER dma_sser
  212 +#define artpec_pinmux_alloc_fixed crisv32_pinmux_alloc_fixed
  213 +#define artpec_request_dma crisv32_request_dma
  214 +#define artpec_free_dma crisv32_free_dma
  215 +
  216 +#ifdef CONFIG_ETRAXFS
  217 +/* ETRAX FS */
  218 +#define DMA_OUT_NBR0 SYNC_SER0_TX_DMA_NBR
  219 +#define DMA_IN_NBR0 SYNC_SER0_RX_DMA_NBR
  220 +#define DMA_OUT_NBR1 SYNC_SER1_TX_DMA_NBR
  221 +#define DMA_IN_NBR1 SYNC_SER1_RX_DMA_NBR
  222 +#define PINMUX_SSER0 pinmux_sser0
  223 +#define PINMUX_SSER1 pinmux_sser1
  224 +#define SYNCSER_INST0 regi_sser0
  225 +#define SYNCSER_INST1 regi_sser1
  226 +#define SYNCSER_INTR_VECT0 SSER0_INTR_VECT
  227 +#define SYNCSER_INTR_VECT1 SSER1_INTR_VECT
  228 +#define OUT_DMA_INST0 regi_dma4
  229 +#define IN_DMA_INST0 regi_dma5
  230 +#define DMA_OUT_INTR_VECT0 DMA4_INTR_VECT
  231 +#define DMA_OUT_INTR_VECT1 DMA7_INTR_VECT
  232 +#define DMA_IN_INTR_VECT0 DMA5_INTR_VECT
  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
212 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
  254 +#endif
213 255  
214   -/* The ports */
215   -static struct sync_port ports[]=
216   -{
217   - {
218   - .regi_sser = SYNCSER_INST,
219   - .regi_dmaout = OUT_DMA_INST,
220   - .regi_dmain = IN_DMA_INST,
221 256 #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
222   - .use_dma = 1,
  257 +#define PORT0_DMA 1
223 258 #else
224   - .use_dma = 0,
  259 +#define PORT0_DMA 0
225 260 #endif
226   - }
227   -#ifdef CONFIG_ETRAXFS
228   - ,
229 261  
  262 +/* The ports */
  263 +static struct sync_port ports[] = {
230 264 {
231   - .regi_sser = regi_sser1,
232   - .regi_dmaout = regi_dma6,
233   - .regi_dmain = regi_dma7,
234   -#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
235   - .use_dma = 1,
236   -#else
237   - .use_dma = 0,
  265 + .regi_sser = SYNCSER_INST0,
  266 + .regi_dmaout = OUT_DMA_INST0,
  267 + .regi_dmain = IN_DMA_INST0,
  268 + .use_dma = PORT0_DMA,
  269 + .dma_in_intr_vect = DMA_IN_INTR_VECT0,
  270 + .dma_out_intr_vect = DMA_OUT_INTR_VECT0,
  271 + .dma_in_nbr = DMA_IN_NBR0,
  272 + .dma_out_nbr = DMA_OUT_NBR0,
  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 + },
238 289 #endif
239   - }
240   -#endif
241 290 };
242 291  
243 292 #define NBR_PORTS ARRAY_SIZE(ports)
244 293  
245   -static const struct file_operations sync_serial_fops = {
  294 +static const struct file_operations syncser_fops = {
246 295 .owner = THIS_MODULE,
247 296 .write = sync_serial_write,
248 297 .read = sync_serial_read,
249 298  
250 299  
251 300  
252 301  
253 302  
... ... @@ -253,61 +302,40 @@
253 302 .llseek = noop_llseek,
254 303 };
255 304  
256   -static int __init etrax_sync_serial_init(void)
257   -{
258   - ports[0].enabled = 0;
259   -#ifdef CONFIG_ETRAXFS
260   - ports[1].enabled = 0;
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   - }
  305 +static dev_t syncser_first;
  306 +static int minor_count = NBR_PORTS;
  307 +#define SYNCSER_NAME "syncser"
  308 +static struct cdev *syncser_cdev;
  309 +static struct class *syncser_class;
268 310  
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   -
290   -#ifdef CONFIG_ETRAXFS
291   - printk(KERN_INFO "ETRAX FS synchronous serial port driver\n");
292   -#else
293   - printk(KERN_INFO "Artpec-3 synchronous serial port driver\n");
294   -#endif
295   - return 0;
  311 +static void sync_serial_start_port(struct sync_port *port)
  312 +{
  313 + reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
  314 + reg_sser_rw_tr_cfg tr_cfg =
  315 + REG_RD(sser, port->regi_sser, rw_tr_cfg);
  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  
298 327 static void __init initialize_port(int portnbr)
299 328 {
300   - int __attribute__((unused)) i;
301 329 struct sync_port *port = &ports[portnbr];
302   - reg_sser_rw_cfg cfg = {0};
303   - reg_sser_rw_frm_cfg frm_cfg = {0};
304   - reg_sser_rw_tr_cfg tr_cfg = {0};
305   - reg_sser_rw_rec_cfg rec_cfg = {0};
  330 + reg_sser_rw_cfg cfg = { 0 };
  331 + reg_sser_rw_frm_cfg frm_cfg = { 0 };
  332 + reg_sser_rw_tr_cfg tr_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 337 port->port_nbr = portnbr;
310   - port->init_irqs = 1;
  338 + port->init_irqs = no_irq_setup;
311 339  
312 340 port->out_rd_ptr = port->out_buffer;
313 341 port->out_buf_count = 0;
314 342  
315 343  
... ... @@ -318,11 +346,12 @@
318 346 port->readp = port->flip;
319 347 port->writep = port->flip;
320 348 port->in_buffer_size = IN_BUFFER_SIZE;
  349 + port->in_buffer_len = 0;
321 350 port->inbufchunk = IN_DESCR_SIZE;
322   - port->next_rx_desc = &port->in_descr[0];
323   - port->prev_rx_desc = &port->in_descr[NBR_IN_DESCR-1];
324   - port->prev_rx_desc->eol = 1;
325 351  
  352 + port->read_ts_idx = 0;
  353 + port->write_ts_idx = 0;
  354 +
326 355 init_waitqueue_head(&port->out_wait_q);
327 356 init_waitqueue_head(&port->in_wait_q);
328 357  
... ... @@ -368,14 +397,18 @@
368 397 REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
369 398  
370 399 #ifdef SYNC_SER_DMA
371   - /* Setup the descriptor ring for dma out/transmit. */
372   - for (i = 0; i < NBR_OUT_DESCR; i++) {
373   - port->out_descr[i].wait = 0;
374   - port->out_descr[i].intr = 1;
375   - port->out_descr[i].eol = 0;
376   - port->out_descr[i].out_eop = 0;
377   - port->out_descr[i].next =
378   - (dma_descr_data *)virt_to_phys(&port->out_descr[i+1]);
  400 + {
  401 + int i;
  402 + /* Setup the descriptor ring for dma out/transmit. */
  403 + for (i = 0; i < NBR_OUT_DESCR; i++) {
  404 + dma_descr_data *descr = &port->out_descr[i];
  405 + descr->wait = 0;
  406 + descr->intr = 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 414 /* Create a ring from the list. */
382 415  
383 416  
384 417  
385 418  
386 419  
387 420  
388 421  
389 422  
390 423  
391 424  
392 425  
393 426  
394 427  
395 428  
... ... @@ -391,201 +424,116 @@
391 424  
392 425 static inline int sync_data_avail(struct sync_port *port)
393 426 {
394   - int avail;
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;
  427 + return port->in_buffer_len;
410 428 }
411 429  
412   -static 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   -}
431   -
432 430 static int sync_serial_open(struct inode *inode, struct file *file)
433 431 {
  432 + int ret = 0;
434 433 int dev = iminor(inode);
435   - int ret = -EBUSY;
436   - sync_port *port;
437   - reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
438   - reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
  434 + struct sync_port *port;
  435 +#ifdef SYNC_SER_DMA
  436 + reg_dma_rw_cfg cfg = { .en = 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);
441   - DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
  440 + DEBUG(pr_debug("Open sync serial port %d\n", dev));
442 441  
443   - if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
444   - {
445   - DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
446   - ret = -ENODEV;
447   - goto out;
  442 + if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
  443 + DEBUG(pr_info("Invalid minor %d\n", dev));
  444 + return -ENODEV;
448 445 }
449 446 port = &ports[dev];
450 447 /* Allow open this device twice (assuming one reader and one writer) */
451   - if (port->busy == 2)
452   - {
453   - DEBUG(printk(KERN_DEBUG "Device is busy.. \n"));
454   - goto out;
  448 + if (port->busy == 2) {
  449 + DEBUG(pr_info("syncser%d is busy\n", dev));
  450 + return -EBUSY;
455 451 }
456 452  
  453 + mutex_lock(&sync_serial_mutex);
457 454  
458   - if (port->init_irqs) {
459   - if (port->use_dma) {
460   - if (port == &ports[0]) {
  455 + /* Clear any stale date left in the flip buffer */
  456 + port->readp = port->writep = port->flip;
  457 + port->in_buffer_len = 0;
  458 + port->read_ts_idx = 0;
  459 + port->write_ts_idx = 0;
  460 +
  461 + if (port->init_irqs != no_irq_setup) {
  462 + /* Init only on first call. */
  463 + port->busy++;
  464 + mutex_unlock(&sync_serial_mutex);
  465 + return 0;
  466 + }
  467 + if (port->use_dma) {
461 468 #ifdef SYNC_SER_DMA
462   - if (request_irq(DMA_OUT_INTR_VECT,
463   - tr_interrupt,
464   - 0,
465   - "synchronous serial 0 dma tr",
466   - &ports[0])) {
467   - printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
468   - goto out;
469   - } else if (request_irq(DMA_IN_INTR_VECT,
470   - rx_interrupt,
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
502   - if (request_irq(DMA6_INTR_VECT,
503   - tr_interrupt,
504   - 0,
505   - "synchronous serial 1 dma tr",
506   - &ports[1])) {
507   - printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
508   - goto out;
509   - } else if (request_irq(DMA7_INTR_VECT,
510   - rx_interrupt,
511   - 0,
512   - "synchronous serial 1 dma rx",
513   - &ports[1])) {
514   - free_irq(DMA6_INTR_VECT, &ports[1]);
515   - printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
516   - goto out;
517   - } else if (crisv32_request_dma(
518   - SYNC_SER1_TX_DMA_NBR,
519   - "synchronous serial 1 dma tr",
520   - DMA_VERBOSE_ON_ERROR,
521   - 0,
522   - dma_sser1)) {
523   - free_irq(DMA6_INTR_VECT, &ports[1]);
524   - free_irq(DMA7_INTR_VECT, &ports[1]);
525   - printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
526   - goto out;
527   - } else if (crisv32_request_dma(
528   - SYNC_SER1_RX_DMA_NBR,
529   - "synchronous serial 3 dma rec",
530   - DMA_VERBOSE_ON_ERROR,
531   - 0,
532   - dma_sser1)) {
533   - crisv32_free_dma(SYNC_SER1_TX_DMA_NBR);
534   - free_irq(DMA6_INTR_VECT, &ports[1]);
535   - free_irq(DMA7_INTR_VECT, &ports[1]);
536   - printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel");
537   - goto out;
538   - }
539   -#endif
540   - }
541   -#endif
542   - /* Enable DMAs */
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);
  469 + const char *tmp;
  470 + DEBUG(pr_info("Using DMA for syncser%d\n", dev));
551 471  
552   - start_dma_in(port);
553   - port->init_irqs = 0;
554   - } else { /* !port->use_dma */
555   -#ifdef SYNC_SER_MANUAL
556   - if (port == &ports[0]) {
557   - if (request_irq(SYNCSER_INTR_VECT,
558   - manual_interrupt,
559   - 0,
560   - "synchronous serial manual irq",
561   - &ports[0])) {
562   - printk("Can't allocate sync serial manual irq");
563   - goto out;
564   - }
565   - }
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   - }
  472 + tmp = dev == 0 ? "syncser0 tx" : "syncser1 tx";
  473 + if (request_irq(port->dma_out_intr_vect, tr_interrupt, 0,
  474 + tmp, port)) {
  475 + pr_err("Can't alloc syncser%d TX IRQ", dev);
  476 + ret = -EBUSY;
  477 + goto unlock_and_exit;
  478 + }
  479 + if (artpec_request_dma(port->dma_out_nbr, tmp,
  480 + DMA_VERBOSE_ON_ERROR, 0, port->req_dma)) {
  481 + free_irq(port->dma_out_intr_vect, port);
  482 + pr_err("Can't alloc syncser%d TX DMA", dev);
  483 + ret = -EBUSY;
  484 + goto unlock_and_exit;
  485 + }
  486 + tmp = dev == 0 ? "syncser0 rx" : "syncser1 rx";
  487 + if (request_irq(port->dma_in_intr_vect, rx_interrupt, 0,
  488 + tmp, port)) {
  489 + artpec_free_dma(port->dma_out_nbr);
  490 + free_irq(port->dma_out_intr_vect, port);
  491 + pr_err("Can't alloc syncser%d RX IRQ", dev);
  492 + ret = -EBUSY;
  493 + goto unlock_and_exit;
  494 + }
  495 + if (artpec_request_dma(port->dma_in_nbr, tmp,
  496 + DMA_VERBOSE_ON_ERROR, 0, port->req_dma)) {
  497 + artpec_free_dma(port->dma_out_nbr);
  498 + free_irq(port->dma_out_intr_vect, port);
  499 + free_irq(port->dma_in_intr_vect, port);
  500 + pr_err("Can't alloc syncser%d RX DMA", dev);
  501 + ret = -EBUSY;
  502 + goto unlock_and_exit;
  503 + }
  504 + /* Enable DMAs */
  505 + REG_WR(dma, port->regi_dmain, rw_cfg, cfg);
  506 + REG_WR(dma, port->regi_dmaout, rw_cfg, cfg);
  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;
577 516 #endif
578   - port->init_irqs = 0;
  517 + } else { /* !port->use_dma */
  518 +#ifdef SYNC_SER_MANUAL
  519 + const char *tmp = dev == 0 ? "syncser0 manual irq" :
  520 + "syncser1 manual irq";
  521 + if (request_irq(port->syncser_intr_vect, manual_interrupt,
  522 + 0, tmp, port)) {
  523 + pr_err("Can't alloc syncser%d manual irq",
  524 + dev);
  525 + ret = -EBUSY;
  526 + goto unlock_and_exit;
  527 + }
  528 + port->init_irqs = manual_irq_setup;
579 529 #else
580   - panic("sync_serial: Manual mode not supported.\n");
  530 + panic("sync_serial: Manual mode not supported\n");
581 531 #endif /* SYNC_SER_MANUAL */
582   - }
583   -
584   - } /* port->init_irqs */
585   -
  532 + }
586 533 port->busy++;
587 534 ret = 0;
588   -out:
  535 +
  536 +unlock_and_exit:
589 537 mutex_unlock(&sync_serial_mutex);
590 538 return ret;
591 539 }
592 540  
593 541  
... ... @@ -593,18 +541,17 @@
593 541 static int sync_serial_release(struct inode *inode, struct file *file)
594 542 {
595 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)
599   - {
600   - DEBUG(printk("Invalid minor %d\n", dev));
  546 + if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
  547 + DEBUG(pr_info("Invalid minor %d\n", dev));
601 548 return -ENODEV;
602 549 }
603 550 port = &ports[dev];
604 551 if (port->busy)
605 552 port->busy--;
606 553 if (!port->busy)
607   - /* XXX */ ;
  554 + /* XXX */;
608 555 return 0;
609 556 }
610 557  
611 558  
... ... @@ -612,21 +559,15 @@
612 559 {
613 560 int dev = iminor(file_inode(file));
614 561 unsigned int mask = 0;
615   - sync_port *port;
616   - DEBUGPOLL( static unsigned int prev_mask = 0; );
  562 + struct sync_port *port;
  563 + DEBUGPOLL(
  564 + static unsigned int prev_mask;
  565 + );
617 566  
618 567 port = &ports[dev];
619 568  
620   - if (!port->started) {
621   - reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
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   - }
  569 + if (!port->started)
  570 + sync_serial_start_port(port);
630 571  
631 572 poll_wait(file, &port->out_wait_q, wait);
632 573 poll_wait(file, &port->in_wait_q, wait);
633 574  
634 575  
635 576  
636 577  
637 578  
... ... @@ -645,33 +586,175 @@
645 586 if (port->input && sync_data_avail(port) >= port->inbufchunk)
646 587 mask |= POLLIN | POLLRDNORM;
647 588  
648   - DEBUGPOLL(if (mask != prev_mask)
649   - printk("sync_serial_poll: mask 0x%08X %s %s\n", mask,
650   - mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":"");
651   - prev_mask = mask;
652   - );
  589 + DEBUGPOLL(
  590 + if (mask != prev_mask)
  591 + pr_info("sync_serial_poll: mask 0x%08X %s %s\n",
  592 + mask,
  593 + mask & POLLOUT ? "POLLOUT" : "",
  594 + mask & POLLIN ? "POLLIN" : "");
  595 + prev_mask = mask;
  596 + );
653 597 return mask;
654 598 }
655 599  
656   -static int sync_serial_ioctl(struct file *file,
657   - unsigned int cmd, unsigned long arg)
  600 +static ssize_t __sync_serial_read(struct file *file,
  601 + char __user *buf,
  602 + size_t count,
  603 + loff_t *ppos,
  604 + struct timespec *ts)
658 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 +
  688 +static 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 +
  736 +static int sync_serial_ioctl_unlocked(struct file *file,
  737 + unsigned int cmd, unsigned long arg)
  738 +{
659 739 int return_val = 0;
660 740 int dma_w_size = regk_dma_set_w_size1;
661 741 int dev = iminor(file_inode(file));
662   - sync_port *port;
  742 + struct sync_port *port;
663 743 reg_sser_rw_tr_cfg tr_cfg;
664 744 reg_sser_rw_rec_cfg rec_cfg;
665 745 reg_sser_rw_frm_cfg frm_cfg;
666 746 reg_sser_rw_cfg gen_cfg;
667 747 reg_sser_rw_intr_mask intr_mask;
668 748  
669   - if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
670   - {
671   - DEBUG(printk("Invalid minor %d\n", dev));
  749 + if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled) {
  750 + DEBUG(pr_info("Invalid minor %d\n", dev));
672 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 758 spin_lock_irq(&port->lock);
676 759  
677 760 tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
678 761  
... ... @@ -680,11 +763,9 @@
680 763 gen_cfg = REG_RD(sser, port->regi_sser, rw_cfg);
681 764 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
682 765  
683   - switch(cmd)
684   - {
  766 + switch (cmd) {
685 767 case SSP_SPEED:
686   - if (GET_SPEED(arg) == CODEC)
687   - {
  768 + if (GET_SPEED(arg) == CODEC) {
688 769 unsigned int freq;
689 770  
690 771 gen_cfg.base_freq = regk_sser_f32;
691 772  
692 773  
693 774  
... ... @@ -701,16 +782,26 @@
701 782 case FREQ_256kHz:
702 783 gen_cfg.clk_div = 125 *
703 784 (1 << (freq - FREQ_256kHz)) - 1;
704   - break;
  785 + break;
705 786 case FREQ_512kHz:
706 787 gen_cfg.clk_div = 62;
707   - break;
  788 + break;
708 789 case FREQ_1MHz:
709 790 case FREQ_2MHz:
710 791 case FREQ_4MHz:
711 792 gen_cfg.clk_div = 8 * (1 << freq) - 1;
712   - break;
  793 + break;
713 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;
  804 + }
714 805 } else {
715 806 gen_cfg.base_freq = regk_sser_f29_493;
716 807 switch (GET_SPEED(arg)) {
717 808  
718 809  
719 810  
... ... @@ -767,62 +858,64 @@
767 858  
768 859 break;
769 860 case SSP_MODE:
770   - switch(arg)
771   - {
772   - case MASTER_OUTPUT:
773   - port->output = 1;
774   - port->input = 0;
775   - frm_cfg.out_on = regk_sser_tr;
776   - frm_cfg.frame_pin_dir = regk_sser_out;
777   - gen_cfg.clk_dir = regk_sser_out;
778   - break;
779   - case SLAVE_OUTPUT:
780   - port->output = 1;
781   - port->input = 0;
782   - frm_cfg.frame_pin_dir = regk_sser_in;
783   - gen_cfg.clk_dir = regk_sser_in;
784   - break;
785   - case MASTER_INPUT:
786   - port->output = 0;
787   - port->input = 1;
788   - frm_cfg.frame_pin_dir = regk_sser_out;
789   - frm_cfg.out_on = regk_sser_intern_tb;
790   - gen_cfg.clk_dir = regk_sser_out;
791   - break;
792   - case SLAVE_INPUT:
793   - port->output = 0;
794   - port->input = 1;
795   - frm_cfg.frame_pin_dir = regk_sser_in;
796   - gen_cfg.clk_dir = regk_sser_in;
797   - break;
798   - case MASTER_BIDIR:
799   - port->output = 1;
800   - port->input = 1;
801   - frm_cfg.frame_pin_dir = regk_sser_out;
802   - frm_cfg.out_on = regk_sser_intern_tb;
803   - gen_cfg.clk_dir = regk_sser_out;
804   - break;
805   - case SLAVE_BIDIR:
806   - port->output = 1;
807   - port->input = 1;
808   - frm_cfg.frame_pin_dir = regk_sser_in;
809   - gen_cfg.clk_dir = regk_sser_in;
810   - break;
811   - default:
812   - spin_unlock_irq(&port->lock);
813   - return -EINVAL;
  861 + switch (arg) {
  862 + case MASTER_OUTPUT:
  863 + port->output = 1;
  864 + port->input = 0;
  865 + frm_cfg.out_on = regk_sser_tr;
  866 + frm_cfg.frame_pin_dir = regk_sser_out;
  867 + gen_cfg.clk_dir = regk_sser_out;
  868 + break;
  869 + case SLAVE_OUTPUT:
  870 + port->output = 1;
  871 + port->input = 0;
  872 + frm_cfg.frame_pin_dir = regk_sser_in;
  873 + gen_cfg.clk_dir = regk_sser_in;
  874 + break;
  875 + case MASTER_INPUT:
  876 + port->output = 0;
  877 + port->input = 1;
  878 + frm_cfg.frame_pin_dir = regk_sser_out;
  879 + frm_cfg.out_on = regk_sser_intern_tb;
  880 + gen_cfg.clk_dir = regk_sser_out;
  881 + break;
  882 + case SLAVE_INPUT:
  883 + port->output = 0;
  884 + port->input = 1;
  885 + frm_cfg.frame_pin_dir = regk_sser_in;
  886 + gen_cfg.clk_dir = regk_sser_in;
  887 + break;
  888 + case MASTER_BIDIR:
  889 + port->output = 1;
  890 + port->input = 1;
  891 + frm_cfg.frame_pin_dir = regk_sser_out;
  892 + frm_cfg.out_on = regk_sser_intern_tb;
  893 + gen_cfg.clk_dir = regk_sser_out;
  894 + break;
  895 + case SLAVE_BIDIR:
  896 + port->output = 1;
  897 + port->input = 1;
  898 + frm_cfg.frame_pin_dir = regk_sser_in;
  899 + gen_cfg.clk_dir = regk_sser_in;
  900 + break;
  901 + default:
  902 + spin_unlock_irq(&port->lock);
  903 + 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 907 intr_mask.rdav = regk_sser_yes;
817 908 break;
818 909 case SSP_FRAME_SYNC:
819 910 if (arg & NORMAL_SYNC) {
820 911 frm_cfg.rec_delay = 1;
821 912 frm_cfg.tr_delay = 1;
822   - }
823   - else if (arg & EARLY_SYNC)
  913 + } else if (arg & EARLY_SYNC)
824 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 919 frm_cfg.rec_delay = 7;
827 920 frm_cfg.tr_delay = 1;
828 921 }
829 922  
... ... @@ -914,15 +1007,12 @@
914 1007 frm_cfg.type = regk_sser_level;
915 1008 frm_cfg.tr_delay = 1;
916 1009 frm_cfg.level = regk_sser_neg_lo;
917   - if (arg & SPI_SLAVE)
918   - {
  1010 + if (arg & SPI_SLAVE) {
919 1011 rec_cfg.clk_pol = regk_sser_neg;
920 1012 gen_cfg.clk_dir = regk_sser_in;
921 1013 port->input = 1;
922 1014 port->output = 0;
923   - }
924   - else
925   - {
  1015 + } else {
926 1016 gen_cfg.out_clk_pol = regk_sser_pos;
927 1017 port->input = 0;
928 1018 port->output = 1;
929 1019  
930 1020  
931 1021  
932 1022  
... ... @@ -965,19 +1055,19 @@
965 1055 }
966 1056  
967 1057 static 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);
973   - ret = sync_serial_ioctl_unlocked(file, cmd, arg);
974   - mutex_unlock(&sync_serial_mutex);
  1062 + mutex_lock(&sync_serial_mutex);
  1063 + ret = sync_serial_ioctl_unlocked(file, cmd, arg);
  1064 + mutex_unlock(&sync_serial_mutex);
975 1065  
976   - return ret;
  1066 + return ret;
977 1067 }
978 1068  
979 1069 /* NOTE: sync_serial_write does not support concurrency */
980   -static ssize_t sync_serial_write(struct file *file, const char *buf,
  1070 +static ssize_t sync_serial_write(struct file *file, const char __user *buf,
981 1071 size_t count, loff_t *ppos)
982 1072 {
983 1073 int dev = iminor(file_inode(file));
... ... @@ -993,7 +1083,7 @@
993 1083 unsigned char *buf_stop_ptr; /* Last byte + 1 */
994 1084  
995 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 1087 return -ENODEV;
998 1088 }
999 1089 port = &ports[dev];
... ... @@ -1006,9 +1096,9 @@
1006 1096 * |_________|___________________|________________________|
1007 1097 * ^ rd_ptr ^ wr_ptr
1008 1098 */
1009   - DEBUGWRITE(printk(KERN_DEBUG "W d%d c %lu a: %p c: %p\n",
1010   - port->port_nbr, count, port->active_tr_descr,
1011   - port->catch_tr_descr));
  1099 + DEBUGWRITE(pr_info("W d%d c %u a: %p c: %p\n",
  1100 + port->port_nbr, count, port->active_tr_descr,
  1101 + port->catch_tr_descr));
1012 1102  
1013 1103 /* Read variables that may be updated by interrupts */
1014 1104 spin_lock_irqsave(&port->lock, flags);
... ... @@ -1020,7 +1110,7 @@
1020 1110 if (port->tr_running &&
1021 1111 ((port->use_dma && port->active_tr_descr == port->catch_tr_descr) ||
1022 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 1114 return -EAGAIN;
1025 1115 }
1026 1116  
1027 1117  
... ... @@ -1043,15 +1133,16 @@
1043 1133 if (copy_from_user(wr_ptr, buf, trunc_count))
1044 1134 return -EFAULT;
1045 1135  
1046   - DEBUGOUTBUF(printk(KERN_DEBUG "%-4d + %-4d = %-4d %p %p %p\n",
1047   - out_buf_count, trunc_count,
1048   - port->out_buf_count, port->out_buffer,
1049   - wr_ptr, buf_stop_ptr));
  1136 + DEBUGOUTBUF(pr_info("%-4d + %-4d = %-4d %p %p %p\n",
  1137 + out_buf_count, trunc_count,
  1138 + port->out_buf_count, port->out_buffer,
  1139 + wr_ptr, buf_stop_ptr));
1050 1140  
1051 1141 /* Make sure transmitter/receiver is running */
1052 1142 if (!port->started) {
1053 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 1146 cfg.en = regk_sser_yes;
1056 1147 rec_cfg.rec_en = port->input;
1057 1148 REG_WR(sser, port->regi_sser, rw_cfg, cfg);
1058 1149  
1059 1150  
... ... @@ -1068,8 +1159,11 @@
1068 1159 spin_lock_irqsave(&port->lock, flags);
1069 1160 port->out_buf_count += trunc_count;
1070 1161 if (port->use_dma) {
  1162 +#ifdef SYNC_SER_DMA
1071 1163 start_dma_out(port, wr_ptr, trunc_count);
  1164 +#endif
1072 1165 } else if (!port->tr_running) {
  1166 +#ifdef SYNC_SER_MANUAL
1073 1167 reg_sser_rw_intr_mask intr_mask;
1074 1168 intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
1075 1169 /* Start sender by writing data */
1076 1170  
... ... @@ -1077,14 +1171,15 @@
1077 1171 /* and enable transmitter ready IRQ */
1078 1172 intr_mask.trdy = 1;
1079 1173 REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
  1174 +#endif
1080 1175 }
1081 1176 spin_unlock_irqrestore(&port->lock, flags);
1082 1177  
1083 1178 /* Exit if non blocking */
1084 1179 if (file->f_flags & O_NONBLOCK) {
1085   - DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu %08x\n",
1086   - port->port_nbr, trunc_count,
1087   - REG_RD_INT(dma, port->regi_dmaout, r_intr)));
  1180 + DEBUGWRITE(pr_info("w d%d c %u %08x\n",
  1181 + port->port_nbr, trunc_count,
  1182 + REG_RD_INT(dma, port->regi_dmaout, r_intr)));
1088 1183 return trunc_count;
1089 1184 }
1090 1185  
1091 1186  
1092 1187  
1093 1188  
1094 1189  
1095 1190  
... ... @@ -1094,105 +1189,32 @@
1094 1189 if (signal_pending(current))
1095 1190 return -EINTR;
1096 1191  
1097   - DEBUGWRITE(printk(KERN_DEBUG "w d%d c %lu\n",
1098   - port->port_nbr, trunc_count));
  1192 + DEBUGWRITE(pr_info("w d%d c %u\n", port->port_nbr, trunc_count));
1099 1193 return trunc_count;
1100 1194 }
1101 1195  
1102   -static ssize_t sync_serial_read(struct file * file, char * buf,
  1196 +static ssize_t sync_serial_read(struct file *file, char __user *buf,
1103 1197 size_t count, loff_t *ppos)
1104 1198 {
1105   - int dev = iminor(file_inode(file));
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;
  1199 + return __sync_serial_read(file, buf, count, ppos, NULL);
1178 1200 }
1179 1201  
1180   -static void send_word(sync_port* port)
  1202 +#ifdef SYNC_SER_MANUAL
  1203 +static void send_word(struct sync_port *port)
1181 1204 {
1182 1205 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
1183 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 1218 int data = (*port->out_rd_ptr++) << 8;
1197 1219 data |= *port->out_rd_ptr++;
1198 1220 port->out_buf_count -= 2;
1199 1221  
... ... @@ -1200,8 +1222,8 @@
1200 1222 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
1201 1223 if (port->out_rd_ptr >= port->out_buffer + OUT_BUFFER_SIZE)
1202 1224 port->out_rd_ptr = port->out_buffer;
  1225 + break;
1203 1226 }
1204   - break;
1205 1227 case 16:
1206 1228 port->out_buf_count -= 2;
1207 1229 tr_data.data = *(unsigned short *)port->out_rd_ptr;
1208 1230  
1209 1231  
1210 1232  
1211 1233  
1212 1234  
... ... @@ -1233,27 +1255,28 @@
1233 1255 break;
1234 1256 }
1235 1257 }
  1258 +#endif
1236 1259  
1237   -static void start_dma_out(struct sync_port *port,
1238   - const char *data, int count)
  1260 +#ifdef SYNC_SER_DMA
  1261 +static 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 1264 port->active_tr_descr->after = port->active_tr_descr->buf + count;
1242 1265 port->active_tr_descr->intr = 1;
1243 1266  
1244 1267 port->active_tr_descr->eol = 1;
1245 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 1271 port->prev_tr_descr, port->active_tr_descr));
1249 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 1275 if (!port->tr_running) {
1253 1276 reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser,
1254 1277 rw_tr_cfg);
1255 1278  
1256   - port->out_context.next = 0;
  1279 + port->out_context.next = NULL;
1257 1280 port->out_context.saved_data =
1258 1281 (dma_descr_data *)virt_to_phys(port->prev_tr_descr);
1259 1282 port->out_context.saved_data_buf = port->prev_tr_descr->buf;
1260 1283  
1261 1284  
1262 1285  
1263 1286  
1264 1287  
1265 1288  
1266 1289  
1267 1290  
1268 1291  
1269 1292  
1270 1293  
... ... @@ -1263,57 +1286,58 @@
1263 1286  
1264 1287 tr_cfg.tr_en = regk_sser_yes;
1265 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 1290 } else {
1268 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 1295 port->tr_running = 1;
1273 1296 }
1274 1297  
1275   -static void start_dma_in(sync_port *port)
  1298 +static void start_dma_in(struct sync_port *port)
1276 1299 {
1277 1300 int i;
1278 1301 char *buf;
  1302 + unsigned long flags;
  1303 + spin_lock_irqsave(&port->lock, flags);
1279 1304 port->writep = port->flip;
  1305 + spin_unlock_irqrestore(&port->lock, flags);
1280 1306  
1281   - if (port->writep > port->flip + port->in_buffer_size) {
1282   - panic("Offset too large in sync serial driver\n");
1283   - return;
1284   - }
1285   - buf = (char*)virt_to_phys(port->in_buffer);
  1307 + buf = (char *)virt_to_phys(port->in_buffer);
1286 1308 for (i = 0; i < NBR_IN_DESCR; i++) {
1287 1309 port->in_descr[i].buf = buf;
1288 1310 port->in_descr[i].after = buf + port->inbufchunk;
1289 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 1314 port->in_descr[i].buf = buf;
1292 1315 buf += port->inbufchunk;
1293 1316 }
1294 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 1320 port->in_descr[i-1].eol = regk_sser_yes;
1297 1321 port->next_rx_desc = &port->in_descr[0];
1298 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 1325 port->in_context.saved_data_buf = port->in_descr[0].buf;
1301 1326 DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context));
1302 1327 }
1303 1328  
1304   -#ifdef SYNC_SER_DMA
1305 1329 static irqreturn_t tr_interrupt(int irq, void *dev_id)
1306 1330 {
1307 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 1333 reg_dma_rw_stat stat;
1310 1334 int i;
1311 1335 int found = 0;
1312 1336 int stop_sser = 0;
1313 1337  
1314 1338 for (i = 0; i < NBR_PORTS; i++) {
1315   - sync_port *port = &ports[i];
1316   - if (!port->enabled || !port->use_dma)
  1339 + struct sync_port *port = &ports[i];
  1340 + if (!port->enabled || !port->use_dma)
1317 1341 continue;
1318 1342  
1319 1343 /* IRQ active for the port? */
1320 1344  
... ... @@ -1338,19 +1362,20 @@
1338 1362 int sent;
1339 1363 sent = port->catch_tr_descr->after -
1340 1364 port->catch_tr_descr->buf;
1341   - DEBUGTXINT(printk(KERN_DEBUG "%-4d - %-4d = %-4d\t"
1342   - "in descr %p (ac: %p)\n",
1343   - port->out_buf_count, sent,
1344   - port->out_buf_count - sent,
1345   - port->catch_tr_descr,
1346   - port->active_tr_descr););
  1365 + DEBUGTXINT(pr_info("%-4d - %-4d = %-4d\t"
  1366 + "in descr %p (ac: %p)\n",
  1367 + port->out_buf_count, sent,
  1368 + port->out_buf_count - sent,
  1369 + port->catch_tr_descr,
  1370 + port->active_tr_descr););
1347 1371 port->out_buf_count -= sent;
1348 1372 port->catch_tr_descr =
1349 1373 phys_to_virt((int) port->catch_tr_descr->next);
1350 1374 port->out_rd_ptr =
1351 1375 phys_to_virt((int) port->catch_tr_descr->buf);
1352 1376 } else {
1353   - int i, sent;
  1377 + reg_sser_rw_tr_cfg tr_cfg;
  1378 + int j, sent;
1354 1379 /* EOL handler.
1355 1380 * Note that if an EOL was encountered during the irq
1356 1381 * locked section of sync_ser_write the DMA will be
1357 1382  
... ... @@ -1358,11 +1383,11 @@
1358 1383 * The remaining descriptors will be traversed by
1359 1384 * the descriptor interrupts as usual.
1360 1385 */
1361   - i = 0;
  1386 + j = 0;
1362 1387 while (!port->catch_tr_descr->eol) {
1363 1388 sent = port->catch_tr_descr->after -
1364 1389 port->catch_tr_descr->buf;
1365   - DEBUGOUTBUF(printk(KERN_DEBUG
  1390 + DEBUGOUTBUF(pr_info(
1366 1391 "traversing descr %p -%d (%d)\n",
1367 1392 port->catch_tr_descr,
1368 1393 sent,
1369 1394  
... ... @@ -1370,16 +1395,15 @@
1370 1395 port->out_buf_count -= sent;
1371 1396 port->catch_tr_descr = phys_to_virt(
1372 1397 (int)port->catch_tr_descr->next);
1373   - i++;
1374   - if (i >= NBR_OUT_DESCR) {
  1398 + j++;
  1399 + if (j >= NBR_OUT_DESCR) {
1375 1400 /* TODO: Reset and recover */
1376 1401 panic("sync_serial: missing eol");
1377 1402 }
1378 1403 }
1379 1404 sent = port->catch_tr_descr->after -
1380 1405 port->catch_tr_descr->buf;
1381   - DEBUGOUTBUF(printk(KERN_DEBUG
1382   - "eol at descr %p -%d (%d)\n",
  1406 + DEBUGOUTBUF(pr_info("eol at descr %p -%d (%d)\n",
1383 1407 port->catch_tr_descr,
1384 1408 sent,
1385 1409 port->out_buf_count));
1386 1410  
... ... @@ -1394,15 +1418,13 @@
1394 1418 OUT_BUFFER_SIZE)
1395 1419 port->out_rd_ptr = port->out_buffer;
1396 1420  
1397   - reg_sser_rw_tr_cfg tr_cfg =
1398   - REG_RD(sser, port->regi_sser, rw_tr_cfg);
1399   - DEBUGTXINT(printk(KERN_DEBUG
  1421 + tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
  1422 + DEBUGTXINT(pr_info(
1400 1423 "tr_int DMA stop %d, set catch @ %p\n",
1401 1424 port->out_buf_count,
1402 1425 port->active_tr_descr));
1403 1426 if (port->out_buf_count != 0)
1404   - printk(KERN_CRIT "sync_ser: buffer not "
1405   - "empty after eol.\n");
  1427 + pr_err("sync_ser: buf not empty after eol\n");
1406 1428 port->catch_tr_descr = port->active_tr_descr;
1407 1429 port->tr_running = 0;
1408 1430 tr_cfg.tr_en = regk_sser_no;
1409 1431  
1410 1432  
1411 1433  
1412 1434  
1413 1435  
... ... @@ -1414,62 +1436,79 @@
1414 1436 return IRQ_RETVAL(found);
1415 1437 } /* tr_interrupt */
1416 1438  
  1439 +
  1440 +static 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 +
1417 1487 static irqreturn_t rx_interrupt(int irq, void *dev_id)
1418 1488 {
1419 1489 reg_dma_r_masked_intr masked;
1420   - reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
1421 1490  
1422 1491 int i;
1423 1492 int found = 0;
1424 1493  
1425   - for (i = 0; i < NBR_PORTS; i++)
1426   - {
1427   - sync_port *port = &ports[i];
  1494 + DEBUG(pr_info("rx_interrupt\n"));
1428 1495  
1429   - if (!port->enabled || !port->use_dma )
  1496 + for (i = 0; i < NBR_PORTS; i++) {
  1497 + struct sync_port *port = &ports[i];
  1498 +
  1499 + if (!port->enabled || !port->use_dma)
1430 1500 continue;
1431 1501  
1432 1502 masked = REG_RD(dma, port->regi_dmain, r_masked_intr);
1433 1503  
1434   - if (masked.data) /* Descriptor interrupt */
1435   - {
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   - }
  1504 + if (!masked.data)
  1505 + continue;
1457 1506  
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   -
1471   - }
1472   - }
  1507 + /* Descriptor interrupt */
  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 1513 return IRQ_RETVAL(found);
1475 1514 } /* rx_interrupt */
1476 1515  
1477 1516  
1478 1517  
1479 1518  
1480 1519  
1481 1520  
1482 1521  
1483 1522  
1484 1523  
1485 1524  
1486 1525  
1487 1526  
1488 1527  
1489 1528  
1490 1529  
1491 1530  
1492 1531  
1493 1532  
1494 1533  
... ... @@ -1478,75 +1517,83 @@
1478 1517 #ifdef SYNC_SER_MANUAL
1479 1518 static irqreturn_t manual_interrupt(int irq, void *dev_id)
1480 1519 {
  1520 + unsigned long flags;
1481 1521 int i;
1482 1522 int found = 0;
1483 1523 reg_sser_r_masked_intr masked;
1484 1524  
1485   - for (i = 0; i < NBR_PORTS; i++)
1486   - {
1487   - sync_port *port = &ports[i];
  1525 + for (i = 0; i < NBR_PORTS; i++) {
  1526 + struct sync_port *port = &ports[i];
1488 1527  
1489 1528 if (!port->enabled || port->use_dma)
1490   - {
1491 1529 continue;
1492   - }
1493 1530  
1494 1531 masked = REG_RD(sser, port->regi_sser, r_masked_intr);
1495   - if (masked.rdav) /* Data received? */
1496   - {
1497   - reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
1498   - reg_sser_r_rec_data data = REG_RD(sser, port->regi_sser, r_rec_data);
  1532 + /* Data received? */
  1533 + if (masked.rdav) {
  1534 + reg_sser_rw_rec_cfg rec_cfg =
  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 1538 found = 1;
1500 1539 /* Read data */
1501   - switch(rec_cfg.sample_size)
1502   - {
  1540 + spin_lock_irqsave(&port->lock, flags);
  1541 + switch (rec_cfg.sample_size) {
1503 1542 case 8:
1504 1543 *port->writep++ = data.data & 0xff;
1505 1544 break;
1506 1545 case 12:
1507 1546 *port->writep = (data.data & 0x0ff0) >> 4;
1508 1547 *(port->writep + 1) = data.data & 0x0f;
1509   - port->writep+=2;
  1548 + port->writep += 2;
1510 1549 break;
1511 1550 case 16:
1512   - *(unsigned short*)port->writep = data.data;
1513   - port->writep+=2;
  1551 + *(unsigned short *)port->writep = data.data;
  1552 + port->writep += 2;
1514 1553 break;
1515 1554 case 24:
1516   - *(unsigned int*)port->writep = data.data;
1517   - port->writep+=3;
  1555 + *(unsigned int *)port->writep = data.data;
  1556 + port->writep += 3;
1518 1557 break;
1519 1558 case 32:
1520   - *(unsigned int*)port->writep = data.data;
1521   - port->writep+=4;
  1559 + *(unsigned int *)port->writep = data.data;
  1560 + port->writep += 4;
1522 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 1566 port->writep = port->flip;
1527 1567 if (port->writep == port->readp) {
1528   - /* receive buffer overrun, discard oldest data
1529   - */
  1568 + /* Receive buf overrun, discard oldest data */
1530 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 1573 port->readp = port->flip;
1533 1574 }
  1575 + spin_unlock_irqrestore(&port->lock, flags);
1534 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? */
1539   - {
  1581 + /* Transmitter ready? */
  1582 + if (masked.trdy) {
1540 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 1586 send_word(port);
1543   - else /* transmission finished */
1544   - {
  1587 + else {
  1588 + /* Transmission finished */
1545 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 1592 intr_mask.trdy = 0;
1548   - REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
1549   - wake_up_interruptible(&port->out_wait_q); /* Wake up application */
  1593 + REG_WR(sser, port->regi_sser,
  1594 + rw_intr_mask, intr_mask);
  1595 + /* Wake up application */
  1596 + wake_up_interruptible(&port->out_wait_q);
1550 1597 }
1551 1598 }
1552 1599 }
1553 1600  
... ... @@ -1554,5 +1601,109 @@
1554 1601 }
1555 1602 #endif
1556 1603  
  1604 +static 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 +
  1676 +static 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 +
1557 1705 module_init(etrax_sync_serial_init);
  1706 +module_exit(etrax_sync_serial_exit);
  1707 +
  1708 +MODULE_LICENSE("GPL");