summaryrefslogtreecommitdiff
path: root/drivers/serial/serial_cs.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-09-16 21:34:11 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-10-01 17:06:30 +0100
commiteee3a883cebefca6c450c3c1c18a996e23001c2c (patch)
tree9f6c0ae92c4bdf97485f0cf40747225d49717048 /drivers/serial/serial_cs.c
parenta8244b564ccc46dabf2367008aecf2b380a9be8d (diff)
downloadlwn-eee3a883cebefca6c450c3c1c18a996e23001c2c.tar.gz
lwn-eee3a883cebefca6c450c3c1c18a996e23001c2c.zip
[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>
Diffstat (limited to 'drivers/serial/serial_cs.c')
-rw-r--r--drivers/serial/serial_cs.c90
1 files changed, 56 insertions, 34 deletions
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 82d42f30725e..ac4571a25b30 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, &reg);
+ 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, &reg);
+ 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, &reg);
- 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, &reg);
- 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);