clean up ssc driver
[openwrt.git] / target / linux / ifxmips / files / drivers / char / ifxmips_ssc.c
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; either version 2 of the License, or
5  *   (at your option) any later version.
6  *
7  *   This program is distributed in the hope that it will be useful,
8  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *   GNU General Public License for more details.
11  *
12  *   You should have received a copy of the GNU General Public License
13  *   along with this program; if not, write to the Free Software
14  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
15  *
16  *   Copyright (C) 2006 infineon
17  *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
18  *
19  */
20
21 // ### TO DO: general issues:
22 //            - power management
23 //            - interrupt handling (direct/indirect)
24 //            - pin/mux-handling (just overall concept due to project dependency)
25 //            - multiple instances capability
26 //            - slave functionality
27
28 #include <linux/module.h>
29 #include <linux/errno.h>
30 #include <linux/signal.h>
31 #include <linux/sched.h>
32 #include <linux/timer.h>
33 #include <linux/interrupt.h>
34 #include <linux/major.h>
35 #include <linux/string.h>
36 #include <linux/fs.h>
37 #include <linux/fcntl.h>
38 #include <linux/ptrace.h>
39 #include <linux/mm.h>
40 #include <linux/ioport.h>
41 #include <linux/init.h>
42 #include <linux/delay.h>
43 #include <linux/spinlock.h>
44 #include <linux/slab.h>
45
46 #include <asm/system.h>
47 #include <asm/io.h>
48 #include <asm/irq.h>
49 #include <asm/uaccess.h>
50 #include <asm/bitops.h>
51
52 #include <linux/types.h>
53 #include <linux/kernel.h>
54 #include <linux/version.h>
55
56 #include <asm/ifxmips/ifxmips.h>
57 #include <asm/ifxmips/ifxmips_irq.h>
58 #include <asm/ifxmips/ifx_ssc_defines.h>
59 #include <asm/ifxmips/ifx_ssc.h>
60
61 /* allow the user to set the major device number */
62 static int maj = 0;
63
64 /*
65  * This is the per-channel data structure containing pointers, flags
66  * and variables for the port. This driver supports a maximum of PORT_CNT.
67  * isp is allocated in ifx_ssc_init() based on the chip version.
68  */
69 static struct ifx_ssc_port *isp;
70
71 /* other forward declarations */
72 static unsigned int ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info);
73 static void tx_int (struct ifx_ssc_port *);
74
75 extern unsigned int ifxmips_get_fpi_hz (void);
76 extern void mask_and_ack_ifxmips_irq (unsigned int irq_nr);
77
78 static inline unsigned int
79 ifx_ssc_get_kernel_clk (struct ifx_ssc_port *info)
80 {
81         unsigned int rmc;
82
83         rmc = (readl(IFXMIPS_SSC_CLC) & IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET;
84         if (rmc == 0)
85         {
86                 printk ("ifx_ssc_get_kernel_clk rmc==0 \n");
87                 return 0;
88         }
89         return ifxmips_get_fpi_hz () / rmc;
90 }
91
92 #ifndef not_yet
93 #ifdef IFX_SSC_INT_USE_BH
94 /*
95  * This routine is used by the interrupt handler to schedule
96  * processing in the software interrupt portion of the driver
97  * (also known as the "bottom half").  This can be called any
98  * number of times for any channel without harm.
99  */
100 static inline void
101 ifx_ssc_sched_event (struct ifx_ssc_port *info, int event)
102 {
103         info->event |= 1 << event;      /* remember what kind of event and who */
104         queue_task (&info->tqueue, &tq_cyclades);       /* it belongs to */
105         mark_bh (CYCLADES_BH);  /* then trigger event */
106 }
107
108 static void
109 do_softint (void *private_)
110 {
111         struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_;
112
113         if (test_and_clear_bit (Cy_EVENT_HANGUP, &info->event))
114         {
115                 wake_up_interruptible (&info->open_wait);
116                 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CALLOUT_ACTIVE);
117         }
118
119         if (test_and_clear_bit (Cy_EVENT_OPEN_WAKEUP, &info->event))
120                 wake_up_interruptible (&info->open_wait);
121
122         if (test_and_clear_bit (Cy_EVENT_DELTA_WAKEUP, &info->event))
123                 wake_up_interruptible (&info->delta_msr_wait);
124
125         if (test_and_clear_bit (Cy_EVENT_WRITE_WAKEUP, &info->event))
126                 wake_up_interruptible (&tty->write_wait);
127 #ifdef Z_WAKE
128         if (test_and_clear_bit (Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
129                 wake_up_interruptible (&info->shutdown_wait);
130 #endif
131 }
132 #endif
133 #endif
134
135 inline static void
136 rx_int (struct ifx_ssc_port *info)
137 {
138         int fifo_fill_lev, bytes_in_buf, i;
139         unsigned long tmp_val;
140         unsigned long *tmp_ptr;
141         unsigned int rx_valid_cnt;
142         /* number of words waiting in the RX FIFO */
143         fifo_fill_lev = (readl(IFXMIPS_SSC_FSTAT) & IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >> IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET;
144         bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr;
145         // transfer with 32 bits per entry
146         while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) {
147                 tmp_ptr = (unsigned long *) info->rxbuf_ptr;
148                 *tmp_ptr = readl(IFXMIPS_SSC_RB);
149                 info->rxbuf_ptr += 4;
150                 info->stats.rxBytes += 4;
151                 fifo_fill_lev--;
152                 bytes_in_buf -= 4;
153         }
154
155         // now do the rest as mentioned in STATE.RXBV
156         while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) {
157                 rx_valid_cnt = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET;
158                 if (rx_valid_cnt == 0)
159                         break;
160
161                 if (rx_valid_cnt > bytes_in_buf)
162                         rx_valid_cnt = bytes_in_buf;
163
164                 tmp_val = readl(IFXMIPS_SSC_RB);
165
166                 for (i = 0; i < rx_valid_cnt; i++)
167                 {
168                         *info->rxbuf_ptr = (tmp_val >> (8 * (rx_valid_cnt - i - 1))) & 0xff;
169                         bytes_in_buf--;
170                         info->rxbuf_ptr++;
171                 }
172                 info->stats.rxBytes += rx_valid_cnt;
173         }
174
175         // check if transfer is complete
176         if (info->rxbuf_ptr >= info->rxbuf_end)
177         {
178                 disable_irq(IFXMIPS_SSC_RIR);
179                 wake_up_interruptible (&info->rwait);
180         } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && (readl(IFXMIPS_SSC_RXCNT) == 0))
181         {
182                 if (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE)
183                         writel((info->rxbuf_end - info->rxbuf_ptr) << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
184                 else
185                         writel(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET,  IFXMIPS_SSC_RXREQ);
186         }
187 }
188
189 inline static void
190 tx_int (struct ifx_ssc_port *info)
191 {
192
193         int fifo_space, fill, i;
194         fifo_space = ((readl(IFXMIPS_SSC_ID) & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET)
195                 - ((readl(IFXMIPS_SSC_FSTAT) & IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET);
196
197         if (fifo_space == 0)
198                 return;
199
200         fill = info->txbuf_end - info->txbuf_ptr;
201
202         if (fill > fifo_space * 4)
203                 fill = fifo_space * 4;
204
205         for (i = 0; i < fill / 4; i++)
206         {
207                 // at first 32 bit access
208                 writel(*(UINT32 *) info->txbuf_ptr, IFXMIPS_SSC_TB);
209                 info->txbuf_ptr += 4;
210         }
211
212         fifo_space -= fill / 4;
213         info->stats.txBytes += fill & ~0x3;
214         fill &= 0x3;
215         if ((fifo_space > 0) & (fill > 1))
216         {
217                 // trailing 16 bit access
218                 WRITE_PERIPHERAL_REGISTER_16 (*(UINT16 *) info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
219                 info->txbuf_ptr += 2;
220                 info->stats.txBytes += 2;
221                 fifo_space--;
222                 fill -= 2;
223         }
224
225         if ((fifo_space > 0) & (fill > 0))
226         {
227                 // trailing 8 bit access
228                 WRITE_PERIPHERAL_REGISTER_8 (*(UINT8 *) info->txbuf_ptr, info->mapbase + IFX_SSC_TB);
229                 info->txbuf_ptr++;
230                 info->stats.txBytes++;
231         }
232
233         // check if transmission complete
234         if (info->txbuf_ptr >= info->txbuf_end)
235         {
236                 disable_irq(IFXMIPS_SSC_TIR);
237                 kfree (info->txbuf);
238                 info->txbuf = NULL;
239         }
240
241 }
242
243 irqreturn_t
244 ifx_ssc_rx_int (int irq, void *dev_id)
245 {
246         struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
247         rx_int (info);
248
249         return IRQ_HANDLED;
250 }
251
252 irqreturn_t
253 ifx_ssc_tx_int (int irq, void *dev_id)
254 {
255         struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
256         tx_int (info);
257
258         return IRQ_HANDLED;
259 }
260
261 irqreturn_t
262 ifx_ssc_err_int (int irq, void *dev_id)
263 {
264         struct ifx_ssc_port *info = (struct ifx_ssc_port *) dev_id;
265         unsigned int state;
266         unsigned int write_back = 0;
267         unsigned long flags;
268
269         local_irq_save (flags);
270         state = readl(IFXMIPS_SSC_STATE);
271
272         if ((state & IFX_SSC_STATE_RX_UFL) != 0) {
273                 info->stats.rxUnErr++;
274                 write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR;
275         }
276
277         if ((state & IFX_SSC_STATE_RX_OFL) != 0) {
278                 info->stats.rxOvErr++;
279                 write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR;
280         }
281
282         if ((state & IFX_SSC_STATE_TX_OFL) != 0) {
283                 info->stats.txOvErr++;
284                 write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR;
285         }
286
287         if ((state & IFX_SSC_STATE_TX_UFL) != 0) {
288                 info->stats.txUnErr++;
289                 write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR;
290         }
291
292         if ((state & IFX_SSC_STATE_MODE_ERR) != 0) {
293                 info->stats.modeErr++;
294                 write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR;
295         }
296
297         if (write_back)
298                 writel(write_back, IFXMIPS_SSC_WHBSTATE);
299
300         local_irq_restore (flags);
301
302         return IRQ_HANDLED;
303 }
304
305 static void
306 ifx_ssc_abort (struct ifx_ssc_port *info)
307 {
308         unsigned long flags;
309         bool enabled;
310
311         local_irq_save (flags);
312
313         disable_irq(IFXMIPS_SSC_RIR);
314         disable_irq(IFXMIPS_SSC_TIR);
315         disable_irq(IFXMIPS_SSC_EIR);
316
317         local_irq_restore (flags);
318
319         // disable SSC (also aborts a receive request!)
320         // ### TO DO: Perhaps it's better to abort after the receiption of a 
321         // complete word. The disable cuts the transmission immediatly and 
322         // releases the chip selects. This could result in unpredictable 
323         // behavior of connected external devices!
324         enabled = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED) != 0;
325         writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
326
327         // flush fifos
328         writel(IFX_SSC_XFCON_FIFO_FLUSH, IFXMIPS_SSC_TXFCON);
329         writel(IFX_SSC_XFCON_FIFO_FLUSH, IFXMIPS_SSC_RXFCON);
330
331         // free txbuf
332         if (info->txbuf != NULL)
333         {
334                 kfree (info->txbuf);
335                 info->txbuf = NULL;
336         }
337
338         // wakeup read process
339         if (info->rxbuf != NULL)
340                 wake_up_interruptible (&info->rwait);
341
342         // clear pending int's 
343         mask_and_ack_ifxmips_irq(IFXMIPS_SSC_RIR);
344         mask_and_ack_ifxmips_irq(IFXMIPS_SSC_TIR);
345         mask_and_ack_ifxmips_irq(IFXMIPS_SSC_EIR);
346
347         // clear error flags
348         writel(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, IFXMIPS_SSC_WHBSTATE);
349
350         if (enabled)
351                 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
352
353 }
354
355 /*
356  * This routine is called whenever a port is opened.  It enforces
357  * exclusive opening of a port and enables interrupts, etc.
358  */
359 int
360 ifx_ssc_open (struct inode *inode, struct file *filp)
361 {
362         struct ifx_ssc_port *info;
363         int line;
364         int from_kernel = 0;
365
366         if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1)) {
367                 from_kernel = 1;
368                 line = (int) inode;
369         } else {
370                 line = MINOR (filp->f_dentry->d_inode->i_rdev);
371         }
372
373         /* don't open more minor devices than we can support */
374         if (line < 0 || line >= PORT_CNT)
375                 return -ENXIO;
376
377         info = &isp[line];
378
379         /* exclusive open */
380         if (info->port_is_open != 0)
381                 return -EBUSY;
382         info->port_is_open++;
383
384         disable_irq(IFXMIPS_SSC_RIR);
385         disable_irq(IFXMIPS_SSC_TIR);
386         disable_irq(IFXMIPS_SSC_EIR);
387
388         /* Flush and enable TX/RX FIFO */
389         writel((IFX_SSC_DEF_TXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_FLUSH | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_TXFCON);
390         writel((IFX_SSC_DEF_RXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_FLUSH | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_RXFCON);
391
392         /* logically flush the software FIFOs */
393         info->rxbuf_ptr = 0;
394         info->txbuf_ptr = 0;
395
396         /* clear all error bits */
397         writel(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, IFXMIPS_SSC_WHBSTATE);
398
399         // clear pending interrupts
400         mask_and_ack_ifxmips_irq(IFXMIPS_SSC_RIR);
401         mask_and_ack_ifxmips_irq(IFXMIPS_SSC_TIR);
402         mask_and_ack_ifxmips_irq(IFXMIPS_SSC_EIR);
403
404         writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
405
406         return 0;
407 }
408 EXPORT_SYMBOL(ifx_ssc_open);
409
410 int
411 ifx_ssc_close (struct inode *inode, struct file *filp)
412 {
413         struct ifx_ssc_port *info;
414         int idx;
415
416         if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1))
417                 idx = (int) inode;
418         else
419                 idx = MINOR (filp->f_dentry->d_inode->i_rdev);
420
421         if (idx < 0 || idx >= PORT_CNT)
422                 return -ENXIO;
423
424         info = &isp[idx];
425         if (!info)
426                 return -ENXIO;
427
428         writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
429
430         ifx_ssc_abort(info);
431
432         info->port_is_open--;
433
434         return 0;
435 }
436 EXPORT_SYMBOL(ifx_ssc_close);
437
438 static ssize_t
439 ifx_ssc_read_helper_poll (struct ifx_ssc_port *info, char *buf, size_t len, int from_kernel)
440 {
441         ssize_t ret_val;
442         unsigned long flags;
443
444         if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
445                 return -EFAULT;
446         local_irq_save (flags);
447         info->rxbuf_ptr = info->rxbuf;
448         info->rxbuf_end = info->rxbuf + len;
449         local_irq_restore (flags);
450         /* Vinetic driver always works in IFX_SSC_MODE_RXTX */
451         /* TXRX in poll mode */
452         while (info->rxbuf_ptr < info->rxbuf_end)
453         {
454                 if (info->txbuf_ptr < info->txbuf_end)
455                         tx_int (info);
456
457                 rx_int (info);
458         };
459
460         ret_val = info->rxbuf_ptr - info->rxbuf;
461
462         return ret_val;
463 }
464
465 static ssize_t
466 ifx_ssc_read_helper (struct ifx_ssc_port *info, char *buf, size_t len, int from_kernel)
467 {
468         ssize_t ret_val;
469         unsigned long flags;
470         DECLARE_WAITQUEUE (wait, current);
471
472         if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
473                 return -EFAULT;
474
475         local_irq_save (flags);
476         info->rxbuf_ptr = info->rxbuf;
477         info->rxbuf_end = info->rxbuf + len;
478
479         if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX)
480         {
481                 if ((info->txbuf == NULL) || (info->txbuf != info->txbuf_ptr) || (info->txbuf_end != len + info->txbuf))
482                 {
483                         local_irq_restore (flags);
484                         printk ("IFX SSC - %s: write must be called before calling " "read in combined RX/TX!\n", __func__);
485                         return -EFAULT;
486                 }
487
488                 local_irq_restore(flags);
489                 tx_int (info);
490
491                 if (info->txbuf_ptr < info->txbuf_end)
492                         enable_irq(IFXMIPS_SSC_TIR);
493
494                 enable_irq(IFXMIPS_SSC_RIR);
495         } else {
496                 local_irq_restore(flags);
497                 if (readl(IFXMIPS_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK)
498                         return -EBUSY;
499                 enable_irq(IFXMIPS_SSC_RIR);
500                 if (len < IFX_SSC_RXREQ_BLOCK_SIZE)
501                         writel(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
502                 else
503                         writel(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, IFXMIPS_SSC_RXREQ);
504         }
505
506         __add_wait_queue (&info->rwait, &wait);
507         set_current_state (TASK_INTERRUPTIBLE);
508
509         do {
510                 local_irq_save (flags);
511                 if (info->rxbuf_ptr >= info->rxbuf_end)
512                         break;
513
514                 local_irq_restore (flags);
515
516                 if (signal_pending (current))
517                 {
518                         ret_val = -ERESTARTSYS;
519                         goto out;
520                 }
521                 schedule();
522         } while (1);
523
524         ret_val = info->rxbuf_ptr - info->rxbuf;
525         local_irq_restore (flags);
526
527 out:
528         current->state = TASK_RUNNING;
529         __remove_wait_queue (&info->rwait, &wait);
530
531         return (ret_val);
532 }
533
534 static ssize_t
535 ifx_ssc_write_helper (struct ifx_ssc_port *info, const char *buf,
536                       size_t len, int from_kernel)
537 {
538         if (info->opts.modeRxTx == IFX_SSC_MODE_RX)
539                 return -EFAULT;
540
541         info->txbuf_ptr = info->txbuf;
542         info->txbuf_end = len + info->txbuf;
543         if (info->opts.modeRxTx == IFX_SSC_MODE_TX)
544         {
545                 tx_int (info);
546                 if (info->txbuf_ptr < info->txbuf_end)
547                 {
548                         enable_irq(IFXMIPS_SSC_TIR);
549                 }
550         }
551
552         return len;
553 }
554
555 ssize_t
556 ifx_ssc_kread (int port, char *kbuf, size_t len)
557 {
558         struct ifx_ssc_port *info;
559         ssize_t ret_val;
560
561         if (port < 0 || port >= PORT_CNT)
562                 return -ENXIO;
563
564         if (len == 0)
565                 return 0;
566
567         info = &isp[port];
568
569         if (info->rxbuf != NULL)
570         {
571                 printk ("SSC device busy\n");
572                 return -EBUSY;
573         }
574
575         info->rxbuf = kbuf;
576         if (info->rxbuf == NULL)
577         {
578                 printk ("SSC device error\n");
579                 return -EINVAL;
580         }
581
582         ret_val = ifx_ssc_read_helper_poll (info, kbuf, len, 1);
583         info->rxbuf = NULL;
584
585         disable_irq(IFXMIPS_SSC_RIR);
586
587         return ret_val;
588 }
589 EXPORT_SYMBOL(ifx_ssc_kread);
590
591 ssize_t
592 ifx_ssc_kwrite (int port, const char *kbuf, size_t len)
593 {
594         struct ifx_ssc_port *info;
595         ssize_t ret_val;
596
597         if (port < 0 || port >= PORT_CNT)
598                 return -ENXIO;
599
600         if (len == 0)
601                 return 0;
602
603         info = &isp[port];
604
605         // check if transmission in progress
606         if (info->txbuf != NULL)
607                 return -EBUSY;
608
609         info->txbuf = (char *) kbuf;
610
611         ret_val = ifx_ssc_write_helper (info, info->txbuf, len, 1);
612
613         if (ret_val < 0)
614                 info->txbuf = NULL;
615
616         return ret_val;
617 }
618 EXPORT_SYMBOL(ifx_ssc_kwrite);
619
620 static ssize_t
621 ifx_ssc_read (struct file *filp, char *ubuf, size_t len, loff_t * off)
622 {
623         ssize_t ret_val;
624         int idx;
625         struct ifx_ssc_port *info;
626
627         idx = MINOR (filp->f_dentry->d_inode->i_rdev);
628         info = &isp[idx];
629
630         if (info->rxbuf != NULL)
631                 return -EBUSY;
632
633         info->rxbuf = kmalloc (len + 3, GFP_KERNEL);
634         if (info->rxbuf == NULL)
635                 return -ENOMEM;
636
637         ret_val = ifx_ssc_read_helper (info, info->rxbuf, len, 0);
638         if (copy_to_user ((void *) ubuf, info->rxbuf, ret_val) != 0)
639                 ret_val = -EFAULT;
640
641         disable_irq(IFXMIPS_SSC_RIR);
642
643         kfree (info->rxbuf);
644         info->rxbuf = NULL;
645
646         return (ret_val);
647 }
648
649 static ssize_t
650 ifx_ssc_write (struct file *filp, const char *ubuf, size_t len, loff_t * off)
651 {
652         int idx;
653         struct ifx_ssc_port *info;
654         int ret_val;
655
656         if (len == 0)
657                 return (0);
658
659         idx = MINOR (filp->f_dentry->d_inode->i_rdev);
660         info = &isp[idx];
661
662         if (info->txbuf != NULL)
663                 return -EBUSY;
664
665         info->txbuf = kmalloc (len + 3, GFP_KERNEL);
666         if (info->txbuf == NULL)
667                 return -ENOMEM;
668
669         ret_val = copy_from_user (info->txbuf, ubuf, len);
670         if (ret_val == 0)
671                 ret_val = ifx_ssc_write_helper (info, info->txbuf, len, 0);
672         else
673                 ret_val = -EFAULT;
674
675         if (ret_val < 0)
676         {
677                 kfree (info->txbuf);
678                 info->txbuf = NULL;
679         }
680
681         return (ret_val);
682 }
683
684 static struct ifx_ssc_frm_status *
685 ifx_ssc_frm_status_get (struct ifx_ssc_port *info)
686 {
687         unsigned long tmp;
688
689         tmp = readl(IFXMIPS_SSC_SFSTAT);
690         info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0;
691         info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0;
692         info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET;
693         info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET;
694         tmp = readl(IFXMIPS_SSC_SFCON);
695         info->frm_status.EnIntAfterData = (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0;
696         info->frm_status.EnIntAfterPause = (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0;
697
698         return &info->frm_status;
699 }
700
701
702 static struct ifx_ssc_frm_opts *
703 ifx_ssc_frm_control_get (struct ifx_ssc_port *info)
704 {
705         unsigned long tmp;
706
707         tmp = readl(IFXMIPS_SSC_SFCON);
708         info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0;
709         info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
710         info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
711         info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
712         info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
713         info->frm_opts.StopAfterPause = (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0;
714
715         return &info->frm_opts;
716 }
717
718 static int
719 ifx_ssc_frm_control_set (struct ifx_ssc_port *info)
720 {
721         unsigned long tmp;
722
723         // check parameters
724         if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX)
725             || (info->frm_opts.DataLength < 1)
726             || (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX)
727             || (info->frm_opts.PauseLength < 1)
728             || (info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET))
729             || (info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)))
730                 return -EINVAL;
731
732         // read interrupt bits (they're not changed here)
733         tmp = readl(IFXMIPS_SSC_SFCON) &
734                 (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE);
735
736         // set all values with respect to it's bit position (for data and pause 
737         // length set N-1)
738         tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET;
739         tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET;
740         tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET;
741         tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET;
742         tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE;
743         tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE;
744
745         writel(tmp, IFXMIPS_SSC_SFCON);
746
747         return 0;
748 }
749
750 static int
751 ifx_ssc_rxtx_mode_set (struct ifx_ssc_port *info, unsigned int val)
752 {
753         unsigned long tmp;
754
755         if (!(info) || (val & ~(IFX_SSC_MODE_MASK)))
756                 return -EINVAL;
757
758         if ((readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_BUSY)
759             || (readl(IFXMIPS_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK))
760                 return -EBUSY;
761
762         tmp = (readl(IFXMIPS_SSC_CON) & ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val);
763         writel(tmp, IFXMIPS_SSC_SFCON);
764         info->opts.modeRxTx = val;
765
766         return 0;
767 }
768
769 static int
770 ifx_ssc_sethwopts (struct ifx_ssc_port *info)
771 {
772         unsigned long flags, bits;
773         struct ifx_ssc_hwopts *opts = &info->opts;
774
775         if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH)
776             || (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH))
777                 return -EINVAL;
778
779         bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET;
780         bits |= IFX_SSC_CON_ENABLE_BYTE_VALID;
781
782         if (opts->rxOvErrDetect)
783                 bits |= IFX_SSC_CON_RX_OFL_CHECK;
784         if (opts->rxUndErrDetect)
785                 bits |= IFX_SSC_CON_RX_UFL_CHECK;
786         if (opts->txOvErrDetect)
787                 bits |= IFX_SSC_CON_TX_OFL_CHECK;
788         if (opts->txUndErrDetect)
789                 bits |= IFX_SSC_CON_TX_UFL_CHECK;
790         if (opts->loopBack)
791                 bits |= IFX_SSC_CON_LOOPBACK_MODE;
792         if (opts->echoMode)
793                 bits |= IFX_SSC_CON_ECHO_MODE_ON;
794         if (opts->headingControl)
795                 bits |= IFX_SSC_CON_MSB_FIRST;
796         if (opts->clockPhase)
797                 bits |= IFX_SSC_CON_LATCH_THEN_SHIFT;
798         if (opts->clockPolarity)
799                 bits |= IFX_SSC_CON_CLOCK_FALL;
800
801         switch (opts->modeRxTx)
802         {
803         case IFX_SSC_MODE_TX:
804                 bits |= IFX_SSC_CON_RX_OFF;
805                 break;
806         case IFX_SSC_MODE_RX:
807                 bits |= IFX_SSC_CON_TX_OFF;
808                 break;
809         }
810
811         local_irq_save (flags);
812
813         writel(bits, IFXMIPS_SSC_CON);
814         writel((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) |
815                                    (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), IFXMIPS_SSC_GPOCON);
816
817         writel(info->opts.gpoCs << IFX_SSC_WHBGPOSTAT_SETOUT0_POS, IFXMIPS_SSC_WHBGPOSTAT);
818
819         //master mode
820         if (opts->masterSelect)
821                 writel(IFX_SSC_WHBSTATE_SET_MASTER_SELECT, IFXMIPS_SSC_WHBSTATE);
822         else
823                 writel(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT, IFXMIPS_SSC_WHBSTATE);
824
825         // init serial framing
826         writel(0, IFXMIPS_SSC_SFCON);
827         /* set up the port pins */
828         //check for general requirements to switch (external) pad/pin characteristics
829         /* TODO: P0.9 SPI_CS4, P0.10 SPI_CS5, P 0.11 SPI_CS6, because of ASC0 */
830         /* p0.15 SPI_CS1(EEPROM), P0.13 SPI_CS3, */
831         /* Set p0.15 to alternative 01, others to 00 (In/OUT) */
832         *(IFXMIPS_GPIO_P0_DIR) = (*IFXMIPS_GPIO_P0_DIR) | (0xA000);
833         *(IFXMIPS_GPIO_P0_ALTSEL0) = (((*IFXMIPS_GPIO_P0_ALTSEL0) | (0x8000)) & (~(0x2000)));
834         *(IFXMIPS_GPIO_P0_ALTSEL1) = (((*IFXMIPS_GPIO_P0_ALTSEL1) & (~0x8000)) & (~(0x2000)));
835         *(IFXMIPS_GPIO_P0_OD) = (*IFXMIPS_GPIO_P0_OD) | 0xA000;
836
837         /* p1.6 SPI_CS2(SFLASH), p1.0 SPI_DIN, p1.1 SPI_DOUT, p1.2 SPI_CLK */
838         *(IFXMIPS_GPIO_P1_DIR) = ((*IFXMIPS_GPIO_P1_DIR) | (0x46)) & (~1);
839         *(IFXMIPS_GPIO_P1_ALTSEL0) = ((*IFXMIPS_GPIO_P1_ALTSEL0) | (0x47));
840         *(IFXMIPS_GPIO_P1_ALTSEL1) = (*IFXMIPS_GPIO_P1_ALTSEL1) & (~0x47);
841         *(IFXMIPS_GPIO_P1_OD) = (*IFXMIPS_GPIO_P1_OD) | 0x0046;
842
843         /*CS3 */
844         /*TODO: CS4 CS5 CS6 */
845         *IFXMIPS_GPIO_P0_OUT = ((*IFXMIPS_GPIO_P0_OUT) | 0x2000);
846
847         local_irq_restore (flags);
848
849         return 0;
850 }
851
852 static int
853 ifx_ssc_set_baud (struct ifx_ssc_port *info, unsigned int baud)
854 {
855         unsigned int ifx_ssc_clock;
856         unsigned int br;
857         unsigned long flags;
858         bool enabled;
859         int retval = 0;
860
861         ifx_ssc_clock = ifx_ssc_get_kernel_clk(info);
862         if (ifx_ssc_clock == 0)
863         {
864                 retval = -EINVAL;
865                 goto out;
866         }
867
868         local_irq_save (flags);
869
870         enabled = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED);
871         writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
872
873         br = (((ifx_ssc_clock >> 1) + baud / 2) / baud) - 1;
874         wmb();
875
876         if (br > 0xffff || ((br == 0) &&
877                         ((readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_MASTER) == 0))) {
878                 local_irq_restore (flags);
879                 printk ("%s: invalid baudrate %u\n", __func__, baud);
880                 return -EINVAL;
881         }
882
883         writel(br, IFXMIPS_SSC_BR);
884
885         if (enabled)
886                 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
887
888         local_irq_restore(flags);
889
890 out:
891         return retval;
892 }
893
894 static int
895 ifx_ssc_hwinit (struct ifx_ssc_port *info)
896 {
897         unsigned long flags;
898         bool enabled;
899
900         enabled = (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_IS_ENABLED);
901         writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
902
903         if (ifx_ssc_sethwopts (info) < 0)
904         {
905                 printk ("%s: setting the hardware options failed\n", __func__);
906                 return -EINVAL;
907         }
908
909         if (ifx_ssc_set_baud (info, info->baud) < 0)
910         {
911                 printk ("%s: setting the baud rate failed\n", __func__);
912                 return -EINVAL;
913         }
914
915         local_irq_save (flags);
916
917         /* TX FIFO */
918         writel((IFX_SSC_DEF_TXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_TXFCON);
919         /* RX FIFO */
920         writel((IFX_SSC_DEF_RXFIFO_FL << IFX_SSC_XFCON_ITL_OFFSET) | IFX_SSC_XFCON_FIFO_ENABLE, IFXMIPS_SSC_RXFCON);
921
922         local_irq_restore (flags);
923
924         if (enabled)
925                 writel(IFX_SSC_WHBSTATE_SET_ENABLE, IFXMIPS_SSC_WHBSTATE);
926
927         return 0;
928 }
929
930 int
931 ifx_ssc_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)
932 {
933         struct ifx_ssc_port *info;
934         int line, ret_val = 0;
935         unsigned long flags;
936         unsigned long tmp;
937         int from_kernel = 0;
938
939         if ((inode == (struct inode *) 0) || (inode == (struct inode *) 1))
940         {
941                 from_kernel = 1;
942                 line = (int) inode;
943         } else {
944                 line = MINOR (filp->f_dentry->d_inode->i_rdev);
945         }
946
947         if (line < 0 || line >= PORT_CNT)
948                 return -ENXIO;
949
950         info = &isp[line];
951
952         switch (cmd)
953         {
954         case IFX_SSC_STATS_READ:
955                 /* data must be a pointer to a struct ifx_ssc_statistics */
956                 if (from_kernel)
957                         memcpy ((void *) data, (void *) &info->stats,
958                                 sizeof (struct ifx_ssc_statistics));
959                 else if (copy_to_user ((void *) data,
960                                        (void *) &info->stats,
961                                        sizeof (struct ifx_ssc_statistics)))
962                         ret_val = -EFAULT;
963                 break;
964         case IFX_SSC_STATS_RESET:
965                 /* just resets the statistics counters */
966                 memset ((void *) &info->stats, 0,
967                         sizeof (struct ifx_ssc_statistics));
968                 break;
969         case IFX_SSC_BAUD_SET:
970                 /* if the buffers are not empty then the port is */
971                 /* busy and we shouldn't change things on-the-fly! */
972                 if (!info->txbuf || !info->rxbuf ||
973                     (readl(IFXMIPS_SSC_STATE) & IFX_SSC_STATE_BUSY)) {
974                         ret_val = -EBUSY;
975                         break;
976                 }
977                 /* misuse flags */
978                 if (from_kernel)
979                         flags = *((unsigned long *) data);
980                 else if (copy_from_user ((void *) &flags,
981                                          (void *) data, sizeof (flags))) {
982                         ret_val = -EFAULT;
983                         break;
984                 }
985                 if (flags == 0) {
986                         ret_val = -EINVAL;
987                         break;
988                 }
989                 if (ifx_ssc_set_baud (info, flags) < 0) {
990                         ret_val = -EINVAL;
991                         break;
992                 }
993                 info->baud = flags;
994                 break;
995         case IFX_SSC_BAUD_GET:
996                 if (from_kernel)
997                         *((unsigned int *) data) = info->baud;
998                 else if (copy_to_user ((void *) data,
999                                        (void *) &info->baud,
1000                                        sizeof (unsigned long)))
1001                         ret_val = -EFAULT;
1002                 break;
1003         case IFX_SSC_RXTX_MODE_SET:
1004                 if (from_kernel)
1005                         tmp = *((unsigned long *) data);
1006                 else if (copy_from_user ((void *) &tmp,
1007                                          (void *) data, sizeof (tmp))) {
1008                         ret_val = -EFAULT;
1009                         break;
1010                 }
1011                 ret_val = ifx_ssc_rxtx_mode_set (info, tmp);
1012                 break;
1013         case IFX_SSC_RXTX_MODE_GET:
1014                 tmp = readl(IFXMIPS_SSC_CON) &
1015                         (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF));
1016                 if (from_kernel)
1017                         *((unsigned int *) data) = tmp;
1018                 else if (copy_to_user ((void *) data,
1019                                        (void *) &tmp, sizeof (tmp)))
1020                         ret_val = -EFAULT;
1021                 break;
1022
1023         case IFX_SSC_ABORT:
1024                 ifx_ssc_abort (info);
1025                 break;
1026
1027         case IFX_SSC_GPO_OUT_SET:
1028                 if (from_kernel)
1029                         tmp = *((unsigned long *) data);
1030                 else if (copy_from_user ((void *) &tmp,
1031                                          (void *) data, sizeof (tmp))) {
1032                         ret_val = -EFAULT;
1033                         break;
1034                 }
1035                 if (tmp > IFX_SSC_MAX_GPO_OUT)
1036                         ret_val = -EINVAL;
1037                 else
1038                         writel(1 << (tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS),
1039                                  IFXMIPS_SSC_WHBGPOSTAT);
1040                 break;
1041         case IFX_SSC_GPO_OUT_CLR:
1042                 if (from_kernel)
1043                         tmp = *((unsigned long *) data);
1044                 else if (copy_from_user ((void *) &tmp, (void *) data, sizeof (tmp))) {
1045                         ret_val = -EFAULT;
1046                         break;
1047                 }
1048                 if (tmp > IFX_SSC_MAX_GPO_OUT)
1049                         ret_val = -EINVAL;
1050                 else {
1051                         writel(1 << (tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS),
1052                                  IFXMIPS_SSC_WHBGPOSTAT);
1053                 }
1054                 break;
1055         case IFX_SSC_GPO_OUT_GET:
1056                 tmp = readl(IFXMIPS_SSC_GPOSTAT);
1057                 if (from_kernel)
1058                         *((unsigned int *) data) = tmp;
1059                 else if (copy_to_user ((void *) data,
1060                                        (void *) &tmp, sizeof (tmp)))
1061                         ret_val = -EFAULT;
1062                 break;
1063         case IFX_SSC_FRM_STATUS_GET:
1064                 ifx_ssc_frm_status_get (info);
1065                 if (from_kernel)
1066                         memcpy ((void *) data, (void *) &info->frm_status,
1067                                 sizeof (struct ifx_ssc_frm_status));
1068                 else if (copy_to_user ((void *) data,
1069                                        (void *) &info->frm_status,
1070                                        sizeof (struct ifx_ssc_frm_status)))
1071                         ret_val = -EFAULT;
1072                 break;
1073         case IFX_SSC_FRM_CONTROL_GET:
1074                 ifx_ssc_frm_control_get (info);
1075                 if (from_kernel)
1076                         memcpy ((void *) data, (void *) &info->frm_opts,
1077                                 sizeof (struct ifx_ssc_frm_opts));
1078                 else if (copy_to_user ((void *) data,
1079                                        (void *) &info->frm_opts,
1080                                        sizeof (struct ifx_ssc_frm_opts)))
1081                         ret_val = -EFAULT;
1082                 break;
1083         case IFX_SSC_FRM_CONTROL_SET:
1084                 if (from_kernel)
1085                         memcpy ((void *) &info->frm_opts, (void *) data,
1086                                 sizeof (struct ifx_ssc_frm_opts));
1087                 else if (copy_to_user ((void *) &info->frm_opts,
1088                                        (void *) data,
1089                                        sizeof (struct ifx_ssc_frm_opts))) {
1090                         ret_val = -EFAULT;
1091                         break;
1092                 }
1093                 ret_val = ifx_ssc_frm_control_set (info);
1094                 break;
1095         case IFX_SSC_HWOPTS_SET:
1096                 /* data must be a pointer to a struct ifx_ssc_hwopts */
1097                 /* if the buffers are not empty then the port is */
1098                 /* busy and we shouldn't change things on-the-fly! */
1099                 if (!info->txbuf || !info->rxbuf ||
1100                     (readl(IFXMIPS_SSC_STATE)
1101                      & IFX_SSC_STATE_BUSY)) {
1102                         ret_val = -EBUSY;
1103                         break;
1104                 }
1105                 if (from_kernel)
1106                         memcpy ((void *) &info->opts, (void *) data,
1107                                 sizeof (struct ifx_ssc_hwopts));
1108                 else if (copy_from_user ((void *) &info->opts,
1109                                          (void *) data, sizeof(struct ifx_ssc_hwopts))) {
1110                         ret_val = -EFAULT;
1111                         break;
1112                 }
1113                 if (ifx_ssc_hwinit (info) < 0) {
1114                         ret_val = -EIO;
1115                 }
1116                 break;
1117         case IFX_SSC_HWOPTS_GET:
1118                 /* data must be a pointer to a struct ifx_ssc_hwopts */
1119                 if (from_kernel)
1120                         memcpy ((void *) data, (void *) &info->opts,
1121                                 sizeof (struct ifx_ssc_hwopts));
1122                 else if (copy_to_user ((void *) data,
1123                                        (void *) &info->opts,
1124                                        sizeof (struct ifx_ssc_hwopts)))
1125                         ret_val = -EFAULT;
1126                 break;
1127         default:
1128                 ret_val = -ENOIOCTLCMD;
1129         }
1130
1131         return ret_val;
1132 }
1133 EXPORT_SYMBOL(ifx_ssc_ioctl);
1134
1135 static struct file_operations ifx_ssc_fops = {
1136       .owner = THIS_MODULE,
1137       .read = ifx_ssc_read,
1138       .write = ifx_ssc_write,
1139       .ioctl = ifx_ssc_ioctl,
1140       .open = ifx_ssc_open,
1141       .release = ifx_ssc_close,
1142 };
1143
1144 int __init
1145 ifx_ssc_init (void)
1146 {
1147         struct ifx_ssc_port *info;
1148         int i, nbytes;
1149         unsigned long flags;
1150         int ret_val;
1151
1152         ret_val = -ENOMEM;
1153         nbytes = PORT_CNT * sizeof(struct ifx_ssc_port);
1154         isp = (struct ifx_ssc_port*)kmalloc(nbytes, GFP_KERNEL);
1155
1156         if (isp == NULL)
1157         {
1158                 printk("%s: no memory for isp\n", __func__);
1159                 return (ret_val);
1160         }
1161         memset(isp, 0, nbytes);
1162
1163         ret_val = -ENXIO;
1164         if ((i = register_chrdev (maj, "ssc", &ifx_ssc_fops)) < 0)
1165         {
1166                 printk ("Unable to register major %d for the Infineon SSC\n", maj);
1167                 if (maj == 0)
1168                 {
1169                         goto errout;
1170                 } else {
1171                         maj = 0;
1172                         if ((i = register_chrdev (maj, "ssc", &ifx_ssc_fops)) < 0)
1173                         {
1174                                 printk ("Unable to register major %d for the Infineon SSC\n", maj);
1175                                 goto errout;
1176                         }
1177                 }
1178         }
1179
1180         if (maj == 0)
1181                 maj = i;
1182
1183         /* set default values in ifx_ssc_port */
1184         for (i = 0; i < PORT_CNT; i++) {
1185                 info = &isp[i];
1186                 info->port_nr = i;
1187                 /* default values for the HwOpts */
1188                 info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT;
1189                 info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT;
1190                 info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT;
1191                 info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT;
1192                 info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT;
1193                 info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK;
1194                 info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE;
1195                 info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA;
1196                 info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY;
1197                 info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE;
1198                 info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL;
1199                 info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH;
1200                 info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX;
1201                 info->opts.gpoCs = IFX_SSC_DEF_GPO_CS;
1202                 info->opts.gpoInv = IFX_SSC_DEF_GPO_INV;
1203                 info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE;
1204                 info->baud = IFX_SSC_DEF_BAUDRATE;
1205                 info->rxbuf = NULL;
1206                 info->txbuf = NULL;
1207                 /* values specific to SSC1 */
1208                 if (i == 0) {
1209                         info->mapbase = IFXMIPS_SSC_BASE_ADDR;
1210                 }
1211
1212                 writel(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, IFXMIPS_SSC_CLC);
1213
1214                 init_waitqueue_head (&info->rwait);
1215
1216                 local_irq_save (flags);
1217
1218                 // init serial framing register
1219                 writel(IFX_SSC_DEF_SFCON, IFXMIPS_SSC_SFCON);
1220
1221                 ret_val = request_irq(IFXMIPS_SSC_TIR, ifx_ssc_tx_int, IRQF_DISABLED, "ifx_ssc_tx", info);
1222                 if (ret_val)
1223                 {
1224                         printk("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_TIR);
1225                         local_irq_restore(flags);
1226                         goto errout;
1227                 }
1228
1229                 ret_val = request_irq(IFXMIPS_SSC_RIR, ifx_ssc_rx_int, IRQF_DISABLED, "ifx_ssc_rx", info);
1230                 if (ret_val)
1231                 {
1232                         printk ("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_RIR);
1233                         local_irq_restore (flags);
1234                         goto irqerr;
1235                 }
1236
1237                 ret_val = request_irq(IFXMIPS_SSC_EIR, ifx_ssc_err_int, IRQF_DISABLED, "ifx_ssc_err", info);
1238                 if (ret_val)
1239                 {
1240                         printk ("%s: unable to get irq %d\n", __func__, IFXMIPS_SSC_EIR);
1241                         local_irq_restore (flags);
1242                         goto irqerr;
1243                 }
1244                 writel(IFX_SSC_DEF_IRNEN, IFXMIPS_SSC_IRN);
1245
1246                 //enable_irq(IFXMIPS_SSC_TIR);
1247                 //enable_irq(IFXMIPS_SSC_RIR);
1248                 //enable_irq(IFXMIPS_SSC_EIR);
1249
1250                 local_irq_restore (flags);
1251         }
1252
1253         for (i = 0; i < PORT_CNT; i++) {
1254                 info = &isp[i];
1255                 if (ifx_ssc_hwinit (info) < 0)
1256                 {
1257                         printk ("%s: hardware init failed for port %d\n", __func__, i);
1258                         goto irqerr;
1259                 }
1260         }
1261
1262
1263         return 0;
1264
1265 irqerr:
1266         free_irq(IFXMIPS_SSC_TIR, &isp[0]);
1267         free_irq(IFXMIPS_SSC_RIR, &isp[0]);
1268         free_irq(IFXMIPS_SSC_EIR, &isp[0]);
1269 errout:
1270         kfree (isp);
1271         return (ret_val);
1272 }
1273
1274 void
1275 ifx_ssc_cleanup_module (void)
1276 {
1277         int i;
1278
1279         for (i = 0; i < PORT_CNT; i++) {
1280                 writel(IFX_SSC_WHBSTATE_CLR_ENABLE, IFXMIPS_SSC_WHBSTATE);
1281                 free_irq(IFXMIPS_SSC_TIR, &isp[i]);
1282                 free_irq(IFXMIPS_SSC_RIR, &isp[i]);
1283                 free_irq(IFXMIPS_SSC_EIR, &isp[i]);
1284         }
1285         kfree (isp);
1286 }
1287
1288 module_init(ifx_ssc_init);
1289 module_exit(ifx_ssc_cleanup_module);
1290
1291
1292 inline int
1293 ifx_ssc_cs_low (u32 pin)
1294 {
1295         int ret = 0;
1296         if ((ret = ifx_ssc_ioctl ((struct inode *) 0, NULL, IFX_SSC_GPO_OUT_CLR, (unsigned long) &pin)))
1297                 printk ("clear CS %d fails\n", pin);
1298         wmb ();
1299
1300         return ret;
1301 }
1302 EXPORT_SYMBOL(ifx_ssc_cs_low);
1303
1304 inline int
1305 ifx_ssc_cs_high (u32 pin)
1306 {
1307         int ret = 0;
1308         if ((ret = ifx_ssc_ioctl((struct inode *) 0, NULL, IFX_SSC_GPO_OUT_SET, (unsigned long) &pin)))
1309                 printk ("set CS %d fails\n", pin);
1310         wmb ();
1311
1312         return ret;
1313 }
1314 EXPORT_SYMBOL(ifx_ssc_cs_high);
1315
1316 static int
1317 ssc_session (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len)
1318 {
1319         int ret = 0;
1320
1321         char *ssc_tx_buf = NULL;
1322         char *ssc_rx_buf = NULL;
1323         int eff_size = 0;
1324         u8 mode = 0;
1325
1326         if (tx_buf == NULL && tx_len == 0 && rx_buf == NULL && rx_len == 0) {
1327                 printk ("invalid parameters\n");
1328                 ret = -EINVAL;
1329                 goto ssc_session_exit;
1330         }
1331         else if (tx_buf == NULL || tx_len == 0) {
1332                 if (rx_buf != NULL && rx_len != 0) {
1333                         mode = IFX_SSC_MODE_RX;
1334                 }
1335                 else {
1336                         printk ("invalid parameters\n");
1337                         ret = -EINVAL;
1338                         goto ssc_session_exit;
1339                 }
1340         }
1341         else if (rx_buf == NULL || rx_len == 0) {
1342                 if (tx_buf != NULL && tx_len != 0) {
1343                         mode = IFX_SSC_MODE_TX;
1344                 }
1345                 else {
1346                         printk ("invalid parameters\n");
1347                         ret = -EINVAL;
1348                         goto ssc_session_exit;
1349                 }
1350         }
1351         else {
1352                 mode = IFX_SSC_MODE_RXTX;
1353         }
1354
1355         if (mode == IFX_SSC_MODE_RXTX) {
1356                 eff_size = tx_len + rx_len;
1357         }
1358         else if (mode == IFX_SSC_MODE_RX) {
1359                 eff_size = rx_len;
1360         }
1361         else {
1362                 eff_size = tx_len;
1363         }
1364
1365         //4 bytes alignment,  required by driver
1366         /* change by TaiCheng */
1367         //if (in_irq()){
1368         if (1) {
1369                 ssc_tx_buf =
1370                         (char *) kmalloc (sizeof (char) *
1371                                           ((eff_size + 3) & (~3)),
1372                                           GFP_ATOMIC);
1373                 ssc_rx_buf =
1374                         (char *) kmalloc (sizeof (char) *
1375                                           ((eff_size + 3) & (~3)),
1376                                           GFP_ATOMIC);
1377         }
1378         else {
1379                 ssc_tx_buf =
1380                         (char *) kmalloc (sizeof (char) *
1381                                           ((eff_size + 3) & (~3)),
1382                                           GFP_KERNEL);
1383                 ssc_rx_buf =
1384                         (char *) kmalloc (sizeof (char) *
1385                                           ((eff_size + 3) & (~3)),
1386                                           GFP_KERNEL);
1387         }
1388         if (ssc_tx_buf == NULL || ssc_rx_buf == NULL) {
1389                 printk ("no memory for size of %d\n", eff_size);
1390                 ret = -ENOMEM;
1391                 goto ssc_session_exit;
1392         }
1393         memset ((void *) ssc_tx_buf, 0, eff_size);
1394         memset ((void *) ssc_rx_buf, 0, eff_size);
1395
1396         if (tx_len > 0) {
1397                 memcpy (ssc_tx_buf, tx_buf, tx_len);
1398         }
1399
1400         ret = ifx_ssc_kwrite (0, ssc_tx_buf, eff_size);
1401
1402         if (ret > 0) {
1403                 ssc_tx_buf = NULL;      //should be freed by ifx_ssc_kwrite
1404         }
1405
1406         if (ret != eff_size) {
1407                 printk ("ifx_ssc_write return %d\n", ret);
1408                 goto ssc_session_exit;
1409         }
1410         ret = ifx_ssc_kread (0, ssc_rx_buf, eff_size);
1411         if (ret != eff_size) {
1412                 printk ("ifx_ssc_read return %d\n", ret);
1413                 goto ssc_session_exit;
1414         }
1415
1416         memcpy (rx_buf, ssc_rx_buf + tx_len, rx_len);
1417
1418         if (mode == IFX_SSC_MODE_TX) {
1419                 ret = tx_len;
1420         }
1421         else {
1422                 ret = rx_len;
1423         }
1424       ssc_session_exit:
1425
1426         if (ssc_tx_buf != NULL)
1427                 kfree (ssc_tx_buf);
1428         if (ssc_rx_buf != NULL)
1429                 kfree (ssc_rx_buf);
1430
1431         if (ret < 0) {
1432                 printk ("ssc session fails\n");
1433         }
1434         return ret;
1435 }
1436
1437 int
1438 ifx_ssc_txrx (char *tx_buf, u32 tx_len, char *rx_buf, u32 rx_len)
1439 {
1440         return ssc_session(tx_buf, tx_len, rx_buf, rx_len);
1441 }
1442 EXPORT_SYMBOL(ifx_ssc_txrx);
1443
1444 int
1445 ifx_ssc_tx (char *tx_buf, u32 tx_len)
1446 {
1447         return ssc_session(tx_buf, tx_len, NULL, 0);
1448 }
1449 EXPORT_SYMBOL(ifx_ssc_tx);
1450
1451 int
1452 ifx_ssc_rx (char *rx_buf, u32 rx_len)
1453 {
1454         return ssc_session(NULL, 0, rx_buf, rx_len);
1455 }
1456 EXPORT_SYMBOL(ifx_ssc_rx);
1457
1458 MODULE_LICENSE("GPL");
1459 MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
1460 MODULE_DESCRIPTION("ifxmips ssc driver");
1461