More ACPI updates for v4.8-rc1
- An ACPI EC driver fix from the 4.3 cycle may cause the ACPICA's method reentrancy limit to be exceeded for a _Qxx method due to a large number of concurrent EC operations, so prevent that from happening by moving the EC handling into a separate workqueue with a limit on the number of concurrently executed work items (Lv Zheng). - Fix the cleanup code in the ACPI button driver that forgets to clear two variables on exit which causes an error to occur on the next attmpt to load the driver (Benjamin Tissoires). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJXpKM9AAoJEILEb/54YlRxTagP/0FSQSfUX5N7UERhpV5zmC/D hw8xv4nsZwdBicABuOT2dqIB6Xs2J3WtK93exR6EvVTw2OY0qZCcEluj4OYDvqP6 JtgHiWnoLjGN66hWcTDjY4ncWjC7vO8ohH/fisBrUkMhK6bNE3E/E1ffFx+BSnxP 1BpJH8erFxWVAREuYYqv7CdGFVNa3Ij7D678+3BtRVncfpCXSRyhT37/RZXyEJgu zZ+c0aU1vaLYtyyrGVnQ5b420CQSWO8Mi7o5hD5D6mR4zKE4p/KtdivE9ipivgzh axuotmOdQQn1qu+EpKyEDHj1OgMg+5tVlfw/zkUeRmtWC5xcwvRvWKiAA4bVNkur PxWnvUUSc1PLPz2ex0NmXwHBwHTVQtcJpZy/NH/v4E+TbtRMLBt85Cg7V7Hwn5RR mDBOP526LClwrxnBpioSD/lNYeaM4F8STVbk0MpC4n/vmPQkhsKn6eyRNCM9gw0q F2z2NLekqrSiI5kuR36yR32m5mbydIAEhxRXFTQL2ggCY8CZUOiLLRsQerQ4wIgH p2LKLVpQRgZCh/gcsLfCRv6i/wD7Lmzokf6lQD/JXzv/prXRq0oCvRs96JbxNT6q NepJsAI0AtUqEcuMaadMGnMPZLoJAMzFPSGdK/ZHMpSxGy0xBuEmNUHl1Vm50hcr MMZlQPz05afSMApzLBAf =Uafi -----END PGP SIGNATURE----- Merge tag 'acpi-extra-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more ACPI updates from Rafael Wysocki: "Two more fixes in ACPI drivers, one in the ACPI EC driver (stable-candidate) and one in the ACPI button driver. Specifics: - An ACPI EC driver fix from the 4.3 cycle may cause the ACPICA's method reentrancy limit to be exceeded for a _Qxx method due to a large number of concurrent EC operations, so prevent that from happening by moving the EC handling into a separate workqueue with a limit on the number of concurrently executed work items (Lv Zheng) - Fix the cleanup code in the ACPI button driver that forgets to clear two variables on exit which causes an error to occur on the next attmpt to load the driver (Benjamin Tissoires)" * tag 'acpi-extra-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / EC: Work around method reentrancy limit in ACPICA for _Qxx ACPI / button: remove pointer to old lid_sysfs on unbind
This commit is contained in:
commit
0524b422fa
|
@ -232,8 +232,10 @@ static int acpi_button_add_fs(struct acpi_device *device)
|
|||
acpi_device_dir(device) = NULL;
|
||||
remove_lid_dir:
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
|
||||
acpi_lid_dir = NULL;
|
||||
remove_button_dir:
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
acpi_button_dir = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -250,7 +252,9 @@ static int acpi_button_remove_fs(struct acpi_device *device)
|
|||
acpi_lid_dir);
|
||||
acpi_device_dir(device) = NULL;
|
||||
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
|
||||
acpi_lid_dir = NULL;
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
acpi_button_dir = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ enum ec_command {
|
|||
#define ACPI_EC_UDELAY_POLL 550 /* Wait 1ms for EC transaction polling */
|
||||
#define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query
|
||||
* when trying to clear the EC */
|
||||
#define ACPI_EC_MAX_QUERIES 16 /* Maximum number of parallel queries */
|
||||
|
||||
enum {
|
||||
EC_FLAGS_QUERY_PENDING, /* Query is pending */
|
||||
|
@ -121,6 +122,10 @@ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
|
|||
module_param(ec_delay, uint, 0644);
|
||||
MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
|
||||
|
||||
static unsigned int ec_max_queries __read_mostly = ACPI_EC_MAX_QUERIES;
|
||||
module_param(ec_max_queries, uint, 0644);
|
||||
MODULE_PARM_DESC(ec_max_queries, "Maximum parallel _Qxx evaluations");
|
||||
|
||||
static bool ec_busy_polling __read_mostly;
|
||||
module_param(ec_busy_polling, bool, 0644);
|
||||
MODULE_PARM_DESC(ec_busy_polling, "Use busy polling to advance EC transaction");
|
||||
|
@ -174,6 +179,7 @@ static void acpi_ec_event_processor(struct work_struct *work);
|
|||
|
||||
struct acpi_ec *boot_ec, *first_ec;
|
||||
EXPORT_SYMBOL(first_ec);
|
||||
static struct workqueue_struct *ec_query_wq;
|
||||
|
||||
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
|
||||
static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
|
||||
|
@ -1098,7 +1104,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
|
|||
* work queue execution.
|
||||
*/
|
||||
ec_dbg_evt("Query(0x%02x) scheduled", value);
|
||||
if (!schedule_work(&q->work)) {
|
||||
if (!queue_work(ec_query_wq, &q->work)) {
|
||||
ec_dbg_evt("Query(0x%02x) overlapped", value);
|
||||
result = -EBUSY;
|
||||
}
|
||||
|
@ -1660,15 +1666,41 @@ static struct acpi_driver acpi_ec_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static inline int acpi_ec_query_init(void)
|
||||
{
|
||||
if (!ec_query_wq) {
|
||||
ec_query_wq = alloc_workqueue("kec_query", 0,
|
||||
ec_max_queries);
|
||||
if (!ec_query_wq)
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void acpi_ec_query_exit(void)
|
||||
{
|
||||
if (ec_query_wq) {
|
||||
destroy_workqueue(ec_query_wq);
|
||||
ec_query_wq = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int __init acpi_ec_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
int result;
|
||||
|
||||
/* register workqueue for _Qxx evaluations */
|
||||
result = acpi_ec_query_init();
|
||||
if (result)
|
||||
goto err_exit;
|
||||
/* Now register the driver for the EC */
|
||||
result = acpi_bus_register_driver(&acpi_ec_driver);
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
if (result)
|
||||
goto err_exit;
|
||||
|
||||
err_exit:
|
||||
if (result)
|
||||
acpi_ec_query_exit();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1678,5 +1710,6 @@ static void __exit acpi_ec_exit(void)
|
|||
{
|
||||
|
||||
acpi_bus_unregister_driver(&acpi_ec_driver);
|
||||
acpi_ec_query_exit();
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user