mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
Revert "driver core: Add support for linking devices during device addition"
This reverts commit 5302dd7dd0
.
Based on a lot of email and in-person discussions, this patch series is
being reworked to address a number of issues that were pointed out that
needed to be taken care of before it should be merged. It will be
resubmitted with those changes hopefully soon.
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Saravana Kannan <saravanak@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
33cbfe5449
commit
bfb3943bed
@ -44,8 +44,6 @@ early_param("sysfs.deprecated", sysfs_deprecated_setup);
|
||||
#endif
|
||||
|
||||
/* Device links support. */
|
||||
static LIST_HEAD(wait_for_suppliers);
|
||||
static DEFINE_MUTEX(wfs_lock);
|
||||
|
||||
#ifdef CONFIG_SRCU
|
||||
static DEFINE_MUTEX(device_links_lock);
|
||||
@ -420,51 +418,6 @@ struct device_link *device_link_add(struct device *consumer,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_link_add);
|
||||
|
||||
/**
|
||||
* device_link_wait_for_supplier - Mark device as waiting for supplier
|
||||
* @consumer: Consumer device
|
||||
*
|
||||
* Marks the consumer device as waiting for suppliers to become available. The
|
||||
* consumer device will never be probed until it's unmarked as waiting for
|
||||
* suppliers. The caller is responsible for adding the link to the supplier
|
||||
* once the supplier device is present.
|
||||
*
|
||||
* This function is NOT meant to be called from the probe function of the
|
||||
* consumer but rather from code that creates/adds the consumer device.
|
||||
*/
|
||||
static void device_link_wait_for_supplier(struct device *consumer)
|
||||
{
|
||||
mutex_lock(&wfs_lock);
|
||||
list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers);
|
||||
mutex_unlock(&wfs_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* device_link_check_waiting_consumers - Try to unmark waiting consumers
|
||||
*
|
||||
* Loops through all consumers waiting on suppliers and tries to add all their
|
||||
* supplier links. If that succeeds, the consumer device is unmarked as waiting
|
||||
* for suppliers. Otherwise, they are left marked as waiting on suppliers,
|
||||
*
|
||||
* The add_links bus callback is expected to return 0 if it has found and added
|
||||
* all the supplier links for the consumer device. It should return an error if
|
||||
* it isn't able to do so.
|
||||
*
|
||||
* The caller of device_link_wait_for_supplier() is expected to call this once
|
||||
* it's aware of potential suppliers becoming available.
|
||||
*/
|
||||
static void device_link_check_waiting_consumers(void)
|
||||
{
|
||||
struct device *dev, *tmp;
|
||||
|
||||
mutex_lock(&wfs_lock);
|
||||
list_for_each_entry_safe(dev, tmp, &wait_for_suppliers,
|
||||
links.needs_suppliers)
|
||||
if (!dev->bus->add_links(dev))
|
||||
list_del_init(&dev->links.needs_suppliers);
|
||||
mutex_unlock(&wfs_lock);
|
||||
}
|
||||
|
||||
static void device_link_free(struct device_link *link)
|
||||
{
|
||||
while (refcount_dec_not_one(&link->rpm_active))
|
||||
@ -599,19 +552,6 @@ int device_links_check_suppliers(struct device *dev)
|
||||
struct device_link *link;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* If a device is waiting for one or more suppliers (in
|
||||
* wait_for_suppliers list), it is not ready to probe yet. So just
|
||||
* return -EPROBE_DEFER without having to check the links with existing
|
||||
* suppliers.
|
||||
*/
|
||||
mutex_lock(&wfs_lock);
|
||||
if (!list_empty(&dev->links.needs_suppliers)) {
|
||||
mutex_unlock(&wfs_lock);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
mutex_unlock(&wfs_lock);
|
||||
|
||||
device_links_write_lock();
|
||||
|
||||
list_for_each_entry(link, &dev->links.suppliers, c_node) {
|
||||
@ -896,10 +836,6 @@ static void device_links_purge(struct device *dev)
|
||||
{
|
||||
struct device_link *link, *ln;
|
||||
|
||||
mutex_lock(&wfs_lock);
|
||||
list_del(&dev->links.needs_suppliers);
|
||||
mutex_unlock(&wfs_lock);
|
||||
|
||||
/*
|
||||
* Delete all of the remaining links from this device to any other
|
||||
* devices (either consumers or suppliers).
|
||||
@ -1764,7 +1700,6 @@ void device_initialize(struct device *dev)
|
||||
#endif
|
||||
INIT_LIST_HEAD(&dev->links.consumers);
|
||||
INIT_LIST_HEAD(&dev->links.suppliers);
|
||||
INIT_LIST_HEAD(&dev->links.needs_suppliers);
|
||||
dev->links.status = DL_DEV_NO_DRIVER;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_initialize);
|
||||
@ -2251,24 +2186,6 @@ int device_add(struct device *dev)
|
||||
BUS_NOTIFY_ADD_DEVICE, dev);
|
||||
|
||||
kobject_uevent(&dev->kobj, KOBJ_ADD);
|
||||
|
||||
/*
|
||||
* Check if any of the other devices (consumers) have been waiting for
|
||||
* this device (supplier) to be added so that they can create a device
|
||||
* link to it.
|
||||
*
|
||||
* This needs to happen after device_pm_add() because device_link_add()
|
||||
* requires the supplier be registered before it's called.
|
||||
*
|
||||
* But this also needs to happe before bus_probe_device() to make sure
|
||||
* waiting consumers can link to it before the driver is bound to the
|
||||
* device and the driver sync_state callback is called for this device.
|
||||
*/
|
||||
device_link_check_waiting_consumers();
|
||||
|
||||
if (dev->bus && dev->bus->add_links && dev->bus->add_links(dev))
|
||||
device_link_wait_for_supplier(dev);
|
||||
|
||||
bus_probe_device(dev);
|
||||
if (parent)
|
||||
klist_add_tail(&dev->p->knode_parent,
|
||||
|
@ -78,17 +78,6 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
|
||||
* -EPROBE_DEFER it will queue the device for deferred probing.
|
||||
* @uevent: Called when a device is added, removed, or a few other things
|
||||
* that generate uevents to add the environment variables.
|
||||
* @add_links: Called, perhaps multiple times per device, after a device is
|
||||
* added to this bus. The function is expected to create device
|
||||
* links to all the suppliers of the input device that are
|
||||
* available at the time this function is called. As in, the
|
||||
* function should NOT stop at the first failed device link if
|
||||
* other unlinked supplier devices are present in the system.
|
||||
*
|
||||
* Return 0 if device links have been successfully created to all
|
||||
* the suppliers of this device. Return an error if some of the
|
||||
* suppliers are not yet available and this function needs to be
|
||||
* reattempted in the future.
|
||||
* @probe: Called when a new device or driver add to this bus, and callback
|
||||
* the specific driver's probe to initial the matched device.
|
||||
* @remove: Called when a device removed from this bus.
|
||||
@ -133,7 +122,6 @@ struct bus_type {
|
||||
|
||||
int (*match)(struct device *dev, struct device_driver *drv);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
int (*add_links)(struct device *dev);
|
||||
int (*probe)(struct device *dev);
|
||||
int (*remove)(struct device *dev);
|
||||
void (*shutdown)(struct device *dev);
|
||||
@ -1143,13 +1131,11 @@ enum dl_dev_state {
|
||||
* struct dev_links_info - Device data related to device links.
|
||||
* @suppliers: List of links to supplier devices.
|
||||
* @consumers: List of links to consumer devices.
|
||||
* @needs_suppliers: Hook to global list of devices waiting for suppliers.
|
||||
* @status: Driver status information.
|
||||
*/
|
||||
struct dev_links_info {
|
||||
struct list_head suppliers;
|
||||
struct list_head consumers;
|
||||
struct list_head needs_suppliers;
|
||||
enum dl_dev_state status;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user