diff options
author | Andres Salomon <dilinger@queued.net> | 2010-10-23 03:41:09 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-01-14 06:37:44 -0500 |
commit | df96669401cb8bac216f911f5bf92910357b29d3 (patch) | |
tree | f3e5a714bb1d3cf91c2279f461e2d71db9e21309 /drivers/gpio | |
parent | 816b4580cef948c7d9ac9e3e63fb1b663012f057 (diff) |
gpio: Convert cs5535 from pci device to platform device
The cs5535-mfd driver now takes care of the PCI BAR handling; this
simplifies the gpio driver a lot.
Signed-off-by: Andres Salomon <dilinger@queued.net>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/cs5535-gpio.c | 93 |
1 files changed, 31 insertions, 62 deletions
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 815d98b2c1ba..70967e23bc3d 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c | |||
@@ -11,14 +11,13 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/cs5535.h> | 17 | #include <linux/cs5535.h> |
18 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
19 | 19 | ||
20 | #define DRV_NAME "cs5535-gpio" | 20 | #define DRV_NAME "cs5535-gpio" |
21 | #define GPIO_BAR 1 | ||
22 | 21 | ||
23 | /* | 22 | /* |
24 | * Some GPIO pins | 23 | * Some GPIO pins |
@@ -47,7 +46,7 @@ static struct cs5535_gpio_chip { | |||
47 | struct gpio_chip chip; | 46 | struct gpio_chip chip; |
48 | resource_size_t base; | 47 | resource_size_t base; |
49 | 48 | ||
50 | struct pci_dev *pdev; | 49 | struct platform_device *pdev; |
51 | spinlock_t lock; | 50 | spinlock_t lock; |
52 | } cs5535_gpio_chip; | 51 | } cs5535_gpio_chip; |
53 | 52 | ||
@@ -301,10 +300,10 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = { | |||
301 | }, | 300 | }, |
302 | }; | 301 | }; |
303 | 302 | ||
304 | static int __init cs5535_gpio_probe(struct pci_dev *pdev, | 303 | static int __devinit cs5535_gpio_probe(struct platform_device *pdev) |
305 | const struct pci_device_id *pci_id) | ||
306 | { | 304 | { |
307 | int err; | 305 | struct resource *res; |
306 | int err = -EIO; | ||
308 | ulong mask_orig = mask; | 307 | ulong mask_orig = mask; |
309 | 308 | ||
310 | /* There are two ways to get the GPIO base address; one is by | 309 | /* There are two ways to get the GPIO base address; one is by |
@@ -314,25 +313,24 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev, | |||
314 | * it turns out to be unreliable in the face of crappy BIOSes, we | 313 | * it turns out to be unreliable in the face of crappy BIOSes, we |
315 | * can always go back to using MSRs.. */ | 314 | * can always go back to using MSRs.. */ |
316 | 315 | ||
317 | err = pci_enable_device_io(pdev); | 316 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
318 | if (err) { | 317 | if (!res) { |
319 | dev_err(&pdev->dev, "can't enable device IO\n"); | 318 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
320 | goto done; | 319 | goto done; |
321 | } | 320 | } |
322 | 321 | ||
323 | err = pci_request_region(pdev, GPIO_BAR, DRV_NAME); | 322 | if (!request_region(res->start, resource_size(res), pdev->name)) { |
324 | if (err) { | 323 | dev_err(&pdev->dev, "can't request region\n"); |
325 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); | ||
326 | goto done; | 324 | goto done; |
327 | } | 325 | } |
328 | 326 | ||
329 | /* set up the driver-specific struct */ | 327 | /* set up the driver-specific struct */ |
330 | cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR); | 328 | cs5535_gpio_chip.base = res->start; |
331 | cs5535_gpio_chip.pdev = pdev; | 329 | cs5535_gpio_chip.pdev = pdev; |
332 | spin_lock_init(&cs5535_gpio_chip.lock); | 330 | spin_lock_init(&cs5535_gpio_chip.lock); |
333 | 331 | ||
334 | dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR, | 332 | dev_info(&pdev->dev, "region 0x%x - 0x%x reserved\n", |
335 | (unsigned long long) cs5535_gpio_chip.base); | 333 | res->start, res->end); |
336 | 334 | ||
337 | /* mask out reserved pins */ | 335 | /* mask out reserved pins */ |
338 | mask &= 0x1F7FFFFF; | 336 | mask &= 0x1F7FFFFF; |
@@ -350,78 +348,49 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev, | |||
350 | if (err) | 348 | if (err) |
351 | goto release_region; | 349 | goto release_region; |
352 | 350 | ||
353 | dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n"); | 351 | dev_info(&pdev->dev, "GPIO support successfully loaded.\n"); |
354 | return 0; | 352 | return 0; |
355 | 353 | ||
356 | release_region: | 354 | release_region: |
357 | pci_release_region(pdev, GPIO_BAR); | 355 | release_region(res->start, resource_size(res)); |
358 | done: | 356 | done: |
359 | return err; | 357 | return err; |
360 | } | 358 | } |
361 | 359 | ||
362 | static void __exit cs5535_gpio_remove(struct pci_dev *pdev) | 360 | static int __devexit cs5535_gpio_remove(struct platform_device *pdev) |
363 | { | 361 | { |
362 | struct resource *r; | ||
364 | int err; | 363 | int err; |
365 | 364 | ||
366 | err = gpiochip_remove(&cs5535_gpio_chip.chip); | 365 | err = gpiochip_remove(&cs5535_gpio_chip.chip); |
367 | if (err) { | 366 | if (err) { |
368 | /* uhh? */ | 367 | /* uhh? */ |
369 | dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); | 368 | dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); |
369 | return err; | ||
370 | } | 370 | } |
371 | pci_release_region(pdev, GPIO_BAR); | ||
372 | } | ||
373 | |||
374 | static struct pci_device_id cs5535_gpio_pci_tbl[] = { | ||
375 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
376 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
377 | { 0, }, | ||
378 | }; | ||
379 | MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl); | ||
380 | 371 | ||
381 | /* | 372 | r = platform_get_resource(pdev, IORESOURCE_IO, 0); |
382 | * We can't use the standard PCI driver registration stuff here, since | 373 | release_region(r->start, resource_size(r)); |
383 | * that allows only one driver to bind to each PCI device (and we want | 374 | return 0; |
384 | * multiple drivers to be able to bind to the device). Instead, manually | ||
385 | * scan for the PCI device, request a single region, and keep track of the | ||
386 | * devices that we're using. | ||
387 | */ | ||
388 | |||
389 | static int __init cs5535_gpio_scan_pci(void) | ||
390 | { | ||
391 | struct pci_dev *pdev; | ||
392 | int err = -ENODEV; | ||
393 | int i; | ||
394 | |||
395 | for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) { | ||
396 | pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor, | ||
397 | cs5535_gpio_pci_tbl[i].device, NULL); | ||
398 | if (pdev) { | ||
399 | err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]); | ||
400 | if (err) | ||
401 | pci_dev_put(pdev); | ||
402 | |||
403 | /* we only support a single CS5535/6 southbridge */ | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | return err; | ||
409 | } | 375 | } |
410 | 376 | ||
411 | static void __exit cs5535_gpio_free_pci(void) | 377 | static struct platform_driver cs5535_gpio_drv = { |
412 | { | 378 | .driver = { |
413 | cs5535_gpio_remove(cs5535_gpio_chip.pdev); | 379 | .name = DRV_NAME, |
414 | pci_dev_put(cs5535_gpio_chip.pdev); | 380 | .owner = THIS_MODULE, |
415 | } | 381 | }, |
382 | .probe = cs5535_gpio_probe, | ||
383 | .remove = __devexit_p(cs5535_gpio_remove), | ||
384 | }; | ||
416 | 385 | ||
417 | static int __init cs5535_gpio_init(void) | 386 | static int __init cs5535_gpio_init(void) |
418 | { | 387 | { |
419 | return cs5535_gpio_scan_pci(); | 388 | return platform_driver_register(&cs5535_gpio_drv); |
420 | } | 389 | } |
421 | 390 | ||
422 | static void __exit cs5535_gpio_exit(void) | 391 | static void __exit cs5535_gpio_exit(void) |
423 | { | 392 | { |
424 | cs5535_gpio_free_pci(); | 393 | platform_driver_unregister(&cs5535_gpio_drv); |
425 | } | 394 | } |
426 | 395 | ||
427 | module_init(cs5535_gpio_init); | 396 | module_init(cs5535_gpio_init); |