diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-06-06 18:17:50 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-06-06 18:17:50 -0400 |
commit | 3eba148d75670f61463dd3c9ef8672da8f290f36 (patch) | |
tree | 45cb8fbda6d6ce9d73aeeac673282e37b0be2531 /drivers/base | |
parent | 057b0a7518e4b8fca26201715996d6d928a62300 (diff) | |
parent | 4cf563c5d97c83d4b2fb3a778dd7d5e362cc3e34 (diff) |
Merge branch 'acpi-pm' into pm-sleep
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/dd.c | 17 | ||||
-rw-r--r-- | drivers/base/platform.c | 7 |
2 files changed, 23 insertions, 1 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 8986b9f22781..62ec61e8f84a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -52,6 +52,7 @@ static DEFINE_MUTEX(deferred_probe_mutex); | |||
52 | static LIST_HEAD(deferred_probe_pending_list); | 52 | static LIST_HEAD(deferred_probe_pending_list); |
53 | static LIST_HEAD(deferred_probe_active_list); | 53 | static LIST_HEAD(deferred_probe_active_list); |
54 | static struct workqueue_struct *deferred_wq; | 54 | static struct workqueue_struct *deferred_wq; |
55 | static atomic_t deferred_trigger_count = ATOMIC_INIT(0); | ||
55 | 56 | ||
56 | /** | 57 | /** |
57 | * deferred_probe_work_func() - Retry probing devices in the active list. | 58 | * deferred_probe_work_func() - Retry probing devices in the active list. |
@@ -135,6 +136,17 @@ static bool driver_deferred_probe_enable = false; | |||
135 | * This functions moves all devices from the pending list to the active | 136 | * This functions moves all devices from the pending list to the active |
136 | * list and schedules the deferred probe workqueue to process them. It | 137 | * list and schedules the deferred probe workqueue to process them. It |
137 | * should be called anytime a driver is successfully bound to a device. | 138 | * should be called anytime a driver is successfully bound to a device. |
139 | * | ||
140 | * Note, there is a race condition in multi-threaded probe. In the case where | ||
141 | * more than one device is probing at the same time, it is possible for one | ||
142 | * probe to complete successfully while another is about to defer. If the second | ||
143 | * depends on the first, then it will get put on the pending list after the | ||
144 | * trigger event has already occured and will be stuck there. | ||
145 | * | ||
146 | * The atomic 'deferred_trigger_count' is used to determine if a successful | ||
147 | * trigger has occurred in the midst of probing a driver. If the trigger count | ||
148 | * changes in the midst of a probe, then deferred processing should be triggered | ||
149 | * again. | ||
138 | */ | 150 | */ |
139 | static void driver_deferred_probe_trigger(void) | 151 | static void driver_deferred_probe_trigger(void) |
140 | { | 152 | { |
@@ -147,6 +159,7 @@ static void driver_deferred_probe_trigger(void) | |||
147 | * into the active list so they can be retried by the workqueue | 159 | * into the active list so they can be retried by the workqueue |
148 | */ | 160 | */ |
149 | mutex_lock(&deferred_probe_mutex); | 161 | mutex_lock(&deferred_probe_mutex); |
162 | atomic_inc(&deferred_trigger_count); | ||
150 | list_splice_tail_init(&deferred_probe_pending_list, | 163 | list_splice_tail_init(&deferred_probe_pending_list, |
151 | &deferred_probe_active_list); | 164 | &deferred_probe_active_list); |
152 | mutex_unlock(&deferred_probe_mutex); | 165 | mutex_unlock(&deferred_probe_mutex); |
@@ -265,6 +278,7 @@ static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); | |||
265 | static int really_probe(struct device *dev, struct device_driver *drv) | 278 | static int really_probe(struct device *dev, struct device_driver *drv) |
266 | { | 279 | { |
267 | int ret = 0; | 280 | int ret = 0; |
281 | int local_trigger_count = atomic_read(&deferred_trigger_count); | ||
268 | 282 | ||
269 | atomic_inc(&probe_count); | 283 | atomic_inc(&probe_count); |
270 | pr_debug("bus: '%s': %s: probing driver %s with device %s\n", | 284 | pr_debug("bus: '%s': %s: probing driver %s with device %s\n", |
@@ -310,6 +324,9 @@ probe_failed: | |||
310 | /* Driver requested deferred probing */ | 324 | /* Driver requested deferred probing */ |
311 | dev_info(dev, "Driver %s requests probe deferral\n", drv->name); | 325 | dev_info(dev, "Driver %s requests probe deferral\n", drv->name); |
312 | driver_deferred_probe_add(dev); | 326 | driver_deferred_probe_add(dev); |
327 | /* Did a trigger occur while probing? Need to re-trigger if yes */ | ||
328 | if (local_trigger_count != atomic_read(&deferred_trigger_count)) | ||
329 | driver_deferred_probe_trigger(); | ||
313 | } else if (ret != -ENODEV && ret != -ENXIO) { | 330 | } else if (ret != -ENODEV && ret != -ENXIO) { |
314 | /* driver matched but the probe failed */ | 331 | /* driver matched but the probe failed */ |
315 | printk(KERN_WARNING | 332 | printk(KERN_WARNING |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index e714709704e4..5b47210889e0 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
16 | #include <linux/of_irq.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
@@ -87,7 +88,11 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) | |||
87 | return -ENXIO; | 88 | return -ENXIO; |
88 | return dev->archdata.irqs[num]; | 89 | return dev->archdata.irqs[num]; |
89 | #else | 90 | #else |
90 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); | 91 | struct resource *r; |
92 | if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) | ||
93 | return of_irq_get(dev->dev.of_node, num); | ||
94 | |||
95 | r = platform_get_resource(dev, IORESOURCE_IRQ, num); | ||
91 | 96 | ||
92 | return r ? r->start : -ENXIO; | 97 | return r ? r->start : -ENXIO; |
93 | #endif | 98 | #endif |