X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fhvsi.c;h=d7806834fc171ad07f08c90f0e5b20a30c000987;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=f1f1192ba2b50ce00706f2dbb1ee9c850f338329;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index f1f1192ba..d7806834f 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c @@ -69,7 +69,7 @@ #define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) struct hvsi_struct { - struct work_struct writer; + struct delayed_work writer; struct work_struct handshaker; wait_queue_head_t emptyq; /* woken when outbuf is emptied */ wait_queue_head_t stateq; /* woken when HVSI state changes */ @@ -197,7 +197,7 @@ static inline void print_state(struct hvsi_struct *hp) }; const char *name = state_names[hp->state]; - if (hp->state > (sizeof(state_names)/sizeof(char*))) + if (hp->state > ARRAY_SIZE(state_names)) name = "UNKNOWN"; pr_debug("hvsi%i: state = %s\n", hp->index, name); @@ -291,15 +291,13 @@ static void dump_packet(uint8_t *packet) dump_hex(packet, header->len); } -/* can't use hvc_get_chars because that strips CRs */ static int hvsi_read(struct hvsi_struct *hp, char *buf, int count) { unsigned long got; - if (plpar_hcall(H_GET_TERM_CHAR, hp->vtermno, 0, 0, 0, &got, - (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) - return got; - return 0; + got = hvc_get_chars(hp->vtermno, buf, count); + + return got; } static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, @@ -313,7 +311,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, /* CD went away; no more connection */ pr_debug("hvsi%i: CD dropped\n", hp->index); hp->mctrl &= TIOCM_CD; - if (!(hp->tty->flags & CLOCAL)) + /* If userland hasn't done an open(2) yet, hp->tty is NULL. */ + if (hp->tty && !(hp->tty->flags & CLOCAL)) *to_hangup = hp->tty; } break; @@ -407,7 +406,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) hp->sysrq = 1; continue; } else if (hp->sysrq) { - handle_sysrq(c, NULL, hp->tty); + handle_sysrq(c, hp->tty); hp->sysrq = 0; continue; } @@ -556,7 +555,7 @@ static void hvsi_send_overflow(struct hvsi_struct *hp) * must get all pending data because we only get an irq on empty->non-empty * transition */ -static irqreturn_t hvsi_interrupt(int irq, void *arg, struct pt_regs *regs) +static irqreturn_t hvsi_interrupt(int irq, void *arg) { struct hvsi_struct *hp = (struct hvsi_struct *)arg; struct tty_struct *flip; @@ -617,7 +616,7 @@ static int __init poll_for_state(struct hvsi_struct *hp, int state) unsigned long end_jiffies = jiffies + HVSI_TIMEOUT; for (;;) { - hvsi_interrupt(hp->virq, (void *)hp, NULL); /* get pending data */ + hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */ if (hp->state == state) return 0; @@ -745,9 +744,10 @@ static int hvsi_handshake(struct hvsi_struct *hp) return 0; } -static void hvsi_handshaker(void *arg) +static void hvsi_handshaker(struct work_struct *work) { - struct hvsi_struct *hp = (struct hvsi_struct *)arg; + struct hvsi_struct *hp = + container_of(work, struct hvsi_struct, handshaker); if (hvsi_handshake(hp) >= 0) return; @@ -952,9 +952,10 @@ static void hvsi_push(struct hvsi_struct *hp) } /* hvsi_write_worker will keep rescheduling itself until outbuf is empty */ -static void hvsi_write_worker(void *arg) +static void hvsi_write_worker(struct work_struct *work) { - struct hvsi_struct *hp = (struct hvsi_struct *)arg; + struct hvsi_struct *hp = + container_of(work, struct hvsi_struct, writer.work); unsigned long flags; #ifdef DEBUG static long start_j = 0; @@ -988,10 +989,7 @@ static void hvsi_write_worker(void *arg) start_j = 0; #endif /* DEBUG */ wake_up_all(&hp->emptyq); - if (test_bit(TTY_DO_WRITE_WAKEUP, &hp->tty->flags) - && hp->tty->ldisc.write_wakeup) - hp->tty->ldisc.write_wakeup(hp->tty); - wake_up_interruptible(&hp->tty->write_wait); + tty_wakeup(hp->tty); } out: @@ -1134,7 +1132,7 @@ static int hvsi_tiocmset(struct tty_struct *tty, struct file *file, } -static struct tty_operations hvsi_ops = { +static const struct tty_operations hvsi_ops = { .open = hvsi_open, .close = hvsi_close, .write = hvsi_write, @@ -1156,7 +1154,6 @@ static int __init hvsi_init(void) return -ENOMEM; hvsi_driver->owner = THIS_MODULE; - hvsi_driver->devfs_name = "hvsi/"; hvsi_driver->driver_name = "hvsi"; hvsi_driver->name = "hvsi"; hvsi_driver->major = HVSI_MAJOR; @@ -1164,6 +1161,8 @@ static int __init hvsi_init(void) hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM; hvsi_driver->init_termios = tty_std_termios; hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; + hvsi_driver->init_termios.c_ispeed = 9600; + hvsi_driver->init_termios.c_ospeed = 9600; hvsi_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(hvsi_driver, &hvsi_ops); @@ -1171,7 +1170,7 @@ static int __init hvsi_init(void) struct hvsi_struct *hp = &hvsi_ports[i]; int ret = 1; - ret = request_irq(hp->virq, hvsi_interrupt, SA_INTERRUPT, "hvsi", hp); + ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp); if (ret) printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", hp->virq, ret); @@ -1181,7 +1180,7 @@ static int __init hvsi_init(void) if (tty_register_driver(hvsi_driver)) panic("Couldn't register hvsi console driver\n"); - printk(KERN_INFO "HVSI: registered %i devices\n", hvsi_count); + printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count); return 0; } @@ -1279,11 +1278,10 @@ static int __init hvsi_console_init(void) vty != NULL; vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) { struct hvsi_struct *hp; - uint32_t *vtermno; - uint32_t *irq; + const uint32_t *vtermno, *irq; - vtermno = (uint32_t *)get_property(vty, "reg", NULL); - irq = (uint32_t *)get_property(vty, "interrupts", NULL); + vtermno = get_property(vty, "reg", NULL); + irq = get_property(vty, "interrupts", NULL); if (!vtermno || !irq) continue; @@ -1293,8 +1291,8 @@ static int __init hvsi_console_init(void) } hp = &hvsi_ports[hvsi_count]; - INIT_WORK(&hp->writer, hvsi_write_worker, hp); - INIT_WORK(&hp->handshaker, hvsi_handshaker, hp); + INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker); + INIT_WORK(&hp->handshaker, hvsi_handshaker); init_waitqueue_head(&hp->emptyq); init_waitqueue_head(&hp->stateq); spin_lock_init(&hp->lock); @@ -1302,13 +1300,12 @@ static int __init hvsi_console_init(void) hp->inbuf_end = hp->inbuf; hp->state = HVSI_CLOSED; hp->vtermno = *vtermno; - hp->virq = virt_irq_create_mapping(irq[0]); + hp->virq = irq_create_mapping(NULL, irq[0]); if (hp->virq == NO_IRQ) { printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", - __FUNCTION__, hp->virq); + __FUNCTION__, irq[0]); continue; - } else - hp->virq = irq_offset_up(hp->virq); + } hvsi_count++; }