@ -72,7 +72,7 @@ static DEFINE_MUTEX(hotplug_lock);
struct dock_dependent_device {
struct list_head list ;
acpi_handle handle ;
struct acpi_device * adev ;
const struct acpi_dock_ops * hp_ops ;
void * hp_context ;
unsigned int hp_refcount ;
@ -98,12 +98,13 @@ enum dock_callback_type {
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* add_dock_dependent_device - associate a device with the dock station
* @ ds : The dock station
* @ handle : handle of the dependent device
* @ ds : Dock station .
* @ adev : Dependent ACPI device object .
*
* Add the dependent device to the dock ' s dependent device list .
*/
static int add_dock_dependent_device ( struct dock_station * ds , acpi_handle handle )
static int add_dock_dependent_device ( struct dock_station * ds ,
struct acpi_device * adev )
{
struct dock_dependent_device * dd ;
@ -111,7 +112,7 @@ static int add_dock_dependent_device(struct dock_station *ds, acpi_handle handle
if ( ! dd )
return - ENOMEM ;
dd - > h an dl e = h an dl e;
dd - > adev = adev ;
INIT_LIST_HEAD ( & dd - > list ) ;
list_add_tail ( & dd - > list , & ds - > dependent_devices ) ;
@ -212,7 +213,7 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
return ;
if ( cb )
cb ( dd - > handle , event , dd - > hp_context ) ;
cb ( dd - > adev - > handle , event , dd - > hp_context ) ;
dock_release_hotplug ( dd ) ;
}
@ -231,18 +232,18 @@ static struct dock_station *find_dock_station(acpi_handle handle)
/**
* find_dock_dependent_device - get a device dependent on this dock
* @ ds : the dock station
* @ handle : the acpi_handle of the device we want
* @ adev : ACPI device object to find .
*
* iterate over the dependent device list for this dock . If the
* dependent device matches the handle , return .
*/
static struct dock_dependent_device *
find_dock_dependent_device ( struct dock_station * ds , acpi_handle handle )
find_dock_dependent_device ( struct dock_station * ds , struct acpi_device * adev )
{
struct dock_dependent_device * dd ;
list_for_each_entry ( dd , & ds - > dependent_devices , list )
if ( h an dl e = = dd - > h an dl e)
if ( adev = = dd - > adev )
return dd ;
return NULL ;
@ -252,10 +253,9 @@ void register_dock_dependent_device(struct acpi_device *adev,
acpi_handle dshandle )
{
struct dock_station * ds = find_dock_station ( dshandle ) ;
acpi_handle handle = adev - > handle ;
if ( ds & & ! find_dock_dependent_device ( ds , h an dl e) )
add_dock_dependent_device ( ds , h an dl e) ;
if ( ds & & ! find_dock_dependent_device ( ds , adev ) )
add_dock_dependent_device ( ds , adev ) ;
}
/*****************************************************************************
@ -264,24 +264,24 @@ void register_dock_dependent_device(struct acpi_device *adev,
/**
* is_dock_device - see if a device is on a dock station
* @ handle : acpi handle of the device
* @ adev : ACPI device object to check .
*
* If this device is either the dock station itself ,
* or is a device dependent on the dock station , then it
* is a dock device
*/
int is_dock_device ( acpi_handle handle )
int is_dock_device ( struct acpi_device * adev )
{
struct dock_station * dock_station ;
if ( ! dock_station_count )
return 0 ;
if ( acpi_dock_match ( handle ) )
if ( acpi_dock_match ( adev - > handle ) )
return 1 ;
list_for_each_entry ( dock_station , & dock_stations , sibling )
if ( find_dock_dependent_device ( dock_station , h an dl e) )
if ( find_dock_dependent_device ( dock_station , adev ) )
return 1 ;
return 0 ;
@ -308,43 +308,6 @@ static int dock_present(struct dock_station *ds)
return 0 ;
}
/**
* dock_create_acpi_device - add new devices to acpi
* @ handle - handle of the device to add
*
* This function will create a new acpi_device for the given
* handle if one does not exist already . This should cause
* acpi to scan for drivers for the given devices , and call
* matching driver ' s add routine .
*/
static void dock_create_acpi_device ( acpi_handle handle )
{
struct acpi_device * device = NULL ;
int ret ;
acpi_bus_get_device ( handle , & device ) ;
if ( ! acpi_device_enumerated ( device ) ) {
ret = acpi_bus_scan ( handle ) ;
if ( ret )
pr_debug ( " error adding bus, %x \n " , - ret ) ;
}
}
/**
* dock_remove_acpi_device - remove the acpi_device struct from acpi
* @ handle - the handle of the device to remove
*
* Tell acpi to remove the acpi_device . This should cause any loaded
* driver to have it ' s remove routine called .
*/
static void dock_remove_acpi_device ( acpi_handle handle )
{
struct acpi_device * device ;
if ( ! acpi_bus_get_device ( handle , & device ) )
acpi_bus_trim ( device ) ;
}
/**
* hot_remove_dock_devices - Remove dock station devices .
* @ ds : Dock station .
@ -362,7 +325,7 @@ static void hot_remove_dock_devices(struct dock_station *ds)
dock_hotplug_event ( dd , ACPI_NOTIFY_EJECT_REQUEST , false ) ;
list_for_each_entry_reverse ( dd , & ds - > dependent_devices , list )
dock_remove_acpi_device ( dd - > h an dl e) ;
acpi_bus_trim ( dd - > adev ) ;
}
/**
@ -388,12 +351,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
dock_hotplug_event ( dd , event , DOCK_CALL_HANDLER ) ;
/*
* Now make sure that an acpi_device is created for each dependent
* device . That will cause scan handlers to be attached to device
* objects or acpi_drivers to be stopped / started if they are present .
* Check if all devices have been enumerated already . If not , run
* acpi_bus_scan ( ) for them and that will cause scan handlers to be
* attached to device objects or acpi_drivers to be stopped / started if
* they are present .
*/
list_for_each_entry ( dd , & ds - > dependent_devices , list )
dock_create_acpi_device ( dd - > handle ) ;
list_for_each_entry ( dd , & ds - > dependent_devices , list ) {
struct acpi_device * adev = dd - > adev ;
if ( ! acpi_device_enumerated ( adev ) ) {
int ret = acpi_bus_scan ( adev - > handle ) ;
if ( ret )
dev_dbg ( & adev - > dev , " scan error %d \n " , - ret ) ;
}
}
}
static void dock_event ( struct dock_station * ds , u32 event , int num )
@ -514,6 +485,7 @@ int register_hotplug_dock_device(acpi_handle handle,
{
struct dock_dependent_device * dd ;
struct dock_station * dock_station ;
struct acpi_device * adev ;
int ret = - EINVAL ;
if ( WARN_ON ( ! context ) )
@ -522,6 +494,10 @@ int register_hotplug_dock_device(acpi_handle handle,
if ( ! dock_station_count )
return - ENODEV ;
ret = acpi_bus_get_device ( handle , & adev ) ;
if ( ret )
return ret ;
/*
* make sure this handle is for a device dependent on the dock ,
* this would include the dock station itself
@ -532,7 +508,7 @@ int register_hotplug_dock_device(acpi_handle handle,
* separately , so there are two ' dock stations ' which need the
* ops
*/
dd = find_dock_dependent_device ( dock_station , h an dl e) ;
dd = find_dock_dependent_device ( dock_station , adev ) ;
if ( dd & & ! dock_init_hotplug ( dd , ops , context , init , release ) )
ret = 0 ;
}
@ -549,12 +525,16 @@ void unregister_hotplug_dock_device(acpi_handle handle)
{
struct dock_dependent_device * dd ;
struct dock_station * dock_station ;
struct acpi_device * adev ;
if ( ! dock_station_count )
return ;
if ( acpi_bus_get_device ( handle , & adev ) )
return ;
list_for_each_entry ( dock_station , & dock_stations , sibling ) {
dd = find_dock_dependent_device ( dock_station , handle ) ;
dd = find_dock_dependent_device ( dock_station , adev ) ;
if ( dd )
dock_release_hotplug ( dd ) ;
}
@ -807,7 +787,7 @@ void acpi_dock_add(struct acpi_device *adev)
goto err_unregister ;
/* add the dock station as a device dependent on itself */
ret = add_dock_dependent_device ( dock_station , h an dl e) ;
ret = add_dock_dependent_device ( dock_station , adev ) ;
if ( ret )
goto err_rmgroup ;