[SERIAL] serial_cs: convert IBM post-init handling to a quirk
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Sat, 16 Sep 2006 20:34:11 +0000 (21:34 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 1 Oct 2006 16:06:30 +0000 (17:06 +0100)
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>
drivers/serial/serial_cs.c

index 82d42f30725ed603903293e60c5c7a0bb70baf69..ac4571a25b30465627d4c4f235217effd461a537 100644 (file)
@@ -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);