patch-2.4.4 linux/drivers/char/sh-sci.c
Next file: linux/drivers/char/sh-sci.h
Previous file: linux/drivers/char/serial.c
Back to the patch index
Back to the overall index
- Lines: 167
- Date:
Wed Apr 11 21:24:52 2001
- Orig file:
v2.4.3/linux/drivers/char/sh-sci.c
- Orig date:
Fri Feb 9 11:30:22 2001
diff -u --recursive --new-file v2.4.3/linux/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
@@ -74,6 +74,8 @@
static void sci_hungup(void *ptr);
static void sci_close(void *ptr);
static int sci_chars_in_buffer(void *ptr);
+static int sci_request_irq(struct sci_port *port);
+static void sci_free_irq(struct sci_port *port);
static int sci_init_drivers(void);
static struct tty_driver sci_driver, sci_callout_driver;
@@ -83,8 +85,8 @@
static struct termios *sci_termios[SCI_NPORTS];
static struct termios *sci_termios_locked[SCI_NPORTS];
-int sci_refcount;
-int sci_debug = 0;
+static int sci_refcount;
+static int sci_debug = 0;
#ifdef MODULE
MODULE_PARM(sci_debug, "i");
@@ -102,7 +104,7 @@
do
status = sci_in(port, SCxSR);
while (!(status & SCxSR_TDxE(port)));
-
+
sci_out(port, SCxTDR, c);
sci_in(port, SCxSR); /* Dummy read */
sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
@@ -626,10 +628,10 @@
dprintk("sci: BREAK detected\n");
}
-#if defined(CONFIG_CPU_SUBTYPE_SH7750)
+#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1)
/* XXX: Handle SCIF overrun error */
- if (port->type == PORT_SCIF && (ctrl_inw(SCLSR2) & SCIF_ORER) != 0) {
- ctrl_outw(0, SCLSR2);
+ if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
+ sci_out(port, SCLSR, 0);
if(tty->flip.count<TTY_FLIPBUF_SIZE) {
copied++;
*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
@@ -796,6 +798,7 @@
port->gs.flags &= ~ GS_ACTIVE;
if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
sci_setsignals(port, 0, 0);
+ sci_free_irq(port);
}
/* ********************************************************************** *
@@ -828,8 +831,7 @@
*/
retval = gs_init_port(&port->gs);
if (retval) {
- port->gs.count--;
- return retval;
+ goto failed_1;
}
port->gs.flags |= GS_ACTIVE;
@@ -837,14 +839,17 @@
if (port->gs.count == 1) {
MOD_INC_USE_COUNT;
+
+ retval = sci_request_irq(port);
+ if (retval) {
+ goto failed_2;
+ }
}
retval = gs_block_til_ready(port, filp);
if (retval) {
- MOD_DEC_USE_COUNT;
- port->gs.count--;
- return retval;
+ goto failed_3;
}
if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
@@ -870,6 +875,14 @@
port->gs.pgrp = current->pgrp;
return 0;
+
+failed_3:
+ sci_free_irq(port);
+failed_2:
+ MOD_DEC_USE_COUNT;
+failed_1:
+ port->gs.count--;
+ return retval;
}
static void sci_hungup(void *ptr)
@@ -1094,29 +1107,46 @@
return 0;
}
-int __init sci_init(void)
+static int sci_request_irq(struct sci_port *port)
{
- struct sci_port *port;
- int i, j;
+ int i;
void (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = {
sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
sci_br_interrupt,
};
+ for (i=0; i<4; i++) {
+ if (!port->irqs[i]) continue;
+ if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
+ "sci", port)) {
+ printk(KERN_ERR "sci: Cannot allocate irq.\n");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+
+static void sci_free_irq(struct sci_port *port)
+{
+ int i;
+
+ for (i=0; i<4; i++) {
+ if (!port->irqs[i]) continue;
+ free_irq(port->irqs[i], port);
+ }
+}
+
+int __init sci_init(void)
+{
+ struct sci_port *port;
+ int j;
+
printk("SuperH SCI(F) driver initialized\n");
for (j=0; j<SCI_NPORTS; j++) {
port = &sci_ports[j];
printk("ttySC%d at 0x%08x is a %s\n", j, port->base,
(port->type == PORT_SCI) ? "SCI" : "SCIF");
- for (i=0; i<4; i++) {
- if (!port->irqs[i]) continue;
- if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
- "sci", port)) {
- printk(KERN_ERR "sci: Cannot allocate irq.\n");
- return -ENODEV;
- }
- }
}
sci_init_drivers();
@@ -1135,11 +1165,6 @@
void cleanup_module(void)
{
- int i;
-
- for (i=SCI_ERI_IRQ; i<SCI_TEI_IRQ; i++) /* XXX: irq_end?? */
- free_irq(i, port);
-
tty_unregister_driver(&sci_driver);
tty_unregister_driver(&sci_callout_driver);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)