Post Job Free
Sign in

Driver Linux .Net Drivers Power Development Device

Location:
United States
Posted:
October 08, 2012

Contact this candidate

Resume:

Not logged in

Log in now

Create an accountSubscribe to LWN

Recent Features

LWN.net Weekly Edition for September 13, 2012

LinuxCon: Open hardware for open hardware

Bazaar on the slow track

LWN.net Weekly Edition for September 7, 2012

LinuxCon: funding development

Printable page

Weekly edition Kernel Security Distributions Contact Us Search

Archives Calendar Subscribe Write for LWN LWN.net FAQ Sponsors

[RFC] firmware load: defer request_firmware during early boot and resume

[Posted August 15, 2012 by corbet]

From: Ming Lei

To: Linux Kernel Mailing List, linux-usb

Subject: [RFC] firmware load: defer request_firmware during early boot and resume

Date: Fri, 20 Jul 2012 20:33:32 +0800

Message-ID:

Cc: Alan Stern, Greg Kroah-Hartman, Oliver Neukum, "Rafael J. Wysocki"

Archive-link: Article, Thread

The RFC patch is just for discussing if the idea of deferring

request_firmware is doable for addressing the issue of

request_firmware in resume path, which is caused by driver

unbind/rebind during resume.

At least usb bus is involved in such things, one driver may be

unbound and rebound in resume path at several situations, and

request_firmware is often called inside probe .

Also the idea should be helpful for other hotplug buses too,

at least there was the similar problem report on pcmcia bus.

diff --git a/drivers/base/dd.c b/drivers/base/dd.c

index 6cd2c6c..fb02eff 100644

--- a/drivers/base/dd.c

+++ b/drivers/base/dd.c

@@ -123,7 +123,7 @@ static bool driver_deferred_probe_enable = false;

* list and schedules the deferred probe workqueue to process them. It

* should be called anytime a driver is successfully bound to a device.

*/

-static void driver_deferred_probe_trigger(void)

+void driver_deferred_probe_trigger(void)

{

if (!driver_deferred_probe_enable)

return;

@@ -144,6 +144,7 @@ static void driver_deferred_probe_trigger(void)

*/

queue_work(deferred_wq, &deferred_probe_work);

}

+EXPORT_SYMBOL_GPL(driver_deferred_probe_trigger);

/**

* deferred_probe_initcall - Enable probing of deferred devices

diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c

index 5401814..4fe742f 100644

--- a/drivers/base/firmware_class.c

+++ b/drivers/base/firmware_class.c

@@ -593,6 +593,9 @@ request_firmware(const struct firmware

**firmware_p, const char *name,

if (IS_ERR_OR_NULL(fw_priv))

return PTR_RET(fw_priv);

+ if (system_state != SYSTEM_RUNNING)

+ return -EPROBE_DEFER;

+

ret = usermodehelper_read_trylock ;

if (WARN_ON(ret)) {

dev_err(device, "firmware: %s will not be loaded\n", name);

diff --git a/include/linux/device.h b/include/linux/device.h

index d0e4d99..a63d3171 100644

--- a/include/linux/device.h

+++ b/include/linux/device.h

@@ -244,7 +244,7 @@ extern struct device_driver *driver_find(const char *name,

struct bus_type *bus);

extern int driver_probe_done(void);

extern void wait_for_device_probe(void);

-

+extern void driver_deferred_probe_trigger(void);

/* sysfs interface for exporting driver attributes */

diff --git a/include/linux/kernel.h b/include/linux/kernel.h

index e07f5e0..c8d74c6 100644

--- a/include/linux/kernel.h

+++ b/include/linux/kernel.h

@@ -378,6 +378,7 @@ extern enum system_states {

SYSTEM_POWER_OFF,

SYSTEM_RESTART,

SYSTEM_SUSPEND_DISK,

+ SYSTEM_SUSPEND,

} system_state;

#define TAINT_PROPRIETARY_MODULE 0

diff --git a/init/main.c b/init/main.c

index e60679d..237eae1 100644

--- a/init/main.c

+++ b/init/main.c

@@ -809,6 +809,8 @@ static noinline int init_post(void)

current->signal->flags = SIGNAL_UNKILLABLE;

flush_delayed_fput ;

+ driver_deferred_probe_trigger ;

+

if (ramdisk_execute_command) {

run_init_process(ramdisk_execute_command);

printk(KERN_WARNING "Failed to execute %s\n",

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c

index 1da39ea..dbf6ffb 100644

--- a/kernel/power/suspend.c

+++ b/kernel/power/suspend.c

@@ -224,6 +224,9 @@ int suspend_devices_and_enter(suspend_state_t state)

goto Recover_platform;

}

suspend_test_finish("suspend devices");

+

+ system_state = SYSTEM_SUSPEND;

+

if (suspend_test(TEST_DEVICES))

goto Recover_platform;

@@ -301,6 +304,10 @@ static int enter_state(suspend_state_t state)

Finish:

pr_debug("PM: Finishing wakeup.\n");

suspend_finish ;

+

+ system_state = SYSTEM_RUNNING;

+ driver_deferred_probe_trigger ;

+

Unlock:

mutex_unlock(&pm_mutex);

return error;

Thanks,

--

Ming Lei

--

To unsubscribe from this list: send the line "unsubscribe linux-usb" in

the body of a message to *********-**********************@******.*****.***

More majordomo info at http://vger.kernel.org/majordomo-info.html

(Log in to post comments)

Copyright c 2012, Eklektix, Inc.

Comments and public postings are copyrighted by their creators.

Linux is a registered trademark of Linus Torvalds



Contact this candidate