diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2006-09-16 21:34:11 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-10-01 17:06:30 +0100 |
commit | eee3a883cebefca6c450c3c1c18a996e23001c2c (patch) | |
tree | 9f6c0ae92c4bdf97485f0cf40747225d49717048 | |
parent | a8244b564ccc46dabf2367008aecf2b380a9be8d (diff) | |
download | op-kernel-dev-eee3a883cebefca6c450c3c1c18a996e23001c2c.zip op-kernel-dev-eee3a883cebefca6c450c3c1c18a996e23001c2c.tar.gz |
[SERIAL] serial_cs: convert IBM post-init handling to a quirk
Move IBM quirk handling into its own quirk entry. Note that doing
quirk handling after we've registered the ports is racy, but since
I don't know if moving this will have an undesired effect, it's
probably better to leave where it is.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/serial/serial_cs.c | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 82d42f3..ac4571a 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -84,10 +84,59 @@ struct serial_quirk { unsigned int manfid; unsigned int prodid; int multi; /* 1 = multifunction, > 1 = # ports */ + int (*post)(struct pcmcia_device *); }; +struct serial_info { + struct pcmcia_device *p_dev; + int ndev; + int multi; + int slave; + int manfid; + int prodid; + int c950ctrl; + dev_node_t node[4]; + int line[4]; + const struct serial_quirk *quirk; +}; + +struct serial_cfg_mem { + tuple_t tuple; + cisparse_t parse; + u_char buf[256]; +}; + +static int quirk_post_ibm(struct pcmcia_device *link) +{ + conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; + int last_ret, last_fn; + + last_ret = pcmcia_access_configuration_register(link, ®); + if (last_ret) { + last_fn = AccessConfigurationRegister; + goto cs_failed; + } + reg.Action = CS_WRITE; + reg.Value = reg.Value | 1; + last_ret = pcmcia_access_configuration_register(link, ®); + if (last_ret) { + last_fn = AccessConfigurationRegister; + goto cs_failed; + } + return 0; + + cs_failed: + cs_error(link, last_fn, last_ret); + return -ENODEV; +} + static const struct serial_quirk quirks[] = { { + .manfid = MANFID_IBM, + .prodid = ~0, + .multi = -1, + .post = quirk_post_ibm, + }, { .manfid = MANFID_OMEGA, .prodid = PRODID_OMEGA_QSP_100, .multi = 4, @@ -118,25 +167,6 @@ static const struct serial_quirk quirks[] = { } }; -struct serial_info { - struct pcmcia_device *p_dev; - int ndev; - int multi; - int slave; - int manfid; - int prodid; - int c950ctrl; - dev_node_t node[4]; - int line[4]; - const struct serial_quirk *quirk; -}; - -struct serial_cfg_mem { - tuple_t tuple; - cisparse_t parse; - u_char buf[256]; -}; - static int serial_config(struct pcmcia_device * link); @@ -687,21 +717,13 @@ static int serial_config(struct pcmcia_device * link) if (info->ndev == 0) goto failed; - if (info->manfid == MANFID_IBM) { - conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; - last_ret = pcmcia_access_configuration_register(link, ®); - if (last_ret) { - last_fn = AccessConfigurationRegister; - goto cs_failed; - } - reg.Action = CS_WRITE; - reg.Value = reg.Value | 1; - last_ret = pcmcia_access_configuration_register(link, ®); - if (last_ret) { - last_fn = AccessConfigurationRegister; - goto cs_failed; - } - } + /* + * Apply any post-init quirk. FIXME: This should really happen + * before we register the port, since it might already be in use. + */ + if (info->quirk && info->quirk->post) + if (info->quirk->post(link)) + goto failed; link->dev_node = &info->node[0]; kfree(cfg_mem); |