diff options
-rw-r--r-- | drivers/base/base.h | 5 | ||||
-rw-r--r-- | drivers/base/core.c | 2 | ||||
-rw-r--r-- | drivers/base/dd.c | 18 | ||||
-rw-r--r-- | include/linux/device.h | 5 |
4 files changed, 16 insertions, 14 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h index 2c13deae5f82..6ee17bb391a9 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -59,6 +59,10 @@ struct driver_private { | |||
59 | * @knode_parent - node in sibling list | 59 | * @knode_parent - node in sibling list |
60 | * @knode_driver - node in driver list | 60 | * @knode_driver - node in driver list |
61 | * @knode_bus - node in bus list | 61 | * @knode_bus - node in bus list |
62 | * @deferred_probe - entry in deferred_probe_list which is used to retry the | ||
63 | * binding of drivers which were unable to get all the resources needed by | ||
64 | * the device; typically because it depends on another driver getting | ||
65 | * probed first. | ||
62 | * @driver_data - private pointer for driver specific info. Will turn into a | 66 | * @driver_data - private pointer for driver specific info. Will turn into a |
63 | * list soon. | 67 | * list soon. |
64 | * @device - pointer back to the struct class that this structure is | 68 | * @device - pointer back to the struct class that this structure is |
@@ -71,6 +75,7 @@ struct device_private { | |||
71 | struct klist_node knode_parent; | 75 | struct klist_node knode_parent; |
72 | struct klist_node knode_driver; | 76 | struct klist_node knode_driver; |
73 | struct klist_node knode_bus; | 77 | struct klist_node knode_bus; |
78 | struct list_head deferred_probe; | ||
74 | void *driver_data; | 79 | void *driver_data; |
75 | struct device *device; | 80 | struct device *device; |
76 | }; | 81 | }; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index d4ff7adce38c..7050a75dde38 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -644,7 +644,6 @@ void device_initialize(struct device *dev) | |||
644 | { | 644 | { |
645 | dev->kobj.kset = devices_kset; | 645 | dev->kobj.kset = devices_kset; |
646 | kobject_init(&dev->kobj, &device_ktype); | 646 | kobject_init(&dev->kobj, &device_ktype); |
647 | INIT_LIST_HEAD(&dev->deferred_probe); | ||
648 | INIT_LIST_HEAD(&dev->dma_pools); | 647 | INIT_LIST_HEAD(&dev->dma_pools); |
649 | mutex_init(&dev->mutex); | 648 | mutex_init(&dev->mutex); |
650 | lockdep_set_novalidate_class(&dev->mutex); | 649 | lockdep_set_novalidate_class(&dev->mutex); |
@@ -922,6 +921,7 @@ int device_private_init(struct device *dev) | |||
922 | dev->p->device = dev; | 921 | dev->p->device = dev; |
923 | klist_init(&dev->p->klist_children, klist_children_get, | 922 | klist_init(&dev->p->klist_children, klist_children_get, |
924 | klist_children_put); | 923 | klist_children_put); |
924 | INIT_LIST_HEAD(&dev->p->deferred_probe); | ||
925 | return 0; | 925 | return 0; |
926 | } | 926 | } |
927 | 927 | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 442b7641a086..9fa888e08059 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -45,7 +45,7 @@ | |||
45 | * retry them. | 45 | * retry them. |
46 | * | 46 | * |
47 | * The deferred_probe_mutex must be held any time the deferred_probe_*_list | 47 | * The deferred_probe_mutex must be held any time the deferred_probe_*_list |
48 | * of the (struct device*)->deferred_probe pointers are manipulated | 48 | * of the (struct device*)->p->deferred_probe pointers are manipulated |
49 | */ | 49 | */ |
50 | static DEFINE_MUTEX(deferred_probe_mutex); | 50 | static DEFINE_MUTEX(deferred_probe_mutex); |
51 | static LIST_HEAD(deferred_probe_pending_list); | 51 | static LIST_HEAD(deferred_probe_pending_list); |
@@ -58,6 +58,7 @@ static struct workqueue_struct *deferred_wq; | |||
58 | static void deferred_probe_work_func(struct work_struct *work) | 58 | static void deferred_probe_work_func(struct work_struct *work) |
59 | { | 59 | { |
60 | struct device *dev; | 60 | struct device *dev; |
61 | struct device_private *private; | ||
61 | /* | 62 | /* |
62 | * This block processes every device in the deferred 'active' list. | 63 | * This block processes every device in the deferred 'active' list. |
63 | * Each device is removed from the active list and passed to | 64 | * Each device is removed from the active list and passed to |
@@ -72,9 +73,10 @@ static void deferred_probe_work_func(struct work_struct *work) | |||
72 | */ | 73 | */ |
73 | mutex_lock(&deferred_probe_mutex); | 74 | mutex_lock(&deferred_probe_mutex); |
74 | while (!list_empty(&deferred_probe_active_list)) { | 75 | while (!list_empty(&deferred_probe_active_list)) { |
75 | dev = list_first_entry(&deferred_probe_active_list, | 76 | private = list_first_entry(&deferred_probe_active_list, |
76 | typeof(*dev), deferred_probe); | 77 | typeof(*dev->p), deferred_probe); |
77 | list_del_init(&dev->deferred_probe); | 78 | dev = private->device; |
79 | list_del_init(&private->deferred_probe); | ||
78 | 80 | ||
79 | get_device(dev); | 81 | get_device(dev); |
80 | 82 | ||
@@ -94,9 +96,9 @@ static DECLARE_WORK(deferred_probe_work, deferred_probe_work_func); | |||
94 | static void driver_deferred_probe_add(struct device *dev) | 96 | static void driver_deferred_probe_add(struct device *dev) |
95 | { | 97 | { |
96 | mutex_lock(&deferred_probe_mutex); | 98 | mutex_lock(&deferred_probe_mutex); |
97 | if (list_empty(&dev->deferred_probe)) { | 99 | if (list_empty(&dev->p->deferred_probe)) { |
98 | dev_dbg(dev, "Added to deferred list\n"); | 100 | dev_dbg(dev, "Added to deferred list\n"); |
99 | list_add(&dev->deferred_probe, &deferred_probe_pending_list); | 101 | list_add(&dev->p->deferred_probe, &deferred_probe_pending_list); |
100 | } | 102 | } |
101 | mutex_unlock(&deferred_probe_mutex); | 103 | mutex_unlock(&deferred_probe_mutex); |
102 | } | 104 | } |
@@ -104,9 +106,9 @@ static void driver_deferred_probe_add(struct device *dev) | |||
104 | void driver_deferred_probe_del(struct device *dev) | 106 | void driver_deferred_probe_del(struct device *dev) |
105 | { | 107 | { |
106 | mutex_lock(&deferred_probe_mutex); | 108 | mutex_lock(&deferred_probe_mutex); |
107 | if (!list_empty(&dev->deferred_probe)) { | 109 | if (!list_empty(&dev->p->deferred_probe)) { |
108 | dev_dbg(dev, "Removed from deferred list\n"); | 110 | dev_dbg(dev, "Removed from deferred list\n"); |
109 | list_del_init(&dev->deferred_probe); | 111 | list_del_init(&dev->p->deferred_probe); |
110 | } | 112 | } |
111 | mutex_unlock(&deferred_probe_mutex); | 113 | mutex_unlock(&deferred_probe_mutex); |
112 | } | 114 | } |
diff --git a/include/linux/device.h b/include/linux/device.h index 22d6938ddbb4..f62e21689fdd 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -585,10 +585,6 @@ struct device_dma_parameters { | |||
585 | * @mutex: Mutex to synchronize calls to its driver. | 585 | * @mutex: Mutex to synchronize calls to its driver. |
586 | * @bus: Type of bus device is on. | 586 | * @bus: Type of bus device is on. |
587 | * @driver: Which driver has allocated this | 587 | * @driver: Which driver has allocated this |
588 | * @deferred_probe: entry in deferred_probe_list which is used to retry the | ||
589 | * binding of drivers which were unable to get all the resources | ||
590 | * needed by the device; typically because it depends on another | ||
591 | * driver getting probed first. | ||
592 | * @platform_data: Platform data specific to the device. | 588 | * @platform_data: Platform data specific to the device. |
593 | * Example: For devices on custom boards, as typical of embedded | 589 | * Example: For devices on custom boards, as typical of embedded |
594 | * and SOC based hardware, Linux often uses platform_data to point | 590 | * and SOC based hardware, Linux often uses platform_data to point |
@@ -648,7 +644,6 @@ struct device { | |||
648 | struct bus_type *bus; /* type of bus device is on */ | 644 | struct bus_type *bus; /* type of bus device is on */ |
649 | struct device_driver *driver; /* which driver has allocated this | 645 | struct device_driver *driver; /* which driver has allocated this |
650 | device */ | 646 | device */ |
651 | struct list_head deferred_probe; | ||
652 | void *platform_data; /* Platform specific data, device | 647 | void *platform_data; /* Platform specific data, device |
653 | core doesn't touch it */ | 648 | core doesn't touch it */ |
654 | struct dev_pm_info power; | 649 | struct dev_pm_info power; |