Loading drivers/serial/sunsab.c +42 −65 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ struct uart_sunsab_port { unsigned char interrupt_mask1;/* ISR1 masking */ unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ unsigned int gis_shift; int type; /* SAB82532 version */ /* Setting configuration bits while the transmitter is active Loading Loading @@ -305,13 +306,15 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) struct tty_struct *tty; union sab82532_irq_status status; unsigned long flags; unsigned char gis; spin_lock_irqsave(&up->port.lock, flags); status.stat = 0; if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA0) gis = readb(&up->regs->r.gis) >> up->gis_shift; if (gis & 1) status.sreg.isr0 = readb(&up->regs->r.isr0); if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA1) if (gis & 2) status.sreg.isr1 = readb(&up->regs->r.isr1); tty = NULL; Loading @@ -327,35 +330,6 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) transmit_chars(up, &status); } spin_unlock(&up->port.lock); if (tty) tty_flip_buffer_push(tty); up++; spin_lock(&up->port.lock); status.stat = 0; if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB0) status.sreg.isr0 = readb(&up->regs->r.isr0); if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB1) status.sreg.isr1 = readb(&up->regs->r.isr1); tty = NULL; if (status.stat) { if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || (status.sreg.isr1 & SAB82532_ISR1_BRK)) tty = receive_chars(up, &status); if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC))) check_status(up, &status); if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR)) transmit_chars(up, &status); } spin_unlock_irqrestore(&up->port.lock, flags); if (tty) Loading Loading @@ -539,6 +513,10 @@ static int sunsab_startup(struct uart_port *port) struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; unsigned long flags; unsigned char tmp; int err = request_irq(up->port.irq, sunsab_interrupt, IRQF_SHARED, "sab", up); if (err) return err; spin_lock_irqsave(&up->port.lock, flags); Loading Loading @@ -641,6 +619,7 @@ static void sunsab_shutdown(struct uart_port *port) #endif spin_unlock_irqrestore(&up->port.lock, flags); free_irq(up->port.irq, up); } /* Loading Loading @@ -1008,9 +987,11 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, if ((up->port.line & 0x1) == 0) { up->pvr_dsr_bit = (1 << 0); up->pvr_dtr_bit = (1 << 1); up->gis_shift = 2; } else { up->pvr_dsr_bit = (1 << 3); up->pvr_dtr_bit = (1 << 2); up->gis_shift = 0; } up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4); writeb(up->cached_pvr, &up->regs->w.pvr); Loading @@ -1023,19 +1004,6 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; if (!(up->port.line & 0x01)) { int err; err = request_irq(up->port.irq, sunsab_interrupt, IRQF_SHARED, "sab", up); if (err) { of_iounmap(&op->resource[0], up->port.membase, sizeof(union sab82532_async_regs)); return err; } } return 0; } Loading @@ -1051,52 +1019,60 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * 0, (inst * 2) + 0); if (err) return err; goto out; err = sunsab_init_one(&up[1], op, sizeof(union sab82532_async_regs), (inst * 2) + 1); if (err) { of_iounmap(&op->resource[0], up[0].port.membase, sizeof(union sab82532_async_regs)); free_irq(up[0].port.irq, &up[0]); return err; } if (err) goto out1; sunserial_console_match(SUNSAB_CONSOLE(), op->node, &sunsab_reg, up[0].port.line); uart_add_one_port(&sunsab_reg, &up[0].port); sunserial_console_match(SUNSAB_CONSOLE(), op->node, &sunsab_reg, up[1].port.line); uart_add_one_port(&sunsab_reg, &up[1].port); err = uart_add_one_port(&sunsab_reg, &up[0].port); if (err) goto out2; err = uart_add_one_port(&sunsab_reg, &up[1].port); if (err) goto out3; dev_set_drvdata(&op->dev, &up[0]); inst++; return 0; } static void __devexit sab_remove_one(struct uart_sunsab_port *up) { struct of_device *op = to_of_device(up->port.dev); uart_remove_one_port(&sunsab_reg, &up->port); if (!(up->port.line & 1)) free_irq(up->port.irq, up); out3: uart_remove_one_port(&sunsab_reg, &up[0].port); out2: of_iounmap(&op->resource[0], up[1].port.membase, sizeof(union sab82532_async_regs)); out1: of_iounmap(&op->resource[0], up->port.membase, up[0].port.membase, sizeof(union sab82532_async_regs)); out: return err; } static int __devexit sab_remove(struct of_device *op) { struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); sab_remove_one(&up[0]); sab_remove_one(&up[1]); uart_remove_one_port(&sunsab_reg, &up[1].port); uart_remove_one_port(&sunsab_reg, &up[0].port); of_iounmap(&op->resource[0], up[1].port.membase, sizeof(union sab82532_async_regs)); of_iounmap(&op->resource[0], up[0].port.membase, sizeof(union sab82532_async_regs)); dev_set_drvdata(&op->dev, NULL); Loading Loading @@ -1143,6 +1119,7 @@ static int __init sunsab_init(void) sunsab_reg.minor = sunserial_current_minor; sunsab_reg.nr = num_channels; sunsab_reg.cons = SUNSAB_CONSOLE(); err = uart_register_driver(&sunsab_reg); if (err) { Loading Loading
drivers/serial/sunsab.c +42 −65 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ struct uart_sunsab_port { unsigned char interrupt_mask1;/* ISR1 masking */ unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ unsigned int gis_shift; int type; /* SAB82532 version */ /* Setting configuration bits while the transmitter is active Loading Loading @@ -305,13 +306,15 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) struct tty_struct *tty; union sab82532_irq_status status; unsigned long flags; unsigned char gis; spin_lock_irqsave(&up->port.lock, flags); status.stat = 0; if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA0) gis = readb(&up->regs->r.gis) >> up->gis_shift; if (gis & 1) status.sreg.isr0 = readb(&up->regs->r.isr0); if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA1) if (gis & 2) status.sreg.isr1 = readb(&up->regs->r.isr1); tty = NULL; Loading @@ -327,35 +330,6 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) transmit_chars(up, &status); } spin_unlock(&up->port.lock); if (tty) tty_flip_buffer_push(tty); up++; spin_lock(&up->port.lock); status.stat = 0; if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB0) status.sreg.isr0 = readb(&up->regs->r.isr0); if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB1) status.sreg.isr1 = readb(&up->regs->r.isr1); tty = NULL; if (status.stat) { if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || (status.sreg.isr1 & SAB82532_ISR1_BRK)) tty = receive_chars(up, &status); if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC))) check_status(up, &status); if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR)) transmit_chars(up, &status); } spin_unlock_irqrestore(&up->port.lock, flags); if (tty) Loading Loading @@ -539,6 +513,10 @@ static int sunsab_startup(struct uart_port *port) struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; unsigned long flags; unsigned char tmp; int err = request_irq(up->port.irq, sunsab_interrupt, IRQF_SHARED, "sab", up); if (err) return err; spin_lock_irqsave(&up->port.lock, flags); Loading Loading @@ -641,6 +619,7 @@ static void sunsab_shutdown(struct uart_port *port) #endif spin_unlock_irqrestore(&up->port.lock, flags); free_irq(up->port.irq, up); } /* Loading Loading @@ -1008,9 +987,11 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, if ((up->port.line & 0x1) == 0) { up->pvr_dsr_bit = (1 << 0); up->pvr_dtr_bit = (1 << 1); up->gis_shift = 2; } else { up->pvr_dsr_bit = (1 << 3); up->pvr_dtr_bit = (1 << 2); up->gis_shift = 0; } up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4); writeb(up->cached_pvr, &up->regs->w.pvr); Loading @@ -1023,19 +1004,6 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; if (!(up->port.line & 0x01)) { int err; err = request_irq(up->port.irq, sunsab_interrupt, IRQF_SHARED, "sab", up); if (err) { of_iounmap(&op->resource[0], up->port.membase, sizeof(union sab82532_async_regs)); return err; } } return 0; } Loading @@ -1051,52 +1019,60 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * 0, (inst * 2) + 0); if (err) return err; goto out; err = sunsab_init_one(&up[1], op, sizeof(union sab82532_async_regs), (inst * 2) + 1); if (err) { of_iounmap(&op->resource[0], up[0].port.membase, sizeof(union sab82532_async_regs)); free_irq(up[0].port.irq, &up[0]); return err; } if (err) goto out1; sunserial_console_match(SUNSAB_CONSOLE(), op->node, &sunsab_reg, up[0].port.line); uart_add_one_port(&sunsab_reg, &up[0].port); sunserial_console_match(SUNSAB_CONSOLE(), op->node, &sunsab_reg, up[1].port.line); uart_add_one_port(&sunsab_reg, &up[1].port); err = uart_add_one_port(&sunsab_reg, &up[0].port); if (err) goto out2; err = uart_add_one_port(&sunsab_reg, &up[1].port); if (err) goto out3; dev_set_drvdata(&op->dev, &up[0]); inst++; return 0; } static void __devexit sab_remove_one(struct uart_sunsab_port *up) { struct of_device *op = to_of_device(up->port.dev); uart_remove_one_port(&sunsab_reg, &up->port); if (!(up->port.line & 1)) free_irq(up->port.irq, up); out3: uart_remove_one_port(&sunsab_reg, &up[0].port); out2: of_iounmap(&op->resource[0], up[1].port.membase, sizeof(union sab82532_async_regs)); out1: of_iounmap(&op->resource[0], up->port.membase, up[0].port.membase, sizeof(union sab82532_async_regs)); out: return err; } static int __devexit sab_remove(struct of_device *op) { struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); sab_remove_one(&up[0]); sab_remove_one(&up[1]); uart_remove_one_port(&sunsab_reg, &up[1].port); uart_remove_one_port(&sunsab_reg, &up[0].port); of_iounmap(&op->resource[0], up[1].port.membase, sizeof(union sab82532_async_regs)); of_iounmap(&op->resource[0], up[0].port.membase, sizeof(union sab82532_async_regs)); dev_set_drvdata(&op->dev, NULL); Loading Loading @@ -1143,6 +1119,7 @@ static int __init sunsab_init(void) sunsab_reg.minor = sunserial_current_minor; sunsab_reg.nr = num_channels; sunsab_reg.cons = SUNSAB_CONSOLE(); err = uart_register_driver(&sunsab_reg); if (err) { Loading