aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/nsc-ircc.c
diff options
context:
space:
mode:
authorJean Tourrilhes <jt@hpl.hp.com>2006-03-20 21:54:03 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 21:54:03 -0500
commitec4f32d550b94b4b66c9c7689bc09c6b32c8e82e (patch)
treeb9eca8a87257ebf0585bc4817ec78c5cf98de47e /drivers/net/irda/nsc-ircc.c
parent4277a083ecd2c8771058641132bcecea04ca6608 (diff)
[IRDA]: nsc-ircc: ISAPnP support
This enables PnP support for the nsc-ircc chipset. Since we can't fetch the chipset cfg_base from the PnP layer, we just use the PnP information as one more hint when probing the chip. Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com> Signed-off-by: Samuel Ortiz <samuel.ortiz@nokia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/irda/nsc-ircc.c')
-rw-r--r--drivers/net/irda/nsc-ircc.c185
1 files changed, 151 insertions, 34 deletions
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index ee717d0e939e..282414ba22f0 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -12,6 +12,7 @@
12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no> 12 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
13 * Copyright (c) 1998 Lichen Wang, <lwang@actisys.com> 13 * Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
14 * Copyright (c) 1998 Actisys Corp., www.actisys.com 14 * Copyright (c) 1998 Actisys Corp., www.actisys.com
15 * Copyright (c) 2000-2004 Jean Tourrilhes <jt@hpl.hp.com>
15 * All Rights Reserved 16 * All Rights Reserved
16 * 17 *
17 * This program is free software; you can redistribute it and/or 18 * This program is free software; you can redistribute it and/or
@@ -53,6 +54,7 @@
53#include <linux/init.h> 54#include <linux/init.h>
54#include <linux/rtnetlink.h> 55#include <linux/rtnetlink.h>
55#include <linux/dma-mapping.h> 56#include <linux/dma-mapping.h>
57#include <linux/pnp.h>
56 58
57#include <asm/io.h> 59#include <asm/io.h>
58#include <asm/dma.h> 60#include <asm/dma.h>
@@ -78,8 +80,8 @@ static int dongle_id;
78 80
79/* Use BIOS settions by default, but user may supply module parameters */ 81/* Use BIOS settions by default, but user may supply module parameters */
80static unsigned int io[] = { ~0, ~0, ~0, ~0 }; 82static unsigned int io[] = { ~0, ~0, ~0, ~0 };
81static unsigned int irq[] = { 0, 0, 0, 0, 0 }; 83static unsigned int irq[] = { 0, 0, 0, 0 };
82static unsigned int dma[] = { 0, 0, 0, 0, 0 }; 84static unsigned int dma[] = { 0, 0, 0, 0 };
83 85
84static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info); 86static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info);
85static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info); 87static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info);
@@ -87,6 +89,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info);
87static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); 89static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info);
88static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); 90static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info);
89static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); 91static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info);
92static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id);
90 93
91/* These are the known NSC chips */ 94/* These are the known NSC chips */
92static nsc_chip_t chips[] = { 95static nsc_chip_t chips[] = {
@@ -104,7 +107,6 @@ static nsc_chip_t chips[] = {
104 { NULL } 107 { NULL }
105}; 108};
106 109
107/* Max 4 instances for now */
108static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; 110static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL };
109 111
110static char *dongle_types[] = { 112static char *dongle_types[] = {
@@ -126,8 +128,24 @@ static char *dongle_types[] = {
126 "No dongle connected", 128 "No dongle connected",
127}; 129};
128 130
131/* PNP probing */
132static chipio_t pnp_info;
133static const struct pnp_device_id nsc_ircc_pnp_table[] = {
134 { .id = "NSC6001", .driver_data = 0 },
135 { .id = "IBM0071", .driver_data = 0 },
136 { }
137};
138
139MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table);
140
141static struct pnp_driver nsc_ircc_pnp_driver = {
142 .name = "nsc-ircc",
143 .id_table = nsc_ircc_pnp_table,
144 .probe = nsc_ircc_pnp_probe,
145};
146
129/* Some prototypes */ 147/* Some prototypes */
130static int nsc_ircc_open(int i, chipio_t *info); 148static int nsc_ircc_open(chipio_t *info);
131static int nsc_ircc_close(struct nsc_ircc_cb *self); 149static int nsc_ircc_close(struct nsc_ircc_cb *self);
132static int nsc_ircc_setup(chipio_t *info); 150static int nsc_ircc_setup(chipio_t *info);
133static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self); 151static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self);
@@ -148,6 +166,10 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd
148static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev); 166static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev);
149static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data); 167static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
150 168
169/* Globals */
170static int pnp_registered;
171static int pnp_succeeded;
172
151/* 173/*
152 * Function nsc_ircc_init () 174 * Function nsc_ircc_init ()
153 * 175 *
@@ -158,28 +180,30 @@ static int __init nsc_ircc_init(void)
158{ 180{
159 chipio_t info; 181 chipio_t info;
160 nsc_chip_t *chip; 182 nsc_chip_t *chip;
161 int ret = -ENODEV; 183 int ret;
162 int cfg_base; 184 int cfg_base;
163 int cfg, id; 185 int cfg, id;
164 int reg; 186 int reg;
165 int i = 0; 187 int i = 0;
166 188
189 /* Register with PnP subsystem to detect disable ports */
190 ret = pnp_register_driver(&nsc_ircc_pnp_driver);
191
192 if (ret >= 0)
193 pnp_registered = 1;
194
195 ret = -ENODEV;
196
167 /* Probe for all the NSC chipsets we know about */ 197 /* Probe for all the NSC chipsets we know about */
168 for (chip=chips; chip->name ; chip++) { 198 for (chip = chips; chip->name ; chip++) {
169 IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__, 199 IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__,
170 chip->name); 200 chip->name);
171 201
172 /* Try all config registers for this chip */ 202 /* Try all config registers for this chip */
173 for (cfg=0; cfg<3; cfg++) { 203 for (cfg = 0; cfg < ARRAY_SIZE(chip->cfg); cfg++) {
174 cfg_base = chip->cfg[cfg]; 204 cfg_base = chip->cfg[cfg];
175 if (!cfg_base) 205 if (!cfg_base)
176 continue; 206 continue;
177
178 memset(&info, 0, sizeof(chipio_t));
179 info.cfg_base = cfg_base;
180 info.fir_base = io[i];
181 info.dma = dma[i];
182 info.irq = irq[i];
183 207
184 /* Read index register */ 208 /* Read index register */
185 reg = inb(cfg_base); 209 reg = inb(cfg_base);
@@ -194,24 +218,64 @@ static int __init nsc_ircc_init(void)
194 if ((id & chip->cid_mask) == chip->cid_value) { 218 if ((id & chip->cid_mask) == chip->cid_value) {
195 IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n", 219 IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n",
196 __FUNCTION__, chip->name, id & ~chip->cid_mask); 220 __FUNCTION__, chip->name, id & ~chip->cid_mask);
197 /*
198 * If the user supplies the base address, then
199 * we init the chip, if not we probe the values
200 * set by the BIOS
201 */
202 if (io[i] < 0x2000) {
203 chip->init(chip, &info);
204 } else
205 chip->probe(chip, &info);
206 221
207 if (nsc_ircc_open(i, &info) == 0) 222 /*
208 ret = 0; 223 * If we found a correct PnP setting,
224 * we first try it.
225 */
226 if (pnp_succeeded) {
227 memset(&info, 0, sizeof(chipio_t));
228 info.cfg_base = cfg_base;
229 info.fir_base = pnp_info.fir_base;
230 info.dma = pnp_info.dma;
231 info.irq = pnp_info.irq;
232
233 if (info.fir_base < 0x2000) {
234 IRDA_MESSAGE("%s, chip->init\n", driver_name);
235 chip->init(chip, &info);
236 } else
237 chip->probe(chip, &info);
238
239 if (nsc_ircc_open(&info) >= 0)
240 ret = 0;
241 }
242
243 /*
244 * Opening based on PnP values failed.
245 * Let's fallback to user values, or probe
246 * the chip.
247 */
248 if (ret) {
249 IRDA_DEBUG(2, "%s, PnP init failed\n", driver_name);
250 memset(&info, 0, sizeof(chipio_t));
251 info.cfg_base = cfg_base;
252 info.fir_base = io[i];
253 info.dma = dma[i];
254 info.irq = irq[i];
255
256 /*
257 * If the user supplies the base address, then
258 * we init the chip, if not we probe the values
259 * set by the BIOS
260 */
261 if (io[i] < 0x2000) {
262 chip->init(chip, &info);
263 } else
264 chip->probe(chip, &info);
265
266 if (nsc_ircc_open(&info) >= 0)
267 ret = 0;
268 }
209 i++; 269 i++;
210 } else { 270 } else {
211 IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id); 271 IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id);
212 } 272 }
213 } 273 }
214 274 }
275
276 if (ret) {
277 pnp_unregister_driver(&nsc_ircc_pnp_driver);
278 pnp_registered = 0;
215 } 279 }
216 280
217 return ret; 281 return ret;
@@ -229,10 +293,15 @@ static void __exit nsc_ircc_cleanup(void)
229 293
230 pm_unregister_all(nsc_ircc_pmproc); 294 pm_unregister_all(nsc_ircc_pmproc);
231 295
232 for (i=0; i < 4; i++) { 296 for (i = 0; i < ARRAY_SIZE(dev_self); i++) {
233 if (dev_self[i]) 297 if (dev_self[i])
234 nsc_ircc_close(dev_self[i]); 298 nsc_ircc_close(dev_self[i]);
235 } 299 }
300
301 if (pnp_registered)
302 pnp_unregister_driver(&nsc_ircc_pnp_driver);
303
304 pnp_registered = 0;
236} 305}
237 306
238/* 307/*
@@ -241,16 +310,27 @@ static void __exit nsc_ircc_cleanup(void)
241 * Open driver instance 310 * Open driver instance
242 * 311 *
243 */ 312 */
244static int __init nsc_ircc_open(int i, chipio_t *info) 313static int __init nsc_ircc_open(chipio_t *info)
245{ 314{
246 struct net_device *dev; 315 struct net_device *dev;
247 struct nsc_ircc_cb *self; 316 struct nsc_ircc_cb *self;
248 struct pm_dev *pmdev; 317 struct pm_dev *pmdev;
249 void *ret; 318 void *ret;
250 int err; 319 int err, chip_index;
251 320
252 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 321 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
253 322
323
324 for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) {
325 if (!dev_self[chip_index])
326 break;
327 }
328
329 if (chip_index == ARRAY_SIZE(dev_self)) {
330 IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __FUNCTION__);
331 return -ENOMEM;
332 }
333
254 IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name, 334 IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
255 info->cfg_base); 335 info->cfg_base);
256 336
@@ -271,8 +351,8 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
271 spin_lock_init(&self->lock); 351 spin_lock_init(&self->lock);
272 352
273 /* Need to store self somewhere */ 353 /* Need to store self somewhere */
274 dev_self[i] = self; 354 dev_self[chip_index] = self;
275 self->index = i; 355 self->index = chip_index;
276 356
277 /* Initialize IO */ 357 /* Initialize IO */
278 self->io.cfg_base = info->cfg_base; 358 self->io.cfg_base = info->cfg_base;
@@ -351,7 +431,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
351 431
352 /* Check if user has supplied a valid dongle id or not */ 432 /* Check if user has supplied a valid dongle id or not */
353 if ((dongle_id <= 0) || 433 if ((dongle_id <= 0) ||
354 (dongle_id >= (sizeof(dongle_types) / sizeof(dongle_types[0]))) ) { 434 (dongle_id >= ARRAY_SIZE(dongle_types))) {
355 dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base); 435 dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base);
356 436
357 IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name, 437 IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name,
@@ -368,7 +448,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
368 if (pmdev) 448 if (pmdev)
369 pmdev->data = self; 449 pmdev->data = self;
370 450
371 return 0; 451 return chip_index;
372 out4: 452 out4:
373 dma_free_coherent(NULL, self->tx_buff.truesize, 453 dma_free_coherent(NULL, self->tx_buff.truesize,
374 self->tx_buff.head, self->tx_buff_dma); 454 self->tx_buff.head, self->tx_buff_dma);
@@ -379,7 +459,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
379 release_region(self->io.fir_base, self->io.fir_ext); 459 release_region(self->io.fir_base, self->io.fir_ext);
380 out1: 460 out1:
381 free_netdev(dev); 461 free_netdev(dev);
382 dev_self[i] = NULL; 462 dev_self[chip_index] = NULL;
383 return err; 463 return err;
384} 464}
385 465
@@ -806,6 +886,43 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info)
806 return 0; 886 return 0;
807} 887}
808 888
889/* PNP probing */
890static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id)
891{
892 memset(&pnp_info, 0, sizeof(chipio_t));
893 pnp_info.irq = -1;
894 pnp_info.dma = -1;
895 pnp_succeeded = 1;
896
897 /* There don't seem to be any way to get the cfg_base.
898 * On my box, cfg_base is in the PnP descriptor of the
899 * motherboard. Oh well... Jean II */
900
901 if (pnp_port_valid(dev, 0) &&
902 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED))
903 pnp_info.fir_base = pnp_port_start(dev, 0);
904
905 if (pnp_irq_valid(dev, 0) &&
906 !(pnp_irq_flags(dev, 0) & IORESOURCE_DISABLED))
907 pnp_info.irq = pnp_irq(dev, 0);
908
909 if (pnp_dma_valid(dev, 0) &&
910 !(pnp_dma_flags(dev, 0) & IORESOURCE_DISABLED))
911 pnp_info.dma = pnp_dma(dev, 0);
912
913 IRDA_DEBUG(0, "%s() : From PnP, found firbase 0x%03X ; irq %d ; dma %d.\n",
914 __FUNCTION__, pnp_info.fir_base, pnp_info.irq, pnp_info.dma);
915
916 if((pnp_info.fir_base == 0) ||
917 (pnp_info.irq == -1) || (pnp_info.dma == -1)) {
918 /* Returning an error will disable the device. Yuck ! */
919 //return -EINVAL;
920 pnp_succeeded = 0;
921 }
922
923 return 0;
924}
925
809/* 926/*
810 * Function nsc_ircc_setup (info) 927 * Function nsc_ircc_setup (info)
811 * 928 *