@@ -101,6 +101,7 @@ enum ec_command {
101
101
#define ACPI_EC_UDELAY_POLL 550 /* Wait 1ms for EC transaction polling */
102
102
#define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query
103
103
* when trying to clear the EC */
104
+ #define ACPI_EC_MAX_QUERIES 16 /* Maximum number of parallel queries */
104
105
105
106
enum {
106
107
EC_FLAGS_QUERY_PENDING , /* Query is pending */
@@ -121,6 +122,10 @@ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
121
122
module_param (ec_delay , uint , 0644 );
122
123
MODULE_PARM_DESC (ec_delay , "Timeout(ms) waited until an EC command completes" );
123
124
125
+ static unsigned int ec_max_queries __read_mostly = ACPI_EC_MAX_QUERIES ;
126
+ module_param (ec_max_queries , uint , 0644 );
127
+ MODULE_PARM_DESC (ec_max_queries , "Maximum parallel _Qxx evaluations" );
128
+
124
129
static bool ec_busy_polling __read_mostly ;
125
130
module_param (ec_busy_polling , bool , 0644 );
126
131
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);
174
179
175
180
struct acpi_ec * boot_ec , * first_ec ;
176
181
EXPORT_SYMBOL (first_ec );
182
+ static struct workqueue_struct * ec_query_wq ;
177
183
178
184
static int EC_FLAGS_CLEAR_ON_RESUME ; /* Needs acpi_ec_clear() on boot/resume */
179
185
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)
1098
1104
* work queue execution.
1099
1105
*/
1100
1106
ec_dbg_evt ("Query(0x%02x) scheduled" , value );
1101
- if (!schedule_work ( & q -> work )) {
1107
+ if (!queue_work ( ec_query_wq , & q -> work )) {
1102
1108
ec_dbg_evt ("Query(0x%02x) overlapped" , value );
1103
1109
result = - EBUSY ;
1104
1110
}
@@ -1660,15 +1666,41 @@ static struct acpi_driver acpi_ec_driver = {
1660
1666
},
1661
1667
};
1662
1668
1669
+ static inline int acpi_ec_query_init (void )
1670
+ {
1671
+ if (!ec_query_wq ) {
1672
+ ec_query_wq = alloc_workqueue ("kec_query" , 0 ,
1673
+ ec_max_queries );
1674
+ if (!ec_query_wq )
1675
+ return - ENODEV ;
1676
+ }
1677
+ return 0 ;
1678
+ }
1679
+
1680
+ static inline void acpi_ec_query_exit (void )
1681
+ {
1682
+ if (ec_query_wq ) {
1683
+ destroy_workqueue (ec_query_wq );
1684
+ ec_query_wq = NULL ;
1685
+ }
1686
+ }
1687
+
1663
1688
int __init acpi_ec_init (void )
1664
1689
{
1665
- int result = 0 ;
1690
+ int result ;
1666
1691
1692
+ /* register workqueue for _Qxx evaluations */
1693
+ result = acpi_ec_query_init ();
1694
+ if (result )
1695
+ goto err_exit ;
1667
1696
/* Now register the driver for the EC */
1668
1697
result = acpi_bus_register_driver (& acpi_ec_driver );
1669
- if (result < 0 )
1670
- return - ENODEV ;
1698
+ if (result )
1699
+ goto err_exit ;
1671
1700
1701
+ err_exit :
1702
+ if (result )
1703
+ acpi_ec_query_exit ();
1672
1704
return result ;
1673
1705
}
1674
1706
@@ -1678,5 +1710,6 @@ static void __exit acpi_ec_exit(void)
1678
1710
{
1679
1711
1680
1712
acpi_bus_unregister_driver (& acpi_ec_driver );
1713
+ acpi_ec_query_exit ();
1681
1714
}
1682
1715
#endif /* 0 */
0 commit comments