diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-07-30 07:13:46 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-09-29 11:20:24 -0400 |
commit | 00990e7ce0b0e596fe41d9c64d6933ea70084003 (patch) | |
tree | 189e0dd92860feba84231c66955749574cac5d6d /drivers/char/pcmcia | |
parent | 440eed43e2a95bb842488755683716814da10f2b (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/char/pcmcia')
-rw-r--r-- | drivers/char/pcmcia/cm4000_cs.c | 15 | ||||
-rw-r--r-- | drivers/char/pcmcia/cm4040_cs.c | 22 | ||||
-rw-r--r-- | drivers/char/pcmcia/ipwireless/main.c | 26 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 16 |
4 files changed, 17 insertions, 62 deletions
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 0b2f3b9d261a..79de9ccb8caf 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1741,19 +1741,8 @@ static void cmm_cm4000_release(struct pcmcia_device * link) | |||
1741 | 1741 | ||
1742 | /*==== Interface to PCMCIA Layer =======================================*/ | 1742 | /*==== Interface to PCMCIA Layer =======================================*/ |
1743 | 1743 | ||
1744 | static int cm4000_config_check(struct pcmcia_device *p_dev, | 1744 | static int cm4000_config_check(struct pcmcia_device *p_dev, void *priv_data) |
1745 | cistpl_cftable_entry_t *cfg, | ||
1746 | cistpl_cftable_entry_t *dflt, | ||
1747 | void *priv_data) | ||
1748 | { | 1745 | { |
1749 | if (!cfg->io.nwin) | ||
1750 | return -ENODEV; | ||
1751 | |||
1752 | p_dev->resource[0]->start = cfg->io.win[0].base; | ||
1753 | p_dev->resource[0]->end = cfg->io.win[0].len; | ||
1754 | p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags); | ||
1755 | p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
1756 | |||
1757 | return pcmcia_request_io(p_dev); | 1746 | return pcmcia_request_io(p_dev); |
1758 | } | 1747 | } |
1759 | 1748 | ||
@@ -1761,6 +1750,8 @@ static int cm4000_config(struct pcmcia_device * link, int devno) | |||
1761 | { | 1750 | { |
1762 | struct cm4000_dev *dev; | 1751 | struct cm4000_dev *dev; |
1763 | 1752 | ||
1753 | link->config_flags |= CONF_AUTO_SET_IO; | ||
1754 | |||
1764 | /* read the config-tuples */ | 1755 | /* read the config-tuples */ |
1765 | if (pcmcia_loop_config(link, cm4000_config_check, NULL)) | 1756 | if (pcmcia_loop_config(link, cm4000_config_check, NULL)) |
1766 | goto cs_release; | 1757 | goto cs_release; |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index acf88d5c72b2..bf012d228a9e 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -515,25 +515,9 @@ static void cm4040_reader_release(struct pcmcia_device *link) | |||
515 | return; | 515 | return; |
516 | } | 516 | } |
517 | 517 | ||
518 | static int cm4040_config_check(struct pcmcia_device *p_dev, | 518 | static int cm4040_config_check(struct pcmcia_device *p_dev, void *priv_data) |
519 | cistpl_cftable_entry_t *cfg, | ||
520 | cistpl_cftable_entry_t *dflt, | ||
521 | void *priv_data) | ||
522 | { | 519 | { |
523 | int rc; | 520 | return pcmcia_request_io(p_dev); |
524 | if (!cfg->io.nwin) | ||
525 | return -ENODEV; | ||
526 | |||
527 | /* Get the IOaddr */ | ||
528 | p_dev->resource[0]->start = cfg->io.win[0].base; | ||
529 | p_dev->resource[0]->end = cfg->io.win[0].len; | ||
530 | p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags); | ||
531 | p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
532 | rc = pcmcia_request_io(p_dev); | ||
533 | |||
534 | dev_printk(KERN_INFO, &p_dev->dev, | ||
535 | "pcmcia_request_io returned 0x%x\n", rc); | ||
536 | return rc; | ||
537 | } | 521 | } |
538 | 522 | ||
539 | 523 | ||
@@ -542,6 +526,8 @@ static int reader_config(struct pcmcia_device *link, int devno) | |||
542 | struct reader_dev *dev; | 526 | struct reader_dev *dev; |
543 | int fail_rc; | 527 | int fail_rc; |
544 | 528 | ||
529 | link->config_flags |= CONF_AUTO_SET_IO; | ||
530 | |||
545 | if (pcmcia_loop_config(link, cm4040_config_check, NULL)) | 531 | if (pcmcia_loop_config(link, cm4040_config_check, NULL)) |
546 | goto cs_release; | 532 | goto cs_release; |
547 | 533 | ||
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 1b7f0920737b..594c23be69f5 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c | |||
@@ -75,22 +75,18 @@ static void signalled_reboot_callback(void *callback_data) | |||
75 | schedule_work(&ipw->work_reboot); | 75 | schedule_work(&ipw->work_reboot); |
76 | } | 76 | } |
77 | 77 | ||
78 | static int ipwireless_probe(struct pcmcia_device *p_dev, | 78 | static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) |
79 | cistpl_cftable_entry_t *cfg, | ||
80 | cistpl_cftable_entry_t *dflt, | ||
81 | void *priv_data) | ||
82 | { | 79 | { |
83 | struct ipw_dev *ipw = priv_data; | 80 | struct ipw_dev *ipw = priv_data; |
84 | struct resource *io_resource; | 81 | struct resource *io_resource; |
85 | int ret; | 82 | int ret; |
86 | 83 | ||
84 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
87 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | 85 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; |
88 | p_dev->resource[0]->start = cfg->io.win[0].base; | ||
89 | p_dev->resource[0]->end = cfg->io.win[0].len; | ||
90 | 86 | ||
91 | /* 0x40 causes it to generate level mode interrupts. */ | 87 | /* 0x40 causes it to generate level mode interrupts. */ |
92 | /* 0x04 enables IREQ pin. */ | 88 | /* 0x04 enables IREQ pin. */ |
93 | p_dev->config_index = cfg->index | 0x44; | 89 | p_dev->config_index |= 0x44; |
94 | p_dev->io_lines = 16; | 90 | p_dev->io_lines = 16; |
95 | ret = pcmcia_request_io(p_dev); | 91 | ret = pcmcia_request_io(p_dev); |
96 | if (ret) | 92 | if (ret) |
@@ -100,26 +96,18 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, | |||
100 | resource_size(p_dev->resource[0]), | 96 | resource_size(p_dev->resource[0]), |
101 | IPWIRELESS_PCCARD_NAME); | 97 | IPWIRELESS_PCCARD_NAME); |
102 | 98 | ||
103 | if (cfg->mem.nwin == 0) | ||
104 | return 0; | ||
105 | |||
106 | p_dev->resource[2]->flags |= | 99 | p_dev->resource[2]->flags |= |
107 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; | 100 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; |
108 | p_dev->resource[2]->start = cfg->mem.win[0].host_addr; | ||
109 | p_dev->resource[2]->end = cfg->mem.win[0].len; | ||
110 | if (p_dev->resource[2]->end < 0x1000) | ||
111 | p_dev->resource[2]->end = 0x1000; | ||
112 | 101 | ||
113 | ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0); | 102 | ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0); |
114 | if (ret != 0) | 103 | if (ret != 0) |
115 | goto exit1; | 104 | goto exit1; |
116 | 105 | ||
117 | ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], | 106 | ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr); |
118 | cfg->mem.win[0].card_addr); | ||
119 | if (ret != 0) | 107 | if (ret != 0) |
120 | goto exit2; | 108 | goto exit2; |
121 | 109 | ||
122 | ipw->is_v2_card = cfg->mem.win[0].len == 0x100; | 110 | ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100; |
123 | 111 | ||
124 | ipw->attr_memory = ioremap(p_dev->resource[2]->start, | 112 | ipw->attr_memory = ioremap(p_dev->resource[2]->start, |
125 | resource_size(p_dev->resource[2])); | 113 | resource_size(p_dev->resource[2])); |
@@ -165,13 +153,13 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
165 | int ret = 0; | 153 | int ret = 0; |
166 | 154 | ||
167 | ipw->is_v2_card = 0; | 155 | ipw->is_v2_card = 0; |
156 | link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM | | ||
157 | CONF_ENABLE_IRQ; | ||
168 | 158 | ||
169 | ret = pcmcia_loop_config(link, ipwireless_probe, ipw); | 159 | ret = pcmcia_loop_config(link, ipwireless_probe, ipw); |
170 | if (ret != 0) | 160 | if (ret != 0) |
171 | return ret; | 161 | return ret; |
172 | 162 | ||
173 | link->config_flags |= CONF_ENABLE_IRQ; | ||
174 | |||
175 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); | 163 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); |
176 | 164 | ||
177 | ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, | 165 | ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index c701434f76b7..a343b8f817e4 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -561,19 +561,8 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
561 | /* Card has been inserted. | 561 | /* Card has been inserted. |
562 | */ | 562 | */ |
563 | 563 | ||
564 | static int mgslpc_ioprobe(struct pcmcia_device *p_dev, | 564 | static int mgslpc_ioprobe(struct pcmcia_device *p_dev, void *priv_data) |
565 | cistpl_cftable_entry_t *cfg, | ||
566 | cistpl_cftable_entry_t *dflt, | ||
567 | void *priv_data) | ||
568 | { | 565 | { |
569 | if (!cfg->io.nwin) | ||
570 | return -ENODEV; | ||
571 | |||
572 | p_dev->resource[0]->start = cfg->io.win[0].base; | ||
573 | p_dev->resource[0]->end = cfg->io.win[0].len; | ||
574 | p_dev->resource[0]->flags |= pcmcia_io_cfg_data_width(cfg->io.flags); | ||
575 | p_dev->io_lines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
576 | |||
577 | return pcmcia_request_io(p_dev); | 566 | return pcmcia_request_io(p_dev); |
578 | } | 567 | } |
579 | 568 | ||
@@ -585,11 +574,12 @@ static int mgslpc_config(struct pcmcia_device *link) | |||
585 | if (debug_level >= DEBUG_LEVEL_INFO) | 574 | if (debug_level >= DEBUG_LEVEL_INFO) |
586 | printk("mgslpc_config(0x%p)\n", link); | 575 | printk("mgslpc_config(0x%p)\n", link); |
587 | 576 | ||
577 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; | ||
578 | |||
588 | ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); | 579 | ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); |
589 | if (ret != 0) | 580 | if (ret != 0) |
590 | goto failed; | 581 | goto failed; |
591 | 582 | ||
592 | link->config_flags |= CONF_ENABLE_IRQ; | ||
593 | link->config_index = 8; | 583 | link->config_index = 8; |
594 | link->config_regs = PRESENT_OPTION; | 584 | link->config_regs = PRESENT_OPTION; |
595 | 585 | ||