aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {
84 unsigned int manfid; 84 unsigned int manfid;
85 unsigned int prodid; 85 unsigned int prodid;
86 int multi; /* 1 = multifunction, > 1 = # ports */ 86 int multi; /* 1 = multifunction, > 1 = # ports */
87 int (*post)(struct pcmcia_device *);
87}; 88};
88 89
90struct serial_info {
91 struct pcmcia_device *p_dev;
92 int ndev;
93 int multi;
94 int slave;
95 int manfid;
96 int prodid;
97 int c950ctrl;
98 dev_node_t node[4];
99 int line[4];
100 const struct serial_quirk *quirk;
101};
102
103struct serial_cfg_mem {
104 tuple_t tuple;
105 cisparse_t parse;
106 u_char buf[256];
107};
108
109static int quirk_post_ibm(struct pcmcia_device *link)
110{
111 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
112 int last_ret, last_fn;
113
114 last_ret = pcmcia_access_configuration_register(link, &reg);
115 if (last_ret) {
116 last_fn = AccessConfigurationRegister;
117 goto cs_failed;
118 }
119 reg.Action = CS_WRITE;
120 reg.Value = reg.Value | 1;
121 last_ret = pcmcia_access_configuration_register(link, &reg);
122 if (last_ret) {
123 last_fn = AccessConfigurationRegister;
124 goto cs_failed;
125 }
126 return 0;
127
128 cs_failed:
129 cs_error(link, last_fn, last_ret);
130 return -ENODEV;
131}
132
89static const struct serial_quirk quirks[] = { 133static const struct serial_quirk quirks[] = {
90 { 134 {
135 .manfid = MANFID_IBM,
136 .prodid = ~0,
137 .multi = -1,
138 .post = quirk_post_ibm,
139 }, {
91 .manfid = MANFID_OMEGA, 140 .manfid = MANFID_OMEGA,
92 .prodid = PRODID_OMEGA_QSP_100, 141 .prodid = PRODID_OMEGA_QSP_100,
93 .multi = 4, 142 .multi = 4,
@@ -118,25 +167,6 @@ static const struct serial_quirk quirks[] = {
118 } 167 }
119}; 168};
120 169
121struct serial_info {
122 struct pcmcia_device *p_dev;
123 int ndev;
124 int multi;
125 int slave;
126 int manfid;
127 int prodid;
128 int c950ctrl;
129 dev_node_t node[4];
130 int line[4];
131 const struct serial_quirk *quirk;
132};
133
134struct serial_cfg_mem {
135 tuple_t tuple;
136 cisparse_t parse;
137 u_char buf[256];
138};
139
140 170
141static int serial_config(struct pcmcia_device * link); 171static int serial_config(struct pcmcia_device * link);
142 172
@@ -687,21 +717,13 @@ static int serial_config(struct pcmcia_device * link)
687 if (info->ndev == 0) 717 if (info->ndev == 0)
688 goto failed; 718 goto failed;
689 719
690 if (info->manfid == MANFID_IBM) { 720 /*
691 conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; 721 * Apply any post-init quirk. FIXME: This should really happen
692 last_ret = pcmcia_access_configuration_register(link, &reg); 722 * before we register the port, since it might already be in use.
693 if (last_ret) { 723 */
694 last_fn = AccessConfigurationRegister; 724 if (info->quirk && info->quirk->post)
695 goto cs_failed; 725 if (info->quirk->post(link))
696 } 726 goto failed;
697 reg.Action = CS_WRITE;
698 reg.Value = reg.Value | 1;
699 last_ret = pcmcia_access_configuration_register(link, &reg);
700 if (last_ret) {
701 last_fn = AccessConfigurationRegister;
702 goto cs_failed;
703 }
704 }
705 727
706 link->dev_node = &info->node[0]; 728 link->dev_node = &info->node[0];
707 kfree(cfg_mem); 729 kfree(cfg_mem);