aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-08 18:46:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-08 18:46:14 -0400
commit68e24113457e437b1576670f2419b77ed0531e9e (patch)
tree4737e411b3df714ff1a2c911dbc66d0ba5e5cf5b /drivers/usb/serial/usb-serial.c
parentd56ba3205fe2e61264ef41f29cd90a666df032e4 (diff)
USB: serial: rework usb_serial_register/deregister_drivers()
This reworks the usb_serial_register_drivers() and usb_serial_deregister_drivers() to not need a pointer to a struct usb_driver anymore. The usb_driver structure is now created dynamically and registered and unregistered as needed. This saves lines of code in each usb-serial driver. All in-kernel users of these functions were also fixed up at this time. The pl2303 driver was tested that everything worked properly. Thanks for the idea to do this from Alan Stern. Cc: Adhir Ramjiawan <adhirramjiawan0@gmail.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Al Borchers <alborchers@steinerpoint.com> Cc: Aleksey Babahin <tamerlan311@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andrew Worsley <amworsley@gmail.com> Cc: Bart Hartgers <bart.hartgers@gmail.com> Cc: Bill Pemberton <wfp5p@virginia.edu> Cc: Dan Carpenter <error27@gmail.com> Cc: Dan Williams <dcbw@redhat.com> Cc: Donald Lee <donald@asix.com.tw> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Felipe Balbi <balbi@ti.com> Cc: Gary Brubaker <xavyer@ix.netcom.com> Cc: Jesper Juhl <jj@chaosbits.net> Cc: Jiri Kosina <jkosina@suse.cz> Cc: Johan Hovold <jhovold@gmail.com> Cc: Julia Lawall <julia@diku.dk> Cc: Kautuk Consul <consul.kautuk@gmail.com> Cc: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Cc: Lonnie Mendez <dignome@gmail.com> Cc: Matthias Bruestle and Harald Welte <support@reiner-sct.com> Cc: Matthias Urlichs <smurf@smurf.noris.de> Cc: Mauro Carvalho Chehab <mchehab@redhat.com> Cc: Michal Sroczynski <msroczyn@gmail.com> Cc: "Michał Wróbel" <michal.wrobel@flytronic.pl> Cc: Oliver Neukum <oliver@neukum.name> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Peter Berger <pberger@brimson.com> Cc: Preston Fick <preston.fick@silabs.com> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Cc: Rigbert Hamisch <rigbert@gmx.de> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Simon Arlott <simon@fire.lp0.eu> Cc: Support Department <support@connecttech.com> Cc: Thomas Tuttle <ttuttle@chromium.org> Cc: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> Cc: Wang YanQing <Udknight@gmail.com> Cc: William Greathouse <wgreathouse@smva.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index d1840aef0d53..62dd92270525 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1364,18 +1364,19 @@ static void usb_serial_deregister(struct usb_serial_driver *device)
1364 1364
1365/** 1365/**
1366 * usb_serial_register_drivers - register drivers for a usb-serial module 1366 * usb_serial_register_drivers - register drivers for a usb-serial module
1367 * @udriver: usb_driver used for matching devices/interfaces
1368 * @serial_drivers: NULL-terminated array of pointers to drivers to be registered 1367 * @serial_drivers: NULL-terminated array of pointers to drivers to be registered
1368 * @name: name of the usb_driver for this set of @serial_drivers
1369 * @id_table: list of all devices this @serial_drivers set binds to
1369 * 1370 *
1370 * Registers @udriver and all the drivers in the @serial_drivers array. 1371 * Registers all the drivers in the @serial_drivers array, and dynamically
1371 * Automatically fills in the .no_dynamic_id and PM fields in @udriver and 1372 * creates a struct usb_driver with the name @name and id_table of @id_table.
1372 * the .usb_driver field in each serial driver.
1373 */ 1373 */
1374int usb_serial_register_drivers(struct usb_driver *udriver, 1374int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
1375 struct usb_serial_driver * const serial_drivers[]) 1375 const char *name,
1376 const struct usb_device_id *id_table)
1376{ 1377{
1377 int rc; 1378 int rc;
1378 const struct usb_device_id *saved_id_table; 1379 struct usb_driver *udriver;
1379 struct usb_serial_driver * const *sd; 1380 struct usb_serial_driver * const *sd;
1380 1381
1381 /* 1382 /*
@@ -1386,14 +1387,16 @@ int usb_serial_register_drivers(struct usb_driver *udriver,
1386 * Performance hack: We don't want udriver to be probed until 1387 * Performance hack: We don't want udriver to be probed until
1387 * the serial drivers are registered, because the probe would 1388 * the serial drivers are registered, because the probe would
1388 * simply fail for lack of a matching serial driver. 1389 * simply fail for lack of a matching serial driver.
1389 * Therefore save off udriver's id_table until we are all set. 1390 * So we leave udriver's id_table set to NULL until we are all set.
1390 * 1391 *
1391 * Suspend/resume support is implemented in the usb-serial core, 1392 * Suspend/resume support is implemented in the usb-serial core,
1392 * so fill in the PM-related fields in udriver. 1393 * so fill in the PM-related fields in udriver.
1393 */ 1394 */
1394 saved_id_table = udriver->id_table; 1395 udriver = kzalloc(sizeof(*udriver), GFP_KERNEL);
1395 udriver->id_table = NULL; 1396 if (!udriver)
1397 return -ENOMEM;
1396 1398
1399 udriver->name = name;
1397 udriver->no_dynamic_id = 1; 1400 udriver->no_dynamic_id = 1;
1398 udriver->supports_autosuspend = 1; 1401 udriver->supports_autosuspend = 1;
1399 udriver->suspend = usb_serial_suspend; 1402 udriver->suspend = usb_serial_suspend;
@@ -1411,8 +1414,8 @@ int usb_serial_register_drivers(struct usb_driver *udriver,
1411 goto failed; 1414 goto failed;
1412 } 1415 }
1413 1416
1414 /* Now restore udriver's id_table and look for matches */ 1417 /* Now set udriver's id_table and look for matches */
1415 udriver->id_table = saved_id_table; 1418 udriver->id_table = id_table;
1416 rc = driver_attach(&udriver->drvwrap.driver); 1419 rc = driver_attach(&udriver->drvwrap.driver);
1417 return 0; 1420 return 0;
1418 1421
@@ -1426,17 +1429,20 @@ EXPORT_SYMBOL_GPL(usb_serial_register_drivers);
1426 1429
1427/** 1430/**
1428 * usb_serial_deregister_drivers - deregister drivers for a usb-serial module 1431 * usb_serial_deregister_drivers - deregister drivers for a usb-serial module
1429 * @udriver: usb_driver to unregister
1430 * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered 1432 * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered
1431 * 1433 *
1432 * Deregisters @udriver and all the drivers in the @serial_drivers array. 1434 * Deregisters all the drivers in the @serial_drivers array and deregisters and
1435 * frees the struct usb_driver that was created by the call to
1436 * usb_serial_register_drivers().
1433 */ 1437 */
1434void usb_serial_deregister_drivers(struct usb_driver *udriver, 1438void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[])
1435 struct usb_serial_driver * const serial_drivers[])
1436{ 1439{
1440 struct usb_driver *udriver = (*serial_drivers)->usb_driver;
1441
1437 for (; *serial_drivers; ++serial_drivers) 1442 for (; *serial_drivers; ++serial_drivers)
1438 usb_serial_deregister(*serial_drivers); 1443 usb_serial_deregister(*serial_drivers);
1439 usb_deregister(udriver); 1444 usb_deregister(udriver);
1445 kfree(udriver);
1440} 1446}
1441EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); 1447EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers);
1442 1448