11
11
* spi-atmel.c, Copyright (C) 2006 Atmel Corporation
12
12
*/
13
13
14
+ #include <linux/cleanup.h>
14
15
#include <linux/clk.h>
15
16
#include <linux/completion.h>
16
17
#include <linux/debugfs.h>
26
27
#include <linux/of_address.h>
27
28
#include <linux/platform_device.h>
28
29
#include <linux/gpio/consumer.h>
29
- #include <linux/gpio/machine.h> /* FIXME: using chip internals */
30
- #include <linux/gpio/driver.h> /* FIXME: using chip internals */
30
+ #include <linux/gpio/machine.h> /* FIXME: using GPIO lookup tables */
31
31
#include <linux/of_irq.h>
32
+ #include <linux/overflow.h>
33
+ #include <linux/slab.h>
32
34
#include <linux/spi/spi.h>
33
35
34
36
/* SPI register offsets */
@@ -83,6 +85,7 @@ MODULE_PARM_DESC(polling_limit_us,
83
85
* struct bcm2835_spi - BCM2835 SPI controller
84
86
* @regs: base address of register map
85
87
* @clk: core clock, divided to calculate serial clock
88
+ * @cs_gpio: chip-select GPIO descriptor
86
89
* @clk_hz: core clock cached speed
87
90
* @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full
88
91
* @tfr: SPI transfer currently processed
@@ -117,6 +120,7 @@ MODULE_PARM_DESC(polling_limit_us,
117
120
struct bcm2835_spi {
118
121
void __iomem * regs ;
119
122
struct clk * clk ;
123
+ struct gpio_desc * cs_gpio ;
120
124
unsigned long clk_hz ;
121
125
int irq ;
122
126
struct spi_transfer * tfr ;
@@ -1156,15 +1160,11 @@ static void bcm2835_spi_handle_err(struct spi_controller *ctlr,
1156
1160
bcm2835_spi_reset_hw (bs );
1157
1161
}
1158
1162
1159
- static int chip_match_name (struct gpio_chip * chip , void * data )
1160
- {
1161
- return !strcmp (chip -> label , data );
1162
- }
1163
-
1164
1163
static void bcm2835_spi_cleanup (struct spi_device * spi )
1165
1164
{
1166
1165
struct bcm2835_spidev * target = spi_get_ctldata (spi );
1167
1166
struct spi_controller * ctlr = spi -> controller ;
1167
+ struct bcm2835_spi * bs = spi_controller_get_devdata (ctlr );
1168
1168
1169
1169
if (target -> clear_rx_desc )
1170
1170
dmaengine_desc_free (target -> clear_rx_desc );
@@ -1175,6 +1175,9 @@ static void bcm2835_spi_cleanup(struct spi_device *spi)
1175
1175
sizeof (u32 ),
1176
1176
DMA_TO_DEVICE );
1177
1177
1178
+ gpiod_put (bs -> cs_gpio );
1179
+ spi_set_csgpiod (spi , 0 , NULL );
1180
+
1178
1181
kfree (target );
1179
1182
}
1180
1183
@@ -1221,7 +1224,7 @@ static int bcm2835_spi_setup(struct spi_device *spi)
1221
1224
struct spi_controller * ctlr = spi -> controller ;
1222
1225
struct bcm2835_spi * bs = spi_controller_get_devdata (ctlr );
1223
1226
struct bcm2835_spidev * target = spi_get_ctldata (spi );
1224
- struct gpio_chip * chip ;
1227
+ struct gpiod_lookup_table * lookup __free ( kfree ) = NULL ;
1225
1228
int ret ;
1226
1229
u32 cs ;
1227
1230
@@ -1288,29 +1291,36 @@ static int bcm2835_spi_setup(struct spi_device *spi)
1288
1291
}
1289
1292
1290
1293
/*
1291
- * Translate native CS to GPIO
1294
+ * TODO: The code below is a slightly better alternative to the utter
1295
+ * abuse of the GPIO API that I found here before. It creates a
1296
+ * temporary lookup table, assigns it to the SPI device, gets the GPIO
1297
+ * descriptor and then releases the lookup table.
1292
1298
*
1293
- * FIXME: poking around in the gpiolib internals like this is
1294
- * not very good practice. Find a way to locate the real problem
1295
- * and fix it. Why is the GPIO descriptor in spi->cs_gpiod
1296
- * sometimes not assigned correctly? Erroneous device trees?
1299
+ * More on the problem that it addresses:
1300
+ * https://www.spinics.net/lists/linux-gpio/msg36218.html
1297
1301
*/
1302
+ lookup = kzalloc (struct_size (lookup , table , 1 ), GFP_KERNEL );
1303
+ if (!lookup ) {
1304
+ ret = - ENOMEM ;
1305
+ goto err_cleanup ;
1306
+ }
1298
1307
1299
- /* get the gpio chip for the base */
1300
- chip = gpiochip_find ("pinctrl-bcm2835" , chip_match_name );
1301
- if (! chip )
1302
- return 0 ;
1308
+ lookup -> dev_id = dev_name ( & spi -> dev );
1309
+ lookup -> table [ 0 ] = GPIO_LOOKUP ("pinctrl-bcm2835" ,
1310
+ 8 - ( spi_get_chipselect ( spi , 0 )),
1311
+ "cs" , GPIO_LOOKUP_FLAGS_DEFAULT ) ;
1303
1312
1304
- spi_set_csgpiod (spi , 0 , gpiochip_request_own_desc (chip ,
1305
- 8 - (spi_get_chipselect (spi , 0 )),
1306
- DRV_NAME ,
1307
- GPIO_LOOKUP_FLAGS_DEFAULT ,
1308
- GPIOD_OUT_LOW ));
1309
- if (IS_ERR (spi_get_csgpiod (spi , 0 ))) {
1310
- ret = PTR_ERR (spi_get_csgpiod (spi , 0 ));
1313
+ gpiod_add_lookup_table (lookup );
1314
+
1315
+ bs -> cs_gpio = gpiod_get (& spi -> dev , "cs" , GPIOD_OUT_LOW );
1316
+ gpiod_remove_lookup_table (lookup );
1317
+ if (IS_ERR (bs -> cs_gpio )) {
1318
+ ret = PTR_ERR (bs -> cs_gpio );
1311
1319
goto err_cleanup ;
1312
1320
}
1313
1321
1322
+ spi_set_csgpiod (spi , 0 , bs -> cs_gpio );
1323
+
1314
1324
/* and set up the "mode" and level */
1315
1325
dev_info (& spi -> dev , "setting up native-CS%i to use GPIO\n" ,
1316
1326
spi_get_chipselect (spi , 0 ));
0 commit comments