aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_bfin5xx.c
diff options
context:
space:
mode:
authorBarry Song <barry.song@analog.com>2009-06-17 06:10:53 -0400
committerMike Frysinger <vapier@gentoo.org>2010-10-18 02:49:30 -0400
commit8221610e9990e7ee542a4e508d278302af8a9e75 (patch)
treec08fca285205f621061adbb95f876cecd6700157 /drivers/spi/spi_bfin5xx.c
parentf6a6d96685be6e784849d067b44acb831f595417 (diff)
spi/bfin_spi: fix CS handling
The CS helper functions were toggling both the Flag Enable and the Flag Value bits, but the Flag Value bit is ignored if the corresponding Flag Enable bit is cleared. So under high speed transactions, the CS sometimes would not toggle properly. Since it makes no sense to toggle the Flag Enable bit dynamically when we actually want to control the Flag Value, do this when setting up the device and then only handle toggling of the CS value during runtime. Signed-off-by: Barry Song <barry.song@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'drivers/spi/spi_bfin5xx.c')
-rw-r--r--drivers/spi/spi_bfin5xx.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 3736c3596a41..6150a8cfb82a 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -188,8 +188,7 @@ static void bfin_spi_cs_active(struct driver_data *drv_data, struct chip_data *c
188 if (likely(chip->chip_select_num)) { 188 if (likely(chip->chip_select_num)) {
189 u16 flag = read_FLAG(drv_data); 189 u16 flag = read_FLAG(drv_data);
190 190
191 flag |= chip->flag; 191 flag &= ~chip->flag;
192 flag &= ~(chip->flag << 8);
193 192
194 write_FLAG(drv_data, flag); 193 write_FLAG(drv_data, flag);
195 } else { 194 } else {
@@ -202,8 +201,7 @@ static void bfin_spi_cs_deactive(struct driver_data *drv_data, struct chip_data
202 if (likely(chip->chip_select_num)) { 201 if (likely(chip->chip_select_num)) {
203 u16 flag = read_FLAG(drv_data); 202 u16 flag = read_FLAG(drv_data);
204 203
205 flag &= ~chip->flag; 204 flag |= chip->flag;
206 flag |= (chip->flag << 8);
207 205
208 write_FLAG(drv_data, flag); 206 write_FLAG(drv_data, flag);
209 } else { 207 } else {
@@ -215,6 +213,25 @@ static void bfin_spi_cs_deactive(struct driver_data *drv_data, struct chip_data
215 udelay(chip->cs_chg_udelay); 213 udelay(chip->cs_chg_udelay);
216} 214}
217 215
216/* enable or disable the pin muxed by GPIO and SPI CS to work as SPI CS */
217static inline void bfin_spi_cs_enable(struct driver_data *drv_data, struct chip_data *chip)
218{
219 u16 flag = read_FLAG(drv_data);
220
221 flag |= (chip->flag >> 8);
222
223 write_FLAG(drv_data, flag);
224}
225
226static inline void bfin_spi_cs_disable(struct driver_data *drv_data, struct chip_data *chip)
227{
228 u16 flag = read_FLAG(drv_data);
229
230 flag &= ~(chip->flag >> 8);
231
232 write_FLAG(drv_data, flag);
233}
234
218/* stop controller and re-config current chip*/ 235/* stop controller and re-config current chip*/
219static void bfin_spi_restore_state(struct driver_data *drv_data) 236static void bfin_spi_restore_state(struct driver_data *drv_data)
220{ 237{
@@ -1169,7 +1186,7 @@ static int bfin_spi_setup(struct spi_device *spi)
1169 * SPI_BAUD, not the real baudrate 1186 * SPI_BAUD, not the real baudrate
1170 */ 1187 */
1171 chip->baud = hz_to_spi_baud(spi->max_speed_hz); 1188 chip->baud = hz_to_spi_baud(spi->max_speed_hz);
1172 chip->flag = 1 << (spi->chip_select); 1189 chip->flag = (1 << (spi->chip_select)) << 8;
1173 chip->chip_select_num = spi->chip_select; 1190 chip->chip_select_num = spi->chip_select;
1174 1191
1175 switch (chip->bits_per_word) { 1192 switch (chip->bits_per_word) {
@@ -1268,6 +1285,7 @@ static int bfin_spi_setup(struct spi_device *spi)
1268 } 1285 }
1269 } 1286 }
1270 1287
1288 bfin_spi_cs_enable(drv_data, chip);
1271 bfin_spi_cs_deactive(drv_data, chip); 1289 bfin_spi_cs_deactive(drv_data, chip);
1272 1290
1273 return 0; 1291 return 0;
@@ -1299,14 +1317,17 @@ static int bfin_spi_setup(struct spi_device *spi)
1299static void bfin_spi_cleanup(struct spi_device *spi) 1317static void bfin_spi_cleanup(struct spi_device *spi)
1300{ 1318{
1301 struct chip_data *chip = spi_get_ctldata(spi); 1319 struct chip_data *chip = spi_get_ctldata(spi);
1320 struct driver_data *drv_data = spi_master_get_devdata(spi->master);
1302 1321
1303 if (!chip) 1322 if (!chip)
1304 return; 1323 return;
1305 1324
1306 if ((chip->chip_select_num > 0) 1325 if ((chip->chip_select_num > 0)
1307 && (chip->chip_select_num <= spi->master->num_chipselect)) 1326 && (chip->chip_select_num <= spi->master->num_chipselect)) {
1308 peripheral_free(ssel[spi->master->bus_num] 1327 peripheral_free(ssel[spi->master->bus_num]
1309 [chip->chip_select_num-1]); 1328 [chip->chip_select_num-1]);
1329 bfin_spi_cs_disable(drv_data, chip);
1330 }
1310 1331
1311 if (chip->chip_select_num == 0) 1332 if (chip->chip_select_num == 0)
1312 gpio_free(chip->cs_gpio); 1333 gpio_free(chip->cs_gpio);