diff options
author | Jean Delvare <khali@linux-fr.org> | 2007-05-08 03:27:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:05 -0400 |
commit | a7d801afc3d4d1c8aaa0449f17b9f9ce62e16236 (patch) | |
tree | f6e94a90d13271d12a2e7179bf22a9c0084972a2 /drivers/parport/parport_pc.c | |
parent | c15a3837d2aa30e3ea41aed49d80abed355ab6bd (diff) |
legacy PC parports support parport->dev
Give legacy parallel ports a platform device in the device tree.
This is a quick and dirty implementation; it doesn't actually convert the
legacy parport code to the device driver model (by splitting out probing from
device creation). But at least parallel port device drivers will finally have
a device to work with.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/parport/parport_pc.c')
-rw-r--r-- | drivers/parport/parport_pc.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index c3240a67ef85..02c0d52c9f76 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/slab.h> | 53 | #include <linux/slab.h> |
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/pnp.h> | 55 | #include <linux/pnp.h> |
56 | #include <linux/platform_device.h> | ||
56 | #include <linux/sysctl.h> | 57 | #include <linux/sysctl.h> |
57 | 58 | ||
58 | #include <asm/io.h> | 59 | #include <asm/io.h> |
@@ -2156,6 +2157,17 @@ struct parport *parport_pc_probe_port (unsigned long int base, | |||
2156 | struct resource *base_res; | 2157 | struct resource *base_res; |
2157 | struct resource *ECR_res = NULL; | 2158 | struct resource *ECR_res = NULL; |
2158 | struct resource *EPP_res = NULL; | 2159 | struct resource *EPP_res = NULL; |
2160 | struct platform_device *pdev = NULL; | ||
2161 | |||
2162 | if (!dev) { | ||
2163 | /* We need a physical device to attach to, but none was | ||
2164 | * provided. Create our own. */ | ||
2165 | pdev = platform_device_register_simple("parport_pc", | ||
2166 | base, NULL, 0); | ||
2167 | if (IS_ERR(pdev)) | ||
2168 | return NULL; | ||
2169 | dev = &pdev->dev; | ||
2170 | } | ||
2159 | 2171 | ||
2160 | ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); | 2172 | ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); |
2161 | if (!ops) | 2173 | if (!ops) |
@@ -2359,6 +2371,8 @@ out3: | |||
2359 | out2: | 2371 | out2: |
2360 | kfree (ops); | 2372 | kfree (ops); |
2361 | out1: | 2373 | out1: |
2374 | if (pdev) | ||
2375 | platform_device_unregister(pdev); | ||
2362 | return NULL; | 2376 | return NULL; |
2363 | } | 2377 | } |
2364 | 2378 | ||
@@ -3106,6 +3120,21 @@ static struct pnp_driver parport_pc_pnp_driver = { | |||
3106 | }; | 3120 | }; |
3107 | 3121 | ||
3108 | 3122 | ||
3123 | static int __devinit parport_pc_platform_probe(struct platform_device *pdev) | ||
3124 | { | ||
3125 | /* Always succeed, the actual probing is done in | ||
3126 | * parport_pc_probe_port(). */ | ||
3127 | return 0; | ||
3128 | } | ||
3129 | |||
3130 | static struct platform_driver parport_pc_platform_driver = { | ||
3131 | .driver = { | ||
3132 | .owner = THIS_MODULE, | ||
3133 | .name = "parport_pc", | ||
3134 | }, | ||
3135 | .probe = parport_pc_platform_probe, | ||
3136 | }; | ||
3137 | |||
3109 | /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ | 3138 | /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ |
3110 | static int __devinit __attribute__((unused)) | 3139 | static int __devinit __attribute__((unused)) |
3111 | parport_pc_find_isa_ports (int autoirq, int autodma) | 3140 | parport_pc_find_isa_ports (int autoirq, int autodma) |
@@ -3381,9 +3410,15 @@ __setup("parport_init_mode=",parport_init_mode_setup); | |||
3381 | 3410 | ||
3382 | static int __init parport_pc_init(void) | 3411 | static int __init parport_pc_init(void) |
3383 | { | 3412 | { |
3413 | int err; | ||
3414 | |||
3384 | if (parse_parport_params()) | 3415 | if (parse_parport_params()) |
3385 | return -EINVAL; | 3416 | return -EINVAL; |
3386 | 3417 | ||
3418 | err = platform_driver_register(&parport_pc_platform_driver); | ||
3419 | if (err) | ||
3420 | return err; | ||
3421 | |||
3387 | if (io[0]) { | 3422 | if (io[0]) { |
3388 | int i; | 3423 | int i; |
3389 | /* Only probe the ports we were given. */ | 3424 | /* Only probe the ports we were given. */ |
@@ -3408,6 +3443,7 @@ static void __exit parport_pc_exit(void) | |||
3408 | pci_unregister_driver (&parport_pc_pci_driver); | 3443 | pci_unregister_driver (&parport_pc_pci_driver); |
3409 | if (pnp_registered_parport) | 3444 | if (pnp_registered_parport) |
3410 | pnp_unregister_driver (&parport_pc_pnp_driver); | 3445 | pnp_unregister_driver (&parport_pc_pnp_driver); |
3446 | platform_driver_unregister(&parport_pc_platform_driver); | ||
3411 | 3447 | ||
3412 | spin_lock(&ports_lock); | 3448 | spin_lock(&ports_lock); |
3413 | while (!list_empty(&ports_list)) { | 3449 | while (!list_empty(&ports_list)) { |
@@ -3416,6 +3452,9 @@ static void __exit parport_pc_exit(void) | |||
3416 | priv = list_entry(ports_list.next, | 3452 | priv = list_entry(ports_list.next, |
3417 | struct parport_pc_private, list); | 3453 | struct parport_pc_private, list); |
3418 | port = priv->port; | 3454 | port = priv->port; |
3455 | if (port->dev && port->dev->bus == &platform_bus_type) | ||
3456 | platform_device_unregister( | ||
3457 | to_platform_device(port->dev)); | ||
3419 | spin_unlock(&ports_lock); | 3458 | spin_unlock(&ports_lock); |
3420 | parport_pc_unregister_port(port); | 3459 | parport_pc_unregister_port(port); |
3421 | spin_lock(&ports_lock); | 3460 | spin_lock(&ports_lock); |