@@ -783,6 +783,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
783
783
unsigned long tmp ;
784
784
int ret = 0 ;
785
785
786
+ if (t -> rdata )
787
+ memset (t -> rdata , 0 , t -> rlen );
788
+
786
789
/* start transaction */
787
790
spin_lock_irqsave (& ec -> lock , tmp );
788
791
/* Enable GPE for command processing (IBF=0/OBF=1) */
@@ -819,8 +822,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
819
822
820
823
if (!ec || (!t ) || (t -> wlen && !t -> wdata ) || (t -> rlen && !t -> rdata ))
821
824
return - EINVAL ;
822
- if (t -> rdata )
823
- memset (t -> rdata , 0 , t -> rlen );
824
825
825
826
mutex_lock (& ec -> mutex );
826
827
if (ec -> global_lock ) {
@@ -847,7 +848,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
847
848
.wdata = NULL , .rdata = & d ,
848
849
.wlen = 0 , .rlen = 1 };
849
850
850
- return acpi_ec_transaction (ec , & t );
851
+ return acpi_ec_transaction_unlocked (ec , & t );
851
852
}
852
853
853
854
static int acpi_ec_burst_disable (struct acpi_ec * ec )
@@ -857,7 +858,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
857
858
.wlen = 0 , .rlen = 0 };
858
859
859
860
return (acpi_ec_read_status (ec ) & ACPI_EC_FLAG_BURST ) ?
860
- acpi_ec_transaction (ec , & t ) : 0 ;
861
+ acpi_ec_transaction_unlocked (ec , & t ) : 0 ;
861
862
}
862
863
863
864
static int acpi_ec_read (struct acpi_ec * ec , u8 address , u8 * data )
@@ -873,6 +874,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
873
874
return result ;
874
875
}
875
876
877
+ static int acpi_ec_read_unlocked (struct acpi_ec * ec , u8 address , u8 * data )
878
+ {
879
+ int result ;
880
+ u8 d ;
881
+ struct transaction t = {.command = ACPI_EC_COMMAND_READ ,
882
+ .wdata = & address , .rdata = & d ,
883
+ .wlen = 1 , .rlen = 1 };
884
+
885
+ result = acpi_ec_transaction_unlocked (ec , & t );
886
+ * data = d ;
887
+ return result ;
888
+ }
889
+
876
890
static int acpi_ec_write (struct acpi_ec * ec , u8 address , u8 data )
877
891
{
878
892
u8 wdata [2 ] = { address , data };
@@ -883,6 +897,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
883
897
return acpi_ec_transaction (ec , & t );
884
898
}
885
899
900
+ static int acpi_ec_write_unlocked (struct acpi_ec * ec , u8 address , u8 data )
901
+ {
902
+ u8 wdata [2 ] = { address , data };
903
+ struct transaction t = {.command = ACPI_EC_COMMAND_WRITE ,
904
+ .wdata = wdata , .rdata = NULL ,
905
+ .wlen = 2 , .rlen = 0 };
906
+
907
+ return acpi_ec_transaction_unlocked (ec , & t );
908
+ }
909
+
886
910
int ec_read (u8 addr , u8 * val )
887
911
{
888
912
int err ;
@@ -1323,27 +1347,46 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
1323
1347
struct acpi_ec * ec = handler_context ;
1324
1348
int result = 0 , i , bytes = bits / 8 ;
1325
1349
u8 * value = (u8 * )value64 ;
1350
+ u32 glk ;
1326
1351
1327
1352
if ((address > 0xFF ) || !value || !handler_context )
1328
1353
return AE_BAD_PARAMETER ;
1329
1354
1330
1355
if (function != ACPI_READ && function != ACPI_WRITE )
1331
1356
return AE_BAD_PARAMETER ;
1332
1357
1358
+ mutex_lock (& ec -> mutex );
1359
+
1360
+ if (ec -> global_lock ) {
1361
+ acpi_status status ;
1362
+
1363
+ status = acpi_acquire_global_lock (ACPI_EC_UDELAY_GLK , & glk );
1364
+ if (ACPI_FAILURE (status )) {
1365
+ result = - ENODEV ;
1366
+ goto unlock ;
1367
+ }
1368
+ }
1369
+
1333
1370
if (ec -> busy_polling || bits > 8 )
1334
1371
acpi_ec_burst_enable (ec );
1335
1372
1336
1373
for (i = 0 ; i < bytes ; ++ i , ++ address , ++ value ) {
1337
1374
result = (function == ACPI_READ ) ?
1338
- acpi_ec_read (ec , address , value ) :
1339
- acpi_ec_write (ec , address , * value );
1375
+ acpi_ec_read_unlocked (ec , address , value ) :
1376
+ acpi_ec_write_unlocked (ec , address , * value );
1340
1377
if (result < 0 )
1341
1378
break ;
1342
1379
}
1343
1380
1344
1381
if (ec -> busy_polling || bits > 8 )
1345
1382
acpi_ec_burst_disable (ec );
1346
1383
1384
+ if (ec -> global_lock )
1385
+ acpi_release_global_lock (glk );
1386
+
1387
+ unlock :
1388
+ mutex_unlock (& ec -> mutex );
1389
+
1347
1390
switch (result ) {
1348
1391
case - EINVAL :
1349
1392
return AE_BAD_PARAMETER ;
0 commit comments