40
40
#include <linux/ioport.h>
41
41
#include <linux/acpi.h>
42
42
#include <linux/highmem.h>
43
+ #include <linux/idr.h>
43
44
44
45
#define CREATE_TRACE_POINTS
45
46
#include <trace/events/spi.h>
47
+ #define SPI_DYN_FIRST_BUS_NUM 0
48
+
49
+ static DEFINE_IDR (spi_master_idr );
46
50
47
51
static void spidev_release (struct device * dev )
48
52
{
@@ -420,6 +424,7 @@ static LIST_HEAD(spi_controller_list);
420
424
/*
421
425
* Used to protect add/del opertion for board_info list and
422
426
* spi_controller list, and their matching process
427
+ * also used to protect object of type struct idr
423
428
*/
424
429
static DEFINE_MUTEX (board_lock );
425
430
@@ -2051,11 +2056,10 @@ static int of_spi_register_master(struct spi_controller *ctlr)
2051
2056
*/
2052
2057
int spi_register_controller (struct spi_controller * ctlr )
2053
2058
{
2054
- static atomic_t dyn_bus_id = ATOMIC_INIT ((1 <<15 ) - 1 );
2055
2059
struct device * dev = ctlr -> dev .parent ;
2056
2060
struct boardinfo * bi ;
2057
2061
int status = - ENODEV ;
2058
- int dynamic = 0 ;
2062
+ int id ;
2059
2063
2060
2064
if (!dev )
2061
2065
return - ENODEV ;
@@ -2071,17 +2075,29 @@ int spi_register_controller(struct spi_controller *ctlr)
2071
2075
*/
2072
2076
if (ctlr -> num_chipselect == 0 )
2073
2077
return - EINVAL ;
2074
-
2075
- if ((ctlr -> bus_num < 0 ) && ctlr -> dev .of_node )
2076
- ctlr -> bus_num = of_alias_get_id (ctlr -> dev .of_node , "spi" );
2077
-
2078
- /* convention: dynamically assigned bus IDs count down from the max */
2078
+
2079
+ /* allocate dynamic bus number using Linux idr */
2080
+ if ((ctlr -> bus_num < 0 ) && ctlr -> dev .of_node ) {
2081
+ id = of_alias_get_id (ctlr -> dev .of_node , "spi" );
2082
+ if (id >= 0 ) {
2083
+ ctlr -> bus_num = id ;
2084
+ mutex_lock (& board_lock );
2085
+ id = idr_alloc (& spi_master_idr , ctlr , ctlr -> bus_num ,
2086
+ ctlr -> bus_num + 1 , GFP_KERNEL );
2087
+ mutex_unlock (& board_lock );
2088
+ if (WARN (id < 0 , "couldn't get idr" ))
2089
+ return id == - ENOSPC ? - EBUSY : id ;
2090
+ }
2091
+ }
2079
2092
if (ctlr -> bus_num < 0 ) {
2080
- /* FIXME switch to an IDR based scheme, something like
2081
- * I2C now uses, so we can't run out of "dynamic" IDs
2082
- */
2083
- ctlr -> bus_num = atomic_dec_return (& dyn_bus_id );
2084
- dynamic = 1 ;
2093
+ mutex_lock (& board_lock );
2094
+ id = idr_alloc (& spi_master_idr , ctlr ,
2095
+ SPI_DYN_FIRST_BUS_NUM , 0 , GFP_KERNEL );
2096
+ mutex_unlock (& board_lock );
2097
+ if (WARN (id < 0 , "couldn't get idr" ))
2098
+ return id ;
2099
+
2100
+ ctlr -> bus_num = id ;
2085
2101
}
2086
2102
2087
2103
INIT_LIST_HEAD (& ctlr -> queue );
@@ -2099,11 +2115,16 @@ int spi_register_controller(struct spi_controller *ctlr)
2099
2115
*/
2100
2116
dev_set_name (& ctlr -> dev , "spi%u" , ctlr -> bus_num );
2101
2117
status = device_add (& ctlr -> dev );
2102
- if (status < 0 )
2118
+ if (status < 0 ) {
2119
+ /* free bus id */
2120
+ mutex_lock (& board_lock );
2121
+ idr_remove (& spi_master_idr , ctlr -> bus_num );
2122
+ mutex_unlock (& board_lock );
2103
2123
goto done ;
2104
- dev_dbg (dev , "registered %s %s%s\n" ,
2124
+ }
2125
+ dev_dbg (dev , "registered %s %s\n" ,
2105
2126
spi_controller_is_slave (ctlr ) ? "slave" : "master" ,
2106
- dev_name (& ctlr -> dev ), dynamic ? " (dynamic)" : "" );
2127
+ dev_name (& ctlr -> dev ));
2107
2128
2108
2129
/* If we're using a queued driver, start the queue */
2109
2130
if (ctlr -> transfer )
@@ -2112,6 +2133,10 @@ int spi_register_controller(struct spi_controller *ctlr)
2112
2133
status = spi_controller_initialize_queue (ctlr );
2113
2134
if (status ) {
2114
2135
device_del (& ctlr -> dev );
2136
+ /* free bus id */
2137
+ mutex_lock (& board_lock );
2138
+ idr_remove (& spi_master_idr , ctlr -> bus_num );
2139
+ mutex_unlock (& board_lock );
2115
2140
goto done ;
2116
2141
}
2117
2142
}
@@ -2190,8 +2215,20 @@ static int __unregister(struct device *dev, void *null)
2190
2215
*/
2191
2216
void spi_unregister_controller (struct spi_controller * ctlr )
2192
2217
{
2218
+ struct spi_controller * found ;
2193
2219
int dummy ;
2194
2220
2221
+ /* First make sure that this controller was ever added */
2222
+ mutex_lock (& board_lock );
2223
+ found = idr_find (& spi_master_idr , ctlr -> bus_num );
2224
+ mutex_unlock (& board_lock );
2225
+ if (found != ctlr ) {
2226
+ dev_dbg (& ctlr -> dev ,
2227
+ "attempting to delete unregistered controller [%s]\n" ,
2228
+ dev_name (& ctlr -> dev ));
2229
+ return ;
2230
+ }
2231
+
2195
2232
if (ctlr -> queued ) {
2196
2233
if (spi_destroy_queue (ctlr ))
2197
2234
dev_err (& ctlr -> dev , "queue remove failed\n" );
@@ -2203,6 +2240,10 @@ void spi_unregister_controller(struct spi_controller *ctlr)
2203
2240
2204
2241
dummy = device_for_each_child (& ctlr -> dev , NULL , __unregister );
2205
2242
device_unregister (& ctlr -> dev );
2243
+ /* free bus id */
2244
+ mutex_lock (& board_lock );
2245
+ idr_remove (& spi_master_idr , ctlr -> bus_num );
2246
+ mutex_unlock (& board_lock );
2206
2247
}
2207
2248
EXPORT_SYMBOL_GPL (spi_unregister_controller );
2208
2249
0 commit comments