@@ -135,6 +135,8 @@ struct sci_port {
135
135
struct dma_chan * chan_rx ;
136
136
137
137
#ifdef CONFIG_SERIAL_SH_SCI_DMA
138
+ struct dma_chan * chan_tx_saved ;
139
+ struct dma_chan * chan_rx_saved ;
138
140
dma_cookie_t cookie_tx ;
139
141
dma_cookie_t cookie_rx [2 ];
140
142
dma_cookie_t active_rx ;
@@ -1212,25 +1214,16 @@ static int sci_dma_rx_find_active(struct sci_port *s)
1212
1214
return -1 ;
1213
1215
}
1214
1216
1215
- static void sci_rx_dma_release (struct sci_port * s , bool enable_pio )
1217
+ static void sci_rx_dma_release (struct sci_port * s )
1216
1218
{
1217
- struct dma_chan * chan = s -> chan_rx ;
1218
- struct uart_port * port = & s -> port ;
1219
- unsigned long flags ;
1219
+ struct dma_chan * chan = s -> chan_rx_saved ;
1220
1220
1221
- spin_lock_irqsave (& port -> lock , flags );
1222
- s -> chan_rx = NULL ;
1221
+ s -> chan_rx_saved = s -> chan_rx = NULL ;
1223
1222
s -> cookie_rx [0 ] = s -> cookie_rx [1 ] = - EINVAL ;
1224
- spin_unlock_irqrestore (& port -> lock , flags );
1225
1223
dmaengine_terminate_all (chan );
1226
1224
dma_free_coherent (chan -> device -> dev , s -> buf_len_rx * 2 , s -> rx_buf [0 ],
1227
1225
sg_dma_address (& s -> sg_rx [0 ]));
1228
1226
dma_release_channel (chan );
1229
- if (enable_pio ) {
1230
- spin_lock_irqsave (& port -> lock , flags );
1231
- sci_start_rx (port );
1232
- spin_unlock_irqrestore (& port -> lock , flags );
1233
- }
1234
1227
}
1235
1228
1236
1229
static void start_hrtimer_us (struct hrtimer * hrt , unsigned long usec )
@@ -1289,33 +1282,30 @@ static void sci_dma_rx_complete(void *arg)
1289
1282
fail :
1290
1283
spin_unlock_irqrestore (& port -> lock , flags );
1291
1284
dev_warn (port -> dev , "Failed submitting Rx DMA descriptor\n" );
1292
- sci_rx_dma_release (s , true);
1285
+ /* Switch to PIO */
1286
+ spin_lock_irqsave (& port -> lock , flags );
1287
+ s -> chan_rx = NULL ;
1288
+ sci_start_rx (port );
1289
+ spin_unlock_irqrestore (& port -> lock , flags );
1293
1290
}
1294
1291
1295
- static void sci_tx_dma_release (struct sci_port * s , bool enable_pio )
1292
+ static void sci_tx_dma_release (struct sci_port * s )
1296
1293
{
1297
- struct dma_chan * chan = s -> chan_tx ;
1298
- struct uart_port * port = & s -> port ;
1299
- unsigned long flags ;
1294
+ struct dma_chan * chan = s -> chan_tx_saved ;
1300
1295
1301
- spin_lock_irqsave (& port -> lock , flags );
1302
- s -> chan_tx = NULL ;
1296
+ s -> chan_tx_saved = s -> chan_tx = NULL ;
1303
1297
s -> cookie_tx = - EINVAL ;
1304
- spin_unlock_irqrestore (& port -> lock , flags );
1305
1298
dmaengine_terminate_all (chan );
1306
1299
dma_unmap_single (chan -> device -> dev , s -> tx_dma_addr , UART_XMIT_SIZE ,
1307
1300
DMA_TO_DEVICE );
1308
1301
dma_release_channel (chan );
1309
- if (enable_pio ) {
1310
- spin_lock_irqsave (& port -> lock , flags );
1311
- sci_start_tx (port );
1312
- spin_unlock_irqrestore (& port -> lock , flags );
1313
- }
1314
1302
}
1315
1303
1316
1304
static void sci_submit_rx (struct sci_port * s )
1317
1305
{
1318
1306
struct dma_chan * chan = s -> chan_rx ;
1307
+ struct uart_port * port = & s -> port ;
1308
+ unsigned long flags ;
1319
1309
int i ;
1320
1310
1321
1311
for (i = 0 ; i < 2 ; i ++ ) {
@@ -1347,7 +1337,11 @@ static void sci_submit_rx(struct sci_port *s)
1347
1337
for (i = 0 ; i < 2 ; i ++ )
1348
1338
s -> cookie_rx [i ] = - EINVAL ;
1349
1339
s -> active_rx = - EINVAL ;
1350
- sci_rx_dma_release (s , true);
1340
+ /* Switch to PIO */
1341
+ spin_lock_irqsave (& port -> lock , flags );
1342
+ s -> chan_rx = NULL ;
1343
+ sci_start_rx (port );
1344
+ spin_unlock_irqrestore (& port -> lock , flags );
1351
1345
}
1352
1346
1353
1347
static void work_fn_tx (struct work_struct * work )
@@ -1357,6 +1351,7 @@ static void work_fn_tx(struct work_struct *work)
1357
1351
struct dma_chan * chan = s -> chan_tx ;
1358
1352
struct uart_port * port = & s -> port ;
1359
1353
struct circ_buf * xmit = & port -> state -> xmit ;
1354
+ unsigned long flags ;
1360
1355
dma_addr_t buf ;
1361
1356
1362
1357
/*
@@ -1378,9 +1373,7 @@ static void work_fn_tx(struct work_struct *work)
1378
1373
DMA_PREP_INTERRUPT | DMA_CTRL_ACK );
1379
1374
if (!desc ) {
1380
1375
dev_warn (port -> dev , "Failed preparing Tx DMA descriptor\n" );
1381
- /* switch to PIO */
1382
- sci_tx_dma_release (s , true);
1383
- return ;
1376
+ goto switch_to_pio ;
1384
1377
}
1385
1378
1386
1379
dma_sync_single_for_device (chan -> device -> dev , buf , s -> tx_dma_len ,
@@ -1393,15 +1386,21 @@ static void work_fn_tx(struct work_struct *work)
1393
1386
s -> cookie_tx = dmaengine_submit (desc );
1394
1387
if (dma_submit_error (s -> cookie_tx )) {
1395
1388
dev_warn (port -> dev , "Failed submitting Tx DMA descriptor\n" );
1396
- /* switch to PIO */
1397
- sci_tx_dma_release (s , true);
1398
- return ;
1389
+ goto switch_to_pio ;
1399
1390
}
1400
1391
1401
1392
dev_dbg (port -> dev , "%s: %p: %d...%d, cookie %d\n" ,
1402
1393
__func__ , xmit -> buf , xmit -> tail , xmit -> head , s -> cookie_tx );
1403
1394
1404
1395
dma_async_issue_pending (chan );
1396
+ return ;
1397
+
1398
+ switch_to_pio :
1399
+ spin_lock_irqsave (& port -> lock , flags );
1400
+ s -> chan_tx = NULL ;
1401
+ sci_start_tx (port );
1402
+ spin_unlock_irqrestore (& port -> lock , flags );
1403
+ return ;
1405
1404
}
1406
1405
1407
1406
static enum hrtimer_restart rx_timer_fn (struct hrtimer * t )
@@ -1535,7 +1534,6 @@ static void sci_request_dma(struct uart_port *port)
1535
1534
chan = sci_request_dma_chan (port , DMA_MEM_TO_DEV );
1536
1535
dev_dbg (port -> dev , "%s: TX: got channel %p\n" , __func__ , chan );
1537
1536
if (chan ) {
1538
- s -> chan_tx = chan ;
1539
1537
/* UART circular tx buffer is an aligned page. */
1540
1538
s -> tx_dma_addr = dma_map_single (chan -> device -> dev ,
1541
1539
port -> state -> xmit .buf ,
@@ -1544,11 +1542,13 @@ static void sci_request_dma(struct uart_port *port)
1544
1542
if (dma_mapping_error (chan -> device -> dev , s -> tx_dma_addr )) {
1545
1543
dev_warn (port -> dev , "Failed mapping Tx DMA descriptor\n" );
1546
1544
dma_release_channel (chan );
1547
- s -> chan_tx = NULL ;
1545
+ chan = NULL ;
1548
1546
} else {
1549
1547
dev_dbg (port -> dev , "%s: mapped %lu@%p to %pad\n" ,
1550
1548
__func__ , UART_XMIT_SIZE ,
1551
1549
port -> state -> xmit .buf , & s -> tx_dma_addr );
1550
+
1551
+ s -> chan_tx_saved = s -> chan_tx = chan ;
1552
1552
}
1553
1553
1554
1554
INIT_WORK (& s -> work_tx , work_fn_tx );
@@ -1561,16 +1561,13 @@ static void sci_request_dma(struct uart_port *port)
1561
1561
dma_addr_t dma ;
1562
1562
void * buf ;
1563
1563
1564
- s -> chan_rx = chan ;
1565
-
1566
1564
s -> buf_len_rx = 2 * max_t (size_t , 16 , port -> fifosize );
1567
1565
buf = dma_alloc_coherent (chan -> device -> dev , s -> buf_len_rx * 2 ,
1568
1566
& dma , GFP_KERNEL );
1569
1567
if (!buf ) {
1570
1568
dev_warn (port -> dev ,
1571
1569
"Failed to allocate Rx dma buffer, using PIO\n" );
1572
1570
dma_release_channel (chan );
1573
- s -> chan_rx = NULL ;
1574
1571
return ;
1575
1572
}
1576
1573
@@ -1591,17 +1588,19 @@ static void sci_request_dma(struct uart_port *port)
1591
1588
1592
1589
if (port -> type == PORT_SCIFA || port -> type == PORT_SCIFB )
1593
1590
sci_submit_rx (s );
1591
+
1592
+ s -> chan_rx_saved = s -> chan_rx = chan ;
1594
1593
}
1595
1594
}
1596
1595
1597
1596
static void sci_free_dma (struct uart_port * port )
1598
1597
{
1599
1598
struct sci_port * s = to_sci_port (port );
1600
1599
1601
- if (s -> chan_tx )
1602
- sci_tx_dma_release (s , false );
1603
- if (s -> chan_rx )
1604
- sci_rx_dma_release (s , false );
1600
+ if (s -> chan_tx_saved )
1601
+ sci_tx_dma_release (s );
1602
+ if (s -> chan_rx_saved )
1603
+ sci_rx_dma_release (s );
1605
1604
}
1606
1605
1607
1606
static void sci_flush_buffer (struct uart_port * port )
@@ -2092,7 +2091,7 @@ static void sci_shutdown(struct uart_port *port)
2092
2091
spin_unlock_irqrestore (& port -> lock , flags );
2093
2092
2094
2093
#ifdef CONFIG_SERIAL_SH_SCI_DMA
2095
- if (s -> chan_rx ) {
2094
+ if (s -> chan_rx_saved ) {
2096
2095
dev_dbg (port -> dev , "%s(%d) deleting rx_timer\n" , __func__ ,
2097
2096
port -> line );
2098
2097
hrtimer_cancel (& s -> rx_timer );
0 commit comments