linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing
@ 2007-10-30  9:17 Bryan Wu
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA

 - BF54x supported
 - multi-port supported
 - bunch of bug fixing 


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH 01/14] Blackfin SPI driver: Initial supporting BF54x in SPI driver
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:17   ` [PATCH 02/14] Blackfin SPI driver: use new GPIO API and add error handling Bryan Wu
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA

 - support BF54x SPI0
 - clean up some code
 - will support multiports in the future

Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c                       |  129 +++++++++++------------
 include/asm-blackfin/mach-bf548/defBF54x_base.h |   17 +++
 2 files changed, 80 insertions(+), 66 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 2ef11bb..621a3eb 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1,17 +1,20 @@
 /*
- * File:         drivers/spi/bfin5xx_spi.c
- * Based on:     N/A
- * Author:       Luke Yang (Analog Devices Inc.)
+ * File:	drivers/spi/bfin5xx_spi.c
+ * Maintainer:
+ * 		Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
+ * Original Author:
+ * 		Luke Yang (Analog Devices Inc.)
  *
- * Created:      March. 10th 2006
- * Description:  SPI controller driver for Blackfin 5xx
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ * Created:	March. 10th 2006
+ * Description:	SPI controller driver for Blackfin BF5xx
+ * Bugs:	Enter bugs at http://blackfin.uclinux.org/
  *
  * Modified:
  *	March 10, 2006  bfin5xx_spi.c Created. (Luke Yang)
  *      August 7, 2006  added full duplex mode (Axel Weiss & Luke Yang)
+ *      July  17, 2007  add support for BF54x SPI0 controller (Bryan Wu)
  *
- * Copyright 2004-2006 Analog Devices Inc.
+ * Copyright 2004-2007 Analog Devices Inc.
  *
  * This program is free software ;  you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,27 +34,27 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
+#include <linux/irq.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/spi/spi.h>
 #include <linux/workqueue.h>
-#include <linux/delay.h>
 
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/delay.h>
 #include <asm/dma.h>
-
+#include <asm/portmux.h>
 #include <asm/bfin5xx_spi.h>
 
-MODULE_AUTHOR("Luke Yang");
-MODULE_DESCRIPTION("Blackfin 5xx SPI Contoller");
+MODULE_AUTHOR("Bryan Wu, Luke Yang");
+MODULE_DESCRIPTION("Blackfin BF5xx SPI Contoller Driver");
 MODULE_LICENSE("GPL");
 
+#define DRV_NAME	"bfin-spi-master"
 #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
 
 #define DEFINE_SPI_REG(reg, off) \
@@ -124,6 +127,7 @@ struct chip_data {
 	u16 flag;
 
 	u8 chip_select_num;
+	u8 chip_select_requested;
 	u8 n_bytes;
 	u8 width;		/* 0 or 1 */
 	u8 enable_dma;
@@ -188,53 +192,37 @@ static void restore_state(struct driver_data *drv_data)
 	bfin_spi_disable(drv_data);
 	dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");
 
-#if defined(CONFIG_BF534) || defined(CONFIG_BF536) || defined(CONFIG_BF537)
-	dev_dbg(&drv_data->pdev->dev, 
-		"chip select number is %d\n", chip->chip_select_num);
-	
-	switch (chip->chip_select_num) {
-	case 1:
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3c00);
-		SSYNC();
-		break;
-
-	case 2:
-	case 3:
-		bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJSE_SPI);
-		SSYNC();
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800);
-		SSYNC();
-		break;
-
-	case 4:
-		bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS4E_SPI);
-		SSYNC();
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3840);
-		SSYNC();
-		break;
+	if (!chip->chip_select_requested) {
 
-	case 5:
-		bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS5E_SPI);
-		SSYNC();
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3820);
-		SSYNC();
-		break;
+		dev_dbg(&drv_data->pdev->dev,
+		"chip select number is %d\n", chip->chip_select_num);
 
-	case 6:
-		bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS6E_SPI);
-		SSYNC();
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3810);
-		SSYNC();
-		break;
+		switch (chip->chip_select_num) {
+		case 1:
+			peripheral_request(P_SPI0_SSEL1, DRV_NAME);
+			break;
+		case 2:
+			peripheral_request(P_SPI0_SSEL2, DRV_NAME);
+			break;
+		case 3:
+			peripheral_request(P_SPI0_SSEL3, DRV_NAME);
+			break;
+		case 4:
+			peripheral_request(P_SPI0_SSEL4, DRV_NAME);
+			break;
+		case 5:
+			peripheral_request(P_SPI0_SSEL5, DRV_NAME);
+			break;
+		case 6:
+			peripheral_request(P_SPI0_SSEL6, DRV_NAME);
+			break;
+		case 7:
+			peripheral_request(P_SPI0_SSEL7, DRV_NAME);
+			break;
+		}
 
-	case 7:
-		bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJCE_SPI);
-		SSYNC();
-		bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800);
-		SSYNC();
-		break;
+		chip->chip_select_requested = 1;
 	}
-#endif
 
 	/* Load the registers */
 	write_CTRL(chip->ctl_reg);
@@ -277,7 +265,7 @@ static void null_reader(struct driver_data *drv_data)
 
 static void u8_writer(struct driver_data *drv_data)
 {
-	dev_dbg(&drv_data->pdev->dev, 
+	dev_dbg(&drv_data->pdev->dev,
 		"cr8-s is 0x%x\n", read_STAT());
 	while (drv_data->tx < drv_data->tx_end) {
 		write_TDBR(*(u8 *) (drv_data->tx));
@@ -316,7 +304,7 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 
 static void u8_reader(struct driver_data *drv_data)
 {
-	dev_dbg(&drv_data->pdev->dev, 
+	dev_dbg(&drv_data->pdev->dev,
 		"cr-8 is 0x%x\n", read_STAT());
 
 	/* clear TDBR buffer before read(else it will be shifted out) */
@@ -403,7 +391,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 
 static void u16_writer(struct driver_data *drv_data)
 {
-	dev_dbg(&drv_data->pdev->dev, 
+	dev_dbg(&drv_data->pdev->dev,
 		"cr16 is 0x%x\n", read_STAT());
 
 	while (drv_data->tx < drv_data->tx_end) {
@@ -816,7 +804,7 @@ static void pump_transfers(unsigned long data)
 			/* full duplex mode */
 			BUG_ON((drv_data->tx_end - drv_data->tx) !=
 			       (drv_data->rx_end - drv_data->rx));
-			cr = (read_CTRL() & (~BIT_CTL_TIMOD));	
+			cr = (read_CTRL() & (~BIT_CTL_TIMOD));
 			cr |= CFG_SPI_WRITE | (width << 8) |
 				(CFG_SPI_ENABLE << 14);
 			dev_dbg(&drv_data->pdev->dev,
@@ -834,7 +822,7 @@ static void pump_transfers(unsigned long data)
 			cr = (read_CTRL() & (~BIT_CTL_TIMOD));
 			cr |= CFG_SPI_WRITE | (width << 8) |
 				(CFG_SPI_ENABLE << 14);
-			dev_dbg(&drv_data->pdev->dev, 
+			dev_dbg(&drv_data->pdev->dev,
 				"IO write: cr is 0x%x\n", cr);
 
 			write_CTRL(cr);
@@ -849,7 +837,7 @@ static void pump_transfers(unsigned long data)
 			cr = (read_CTRL() & (~BIT_CTL_TIMOD));
 			cr |= CFG_SPI_READ | (width << 8) |
 				(CFG_SPI_ENABLE << 14);
-			dev_dbg(&drv_data->pdev->dev, 
+			dev_dbg(&drv_data->pdev->dev,
 				"IO read: cr is 0x%x\n", cr);
 
 			write_CTRL(cr);
@@ -861,7 +849,7 @@ static void pump_transfers(unsigned long data)
 		}
 
 		if (!tranf_success) {
-			dev_dbg(&drv_data->pdev->dev, 
+			dev_dbg(&drv_data->pdev->dev,
 				"IO write error!\n");
 			message->state = ERROR_STATE;
 		} else {
@@ -916,8 +904,8 @@ static void pump_messages(struct work_struct *work)
 		"got a message to pump, state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
    		drv_data->cur_chip->baud, drv_data->cur_chip->flag,
    		drv_data->cur_chip->ctl_reg);
-	
-	dev_dbg(&drv_data->pdev->dev, 
+
+	dev_dbg(&drv_data->pdev->dev,
 		"the first transfer len is %d\n",
 		drv_data->cur_transfer->len);
 
@@ -1193,6 +1181,15 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "can not alloc spi_master\n");
 		return -ENOMEM;
 	}
+
+	if (peripheral_request(P_SPI0_SCK, DRV_NAME) ||
+		 peripheral_request(P_SPI0_MISO, DRV_NAME) ||
+		 peripheral_request(P_SPI0_MOSI, DRV_NAME) ) {
+
+		dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
+		goto out_error_queue_alloc;
+	}
+
 	drv_data = spi_master_get_devdata(master);
 	drv_data->master = master;
 	drv_data->master_info = platform_info;
diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h
index da979cb..319a485 100644
--- a/include/asm-blackfin/mach-bf548/defBF54x_base.h
+++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h
@@ -1644,8 +1644,25 @@
 #define                   RESTART  0x20       /* Work Unit Transitions */
 #define                    DI_SEL  0x40       /* Data Interrupt Timing Select */
 #define                     DI_EN  0x80       /* Data Interrupt Enable */
+
 #define                    NDSIZE  0xf00      /* Flex Descriptor Size */
+#define                  NDSIZE_0 0x0000      /* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define                  NDSIZE_1 0x0100      /* Next Descriptor Size = 1 */
+#define                  NDSIZE_2 0x0200      /* Next Descriptor Size = 2 */
+#define                  NDSIZE_3 0x0300      /* Next Descriptor Size = 3 */
+#define                  NDSIZE_4 0x0400      /* Next Descriptor Size = 4 */
+#define                  NDSIZE_5 0x0500      /* Next Descriptor Size = 5 */
+#define                  NDSIZE_6 0x0600      /* Next Descriptor Size = 6 */
+#define                  NDSIZE_7 0x0700      /* Next Descriptor Size = 7 */
+#define                  NDSIZE_8 0x0800      /* Next Descriptor Size = 8 */
+#define                  NDSIZE_9 0x0900      /* Next Descriptor Size = 9 */
+
 #define                   DMAFLOW  0xf000     /* Next Operation */
+#define              DMAFLOW_STOP  0x0000     /* Stop Mode */
+#define              DMAFLOW_AUTO  0x1000     /* Autobuffer Mode */
+#define             DMAFLOW_ARRAY  0x4000     /* Descriptor Array Mode */
+#define             DMAFLOW_SMALL  0x6000     /* Small Model Descriptor List Mode */
+#define             DMAFLOW_LARGE  0x7000     /* Large Model Descriptor List Mode */
 
 /* Bit masks for DMAx_IRQ_STATUS, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
 
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 02/14] Blackfin SPI driver: use new GPIO API and add error handling
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
  2007-10-30  9:17   ` [PATCH 01/14] Blackfin SPI driver: Initial supporting BF54x in SPI driver Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:17   ` [PATCH 03/14] Blackfin SPI driver: add error handing Bryan Wu
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Michael Hennerich

From: Michael Hennerich <michael.hennerich-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Michael Hennerich <michael.hennerich-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c                 |   29 +++++++++++++++++++++++------
 include/asm-blackfin/mach-bf533/portmux.h |    2 +-
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 621a3eb..eeaa65d 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1165,6 +1165,22 @@ static inline int destroy_queue(struct driver_data *drv_data)
 	return 0;
 }
 
+static int setup_pin_mux(int action)
+{
+
+	u16 pin_req[] = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0};
+
+	if (action) {
+		if (peripheral_request_list(pin_req, DRV_NAME)) {
+			return -EFAULT;
+		}
+	} else {
+		peripheral_free_list(pin_req);
+	}
+
+	return 0;
+}
+
 static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1182,12 +1198,9 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	if (peripheral_request(P_SPI0_SCK, DRV_NAME) ||
-		 peripheral_request(P_SPI0_MISO, DRV_NAME) ||
-		 peripheral_request(P_SPI0_MOSI, DRV_NAME) ) {
-
+	if (setup_pin_mux(1)) {
 		dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
-		goto out_error_queue_alloc;
+		goto out_error;
 	}
 
 	drv_data = spi_master_get_devdata(master);
@@ -1223,9 +1236,11 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "controller probe successfully\n");
 	return status;
 
-      out_error_queue_alloc:
+out_error_queue_alloc:
 	destroy_queue(drv_data);
+out_error:
 	spi_master_put(master);
+
 	return status;
 }
 
@@ -1255,6 +1270,8 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
 	/* Disconnect from the SPI framework */
 	spi_unregister_master(drv_data->master);
 
+	setup_pin_mux(0);
+
 	/* Prevent double remove */
 	platform_set_drvdata(pdev, NULL);
 
diff --git a/include/asm-blackfin/mach-bf533/portmux.h b/include/asm-blackfin/mach-bf533/portmux.h
index b88d7a0..137f488 100644
--- a/include/asm-blackfin/mach-bf533/portmux.h
+++ b/include/asm-blackfin/mach-bf533/portmux.h
@@ -42,7 +42,7 @@
 #define P_SPORT0_DRPRI	(P_DONTCARE)
 
 #define P_SPI0_MOSI	(P_DONTCARE)
-#define P_SPI0_MIS0	(P_DONTCARE)
+#define P_SPI0_MISO	(P_DONTCARE)
 #define P_SPI0_SCK	(P_DONTCARE)
 #define P_SPI0_SSEL7	(P_DEFINED | P_IDENT(GPIO_PF7))
 #define P_SPI0_SSEL6	(P_DEFINED | P_IDENT(GPIO_PF6))
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 03/14] Blackfin SPI driver: add error handing
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
  2007-10-30  9:17   ` [PATCH 01/14] Blackfin SPI driver: Initial supporting BF54x in SPI driver Bryan Wu
  2007-10-30  9:17   ` [PATCH 02/14] Blackfin SPI driver: use new GPIO API and add error handling Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:17   ` [PATCH 04/14] Blackfin SPI driver: Blackfin SPI driver does not respect the per-transfer cs_change field Bryan Wu
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Michael Hennerich

 - add error handling in SPI bus driver with selecting clients
 - use proper defines to access Blackfin MMRs
 - remove useless SSYNCs

Signed-off-by: Michael Hennerich <michael.hennerich-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |  107 +++++++++++++++++++--------------------------
 1 files changed, 45 insertions(+), 62 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index eeaa65d..49f4eac 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -59,10 +59,9 @@ MODULE_LICENSE("GPL");
 
 #define DEFINE_SPI_REG(reg, off) \
 static inline u16 read_##reg(void) \
-            { return *(volatile unsigned short*)(SPI0_REGBASE + off); } \
+	{ return bfin_read16(SPI0_REGBASE + off); } \
 static inline void write_##reg(u16 v) \
-            {*(volatile unsigned short*)(SPI0_REGBASE + off) = v;\
-             SSYNC();}
+	{bfin_write16(SPI0_REGBASE + off, v); }
 
 DEFINE_SPI_REG(CTRL, 0x00)
 DEFINE_SPI_REG(FLAG, 0x04)
@@ -145,7 +144,6 @@ static void bfin_spi_enable(struct driver_data *drv_data)
 
 	cr = read_CTRL();
 	write_CTRL(cr | BIT_CTL_ENABLE);
-	SSYNC();
 }
 
 static void bfin_spi_disable(struct driver_data *drv_data)
@@ -154,7 +152,6 @@ static void bfin_spi_disable(struct driver_data *drv_data)
 
 	cr = read_CTRL();
 	write_CTRL(cr & (~BIT_CTL_ENABLE));
-	SSYNC();
 }
 
 /* Caculate the SPI_BAUD register value based on input HZ */
@@ -182,52 +179,44 @@ static int flush(struct driver_data *drv_data)
 	return limit;
 }
 
+#define MAX_SPI0_SSEL	7
+
 /* stop controller and re-config current chip*/
-static void restore_state(struct driver_data *drv_data)
+static int restore_state(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
+	int ret = 0;
+	u16 ssel[MAX_SPI0_SSEL] = {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
+					P_SPI0_SSEL4, P_SPI0_SSEL5,
+					P_SPI0_SSEL6, P_SPI0_SSEL7,};
 
 	/* Clear status and disable clock */
 	write_STAT(BIT_STAT_CLR);
 	bfin_spi_disable(drv_data);
 	dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");
 
+	/* Load the registers */
+	write_CTRL(chip->ctl_reg);
+	write_BAUD(chip->baud);
+	write_FLAG(chip->flag);
+
 	if (!chip->chip_select_requested) {
+		int i = chip->chip_select_num;
 
-		dev_dbg(&drv_data->pdev->dev,
-		"chip select number is %d\n", chip->chip_select_num);
-
-		switch (chip->chip_select_num) {
-		case 1:
-			peripheral_request(P_SPI0_SSEL1, DRV_NAME);
-			break;
-		case 2:
-			peripheral_request(P_SPI0_SSEL2, DRV_NAME);
-			break;
-		case 3:
-			peripheral_request(P_SPI0_SSEL3, DRV_NAME);
-			break;
-		case 4:
-			peripheral_request(P_SPI0_SSEL4, DRV_NAME);
-			break;
-		case 5:
-			peripheral_request(P_SPI0_SSEL5, DRV_NAME);
-			break;
-		case 6:
-			peripheral_request(P_SPI0_SSEL6, DRV_NAME);
-			break;
-		case 7:
-			peripheral_request(P_SPI0_SSEL7, DRV_NAME);
-			break;
-		}
+		dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
+
+		if ((i > 0) && (i <= MAX_SPI0_SSEL))
+			ret = peripheral_request(ssel[i-1], DRV_NAME);
 
 		chip->chip_select_requested = 1;
 	}
 
-	/* Load the registers */
-	write_CTRL(chip->ctl_reg);
-	write_BAUD(chip->baud);
-	write_FLAG(chip->flag);
+	if (ret)
+		dev_dbg(&drv_data->pdev->dev,
+			": request chip select number %d failed\n",
+			chip->chip_select_num);
+
+	return ret;
 }
 
 /* used to kick off transfer in rx mode */
@@ -285,7 +274,6 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 
 	while (drv_data->tx < drv_data->tx_end) {
 		write_FLAG(chip->flag);
-		SSYNC();
 
 		write_TDBR(*(u8 *) (drv_data->tx));
 		while (read_STAT() & BIT_STAT_TXS)
@@ -293,13 +281,13 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 		while (!(read_STAT() & BIT_STAT_SPIF))
 			continue;
 		write_FLAG(0xFF00 | chip->flag);
-		SSYNC();
+
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->tx;
 	}
 	write_FLAG(0xFF00);
-	SSYNC();
+
 }
 
 static void u8_reader(struct driver_data *drv_data)
@@ -331,7 +319,6 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 
 	while (drv_data->rx < drv_data->rx_end) {
 		write_FLAG(chip->flag);
-		SSYNC();
 
 		read_RDBR();	/* kick off */
 		while (!(read_STAT() & BIT_STAT_RXS))
@@ -340,13 +327,13 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 			continue;
 		*(u8 *) (drv_data->rx) = read_SHAW();
 		write_FLAG(0xFF00 | chip->flag);
-		SSYNC();
+
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->rx;
 	}
 	write_FLAG(0xFF00);
-	SSYNC();
+
 }
 
 static void u8_duplex(struct driver_data *drv_data)
@@ -370,7 +357,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 
 	while (drv_data->rx < drv_data->rx_end) {
 		write_FLAG(chip->flag);
-		SSYNC();
+
 
 		write_TDBR(*(u8 *) (drv_data->tx));
 		while (!(read_STAT() & BIT_STAT_SPIF))
@@ -379,14 +366,14 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 			continue;
 		*(u8 *) (drv_data->rx) = read_RDBR();
 		write_FLAG(0xFF00 | chip->flag);
-		SSYNC();
+
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->rx;
 		++drv_data->tx;
 	}
 	write_FLAG(0xFF00);
-	SSYNC();
+
 }
 
 static void u16_writer(struct driver_data *drv_data)
@@ -412,7 +399,6 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 
 	while (drv_data->tx < drv_data->tx_end) {
 		write_FLAG(chip->flag);
-		SSYNC();
 
 		write_TDBR(*(u16 *) (drv_data->tx));
 		while ((read_STAT() & BIT_STAT_TXS))
@@ -420,13 +406,12 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 		while (!(read_STAT() & BIT_STAT_SPIF))
 			continue;
 		write_FLAG(0xFF00 | chip->flag);
-		SSYNC();
+
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->tx += 2;
 	}
 	write_FLAG(0xFF00);
-	SSYNC();
 }
 
 static void u16_reader(struct driver_data *drv_data)
@@ -454,7 +439,6 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 
 	while (drv_data->rx < drv_data->rx_end) {
 		write_FLAG(chip->flag);
-		SSYNC();
 
 		read_RDBR();	/* kick off */
 		while (!(read_STAT() & BIT_STAT_RXS))
@@ -463,13 +447,12 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 			continue;
 		*(u16 *) (drv_data->rx) = read_SHAW();
 		write_FLAG(0xFF00 | chip->flag);
-		SSYNC();
+
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->rx += 2;
 	}
 	write_FLAG(0xFF00);
-	SSYNC();
 }
 
 static void u16_duplex(struct driver_data *drv_data)
@@ -493,7 +476,6 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 
 	while (drv_data->tx < drv_data->tx_end) {
 		write_FLAG(chip->flag);
-		SSYNC();
 
 		write_TDBR(*(u16 *) (drv_data->tx));
 		while (!(read_STAT() & BIT_STAT_SPIF))
@@ -502,14 +484,13 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 			continue;
 		*(u16 *) (drv_data->rx) = read_RDBR();
 		write_FLAG(0xFF00 | chip->flag);
-		SSYNC();
+
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
 	write_FLAG(0xFF00);
-	SSYNC();
 }
 
 /* test if ther is more transfer to be done */
@@ -811,7 +792,6 @@ static void pump_transfers(unsigned long data)
 				"IO duplex: cr is 0x%x\n", cr);
 
 			write_CTRL(cr);
-			SSYNC();
 
 			drv_data->duplex(drv_data);
 
@@ -826,7 +806,6 @@ static void pump_transfers(unsigned long data)
 				"IO write: cr is 0x%x\n", cr);
 
 			write_CTRL(cr);
-			SSYNC();
 
 			drv_data->write(drv_data);
 
@@ -841,7 +820,6 @@ static void pump_transfers(unsigned long data)
 				"IO read: cr is 0x%x\n", cr);
 
 			write_CTRL(cr);
-			SSYNC();
 
 			drv_data->read(drv_data);
 			if (drv_data->rx != drv_data->rx_end)
@@ -890,6 +868,14 @@ static void pump_messages(struct work_struct *work)
 	/* Extract head of queue */
 	drv_data->cur_msg = list_entry(drv_data->queue.next,
 				       struct spi_message, queue);
+
+	/* Setup the SSP using the per chip configuration */
+	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
+	if (restore_state(drv_data)) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return;
+	};
+
 	list_del_init(&drv_data->cur_msg->queue);
 
 	/* Initial message state */
@@ -897,13 +883,10 @@ static void pump_messages(struct work_struct *work)
 	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
 					    struct spi_transfer, transfer_list);
 
-	/* Setup the SSP using the per chip configuration */
-	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
-	restore_state(drv_data);
 	dev_dbg(&drv_data->pdev->dev,
 		"got a message to pump, state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
-   		drv_data->cur_chip->baud, drv_data->cur_chip->flag,
-   		drv_data->cur_chip->ctl_reg);
+		drv_data->cur_chip->baud, drv_data->cur_chip->flag,
+		drv_data->cur_chip->ctl_reg);
 
 	dev_dbg(&drv_data->pdev->dev,
 		"the first transfer len is %d\n",
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 04/14] Blackfin SPI driver: Blackfin SPI driver does not respect the per-transfer cs_change field
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (2 preceding siblings ...)
  2007-10-30  9:17   ` [PATCH 03/14] Blackfin SPI driver: add error handing Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:17   ` [PATCH 05/14] Blackfin SPI driver: prevent people from setting bits in ctl_reg Bryan Wu
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA

Add cs_active/cs_deactive functions and try to catch the cs_change flag.

Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |   76 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 49f4eac..1a55aa7 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -115,6 +115,7 @@ struct driver_data {
 	size_t rx_map_len;
 	size_t tx_map_len;
 	u8 n_bytes;
+	int cs_change;
 	void (*write) (struct driver_data *);
 	void (*read) (struct driver_data *);
 	void (*duplex) (struct driver_data *);
@@ -179,6 +180,26 @@ static int flush(struct driver_data *drv_data)
 	return limit;
 }
 
+/* Chip select operation functions for cs_change flag */
+static void cs_active(struct chip_data *chip)
+{
+	u16 flag = read_FLAG();
+
+	flag |= chip->flag;
+	flag &= ~(chip->flag << 8);
+
+	write_FLAG(flag);
+}
+
+static void cs_deactive(struct chip_data *chip)
+{
+	u16 flag = read_FLAG();
+
+	flag |= (chip->flag << 8);
+
+	write_FLAG(flag);
+}
+
 #define MAX_SPI0_SSEL	7
 
 /* stop controller and re-config current chip*/
@@ -198,7 +219,7 @@ static int restore_state(struct driver_data *drv_data)
 	/* Load the registers */
 	write_CTRL(chip->ctl_reg);
 	write_BAUD(chip->baud);
-	write_FLAG(chip->flag);
+	cs_active(chip);
 
 	if (!chip->chip_select_requested) {
 		int i = chip->chip_select_num;
@@ -273,20 +294,20 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		write_FLAG(chip->flag);
+		cs_active(chip);
 
 		write_TDBR(*(u8 *) (drv_data->tx));
 		while (read_STAT() & BIT_STAT_TXS)
 			continue;
 		while (!(read_STAT() & BIT_STAT_SPIF))
 			continue;
-		write_FLAG(0xFF00 | chip->flag);
+		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->tx;
 	}
-	write_FLAG(0xFF00);
+	cs_deactive(chip);
 
 }
 
@@ -318,7 +339,7 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	while (drv_data->rx < drv_data->rx_end) {
-		write_FLAG(chip->flag);
+		cs_active(chip);
 
 		read_RDBR();	/* kick off */
 		while (!(read_STAT() & BIT_STAT_RXS))
@@ -326,13 +347,13 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 		while (!(read_STAT() & BIT_STAT_SPIF))
 			continue;
 		*(u8 *) (drv_data->rx) = read_SHAW();
-		write_FLAG(0xFF00 | chip->flag);
+		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->rx;
 	}
-	write_FLAG(0xFF00);
+	cs_deactive(chip);
 
 }
 
@@ -356,7 +377,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	while (drv_data->rx < drv_data->rx_end) {
-		write_FLAG(chip->flag);
+		cs_active(chip);
 
 
 		write_TDBR(*(u8 *) (drv_data->tx));
@@ -365,15 +386,14 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
 		*(u8 *) (drv_data->rx) = read_RDBR();
-		write_FLAG(0xFF00 | chip->flag);
+		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->rx;
 		++drv_data->tx;
 	}
-	write_FLAG(0xFF00);
-
+	cs_deactive(chip);
 }
 
 static void u16_writer(struct driver_data *drv_data)
@@ -398,20 +418,20 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		write_FLAG(chip->flag);
+		cs_active(chip);
 
 		write_TDBR(*(u16 *) (drv_data->tx));
 		while ((read_STAT() & BIT_STAT_TXS))
 			continue;
 		while (!(read_STAT() & BIT_STAT_SPIF))
 			continue;
-		write_FLAG(0xFF00 | chip->flag);
+		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->tx += 2;
 	}
-	write_FLAG(0xFF00);
+	cs_deactive(chip);
 }
 
 static void u16_reader(struct driver_data *drv_data)
@@ -438,7 +458,7 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	while (drv_data->rx < drv_data->rx_end) {
-		write_FLAG(chip->flag);
+		cs_active(chip);
 
 		read_RDBR();	/* kick off */
 		while (!(read_STAT() & BIT_STAT_RXS))
@@ -446,13 +466,13 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 		while (!(read_STAT() & BIT_STAT_SPIF))
 			continue;
 		*(u16 *) (drv_data->rx) = read_SHAW();
-		write_FLAG(0xFF00 | chip->flag);
+		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->rx += 2;
 	}
-	write_FLAG(0xFF00);
+	cs_deactive(chip);
 }
 
 static void u16_duplex(struct driver_data *drv_data)
@@ -475,7 +495,7 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		write_FLAG(chip->flag);
+		cs_active(chip);
 
 		write_TDBR(*(u16 *) (drv_data->tx));
 		while (!(read_STAT() & BIT_STAT_SPIF))
@@ -483,14 +503,14 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
 		*(u16 *) (drv_data->rx) = read_RDBR();
-		write_FLAG(0xFF00 | chip->flag);
+		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
-	write_FLAG(0xFF00);
+	cs_deactive(chip);
 }
 
 /* test if ther is more transfer to be done */
@@ -515,6 +535,7 @@ static void *next_transfer(struct driver_data *drv_data)
  */
 static void giveback(struct driver_data *drv_data)
 {
+	struct chip_data *chip = drv_data->cur_chip;
 	struct spi_transfer *last_transfer;
 	unsigned long flags;
 	struct spi_message *msg;
@@ -534,10 +555,13 @@ static void giveback(struct driver_data *drv_data)
 
 	/* disable chip select signal. And not stop spi in autobuffer mode */
 	if (drv_data->tx_dma != 0xFFFF) {
-		write_FLAG(0xFF00);
+		cs_deactive(chip);
 		bfin_spi_disable(drv_data);
 	}
 
+	if (!drv_data->cs_change)
+		cs_deactive(chip);
+
 	if (msg->complete)
 		msg->complete(msg->context);
 }
@@ -546,6 +570,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
 	struct driver_data *drv_data = (struct driver_data *)dev_id;
 	struct spi_message *msg = drv_data->cur_msg;
+	struct chip_data *chip = drv_data->cur_chip;
 
 	dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
 	clear_dma_irqstat(CH_SPI);
@@ -573,6 +598,9 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 
 	msg->actual_length += drv_data->len_in_bytes;
 
+	if (drv_data->cs_change)
+		cs_deactive(chip);
+
 	/* Move to next transfer */
 	msg->state = next_transfer(drv_data);
 
@@ -659,6 +687,7 @@ static void pump_transfers(unsigned long data)
 	drv_data->rx_dma = transfer->rx_dma;
 	drv_data->tx_dma = transfer->tx_dma;
 	drv_data->len_in_bytes = transfer->len;
+	drv_data->cs_change = transfer->cs_change;
 
 	width = chip->width;
 	if (width == CFG_SPI_WORDSIZE16) {
@@ -683,7 +712,7 @@ static void pump_transfers(unsigned long data)
 	} else {
 		write_BAUD(chip->baud);
 	}
-	write_FLAG(chip->flag);
+	cs_active(chip);
 
 	dev_dbg(&drv_data->pdev->dev,
 		"now pumping a transfer: width is %d, len is %d\n",
@@ -834,6 +863,9 @@ static void pump_transfers(unsigned long data)
 			/* Update total byte transfered */
 			message->actual_length += drv_data->len;
 
+			if (drv_data->cs_change)
+				cs_deactive(chip);
+
 			/* Move to next transfer of this msg */
 			message->state = next_transfer(drv_data);
 		}
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 05/14] Blackfin SPI driver: prevent people from setting bits in ctl_reg
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (3 preceding siblings ...)
  2007-10-30  9:17   ` [PATCH 04/14] Blackfin SPI driver: Blackfin SPI driver does not respect the per-transfer cs_change field Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:17   ` [PATCH 06/14] Blackfin SPI driver: update spi driver to support multi-ports Bryan Wu
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, Mike Frysinger, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Mike Frysinger <michael.frysinger-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Prevent people from setting bits in ctl_reg that the SPI
framework already handles, hopefully we can one day drop
ctl_reg completely

Signed-off-by: Mike Frysinger <michael.frysinger-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 1a55aa7..e4d64a0 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -996,6 +996,16 @@ static int setup(struct spi_device *spi)
 
 	/* chip_info isn't always needed */
 	if (chip_info) {
+		/* Make sure people stop trying to set fields via ctl_reg when they
+		 * should actually be using common SPI framework.  Currently we let
+		 * through: WOM EMISO PSSE GM SZ TIMOD.  Not sure if a user actually
+		 * needs/uses any of these, but let's assume (for now) they do.
+		 */
+		if (chip_info->ctl_reg & (SPE | MSTR | CPOL | CPHA | LSBF | SIZE)) {
+			dev_err(&spi->dev, "do not set bits in ctl_reg that the SPI framework provides\n");
+			return -EINVAL;
+		}
+
 		chip->enable_dma = chip_info->enable_dma != 0
 		    && drv_data->master_info->enable_dma;
 		chip->ctl_reg = chip_info->ctl_reg;
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 06/14] Blackfin SPI driver: update spi driver to support multi-ports
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (4 preceding siblings ...)
  2007-10-30  9:17   ` [PATCH 05/14] Blackfin SPI driver: prevent people from setting bits in ctl_reg Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:17   ` [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1 Bryan Wu
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA

update spi driver to support multi-ports by add platform_resource,
tested on STAMP537+SPI_MMC, other boards need more testing

Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |  124 ++++++++++++++++++++++++++++++---------------
 1 files changed, 83 insertions(+), 41 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index e4d64a0..3f3630c 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -13,6 +13,8 @@
  *	March 10, 2006  bfin5xx_spi.c Created. (Luke Yang)
  *      August 7, 2006  added full duplex mode (Axel Weiss & Luke Yang)
  *      July  17, 2007  add support for BF54x SPI0 controller (Bryan Wu)
+ *      July  30, 2007  add platfrom_resource interface to support multi-port
+ *                      SPI controller (Bryan Wu)
  *
  * Copyright 2004-2007 Analog Devices Inc.
  *
@@ -50,18 +52,25 @@
 #include <asm/portmux.h>
 #include <asm/bfin5xx_spi.h>
 
-MODULE_AUTHOR("Bryan Wu, Luke Yang");
-MODULE_DESCRIPTION("Blackfin BF5xx SPI Contoller Driver");
+#define DRV_NAME	"bfin-spi"
+#define DRV_AUTHOR	"Bryan Wu, Luke Yang"
+#define DRV_DESC	"Blackfin BF5xx on-chip SPI Contoller Driver"
+#define DRV_VERSION	"1.0"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
 MODULE_LICENSE("GPL");
 
-#define DRV_NAME	"bfin-spi-master"
 #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
 
+static u32 spi_dma_ch;
+static u32 spi_regs_base;
+
 #define DEFINE_SPI_REG(reg, off) \
 static inline u16 read_##reg(void) \
-	{ return bfin_read16(SPI0_REGBASE + off); } \
+	{ return bfin_read16(spi_regs_base + off); } \
 static inline void write_##reg(u16 v) \
-	{bfin_write16(SPI0_REGBASE + off, v); }
+	{bfin_write16(spi_regs_base + off, v); }
 
 DEFINE_SPI_REG(CTRL, 0x00)
 DEFINE_SPI_REG(FLAG, 0x04)
@@ -573,10 +582,10 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
-	clear_dma_irqstat(CH_SPI);
+	clear_dma_irqstat(spi_dma_ch);
 
 	/* Wait for DMA to complete */
-	while (get_dma_curr_irqstat(CH_SPI) & DMA_RUN)
+	while (get_dma_curr_irqstat(spi_dma_ch) & DMA_RUN)
 		continue;
 
 	/*
@@ -586,12 +595,12 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 	 * register until it goes low for 2 successive reads
 	 */
 	if (drv_data->tx != NULL) {
-		while ((bfin_read_SPI_STAT() & TXS) ||
-		       (bfin_read_SPI_STAT() & TXS))
+		while ((read_STAT() & TXS) ||
+		       (read_STAT() & TXS))
 			continue;
 	}
 
-	while (!(bfin_read_SPI_STAT() & SPIF))
+	while (!(read_STAT() & SPIF))
 		continue;
 
 	bfin_spi_disable(drv_data);
@@ -610,8 +619,8 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 	/* free the irq handler before next transfer */
 	dev_dbg(&drv_data->pdev->dev,
 		"disable dma channel irq%d\n",
-		CH_SPI);
-	dma_disable_irq(CH_SPI);
+		spi_dma_ch);
+	dma_disable_irq(spi_dma_ch);
 
 	return IRQ_HANDLED;
 }
@@ -726,19 +735,19 @@ static void pump_transfers(unsigned long data)
 	if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
 
 		write_STAT(BIT_STAT_CLR);
-		disable_dma(CH_SPI);
-		clear_dma_irqstat(CH_SPI);
+		disable_dma(spi_dma_ch);
+		clear_dma_irqstat(spi_dma_ch);
 		bfin_spi_disable(drv_data);
 
 		/* config dma channel */
 		dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
 		if (width == CFG_SPI_WORDSIZE16) {
-			set_dma_x_count(CH_SPI, drv_data->len);
-			set_dma_x_modify(CH_SPI, 2);
+			set_dma_x_count(spi_dma_ch, drv_data->len);
+			set_dma_x_modify(spi_dma_ch, 2);
 			dma_width = WDSIZE_16;
 		} else {
-			set_dma_x_count(CH_SPI, drv_data->len);
-			set_dma_x_modify(CH_SPI, 1);
+			set_dma_x_count(spi_dma_ch, drv_data->len);
+			set_dma_x_modify(spi_dma_ch, 1);
 			dma_width = WDSIZE_8;
 		}
 
@@ -753,9 +762,10 @@ static void pump_transfers(unsigned long data)
 			/* no irq in autobuffer mode */
 			dma_config =
 			    (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
-			set_dma_config(CH_SPI, dma_config);
-			set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx);
-			enable_dma(CH_SPI);
+			set_dma_config(spi_dma_ch, dma_config);
+			set_dma_start_addr(spi_dma_ch,
+					(unsigned long)drv_data->tx);
+			enable_dma(spi_dma_ch);
 			write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
 				   (CFG_SPI_ENABLE << 14));
 
@@ -776,14 +786,15 @@ static void pump_transfers(unsigned long data)
 			/* clear tx reg soformer data is not shifted out */
 			write_TDBR(0xFF);
 
-			set_dma_x_count(CH_SPI, drv_data->len);
+			set_dma_x_count(spi_dma_ch, drv_data->len);
 
 			/* start dma */
-			dma_enable_irq(CH_SPI);
+			dma_enable_irq(spi_dma_ch);
 			dma_config = (WNR | RESTART | dma_width | DI_EN);
-			set_dma_config(CH_SPI, dma_config);
-			set_dma_start_addr(CH_SPI, (unsigned long)drv_data->rx);
-			enable_dma(CH_SPI);
+			set_dma_config(spi_dma_ch, dma_config);
+			set_dma_start_addr(spi_dma_ch,
+					(unsigned long)drv_data->rx);
+			enable_dma(spi_dma_ch);
 
 			cr |=
 			    CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE <<
@@ -794,11 +805,12 @@ static void pump_transfers(unsigned long data)
 			dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
 
 			/* start dma */
-			dma_enable_irq(CH_SPI);
+			dma_enable_irq(spi_dma_ch);
 			dma_config = (RESTART | dma_width | DI_EN);
-			set_dma_config(CH_SPI, dma_config);
-			set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx);
-			enable_dma(CH_SPI);
+			set_dma_config(spi_dma_ch, dma_config);
+			set_dma_start_addr(spi_dma_ch,
+					(unsigned long)drv_data->tx);
+			enable_dma(spi_dma_ch);
 
 			write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
 				   (CFG_SPI_ENABLE << 14));
@@ -1030,17 +1042,17 @@ static int setup(struct spi_device *spi)
 	 */
 	if (chip->enable_dma && !dma_requested) {
 		/* register dma irq handler */
-		if (request_dma(CH_SPI, "BF53x_SPI_DMA") < 0) {
+		if (request_dma(spi_dma_ch, "BF53x_SPI_DMA") < 0) {
 			dev_dbg(&spi->dev,
 				"Unable to request BlackFin SPI DMA channel\n");
 			return -ENODEV;
 		}
-		if (set_dma_callback(CH_SPI, (void *)dma_irq_handler, drv_data)
-		    < 0) {
+		if (set_dma_callback(spi_dma_ch, (void *)dma_irq_handler,
+			drv_data) < 0) {
 			dev_dbg(&spi->dev, "Unable to set dma callback\n");
 			return -EPERM;
 		}
-		dma_disable_irq(CH_SPI);
+		dma_disable_irq(spi_dma_ch);
 		dma_requested = 1;
 	}
 
@@ -1212,6 +1224,7 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 	struct bfin5xx_spi_master *platform_info;
 	struct spi_master *master;
 	struct driver_data *drv_data = 0;
+	struct resource *res;
 	int status = 0;
 
 	platform_info = dev->platform_data;
@@ -1239,15 +1252,38 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 	master->setup = setup;
 	master->transfer = transfer;
 
+	/* Find and map our resources */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "Cannot get IORESOURCE_MEM\n");
+		status = -ENOENT;
+		goto out_error_get_res;
+	}
+
+	spi_regs_base = (u32) ioremap(res->start, (res->end - res->start)+1);
+	if (!spi_regs_base) {
+		dev_err(dev, "Cannot map IO\n");
+		status = -ENXIO;
+		goto out_error_ioremap;
+	}
+
+	spi_dma_ch = platform_get_irq(pdev, 0);
+	if (spi_dma_ch < 0) {
+		dev_err(dev, "No DMA channel specified\n");
+		status = -ENOENT;
+		goto out_error_no_dma_ch;
+	}
+
 	/* Initial and start queue */
 	status = init_queue(drv_data);
 	if (status != 0) {
-		dev_err(&pdev->dev, "problem initializing queue\n");
+		dev_err(dev, "problem initializing queue\n");
 		goto out_error_queue_alloc;
 	}
+
 	status = start_queue(drv_data);
 	if (status != 0) {
-		dev_err(&pdev->dev, "problem starting queue\n");
+		dev_err(dev, "problem starting queue\n");
 		goto out_error_queue_alloc;
 	}
 
@@ -1255,14 +1291,20 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, drv_data);
 	status = spi_register_master(master);
 	if (status != 0) {
-		dev_err(&pdev->dev, "problem registering spi master\n");
+		dev_err(dev, "problem registering spi master\n");
 		goto out_error_queue_alloc;
 	}
-	dev_dbg(&pdev->dev, "controller probe successfully\n");
+
+	dev_info(dev, "%s, Version %s, regs_base @ 0x%08x\n",
+		DRV_DESC, DRV_VERSION, spi_regs_base);
 	return status;
 
 out_error_queue_alloc:
 	destroy_queue(drv_data);
+out_error_no_dma_ch:
+	iounmap((void *) spi_regs_base);
+out_error_ioremap:
+out_error_get_res:
 out_error:
 	spi_master_put(master);
 
@@ -1288,8 +1330,8 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
 
 	/* Release DMA */
 	if (drv_data->master_info->enable_dma) {
-		if (dma_channel_active(CH_SPI))
-			free_dma(CH_SPI);
+		if (dma_channel_active(spi_dma_ch))
+			free_dma(spi_dma_ch);
 	}
 
 	/* Disconnect from the SPI framework */
@@ -1344,7 +1386,7 @@ static int bfin5xx_spi_resume(struct platform_device *pdev)
 MODULE_ALIAS("bfin-spi-master");	/* for platform bus hotplug */
 static struct platform_driver bfin5xx_spi_driver = {
 	.driver	= {
-		.name	= "bfin-spi-master",
+		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 	},
 	.suspend	= bfin5xx_spi_suspend,
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (5 preceding siblings ...)
  2007-10-30  9:17   ` [PATCH 06/14] Blackfin SPI driver: update spi driver to support multi-ports Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30 19:08     ` David Brownell
  2007-10-30  9:17   ` [PATCH 08/14] Blackfin SPI driver: Move GPIO config to setup and cleanup Bryan Wu
                     ` (7 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, Sonic Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |   52 ++++++++++++++++++++++++++------------------
 1 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 3f3630c..3bd8359 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -209,17 +209,26 @@ static void cs_deactive(struct chip_data *chip)
 	write_FLAG(flag);
 }
 
-#define MAX_SPI0_SSEL	7
+#define MAX_SPI_SSEL	7
 
 /* stop controller and re-config current chip*/
 static int restore_state(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 	int ret = 0;
-	u16 ssel[MAX_SPI0_SSEL] = {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
-					P_SPI0_SSEL4, P_SPI0_SSEL5,
-					P_SPI0_SSEL6, P_SPI0_SSEL7,};
-
+	u16 ssel[3][MAX_SPI_SSEL] = {
+		{P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
+		P_SPI0_SSEL4, P_SPI0_SSEL5,
+		P_SPI0_SSEL6, P_SPI0_SSEL7},
+
+		{P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3,
+		P_SPI1_SSEL4, P_SPI1_SSEL5,
+		P_SPI1_SSEL6, P_SPI1_SSEL7},
+
+		{P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3,
+		P_SPI2_SSEL4, P_SPI2_SSEL5,
+		P_SPI2_SSEL6, P_SPI2_SSEL7},
+	};
 	/* Clear status and disable clock */
 	write_STAT(BIT_STAT_CLR);
 	bfin_spi_disable(drv_data);
@@ -234,9 +243,9 @@ static int restore_state(struct driver_data *drv_data)
 		int i = chip->chip_select_num;
 
 		dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
-
-		if ((i > 0) && (i <= MAX_SPI0_SSEL))
-			ret = peripheral_request(ssel[i-1], DRV_NAME);
+		if ((i > 0) && (i <= MAX_SPI_SSEL))
+			ret = peripheral_request(
+				ssel[drv_data->master->bus_num][i-1], DRV_NAME);
 
 		chip->chip_select_requested = 1;
 	}
@@ -329,7 +338,6 @@ static void u8_reader(struct driver_data *drv_data)
 	write_TDBR(0xFFFF);
 
 	dummy_read();
-
 	while (drv_data->rx < drv_data->rx_end - 1) {
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
@@ -640,7 +648,6 @@ static void pump_transfers(unsigned long data)
 	message = drv_data->cur_msg;
 	transfer = drv_data->cur_transfer;
 	chip = drv_data->cur_chip;
-
 	/*
 	 * if msg is error or done, report it back using complete() callback
 	 */
@@ -1202,17 +1209,20 @@ static inline int destroy_queue(struct driver_data *drv_data)
 	return 0;
 }
 
-static int setup_pin_mux(int action)
+static int setup_pin_mux(int action, int bus_num)
 {
 
-	u16 pin_req[] = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0};
+	u16 pin_req[3][4] = {
+		{P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+		{P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
+		{P_SPI2_SCK, P_SPI2_MISO, P_SPI2_MOSI, 0},
+	};
 
 	if (action) {
-		if (peripheral_request_list(pin_req, DRV_NAME)) {
+		if (peripheral_request_list(pin_req[bus_num], DRV_NAME))
 			return -EFAULT;
-		}
 	} else {
-		peripheral_free_list(pin_req);
+		peripheral_free_list(pin_req[bus_num]);
 	}
 
 	return 0;
@@ -1236,11 +1246,6 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	if (setup_pin_mux(1)) {
-		dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
-		goto out_error;
-	}
-
 	drv_data = spi_master_get_devdata(master);
 	drv_data->master = master;
 	drv_data->master_info = platform_info;
@@ -1295,6 +1300,11 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 		goto out_error_queue_alloc;
 	}
 
+	if (setup_pin_mux(1, master->bus_num)) {
+		dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
+		goto out_error;
+	}
+
 	dev_info(dev, "%s, Version %s, regs_base @ 0x%08x\n",
 		DRV_DESC, DRV_VERSION, spi_regs_base);
 	return status;
@@ -1337,7 +1347,7 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
 	/* Disconnect from the SPI framework */
 	spi_unregister_master(drv_data->master);
 
-	setup_pin_mux(0);
+	setup_pin_mux(0, drv_data->master->bus_num);
 
 	/* Prevent double remove */
 	platform_set_drvdata(pdev, NULL);
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 08/14] Blackfin SPI driver: Move GPIO config to setup and cleanup
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (6 preceding siblings ...)
  2007-10-30  9:17   ` [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1 Bryan Wu
@ 2007-10-30  9:17   ` Bryan Wu
  2007-10-30  9:18   ` [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548 Bryan Wu
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:17 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, Sonic Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |   52 +++++++++++++++++++++++---------------------
 1 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 3bd8359..7f95797 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -136,7 +136,6 @@ struct chip_data {
 	u16 flag;
 
 	u8 chip_select_num;
-	u8 chip_select_requested;
 	u8 n_bytes;
 	u8 width;		/* 0 or 1 */
 	u8 enable_dma;
@@ -216,19 +215,7 @@ static int restore_state(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 	int ret = 0;
-	u16 ssel[3][MAX_SPI_SSEL] = {
-		{P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
-		P_SPI0_SSEL4, P_SPI0_SSEL5,
-		P_SPI0_SSEL6, P_SPI0_SSEL7},
-
-		{P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3,
-		P_SPI1_SSEL4, P_SPI1_SSEL5,
-		P_SPI1_SSEL6, P_SPI1_SSEL7},
-
-		{P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3,
-		P_SPI2_SSEL4, P_SPI2_SSEL5,
-		P_SPI2_SSEL6, P_SPI2_SSEL7},
-	};
+
 	/* Clear status and disable clock */
 	write_STAT(BIT_STAT_CLR);
 	bfin_spi_disable(drv_data);
@@ -239,17 +226,6 @@ static int restore_state(struct driver_data *drv_data)
 	write_BAUD(chip->baud);
 	cs_active(chip);
 
-	if (!chip->chip_select_requested) {
-		int i = chip->chip_select_num;
-
-		dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
-		if ((i > 0) && (i <= MAX_SPI_SSEL))
-			ret = peripheral_request(
-				ssel[drv_data->master->bus_num][i-1], DRV_NAME);
-
-		chip->chip_select_requested = 1;
-	}
-
 	if (ret)
 		dev_dbg(&drv_data->pdev->dev,
 			": request chip select number %d failed\n",
@@ -981,6 +957,22 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
 	return 0;
 }
 
+#define MAX_SPI_SSEL	7
+
+static u16 ssel[3][MAX_SPI_SSEL] = {
+	{P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
+	P_SPI0_SSEL4, P_SPI0_SSEL5,
+	P_SPI0_SSEL6, P_SPI0_SSEL7},
+
+	{P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3,
+	P_SPI1_SSEL4, P_SPI1_SSEL5,
+	P_SPI1_SSEL6, P_SPI1_SSEL7},
+
+	{P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3,
+	P_SPI2_SSEL4, P_SPI2_SSEL5,
+	P_SPI2_SSEL6, P_SPI2_SSEL7},
+};
+
 /* first setup for new devices */
 static int setup(struct spi_device *spi)
 {
@@ -1109,6 +1101,12 @@ static int setup(struct spi_device *spi)
 
 	spi_set_ctldata(spi, chip);
 
+	dev_dbg(&spi->dev, "chip select number is %d\n", chip->chip_select_num);
+	if ((chip->chip_select_num > 0)
+		&& (chip->chip_select_num <= spi->master->num_chipselect))
+		peripheral_request(ssel[spi->master->bus_num]
+			[chip->chip_select_num-1], DRV_NAME);
+
 	return 0;
 }
 
@@ -1120,6 +1118,10 @@ static void cleanup(struct spi_device *spi)
 {
 	struct chip_data *chip = spi_get_ctldata(spi);
 
+	if ((chip->chip_select_num > 0)
+		&& (chip->chip_select_num <= spi->master->num_chipselect))
+		peripheral_free(ssel[spi->master->bus_num][chip->chip_select_num-1]);
+
 	kfree(chip);
 }
 
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (7 preceding siblings ...)
  2007-10-30  9:17   ` [PATCH 08/14] Blackfin SPI driver: Move GPIO config to setup and cleanup Bryan Wu
@ 2007-10-30  9:18   ` Bryan Wu
  2007-10-30 20:05     ` David Brownell
  2007-10-30  9:18   ` [PATCH 10/14] Blackfin SPI driver: Clean up useless wait in bfin SPI driver Bryan Wu
                     ` (5 subsequent siblings)
  14 siblings, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:18 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, Sonic Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Current SPI driver enables SPI controller and set the SPI baud register
for each SPI transfer. But, they should never be changed within a SPI
message session, in which seveal SPI transfers are pumped. This patch
move move SPI setting to the begining of a message session. And never
disables SPI controller until an error occurs.

Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |  162 ++++++++++++++++++++++++---------------------
 1 files changed, 87 insertions(+), 75 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 7f95797..e1fd197 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -222,9 +222,13 @@ static int restore_state(struct driver_data *drv_data)
 	dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");
 
 	/* Load the registers */
-	write_CTRL(chip->ctl_reg);
+	cs_deactive(chip);
 	write_BAUD(chip->baud);
-	cs_active(chip);
+	chip->ctl_reg &= (~BIT_CTL_TIMOD);
+	chip->ctl_reg |= (chip->width << 8);
+	write_CTRL(chip->ctl_reg);
+
+	bfin_spi_enable(drv_data);
 
 	if (ret)
 		dev_dbg(&drv_data->pdev->dev,
@@ -271,6 +275,7 @@ static void u8_writer(struct driver_data *drv_data)
 {
 	dev_dbg(&drv_data->pdev->dev,
 		"cr8-s is 0x%x\n", read_STAT());
+
 	while (drv_data->tx < drv_data->tx_end) {
 		write_TDBR(*(u8 *) (drv_data->tx));
 		while (read_STAT() & BIT_STAT_TXS)
@@ -293,16 +298,16 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 		write_TDBR(*(u8 *) (drv_data->tx));
 		while (read_STAT() & BIT_STAT_TXS)
 			continue;
-		while (!(read_STAT() & BIT_STAT_SPIF))
-			continue;
 		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->tx;
 	}
-	cs_deactive(chip);
 
+	/* poll for SPI completion before returning */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
 }
 
 static void u8_reader(struct driver_data *drv_data)
@@ -314,6 +319,7 @@ static void u8_reader(struct driver_data *drv_data)
 	write_TDBR(0xFFFF);
 
 	dummy_read();
+
 	while (drv_data->rx < drv_data->rx_end - 1) {
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
@@ -331,23 +337,30 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
-	while (drv_data->rx < drv_data->rx_end) {
-		cs_active(chip);
+	/* clear TDBR buffer before read(else it will be shifted out) */
+	write_TDBR(0xFFFF);
 
-		read_RDBR();	/* kick off */
-		while (!(read_STAT() & BIT_STAT_RXS))
-			continue;
-		while (!(read_STAT() & BIT_STAT_SPIF))
-			continue;
-		*(u8 *) (drv_data->rx) = read_SHAW();
+	cs_active(chip);
+	dummy_read();
+
+	while (drv_data->rx < drv_data->rx_end - 1) {
 		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
+
+		while (!(read_STAT() & BIT_STAT_RXS))
+			continue;
+		cs_active(chip);
+		*(u8 *) (drv_data->rx) = read_RDBR();
 		++drv_data->rx;
 	}
 	cs_deactive(chip);
 
+	while (!(read_STAT() & BIT_STAT_RXS))
+		continue;
+	*(u8 *) (drv_data->rx) = read_SHAW();
+	++drv_data->rx;
 }
 
 static void u8_duplex(struct driver_data *drv_data)
@@ -355,7 +368,7 @@ static void u8_duplex(struct driver_data *drv_data)
 	/* in duplex mode, clk is triggered by writing of TDBR */
 	while (drv_data->rx < drv_data->rx_end) {
 		write_TDBR(*(u8 *) (drv_data->tx));
-		while (!(read_STAT() & BIT_STAT_SPIF))
+		while (read_STAT() & BIT_STAT_TXS)
 			continue;
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
@@ -363,6 +376,10 @@ static void u8_duplex(struct driver_data *drv_data)
 		++drv_data->rx;
 		++drv_data->tx;
 	}
+
+	/* poll for SPI completion before returning */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
 }
 
 static void u8_cs_chg_duplex(struct driver_data *drv_data)
@@ -372,9 +389,8 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 	while (drv_data->rx < drv_data->rx_end) {
 		cs_active(chip);
 
-
 		write_TDBR(*(u8 *) (drv_data->tx));
-		while (!(read_STAT() & BIT_STAT_SPIF))
+		while (read_STAT() & BIT_STAT_TXS)
 			continue;
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
@@ -386,7 +402,10 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 		++drv_data->rx;
 		++drv_data->tx;
 	}
-	cs_deactive(chip);
+
+	/* poll for SPI completion before returning */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
 }
 
 static void u16_writer(struct driver_data *drv_data)
@@ -416,21 +435,26 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 		write_TDBR(*(u16 *) (drv_data->tx));
 		while ((read_STAT() & BIT_STAT_TXS))
 			continue;
-		while (!(read_STAT() & BIT_STAT_SPIF))
-			continue;
 		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 		drv_data->tx += 2;
 	}
-	cs_deactive(chip);
+
+	/* poll for SPI completion before returning */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
 }
 
 static void u16_reader(struct driver_data *drv_data)
 {
 	dev_dbg(&drv_data->pdev->dev,
 		"cr-16 is 0x%x\n", read_STAT());
+
+	/* clear TDBR buffer before read(else it will be shifted out) */
+	write_TDBR(0xFFFF);
+
 	dummy_read();
 
 	while (drv_data->rx < (drv_data->rx_end - 2)) {
@@ -450,22 +474,30 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
-	while (drv_data->rx < drv_data->rx_end) {
-		cs_active(chip);
+	/* clear TDBR buffer before read(else it will be shifted out) */
+	write_TDBR(0xFFFF);
 
-		read_RDBR();	/* kick off */
-		while (!(read_STAT() & BIT_STAT_RXS))
-			continue;
-		while (!(read_STAT() & BIT_STAT_SPIF))
-			continue;
-		*(u16 *) (drv_data->rx) = read_SHAW();
+	cs_active(chip);
+	dummy_read();
+
+	while (drv_data->rx < drv_data->rx_end) {
 		cs_deactive(chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
+
+		while (!(read_STAT() & BIT_STAT_RXS))
+			continue;
+		cs_active(chip);
+		*(u16 *) (drv_data->rx) = read_RDBR();
 		drv_data->rx += 2;
 	}
 	cs_deactive(chip);
+
+	while (!(read_STAT() & BIT_STAT_RXS))
+		continue;
+	*(u16 *) (drv_data->rx) = read_SHAW();
+	drv_data->rx += 2;
 }
 
 static void u16_duplex(struct driver_data *drv_data)
@@ -473,7 +505,7 @@ static void u16_duplex(struct driver_data *drv_data)
 	/* in duplex mode, clk is triggered by writing of TDBR */
 	while (drv_data->tx < drv_data->tx_end) {
 		write_TDBR(*(u16 *) (drv_data->tx));
-		while (!(read_STAT() & BIT_STAT_SPIF))
+		while (read_STAT() & BIT_STAT_TXS)
 			continue;
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
@@ -481,6 +513,10 @@ static void u16_duplex(struct driver_data *drv_data)
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
+
+	/* poll for SPI completion before returning */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
 }
 
 static void u16_cs_chg_duplex(struct driver_data *drv_data)
@@ -491,7 +527,7 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 		cs_active(chip);
 
 		write_TDBR(*(u16 *) (drv_data->tx));
-		while (!(read_STAT() & BIT_STAT_SPIF))
+		while (read_STAT() & BIT_STAT_TXS)
 			continue;
 		while (!(read_STAT() & BIT_STAT_RXS))
 			continue;
@@ -503,7 +539,10 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
-	cs_deactive(chip);
+
+	/* poll for SPI completion before returning */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
 }
 
 /* test if ther is more transfer to be done */
@@ -587,8 +626,6 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 	while (!(read_STAT() & SPIF))
 		continue;
 
-	bfin_spi_disable(drv_data);
-
 	msg->actual_length += drv_data->len_in_bytes;
 
 	if (drv_data->cs_change)
@@ -698,12 +735,8 @@ static void pump_transfers(unsigned long data)
 	message->state = RUNNING_STATE;
 	dma_config = 0;
 
-	/* restore spi status for each spi transfer */
-	if (transfer->speed_hz) {
-		write_BAUD(hz_to_spi_baud(transfer->speed_hz));
-	} else {
-		write_BAUD(chip->baud);
-	}
+	write_STAT(BIT_STAT_CLR);
+	cr = (read_CTRL() & (~BIT_CTL_TIMOD));
 	cs_active(chip);
 
 	dev_dbg(&drv_data->pdev->dev,
@@ -717,10 +750,8 @@ static void pump_transfers(unsigned long data)
 	 */
 	if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
 
-		write_STAT(BIT_STAT_CLR);
 		disable_dma(spi_dma_ch);
 		clear_dma_irqstat(spi_dma_ch);
-		bfin_spi_disable(drv_data);
 
 		/* config dma channel */
 		dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
@@ -734,14 +765,14 @@ static void pump_transfers(unsigned long data)
 			dma_width = WDSIZE_8;
 		}
 
-		/* set transfer width,direction. And enable spi */
-		cr = (read_CTRL() & (~BIT_CTL_TIMOD));
-
 		/* dirty hack for autobuffer DMA mode */
 		if (drv_data->tx_dma == 0xFFFF) {
 			dev_dbg(&drv_data->pdev->dev,
 				"doing autobuffer DMA out.\n");
 
+			/* set SPI transfer mode */
+			write_CTRL(cr | CFG_SPI_DMAWRITE);
+
 			/* no irq in autobuffer mode */
 			dma_config =
 			    (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
@@ -749,8 +780,6 @@ static void pump_transfers(unsigned long data)
 			set_dma_start_addr(spi_dma_ch,
 					(unsigned long)drv_data->tx);
 			enable_dma(spi_dma_ch);
-			write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
-				   (CFG_SPI_ENABLE << 14));
 
 			/* just return here, there can only be one transfer in this mode */
 			message->status = 0;
@@ -763,11 +792,11 @@ static void pump_transfers(unsigned long data)
 			/* set transfer mode, and enable SPI */
 			dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n");
 
-			/* disable SPI before write to TDBR */
-			write_CTRL(cr & ~BIT_CTL_ENABLE);
+			/* set SPI transfer mode */
+			write_CTRL(cr | CFG_SPI_DMAREAD);
 
 			/* clear tx reg soformer data is not shifted out */
-			write_TDBR(0xFF);
+			write_TDBR(0xFFFF);
 
 			set_dma_x_count(spi_dma_ch, drv_data->len);
 
@@ -779,14 +808,12 @@ static void pump_transfers(unsigned long data)
 					(unsigned long)drv_data->rx);
 			enable_dma(spi_dma_ch);
 
-			cr |=
-			    CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE <<
-							      14);
-			/* set transfer mode, and enable SPI */
-			write_CTRL(cr);
 		} else if (drv_data->tx != NULL) {
 			dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
 
+			/* set SPI transfer mode */
+			write_CTRL(cr | CFG_SPI_DMAWRITE);
+
 			/* start dma */
 			dma_enable_irq(spi_dma_ch);
 			dma_config = (RESTART | dma_width | DI_EN);
@@ -794,28 +821,20 @@ static void pump_transfers(unsigned long data)
 			set_dma_start_addr(spi_dma_ch,
 					(unsigned long)drv_data->tx);
 			enable_dma(spi_dma_ch);
-
-			write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
-				   (CFG_SPI_ENABLE << 14));
-
 		}
 	} else {
 		/* IO mode write then read */
 		dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n");
 
-		write_STAT(BIT_STAT_CLR);
-
 		if (drv_data->tx != NULL && drv_data->rx != NULL) {
 			/* full duplex mode */
 			BUG_ON((drv_data->tx_end - drv_data->tx) !=
 			       (drv_data->rx_end - drv_data->rx));
-			cr = (read_CTRL() & (~BIT_CTL_TIMOD));
-			cr |= CFG_SPI_WRITE | (width << 8) |
-				(CFG_SPI_ENABLE << 14);
 			dev_dbg(&drv_data->pdev->dev,
 				"IO duplex: cr is 0x%x\n", cr);
 
-			write_CTRL(cr);
+			/* set SPI transfer mode */
+			write_CTRL(cr | CFG_SPI_WRITE);
 
 			drv_data->duplex(drv_data);
 
@@ -823,13 +842,11 @@ static void pump_transfers(unsigned long data)
 				tranf_success = 0;
 		} else if (drv_data->tx != NULL) {
 			/* write only half duplex */
-			cr = (read_CTRL() & (~BIT_CTL_TIMOD));
-			cr |= CFG_SPI_WRITE | (width << 8) |
-				(CFG_SPI_ENABLE << 14);
 			dev_dbg(&drv_data->pdev->dev,
 				"IO write: cr is 0x%x\n", cr);
 
-			write_CTRL(cr);
+			/* set SPI transfer mode */
+			write_CTRL(cr | CFG_SPI_WRITE);
 
 			drv_data->write(drv_data);
 
@@ -837,13 +854,11 @@ static void pump_transfers(unsigned long data)
 				tranf_success = 0;
 		} else if (drv_data->rx != NULL) {
 			/* read only half duplex */
-			cr = (read_CTRL() & (~BIT_CTL_TIMOD));
-			cr |= CFG_SPI_READ | (width << 8) |
-				(CFG_SPI_ENABLE << 14);
 			dev_dbg(&drv_data->pdev->dev,
 				"IO read: cr is 0x%x\n", cr);
 
-			write_CTRL(cr);
+			/* set SPI transfer mode */
+			write_CTRL(cr | CFG_SPI_READ);
 
 			drv_data->read(drv_data);
 			if (drv_data->rx != drv_data->rx_end)
@@ -858,9 +873,6 @@ static void pump_transfers(unsigned long data)
 			/* Update total byte transfered */
 			message->actual_length += drv_data->len;
 
-			if (drv_data->cs_change)
-				cs_deactive(chip);
-
 			/* Move to next transfer of this msg */
 			message->state = next_transfer(drv_data);
 		}
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 10/14] Blackfin SPI driver: Clean up useless wait in bfin SPI driver
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (8 preceding siblings ...)
  2007-10-30  9:18   ` [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548 Bryan Wu
@ 2007-10-30  9:18   ` Bryan Wu
  2007-10-30  9:18   ` [PATCH 11/14] Blackfin SPI driver: Move global SPI regs_base and dma_ch to struct driver_data Bryan Wu
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:18 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, Sonic Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |   84 ++++++++++++++++++++++++++++-----------------
 1 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index e1fd197..d69719b 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -276,22 +276,26 @@ static void u8_writer(struct driver_data *drv_data)
 	dev_dbg(&drv_data->pdev->dev,
 		"cr8-s is 0x%x\n", read_STAT());
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	while (drv_data->tx < drv_data->tx_end) {
 		write_TDBR(*(u8 *) (drv_data->tx));
 		while (read_STAT() & BIT_STAT_TXS)
 			continue;
 		++drv_data->tx;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u8_cs_chg_writer(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	while (drv_data->tx < drv_data->tx_end) {
 		cs_active(chip);
 
@@ -304,10 +308,6 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 			udelay(chip->cs_chg_udelay);
 		++drv_data->tx;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u8_reader(struct driver_data *drv_data)
@@ -315,6 +315,10 @@ static void u8_reader(struct driver_data *drv_data)
 	dev_dbg(&drv_data->pdev->dev,
 		"cr-8 is 0x%x\n", read_STAT());
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	/* clear TDBR buffer before read(else it will be shifted out) */
 	write_TDBR(0xFFFF);
 
@@ -337,6 +341,10 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	/* clear TDBR buffer before read(else it will be shifted out) */
 	write_TDBR(0xFFFF);
 
@@ -365,6 +373,10 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 
 static void u8_duplex(struct driver_data *drv_data)
 {
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	/* in duplex mode, clk is triggered by writing of TDBR */
 	while (drv_data->rx < drv_data->rx_end) {
 		write_TDBR(*(u8 *) (drv_data->tx));
@@ -376,16 +388,16 @@ static void u8_duplex(struct driver_data *drv_data)
 		++drv_data->rx;
 		++drv_data->tx;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u8_cs_chg_duplex(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	while (drv_data->rx < drv_data->rx_end) {
 		cs_active(chip);
 
@@ -402,10 +414,6 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 		++drv_data->rx;
 		++drv_data->tx;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u16_writer(struct driver_data *drv_data)
@@ -413,22 +421,26 @@ static void u16_writer(struct driver_data *drv_data)
 	dev_dbg(&drv_data->pdev->dev,
 		"cr16 is 0x%x\n", read_STAT());
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	while (drv_data->tx < drv_data->tx_end) {
 		write_TDBR(*(u16 *) (drv_data->tx));
 		while ((read_STAT() & BIT_STAT_TXS))
 			continue;
 		drv_data->tx += 2;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u16_cs_chg_writer(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	while (drv_data->tx < drv_data->tx_end) {
 		cs_active(chip);
 
@@ -441,10 +453,6 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 			udelay(chip->cs_chg_udelay);
 		drv_data->tx += 2;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u16_reader(struct driver_data *drv_data)
@@ -452,6 +460,10 @@ static void u16_reader(struct driver_data *drv_data)
 	dev_dbg(&drv_data->pdev->dev,
 		"cr-16 is 0x%x\n", read_STAT());
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	/* clear TDBR buffer before read(else it will be shifted out) */
 	write_TDBR(0xFFFF);
 
@@ -474,6 +486,10 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	/* clear TDBR buffer before read(else it will be shifted out) */
 	write_TDBR(0xFFFF);
 
@@ -502,6 +518,10 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 
 static void u16_duplex(struct driver_data *drv_data)
 {
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	/* in duplex mode, clk is triggered by writing of TDBR */
 	while (drv_data->tx < drv_data->tx_end) {
 		write_TDBR(*(u16 *) (drv_data->tx));
@@ -513,16 +533,16 @@ static void u16_duplex(struct driver_data *drv_data)
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 static void u16_cs_chg_duplex(struct driver_data *drv_data)
 {
 	struct chip_data *chip = drv_data->cur_chip;
 
+	/* poll for SPI completion before start */
+	while (!(read_STAT() & BIT_STAT_SPIF))
+		continue;
+
 	while (drv_data->tx < drv_data->tx_end) {
 		cs_active(chip);
 
@@ -539,10 +559,6 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
-
-	/* poll for SPI completion before returning */
-	while (!(read_STAT() & BIT_STAT_SPIF))
-		continue;
 }
 
 /* test if ther is more transfer to be done */
@@ -765,6 +781,10 @@ static void pump_transfers(unsigned long data)
 			dma_width = WDSIZE_8;
 		}
 
+		/* poll for SPI completion before start */
+		while (!(read_STAT() & BIT_STAT_SPIF))
+			continue;
+
 		/* dirty hack for autobuffer DMA mode */
 		if (drv_data->tx_dma == 0xFFFF) {
 			dev_dbg(&drv_data->pdev->dev,
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 11/14] Blackfin SPI driver: Move global SPI regs_base and dma_ch to struct driver_data
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (9 preceding siblings ...)
  2007-10-30  9:18   ` [PATCH 10/14] Blackfin SPI driver: Clean up useless wait in bfin SPI driver Bryan Wu
@ 2007-10-30  9:18   ` Bryan Wu
  2007-10-30  9:18   ` [PATCH 12/14] Blackfin SPI driver: Fix bug in u16_cs_chg_reader to read data_len-2 bytes data firstly, then read out the last 2 bytes data Bryan Wu
                     ` (3 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:18 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA

Test on BF54x SPI Flash with 2 SPI master driver enabled

Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |  357 +++++++++++++++++++++++----------------------
 1 files changed, 182 insertions(+), 175 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index d69719b..5924903 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -63,29 +63,12 @@ MODULE_LICENSE("GPL");
 
 #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
 
-static u32 spi_dma_ch;
-static u32 spi_regs_base;
-
-#define DEFINE_SPI_REG(reg, off) \
-static inline u16 read_##reg(void) \
-	{ return bfin_read16(spi_regs_base + off); } \
-static inline void write_##reg(u16 v) \
-	{bfin_write16(spi_regs_base + off, v); }
-
-DEFINE_SPI_REG(CTRL, 0x00)
-DEFINE_SPI_REG(FLAG, 0x04)
-DEFINE_SPI_REG(STAT, 0x08)
-DEFINE_SPI_REG(TDBR, 0x0C)
-DEFINE_SPI_REG(RDBR, 0x10)
-DEFINE_SPI_REG(BAUD, 0x14)
-DEFINE_SPI_REG(SHAW, 0x18)
 #define START_STATE ((void*)0)
 #define RUNNING_STATE ((void*)1)
 #define DONE_STATE ((void*)2)
 #define ERROR_STATE ((void*)-1)
 #define QUEUE_RUNNING 0
 #define QUEUE_STOPPED 1
-int dma_requested;
 
 struct driver_data {
 	/* Driver model hookup */
@@ -94,6 +77,9 @@ struct driver_data {
 	/* SPI framework hookup */
 	struct spi_master *master;
 
+	/* Regs base of SPI controller */
+	u32 regs_base;
+
 	/* BFIN hookup */
 	struct bfin5xx_spi_master *master_info;
 
@@ -118,9 +104,14 @@ struct driver_data {
 	void *tx_end;
 	void *rx;
 	void *rx_end;
+
+	/* DMA stuffs */
+	int dma_channel;
 	int dma_mapped;
+	int dma_requested;
 	dma_addr_t rx_dma;
 	dma_addr_t tx_dma;
+
 	size_t rx_map_len;
 	size_t tx_map_len;
 	u8 n_bytes;
@@ -147,20 +138,34 @@ struct chip_data {
 	void (*duplex) (struct driver_data *);
 };
 
+#define DEFINE_SPI_REG(reg, off) \
+static inline u16 read_##reg(struct driver_data *drv_data) \
+	{ return bfin_read16(drv_data->regs_base + off); } \
+static inline void write_##reg(struct driver_data *drv_data, u16 v) \
+	{ bfin_write16(drv_data->regs_base + off, v); }
+
+DEFINE_SPI_REG(CTRL, 0x00)
+DEFINE_SPI_REG(FLAG, 0x04)
+DEFINE_SPI_REG(STAT, 0x08)
+DEFINE_SPI_REG(TDBR, 0x0C)
+DEFINE_SPI_REG(RDBR, 0x10)
+DEFINE_SPI_REG(BAUD, 0x14)
+DEFINE_SPI_REG(SHAW, 0x18)
+
 static void bfin_spi_enable(struct driver_data *drv_data)
 {
 	u16 cr;
 
-	cr = read_CTRL();
-	write_CTRL(cr | BIT_CTL_ENABLE);
+	cr = read_CTRL(drv_data);
+	write_CTRL(drv_data, (cr | BIT_CTL_ENABLE));
 }
 
 static void bfin_spi_disable(struct driver_data *drv_data)
 {
 	u16 cr;
 
-	cr = read_CTRL();
-	write_CTRL(cr & (~BIT_CTL_ENABLE));
+	cr = read_CTRL(drv_data);
+	write_CTRL(drv_data, (cr & (~BIT_CTL_ENABLE)));
 }
 
 /* Caculate the SPI_BAUD register value based on input HZ */
@@ -180,32 +185,32 @@ static int flush(struct driver_data *drv_data)
 	unsigned long limit = loops_per_jiffy << 1;
 
 	/* wait for stop and clear stat */
-	while (!(read_STAT() & BIT_STAT_SPIF) && limit--)
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF) && limit--)
 		continue;
 
-	write_STAT(BIT_STAT_CLR);
+	write_STAT(drv_data, BIT_STAT_CLR);
 
 	return limit;
 }
 
 /* Chip select operation functions for cs_change flag */
-static void cs_active(struct chip_data *chip)
+static void cs_active(struct driver_data *drv_data, struct chip_data *chip)
 {
-	u16 flag = read_FLAG();
+	u16 flag = read_FLAG(drv_data);
 
 	flag |= chip->flag;
 	flag &= ~(chip->flag << 8);
 
-	write_FLAG(flag);
+	write_FLAG(drv_data, flag);
 }
 
-static void cs_deactive(struct chip_data *chip)
+static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
 {
-	u16 flag = read_FLAG();
+	u16 flag = read_FLAG(drv_data);
 
 	flag |= (chip->flag << 8);
 
-	write_FLAG(flag);
+	write_FLAG(drv_data, flag);
 }
 
 #define MAX_SPI_SSEL	7
@@ -217,16 +222,16 @@ static int restore_state(struct driver_data *drv_data)
 	int ret = 0;
 
 	/* Clear status and disable clock */
-	write_STAT(BIT_STAT_CLR);
+	write_STAT(drv_data, BIT_STAT_CLR);
 	bfin_spi_disable(drv_data);
 	dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");
 
 	/* Load the registers */
-	cs_deactive(chip);
-	write_BAUD(chip->baud);
+	cs_deactive(drv_data, chip);
+	write_BAUD(drv_data, chip->baud);
 	chip->ctl_reg &= (~BIT_CTL_TIMOD);
 	chip->ctl_reg |= (chip->width << 8);
-	write_CTRL(chip->ctl_reg);
+	write_CTRL(drv_data, chip->ctl_reg);
 
 	bfin_spi_enable(drv_data);
 
@@ -239,10 +244,10 @@ static int restore_state(struct driver_data *drv_data)
 }
 
 /* used to kick off transfer in rx mode */
-static unsigned short dummy_read(void)
+static unsigned short dummy_read(struct driver_data *drv_data)
 {
 	unsigned short tmp;
-	tmp = read_RDBR();
+	tmp = read_RDBR(drv_data);
 	return tmp;
 }
 
@@ -251,8 +256,8 @@ static void null_writer(struct driver_data *drv_data)
 	u8 n_bytes = drv_data->n_bytes;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		write_TDBR(0);
-		while ((read_STAT() & BIT_STAT_TXS))
+		write_TDBR(drv_data, 0);
+		while ((read_STAT(drv_data) & BIT_STAT_TXS))
 			continue;
 		drv_data->tx += n_bytes;
 	}
@@ -261,12 +266,12 @@ static void null_writer(struct driver_data *drv_data)
 static void null_reader(struct driver_data *drv_data)
 {
 	u8 n_bytes = drv_data->n_bytes;
-	dummy_read();
+	dummy_read(drv_data);
 
 	while (drv_data->rx < drv_data->rx_end) {
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		dummy_read();
+		dummy_read(drv_data);
 		drv_data->rx += n_bytes;
 	}
 }
@@ -274,15 +279,15 @@ static void null_reader(struct driver_data *drv_data)
 static void u8_writer(struct driver_data *drv_data)
 {
 	dev_dbg(&drv_data->pdev->dev,
-		"cr8-s is 0x%x\n", read_STAT());
+		"cr8-s is 0x%x\n", read_STAT(drv_data));
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		write_TDBR(*(u8 *) (drv_data->tx));
-		while (read_STAT() & BIT_STAT_TXS)
+		write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
+		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
 		++drv_data->tx;
 	}
@@ -293,16 +298,16 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		cs_active(chip);
+		cs_active(drv_data, chip);
 
-		write_TDBR(*(u8 *) (drv_data->tx));
-		while (read_STAT() & BIT_STAT_TXS)
+		write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
+		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
@@ -313,27 +318,27 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 static void u8_reader(struct driver_data *drv_data)
 {
 	dev_dbg(&drv_data->pdev->dev,
-		"cr-8 is 0x%x\n", read_STAT());
+		"cr-8 is 0x%x\n", read_STAT(drv_data));
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	/* clear TDBR buffer before read(else it will be shifted out) */
-	write_TDBR(0xFFFF);
+	write_TDBR(drv_data, 0xFFFF);
 
-	dummy_read();
+	dummy_read(drv_data);
 
 	while (drv_data->rx < drv_data->rx_end - 1) {
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		*(u8 *) (drv_data->rx) = read_RDBR();
+		*(u8 *) (drv_data->rx) = read_RDBR(drv_data);
 		++drv_data->rx;
 	}
 
-	while (!(read_STAT() & BIT_STAT_RXS))
+	while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 		continue;
-	*(u8 *) (drv_data->rx) = read_SHAW();
+	*(u8 *) (drv_data->rx) = read_SHAW(drv_data);
 	++drv_data->rx;
 }
 
@@ -342,49 +347,49 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	/* clear TDBR buffer before read(else it will be shifted out) */
-	write_TDBR(0xFFFF);
+	write_TDBR(drv_data, 0xFFFF);
 
-	cs_active(chip);
-	dummy_read();
+	cs_active(drv_data, chip);
+	dummy_read(drv_data);
 
 	while (drv_data->rx < drv_data->rx_end - 1) {
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		cs_active(chip);
-		*(u8 *) (drv_data->rx) = read_RDBR();
+		cs_active(drv_data, chip);
+		*(u8 *) (drv_data->rx) = read_RDBR(drv_data);
 		++drv_data->rx;
 	}
-	cs_deactive(chip);
+	cs_deactive(drv_data, chip);
 
-	while (!(read_STAT() & BIT_STAT_RXS))
+	while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 		continue;
-	*(u8 *) (drv_data->rx) = read_SHAW();
+	*(u8 *) (drv_data->rx) = read_SHAW(drv_data);
 	++drv_data->rx;
 }
 
 static void u8_duplex(struct driver_data *drv_data)
 {
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	/* in duplex mode, clk is triggered by writing of TDBR */
 	while (drv_data->rx < drv_data->rx_end) {
-		write_TDBR(*(u8 *) (drv_data->tx));
-		while (read_STAT() & BIT_STAT_TXS)
+		write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
+		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		*(u8 *) (drv_data->rx) = read_RDBR();
+		*(u8 *) (drv_data->rx) = read_RDBR(drv_data);
 		++drv_data->rx;
 		++drv_data->tx;
 	}
@@ -395,19 +400,19 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	while (drv_data->rx < drv_data->rx_end) {
-		cs_active(chip);
+		cs_active(drv_data, chip);
 
-		write_TDBR(*(u8 *) (drv_data->tx));
-		while (read_STAT() & BIT_STAT_TXS)
+		write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
+		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		*(u8 *) (drv_data->rx) = read_RDBR();
-		cs_deactive(chip);
+		*(u8 *) (drv_data->rx) = read_RDBR(drv_data);
+		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
@@ -419,15 +424,15 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 static void u16_writer(struct driver_data *drv_data)
 {
 	dev_dbg(&drv_data->pdev->dev,
-		"cr16 is 0x%x\n", read_STAT());
+		"cr16 is 0x%x\n", read_STAT(drv_data));
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		write_TDBR(*(u16 *) (drv_data->tx));
-		while ((read_STAT() & BIT_STAT_TXS))
+		write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
+		while ((read_STAT(drv_data) & BIT_STAT_TXS))
 			continue;
 		drv_data->tx += 2;
 	}
@@ -438,16 +443,16 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		cs_active(chip);
+		cs_active(drv_data, chip);
 
-		write_TDBR(*(u16 *) (drv_data->tx));
-		while ((read_STAT() & BIT_STAT_TXS))
+		write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
+		while ((read_STAT(drv_data) & BIT_STAT_TXS))
 			continue;
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
@@ -458,27 +463,27 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 static void u16_reader(struct driver_data *drv_data)
 {
 	dev_dbg(&drv_data->pdev->dev,
-		"cr-16 is 0x%x\n", read_STAT());
+		"cr-16 is 0x%x\n", read_STAT(drv_data));
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	/* clear TDBR buffer before read(else it will be shifted out) */
-	write_TDBR(0xFFFF);
+	write_TDBR(drv_data, 0xFFFF);
 
-	dummy_read();
+	dummy_read(drv_data);
 
 	while (drv_data->rx < (drv_data->rx_end - 2)) {
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		*(u16 *) (drv_data->rx) = read_RDBR();
+		*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
 		drv_data->rx += 2;
 	}
 
-	while (!(read_STAT() & BIT_STAT_RXS))
+	while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 		continue;
-	*(u16 *) (drv_data->rx) = read_SHAW();
+	*(u16 *) (drv_data->rx) = read_SHAW(drv_data);
 	drv_data->rx += 2;
 }
 
@@ -487,49 +492,49 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	/* clear TDBR buffer before read(else it will be shifted out) */
-	write_TDBR(0xFFFF);
+	write_TDBR(drv_data, 0xFFFF);
 
-	cs_active(chip);
-	dummy_read();
+	cs_active(drv_data, chip);
+	dummy_read(drv_data);
 
 	while (drv_data->rx < drv_data->rx_end) {
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
 
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		cs_active(chip);
-		*(u16 *) (drv_data->rx) = read_RDBR();
+		cs_active(drv_data, chip);
+		*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
 		drv_data->rx += 2;
 	}
-	cs_deactive(chip);
+	cs_deactive(drv_data, chip);
 
-	while (!(read_STAT() & BIT_STAT_RXS))
+	while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 		continue;
-	*(u16 *) (drv_data->rx) = read_SHAW();
+	*(u16 *) (drv_data->rx) = read_SHAW(drv_data);
 	drv_data->rx += 2;
 }
 
 static void u16_duplex(struct driver_data *drv_data)
 {
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	/* in duplex mode, clk is triggered by writing of TDBR */
 	while (drv_data->tx < drv_data->tx_end) {
-		write_TDBR(*(u16 *) (drv_data->tx));
-		while (read_STAT() & BIT_STAT_TXS)
+		write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
+		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		*(u16 *) (drv_data->rx) = read_RDBR();
+		*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
@@ -540,19 +545,19 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 	struct chip_data *chip = drv_data->cur_chip;
 
 	/* poll for SPI completion before start */
-	while (!(read_STAT() & BIT_STAT_SPIF))
+	while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 		continue;
 
 	while (drv_data->tx < drv_data->tx_end) {
-		cs_active(chip);
+		cs_active(drv_data, chip);
 
-		write_TDBR(*(u16 *) (drv_data->tx));
-		while (read_STAT() & BIT_STAT_TXS)
+		write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
+		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
-		while (!(read_STAT() & BIT_STAT_RXS))
+		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
-		*(u16 *) (drv_data->rx) = read_RDBR();
-		cs_deactive(chip);
+		*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
+		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
 			udelay(chip->cs_chg_udelay);
@@ -603,12 +608,12 @@ static void giveback(struct driver_data *drv_data)
 
 	/* disable chip select signal. And not stop spi in autobuffer mode */
 	if (drv_data->tx_dma != 0xFFFF) {
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 		bfin_spi_disable(drv_data);
 	}
 
 	if (!drv_data->cs_change)
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 
 	if (msg->complete)
 		msg->complete(msg->context);
@@ -617,14 +622,14 @@ static void giveback(struct driver_data *drv_data)
 static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
 	struct driver_data *drv_data = (struct driver_data *)dev_id;
-	struct spi_message *msg = drv_data->cur_msg;
 	struct chip_data *chip = drv_data->cur_chip;
+	struct spi_message *msg = drv_data->cur_msg;
 
 	dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
-	clear_dma_irqstat(spi_dma_ch);
+	clear_dma_irqstat(drv_data->dma_channel);
 
 	/* Wait for DMA to complete */
-	while (get_dma_curr_irqstat(spi_dma_ch) & DMA_RUN)
+	while (get_dma_curr_irqstat(drv_data->dma_channel) & DMA_RUN)
 		continue;
 
 	/*
@@ -634,18 +639,18 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 	 * register until it goes low for 2 successive reads
 	 */
 	if (drv_data->tx != NULL) {
-		while ((read_STAT() & TXS) ||
-		       (read_STAT() & TXS))
+		while ((read_STAT(drv_data) & TXS) ||
+		       (read_STAT(drv_data) & TXS))
 			continue;
 	}
 
-	while (!(read_STAT() & SPIF))
+	while (!(read_STAT(drv_data) & SPIF))
 		continue;
 
 	msg->actual_length += drv_data->len_in_bytes;
 
 	if (drv_data->cs_change)
-		cs_deactive(chip);
+		cs_deactive(drv_data, chip);
 
 	/* Move to next transfer */
 	msg->state = next_transfer(drv_data);
@@ -656,8 +661,8 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 	/* free the irq handler before next transfer */
 	dev_dbg(&drv_data->pdev->dev,
 		"disable dma channel irq%d\n",
-		spi_dma_ch);
-	dma_disable_irq(spi_dma_ch);
+		drv_data->dma_channel);
+	dma_disable_irq(drv_data->dma_channel);
 
 	return IRQ_HANDLED;
 }
@@ -751,9 +756,9 @@ static void pump_transfers(unsigned long data)
 	message->state = RUNNING_STATE;
 	dma_config = 0;
 
-	write_STAT(BIT_STAT_CLR);
-	cr = (read_CTRL() & (~BIT_CTL_TIMOD));
-	cs_active(chip);
+	write_STAT(drv_data, BIT_STAT_CLR);
+	cr = (read_CTRL(drv_data) & (~BIT_CTL_TIMOD));
+	cs_active(drv_data, chip);
 
 	dev_dbg(&drv_data->pdev->dev,
 		"now pumping a transfer: width is %d, len is %d\n",
@@ -766,23 +771,23 @@ static void pump_transfers(unsigned long data)
 	 */
 	if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
 
-		disable_dma(spi_dma_ch);
-		clear_dma_irqstat(spi_dma_ch);
+		disable_dma(drv_data->dma_channel);
+		clear_dma_irqstat(drv_data->dma_channel);
 
 		/* config dma channel */
 		dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
 		if (width == CFG_SPI_WORDSIZE16) {
-			set_dma_x_count(spi_dma_ch, drv_data->len);
-			set_dma_x_modify(spi_dma_ch, 2);
+			set_dma_x_count(drv_data->dma_channel, drv_data->len);
+			set_dma_x_modify(drv_data->dma_channel, 2);
 			dma_width = WDSIZE_16;
 		} else {
-			set_dma_x_count(spi_dma_ch, drv_data->len);
-			set_dma_x_modify(spi_dma_ch, 1);
+			set_dma_x_count(drv_data->dma_channel, drv_data->len);
+			set_dma_x_modify(drv_data->dma_channel, 1);
 			dma_width = WDSIZE_8;
 		}
 
 		/* poll for SPI completion before start */
-		while (!(read_STAT() & BIT_STAT_SPIF))
+		while (!(read_STAT(drv_data) & BIT_STAT_SPIF))
 			continue;
 
 		/* dirty hack for autobuffer DMA mode */
@@ -791,15 +796,15 @@ static void pump_transfers(unsigned long data)
 				"doing autobuffer DMA out.\n");
 
 			/* set SPI transfer mode */
-			write_CTRL(cr | CFG_SPI_DMAWRITE);
+			write_CTRL(drv_data, (cr | CFG_SPI_DMAWRITE));
 
 			/* no irq in autobuffer mode */
 			dma_config =
 			    (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
-			set_dma_config(spi_dma_ch, dma_config);
-			set_dma_start_addr(spi_dma_ch,
+			set_dma_config(drv_data->dma_channel, dma_config);
+			set_dma_start_addr(drv_data->dma_channel,
 					(unsigned long)drv_data->tx);
-			enable_dma(spi_dma_ch);
+			enable_dma(drv_data->dma_channel);
 
 			/* just return here, there can only be one transfer in this mode */
 			message->status = 0;
@@ -813,34 +818,34 @@ static void pump_transfers(unsigned long data)
 			dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n");
 
 			/* set SPI transfer mode */
-			write_CTRL(cr | CFG_SPI_DMAREAD);
+			write_CTRL(drv_data, (cr | CFG_SPI_DMAREAD));
 
 			/* clear tx reg soformer data is not shifted out */
-			write_TDBR(0xFFFF);
+			write_TDBR(drv_data, 0xFFFF);
 
-			set_dma_x_count(spi_dma_ch, drv_data->len);
+			set_dma_x_count(drv_data->dma_channel, drv_data->len);
 
 			/* start dma */
-			dma_enable_irq(spi_dma_ch);
+			dma_enable_irq(drv_data->dma_channel);
 			dma_config = (WNR | RESTART | dma_width | DI_EN);
-			set_dma_config(spi_dma_ch, dma_config);
-			set_dma_start_addr(spi_dma_ch,
+			set_dma_config(drv_data->dma_channel, dma_config);
+			set_dma_start_addr(drv_data->dma_channel,
 					(unsigned long)drv_data->rx);
-			enable_dma(spi_dma_ch);
+			enable_dma(drv_data->dma_channel);
 
 		} else if (drv_data->tx != NULL) {
 			dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
 
 			/* set SPI transfer mode */
-			write_CTRL(cr | CFG_SPI_DMAWRITE);
+			write_CTRL(drv_data, (cr | CFG_SPI_DMAWRITE));
 
 			/* start dma */
-			dma_enable_irq(spi_dma_ch);
+			dma_enable_irq(drv_data->dma_channel);
 			dma_config = (RESTART | dma_width | DI_EN);
-			set_dma_config(spi_dma_ch, dma_config);
-			set_dma_start_addr(spi_dma_ch,
+			set_dma_config(drv_data->dma_channel, dma_config);
+			set_dma_start_addr(drv_data->dma_channel,
 					(unsigned long)drv_data->tx);
-			enable_dma(spi_dma_ch);
+			enable_dma(drv_data->dma_channel);
 		}
 	} else {
 		/* IO mode write then read */
@@ -854,7 +859,7 @@ static void pump_transfers(unsigned long data)
 				"IO duplex: cr is 0x%x\n", cr);
 
 			/* set SPI transfer mode */
-			write_CTRL(cr | CFG_SPI_WRITE);
+			write_CTRL(drv_data, (cr | CFG_SPI_WRITE));
 
 			drv_data->duplex(drv_data);
 
@@ -866,7 +871,7 @@ static void pump_transfers(unsigned long data)
 				"IO write: cr is 0x%x\n", cr);
 
 			/* set SPI transfer mode */
-			write_CTRL(cr | CFG_SPI_WRITE);
+			write_CTRL(drv_data, (cr | CFG_SPI_WRITE));
 
 			drv_data->write(drv_data);
 
@@ -878,7 +883,7 @@ static void pump_transfers(unsigned long data)
 				"IO read: cr is 0x%x\n", cr);
 
 			/* set SPI transfer mode */
-			write_CTRL(cr | CFG_SPI_READ);
+			write_CTRL(drv_data, (cr | CFG_SPI_READ));
 
 			drv_data->read(drv_data);
 			if (drv_data->rx != drv_data->rx_end)
@@ -1071,20 +1076,20 @@ static int setup(struct spi_device *spi)
 	 * if any one SPI chip is registered and wants DMA, request the
 	 * DMA channel for it
 	 */
-	if (chip->enable_dma && !dma_requested) {
+	if (chip->enable_dma && !drv_data->dma_requested) {
 		/* register dma irq handler */
-		if (request_dma(spi_dma_ch, "BF53x_SPI_DMA") < 0) {
+		if (request_dma(drv_data->dma_channel, "BF53x_SPI_DMA") < 0) {
 			dev_dbg(&spi->dev,
 				"Unable to request BlackFin SPI DMA channel\n");
 			return -ENODEV;
 		}
-		if (set_dma_callback(spi_dma_ch, (void *)dma_irq_handler,
-			drv_data) < 0) {
+		if (set_dma_callback(drv_data->dma_channel,
+			(void *)dma_irq_handler, drv_data) < 0) {
 			dev_dbg(&spi->dev, "Unable to set dma callback\n");
 			return -EPERM;
 		}
-		dma_disable_irq(spi_dma_ch);
-		dma_requested = 1;
+		dma_disable_irq(drv_data->dma_channel);
+		drv_data->dma_requested = 1;
 	}
 
 	/*
@@ -1299,15 +1304,16 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 		goto out_error_get_res;
 	}
 
-	spi_regs_base = (u32) ioremap(res->start, (res->end - res->start)+1);
-	if (!spi_regs_base) {
+	drv_data->regs_base = (u32) ioremap(res->start,
+					(res->end - res->start + 1));
+	if (!drv_data->regs_base) {
 		dev_err(dev, "Cannot map IO\n");
 		status = -ENXIO;
 		goto out_error_ioremap;
 	}
 
-	spi_dma_ch = platform_get_irq(pdev, 0);
-	if (spi_dma_ch < 0) {
+	drv_data->dma_channel = platform_get_irq(pdev, 0);
+	if (drv_data->dma_channel < 0) {
 		dev_err(dev, "No DMA channel specified\n");
 		status = -ENOENT;
 		goto out_error_no_dma_ch;
@@ -1339,14 +1345,15 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
 		goto out_error;
 	}
 
-	dev_info(dev, "%s, Version %s, regs_base @ 0x%08x\n",
-		DRV_DESC, DRV_VERSION, spi_regs_base);
+	dev_info(dev, "%s, Version %s, regs_base@0x%08x, dma channel@%d\n",
+		DRV_DESC, DRV_VERSION, drv_data->regs_base,
+		drv_data->dma_channel);
 	return status;
 
 out_error_queue_alloc:
 	destroy_queue(drv_data);
 out_error_no_dma_ch:
-	iounmap((void *) spi_regs_base);
+	iounmap((void *) drv_data->regs_base);
 out_error_ioremap:
 out_error_get_res:
 out_error:
@@ -1374,8 +1381,8 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
 
 	/* Release DMA */
 	if (drv_data->master_info->enable_dma) {
-		if (dma_channel_active(spi_dma_ch))
-			free_dma(spi_dma_ch);
+		if (dma_channel_active(drv_data->dma_channel))
+			free_dma(drv_data->dma_channel);
 	}
 
 	/* Disconnect from the SPI framework */
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 12/14] Blackfin SPI driver: Fix bug in u16_cs_chg_reader to read data_len-2 bytes data firstly, then read out the last 2 bytes data
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (10 preceding siblings ...)
  2007-10-30  9:18   ` [PATCH 11/14] Blackfin SPI driver: Move global SPI regs_base and dma_ch to struct driver_data Bryan Wu
@ 2007-10-30  9:18   ` Bryan Wu
  2007-10-30  9:18   ` [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive Bryan Wu
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:18 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA

Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 5924903..41282bf 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -501,7 +501,7 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 	cs_active(drv_data, chip);
 	dummy_read(drv_data);
 
-	while (drv_data->rx < drv_data->rx_end) {
+	while (drv_data->rx < drv_data->rx_end - 2) {
 		cs_deactive(drv_data, chip);
 
 		if (chip->cs_chg_udelay)
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (11 preceding siblings ...)
  2007-10-30  9:18   ` [PATCH 12/14] Blackfin SPI driver: Fix bug in u16_cs_chg_reader to read data_len-2 bytes data firstly, then read out the last 2 bytes data Bryan Wu
@ 2007-10-30  9:18   ` Bryan Wu
       [not found]     ` <1193735885-8202-14-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
  2007-10-30  9:18   ` [PATCH 14/14] Blackfin SPI driver: set correct baud for spi mmc and enable SPI after DMA Bryan Wu
  2007-10-30 20:24   ` [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing David Brownell
  14 siblings, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:18 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Cameron Barfield

Fix bug reported by Cameron Barfield <cbarfield-uxMF5PKaPIoXhy9q4Lf3Ug@public.gmane.org>
https://blackfin.uclinux.org/gf/project/uclinux-dist/forum/?action=ForumBrowse&forum_id=39&_forum_action=ForumMessageBrowse&thread_id=23630&feedback=Message%20replied.

Cc: Cameron Barfield <cbarfield-uxMF5PKaPIoXhy9q4Lf3Ug@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c          |   24 +++++++++---------------
 include/asm-blackfin/bfin5xx_spi.h |    2 +-
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 41282bf..0b22932 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -132,7 +132,7 @@ struct chip_data {
 	u8 enable_dma;
 	u8 bits_per_word;	/* 8 or 16 */
 	u8 cs_change_per_word;
-	u8 cs_chg_udelay;
+	u16 cs_chg_udelay;	/* Some devices require > 255usec delay */
 	void (*write) (struct driver_data *);
 	void (*read) (struct driver_data *);
 	void (*duplex) (struct driver_data *);
@@ -211,6 +211,10 @@ static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
 	flag |= (chip->flag << 8);
 
 	write_FLAG(drv_data, flag);
+
+	/* Move delay here for consistency */
+	if (chip->cs_chg_udelay)
+		udelay(chip->cs_chg_udelay);
 }
 
 #define MAX_SPI_SSEL	7
@@ -307,10 +311,9 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
 		write_TDBR(drv_data, (*(u8 *) (drv_data->tx)));
 		while (read_STAT(drv_data) & BIT_STAT_TXS)
 			continue;
+
 		cs_deactive(drv_data, chip);
 
-		if (chip->cs_chg_udelay)
-			udelay(chip->cs_chg_udelay);
 		++drv_data->tx;
 	}
 }
@@ -359,9 +362,6 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
 	while (drv_data->rx < drv_data->rx_end - 1) {
 		cs_deactive(drv_data, chip);
 
-		if (chip->cs_chg_udelay)
-			udelay(chip->cs_chg_udelay);
-
 		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
 		cs_active(drv_data, chip);
@@ -412,10 +412,9 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
 		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
 		*(u8 *) (drv_data->rx) = read_RDBR(drv_data);
+
 		cs_deactive(drv_data, chip);
 
-		if (chip->cs_chg_udelay)
-			udelay(chip->cs_chg_udelay);
 		++drv_data->rx;
 		++drv_data->tx;
 	}
@@ -452,10 +451,9 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
 		write_TDBR(drv_data, (*(u16 *) (drv_data->tx)));
 		while ((read_STAT(drv_data) & BIT_STAT_TXS))
 			continue;
+
 		cs_deactive(drv_data, chip);
 
-		if (chip->cs_chg_udelay)
-			udelay(chip->cs_chg_udelay);
 		drv_data->tx += 2;
 	}
 }
@@ -504,9 +502,6 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
 	while (drv_data->rx < drv_data->rx_end - 2) {
 		cs_deactive(drv_data, chip);
 
-		if (chip->cs_chg_udelay)
-			udelay(chip->cs_chg_udelay);
-
 		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
 		cs_active(drv_data, chip);
@@ -557,10 +552,9 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
 		while (!(read_STAT(drv_data) & BIT_STAT_RXS))
 			continue;
 		*(u16 *) (drv_data->rx) = read_RDBR(drv_data);
+
 		cs_deactive(drv_data, chip);
 
-		if (chip->cs_chg_udelay)
-			udelay(chip->cs_chg_udelay);
 		drv_data->rx += 2;
 		drv_data->tx += 2;
 	}
diff --git a/include/asm-blackfin/bfin5xx_spi.h b/include/asm-blackfin/bfin5xx_spi.h
index f617d87..d4485b3 100644
--- a/include/asm-blackfin/bfin5xx_spi.h
+++ b/include/asm-blackfin/bfin5xx_spi.h
@@ -162,7 +162,7 @@ struct bfin5xx_spi_chip {
 	u8 enable_dma;
 	u8 bits_per_word;
 	u8 cs_change_per_word;
-	u8 cs_chg_udelay;
+	u16 cs_chg_udelay; /* Some devices require 16-bit delays */
 };
 
 #endif /* _SPI_CHANNEL_H_ */
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH 14/14] Blackfin SPI driver: set correct baud for spi mmc and enable SPI after DMA.
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (12 preceding siblings ...)
  2007-10-30  9:18   ` [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive Bryan Wu
@ 2007-10-30  9:18   ` Bryan Wu
  2007-10-30 20:24   ` [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing David Brownell
  14 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-30  9:18 UTC (permalink / raw)
  To: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
  Cc: Bryan Wu, Sonic Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>

SPI is enabled only after DMA is started.

Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
---
 drivers/spi/spi_bfin5xx.c |   23 +++++++++++++----------
 1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 0b22932..83c866d 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -231,13 +231,13 @@ static int restore_state(struct driver_data *drv_data)
 	dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");
 
 	/* Load the registers */
-	cs_deactive(drv_data, chip);
 	write_BAUD(drv_data, chip->baud);
 	chip->ctl_reg &= (~BIT_CTL_TIMOD);
 	chip->ctl_reg |= (chip->width << 8);
 	write_CTRL(drv_data, chip->ctl_reg);
 
 	bfin_spi_enable(drv_data);
+	cs_active(drv_data, chip);
 
 	if (ret)
 		dev_dbg(&drv_data->pdev->dev,
@@ -767,6 +767,7 @@ static void pump_transfers(unsigned long data)
 
 		disable_dma(drv_data->dma_channel);
 		clear_dma_irqstat(drv_data->dma_channel);
+		bfin_spi_disable(drv_data);
 
 		/* config dma channel */
 		dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
@@ -789,9 +790,6 @@ static void pump_transfers(unsigned long data)
 			dev_dbg(&drv_data->pdev->dev,
 				"doing autobuffer DMA out.\n");
 
-			/* set SPI transfer mode */
-			write_CTRL(drv_data, (cr | CFG_SPI_DMAWRITE));
-
 			/* no irq in autobuffer mode */
 			dma_config =
 			    (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
@@ -800,6 +798,9 @@ static void pump_transfers(unsigned long data)
 					(unsigned long)drv_data->tx);
 			enable_dma(drv_data->dma_channel);
 
+			/* start SPI transfer */
+			write_CTRL(drv_data, (cr | CFG_SPI_DMAWRITE | BIT_CTL_ENABLE));
+
 			/* just return here, there can only be one transfer in this mode */
 			message->status = 0;
 			giveback(drv_data);
@@ -811,9 +812,6 @@ static void pump_transfers(unsigned long data)
 			/* set transfer mode, and enable SPI */
 			dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n");
 
-			/* set SPI transfer mode */
-			write_CTRL(drv_data, (cr | CFG_SPI_DMAREAD));
-
 			/* clear tx reg soformer data is not shifted out */
 			write_TDBR(drv_data, 0xFFFF);
 
@@ -827,12 +825,12 @@ static void pump_transfers(unsigned long data)
 					(unsigned long)drv_data->rx);
 			enable_dma(drv_data->dma_channel);
 
+			/* start SPI transfer */
+			write_CTRL(drv_data, (cr | CFG_SPI_DMAREAD | BIT_CTL_ENABLE));
+
 		} else if (drv_data->tx != NULL) {
 			dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
 
-			/* set SPI transfer mode */
-			write_CTRL(drv_data, (cr | CFG_SPI_DMAWRITE));
-
 			/* start dma */
 			dma_enable_irq(drv_data->dma_channel);
 			dma_config = (RESTART | dma_width | DI_EN);
@@ -840,6 +838,9 @@ static void pump_transfers(unsigned long data)
 			set_dma_start_addr(drv_data->dma_channel,
 					(unsigned long)drv_data->tx);
 			enable_dma(drv_data->dma_channel);
+
+			/* start SPI transfer */
+			write_CTRL(drv_data, (cr | CFG_SPI_DMAWRITE | BIT_CTL_ENABLE));
 		}
 	} else {
 		/* IO mode write then read */
@@ -1138,6 +1139,8 @@ static int setup(struct spi_device *spi)
 		peripheral_request(ssel[spi->master->bus_num]
 			[chip->chip_select_num-1], DRV_NAME);
 
+	cs_deactive(drv_data, chip);
+
 	return 0;
 }
 
-- 
1.5.3.4

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1
  2007-10-30  9:17   ` [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1 Bryan Wu
@ 2007-10-30 19:08     ` David Brownell
       [not found]       ` <200710301208.13367.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-30 19:08 UTC (permalink / raw)
  To: Bryan Wu; +Cc: spi-devel-general, linux-kernel, Sonic Zhang

On Tuesday 30 October 2007, Bryan Wu wrote:
> From: Sonic Zhang <sonic.zhang@analog.com>
> 
> Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
> Signed-off-by: Bryan Wu <bryan.wu@analog.com>

The patch comments in this series leave a bit to be desired,
especially patches from Sonic.  (Several are like this one:
just a $SUBJECT, no description.)  I've improved them in the
versions I'll be sending on ...

It's worth noting that in this case the $SUBJECT doesn't
relate *at all* to what this patch actually does!  Namely,
it uses the portmux mechanism to add support for two more
SPI buses ... it doesn't add a platform device.

- Dave

> ---
>  drivers/spi/spi_bfin5xx.c |   52 ++++++++++++++++++++++++++------------------
>  1 files changed, 31 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
> index 3f3630c..3bd8359 100644
> --- a/drivers/spi/spi_bfin5xx.c
> +++ b/drivers/spi/spi_bfin5xx.c
> @@ -209,17 +209,26 @@ static void cs_deactive(struct chip_data *chip)
>  	write_FLAG(flag);
>  }
>  
> -#define MAX_SPI0_SSEL	7
> +#define MAX_SPI_SSEL	7
>  
>  /* stop controller and re-config current chip*/
>  static int restore_state(struct driver_data *drv_data)
>  {
>  	struct chip_data *chip = drv_data->cur_chip;
>  	int ret = 0;
> -	u16 ssel[MAX_SPI0_SSEL] = {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
> -					P_SPI0_SSEL4, P_SPI0_SSEL5,
> -					P_SPI0_SSEL6, P_SPI0_SSEL7,};
> -
> +	u16 ssel[3][MAX_SPI_SSEL] = {
> +		{P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
> +		P_SPI0_SSEL4, P_SPI0_SSEL5,
> +		P_SPI0_SSEL6, P_SPI0_SSEL7},
> +
> +		{P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3,
> +		P_SPI1_SSEL4, P_SPI1_SSEL5,
> +		P_SPI1_SSEL6, P_SPI1_SSEL7},
> +
> +		{P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3,
> +		P_SPI2_SSEL4, P_SPI2_SSEL5,
> +		P_SPI2_SSEL6, P_SPI2_SSEL7},
> +	};
>  	/* Clear status and disable clock */
>  	write_STAT(BIT_STAT_CLR);
>  	bfin_spi_disable(drv_data);
> @@ -234,9 +243,9 @@ static int restore_state(struct driver_data *drv_data)
>  		int i = chip->chip_select_num;
>  
>  		dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
> -
> -		if ((i > 0) && (i <= MAX_SPI0_SSEL))
> -			ret = peripheral_request(ssel[i-1], DRV_NAME);
> +		if ((i > 0) && (i <= MAX_SPI_SSEL))
> +			ret = peripheral_request(
> +				ssel[drv_data->master->bus_num][i-1], DRV_NAME);
>  
>  		chip->chip_select_requested = 1;
>  	}
> @@ -329,7 +338,6 @@ static void u8_reader(struct driver_data *drv_data)
>  	write_TDBR(0xFFFF);
>  
>  	dummy_read();
> -
>  	while (drv_data->rx < drv_data->rx_end - 1) {
>  		while (!(read_STAT() & BIT_STAT_RXS))
>  			continue;
> @@ -640,7 +648,6 @@ static void pump_transfers(unsigned long data)
>  	message = drv_data->cur_msg;
>  	transfer = drv_data->cur_transfer;
>  	chip = drv_data->cur_chip;
> -
>  	/*
>  	 * if msg is error or done, report it back using complete() callback
>  	 */
> @@ -1202,17 +1209,20 @@ static inline int destroy_queue(struct driver_data *drv_data)
>  	return 0;
>  }
>  
> -static int setup_pin_mux(int action)
> +static int setup_pin_mux(int action, int bus_num)
>  {
>  
> -	u16 pin_req[] = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0};
> +	u16 pin_req[3][4] = {
> +		{P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
> +		{P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
> +		{P_SPI2_SCK, P_SPI2_MISO, P_SPI2_MOSI, 0},
> +	};
>  
>  	if (action) {
> -		if (peripheral_request_list(pin_req, DRV_NAME)) {
> +		if (peripheral_request_list(pin_req[bus_num], DRV_NAME))
>  			return -EFAULT;
> -		}
>  	} else {
> -		peripheral_free_list(pin_req);
> +		peripheral_free_list(pin_req[bus_num]);
>  	}
>  
>  	return 0;
> @@ -1236,11 +1246,6 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	}
>  
> -	if (setup_pin_mux(1)) {
> -		dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
> -		goto out_error;
> -	}
> -
>  	drv_data = spi_master_get_devdata(master);
>  	drv_data->master = master;
>  	drv_data->master_info = platform_info;
> @@ -1295,6 +1300,11 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
>  		goto out_error_queue_alloc;
>  	}
>  
> +	if (setup_pin_mux(1, master->bus_num)) {
> +		dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
> +		goto out_error;
> +	}
> +
>  	dev_info(dev, "%s, Version %s, regs_base @ 0x%08x\n",
>  		DRV_DESC, DRV_VERSION, spi_regs_base);
>  	return status;
> @@ -1337,7 +1347,7 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
>  	/* Disconnect from the SPI framework */
>  	spi_unregister_master(drv_data->master);
>  
> -	setup_pin_mux(0);
> +	setup_pin_mux(0, drv_data->master->bus_num);
>  
>  	/* Prevent double remove */
>  	platform_set_drvdata(pdev, NULL);
> -- 
> 1.5.3.4
> 

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
  2007-10-30  9:18   ` [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548 Bryan Wu
@ 2007-10-30 20:05     ` David Brownell
  2007-10-31  6:50       ` Bryan Wu
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-30 20:05 UTC (permalink / raw)
  To: Bryan Wu; +Cc: spi-devel-general, linux-kernel, Sonic Zhang

On Tuesday 30 October 2007, Bryan Wu wrote:
> Current SPI driver enables SPI controller and set the SPI baud register
> for each SPI transfer. But, they should never be changed within a SPI
> message session, in which seveal SPI transfers are pumped.

That's actually not true.  If a driver sets spi_transfer.max_speed_hz
to a nonzero value that's different from the previous bit rate (which
may be spi_device.max_speed_hz), it should be updated before that
transfer segment.  Example, sometimes data can't be clocked out at
the same rate commands can be clocked in.

Similarly with spi_transfer.bits_per_word ... again, it's very possible
that commands and data have different sizes.

Of course, if those values don't change, there'd be no point in
reconfiguring any aspect of those communications parameters...


I'll be forwarding this patch, since this looks like another case
where the main effect of the patch doesn't match its description
and since this patch series has taken too long already.  (Does this
patch even really relate primarily to working with an ST M25P16
flash part??)  Though it'd be reasonable to be more hard-nosed
about this and insist on another go-around for thesse patches.
(Making this the fifth one??)

But I *STRONGLY* suggest someone revisit the issue of whether those
two per-transfer options are now being handled correctly.  As well
as update procedures so that the patch comments start to have a
direct correspondence to what the patches have changed...

- Dave


> This patch 
> move move SPI setting to the begining of a message session. And never
> disables SPI controller until an error occurs.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive
       [not found]     ` <1193735885-8202-14-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
@ 2007-10-30 20:18       ` David Brownell
       [not found]         ` <200710301319.00071.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-30 20:18 UTC (permalink / raw)
  To: Bryan Wu
  Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Cameron Barfield

On Tuesday 30 October 2007, Bryan Wu wrote:
> @@ -211,6 +211,10 @@ static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
>         flag |= (chip->flag << 8);
>  
>         write_FLAG(drv_data, flag);
> +
> +       /* Move delay here for consistency */
> +       if (chip->cs_chg_udelay)
> +               udelay(chip->cs_chg_udelay);
>  }
>  

By the way, if this is something needed very often, that mechanism
should be moved into the SPI framework.  It wouldn't be polite if
such LCD drivers could only work on Blackfin boards.  :)


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing
       [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
                     ` (13 preceding siblings ...)
  2007-10-30  9:18   ` [PATCH 14/14] Blackfin SPI driver: set correct baud for spi mmc and enable SPI after DMA Bryan Wu
@ 2007-10-30 20:24   ` David Brownell
       [not found]     ` <200710301324.07691.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  14 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-30 20:24 UTC (permalink / raw)
  To: Bryan Wu
  Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tuesday 30 October 2007, Bryan Wu wrote:
>  - BF54x supported
>  - multi-port supported
>  - bunch of bug fixing 

OK, I forwarded these with some more checkpatch.pl fixes.

But as I commented elsewhere, please work harder to make sure
that your patch comments actually match the patches!!

And also, pay closer attention to when you may be making
changes that make device drivers work differently over
your spi_master controller driver than anyone elses ...
such platform-specific behaviors are undesirable, and when
they go against specified behavior they are also bugs.

- Dave



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing
       [not found]     ` <200710301324.07691.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-30 20:29       ` Mike Frysinger
       [not found]         ` <8bd0f97a0710301329i8a21b22ncc9f71a81bc06543-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2007-10-30 20:29 UTC (permalink / raw)
  To: David Brownell
  Cc: Bryan Wu, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/30/07, David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> wrote:
> And also, pay closer attention to when you may be making
> changes that make device drivers work differently over
> your spi_master controller driver than anyone elses ...
> such platform-specific behaviors are undesirable, and when
> they go against specified behavior they are also bugs.

was there something that caught your eye other than the ugly udelay()
you mentioned in the other thread ?
-mike

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing
       [not found]         ` <8bd0f97a0710301329i8a21b22ncc9f71a81bc06543-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2007-10-30 20:42           ` David Brownell
       [not found]             ` <200710301342.18559.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-30 20:42 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Bryan Wu, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tuesday 30 October 2007, Mike Frysinger wrote:
> On 10/30/07, David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> wrote:
> > And also, pay closer attention to when you may be making
> > changes that make device drivers work differently over
> > your spi_master controller driver than anyone elses ...
> > such platform-specific behaviors are undesirable, and when
> > they go against specified behavior they are also bugs.
> 
> was there something that caught your eye other than the ugly udelay()
> you mentioned in the other thread ?

That one was a feature that might be more generally necessary,
just to meet chip timing specs.  Mostly they're no trouble.
But sometimes there are constraints around chipselect, or at
particular points in a protocol exchange ... as you know, SPI
has no in-band synchronization, so timing delays are about as
good as any standardized infrastructure can get.  So if that
particular timing tweak was essential to make that driver work,
it might be something the API should address -- instead of just
a particular controller.

The other point was the handling of the two spi_transfer protocol
tweaking options.  The comment went against the interface spec.
Now, maybe that was an issue of weak English skills ... but from
my scanning the patch, I got the impression one intent of that
patch really was to do what the comment said.  (Of course it did
a lot of other stuff, which looked less dubious and might have
had a lot more to do with why the patch made that m25p16 chip
behave on that new board.)

- Dave

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing
       [not found]             ` <200710301342.18559.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-30 20:54               ` David Brownell
  0 siblings, 0 replies; 34+ messages in thread
From: David Brownell @ 2007-10-30 20:54 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Bryan Wu, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tuesday 30 October 2007, David Brownell wrote:
> > 
> > was there something that caught your eye other than the ugly udelay()
> > you mentioned in the other thread ?
> 
> That one was a feature that might be more generally necessary,
> just to meet chip timing specs.  Mostly they're no trouble.
> 

... although I note that the referenced thread suggested maybe
the problem there was a missing pullup on the chipselect line.  If
that was really the cause, then I think that feature would best
be left out of the framework.  :)



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1
       [not found]       ` <200710301208.13367.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-31  4:18         ` Bryan Wu
  0 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-31  4:18 UTC (permalink / raw)
  To: David Brownell
  Cc: Bryan Wu, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	Sonic Zhang, linux-kernel-u79uwXL29TY76Z2rM5mHXA


On Tue, 2007-10-30 at 12:08 -0700, David Brownell wrote:
> On Tuesday 30 October 2007, Bryan Wu wrote:
> > From: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
> > 
> > Signed-off-by: Sonic Zhang <sonic.zhang-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
> > Signed-off-by: Bryan Wu <bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
> 
> The patch comments in this series leave a bit to be desired,
> especially patches from Sonic.  (Several are like this one:
> just a $SUBJECT, no description.)  I've improved them in the
> versions I'll be sending on ...
> 
Sorry, that's my fault. 

Sonic's original patch modified this driver file and the Blackfin arch
related files. So I separated the patch to this SPI driver specific code
and Blackfin arch related patch which should be merged in Blackfin git
tree.

But I didn't change the description and subject here.

> It's worth noting that in this case the $SUBJECT doesn't
> relate *at all* to what this patch actually does!  Namely,
> it uses the portmux mechanism to add support for two more
> SPI buses ... it doesn't add a platform device.
> 

Sorry again, it will not happen again.

-Bryan Wu

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive
       [not found]         ` <200710301319.00071.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-31  6:30           ` Bryan Wu
  2007-10-31 19:04             ` Cameron Barfield
  0 siblings, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-31  6:30 UTC (permalink / raw)
  To: David Brownell, Cameron Barfield
  Cc: Bryan Wu, spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA


On Tue, 2007-10-30 at 13:18 -0700, David Brownell wrote:
> On Tuesday 30 October 2007, Bryan Wu wrote:
> > @@ -211,6 +211,10 @@ static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
> >         flag |= (chip->flag << 8);
> >  
> >         write_FLAG(drv_data, flag);
> > +
> > +       /* Move delay here for consistency */
> > +       if (chip->cs_chg_udelay)
> > +               udelay(chip->cs_chg_udelay);
> >  }
> >  
> 
> By the way, if this is something needed very often, that mechanism
> should be moved into the SPI framework.  It wouldn't be polite if
> such LCD drivers could only work on Blackfin boards.  :)

I am not sure whether this LCD needs cs_chg_udelay on other boards.
It is found by Cameron Barfield. Maybe it is some timing requirement for
specific hardware.

-Bryan Wu

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
  2007-10-30 20:05     ` David Brownell
@ 2007-10-31  6:50       ` Bryan Wu
  2007-10-31  7:11         ` David Brownell
  0 siblings, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-31  6:50 UTC (permalink / raw)
  To: David Brownell; +Cc: Bryan Wu, spi-devel-general, linux-kernel, Sonic Zhang


On Tue, 2007-10-30 at 13:05 -0700, David Brownell wrote:
> On Tuesday 30 October 2007, Bryan Wu wrote:
> > Current SPI driver enables SPI controller and set the SPI baud register
> > for each SPI transfer. But, they should never be changed within a SPI
> > message session, in which seveal SPI transfers are pumped.
> 
> That's actually not true.  If a driver sets spi_transfer.max_speed_hz
> to a nonzero value that's different from the previous bit rate (which
> may be spi_device.max_speed_hz), it should be updated before that
> transfer segment.  Example, sometimes data can't be clocked out at
> the same rate commands can be clocked in.
> 
> Similarly with spi_transfer.bits_per_word ... again, it's very possible
> that commands and data have different sizes.
> 
I agree with you here. 

Maybe there are some confusion of mixing up the spi_trasnfer.speed_hz
with the spi_device.max_speed_hz.

spi_device.max_speed_hz comes from spi_board_info.max_speed_hz, it is
for the default max speed value.
spi_transfer.speed_hz comes from upper applications for each spi
transfer setting.

Am I right?

I will fix this later.

> Of course, if those values don't change, there'd be no point in
> reconfiguring any aspect of those communications parameters...
> 
> 
> I'll be forwarding this patch, since this looks like another case
> where the main effect of the patch doesn't match its description
> and since this patch series has taken too long already.  (Does this
> patch even really relate primarily to working with an ST M25P16
> flash part??)  Though it'd be reasonable to be more hard-nosed
> about this and insist on another go-around for thesse patches.
> (Making this the fifth one??)
> 
> But I *STRONGLY* suggest someone revisit the issue of whether those
> two per-transfer options are now being handled correctly.  As well
> as update procedures so that the patch comments start to have a
> direct correspondence to what the patches have changed...
> 

OK, we will test this on our hardware.
Thanks, Dave
-Bryan Wu

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
  2007-10-31  6:50       ` Bryan Wu
@ 2007-10-31  7:11         ` David Brownell
       [not found]           ` <200710310011.33545.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-31  7:11 UTC (permalink / raw)
  To: bryan.wu-OyLXuOCK7orQT0dZR+AlfA
  Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tuesday 30 October 2007, Bryan Wu wrote:
> Maybe there are some confusion of mixing up the spi_trasnfer.speed_hz
> with the spi_device.max_speed_hz.
> 
> spi_device.max_speed_hz comes from spi_board_info.max_speed_hz, it is
> for the default max speed value.

It's initialized from board_info, yes.  Drivers can override it
using spi_setup().

One would expect they only override _downwards_ but that's not
guaranteed anywhere.  A driver might have a way to establish that
this particular board can run faster, for example.


> spi_transfer.speed_hz comes from upper applications for each spi
> transfer setting.

Certainly; all spi_transfer records come from applications!
If that value is zero, that transfer segment uses the limit
from the spi_device ... otherwise, it can differ.  Again,
the limits can vary based on devise characteristics; maybe
it can't feed data as fast for some commands.

(ISTR the M25P16 in $SUBJECT has two read commands, one of
which is only usable at clock rates below 33 MHz or so, but
most other commands can work above that speed just fine.)

- Dave

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found]           ` <200710310011.33545.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-31  7:35             ` Bryan Wu
  2007-10-31  8:02               ` David Brownell
  2007-10-31  8:33             ` Mike Frysinger
  1 sibling, 1 reply; 34+ messages in thread
From: Bryan Wu @ 2007-10-31  7:35 UTC (permalink / raw)
  To: David Brownell
  Cc: bryan.wu-OyLXuOCK7orQT0dZR+AlfA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA


On Wed, 2007-10-31 at 00:11 -0700, David Brownell wrote:
> On Tuesday 30 October 2007, Bryan Wu wrote:
> > Maybe there are some confusion of mixing up the spi_trasnfer.speed_hz
> > with the spi_device.max_speed_hz.
> > 
> > spi_device.max_speed_hz comes from spi_board_info.max_speed_hz, it is
> > for the default max speed value.
> 
> It's initialized from board_info, yes.  Drivers can override it
> using spi_setup().
> 
> One would expect they only override _downwards_ but that's not
> guaranteed anywhere.  A driver might have a way to establish that
> this particular board can run faster, for example.
> 

IMO, the spi_transfer.speed_hz <= spi_board_info.max_speed_hz and if
spi_trasnfer.speed_hz is 0, we should use spi_board_info.max_speed_hz.
>From the meaning of max_speed_hz, the spi_transfer.speed_hz should not
beyond max_speed_hz.

In your explanation, the max_speed_hz is just a default value. the
transfer speed_hz can beyond max_speed_hz. We found the bug in M25P16
should be related this missing checking of the transfer  speed_hz.

> 
> > spi_transfer.speed_hz comes from upper applications for each spi
> > transfer setting.
> 
> Certainly; all spi_transfer records come from applications!
> If that value is zero, that transfer segment uses the limit
> from the spi_device ... otherwise, it can differ.  Again,
> the limits can vary based on devise characteristics; maybe
> it can't feed data as fast for some commands.
> 
> (ISTR the M25P16 in $SUBJECT has two read commands, one of
> which is only usable at clock rates below 33 MHz or so, but
> most other commands can work above that speed just fine.)
> 
OK, We check it on Blackfin board.
-Bryan Wu

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
  2007-10-31  7:35             ` Bryan Wu
@ 2007-10-31  8:02               ` David Brownell
       [not found]                 ` <200710310102.36542.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-31  8:02 UTC (permalink / raw)
  To: bryan.wu-OyLXuOCK7orQT0dZR+AlfA
  Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wednesday 31 October 2007, Bryan Wu wrote:
> IMO, the spi_transfer.speed_hz <= spi_board_info.max_speed_hz and if
> spi_trasnfer.speed_hz is 0, we should use spi_board_info.max_speed_hz.
> From the meaning of max_speed_hz, the spi_transfer.speed_hz should not
> beyond max_speed_hz.

According to the interface spec that's not how it works; so I'm
not sure what you base your opinion on.  It's not defined with
such constraints.

That might be a reasonable policy to adopt in many cases, and
nothing prevents any given protocol driver from choosing to follow
it.  But likewise, if the driver chooses _not_ to follow it, it's
wrong for a controller driver to add its own private rules.


> In your explanation, the max_speed_hz is just a default value. the
> transfer speed_hz can beyond max_speed_hz.

Kerneldoc for board info says;

 * @max_speed_hz: Initializes spi_device.max_speed_hz; based on limits
 *      from the chip datasheet and board-specific signal quality issues.

So yes -- initial value, it can be changed.  If a driver says

	spi->max_speed_hz = X;
	spi_setup(spi);

that's how it requests a different clock rate ceiling.  It can lower
the rate; it can raise it.


The reason it's called max_speed_hz is that most systems compute the
clock rate by dividing a base clock, and few can achieve that exact
value.  The name indicates that it's to be treated as an upper limit,
not a lower limit or exact value.  The controller driver should get
as close to that rate as it can, without going over.


> We found the bug in M25P16 
> should be related this missing checking of the transfer  speed_hz.

The m25p80 driver doesn't change that value...

So if there was any issue there, it must have been related to
something else in your controller driver.

- Dave

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found]           ` <200710310011.33545.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  2007-10-31  7:35             ` Bryan Wu
@ 2007-10-31  8:33             ` Mike Frysinger
       [not found]               ` <8bd0f97a0710310133m7b5cbbf3j545a489c401185df-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2007-10-31  8:33 UTC (permalink / raw)
  To: David Brownell
  Cc: bryan.wu-OyLXuOCK7orQT0dZR+AlfA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/31/07, David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> wrote:
> (ISTR the M25P16 in $SUBJECT has two read commands, one of
> which is only usable at clock rates below 33 MHz or so, but
> most other commands can work above that speed just fine.)

pretty much all SPI flashes have two read commands ("slow" and "fast"
as they're typically called).  i dont think any of the linux drivers
though use the "slow" reads with any SPI flashes ... that'd be silly
:)
-mike

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found]                 ` <200710310102.36542.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-31  8:52                   ` Bryan Wu
  0 siblings, 0 replies; 34+ messages in thread
From: Bryan Wu @ 2007-10-31  8:52 UTC (permalink / raw)
  To: David Brownell
  Cc: bryan.wu-OyLXuOCK7orQT0dZR+AlfA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA


On Wed, 2007-10-31 at 01:02 -0700, David Brownell wrote:
> On Wednesday 31 October 2007, Bryan Wu wrote:
> > IMO, the spi_transfer.speed_hz <= spi_board_info.max_speed_hz and if
> > spi_trasnfer.speed_hz is 0, we should use spi_board_info.max_speed_hz.
> > From the meaning of max_speed_hz, the spi_transfer.speed_hz should not
> > beyond max_speed_hz.
> 
> According to the interface spec that's not how it works; so I'm
> not sure what you base your opinion on.  It's not defined with
> such constraints.
> 
My opinion is based on the name of max_speed_hz.
Actually, I know it is for the controller to compute the baud rate from
system bus clock or something similar.

> That might be a reasonable policy to adopt in many cases, and
> nothing prevents any given protocol driver from choosing to follow
> it.  But likewise, if the driver chooses _not_ to follow it, it's
> wrong for a controller driver to add its own private rules.
> 
> > In your explanation, the max_speed_hz is just a default value. the
> > transfer speed_hz can beyond max_speed_hz.
> 
> Kerneldoc for board info says;
> 
>  * @max_speed_hz: Initializes spi_device.max_speed_hz; based on limits
>  *      from the chip datasheet and board-specific signal quality issues.
> 
> So yes -- initial value, it can be changed.  If a driver says
> 
> 	spi->max_speed_hz = X;
> 	spi_setup(spi);
> 
> that's how it requests a different clock rate ceiling.  It can lower
> the rate; it can raise it.
> 
> 
> The reason it's called max_speed_hz is that most systems compute the
> clock rate by dividing a base clock, and few can achieve that exact
> value.  The name indicates that it's to be treated as an upper limit,
> not a lower limit or exact value.  The controller driver should get
> as close to that rate as it can, without going over.
> 

Thanks for this clarification.
max_speed_hz acts as a default clock rate ceiling in the spi_setup(spi)
At the beginning of each real spi transfer, we should check the
spi_transfer.speed_hz like this:

---
		/* Speed setup (surely valid because already checked) */
		tmp = transfer->speed_hz;
		if (tmp == 0)
			tmp = chip->max_speed_hz;
		spi_set_baud_rate(tmp);
---

-Bryan

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found]               ` <8bd0f97a0710310133m7b5cbbf3j545a489c401185df-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2007-10-31 19:01                 ` David Brownell
       [not found]                   ` <200710311201.29643.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: David Brownell @ 2007-10-31 19:01 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: bryan.wu-OyLXuOCK7orQT0dZR+AlfA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wednesday 31 October 2007, Mike Frysinger wrote:
> On 10/31/07, David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> wrote:
> > (ISTR the M25P16 in $SUBJECT has two read commands, one of
> > which is only usable at clock rates below 33 MHz or so, but
> > most other commands can work above that speed just fine.)
> 
> pretty much all SPI flashes have two read commands ("slow" and "fast"
> as they're typically called). 

Not DataFlash.  But many other modern flash chips do, like
most of the ones handled by the m25p80 driver.   As noted
there in the comment about how it should switch over to use
the fast read command ...


> i dont think any of the linux drivers though use the "slow"
> reads with any SPI flashes ... that'd be silly  :)

Considering the m25p80 driver started on a uClinux platform
that ISTR couldn't achieve the 33+ MHz clock rates for SPI,
it doesn't seem at all odd to me!

And in fact, lots of Linux systems for some reason don't
seem to be able to clock SPI that fast, even if a given
board were laid out to handle 50+ MHz signaling there.

- Dave

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive
  2007-10-31  6:30           ` Bryan Wu
@ 2007-10-31 19:04             ` Cameron Barfield
  0 siblings, 0 replies; 34+ messages in thread
From: Cameron Barfield @ 2007-10-31 19:04 UTC (permalink / raw)
  To: bryan.wu-OyLXuOCK7orQT0dZR+AlfA
  Cc: David Brownell,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

It may be hardware specific for our board, but my thought is that any device should be
able to take advantage of the cs_chg_udelay regardless of which write function it uses.

As far as I can see, there is no where else to make a clean change to allow devices that
use the "normal" write function the ability to take advantage of cs_chg_udelay.



Bryan Wu wrote:
> On Tue, 2007-10-30 at 13:18 -0700, David Brownell wrote:
>> On Tuesday 30 October 2007, Bryan Wu wrote:
>>> @@ -211,6 +211,10 @@ static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip)
>>>         flag |= (chip->flag << 8);
>>>  
>>>         write_FLAG(drv_data, flag);
>>> +
>>> +       /* Move delay here for consistency */
>>> +       if (chip->cs_chg_udelay)
>>> +               udelay(chip->cs_chg_udelay);
>>>  }
>>>  
>> By the way, if this is something needed very often, that mechanism
>> should be moved into the SPI framework.  It wouldn't be polite if
>> such LCD drivers could only work on Blackfin boards.  :)
> 
> I am not sure whether this LCD needs cs_chg_udelay on other boards.
> It is found by Cameron Barfield. Maybe it is some timing requirement for
> specific hardware.
> 
> -Bryan Wu
> 
> 

- --
NOTICE AND DISCLAIMER:

This e-mail message and any attachments may contain confidential information intended
solely for the specified individual(s).
If you are not the intended recipient, you are prohibited from viewing, disseminating,
copying, disclosing, or relying upon this
message or any attachment in any way.

If you received this e-mail in error, you should (1) immediately notify the sender by
forwarding this e-mail to him, her, or it and
(2) delete the original e-mail message and all attachments without reading or saving any
of them in any manner.

CyberData Corporation does not accept liability for any damage caused by any virus
transmitted through this e-mail or its
attachments.  CyberData Corporation does not accept liability for any errors or omissions
in the contents of this e-mail
message or any of its attachments.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHKNGq49ZuPDUolt0RAqq/AJ4pU67Hopp42saSVhxAbSHXK8CPCgCfTjTx
ky1p5ou7vrNBTR4VB3b9zQc=
=3UiY
-----END PGP SIGNATURE-----

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found]                   ` <200710311201.29643.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
@ 2007-10-31 19:16                     ` Mike Frysinger
       [not found]                       ` <8bd0f97a0710311216l25f89b37v356fd44d7c1999da-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 34+ messages in thread
From: Mike Frysinger @ 2007-10-31 19:16 UTC (permalink / raw)
  To: David Brownell
  Cc: bryan.wu-OyLXuOCK7orQT0dZR+AlfA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/31/07, David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> wrote:
> On Wednesday 31 October 2007, Mike Frysinger wrote:
> > On 10/31/07, David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org> wrote:
> > > (ISTR the M25P16 in $SUBJECT has two read commands, one of
> > > which is only usable at clock rates below 33 MHz or so, but
> > > most other commands can work above that speed just fine.)
> >
> > pretty much all SPI flashes have two read commands ("slow" and "fast"
> > as they're typically called).
>
> Not DataFlash.

doesnt it ?  AT45DB642D says 0x0B is fast (up to 66mhz) while 0x03 (up to 33mhz)
-mike

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548
       [not found]                       ` <8bd0f97a0710311216l25f89b37v356fd44d7c1999da-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2007-10-31 20:14                         ` David Brownell
  0 siblings, 0 replies; 34+ messages in thread
From: David Brownell @ 2007-10-31 20:14 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: bryan.wu-OyLXuOCK7orQT0dZR+AlfA,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Sonic Zhang,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

> > > pretty much all SPI flashes have two read commands ("slow" and "fast"
> > > as they're typically called).
> >
> > Not DataFlash.
> 
> doesnt it ?  AT45DB642D says 0x0B is fast (up to 66mhz) while 0x03 (up to 33mhz)

And ...041B, ...081B, ...161B, ...321, ...321C, and others don't.
(From a quick scan of datasheets I have locally...)

Those 0x0B and 0x03 commands are "new", and have never been
used by the Linux DataFlash drivers.


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2007-10-31 20:14 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-30  9:17 [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing Bryan Wu
     [not found] ` <1193735885-8202-1-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
2007-10-30  9:17   ` [PATCH 01/14] Blackfin SPI driver: Initial supporting BF54x in SPI driver Bryan Wu
2007-10-30  9:17   ` [PATCH 02/14] Blackfin SPI driver: use new GPIO API and add error handling Bryan Wu
2007-10-30  9:17   ` [PATCH 03/14] Blackfin SPI driver: add error handing Bryan Wu
2007-10-30  9:17   ` [PATCH 04/14] Blackfin SPI driver: Blackfin SPI driver does not respect the per-transfer cs_change field Bryan Wu
2007-10-30  9:17   ` [PATCH 05/14] Blackfin SPI driver: prevent people from setting bits in ctl_reg Bryan Wu
2007-10-30  9:17   ` [PATCH 06/14] Blackfin SPI driver: update spi driver to support multi-ports Bryan Wu
2007-10-30  9:17   ` [PATCH 07/14] Blackfin SPI driver: Add SPI master controller platform device 1 Bryan Wu
2007-10-30 19:08     ` David Brownell
     [not found]       ` <200710301208.13367.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-31  4:18         ` Bryan Wu
2007-10-30  9:17   ` [PATCH 08/14] Blackfin SPI driver: Move GPIO config to setup and cleanup Bryan Wu
2007-10-30  9:18   ` [PATCH 09/14] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548 Bryan Wu
2007-10-30 20:05     ` David Brownell
2007-10-31  6:50       ` Bryan Wu
2007-10-31  7:11         ` David Brownell
     [not found]           ` <200710310011.33545.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-31  7:35             ` Bryan Wu
2007-10-31  8:02               ` David Brownell
     [not found]                 ` <200710310102.36542.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-31  8:52                   ` Bryan Wu
2007-10-31  8:33             ` Mike Frysinger
     [not found]               ` <8bd0f97a0710310133m7b5cbbf3j545a489c401185df-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-10-31 19:01                 ` David Brownell
     [not found]                   ` <200710311201.29643.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-31 19:16                     ` Mike Frysinger
     [not found]                       ` <8bd0f97a0710311216l25f89b37v356fd44d7c1999da-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-10-31 20:14                         ` David Brownell
2007-10-30  9:18   ` [PATCH 10/14] Blackfin SPI driver: Clean up useless wait in bfin SPI driver Bryan Wu
2007-10-30  9:18   ` [PATCH 11/14] Blackfin SPI driver: Move global SPI regs_base and dma_ch to struct driver_data Bryan Wu
2007-10-30  9:18   ` [PATCH 12/14] Blackfin SPI driver: Fix bug in u16_cs_chg_reader to read data_len-2 bytes data firstly, then read out the last 2 bytes data Bryan Wu
2007-10-30  9:18   ` [PATCH 13/14] Blackfin SPI driver: Move cs_chg_udelay to cs_deactive to fix bug when some SPI LCD driver needs delay after cs_deactive Bryan Wu
     [not found]     ` <1193735885-8202-14-git-send-email-bryan.wu-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
2007-10-30 20:18       ` David Brownell
     [not found]         ` <200710301319.00071.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-31  6:30           ` Bryan Wu
2007-10-31 19:04             ` Cameron Barfield
2007-10-30  9:18   ` [PATCH 14/14] Blackfin SPI driver: set correct baud for spi mmc and enable SPI after DMA Bryan Wu
2007-10-30 20:24   ` [PATCH 00/14] Blackfin on-chip SPI controller driver updates and bug-fixing David Brownell
     [not found]     ` <200710301324.07691.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-30 20:29       ` Mike Frysinger
     [not found]         ` <8bd0f97a0710301329i8a21b22ncc9f71a81bc06543-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-10-30 20:42           ` David Brownell
     [not found]             ` <200710301342.18559.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2007-10-30 20:54               ` David Brownell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).