diff options
-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 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 | ||
90 | struct 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 | |||
103 | struct serial_cfg_mem { | ||
104 | tuple_t tuple; | ||
105 | cisparse_t parse; | ||
106 | u_char buf[256]; | ||
107 | }; | ||
108 | |||
109 | static 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, ®); | ||
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, ®); | ||
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 | |||
89 | static const struct serial_quirk quirks[] = { | 133 | static 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 | ||
121 | struct 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 | |||
134 | struct serial_cfg_mem { | ||
135 | tuple_t tuple; | ||
136 | cisparse_t parse; | ||
137 | u_char buf[256]; | ||
138 | }; | ||
139 | |||
140 | 170 | ||
141 | static int serial_config(struct pcmcia_device * link); | 171 | static 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, ®); | 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, ®); | ||
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); |