aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_pcmcia.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-07-30 07:13:46 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-09-29 11:20:24 -0400
commit00990e7ce0b0e596fe41d9c64d6933ea70084003 (patch)
tree189e0dd92860feba84231c66955749574cac5d6d /drivers/ata/pata_pcmcia.c
parent440eed43e2a95bb842488755683716814da10f2b (diff)
pcmcia: use autoconfiguration feature for ioports and iomem
When CONF_AUTO_SET_IO or CONF_AUTO_SET_IOMEM are set, the corresponding fields in struct pcmcia_device *p_dev->resource[0,1,2] are set accordinly. Drivers wishing to override certain settings may do so in the callback function, but they no longer need to parse the CIS entries stored in cistpl_cftable_entry_t themselves. CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: linux-ide@vger.kernel.org CC: linux-usb@vger.kernel.org CC: laforge@gnumonks.org CC: linux-mtd@lists.infradead.org CC: linux-bluetooth@vger.kernel.org CC: alsa-devel@alsa-project.org CC: linux-serial@vger.kernel.org CC: Jiri Kosina <jkosina@suse.cz> CC: linux-scsi@vger.kernel.org Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/ata/pata_pcmcia.c')
-rw-r--r--drivers/ata/pata_pcmcia.c81
1 files changed, 26 insertions, 55 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 954f43c512f1..88cb03c36963 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -167,45 +167,26 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
167}; 167};
168 168
169 169
170struct pcmcia_config_check { 170static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
171 unsigned long ctl_base;
172 int is_kme;
173};
174
175static int pcmcia_check_one_config(struct pcmcia_device *pdev,
176 cistpl_cftable_entry_t *cfg,
177 cistpl_cftable_entry_t *dflt,
178 void *priv_data)
179{ 171{
180 struct pcmcia_config_check *stk = priv_data; 172 int *is_kme = priv_data;
181 173
182 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 174 if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
183 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 175 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
184 pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 176 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
185 pdev->resource[0]->start = io->win[0].base; 177 }
186 if (!(io->flags & CISTPL_IO_16BIT)) { 178 pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
187 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 179 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
188 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 180
189 } 181 if (pdev->resource[1]->end) {
190 if (io->nwin == 2) { 182 pdev->resource[0]->end = 8;
191 pdev->resource[0]->end = 8; 183 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
192 pdev->resource[1]->start = io->win[1].base; 184 } else {
193 pdev->resource[1]->end = (stk->is_kme) ? 2 : 1; 185 if (pdev->resource[0]->end < 16)
194 if (pcmcia_request_io(pdev) != 0)
195 return -ENODEV;
196 stk->ctl_base = pdev->resource[1]->start;
197 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
198 pdev->resource[0]->end = io->win[0].len;
199 pdev->resource[1]->end = 0;
200 if (pcmcia_request_io(pdev) != 0)
201 return -ENODEV;
202 stk->ctl_base = pdev->resource[0]->start + 0x0e;
203 } else
204 return -ENODEV; 186 return -ENODEV;
205 /* If we've got this far, we're done */
206 return 0;
207 } 187 }
208 return -ENODEV; 188
189 return pcmcia_request_io(pdev);
209} 190}
210 191
211/** 192/**
@@ -220,7 +201,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
220{ 201{
221 struct ata_host *host; 202 struct ata_host *host;
222 struct ata_port *ap; 203 struct ata_port *ap;
223 struct pcmcia_config_check *stk = NULL;
224 int is_kme = 0, ret = -ENOMEM, p; 204 int is_kme = 0, ret = -ENOMEM, p;
225 unsigned long io_base, ctl_base; 205 unsigned long io_base, ctl_base;
226 void __iomem *io_addr, *ctl_addr; 206 void __iomem *io_addr, *ctl_addr;
@@ -228,10 +208,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
228 struct ata_port_operations *ops = &pcmcia_port_ops; 208 struct ata_port_operations *ops = &pcmcia_port_ops;
229 209
230 /* Set up attributes in order to probe card and get resources */ 210 /* Set up attributes in order to probe card and get resources */
231 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 211 pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
232 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 212 CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
233 pdev->config_flags |= CONF_ENABLE_IRQ;
234 pdev->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
235 213
236 /* See if we have a manufacturer identifier. Use it to set is_kme for 214 /* See if we have a manufacturer identifier. Use it to set is_kme for
237 vendor quirks */ 215 vendor quirks */
@@ -239,21 +217,17 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
239 ((pdev->card_id == PRODID_KME_KXLC005_A) || 217 ((pdev->card_id == PRODID_KME_KXLC005_A) ||
240 (pdev->card_id == PRODID_KME_KXLC005_B))); 218 (pdev->card_id == PRODID_KME_KXLC005_B)));
241 219
242 /* Allocate resoure probing structures */ 220 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme)) {
243
244 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
245 if (!stk)
246 goto out1;
247 stk->is_kme = is_kme;
248 io_base = ctl_base = 0;
249
250 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) {
251 pdev->config_flags &= ~CONF_AUTO_CHECK_VCC; 221 pdev->config_flags &= ~CONF_AUTO_CHECK_VCC;
252 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, stk)) 222 if (pcmcia_loop_config(pdev, pcmcia_check_one_config, &is_kme))
253 goto failed; /* No suitable config found */ 223 goto failed; /* No suitable config found */
254 } 224 }
255 io_base = pdev->resource[0]->start; 225 io_base = pdev->resource[0]->start;
256 ctl_base = stk->ctl_base; 226 if (pdev->resource[1]->end)
227 ctl_base = pdev->resource[1]->start;
228 else
229 ctl_base = pdev->resource[0]->start + 0x0e;
230
257 if (!pdev->irq) 231 if (!pdev->irq)
258 goto failed; 232 goto failed;
259 233
@@ -310,13 +284,10 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
310 goto failed; 284 goto failed;
311 285
312 pdev->priv = host; 286 pdev->priv = host;
313 kfree(stk);
314 return 0; 287 return 0;
315 288
316failed: 289failed:
317 kfree(stk);
318 pcmcia_disable_device(pdev); 290 pcmcia_disable_device(pdev);
319out1:
320 return ret; 291 return ret;
321} 292}
322 293