aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
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/ide
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/ide')
-rw-r--r--drivers/ide/ide-cs.c82
1 files changed, 25 insertions, 57 deletions
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 25b8a105a98d..c389d9a28881 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -96,10 +96,8 @@ static int ide_probe(struct pcmcia_device *link)
96 info->p_dev = link; 96 info->p_dev = link;
97 link->priv = info; 97 link->priv = info;
98 98
99 link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 99 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
100 link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; 100 CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
101 link->config_flags |= CONF_ENABLE_IRQ;
102 link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
103 101
104 return ide_config(link); 102 return ide_config(link);
105} /* ide_attach */ 103} /* ide_attach */
@@ -194,52 +192,31 @@ out_release:
194 192
195======================================================================*/ 193======================================================================*/
196 194
197struct pcmcia_config_check { 195static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
198 unsigned long ctl_base;
199 int is_kme;
200};
201
202static int pcmcia_check_one_config(struct pcmcia_device *pdev,
203 cistpl_cftable_entry_t *cfg,
204 cistpl_cftable_entry_t *dflt,
205 void *priv_data)
206{ 196{
207 struct pcmcia_config_check *stk = priv_data; 197 int *is_kme = priv_data;
208 198
209 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 199 if (!(pdev->resource[0]->flags & IO_DATA_PATH_WIDTH_8)) {
210 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 200 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
211 pdev->io_lines = io->flags & CISTPL_IO_LINES_MASK; 201 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
212 pdev->config_index = cfg->index; 202 }
213 pdev->resource[0]->start = io->win[0].base; 203 pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
214 if (!(io->flags & CISTPL_IO_16BIT)) { 204 pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
215 pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 205
216 pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 206 if (pdev->resource[1]->end) {
217 } 207 pdev->resource[0]->end = 8;
218 if (io->nwin == 2) { 208 pdev->resource[1]->end = (*is_kme) ? 2 : 1;
219 pdev->resource[0]->end = 8; 209 } else {
220 pdev->resource[1]->start = io->win[1].base; 210 if (pdev->resource[0]->end < 16)
221 pdev->resource[1]->end = (stk->is_kme) ? 2 : 1;
222 if (pcmcia_request_io(pdev) != 0)
223 return -ENODEV;
224 stk->ctl_base = pdev->resource[1]->start;
225 } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
226 pdev->resource[0]->end = io->win[0].len;
227 pdev->resource[1]->end = 0;
228 if (pcmcia_request_io(pdev) != 0)
229 return -ENODEV;
230 stk->ctl_base = pdev->resource[0]->start + 0x0e;
231 } else
232 return -ENODEV; 211 return -ENODEV;
233 /* If we've got this far, we're done */
234 return 0;
235 } 212 }
236 return -ENODEV; 213
214 return pcmcia_request_io(pdev);
237} 215}
238 216
239static int ide_config(struct pcmcia_device *link) 217static int ide_config(struct pcmcia_device *link)
240{ 218{
241 ide_info_t *info = link->priv; 219 ide_info_t *info = link->priv;
242 struct pcmcia_config_check *stk = NULL;
243 int ret = 0, is_kme = 0; 220 int ret = 0, is_kme = 0;
244 unsigned long io_base, ctl_base; 221 unsigned long io_base, ctl_base;
245 struct ide_host *host; 222 struct ide_host *host;
@@ -250,19 +227,16 @@ static int ide_config(struct pcmcia_device *link)
250 ((link->card_id == PRODID_KME_KXLC005_A) || 227 ((link->card_id == PRODID_KME_KXLC005_A) ||
251 (link->card_id == PRODID_KME_KXLC005_B))); 228 (link->card_id == PRODID_KME_KXLC005_B)));
252 229
253 stk = kzalloc(sizeof(*stk), GFP_KERNEL); 230 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
254 if (!stk)
255 goto err_mem;
256 stk->is_kme = is_kme;
257 io_base = ctl_base = 0;
258
259 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
260 link->config_flags &= ~CONF_AUTO_CHECK_VCC; 231 link->config_flags &= ~CONF_AUTO_CHECK_VCC;
261 if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) 232 if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
262 goto failed; /* No suitable config found */ 233 goto failed; /* No suitable config found */
263 } 234 }
264 io_base = link->resource[0]->start; 235 io_base = link->resource[0]->start;
265 ctl_base = stk->ctl_base; 236 if (link->resource[1]->end)
237 ctl_base = link->resource[1]->start;
238 else
239 ctl_base = link->resource[0]->start + 0x0e;
266 240
267 if (!link->irq) 241 if (!link->irq)
268 goto failed; 242 goto failed;
@@ -294,15 +268,9 @@ static int ide_config(struct pcmcia_device *link)
294 'a' + host->ports[0]->index * 2, 268 'a' + host->ports[0]->index * 2,
295 link->vpp / 10, link->vpp % 10); 269 link->vpp / 10, link->vpp % 10);
296 270
297 kfree(stk);
298 return 0; 271 return 0;
299 272
300err_mem:
301 printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
302 goto failed;
303
304failed: 273failed:
305 kfree(stk);
306 ide_release(link); 274 ide_release(link);
307 return -ENODEV; 275 return -ENODEV;
308} /* ide_config */ 276} /* ide_config */