aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/pcmcia
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/char/pcmcia
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/char/pcmcia')
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c15
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c22
-rw-r--r--drivers/char/pcmcia/ipwireless/main.c26
-rw-r--r--drivers/char/pcmcia/synclink_cs.c16
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
1744static int cm4000_config_check(struct pcmcia_device *p_dev, 1744static 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
518static int cm4040_config_check(struct pcmcia_device *p_dev, 518static 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
78static int ipwireless_probe(struct pcmcia_device *p_dev, 78static 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
564static int mgslpc_ioprobe(struct pcmcia_device *p_dev, 564static 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