diff options
author | Andres Salomon <dilinger@queued.net> | 2010-10-23 03:41:14 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-01-14 06:37:44 -0500 |
commit | 69bc6def395ebfdb137898179d7e559ba4c779d8 (patch) | |
tree | 947f897429e89a6ca1dd39323a8a216df6fc7a71 /drivers/misc/cs5535-mfgpt.c | |
parent | df96669401cb8bac216f911f5bf92910357b29d3 (diff) |
misc: Convert cs5535-mfgpt from pci device to platform device
The cs5535-mfd driver now takes care of the PCI BAR handling; this
simplifies the mfgpt driver a bunch.
Signed-off-by: Andres Salomon <dilinger@queued.net>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/misc/cs5535-mfgpt.c')
-rw-r--r-- | drivers/misc/cs5535-mfgpt.c | 73 |
1 files changed, 21 insertions, 52 deletions
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 6f6218061b0d..499bd64e4d1d 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c | |||
@@ -16,12 +16,11 @@ | |||
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/cs5535.h> | 20 | #include <linux/cs5535.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #define DRV_NAME "cs5535-mfgpt" | 23 | #define DRV_NAME "cs5535-mfgpt" |
24 | #define MFGPT_BAR 2 | ||
25 | 24 | ||
26 | static int mfgpt_reset_timers; | 25 | static int mfgpt_reset_timers; |
27 | module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); | 26 | module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); |
@@ -37,7 +36,7 @@ static struct cs5535_mfgpt_chip { | |||
37 | DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); | 36 | DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); |
38 | resource_size_t base; | 37 | resource_size_t base; |
39 | 38 | ||
40 | struct pci_dev *pdev; | 39 | struct platform_device *pdev; |
41 | spinlock_t lock; | 40 | spinlock_t lock; |
42 | int initialized; | 41 | int initialized; |
43 | } cs5535_mfgpt_chip; | 42 | } cs5535_mfgpt_chip; |
@@ -290,10 +289,10 @@ static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt) | |||
290 | return timers; | 289 | return timers; |
291 | } | 290 | } |
292 | 291 | ||
293 | static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, | 292 | static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) |
294 | const struct pci_device_id *pci_id) | ||
295 | { | 293 | { |
296 | int err, t; | 294 | struct resource *res; |
295 | int err = -EIO, t; | ||
297 | 296 | ||
298 | /* There are two ways to get the MFGPT base address; one is by | 297 | /* There are two ways to get the MFGPT base address; one is by |
299 | * fetching it from MSR_LBAR_MFGPT, the other is by reading the | 298 | * fetching it from MSR_LBAR_MFGPT, the other is by reading the |
@@ -302,29 +301,28 @@ static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, | |||
302 | * it turns out to be unreliable in the face of crappy BIOSes, we | 301 | * it turns out to be unreliable in the face of crappy BIOSes, we |
303 | * can always go back to using MSRs.. */ | 302 | * can always go back to using MSRs.. */ |
304 | 303 | ||
305 | err = pci_enable_device_io(pdev); | 304 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
306 | if (err) { | 305 | if (!res) { |
307 | dev_err(&pdev->dev, "can't enable device IO\n"); | 306 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
308 | goto done; | 307 | goto done; |
309 | } | 308 | } |
310 | 309 | ||
311 | err = pci_request_region(pdev, MFGPT_BAR, DRV_NAME); | 310 | if (!request_region(res->start, resource_size(res), pdev->name)) { |
312 | if (err) { | 311 | dev_err(&pdev->dev, "can't request region\n"); |
313 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", MFGPT_BAR); | ||
314 | goto done; | 312 | goto done; |
315 | } | 313 | } |
316 | 314 | ||
317 | /* set up the driver-specific struct */ | 315 | /* set up the driver-specific struct */ |
318 | cs5535_mfgpt_chip.base = pci_resource_start(pdev, MFGPT_BAR); | 316 | cs5535_mfgpt_chip.base = res->start; |
319 | cs5535_mfgpt_chip.pdev = pdev; | 317 | cs5535_mfgpt_chip.pdev = pdev; |
320 | spin_lock_init(&cs5535_mfgpt_chip.lock); | 318 | spin_lock_init(&cs5535_mfgpt_chip.lock); |
321 | 319 | ||
322 | dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", MFGPT_BAR, | 320 | dev_info(&pdev->dev, "region 0x%x - 0x%x reserved\n", res->start, |
323 | (unsigned long long) cs5535_mfgpt_chip.base); | 321 | res->end); |
324 | 322 | ||
325 | /* detect the available timers */ | 323 | /* detect the available timers */ |
326 | t = scan_timers(&cs5535_mfgpt_chip); | 324 | t = scan_timers(&cs5535_mfgpt_chip); |
327 | dev_info(&pdev->dev, DRV_NAME ": %d MFGPT timers available\n", t); | 325 | dev_info(&pdev->dev, "%d MFGPT timers available\n", t); |
328 | cs5535_mfgpt_chip.initialized = 1; | 326 | cs5535_mfgpt_chip.initialized = 1; |
329 | return 0; | 327 | return 0; |
330 | 328 | ||
@@ -332,47 +330,18 @@ done: | |||
332 | return err; | 330 | return err; |
333 | } | 331 | } |
334 | 332 | ||
335 | static struct pci_device_id cs5535_mfgpt_pci_tbl[] = { | 333 | static struct platform_driver cs5535_mfgpt_drv = { |
336 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | 334 | .driver = { |
337 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 335 | .name = DRV_NAME, |
338 | { 0, }, | 336 | .owner = THIS_MODULE, |
337 | }, | ||
338 | .probe = cs5535_mfgpt_probe, | ||
339 | }; | 339 | }; |
340 | MODULE_DEVICE_TABLE(pci, cs5535_mfgpt_pci_tbl); | ||
341 | 340 | ||
342 | /* | ||
343 | * Just like with the cs5535-gpio driver, we can't use the standard PCI driver | ||
344 | * registration stuff. It only allows only one driver to bind to each PCI | ||
345 | * device, and we want the GPIO and MFGPT drivers to be able to share a PCI | ||
346 | * device. Instead, we manually scan for the PCI device, request a single | ||
347 | * region, and keep track of the devices that we're using. | ||
348 | */ | ||
349 | |||
350 | static int __init cs5535_mfgpt_scan_pci(void) | ||
351 | { | ||
352 | struct pci_dev *pdev; | ||
353 | int err = -ENODEV; | ||
354 | int i; | ||
355 | |||
356 | for (i = 0; i < ARRAY_SIZE(cs5535_mfgpt_pci_tbl); i++) { | ||
357 | pdev = pci_get_device(cs5535_mfgpt_pci_tbl[i].vendor, | ||
358 | cs5535_mfgpt_pci_tbl[i].device, NULL); | ||
359 | if (pdev) { | ||
360 | err = cs5535_mfgpt_probe(pdev, | ||
361 | &cs5535_mfgpt_pci_tbl[i]); | ||
362 | if (err) | ||
363 | pci_dev_put(pdev); | ||
364 | |||
365 | /* we only support a single CS5535/6 southbridge */ | ||
366 | break; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | return err; | ||
371 | } | ||
372 | 341 | ||
373 | static int __init cs5535_mfgpt_init(void) | 342 | static int __init cs5535_mfgpt_init(void) |
374 | { | 343 | { |
375 | return cs5535_mfgpt_scan_pci(); | 344 | return platform_driver_register(&cs5535_mfgpt_drv); |
376 | } | 345 | } |
377 | 346 | ||
378 | module_init(cs5535_mfgpt_init); | 347 | module_init(cs5535_mfgpt_init); |