Title: [7382] trunk/drivers/spi/spi_bfin5xx.c: A better fix for SPI CS issue as discussed with Mike.
Revision
7382
Author
bhsong
Date
2009-09-18 05:02:09 -0400 (Fri, 18 Sep 2009)

Log Message

A better fix for SPI CS issue as discussed with Mike.
The aim of bfin_spi_cs_activer/deactive is making the cs level low/high.It is
wrong&redundant to do enable/disable CS every time in bfin_spi_cs_active()/
deactive(). What we should do is only setting the level of CS level in these
two functions.
Then we can enable CS only while requesting it, and disable CS while releasing.

Modified Paths

Diff

Modified: trunk/drivers/spi/spi_bfin5xx.c (7381 => 7382)


--- trunk/drivers/spi/spi_bfin5xx.c	2009-09-18 06:29:21 UTC (rev 7381)
+++ trunk/drivers/spi/spi_bfin5xx.c	2009-09-18 09:02:09 UTC (rev 7382)
@@ -190,7 +190,6 @@
 	if (likely(chip->chip_select_num)) {
 		u16 flag = read_FLAG(drv_data);
 
-		flag |= chip->flag;
 		flag &= ~(chip->flag << 8);
 
 		write_FLAG(drv_data, flag);
@@ -204,13 +203,8 @@
 	if (likely(chip->chip_select_num)) {
 		u16 flag = read_FLAG(drv_data);
 
-		/* Only with CS enabled, we can set the level of CS */
-		flag |= chip->flag;
 		flag |= (chip->flag << 8);
-		write_FLAG(drv_data, flag);
 
-		/* Disable CS after deactive it */
-		flag &= ~chip->flag;
 		write_FLAG(drv_data, flag);
 	} else {
 		gpio_set_value(chip->cs_gpio, 1);
@@ -221,6 +215,25 @@
 		udelay(chip->cs_chg_udelay);
 }
 
+/* enable or disable the pin muxed by GPIO and SPI CS to work as SPI CS */
+static inline void bfin_spi_cs_enable(struct driver_data *drv_data, struct chip_data *chip)
+{
+	u16 flag = read_FLAG(drv_data);
+
+	flag |= chip->flag;
+
+	write_FLAG(drv_data, flag);
+}
+
+static inline void bfin_spi_cs_disable(struct driver_data *drv_data, struct chip_data *chip)
+{
+	u16 flag = read_FLAG(drv_data);
+
+	flag &= ~chip->flag;
+
+	write_FLAG(drv_data, flag);
+}
+
 /* stop controller and re-config current chip*/
 static void bfin_spi_restore_state(struct driver_data *drv_data)
 {
@@ -1345,6 +1358,7 @@
 		}
 	}
 
+	bfin_spi_cs_enable(drv_data, chip);
 	bfin_spi_cs_deactive(drv_data, chip);
 	ret = 0;
 
@@ -1377,14 +1391,17 @@
 static void bfin_spi_cleanup(struct spi_device *spi)
 {
 	struct chip_data *chip = spi_get_ctldata(spi);
+	struct driver_data *drv_data = spi_master_get_devdata(spi->master);
 
 	if (!chip)
 		return;
 
 	if ((chip->chip_select_num > 0)
-		&& (chip->chip_select_num <= spi->master->num_chipselect))
+		&& (chip->chip_select_num <= spi->master->num_chipselect)) {
 		peripheral_free(ssel[spi->master->bus_num]
 					[chip->chip_select_num-1]);
+		bfin_spi_cs_disable(drv_data, chip);
+	}
 
 	if (chip->chip_select_num == 0)
 		gpio_free(chip->cs_gpio);
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to