sunsab.c (92a19f9cec9a80ad93c06e115822deb729e2c6ad) sunsab.c (2e124b4a390ca85325fae75764bef92f0547fa25)
1/* sunsab.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
2 *
3 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
4 * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net)
5 *
6 * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
7 * Maxim Krasnyanskiy <maxk@qualcomm.com>
8 *

--- 93 unchanged lines hidden (view full) ---

102static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up)
103{
104 int timeout = up->cec_timeout;
105
106 while ((readb(&up->regs->r.star) & SAB82532_STAR_CEC) && --timeout)
107 udelay(1);
108}
109
1/* sunsab.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
2 *
3 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
4 * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net)
5 *
6 * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
7 * Maxim Krasnyanskiy <maxk@qualcomm.com>
8 *

--- 93 unchanged lines hidden (view full) ---

102static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up)
103{
104 int timeout = up->cec_timeout;
105
106 while ((readb(&up->regs->r.star) & SAB82532_STAR_CEC) && --timeout)
107 udelay(1);
108}
109
110static struct tty_struct *
110static struct tty_port *
111receive_chars(struct uart_sunsab_port *up,
112 union sab82532_irq_status *stat)
113{
114 struct tty_port *port = NULL;
111receive_chars(struct uart_sunsab_port *up,
112 union sab82532_irq_status *stat)
113{
114 struct tty_port *port = NULL;
115 struct tty_struct *tty = NULL;
116 unsigned char buf[32];
117 int saw_console_brk = 0;
118 int free_fifo = 0;
119 int count = 0;
120 int i;
121
115 unsigned char buf[32];
116 int saw_console_brk = 0;
117 int free_fifo = 0;
118 int count = 0;
119 int i;
120
122 if (up->port.state != NULL) { /* Unopened serial console */
121 if (up->port.state != NULL) /* Unopened serial console */
123 port = &up->port.state->port;
122 port = &up->port.state->port;
124 tty = port->tty;
125 }
126
127 /* Read number of BYTES (Character + Status) available. */
128 if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
129 count = SAB82532_RECV_FIFO_SIZE;
130 free_fifo++;
131 }
132
133 if (stat->sreg.isr0 & SAB82532_ISR0_TCD) {
134 count = readb(&up->regs->r.rbcl) & (SAB82532_RECV_FIFO_SIZE - 1);
135 free_fifo++;
136 }
137
138 /* Issue a FIFO read command in case we where idle. */
139 if (stat->sreg.isr0 & SAB82532_ISR0_TIME) {
140 sunsab_cec_wait(up);
141 writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr);
123
124 /* Read number of BYTES (Character + Status) available. */
125 if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
126 count = SAB82532_RECV_FIFO_SIZE;
127 free_fifo++;
128 }
129
130 if (stat->sreg.isr0 & SAB82532_ISR0_TCD) {
131 count = readb(&up->regs->r.rbcl) & (SAB82532_RECV_FIFO_SIZE - 1);
132 free_fifo++;
133 }
134
135 /* Issue a FIFO read command in case we where idle. */
136 if (stat->sreg.isr0 & SAB82532_ISR0_TIME) {
137 sunsab_cec_wait(up);
138 writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr);
142 return tty;
139 return port;
143 }
144
145 if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
146 free_fifo++;
147
148 /* Read the FIFO. */
149 for (i = 0; i < count; i++)
150 buf[i] = readb(&up->regs->r.rfifo[i]);

--- 63 unchanged lines hidden (view full) ---

214 tty_insert_flip_char(port, ch, flag);
215 if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
216 tty_insert_flip_char(port, 0, TTY_OVERRUN);
217 }
218
219 if (saw_console_brk)
220 sun_do_break();
221
140 }
141
142 if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
143 free_fifo++;
144
145 /* Read the FIFO. */
146 for (i = 0; i < count; i++)
147 buf[i] = readb(&up->regs->r.rfifo[i]);

--- 63 unchanged lines hidden (view full) ---

211 tty_insert_flip_char(port, ch, flag);
212 if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
213 tty_insert_flip_char(port, 0, TTY_OVERRUN);
214 }
215
216 if (saw_console_brk)
217 sun_do_break();
218
222 return tty;
219 return port;
223}
224
225static void sunsab_stop_tx(struct uart_port *);
226static void sunsab_tx_idle(struct uart_sunsab_port *);
227
228static void transmit_chars(struct uart_sunsab_port *up,
229 union sab82532_irq_status *stat)
230{

--- 66 unchanged lines hidden (view full) ---

297 }
298
299 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
300}
301
302static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
303{
304 struct uart_sunsab_port *up = dev_id;
220}
221
222static void sunsab_stop_tx(struct uart_port *);
223static void sunsab_tx_idle(struct uart_sunsab_port *);
224
225static void transmit_chars(struct uart_sunsab_port *up,
226 union sab82532_irq_status *stat)
227{

--- 66 unchanged lines hidden (view full) ---

294 }
295
296 wake_up_interruptible(&up->port.state->port.delta_msr_wait);
297}
298
299static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
300{
301 struct uart_sunsab_port *up = dev_id;
305 struct tty_struct *tty;
302 struct tty_port *port = NULL;
306 union sab82532_irq_status status;
307 unsigned long flags;
308 unsigned char gis;
309
310 spin_lock_irqsave(&up->port.lock, flags);
311
312 status.stat = 0;
313 gis = readb(&up->regs->r.gis) >> up->gis_shift;
314 if (gis & 1)
315 status.sreg.isr0 = readb(&up->regs->r.isr0);
316 if (gis & 2)
317 status.sreg.isr1 = readb(&up->regs->r.isr1);
318
303 union sab82532_irq_status status;
304 unsigned long flags;
305 unsigned char gis;
306
307 spin_lock_irqsave(&up->port.lock, flags);
308
309 status.stat = 0;
310 gis = readb(&up->regs->r.gis) >> up->gis_shift;
311 if (gis & 1)
312 status.sreg.isr0 = readb(&up->regs->r.isr0);
313 if (gis & 2)
314 status.sreg.isr1 = readb(&up->regs->r.isr1);
315
319 tty = NULL;
320 if (status.stat) {
321 if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
322 SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) ||
323 (status.sreg.isr1 & SAB82532_ISR1_BRK))
316 if (status.stat) {
317 if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
318 SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) ||
319 (status.sreg.isr1 & SAB82532_ISR1_BRK))
324 tty = receive_chars(up, &status);
320 port = receive_chars(up, &status);
325 if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
326 (status.sreg.isr1 & SAB82532_ISR1_CSC))
327 check_status(up, &status);
328 if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
329 transmit_chars(up, &status);
330 }
331
332 spin_unlock_irqrestore(&up->port.lock, flags);
333
321 if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
322 (status.sreg.isr1 & SAB82532_ISR1_CSC))
323 check_status(up, &status);
324 if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
325 transmit_chars(up, &status);
326 }
327
328 spin_unlock_irqrestore(&up->port.lock, flags);
329
334 if (tty)
335 tty_flip_buffer_push(tty);
330 if (port)
331 tty_flip_buffer_push(port);
336
337 return IRQ_HANDLED;
338}
339
340/* port->lock is not held. */
341static unsigned int sunsab_tx_empty(struct uart_port *port)
342{
343 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;

--- 808 unchanged lines hidden ---
332
333 return IRQ_HANDLED;
334}
335
336/* port->lock is not held. */
337static unsigned int sunsab_tx_empty(struct uart_port *port)
338{
339 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;

--- 808 unchanged lines hidden ---