30
30
#define CDNS_UART_TTY_NAME "ttyPS"
31
31
#define CDNS_UART_NAME "xuartps"
32
32
#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
33
- #define CDNS_UART_NR_PORTS 2
34
33
#define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
35
34
#define CDNS_UART_REGISTER_SPACE 0x1000
36
35
@@ -1370,6 +1369,88 @@ static const struct of_device_id cdns_uart_of_match[] = {
1370
1369
};
1371
1370
MODULE_DEVICE_TABLE (of , cdns_uart_of_match );
1372
1371
1372
+ /*
1373
+ * Maximum number of instances without alias IDs but if there is alias
1374
+ * which target "< MAX_UART_INSTANCES" range this ID can't be used.
1375
+ */
1376
+ #define MAX_UART_INSTANCES 32
1377
+
1378
+ /* Stores static aliases list */
1379
+ static DECLARE_BITMAP (alias_bitmap , MAX_UART_INSTANCES ) ;
1380
+ static int alias_bitmap_initialized ;
1381
+
1382
+ /* Stores actual bitmap of allocated IDs with alias IDs together */
1383
+ static DECLARE_BITMAP (bitmap , MAX_UART_INSTANCES ) ;
1384
+ /* Protect bitmap operations to have unique IDs */
1385
+ static DEFINE_MUTEX (bitmap_lock );
1386
+
1387
+ static int cdns_get_id (struct platform_device * pdev )
1388
+ {
1389
+ int id , ret ;
1390
+
1391
+ mutex_lock (& bitmap_lock );
1392
+
1393
+ /* Alias list is stable that's why get alias bitmap only once */
1394
+ if (!alias_bitmap_initialized ) {
1395
+ ret = of_alias_get_alias_list (cdns_uart_of_match , "serial" ,
1396
+ alias_bitmap , MAX_UART_INSTANCES );
1397
+ if (ret )
1398
+ return ret ;
1399
+
1400
+ alias_bitmap_initialized ++ ;
1401
+ }
1402
+
1403
+ /* Make sure that alias ID is not taken by instance without alias */
1404
+ bitmap_or (bitmap , bitmap , alias_bitmap , MAX_UART_INSTANCES );
1405
+
1406
+ dev_dbg (& pdev -> dev , "Alias bitmap: %*pb\n" ,
1407
+ MAX_UART_INSTANCES , bitmap );
1408
+
1409
+ /* Look for a serialN alias */
1410
+ id = of_alias_get_id (pdev -> dev .of_node , "serial" );
1411
+ if (id < 0 ) {
1412
+ dev_warn (& pdev -> dev ,
1413
+ "No serial alias passed. Using the first free id\n" );
1414
+
1415
+ /*
1416
+ * Start with id 0 and check if there is no serial0 alias
1417
+ * which points to device which is compatible with this driver.
1418
+ * If alias exists then try next free position.
1419
+ */
1420
+ id = 0 ;
1421
+
1422
+ for (;;) {
1423
+ dev_info (& pdev -> dev , "Checking id %d\n" , id );
1424
+ id = find_next_zero_bit (bitmap , MAX_UART_INSTANCES , id );
1425
+
1426
+ /* No free empty instance */
1427
+ if (id == MAX_UART_INSTANCES ) {
1428
+ dev_err (& pdev -> dev , "No free ID\n" );
1429
+ mutex_unlock (& bitmap_lock );
1430
+ return - EINVAL ;
1431
+ }
1432
+
1433
+ dev_dbg (& pdev -> dev , "The empty id is %d\n" , id );
1434
+ /* Check if ID is empty */
1435
+ if (!test_and_set_bit (id , bitmap )) {
1436
+ /* Break the loop if bit is taken */
1437
+ dev_dbg (& pdev -> dev ,
1438
+ "Selected ID %d allocation passed\n" ,
1439
+ id );
1440
+ break ;
1441
+ }
1442
+ dev_dbg (& pdev -> dev ,
1443
+ "Selected ID %d allocation failed\n" , id );
1444
+ /* if taking bit fails then try next one */
1445
+ id ++ ;
1446
+ }
1447
+ }
1448
+
1449
+ mutex_unlock (& bitmap_lock );
1450
+
1451
+ return id ;
1452
+ }
1453
+
1373
1454
/**
1374
1455
* cdns_uart_probe - Platform driver probe
1375
1456
* @pdev: Pointer to the platform device structure
@@ -1403,21 +1484,17 @@ static int cdns_uart_probe(struct platform_device *pdev)
1403
1484
if (!cdns_uart_uart_driver )
1404
1485
return - ENOMEM ;
1405
1486
1406
- /* Look for a serialN alias */
1407
- cdns_uart_data -> id = of_alias_get_id (pdev -> dev .of_node , "serial" );
1487
+ cdns_uart_data -> id = cdns_get_id (pdev );
1408
1488
if (cdns_uart_data -> id < 0 )
1409
- cdns_uart_data -> id = 0 ;
1410
-
1411
- if (cdns_uart_data -> id >= CDNS_UART_NR_PORTS ) {
1412
- dev_err (& pdev -> dev , "Cannot get uart_port structure\n" );
1413
- return - ENODEV ;
1414
- }
1489
+ return cdns_uart_data -> id ;
1415
1490
1416
1491
/* There is a need to use unique driver name */
1417
1492
driver_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s%d" ,
1418
1493
CDNS_UART_NAME , cdns_uart_data -> id );
1419
- if (!driver_name )
1420
- return - ENOMEM ;
1494
+ if (!driver_name ) {
1495
+ rc = - ENOMEM ;
1496
+ goto err_out_id ;
1497
+ }
1421
1498
1422
1499
cdns_uart_uart_driver -> owner = THIS_MODULE ;
1423
1500
cdns_uart_uart_driver -> driver_name = driver_name ;
@@ -1446,7 +1523,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
1446
1523
rc = uart_register_driver (cdns_uart_uart_driver );
1447
1524
if (rc < 0 ) {
1448
1525
dev_err (& pdev -> dev , "Failed to register driver\n" );
1449
- return rc ;
1526
+ goto err_out_id ;
1450
1527
}
1451
1528
1452
1529
cdns_uart_data -> cdns_uart_driver = cdns_uart_uart_driver ;
@@ -1587,7 +1664,10 @@ static int cdns_uart_probe(struct platform_device *pdev)
1587
1664
clk_disable_unprepare (cdns_uart_data -> pclk );
1588
1665
err_out_unregister_driver :
1589
1666
uart_unregister_driver (cdns_uart_data -> cdns_uart_driver );
1590
-
1667
+ err_out_id :
1668
+ mutex_lock (& bitmap_lock );
1669
+ clear_bit (cdns_uart_data -> id , bitmap );
1670
+ mutex_unlock (& bitmap_lock );
1591
1671
return rc ;
1592
1672
}
1593
1673
@@ -1610,6 +1690,9 @@ static int cdns_uart_remove(struct platform_device *pdev)
1610
1690
#endif
1611
1691
rc = uart_remove_one_port (cdns_uart_data -> cdns_uart_driver , port );
1612
1692
port -> mapbase = 0 ;
1693
+ mutex_lock (& bitmap_lock );
1694
+ clear_bit (cdns_uart_data -> id , bitmap );
1695
+ mutex_unlock (& bitmap_lock );
1613
1696
clk_disable_unprepare (cdns_uart_data -> uartclk );
1614
1697
clk_disable_unprepare (cdns_uart_data -> pclk );
1615
1698
pm_runtime_disable (& pdev -> dev );
0 commit comments