Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/libertas: remove GPIO-CS handling in SPI interface code

This removes the dependency on GPIO framework and lets the SPI host
driver handle the chip select. The SPI host driver is required to keep
the CS active for the entire message unless cs_change says otherwise.
This patch collects the two/three single SPI transfers into a message.
Also the delay in read path in case use_dummy_writes are not used is
moved into the SPI host driver.

Tested-by: Mike Rapoport <mike@compulab.co.il>
Tested-by: Andrey Yurovsky <andrey@cozybit.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Sebastian Andrzej Siewior and committed by
John W. Linville
4d1d4985 582241a0

+45 -52
+1 -1
drivers/net/wireless/Kconfig
··· 153 153 154 154 config LIBERTAS_SPI 155 155 tristate "Marvell Libertas 8686 SPI 802.11b/g cards" 156 - depends on LIBERTAS && SPI && GENERIC_GPIO 156 + depends on LIBERTAS && SPI 157 157 ---help--- 158 158 A driver for Marvell Libertas 8686 SPI devices. 159 159
+44 -48
drivers/net/wireless/libertas/if_spi.c
··· 19 19 20 20 #include <linux/moduleparam.h> 21 21 #include <linux/firmware.h> 22 - #include <linux/gpio.h> 23 22 #include <linux/jiffies.h> 24 23 #include <linux/kthread.h> 25 24 #include <linux/list.h> ··· 49 50 /* The card ID and card revision, as reported by the hardware. */ 50 51 u16 card_id; 51 52 u8 card_rev; 52 - 53 - /* Pin number for our GPIO chip-select. */ 54 - /* TODO: Once the generic SPI layer has some additional features, we 55 - * should take this out and use the normal chip select here. 56 - * We need support for chip select delays, and not dropping chipselect 57 - * after each word. */ 58 - int gpio_cs; 59 53 60 54 /* The last time that we initiated an SPU operation */ 61 55 unsigned long prev_xfer_time; ··· 122 130 * If not, we have to busy-wait to be on the safe side. */ 123 131 ndelay(400); 124 132 } 125 - gpio_set_value(card->gpio_cs, 0); /* assert CS */ 126 133 } 127 134 128 135 static void spu_transaction_finish(struct if_spi_card *card) 129 136 { 130 - gpio_set_value(card->gpio_cs, 1); /* drop CS */ 131 137 card->prev_xfer_time = jiffies; 132 138 } 133 139 ··· 135 145 { 136 146 int err = 0; 137 147 u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); 148 + struct spi_message m; 149 + struct spi_transfer reg_trans; 150 + struct spi_transfer data_trans; 151 + 152 + spi_message_init(&m); 153 + memset(&reg_trans, 0, sizeof(reg_trans)); 154 + memset(&data_trans, 0, sizeof(data_trans)); 138 155 139 156 /* You must give an even number of bytes to the SPU, even if it 140 157 * doesn't care about the last one. */ ··· 150 153 spu_transaction_init(card); 151 154 152 155 /* write SPU register index */ 153 - err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16)); 154 - if (err) 155 - goto out; 156 + reg_trans.tx_buf = &reg_out; 157 + reg_trans.len = sizeof(reg_out); 156 158 157 - err = spi_write(card->spi, buf, len); 159 + data_trans.tx_buf = buf; 160 + data_trans.len = len; 158 161 159 - out: 162 + spi_message_add_tail(&reg_trans, &m); 163 + spi_message_add_tail(&data_trans, &m); 164 + 165 + err = spi_sync(card->spi, &m); 160 166 spu_transaction_finish(card); 161 167 return err; 162 168 } ··· 186 186 187 187 static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) 188 188 { 189 - unsigned int i, delay; 189 + unsigned int delay; 190 190 int err = 0; 191 - u16 zero = 0; 192 191 u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); 192 + struct spi_message m; 193 + struct spi_transfer reg_trans; 194 + struct spi_transfer dummy_trans; 195 + struct spi_transfer data_trans; 193 196 194 197 /* You must take an even number of bytes from the SPU, even if you 195 198 * don't care about the last one. */ ··· 200 197 201 198 spu_transaction_init(card); 202 199 200 + spi_message_init(&m); 201 + memset(&reg_trans, 0, sizeof(reg_trans)); 202 + memset(&dummy_trans, 0, sizeof(dummy_trans)); 203 + memset(&data_trans, 0, sizeof(data_trans)); 204 + 203 205 /* write SPU register index */ 204 - err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16)); 205 - if (err) 206 - goto out; 206 + reg_trans.tx_buf = &reg_out; 207 + reg_trans.len = sizeof(reg_out); 208 + spi_message_add_tail(&reg_trans, &m); 207 209 208 210 delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : 209 211 card->spu_reg_delay; 210 212 if (card->use_dummy_writes) { 211 213 /* Clock in dummy cycles while the SPU fills the FIFO */ 212 - for (i = 0; i < delay / 16; ++i) { 213 - err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); 214 - if (err) 215 - return err; 216 - } 214 + dummy_trans.len = delay / 8; 215 + spi_message_add_tail(&dummy_trans, &m); 217 216 } else { 218 217 /* Busy-wait while the SPU fills the FIFO */ 219 - ndelay(100 + (delay * 10)); 218 + reg_trans.delay_usecs = 219 + DIV_ROUND_UP((100 + (delay * 10)), 1000); 220 220 } 221 221 222 222 /* read in data */ 223 - err = spi_read(card->spi, buf, len); 223 + data_trans.rx_buf = buf; 224 + data_trans.len = len; 225 + spi_message_add_tail(&data_trans, &m); 224 226 225 - out: 227 + err = spi_sync(card->spi, &m); 226 228 spu_transaction_finish(card); 227 229 return err; 228 230 } ··· 1057 1049 spi_set_drvdata(spi, card); 1058 1050 card->pdata = pdata; 1059 1051 card->spi = spi; 1060 - card->gpio_cs = pdata->gpio_cs; 1061 1052 card->prev_xfer_time = jiffies; 1062 1053 1063 1054 sema_init(&card->spi_ready, 0); ··· 1065 1058 INIT_LIST_HEAD(&card->data_packet_list); 1066 1059 spin_lock_init(&card->buffer_lock); 1067 1060 1068 - /* set up GPIO CS line. TODO: use regular CS line */ 1069 - err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); 1070 - if (err) 1071 - goto free_card; 1072 - err = gpio_direction_output(card->gpio_cs, 1); 1073 - if (err) 1074 - goto free_gpio; 1075 - 1076 1061 /* Initialize the SPI Interface Unit */ 1077 1062 err = spu_init(card, pdata->use_dummy_writes); 1078 1063 if (err) 1079 - goto free_gpio; 1064 + goto free_card; 1080 1065 err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); 1081 1066 if (err) 1082 - goto free_gpio; 1067 + goto free_card; 1083 1068 1084 1069 /* Firmware load */ 1085 1070 err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); 1086 1071 if (err) 1087 - goto free_gpio; 1072 + goto free_card; 1088 1073 if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) 1089 1074 lbs_deb_spi("Firmware is already loaded for " 1090 1075 "Marvell WLAN 802.11 adapter\n"); ··· 1084 1085 err = if_spi_calculate_fw_names(card->card_id, 1085 1086 card->helper_fw_name, card->main_fw_name); 1086 1087 if (err) 1087 - goto free_gpio; 1088 + goto free_card; 1088 1089 1089 1090 lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " 1090 1091 "(chip_id = 0x%04x, chip_rev = 0x%02x) " ··· 1095 1096 spi->max_speed_hz); 1096 1097 err = if_spi_prog_helper_firmware(card); 1097 1098 if (err) 1098 - goto free_gpio; 1099 + goto free_card; 1099 1100 err = if_spi_prog_main_firmware(card); 1100 1101 if (err) 1101 - goto free_gpio; 1102 + goto free_card; 1102 1103 lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); 1103 1104 } 1104 1105 1105 1106 err = spu_set_interrupt_mode(card, 0, 1); 1106 1107 if (err) 1107 - goto free_gpio; 1108 + goto free_card; 1108 1109 1109 1110 /* Register our card with libertas. 1110 1111 * This will call alloc_etherdev */ 1111 1112 priv = lbs_add_card(card, &spi->dev); 1112 1113 if (!priv) { 1113 1114 err = -ENOMEM; 1114 - goto free_gpio; 1115 + goto free_card; 1115 1116 } 1116 1117 card->priv = priv; 1117 1118 priv->card = card; ··· 1156 1157 if_spi_terminate_spi_thread(card); 1157 1158 remove_card: 1158 1159 lbs_remove_card(priv); /* will call free_netdev */ 1159 - free_gpio: 1160 - gpio_free(card->gpio_cs); 1161 1160 free_card: 1162 1161 free_if_spi_card(card); 1163 1162 out: ··· 1176 1179 free_irq(spi->irq, card); 1177 1180 if_spi_terminate_spi_thread(card); 1178 1181 lbs_remove_card(priv); /* will call free_netdev */ 1179 - gpio_free(card->gpio_cs); 1180 1182 if (card->pdata->teardown) 1181 1183 card->pdata->teardown(spi); 1182 1184 free_if_spi_card(card);
-3
include/linux/spi/libertas_spi.h
··· 22 22 * speed, you may want to use 0 here. */ 23 23 u16 use_dummy_writes; 24 24 25 - /* GPIO number to use as chip select */ 26 - u16 gpio_cs; 27 - 28 25 /* Board specific setup/teardown */ 29 26 int (*setup)(struct spi_device *spi); 30 27 int (*teardown)(struct spi_device *spi);