From 7ef057fa707897c19725d7e07123e57f6aea79db Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 16 Sep 2006 22:45:41 +0100 Subject: [SERIAL] serial_cs: Convert Oxford 950 / Possio GCC wakeup quirk Move the Oxford Semi OX950 / Possio GCC wakeup handling to a quirk wakeup handler. Signed-off-by: Russell King --- drivers/serial/serial_cs.c | 100 ++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 37 deletions(-) (limited to 'drivers/serial/serial_cs.c') diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index ac4571a25b30..8e48cb659b3d 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -84,6 +84,7 @@ struct serial_quirk { unsigned int manfid; unsigned int prodid; int multi; /* 1 = multifunction, > 1 = # ports */ + void (*wakeup)(struct pcmcia_device *); int (*post)(struct pcmcia_device *); }; @@ -130,16 +131,67 @@ static int quirk_post_ibm(struct pcmcia_device *link) return -ENODEV; } +static void quirk_wakeup_oxsemi(struct pcmcia_device *link) +{ + struct serial_info *info = link->priv; + + outb(12, info->c950ctrl + 1); +} + +/* request_region? oxsemi branch does no request_region too... */ +/* + * This sequence is needed to properly initialize MC45 attached to OXCF950. + * I tried decreasing these msleep()s, but it worked properly (survived + * 1000 stop/start operations) with these timeouts (or bigger). + */ +static void quirk_wakeup_possio_gcc(struct pcmcia_device *link) +{ + struct serial_info *info = link->priv; + unsigned int ctrl = info->c950ctrl; + + outb(0xA, ctrl + 1); + msleep(100); + outb(0xE, ctrl + 1); + msleep(300); + outb(0xC, ctrl + 1); + msleep(100); + outb(0xE, ctrl + 1); + msleep(200); + outb(0xF, ctrl + 1); + msleep(100); + outb(0xE, ctrl + 1); + msleep(100); + outb(0xC, ctrl + 1); +} + static const struct serial_quirk quirks[] = { { .manfid = MANFID_IBM, .prodid = ~0, .multi = -1, .post = quirk_post_ibm, + }, { + .manfid = MANFID_INTEL, + .prodid = PRODID_INTEL_DUAL_RS232, + .multi = 2, + }, { + .manfid = MANFID_NATINST, + .prodid = PRODID_NATINST_QUAD_RS232, + .multi = 4, }, { .manfid = MANFID_OMEGA, .prodid = PRODID_OMEGA_QSP_100, .multi = 4, + }, { + .manfid = MANFID_OXSEMI, + .prodid = ~0, + .multi = -1, + .wakeup = quirk_wakeup_oxsemi, + }, { + .manfid = MANFID_POSSIO, + .prodid = PRODID_POSSIO_GCC, + .multi = -1, + .wakeup = quirk_wakeup_possio_gcc, }, { .manfid = MANFID_QUATECH, .prodid = PRODID_QUATECH_DUAL_RS232, @@ -156,14 +208,6 @@ static const struct serial_quirk quirks[] = { .manfid = MANFID_SOCKET, .prodid = PRODID_SOCKET_DUAL_RS232, .multi = 2, - }, { - .manfid = MANFID_INTEL, - .prodid = PRODID_INTEL_DUAL_RS232, - .multi = 2, - }, { - .manfid = MANFID_NATINST, - .prodid = PRODID_NATINST_QUAD_RS232, - .multi = 4, } }; @@ -171,33 +215,6 @@ static const struct serial_quirk quirks[] = { static int serial_config(struct pcmcia_device * link); -static void wakeup_card(struct serial_info *info) -{ - int ctrl = info->c950ctrl; - - if (info->manfid == MANFID_OXSEMI) { - outb(12, ctrl + 1); - } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) { - /* request_region? oxsemi branch does no request_region too... */ - /* This sequence is needed to properly initialize MC45 attached to OXCF950. - * I tried decreasing these msleep()s, but it worked properly (survived - * 1000 stop/start operations) with these timeouts (or bigger). */ - outb(0xA, ctrl + 1); - msleep(100); - outb(0xE, ctrl + 1); - msleep(300); - outb(0xC, ctrl + 1); - msleep(100); - outb(0xE, ctrl + 1); - msleep(200); - outb(0xF, ctrl + 1); - msleep(100); - outb(0xE, ctrl + 1); - msleep(100); - outb(0xC, ctrl + 1); - } -} - /*====================================================================== After a card is removed, serial_remove() will unregister @@ -243,7 +260,9 @@ static int serial_resume(struct pcmcia_device *link) for (i = 0; i < info->ndev; i++) serial8250_resume_port(info->line[i]); - wakeup_card(info); + + if (info->quirk && info->quirk->wakeup) + info->quirk->wakeup(link); } return 0; @@ -602,7 +621,14 @@ static int multi_config(struct pcmcia_device * link) link->irq.AssignedIRQ); } info->c950ctrl = base2; - wakeup_card(info); + + /* + * FIXME: We really should wake up the port prior to + * handing it over to the serial layer. + */ + if (info->quirk && info->quirk->wakeup) + info->quirk->wakeup(link); + rc = 0; goto free_cfg_mem; } -- cgit v1.2.3-59-g8ed1b