Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 02/12] scsi/cumana_1: Remove unused cumanascsi_setup() function
From: Finn Thain @ 2016-10-06 23:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475791899.git.fthain@telegraphics.com.au>

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/arm/cumana_1.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index 8e9cfe8..f616756 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -33,10 +33,6 @@
 
 #include "../NCR5380.h"
 
-void cumanascsi_setup(char *str, int *ints)
-{
-}
-
 #define CTRL	0x16fc
 #define STAT	0x2004
 #define L(v)	(((v)<<16)|((v) & 0x0000ffff))
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 10/12] scsi/ncr5380: Expedite register polling
From: Finn Thain @ 2016-10-06 23:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475791899.git.fthain@telegraphics.com.au>

Avoid the call to NCR5380_poll_politely2() when possible. The call is
easily short-circuited on the PIO fast path, using the inline wrapper.
This requires that the NCR5380_read macro be made available before
any #include "NCR5380.h" so a few declarations have to be moved too.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/NCR5380.h      | 3 +++
 drivers/scsi/arm/cumana_1.c | 4 ++++
 drivers/scsi/atari_scsi.c   | 6 +++---
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 4682baa..b2c560c 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -310,6 +310,9 @@ static inline int NCR5380_poll_politely(struct NCR5380_hostdata *hostdata,
                                         unsigned int reg, u8 bit, u8 val,
                                         unsigned long wait)
 {
+	if ((NCR5380_read(reg) & bit) == val)
+		return 0;
+
 	return NCR5380_poll_politely2(hostdata, reg, bit, val,
 						reg, bit, val, wait);
 }
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index ae1d4c6..fb7600d 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -29,6 +29,10 @@
 #define NCR5380_implementation_fields	\
 	unsigned ctrl
 
+struct NCR5380_hostdata;
+static u8 cumanascsi_read(struct NCR5380_hostdata *, unsigned int);
+static void cumanascsi_write(struct NCR5380_hostdata *, unsigned int, u8);
+
 #include "../NCR5380.h"
 
 #define CTRL	0x16fc
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index aed69ac..f77c311 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -57,6 +57,9 @@
 
 #define NCR5380_implementation_fields   /* none */
 
+static u8 (*atari_scsi_reg_read)(unsigned int);
+static void (*atari_scsi_reg_write)(unsigned int, u8);
+
 #define NCR5380_read(reg)               atari_scsi_reg_read(reg)
 #define NCR5380_write(reg, value)       atari_scsi_reg_write(reg, value)
 
@@ -126,9 +129,6 @@ static inline unsigned long SCSI_DMA_GETADR(void)
 
 static void atari_scsi_fetch_restbytes(void);
 
-static u8 (*atari_scsi_reg_read)(unsigned int);
-static void (*atari_scsi_reg_write)(unsigned int, u8);
-
 static unsigned long	atari_dma_residual, atari_dma_startaddr;
 static short		atari_dma_active;
 /* pointer to the dribble buffer */
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 08/12] scsi/ncr5380: Use correct types for device register accessors
From: Finn Thain @ 2016-10-06 23:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475791899.git.fthain@telegraphics.com.au>

For timeout values adopt unsigned long, which is the type of jiffies etc.

For chip register values and bit masks pass u8, which is the return type
of readb, inb etc.

For device register offsets adopt unsigned int, as it is suitable for
adding to base addresses.

Pass the NCR5380_hostdata pointer to the board-specific routines instead
of the Scsi_Host pointer. The board-specific code is concerned with
hardware and not with SCSI protocol or the mid-layer.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/NCR5380.c      | 10 ++++++++--
 drivers/scsi/NCR5380.h      |  7 +++++--
 drivers/scsi/arm/cumana_1.c | 20 +++++++++++---------
 drivers/scsi/arm/oak.c      |  6 ++----
 drivers/scsi/atari_scsi.c   | 16 ++++++++--------
 drivers/scsi/dmx3191d.c     |  6 ++----
 drivers/scsi/g_NCR5380.h    |  8 ++------
 drivers/scsi/mac_scsi.c     | 22 ++--------------------
 drivers/scsi/sun3_scsi.c    | 32 +++++++++-----------------------
 9 files changed, 49 insertions(+), 78 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 82fd37d..eb40561 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -196,8 +196,9 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
  */
 
 static int NCR5380_poll_politely2(struct Scsi_Host *instance,
-                                  int reg1, int bit1, int val1,
-                                  int reg2, int bit2, int val2, int wait)
+                                  unsigned int reg1, u8 bit1, u8 val1,
+                                  unsigned int reg2, u8 bit2, u8 val2,
+                                  unsigned long wait)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned long n = hostdata->poll_loops;
@@ -284,6 +285,7 @@ mrs[] = {
 
 static void NCR5380_print(struct Scsi_Host *instance)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char status, data, basr, mr, icr, i;
 
 	data = NCR5380_read(CURRENT_SCSI_DATA_REG);
@@ -333,6 +335,7 @@ static struct {
 
 static void NCR5380_print_phase(struct Scsi_Host *instance)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char status;
 	int i;
 
@@ -1316,6 +1319,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
 				unsigned char *phase, int *count,
 				unsigned char **data)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char p = *phase, tmp;
 	int c = *count;
 	unsigned char *d = *data;
@@ -1438,6 +1442,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
 
 static void do_reset(struct Scsi_Host *instance)
 {
+	struct NCR5380_hostdata __maybe_unused *hostdata = shost_priv(instance);
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -1460,6 +1465,7 @@ static void do_reset(struct Scsi_Host *instance)
 
 static int do_abort(struct Scsi_Host *instance)
 {
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char *msgptr, phase, tmp;
 	int len;
 	int rc;
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 02f20ff..c2d8b78 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -302,10 +302,13 @@ static void NCR5380_reselect(struct Scsi_Host *instance);
 static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
 static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
 static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
-static int NCR5380_poll_politely2(struct Scsi_Host *, int, int, int, int, int, int, int);
+static int NCR5380_poll_politely2(struct Scsi_Host *,
+                                  unsigned int, u8, u8,
+                                  unsigned int, u8, u8, unsigned long);
 
 static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
-					int reg, int bit, int val, int wait)
+                                        unsigned int reg, u8 bit, u8 val,
+                                        unsigned long wait)
 {
 	return NCR5380_poll_politely2(instance, reg, bit, val,
 						reg, bit, val, wait);
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index 88db281..ae1d4c6 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -14,8 +14,8 @@
 #include <scsi/scsi_host.h>
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
-#define NCR5380_read(reg)		cumanascsi_read(instance, reg)
-#define NCR5380_write(reg, value)	cumanascsi_write(instance, reg, value)
+#define NCR5380_read(reg)		cumanascsi_read(hostdata, reg)
+#define NCR5380_write(reg, value)	cumanascsi_write(hostdata, reg, value)
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
 #define NCR5380_dma_recv_setup		cumanascsi_pread
@@ -169,30 +169,32 @@ end:
 	return 0;
 }
 
-static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
+static u8 cumanascsi_read(struct NCR5380_hostdata *hostdata,
+                          unsigned int reg)
 {
-	u8 __iomem *base = priv(host)->io;
-	unsigned char val;
+	u8 __iomem *base = hostdata->io;
+	u8 val;
 
 	writeb(0, base + CTRL);
 
 	val = readb(base + 0x2100 + (reg << 2));
 
-	priv(host)->ctrl = 0x40;
+	hostdata->ctrl = 0x40;
 	writeb(0x40, base + CTRL);
 
 	return val;
 }
 
-static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value)
+static void cumanascsi_write(struct NCR5380_hostdata *hostdata,
+                             unsigned int reg, u8 value)
 {
-	u8 __iomem *base = priv(host)->io;
+	u8 __iomem *base = hostdata->io;
 
 	writeb(0, base + CTRL);
 
 	writeb(value, base + 0x2100 + (reg << 2));
 
-	priv(host)->ctrl = 0x40;
+	hostdata->ctrl = 0x40;
 	writeb(0x40, base + CTRL);
 }
 
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index 1c4a44a..d320f88 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -16,10 +16,8 @@
 
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 
-#define NCR5380_read(reg) \
-	readb(priv(instance)->io + ((reg) << 2))
-#define NCR5380_write(reg, value) \
-	writeb(value, priv(instance)->io + ((reg) << 2))
+#define NCR5380_read(reg)           readb(hostdata->io + ((reg) << 2))
+#define NCR5380_write(reg, value)   writeb(value, hostdata->io + ((reg) << 2))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup		oakscsi_pread
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index 862f30c..aed69ac 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -126,8 +126,8 @@ static inline unsigned long SCSI_DMA_GETADR(void)
 
 static void atari_scsi_fetch_restbytes(void);
 
-static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
-static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
+static u8 (*atari_scsi_reg_read)(unsigned int);
+static void (*atari_scsi_reg_write)(unsigned int, u8);
 
 static unsigned long	atari_dma_residual, atari_dma_startaddr;
 static short		atari_dma_active;
@@ -658,30 +658,30 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
  * NCR5380_write call these functions via function pointers.
  */
 
-static unsigned char atari_scsi_tt_reg_read(unsigned char reg)
+static u8 atari_scsi_tt_reg_read(unsigned int reg)
 {
 	return tt_scsi_regp[reg * 2];
 }
 
-static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value)
+static void atari_scsi_tt_reg_write(unsigned int reg, u8 value)
 {
 	tt_scsi_regp[reg * 2] = value;
 }
 
-static unsigned char atari_scsi_falcon_reg_read(unsigned char reg)
+static u8 atari_scsi_falcon_reg_read(unsigned int reg)
 {
 	unsigned long flags;
-	unsigned char result;
+	u8 result;
 
 	reg += 0x88;
 	local_irq_save(flags);
 	dma_wd.dma_mode_status = (u_short)reg;
-	result = (u_char)dma_wd.fdc_acces_seccount;
+	result = (u8)dma_wd.fdc_acces_seccount;
 	local_irq_restore(flags);
 	return result;
 }
 
-static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
+static void atari_scsi_falcon_reg_write(unsigned int reg, u8 value)
 {
 	unsigned long flags;
 
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index 3b6df90..ab7b097 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -34,10 +34,8 @@
  * Definitions for the generic 5380 driver.
  */
 
-#define priv(instance)	((struct NCR5380_hostdata *)shost_priv(instance))
-
-#define NCR5380_read(reg)		inb(priv(instance)->base + (reg))
-#define NCR5380_write(reg, value)	outb(value, priv(instance)->base + (reg))
+#define NCR5380_read(reg)		inb(hostdata->base + (reg))
+#define NCR5380_write(reg, value)	outb(value, hostdata->base + (reg))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup(instance, dst, len)	(0)
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index ec4d70b..10191d1 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -17,13 +17,9 @@
 #define DRV_MODULE_NAME "g_NCR5380"
 
 #define NCR5380_read(reg) \
-	ioread8(((struct NCR5380_hostdata *)shost_priv(instance))->io + \
-		((struct NCR5380_hostdata *)shost_priv(instance))->offset + \
-		(reg))
+	ioread8(hostdata->io + hostdata->offset + (reg))
 #define NCR5380_write(reg, value) \
-	iowrite8(value, ((struct NCR5380_hostdata *)shost_priv(instance))->io + \
-		((struct NCR5380_hostdata *)shost_priv(instance))->offset + \
-		(reg))
+	iowrite8(value, hostdata->io + hostdata->offset + (reg))
 
 #define NCR5380_implementation_fields \
 	int offset; \
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index 80e10d9..9ac3822 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -30,8 +30,8 @@
 
 #define NCR5380_implementation_fields   int pdma_residual
 
-#define NCR5380_read(reg)               macscsi_read(instance, reg)
-#define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
+#define NCR5380_read(reg)           in_8(hostdata->io + ((reg) << 4))
+#define NCR5380_write(reg, value)   out_8(hostdata->io + ((reg) << 4), value)
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase) \
         macscsi_dma_xfer_len(instance, cmd)
@@ -60,24 +60,6 @@ module_param(setup_hostid, int, 0);
 static int setup_toshiba_delay = -1;
 module_param(setup_toshiba_delay, int, 0);
 
-/*
- * NCR 5380 register access functions
- */
-
-static inline char macscsi_read(struct Scsi_Host *instance, int reg)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	return in_8(hostdata->io + (reg << 4));
-}
-
-static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value)
-{
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
-	out_8(hostdata->io + (reg << 4), value);
-}
-
 #ifndef MODULE
 static int __init mac_scsi_setup(char *str)
 {
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index efee144..b408474 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -43,8 +43,8 @@
 
 #define NCR5380_implementation_fields   /* none */
 
-#define NCR5380_read(reg)               sun3scsi_read(reg)
-#define NCR5380_write(reg, value)       sun3scsi_write(reg, value)
+#define NCR5380_read(reg)               in_8(hostdata->io + (reg))
+#define NCR5380_write(reg, value)       out_8(hostdata->io + (reg), value)
 
 #define NCR5380_queue_command           sun3scsi_queue_command
 #define NCR5380_bus_reset               sun3scsi_bus_reset
@@ -82,7 +82,6 @@ module_param(setup_hostid, int, 0);
 #define SUN3_DVMA_BUFSIZE 0xe000
 
 static struct scsi_cmnd *sun3_dma_setup_done;
-static unsigned char *sun3_scsi_regp;
 static volatile struct sun3_dma_regs *dregs;
 static struct sun3_udc_regs *udc_regs;
 static unsigned char *sun3_dma_orig_addr;
@@ -90,20 +89,6 @@ static unsigned long sun3_dma_orig_count;
 static int sun3_dma_active;
 static unsigned long last_residual;
 
-/*
- * NCR 5380 register access functions
- */
-
-static inline unsigned char sun3scsi_read(int reg)
-{
-	return in_8(sun3_scsi_regp + reg);
-}
-
-static inline void sun3scsi_write(int reg, int value)
-{
-	out_8(sun3_scsi_regp + reg, value);
-}
-
 #ifndef SUN3_SCSI_VME
 /* dma controller register access functions */
 
@@ -431,7 +416,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
 	struct NCR5380_hostdata *hostdata;
 	int error;
 	struct resource *irq, *mem;
-	unsigned char *ioaddr;
+	void __iomem *ioaddr;
 	int host_flags = 0;
 #ifdef SUN3_SCSI_VME
 	int i;
@@ -494,8 +479,6 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
 	}
 #endif
 
-	sun3_scsi_regp = ioaddr;
-
 	instance = scsi_host_alloc(&sun3_scsi_template,
 	                           sizeof(struct NCR5380_hostdata));
 	if (!instance) {
@@ -506,7 +489,8 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
 	instance->irq = irq->start;
 
 	hostdata = shost_priv(instance);
-	hostdata->base = (unsigned long)ioaddr;
+	hostdata->base = mem->start;
+	hostdata->io = ioaddr;
 
 	error = NCR5380_init(instance, host_flags);
 	if (error)
@@ -555,13 +539,15 @@ fail_init:
 fail_alloc:
 	if (udc_regs)
 		dvma_free(udc_regs);
-	iounmap(sun3_scsi_regp);
+	iounmap(ioaddr);
 	return error;
 }
 
 static int __exit sun3_scsi_remove(struct platform_device *pdev)
 {
 	struct Scsi_Host *instance = platform_get_drvdata(pdev);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	void __iomem *ioaddr = hostdata->io;
 
 	scsi_remove_host(instance);
 	free_irq(instance->irq, instance);
@@ -569,7 +555,7 @@ static int __exit sun3_scsi_remove(struct platform_device *pdev)
 	scsi_host_put(instance);
 	if (udc_regs)
 		dvma_free(udc_regs);
-	iounmap(sun3_scsi_regp);
+	iounmap(ioaddr);
 	return 0;
 }
 
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 11/12] scsi/ncr5380: Use correct types for DMA routines
From: Finn Thain @ 2016-10-06 23:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475791899.git.fthain@telegraphics.com.au>

Apply prototypes to get consistent function signatures for the DMA
functions implemented in the board-specific drivers. To avoid using
macros to alter actual parameters, some of those functions are reworked
slightly.

This is a step toward the goal of passing the board-specific routines
to the core driver using an ops struct (as in a platform driver or
library module).

This also helps fix some inconsistent types: where the core driver uses
ints (cmd->SCp.this_residual and hostdata->dma_len) for keeping track of
transfers, certain board-specific routines used unsigned long.

While we are fixing these function signatures, pass the hostdata pointer
to DMA routines instead of a Scsi_Host pointer, for shorter and faster
code.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/NCR5380.c      | 74 +++++++++++++++++++++++++--------------------
 drivers/scsi/NCR5380.h      | 25 +++++++++++++++
 drivers/scsi/arm/cumana_1.c | 26 ++++++++++------
 drivers/scsi/arm/oak.c      | 13 ++++----
 drivers/scsi/atari_scsi.c   | 45 +++++++++++++++------------
 drivers/scsi/dmx3191d.c     |  8 ++---
 drivers/scsi/g_NCR5380.c    | 13 +++-----
 drivers/scsi/g_NCR5380.h    |  5 ++-
 drivers/scsi/mac_scsi.c     | 36 +++++++++++-----------
 drivers/scsi/sun3_scsi.c    | 45 +++++++++++++++++++--------
 10 files changed, 176 insertions(+), 114 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 3f2bfd2..72ac31cd 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -121,9 +121,10 @@
  *
  * Either real DMA *or* pseudo DMA may be implemented
  *
- * NCR5380_dma_write_setup(instance, src, count) - initialize
- * NCR5380_dma_read_setup(instance, dst, count) - initialize
- * NCR5380_dma_residual(instance); - residual count
+ * NCR5380_dma_xfer_len   - determine size of DMA/PDMA transfer
+ * NCR5380_dma_send_setup - execute DMA/PDMA from memory to 5380
+ * NCR5380_dma_recv_setup - execute DMA/PDMA from 5380 to memory
+ * NCR5380_dma_residual   - residual byte count
  *
  * The generic driver is initialized by calling NCR5380_init(instance),
  * after setting the appropriate host specific fields and ID.  If the
@@ -871,7 +872,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
 
-	transferred = hostdata->dma_len - NCR5380_dma_residual(instance);
+	transferred = hostdata->dma_len - NCR5380_dma_residual(hostdata);
 	hostdata->dma_len = 0;
 
 	data = (unsigned char **)&hostdata->connected->SCp.ptr;
@@ -1578,9 +1579,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
 		 * starting the NCR. This is also the cleaner way for the TT.
 		 */
 		if (p & SR_IO)
-			result = NCR5380_dma_recv_setup(instance, d, c);
+			result = NCR5380_dma_recv_setup(hostdata, d, c);
 		else
-			result = NCR5380_dma_send_setup(instance, d, c);
+			result = NCR5380_dma_send_setup(hostdata, d, c);
 	}
 
 	/*
@@ -1612,9 +1613,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
 		 * NCR access, else the DMA setup gets trashed!
 		 */
 		if (p & SR_IO)
-			result = NCR5380_dma_recv_setup(instance, d, c);
+			result = NCR5380_dma_recv_setup(hostdata, d, c);
 		else
-			result = NCR5380_dma_send_setup(instance, d, c);
+			result = NCR5380_dma_send_setup(hostdata, d, c);
 	}
 
 	/* On failure, NCR5380_dma_xxxx_setup() returns a negative int. */
@@ -1754,22 +1755,26 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 				NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
 			}
 #ifdef CONFIG_SUN3
-			if (phase == PHASE_CMDOUT) {
-				void *d;
-				unsigned long count;
+			if (phase == PHASE_CMDOUT &&
+			    sun3_dma_setup_done != cmd) {
+				int count;
 
 				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
-					count = cmd->SCp.buffer->length;
-					d = sg_virt(cmd->SCp.buffer);
-				} else {
-					count = cmd->SCp.this_residual;
-					d = cmd->SCp.ptr;
+					++cmd->SCp.buffer;
+					--cmd->SCp.buffers_residual;
+					cmd->SCp.this_residual = cmd->SCp.buffer->length;
+					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 				}
 
-				if (sun3_dma_setup_done != cmd &&
-				    sun3scsi_dma_xfer_len(count, cmd) > 0) {
-					sun3scsi_dma_setup(instance, d, count,
-					                   rq_data_dir(cmd->request));
+				count = sun3scsi_dma_xfer_len(hostdata, cmd);
+
+				if (count > 0) {
+					if (rq_data_dir(cmd->request))
+						sun3scsi_dma_send_setup(hostdata,
+						                        cmd->SCp.ptr, count);
+					else
+						sun3scsi_dma_recv_setup(hostdata,
+						                        cmd->SCp.ptr, count);
 					sun3_dma_setup_done = cmd;
 				}
 #ifdef SUN3_SCSI_VME
@@ -1830,7 +1835,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 
 				transfersize = 0;
 				if (!cmd->device->borken)
-					transfersize = NCR5380_dma_xfer_len(instance, cmd, phase);
+					transfersize = NCR5380_dma_xfer_len(hostdata, cmd);
 
 				if (transfersize > 0) {
 					len = transfersize;
@@ -2207,22 +2212,25 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
 	}
 
 #ifdef CONFIG_SUN3
-	{
-		void *d;
-		unsigned long count;
+	if (sun3_dma_setup_done != tmp) {
+		int count;
 
 		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
-			count = tmp->SCp.buffer->length;
-			d = sg_virt(tmp->SCp.buffer);
-		} else {
-			count = tmp->SCp.this_residual;
-			d = tmp->SCp.ptr;
+			++tmp->SCp.buffer;
+			--tmp->SCp.buffers_residual;
+			tmp->SCp.this_residual = tmp->SCp.buffer->length;
+			tmp->SCp.ptr = sg_virt(tmp->SCp.buffer);
 		}
 
-		if (sun3_dma_setup_done != tmp &&
-		    sun3scsi_dma_xfer_len(count, tmp) > 0) {
-			sun3scsi_dma_setup(instance, d, count,
-			                   rq_data_dir(tmp->request));
+		count = sun3scsi_dma_xfer_len(hostdata, tmp);
+
+		if (count > 0) {
+			if (rq_data_dir(tmp->request))
+				sun3scsi_dma_send_setup(hostdata,
+				                        tmp->SCp.ptr, count);
+			else
+				sun3scsi_dma_recv_setup(hostdata,
+				                        tmp->SCp.ptr, count);
 			sun3_dma_setup_done = tmp;
 		}
 	}
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index b2c560c..3c6ce54 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -317,5 +317,30 @@ static inline int NCR5380_poll_politely(struct NCR5380_hostdata *hostdata,
 						reg, bit, val, wait);
 }
 
+static int NCR5380_dma_xfer_len(struct NCR5380_hostdata *,
+                                struct scsi_cmnd *);
+static int NCR5380_dma_send_setup(struct NCR5380_hostdata *,
+                                  unsigned char *, int);
+static int NCR5380_dma_recv_setup(struct NCR5380_hostdata *,
+                                  unsigned char *, int);
+static int NCR5380_dma_residual(struct NCR5380_hostdata *);
+
+static inline int NCR5380_dma_xfer_none(struct NCR5380_hostdata *hostdata,
+                                        struct scsi_cmnd *cmd)
+{
+	return 0;
+}
+
+static inline int NCR5380_dma_setup_none(struct NCR5380_hostdata *hostdata,
+                                         unsigned char *data, int count)
+{
+	return 0;
+}
+
+static inline int NCR5380_dma_residual_none(struct NCR5380_hostdata *hostdata)
+{
+	return 0;
+}
+
 #endif				/* __KERNEL__ */
 #endif				/* NCR5380_H */
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index fb7600d..a87b99c 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -17,10 +17,10 @@
 #define NCR5380_read(reg)		cumanascsi_read(hostdata, reg)
 #define NCR5380_write(reg, value)	cumanascsi_write(hostdata, reg, value)
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(cmd->transfersize)
+#define NCR5380_dma_xfer_len		cumanascsi_dma_xfer_len
 #define NCR5380_dma_recv_setup		cumanascsi_pread
 #define NCR5380_dma_send_setup		cumanascsi_pwrite
-#define NCR5380_dma_residual(instance)	(0)
+#define NCR5380_dma_residual		NCR5380_dma_residual_none
 
 #define NCR5380_intr			cumanascsi_intr
 #define NCR5380_queue_command		cumanascsi_queue_command
@@ -40,12 +40,12 @@ static void cumanascsi_write(struct NCR5380_hostdata *, unsigned int, u8);
 #define L(v)	(((v)<<16)|((v) & 0x0000ffff))
 #define H(v)	(((v)>>16)|((v) & 0xffff0000))
 
-static inline int cumanascsi_pwrite(struct Scsi_Host *host,
+static inline int cumanascsi_pwrite(struct NCR5380_hostdata *hostdata,
                                     unsigned char *addr, int len)
 {
   unsigned long *laddr;
-  u8 __iomem *base = priv(host)->io;
-  u8 __iomem *dma = priv(host)->pdma_io + 0x2000;
+  u8 __iomem *base = hostdata->io;
+  u8 __iomem *dma = hostdata->pdma_io + 0x2000;
 
   if(!len) return 0;
 
@@ -100,19 +100,19 @@ static inline int cumanascsi_pwrite(struct Scsi_Host *host,
     }
   }
 end:
-  writeb(priv(host)->ctrl | 0x40, base + CTRL);
+  writeb(hostdata->ctrl | 0x40, base + CTRL);
 
 	if (len)
 		return -1;
 	return 0;
 }
 
-static inline int cumanascsi_pread(struct Scsi_Host *host,
+static inline int cumanascsi_pread(struct NCR5380_hostdata *hostdata,
                                    unsigned char *addr, int len)
 {
   unsigned long *laddr;
-  u8 __iomem *base = priv(host)->io;
-  u8 __iomem *dma = priv(host)->pdma_io + 0x2000;
+  u8 __iomem *base = hostdata->io;
+  u8 __iomem *dma = hostdata->pdma_io + 0x2000;
 
   if(!len) return 0;
 
@@ -166,13 +166,19 @@ static inline int cumanascsi_pread(struct Scsi_Host *host,
     }
   }
 end:
-  writeb(priv(host)->ctrl | 0x40, base + CTRL);
+  writeb(hostdata->ctrl | 0x40, base + CTRL);
 
 	if (len)
 		return -1;
 	return 0;
 }
 
+static int cumanascsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+                                   struct scsi_cmnd *cmd)
+{
+	return cmd->transfersize;
+}
+
 static u8 cumanascsi_read(struct NCR5380_hostdata *hostdata,
                           unsigned int reg)
 {
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index d320f88..6be6666 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -19,10 +19,10 @@
 #define NCR5380_read(reg)           readb(hostdata->io + ((reg) << 2))
 #define NCR5380_write(reg, value)   writeb(value, hostdata->io + ((reg) << 2))
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
+#define NCR5380_dma_xfer_len		NCR5380_dma_xfer_none
 #define NCR5380_dma_recv_setup		oakscsi_pread
 #define NCR5380_dma_send_setup		oakscsi_pwrite
-#define NCR5380_dma_residual(instance)	(0)
+#define NCR5380_dma_residual		NCR5380_dma_residual_none
 
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
@@ -37,10 +37,10 @@
 #define STAT	((128 + 16) << 2)
 #define DATA	((128 + 8) << 2)
 
-static inline int oakscsi_pwrite(struct Scsi_Host *instance,
+static inline int oakscsi_pwrite(struct NCR5380_hostdata *hostdata,
                                  unsigned char *addr, int len)
 {
-  u8 __iomem *base = priv(instance)->io;
+  u8 __iomem *base = hostdata->io;
 
 printk("writing %p len %d\n",addr, len);
 
@@ -52,10 +52,11 @@ printk("writing %p len %d\n",addr, len);
   return 0;
 }
 
-static inline int oakscsi_pread(struct Scsi_Host *instance,
+static inline int oakscsi_pread(struct NCR5380_hostdata *hostdata,
                                 unsigned char *addr, int len)
 {
-  u8 __iomem *base = priv(instance)->io;
+  u8 __iomem *base = hostdata->io;
+
 printk("reading %p len %d\n", addr, len);
   while(len > 0)
   {
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index f77c311..105b353 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -67,14 +67,10 @@ static void (*atari_scsi_reg_write)(unsigned int, u8);
 #define NCR5380_abort                   atari_scsi_abort
 #define NCR5380_info                    atari_scsi_info
 
-#define NCR5380_dma_recv_setup(instance, data, count) \
-        atari_scsi_dma_setup(instance, data, count, 0)
-#define NCR5380_dma_send_setup(instance, data, count) \
-        atari_scsi_dma_setup(instance, data, count, 1)
-#define NCR5380_dma_residual(instance) \
-        atari_scsi_dma_residual(instance)
-#define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
+#define NCR5380_dma_xfer_len            atari_scsi_dma_xfer_len
+#define NCR5380_dma_recv_setup          atari_scsi_dma_recv_setup
+#define NCR5380_dma_send_setup          atari_scsi_dma_send_setup
+#define NCR5380_dma_residual            atari_scsi_dma_residual
 
 #define NCR5380_acquire_dma_irq(instance)      falcon_get_lock(instance)
 #define NCR5380_release_dma_irq(instance)      falcon_release_lock()
@@ -457,15 +453,14 @@ static int __init atari_scsi_setup(char *str)
 __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
-
-static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
+static unsigned long atari_scsi_dma_setup(struct NCR5380_hostdata *hostdata,
 					  void *data, unsigned long count,
 					  int dir)
 {
 	unsigned long addr = virt_to_phys(data);
 
-	dprintk(NDEBUG_DMA, "scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, "
-		   "dir = %d\n", instance->host_no, data, addr, count, dir);
+	dprintk(NDEBUG_DMA, "scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, dir = %d\n",
+	        hostdata->host->host_no, data, addr, count, dir);
 
 	if (!IS_A_TT() && !STRAM_ADDR(addr)) {
 		/* If we have a non-DMAable address on a Falcon, use the dribble
@@ -522,8 +517,19 @@ static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
 	return count;
 }
 
+static inline int atari_scsi_dma_recv_setup(struct NCR5380_hostdata *hostdata,
+                                            unsigned char *data, int count)
+{
+	return atari_scsi_dma_setup(hostdata, data, count, 0);
+}
+
+static inline int atari_scsi_dma_send_setup(struct NCR5380_hostdata *hostdata,
+                                            unsigned char *data, int count)
+{
+	return atari_scsi_dma_setup(hostdata, data, count, 1);
+}
 
-static long atari_scsi_dma_residual(struct Scsi_Host *instance)
+static int atari_scsi_dma_residual(struct NCR5380_hostdata *hostdata)
 {
 	return atari_dma_residual;
 }
@@ -564,10 +570,11 @@ static int falcon_classify_cmd(struct scsi_cmnd *cmd)
  * the overrun problem, so this question is academic :-)
  */
 
-static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
-					struct scsi_cmnd *cmd, int write_flag)
+static int atari_scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+                                   struct scsi_cmnd *cmd)
 {
-	unsigned long	possible_len, limit;
+	int wanted_len = cmd->SCp.this_residual;
+	int possible_len, limit;
 
 	if (wanted_len < DMA_MIN_SIZE)
 		return 0;
@@ -604,7 +611,7 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
 	 * use the dribble buffer and thus can do only STRAM_BUFFER_SIZE bytes.
 	 */
 
-	if (write_flag) {
+	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
 		/* Write operation can always use the DMA, but the transfer size must
 		 * be rounded up to the next multiple of 512 (atari_dma_setup() does
 		 * this).
@@ -644,8 +651,8 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
 		possible_len = limit;
 
 	if (possible_len != wanted_len)
-		dprintk(NDEBUG_DMA, "Sorry, must cut DMA transfer size to %ld bytes "
-			   "instead of %ld\n", possible_len, wanted_len);
+		dprintk(NDEBUG_DMA, "DMA transfer now %d bytes instead of %d\n",
+		        possible_len, wanted_len);
 
 	return possible_len;
 }
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index ab7b097..3aa4657 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -37,10 +37,10 @@
 #define NCR5380_read(reg)		inb(hostdata->base + (reg))
 #define NCR5380_write(reg, value)	outb(value, hostdata->base + (reg))
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
-#define NCR5380_dma_recv_setup(instance, dst, len)	(0)
-#define NCR5380_dma_send_setup(instance, src, len)	(0)
-#define NCR5380_dma_residual(instance)			(0)
+#define NCR5380_dma_xfer_len		NCR5380_dma_xfer_none
+#define NCR5380_dma_recv_setup		NCR5380_dma_setup_none
+#define NCR5380_dma_send_setup		NCR5380_dma_setup_none
+#define NCR5380_dma_residual		NCR5380_dma_residual_none
 
 #define NCR5380_implementation_fields	/* none */
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 98aef0e..7299ad9 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -332,7 +332,7 @@ static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
 
 /**
  *	generic_NCR5380_pread - pseudo DMA read
- *	@instance: adapter to read from
+ *	@hostdata: scsi host private data
  *	@dst: buffer to read into
  *	@len: buffer length
  *
@@ -340,10 +340,9 @@ static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
  *	controller
  */
  
-static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
+static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
                                         unsigned char *dst, int len)
 {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
 	int start = 0;
 
@@ -406,7 +405,7 @@ static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
 
 /**
  *	generic_NCR5380_pwrite - pseudo DMA write
- *	@instance: adapter to read from
+ *	@hostdata: scsi host private data
  *	@dst: buffer to read into
  *	@len: buffer length
  *
@@ -414,10 +413,9 @@ static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
  *	controller
  */
 
-static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
+static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata,
                                          unsigned char *src, int len)
 {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int blocks = len / 128;
 	int start = 0;
 
@@ -480,10 +478,9 @@ static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
 	return 0;
 }
 
-static int generic_NCR5380_dma_xfer_len(struct Scsi_Host *instance,
+static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
                                         struct scsi_cmnd *cmd)
 {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int transfersize = cmd->transfersize;
 
 	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index 10191d1..3ce5b65 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -32,11 +32,10 @@
 #define NCR53C400_host_buffer 0x3900
 #define NCR53C400_region_size 0x3a00
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        generic_NCR5380_dma_xfer_len(instance, cmd)
+#define NCR5380_dma_xfer_len		generic_NCR5380_dma_xfer_len
 #define NCR5380_dma_recv_setup		generic_NCR5380_pread
 #define NCR5380_dma_send_setup		generic_NCR5380_pwrite
-#define NCR5380_dma_residual(instance)	(0)
+#define NCR5380_dma_residual		NCR5380_dma_residual_none
 
 #define NCR5380_intr generic_NCR5380_intr
 #define NCR5380_queue_command generic_NCR5380_queue_command
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index 07f956c..ccb68d1 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -33,11 +33,10 @@
 #define NCR5380_read(reg)           in_8(hostdata->io + ((reg) << 4))
 #define NCR5380_write(reg, value)   out_8(hostdata->io + ((reg) << 4), value)
 
-#define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        macscsi_dma_xfer_len(instance, cmd)
+#define NCR5380_dma_xfer_len            macscsi_dma_xfer_len
 #define NCR5380_dma_recv_setup          macscsi_pread
 #define NCR5380_dma_send_setup          macscsi_pwrite
-#define NCR5380_dma_residual(instance)  (hostdata->pdma_residual)
+#define NCR5380_dma_residual            macscsi_dma_residual
 
 #define NCR5380_intr                    macscsi_intr
 #define NCR5380_queue_command           macscsi_queue_command
@@ -152,10 +151,9 @@ __asm__ __volatile__					\
      : "0"(s), "1"(d), "2"(n)				\
      : "d0")
 
-static int macscsi_pread(struct Scsi_Host *instance,
-                         unsigned char *dst, int len)
+static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
+                                unsigned char *dst, int len)
 {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char *s = hostdata->pdma_io + (INPUT_DATA_REG << 4);
 	unsigned char *d = dst;
 	int n = len;
@@ -181,16 +179,16 @@ static int macscsi_pread(struct Scsi_Host *instance,
 		if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
 			return 0;
 
-		dsprintk(NDEBUG_PSEUDO_DMA, instance,
+		dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
 		         "%s: bus error (%d/%d)\n", __func__, transferred, len);
-		NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+		NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
 		d = dst + transferred;
 		n = len - transferred;
 	}
 
 	scmd_printk(KERN_ERR, hostdata->connected,
 	            "%s: phase mismatch or !DRQ\n", __func__);
-	NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+	NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
 	return -1;
 }
 
@@ -255,10 +253,9 @@ __asm__ __volatile__					\
      : "0"(s), "1"(d), "2"(n)				\
      : "d0")
 
-static int macscsi_pwrite(struct Scsi_Host *instance,
-                          unsigned char *src, int len)
+static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
+                                 unsigned char *src, int len)
 {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char *s = src;
 	unsigned char *d = hostdata->pdma_io + (OUTPUT_DATA_REG << 4);
 	int n = len;
@@ -290,25 +287,23 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
 			return 0;
 		}
 
-		dsprintk(NDEBUG_PSEUDO_DMA, instance,
+		dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
 		         "%s: bus error (%d/%d)\n", __func__, transferred, len);
-		NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+		NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
 		s = src + transferred;
 		n = len - transferred;
 	}
 
 	scmd_printk(KERN_ERR, hostdata->connected,
 	            "%s: phase mismatch or !DRQ\n", __func__);
-	NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
+	NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
 
 	return -1;
 }
 
-static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
+static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
                                 struct scsi_cmnd *cmd)
 {
-	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-
 	if (hostdata->flags & FLAG_NO_PSEUDO_DMA ||
 	    cmd->SCp.this_residual < 16)
 		return 0;
@@ -316,6 +311,11 @@ static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
 	return cmd->SCp.this_residual;
 }
 
+static int macscsi_dma_residual(struct NCR5380_hostdata *hostdata)
+{
+	return hostdata->pdma_residual;
+}
+
 #include "NCR5380.c"
 
 #define DRV_MODULE_NAME         "mac_scsi"
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index b408474..88db699 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -51,12 +51,10 @@
 #define NCR5380_abort                   sun3scsi_abort
 #define NCR5380_info                    sun3scsi_info
 
-#define NCR5380_dma_recv_setup(instance, data, count) (count)
-#define NCR5380_dma_send_setup(instance, data, count) (count)
-#define NCR5380_dma_residual(instance) \
-        sun3scsi_dma_residual(instance)
-#define NCR5380_dma_xfer_len(instance, cmd, phase) \
-        sun3scsi_dma_xfer_len(cmd->SCp.this_residual, cmd)
+#define NCR5380_dma_xfer_len            sun3scsi_dma_xfer_len
+#define NCR5380_dma_recv_setup          sun3scsi_dma_count
+#define NCR5380_dma_send_setup          sun3scsi_dma_count
+#define NCR5380_dma_residual            sun3scsi_dma_residual
 
 #define NCR5380_acquire_dma_irq(instance)    (1)
 #define NCR5380_release_dma_irq(instance)
@@ -143,8 +141,8 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dev)
 }
 
 /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */
-static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
-                                void *data, unsigned long count, int write_flag)
+static int sun3scsi_dma_setup(struct NCR5380_hostdata *hostdata,
+                              unsigned char *data, int count, int write_flag)
 {
 	void *addr;
 
@@ -196,9 +194,10 @@ static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
 	dregs->csr |= CSR_FIFO;
 	
 	if(dregs->fifo_count != count) { 
-		shost_printk(KERN_ERR, instance, "FIFO mismatch %04x not %04x\n",
+		shost_printk(KERN_ERR, hostdata->host,
+		             "FIFO mismatch %04x not %04x\n",
 		             dregs->fifo_count, (unsigned int) count);
-		NCR5380_dprint(NDEBUG_DMA, instance);
+		NCR5380_dprint(NDEBUG_DMA, hostdata->host);
 	}
 
 	/* setup udc */
@@ -233,14 +232,34 @@ static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance,
 
 }
 
-static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
+static int sun3scsi_dma_count(struct NCR5380_hostdata *hostdata,
+                              unsigned char *data, int count)
+{
+	return count;
+}
+
+static inline int sun3scsi_dma_recv_setup(struct NCR5380_hostdata *hostdata,
+                                          unsigned char *data, int count)
+{
+	return sun3scsi_dma_setup(hostdata, data, count, 0);
+}
+
+static inline int sun3scsi_dma_send_setup(struct NCR5380_hostdata *hostdata,
+                                          unsigned char *data, int count)
+{
+	return sun3scsi_dma_setup(hostdata, data, count, 1);
+}
+
+static int sun3scsi_dma_residual(struct NCR5380_hostdata *hostdata)
 {
 	return last_residual;
 }
 
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted_len,
-                                                  struct scsi_cmnd *cmd)
+static int sun3scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+                                 struct scsi_cmnd *cmd)
 {
+	int wanted_len = cmd->SCp.this_residual;
+
 	if (wanted_len < DMA_MIN_SIZE || cmd->request->cmd_type != REQ_TYPE_FS)
 		return 0;
 
-- 
2.7.3

^ permalink raw reply related

* [PATCH v2 07/12] scsi/ncr5380: Store IO ports and addresses in host private data
From: Finn Thain @ 2016-10-06 23:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475791899.git.fthain@telegraphics.com.au>

The various 5380 drivers inconsistently store register pointers
either in the Scsi_Host struct "legacy crap" area or in special,
board-specific members of the NCR5380_hostdata struct. Uniform
use of the latter struct makes for simpler and faster code (see
the following patches) and helps to reduce use of the
NCR5380_implementation_fields macro.

Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/NCR5380.c      |  8 +++---
 drivers/scsi/NCR5380.h      |  5 ++++
 drivers/scsi/arm/cumana_1.c | 60 ++++++++++++++++++++--------------------
 drivers/scsi/arm/oak.c      | 23 ++++++++--------
 drivers/scsi/dmx3191d.c     | 14 +++++++---
 drivers/scsi/g_NCR5380.c    | 67 +++++++++++++++++++++++----------------------
 drivers/scsi/g_NCR5380.h    |  6 ++--
 drivers/scsi/mac_scsi.c     | 27 ++++++++++--------
 drivers/scsi/sun3_scsi.c    |  5 +++-
 9 files changed, 118 insertions(+), 97 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 25ee5be..82fd37d 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -437,14 +437,14 @@ static void prepare_info(struct Scsi_Host *instance)
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
 	snprintf(hostdata->info, sizeof(hostdata->info),
-	         "%s, io_port 0x%lx, n_io_port %d, "
-	         "base 0x%lx, irq %d, "
+	         "%s, irq %d, "
+		 "io_port 0x%lx, base 0x%lx, "
 	         "can_queue %d, cmd_per_lun %d, "
 	         "sg_tablesize %d, this_id %d, "
 	         "flags { %s%s%s}, "
 	         "options { %s} ",
-	         instance->hostt->name, instance->io_port, instance->n_io_port,
-	         instance->base, instance->irq,
+	         instance->hostt->name, instance->irq,
+		 hostdata->io_port, hostdata->base,
 	         instance->can_queue, instance->cmd_per_lun,
 	         instance->sg_tablesize, instance->this_id,
 	         hostdata->flags & FLAG_DMA_FIXUP     ? "DMA_FIXUP "     : "",
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index ceafa0c..02f20ff 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -220,6 +220,8 @@
 
 struct NCR5380_hostdata {
 	NCR5380_implementation_fields;		/* Board-specific data */
+	u8 __iomem *io;				/* Remapped 5380 address */
+	u8 __iomem *pdma_io;			/* Remapped PDMA address */
 	unsigned long poll_loops;		/* Register polling limit */
 	spinlock_t lock;			/* Protects this struct */
 	struct scsi_cmnd *connected;		/* Currently connected cmnd */
@@ -230,6 +232,8 @@ struct NCR5380_hostdata {
 	int flags;				/* Board-specific quirks */
 	int dma_len;				/* Requested length of DMA */
 	int read_overruns;	/* Transfer size reduction for DMA erratum */
+	unsigned long io_port;			/* Device IO port */
+	unsigned long base;			/* Device base address */
 	struct list_head unissued;		/* Waiting to be issued */
 	struct scsi_cmnd *selecting;		/* Cmnd to be connected */
 	struct list_head autosense;		/* Priority cmnd queue */
@@ -239,6 +243,7 @@ struct NCR5380_hostdata {
 	unsigned char id_mask;			/* 1 << Host ID */
 	unsigned char id_higher_mask;		/* All bits above id_mask */
 	unsigned char last_message;		/* Last Message Out */
+	unsigned long region_size;		/* Size of address/port range */
 	char info[256];
 };
 
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index f616756..88db281 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -27,9 +27,7 @@
 #define NCR5380_info			cumanascsi_info
 
 #define NCR5380_implementation_fields	\
-	unsigned ctrl;			\
-	void __iomem *base;		\
-	void __iomem *dma
+	unsigned ctrl
 
 #include "../NCR5380.h"
 
@@ -42,17 +40,18 @@ static inline int cumanascsi_pwrite(struct Scsi_Host *host,
                                     unsigned char *addr, int len)
 {
   unsigned long *laddr;
-  void __iomem *dma = priv(host)->dma + 0x2000;
+  u8 __iomem *base = priv(host)->io;
+  u8 __iomem *dma = priv(host)->pdma_io + 0x2000;
 
   if(!len) return 0;
 
-  writeb(0x02, priv(host)->base + CTRL);
+  writeb(0x02, base + CTRL);
   laddr = (unsigned long *)addr;
   while(len >= 32)
   {
     unsigned int status;
     unsigned long v;
-    status = readb(priv(host)->base + STAT);
+    status = readb(base + STAT);
     if(status & 0x80)
       goto end;
     if(!(status & 0x40))
@@ -71,12 +70,12 @@ static inline int cumanascsi_pwrite(struct Scsi_Host *host,
   }
 
   addr = (unsigned char *)laddr;
-  writeb(0x12, priv(host)->base + CTRL);
+  writeb(0x12, base + CTRL);
 
   while(len > 0)
   {
     unsigned int status;
-    status = readb(priv(host)->base + STAT);
+    status = readb(base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
@@ -86,7 +85,7 @@ static inline int cumanascsi_pwrite(struct Scsi_Host *host,
         break;
     }
 
-    status = readb(priv(host)->base + STAT);
+    status = readb(base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
@@ -97,7 +96,7 @@ static inline int cumanascsi_pwrite(struct Scsi_Host *host,
     }
   }
 end:
-  writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
+  writeb(priv(host)->ctrl | 0x40, base + CTRL);
 
 	if (len)
 		return -1;
@@ -108,16 +107,17 @@ static inline int cumanascsi_pread(struct Scsi_Host *host,
                                    unsigned char *addr, int len)
 {
   unsigned long *laddr;
-  void __iomem *dma = priv(host)->dma + 0x2000;
+  u8 __iomem *base = priv(host)->io;
+  u8 __iomem *dma = priv(host)->pdma_io + 0x2000;
 
   if(!len) return 0;
 
-  writeb(0x00, priv(host)->base + CTRL);
+  writeb(0x00, base + CTRL);
   laddr = (unsigned long *)addr;
   while(len >= 32)
   {
     unsigned int status;
-    status = readb(priv(host)->base + STAT);
+    status = readb(base + STAT);
     if(status & 0x80)
       goto end;
     if(!(status & 0x40))
@@ -136,12 +136,12 @@ static inline int cumanascsi_pread(struct Scsi_Host *host,
   }
 
   addr = (unsigned char *)laddr;
-  writeb(0x10, priv(host)->base + CTRL);
+  writeb(0x10, base + CTRL);
 
   while(len > 0)
   {
     unsigned int status;
-    status = readb(priv(host)->base + STAT);
+    status = readb(base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
@@ -151,7 +151,7 @@ static inline int cumanascsi_pread(struct Scsi_Host *host,
         break;
     }
 
-    status = readb(priv(host)->base + STAT);
+    status = readb(base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
@@ -162,7 +162,7 @@ static inline int cumanascsi_pread(struct Scsi_Host *host,
     }
   }
 end:
-  writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
+  writeb(priv(host)->ctrl | 0x40, base + CTRL);
 
 	if (len)
 		return -1;
@@ -171,7 +171,7 @@ end:
 
 static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
 {
-	void __iomem *base = priv(host)->base;
+	u8 __iomem *base = priv(host)->io;
 	unsigned char val;
 
 	writeb(0, base + CTRL);
@@ -186,7 +186,7 @@ static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
 
 static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value)
 {
-	void __iomem *base = priv(host)->base;
+	u8 __iomem *base = priv(host)->io;
 
 	writeb(0, base + CTRL);
 
@@ -231,11 +231,11 @@ static int cumanascsi1_probe(struct expansion_card *ec,
 		goto out_release;
 	}
 
-	priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
-				   ecard_resource_len(ec, ECARD_RES_IOCSLOW));
-	priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
-				  ecard_resource_len(ec, ECARD_RES_MEMC));
-	if (!priv(host)->base || !priv(host)->dma) {
+	priv(host)->io = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
+	                         ecard_resource_len(ec, ECARD_RES_IOCSLOW));
+	priv(host)->pdma_io = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
+	                              ecard_resource_len(ec, ECARD_RES_MEMC));
+	if (!priv(host)->io || !priv(host)->pdma_io) {
 		ret = -ENOMEM;
 		goto out_unmap;
 	}
@@ -249,7 +249,7 @@ static int cumanascsi1_probe(struct expansion_card *ec,
 	NCR5380_maybe_reset_bus(host);
 
         priv(host)->ctrl = 0;
-        writeb(0, priv(host)->base + CTRL);
+        writeb(0, priv(host)->io + CTRL);
 
 	ret = request_irq(host->irq, cumanascsi_intr, 0,
 			  "CumanaSCSI-1", host);
@@ -271,8 +271,8 @@ static int cumanascsi1_probe(struct expansion_card *ec,
  out_exit:
 	NCR5380_exit(host);
  out_unmap:
-	iounmap(priv(host)->base);
-	iounmap(priv(host)->dma);
+	iounmap(priv(host)->io);
+	iounmap(priv(host)->pdma_io);
 	scsi_host_put(host);
  out_release:
 	ecard_release_resources(ec);
@@ -283,15 +283,17 @@ static int cumanascsi1_probe(struct expansion_card *ec,
 static void cumanascsi1_remove(struct expansion_card *ec)
 {
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	void __iomem *base = priv(host)->io;
+	void __iomem *dma = priv(host)->pdma_io;
 
 	ecard_set_drvdata(ec, NULL);
 
 	scsi_remove_host(host);
 	free_irq(host->irq, host);
 	NCR5380_exit(host);
-	iounmap(priv(host)->base);
-	iounmap(priv(host)->dma);
 	scsi_host_put(host);
+	iounmap(base);
+	iounmap(dma);
 	ecard_release_resources(ec);
 }
 
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index a396024..1c4a44a 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -17,9 +17,9 @@
 #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
 
 #define NCR5380_read(reg) \
-	readb(priv(instance)->base + ((reg) << 2))
+	readb(priv(instance)->io + ((reg) << 2))
 #define NCR5380_write(reg, value) \
-	writeb(value, priv(instance)->base + ((reg) << 2))
+	writeb(value, priv(instance)->io + ((reg) << 2))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup		oakscsi_pread
@@ -29,8 +29,7 @@
 #define NCR5380_queue_command		oakscsi_queue_command
 #define NCR5380_info			oakscsi_info
 
-#define NCR5380_implementation_fields	\
-	void __iomem *base
+#define NCR5380_implementation_fields	/* none */
 
 #include "../NCR5380.h"
 
@@ -43,7 +42,7 @@
 static inline int oakscsi_pwrite(struct Scsi_Host *instance,
                                  unsigned char *addr, int len)
 {
-  void __iomem *base = priv(instance)->base;
+  u8 __iomem *base = priv(instance)->io;
 
 printk("writing %p len %d\n",addr, len);
 
@@ -58,7 +57,7 @@ printk("writing %p len %d\n",addr, len);
 static inline int oakscsi_pread(struct Scsi_Host *instance,
                                 unsigned char *addr, int len)
 {
-  void __iomem *base = priv(instance)->base;
+  u8 __iomem *base = priv(instance)->io;
 printk("reading %p len %d\n", addr, len);
   while(len > 0)
   {
@@ -133,15 +132,14 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 		goto release;
 	}
 
-	priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
-				   ecard_resource_len(ec, ECARD_RES_MEMC));
-	if (!priv(host)->base) {
+	priv(host)->io = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
+	                         ecard_resource_len(ec, ECARD_RES_MEMC));
+	if (!priv(host)->io) {
 		ret = -ENOMEM;
 		goto unreg;
 	}
 
 	host->irq = NO_IRQ;
-	host->n_io_port = 255;
 
 	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
 	if (ret)
@@ -159,7 +157,7 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
  out_exit:
 	NCR5380_exit(host);
  out_unmap:
-	iounmap(priv(host)->base);
+	iounmap(priv(host)->io);
  unreg:
 	scsi_host_put(host);
  release:
@@ -171,13 +169,14 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 static void oakscsi_remove(struct expansion_card *ec)
 {
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
+	void __iomem *base = priv(host)->io;
 
 	ecard_set_drvdata(ec, NULL);
 	scsi_remove_host(host);
 
 	NCR5380_exit(host);
-	iounmap(priv(host)->base);
 	scsi_host_put(host);
+	iounmap(base);
 	ecard_release_resources(ec);
 }
 
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index 9b5a457..3b6df90 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -34,8 +34,10 @@
  * Definitions for the generic 5380 driver.
  */
 
-#define NCR5380_read(reg)		inb(instance->io_port + reg)
-#define NCR5380_write(reg, value)	outb(value, instance->io_port + reg)
+#define priv(instance)	((struct NCR5380_hostdata *)shost_priv(instance))
+
+#define NCR5380_read(reg)		inb(priv(instance)->base + (reg))
+#define NCR5380_write(reg, value)	outb(value, priv(instance)->base + (reg))
 
 #define NCR5380_dma_xfer_len(instance, cmd, phase)	(0)
 #define NCR5380_dma_recv_setup(instance, dst, len)	(0)
@@ -71,6 +73,7 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
 			      const struct pci_device_id *id)
 {
 	struct Scsi_Host *shost;
+	struct NCR5380_hostdata *hostdata;
 	unsigned long io;
 	int error = -ENODEV;
 
@@ -88,7 +91,9 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
 			sizeof(struct NCR5380_hostdata));
 	if (!shost)
 		goto out_release_region;       
-	shost->io_port = io;
+
+	hostdata = shost_priv(shost);
+	hostdata->base = io;
 
 	/* This card does not seem to raise an interrupt on pdev->irq.
 	 * Steam-powered SCSI controllers run without an IRQ anyway.
@@ -125,7 +130,8 @@ out_host_put:
 static void dmx3191d_remove_one(struct pci_dev *pdev)
 {
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
-	unsigned long io = shost->io_port;
+	struct NCR5380_hostdata *hostdata = shost_priv(shost);
+	unsigned long io = hostdata->base;
 
 	scsi_remove_host(shost);
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 4d7a9de..98aef0e 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -115,7 +115,7 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
 	unsigned long region_size;
 	struct Scsi_Host *instance;
 	struct NCR5380_hostdata *hostdata;
-	void __iomem *iomem;
+	u8 __iomem *iomem;
 
 	switch (board) {
 	case BOARD_NCR5380:
@@ -201,11 +201,11 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
 	}
 	hostdata = shost_priv(instance);
 
-	hostdata->iomem = iomem;
+	hostdata->io = iomem;
+	hostdata->region_size = region_size;
 
 	if (is_pmio) {
-		instance->io_port = base;
-		instance->n_io_port = region_size;
+		hostdata->io_port = base;
 		hostdata->io_width = 1; /* 8-bit PDMA by default */
 		hostdata->offset = 0;
 
@@ -215,7 +215,7 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
 		 */
 		switch (board) {
 		case BOARD_NCR53C400:
-			instance->io_port += 8;
+			hostdata->io_port += 8;
 			hostdata->c400_ctl_status = 0;
 			hostdata->c400_blk_cnt = 1;
 			hostdata->c400_host_buf = 4;
@@ -231,8 +231,7 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
 			break;
 		}
 	} else {
-		instance->base = base;
-		hostdata->iomem_size = region_size;
+		hostdata->base = base;
 		hostdata->offset = NCR53C400_mem_base;
 		switch (board) {
 		case BOARD_NCR53C400:
@@ -314,17 +313,21 @@ out_release:
 static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	void __iomem *iomem = hostdata->io;
+	unsigned long io_port = hostdata->io_port;
+	unsigned long base = hostdata->base;
+	unsigned long region_size = hostdata->region_size;
 
 	scsi_remove_host(instance);
 	if (instance->irq != NO_IRQ)
 		free_irq(instance->irq, instance);
 	NCR5380_exit(instance);
-	iounmap(hostdata->iomem);
-	if (instance->io_port)
-		release_region(instance->io_port, instance->n_io_port);
-	else
-		release_mem_region(instance->base, hostdata->iomem_size);
 	scsi_host_put(instance);
+	iounmap(iomem);
+	if (io_port)
+		release_region(io_port, region_size);
+	else
+		release_mem_region(base, region_size);
 }
 
 /**
@@ -356,15 +359,15 @@ static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; /* FIXME - no timeout */
 
-		if (instance->io_port && hostdata->io_width == 2)
-			insw(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_port && hostdata->io_width == 2)
+			insw(hostdata->io_port + hostdata->c400_host_buf,
 							dst + start, 64);
-		else if (instance->io_port)
-			insb(instance->io_port + hostdata->c400_host_buf,
+		else if (hostdata->io_port)
+			insb(hostdata->io_port + hostdata->c400_host_buf,
 							dst + start, 128);
 		else
 			memcpy_fromio(dst + start,
-				hostdata->iomem + NCR53C400_host_buffer, 128);
+				hostdata->io + NCR53C400_host_buffer, 128);
 
 		start += 128;
 		blocks--;
@@ -374,15 +377,15 @@ static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; /* FIXME - no timeout */
 
-		if (instance->io_port && hostdata->io_width == 2)
-			insw(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_port && hostdata->io_width == 2)
+			insw(hostdata->io_port + hostdata->c400_host_buf,
 							dst + start, 64);
-		else if (instance->io_port)
-			insb(instance->io_port + hostdata->c400_host_buf,
+		else if (hostdata->io_port)
+			insb(hostdata->io_port + hostdata->c400_host_buf,
 							dst + start, 128);
 		else
 			memcpy_fromio(dst + start,
-				hostdata->iomem + NCR53C400_host_buffer, 128);
+				hostdata->io + NCR53C400_host_buffer, 128);
 
 		start += 128;
 		blocks--;
@@ -431,14 +434,14 @@ static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - timeout
 
-		if (instance->io_port && hostdata->io_width == 2)
-			outsw(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_port && hostdata->io_width == 2)
+			outsw(hostdata->io_port + hostdata->c400_host_buf,
 							src + start, 64);
-		else if (instance->io_port)
-			outsb(instance->io_port + hostdata->c400_host_buf,
+		else if (hostdata->io_port)
+			outsb(hostdata->io_port + hostdata->c400_host_buf,
 							src + start, 128);
 		else
-			memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+			memcpy_toio(hostdata->io + NCR53C400_host_buffer,
 			            src + start, 128);
 
 		start += 128;
@@ -448,14 +451,14 @@ static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
 		while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
 			; // FIXME - no timeout
 
-		if (instance->io_port && hostdata->io_width == 2)
-			outsw(instance->io_port + hostdata->c400_host_buf,
+		if (hostdata->io_port && hostdata->io_width == 2)
+			outsw(hostdata->io_port + hostdata->c400_host_buf,
 							src + start, 64);
-		else if (instance->io_port)
-			outsb(instance->io_port + hostdata->c400_host_buf,
+		else if (hostdata->io_port)
+			outsb(hostdata->io_port + hostdata->c400_host_buf,
 							src + start, 128);
 		else
-			memcpy_toio(hostdata->iomem + NCR53C400_host_buffer,
+			memcpy_toio(hostdata->io + NCR53C400_host_buffer,
 			            src + start, 128);
 
 		start += 128;
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index 2b777824..ec4d70b 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -17,18 +17,16 @@
 #define DRV_MODULE_NAME "g_NCR5380"
 
 #define NCR5380_read(reg) \
-	ioread8(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+	ioread8(((struct NCR5380_hostdata *)shost_priv(instance))->io + \
 		((struct NCR5380_hostdata *)shost_priv(instance))->offset + \
 		(reg))
 #define NCR5380_write(reg, value) \
-	iowrite8(value, ((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
+	iowrite8(value, ((struct NCR5380_hostdata *)shost_priv(instance))->io + \
 		((struct NCR5380_hostdata *)shost_priv(instance))->offset + \
 		(reg))
 
 #define NCR5380_implementation_fields \
 	int offset; \
-	void __iomem *iomem; \
-	resource_size_t iomem_size; \
 	int c400_ctl_status; \
 	int c400_blk_cnt; \
 	int c400_host_buf; \
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index a590089..80e10d9 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -28,8 +28,7 @@
 
 /* Definitions for the core NCR5380 driver. */
 
-#define NCR5380_implementation_fields   unsigned char *pdma_base; \
-                                        int pdma_residual
+#define NCR5380_implementation_fields   int pdma_residual
 
 #define NCR5380_read(reg)               macscsi_read(instance, reg)
 #define NCR5380_write(reg, value)       macscsi_write(instance, reg, value)
@@ -67,12 +66,16 @@ module_param(setup_toshiba_delay, int, 0);
 
 static inline char macscsi_read(struct Scsi_Host *instance, int reg)
 {
-	return in_8(instance->base + (reg << 4));
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+	return in_8(hostdata->io + (reg << 4));
 }
 
 static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value)
 {
-	out_8(instance->base + (reg << 4), value);
+	struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+	out_8(hostdata->io + (reg << 4), value);
 }
 
 #ifndef MODULE
@@ -171,7 +174,7 @@ static int macscsi_pread(struct Scsi_Host *instance,
                          unsigned char *dst, int len)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
-	unsigned char *s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
+	unsigned char *s = hostdata->pdma_io + (INPUT_DATA_REG << 4);
 	unsigned char *d = dst;
 	int n = len;
 	int transferred;
@@ -275,7 +278,7 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char *s = src;
-	unsigned char *d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
+	unsigned char *d = hostdata->pdma_io + (OUTPUT_DATA_REG << 4);
 	int n = len;
 	int transferred;
 
@@ -356,6 +359,7 @@ static struct scsi_host_template mac_scsi_template = {
 static int __init mac_scsi_probe(struct platform_device *pdev)
 {
 	struct Scsi_Host *instance;
+	struct NCR5380_hostdata *hostdata;
 	int error;
 	int host_flags = 0;
 	struct resource *irq, *pio_mem, *pdma_mem = NULL;
@@ -388,17 +392,18 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
 	if (!instance)
 		return -ENOMEM;
 
-	instance->base = pio_mem->start;
 	if (irq)
 		instance->irq = irq->start;
 	else
 		instance->irq = NO_IRQ;
 
-	if (pdma_mem && setup_use_pdma) {
-		struct NCR5380_hostdata *hostdata = shost_priv(instance);
+	hostdata = shost_priv(instance);
+	hostdata->base = pio_mem->start;
+	hostdata->io = (void *)pio_mem->start;
 
-		hostdata->pdma_base = (unsigned char *)pdma_mem->start;
-	} else
+	if (pdma_mem && setup_use_pdma)
+		hostdata->pdma_io = (void *)pdma_mem->start;
+	else
 		host_flags |= FLAG_NO_PSEUDO_DMA;
 
 	host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index 3c4c070..efee144 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -428,6 +428,7 @@ static struct scsi_host_template sun3_scsi_template = {
 static int __init sun3_scsi_probe(struct platform_device *pdev)
 {
 	struct Scsi_Host *instance;
+	struct NCR5380_hostdata *hostdata;
 	int error;
 	struct resource *irq, *mem;
 	unsigned char *ioaddr;
@@ -502,9 +503,11 @@ static int __init sun3_scsi_probe(struct platform_device *pdev)
 		goto fail_alloc;
 	}
 
-	instance->io_port = (unsigned long)ioaddr;
 	instance->irq = irq->start;
 
+	hostdata = shost_priv(instance);
+	hostdata->base = (unsigned long)ioaddr;
+
 	error = NCR5380_init(instance, host_flags);
 	if (error)
 		goto fail_init;
-- 
2.7.3

^ permalink raw reply related

* [PATCH] net: axienet: Add missing \n to end of dev_err messages
From: David Miller @ 2016-10-07  0:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161004111141.11768-1-colin.king@canonical.com>

From: Colin King <colin.king@canonical.com>
Date: Tue,  4 Oct 2016 12:11:41 +0100

> From: Colin Ian King <colin.king@canonical.com>
> 
> Trival fix, dev_err messages are missing a \n, so add it.
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Applied.

^ permalink raw reply

* [PATCH] clk: lpc32xx: fix pwm clock divider computation
From: Vladimir Zapolskiy @ 2016-10-07  0:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475678416.23405.32.camel@localhost>

Hi Sylvain,

On 05.10.2016 17:40, Sylvain Lemieux wrote:
> On Wed, 2016-10-05 at 05:38 +0300, Vladimir Zapolskiy wrote:
>> Hi Sylvain,
>>
>> On 26.09.2016 21:44, Sylvain Lemieux wrote:
>>> From: Sylvain Lemieux <slemieux@tycoint.com>
>>>
>>> A zero value in the PWM clock divider register
>>> (PWM1_FREQ/PWM2_FREQ) turn off the PWM clock.
>>>
>>> The "CLK_DIVIDER_ALLOW_ZERO" option is used for hardware that handle
>>> the zero divider by not modifying their clock input (i.e. bypass).
>>> See "/include/linux/clk-provider.h" for details.
>>
>> the problem is that the divider value is not set to some non-zero
>> value when the clock is enabled, right?
>>
> The "clk_divider_set_rate" function is working properly and 
> setup the divider properly. There is no need to perform any
> special process when enabling or initializing the PWM clock.
> 
> The problem occur when the PWM is enable in the project specific
> device tree and the PWM output clock is not explicitly setup.
> 
> With the actual implementation, the function that compute the 
> output rate, based on the actual divider, return the parent clock
> rate, which is inaccurate, since the clock is off. The core driver
> will than call the enable function, which should not take place.

this is a reword of my statement above, I'll repeat it for clarity
removing double negation, when PWMx_FREQ bits in PWMCLK_CTRL register
are all zeros gate on/off works incorrectly.

> This patch ensure that the compute output rate for the PWM clock
> handle properly the special case for a 0 divider. By returning 0,
> the core driver do not try to enable the clock, which is the
> expected behavior.

While I admit the problem, the patch is incorrect, it fakes a gated
off clock by assigning zero frequency rate to it. In terms of CCF
the problem is not related to the divider and it shall not be fixed
by introducing a new divider operation, because it is an issue with
the clock on/off setting correctness.

> I still think the current patch is the proper way to fix the
> issue created by the "CLK_DIVIDER_ALLOW_ZERO" flag of the PWM clock.

Dealing with a complex clock it makes sense to decompose it into
a divider clock and a gate clock in terms of CCF. The PWM clock
under discussion does not fit into the common model, it has two
independent gate controls, and half of the controls is placed
into the clock divider bitfield.

CLK_DIVIDER_ALLOW_ZERO is used incorrectly here, like you stated
in the commit message divider's zero value means the same as
non-divided clock, and here it should mean a gated clock.
By the way you may notice that a divider from MS_CTRL is similar.

Theoretically it might be possible to introduce a CCF-wide flag
to describe zero value as a gated off clock, but I hesitate to
do it until I find a ground that the flag is going to be utilized
by other clock drivers.

Below I proposed two options how to resolve the problem, one is
to update clock gate ops, another one is to make zero value never
happen.

I tend to the second option, because it is simpler and direct,
I'll implement it and send a change for your testing.

>> I think it does not matter if the clock rate value is set to parent
>> clock rate or any other value when divider is 0 *and* clock is gated.
>> Enabling or disabling a clock is a gate control, so I suggest two
>> alternative options at your choice (my preference is option 2):
>>
>> 1) add a custom clk_pwm_gate_enable(), clk_pwm_gate_disable() and
>> clk_pwm_gate_is_enabled() functions combined under lpc32xx_clk_pwm_gate_ops.
>>
>> Next instead of adding one more define for a single exception
>> please reassign .ops for two PWM clocks in runtime in
>> lpc32xx_clk_init() function before calling lpc32xx_clk_register()
>> in a loop.
>>
>> But this option is too invasive, a simpler solution is below.
>>
>> 2) in lpc32xx_clk_init() before clock registrations check for zero
>> dividers of PWM clocks, then if a divider is 0 and clock is gated
>> set divider to 1, if the divider is 0 and clock is not gated then
>> gate the clock and set divider to 1, in other cases do nothing.
>>
>>> Remove the CLK_DIVIDER_ALLOW_ZERO option and add support to handle
>>> the clock rate computation of the PWM clock divider 0 value.
>>>
>>> Signed-off-by: Sylvain Lemieux <slemieux@tycoint.com>
>>> ---
>>> Note:
>>> * Should we include a new CLK_DIVIDER option for this case
>>>   (i.e. clock off when zero ) in "clk-provider.h"?
>>>
>>>  drivers/clk/nxp/clk-lpc32xx.c | 52 +++++++++++++++++++++++++++++++++++++++----
>>>  1 file changed, 48 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
>>> index 34c9735..3ca3a14 100644
>>> --- a/drivers/clk/nxp/clk-lpc32xx.c
>>> +++ b/drivers/clk/nxp/clk-lpc32xx.c
>>> @@ -959,6 +959,25 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
>>>  				   divider->flags);
>>>  }
>>>  
>>> +static unsigned long clk_divider_pwm_recalc_rate(struct clk_hw *hw,
>>> +		unsigned long parent_rate)
>>> +{
>>> +	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
>>> +	unsigned int val;
>>> +
>>> +	regmap_read(clk_regmap, divider->reg, &val);
>>> +
>>> +	val >>= divider->shift;
>>> +	val &= div_mask(divider->width);
>>> +
>>> +	/* Handle 0 divider -> PWM clock is off. */
>>> +	if(val == 0)
>>
>> No space in front of the open parenthesis.
>>
>>> +		return 0;
>>> +
>>> +	return divider_recalc_rate(hw, parent_rate, val, divider->table,
>>> +				   divider->flags);
>>> +}
>>> +
>>>  static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
>>>  				unsigned long *prate)
>>>  {
>>> @@ -999,6 +1018,12 @@ static const struct clk_ops lpc32xx_clk_divider_ops = {
>>>  	.set_rate = clk_divider_set_rate,
>>>  };
>>>  
>>> +static const struct clk_ops lpc32xx_clk_pwm_divider_ops = {
>>> +	.recalc_rate = clk_divider_pwm_recalc_rate,
>>> +	.round_rate = clk_divider_round_rate,
>>> +	.set_rate = clk_divider_set_rate,
>>> +};
>>> +
>>>  static u8 clk_mux_get_parent(struct clk_hw *hw)
>>>  {
>>>  	struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw);
>>> @@ -1151,6 +1176,25 @@ struct clk_hw_proto {
>>>  	},								\
>>>  }
>>>  
>>> +#define LPC32XX_DEFINE_PWM_DIV(_idx, _reg, _shift, _width, _tab, _fl)	\
>>> +[CLK_PREFIX(_idx)] = {							\
>>> +	.type = CLK_DIV,						\
>>> +	{								\
>>> +		.hw0 = {						\
>>> +			.ops = &lpc32xx_clk_pwm_divider_ops,		\
>>> +			{						\
>>> +				.div = {				\
>>> +					.reg = LPC32XX_CLKPWR_ ## _reg,	\
>>> +					.shift = (_shift),		\
>>> +					.width = (_width),		\
>>> +					.table = (_tab),		\
>>> +					.flags = (_fl),			\
>>> +				 },					\
>>> +			},						\
>>> +		 },							\
>>> +	},								\
>>> +}
>>> +
>>>  #define LPC32XX_DEFINE_GATE(_idx, _reg, _bit, _flags)			\
>>>  [CLK_PREFIX(_idx)] = {							\
>>>  	.type = CLK_GATE,						\
>>> @@ -1281,14 +1325,14 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
>>>  	LPC32XX_DEFINE_GATE(MCPWM, TIMCLK_CTRL1, 6, 0),
>>>  
>>>  	LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0),
>>> -	LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL,
>>> -			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
>>> +	LPC32XX_DEFINE_PWM_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL,
>>> +			       CLK_DIVIDER_ONE_BASED),
>>>  	LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0),
>>>  	LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE),
>>>  
>>>  	LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0),
>>> -	LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL,
>>> -			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
>>> +	LPC32XX_DEFINE_PWM_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL,
>>> +			       CLK_DIVIDER_ONE_BASED),
>>>  	LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0),
>>>  	LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE),
>>>  
>>>

--
With best wishes,
Vladimir

^ permalink raw reply

* [PATCH] clk: lpc32xx: add a quirk for PWM and MS clock dividers
From: Vladimir Zapolskiy @ 2016-10-07  1:16 UTC (permalink / raw)
  To: linux-arm-kernel

In common clock framework CLK_DIVIDER_ONE_BASED or'ed with
CLK_DIVIDER_ALLOW_ZERO flags indicates that
1) a divider clock may be set to zero value,
2) divider's zero value is interpreted as a non-divided clock.

On the LPC32xx platform clock dividers of PWM and memory card clocks
comply with the first condition, but zero value means a gated clock,
thus it may happen that the divider value is not updated when
the clock is enabled and the clock remains gated.

The change adds one-shot quirks, which check for zero value of divider
on initialization and set it to a non-zero value, therefore in runtime
a gate clock will work as expected.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 drivers/clk/nxp/clk-lpc32xx.c | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
index 34c9735..5b98ff9 100644
--- a/drivers/clk/nxp/clk-lpc32xx.c
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -1282,13 +1282,13 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
 
 	LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0),
 	LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL,
-			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+			   CLK_DIVIDER_ONE_BASED),
 	LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0),
 	LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE),
 
 	LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0),
 	LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL,
-			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+			   CLK_DIVIDER_ONE_BASED),
 	LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0),
 	LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE),
 
@@ -1335,8 +1335,7 @@ static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
 	LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0),
 	LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE),
 
-	LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL,
-			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, CLK_DIVIDER_ONE_BASED),
 	LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9),
 			   0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops),
 	LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE),
@@ -1478,6 +1477,20 @@ static struct clk * __init lpc32xx_clk_register(u32 id)
 	return clk;
 }
 
+static void __init lpc32xx_clk_div_quirk(u32 reg, u32 div_mask, u32 gate)
+{
+	u32 val;
+
+	regmap_read(clk_regmap, reg, &val);
+
+	if (!(val & div_mask)) {
+		val &= ~gate;
+		val |= BIT(__ffs(div_mask));
+	}
+
+	regmap_update_bits(clk_regmap, reg, gate | div_mask, val);
+}
+
 static void __init lpc32xx_clk_init(struct device_node *np)
 {
 	unsigned int i;
@@ -1517,6 +1530,17 @@ static void __init lpc32xx_clk_init(struct device_node *np)
 		return;
 	}
 
+	/*
+	 * Divider part of PWM and MS clocks requires a quirk to avoid
+	 * a misinterpretation of formally valid zero value in register
+	 * bitfield, which indicates another clock gate. Instead of
+	 * adding complexity to a gate clock ensure that zero value in
+	 * divider clock is never met in runtime.
+	 */
+	lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf0, BIT(0));
+	lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf00, BIT(2));
+	lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_MS_CTRL, 0xf, BIT(5) | BIT(9));
+
 	for (i = 1; i < LPC32XX_CLK_MAX; i++) {
 		clk[i] = lpc32xx_clk_register(i);
 		if (IS_ERR(clk[i])) {
-- 
2.8.1

^ permalink raw reply related

* [PATCH 1/3] firmware: add lpc18xx boot rom driver
From: Vladimir Zapolskiy @ 2016-10-07  1:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160913195117.2887-2-manabian@gmail.com>

Hi Joachim,

On 13.09.2016 22:51, Joachim Eastwood wrote:
> Firmware driver for the boot ROM found on all NXP LPC18xx/43xx
> devices. This driver makes it possible to retrieve device specific
> information from either the ROM via API calls or from OTP memory.
> 
> The boot ROM contains several APIs for on-chip devices. Note that not
> all APIs are available on all devices. The API to retrieve device
> information and internal Flash programming (IAP) is only available on
> devices with Flash. Flashless devices retrieve device information from
> OTP memory. The CHIPID register in CREG (syscon) is used to check if
> IAP is available.
> 
> For now this driver is only used to expose device information via a
> 'SoC device'. Linux API for the IAP and OTP will be added later. These
> two APIs will be used by a Flash MTD driver and a OTP NVMEM driver to
> program the memory.
> 
> Signed-off-by: Joachim Eastwood <manabian@gmail.com>

please feel free to add to the series my

  Tested-by: Vladimir Zapolskiy <vz@mleia.com>
  Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>

I tested the change on a board powered by LPC4357.

Nevertheless I have some nitpicks for your consideration.

And the first one is that I'm not totally convinced that drivers/firmware
is the proper place for the driver, I tend to think that it might be
a good time to create drivers/soc/nxp/

> ---
>  drivers/firmware/Kconfig            |  12 ++
>  drivers/firmware/Makefile           |   1 +
>  drivers/firmware/nxp_lpc_boot_rom.c | 411 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 424 insertions(+)
>  create mode 100644 drivers/firmware/nxp_lpc_boot_rom.c
> 

[snip]

> +/* LPC18xx/43xx CREG (syscon) defines */
> +#define LPC18XX_CREG_CHIPID		0x200
> +#define LPC18XX_FLASH_CHIPID0		0x4284e02b
> +#define LPC18XX_FLASH_CHIPID1		0x7284e02b
> +#define LPC18XX_FLASHLESS_CHIPID0	0x5284e02b
> +#define LPC18XX_FLASHLESS_CHIPID1	0x6284e02b
> +#define LPC43XX_FLASH_CHIPID0		0x4906002b
> +#define LPC43XX_FLASH_CHIPID1		0x7906002b
> +#define LPC43XX_FLASHLESS_CHIPID0	0x5906002b
> +#define LPC43XX_FLASHLESS_CHIPID1	0x6906002b
> +
> +#define NXP_PART_LPC(_num, _id0, _id1, _sz0, _sz1)	\
> +	{						\
> +		.name = "LPC"#_num,			\
> +		.id[0] = _id0, .id[1] = _id1,		\
> +		.flash_size[0] = _sz0 * 1024,		\
> +		.flash_size[1] = _sz1 * 1024,		\
> +	}
> +
> +

checkpatch complains:

CHECK: Please don't use multiple blank lines
#145: FILE: drivers/firmware/nxp_lpc_boot_rom.c:75:
+
+

> +struct nxp_lpc_part {
> +	const char *name;
> +	u16 flash_size[2];

flash_size[2] is set by NXP_PART_LPC() macro but unused, however
in my build environment (W=1 and sparse checks) I get tons of
legitimate compile time warnings:

drivers/firmware/nxp_lpc_boot_rom.c:93:9: warning: cast truncates bits from constant value (80000 becomes 0)
drivers/firmware/nxp_lpc_boot_rom.c:93:9: warning: cast truncates bits from constant value (80000 becomes 0)
drivers/firmware/nxp_lpc_boot_rom.c:94:9: warning: cast truncates bits from constant value (80000 becomes 0)
drivers/firmware/nxp_lpc_boot_rom.c:94:9: warning: cast truncates bits from constant value (80000 becomes 0)
....

drivers/firmware/nxp_lpc_boot_rom.c:93:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
   NXP_PART_LPC(1857,  0xf001d830, 0x00, 512, 512),
   ^
drivers/firmware/nxp_lpc_boot_rom.c:93:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
drivers/firmware/nxp_lpc_boot_rom.c:94:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]
   NXP_PART_LPC(18S57, 0xf001d860, 0x00, 512, 512),
   ^
....

and so on.

Please consider either to store flash size in kB or change storage type to u32.

> +	u32 id[2];
> +};
> +
> +static const struct nxp_lpc_part nxp_lpc_parts[] = {
> +	/* LPC18xx Flashless parts */
> +	NXP_PART_LPC(1850,  0xf000d830, 0x00,   0,   0),
> +	NXP_PART_LPC(18S50, 0xf000d860, 0x00,   0,   0),
> +	NXP_PART_LPC(1830,  0xf000da30, 0x00,   0,   0),
> +	NXP_PART_LPC(18S30, 0xf000da60, 0x00,   0,   0),
> +	NXP_PART_LPC(1820,  0xf00adb3c, 0x00,   0,   0),
> +	NXP_PART_LPC(18S20, 0xf00adb6c, 0x00,   0,   0),
> +	NXP_PART_LPC(1810,  0xf00b5b3f, 0x00,   0,   0),
> +	NXP_PART_LPC(18S10, 0xf00b5b6f, 0x00,   0,   0),
> +	/* LPC18xx Flash parts */
> +	NXP_PART_LPC(1857,  0xf001d830, 0x00, 512, 512),
> +	NXP_PART_LPC(18S57, 0xf001d860, 0x00, 512, 512),
> +	NXP_PART_LPC(1853,  0xf001d830, 0x44, 256, 256),
> +	NXP_PART_LPC(1837,  0xf001da30, 0x00, 512, 512),
> +	NXP_PART_LPC(18S37, 0xf001d860, 0x00, 512, 512),
> +	NXP_PART_LPC(1833,  0xf001da30, 0x44, 256, 256),
> +	NXP_PART_LPC(1827,  0xf001db3c, 0x00, 512, 512),
> +	NXP_PART_LPC(1825,  0xf001db3c, 0x22, 384, 384),
> +	NXP_PART_LPC(1823,  0xf00bdb3c, 0x44, 256, 256),
> +	NXP_PART_LPC(1822,  0xf00bdb3c, 0x80, 512,   0),
> +	NXP_PART_LPC(1817,  0xf001db3f, 0x00, 512, 512),
> +	NXP_PART_LPC(1815,  0xf001db3f, 0x22, 384, 384),
> +	NXP_PART_LPC(1813,  0xf00bdb3f, 0x44, 256, 256),
> +	NXP_PART_LPC(1812,  0xf00bdb3f, 0x80, 512,   0),
> +	/* LPC43xx Flashless parts */
> +	NXP_PART_LPC(4370,  0x00000030, 0x00,   0,   0), /* LBGA256 */
> +	NXP_PART_LPC(4370,  0x00000230, 0x00,   0,   0), /* TFBGA100 */
> +	NXP_PART_LPC(43S70, 0x00000060, 0x00,   0,   0),
> +	NXP_PART_LPC(4350,  0xa0000830, 0x00,   0,   0),
> +	NXP_PART_LPC(43S50, 0xa0000860, 0x00,   0,   0),
> +	NXP_PART_LPC(4330,  0xa0000a30, 0x00,   0,   0),
> +	NXP_PART_LPC(43S30, 0xa0000a60, 0x00,   0,   0),
> +	NXP_PART_LPC(4320,  0xa000cb3c, 0x00,   0,   0),
> +	NXP_PART_LPC(43S20, 0xa000cb6c, 0x00,   0,   0),
> +	NXP_PART_LPC(4310,  0xa00acb3f, 0x00,   0,   0),
> +	/* LPC43xx parts with Flash */
> +	NXP_PART_LPC(4367,  0x8001c030, 0x00, 512, 512),
> +	NXP_PART_LPC(43S67, 0x8001c060, 0x00, 512, 512),
> +	NXP_PART_LPC(4357,  0xa001c830, 0x00, 512, 512),
> +	NXP_PART_LPC(43S57, 0xa001c860, 0x00, 512, 512), /* LBGA256 */
> +	NXP_PART_LPC(43S57, 0xa001ca60, 0x00, 512, 512), /* LQFP208 */
> +	NXP_PART_LPC(4353,  0xa001c830, 0x44, 256, 256),
> +	NXP_PART_LPC(4337,  0xa001ca30, 0x00, 512, 512),
> +	NXP_PART_LPC(43S37, 0xa001ca60, 0x00, 512, 512),
> +	NXP_PART_LPC(4333,  0xa001ca30, 0x44, 256, 256),
> +	NXP_PART_LPC(4327,  0xa001cb3c, 0x00, 512, 512),
> +	NXP_PART_LPC(4325,  0xa001cb3c, 0x22, 384, 384),
> +	NXP_PART_LPC(4323,  0xa00bcb3c, 0x44, 256, 256),
> +	NXP_PART_LPC(4322,  0xa00bcb3c, 0x80, 512,   0),
> +	NXP_PART_LPC(4317,  0xa001cb3f, 0x00, 512, 512),
> +	NXP_PART_LPC(4315,  0xa001cb3f, 0x22, 384, 384),
> +	NXP_PART_LPC(4313,  0xa00bcb3f, 0x44, 256, 256),
> +	NXP_PART_LPC(4312,  0xa00bcb3f, 0x80, 512,   0),
> +};
> +
> +struct iap_rom {
> +	void (*entry)(u32 *, u32 *);
> +};

Here it might be simpler to declare a typedef instead of a struct.

> +struct nxp_rom_api {
> +	struct device *dev;
> +	void __iomem *rom;
> +
> +	bool has_iap;
> +	struct iap_rom iap;
> +	spinlock_t lock;
> +
> +	const struct nxp_lpc_part *part;
> +	const char *partname;
> +	u32 boot_version;
> +
> +	struct soc_device *soc_dev;
> +	struct soc_device_attribute soc_dev_attr;
> +};
> +

--
With best wishes,
Vladimir

^ permalink raw reply

* [PATCH 1/3] nvmem: add NXP LPC18xx OTP driver
From: Vladimir Zapolskiy @ 2016-10-07  1:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160913161241.22492-2-manabian@gmail.com>

Hi Joachim, Srinivas,

On 13.09.2016 19:12, Joachim Eastwood wrote:
> Add simple read only driver for the internal OTP (One Time Programmable)
> memory found on all NXP LPC18xx and LPC43xx devices.
> 
> The OTP memory is split into 4 banks each with 4 32-bits word. Some of
> the banks contain predefined data while others are for general purpose
> and user programmable via the OTP API in ROM. Note that writing to the
> OTP memory is not yet supported.
> 
> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
> ---

please feel free to add my

  Tested-by: Vladimir Zapolskiy <vz@mleia.com>

--
With best wishes,
Vladimir

^ permalink raw reply

* [PATCH 3/3] ARM: dts: lpc18xx: add boot rom node
From: Vladimir Zapolskiy @ 2016-10-07  1:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160913195117.2887-4-manabian@gmail.com>

Hi Joachim,

On 13.09.2016 22:51, Joachim Eastwood wrote:
> Add node for the boot ROM found on all NXP LPC18xx/43xx devices.
> 
> Signed-off-by: Joachim Eastwood <manabian@gmail.com>
> ---
>  arch/arm/boot/dts/lpc18xx.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/lpc18xx.dtsi b/arch/arm/boot/dts/lpc18xx.dtsi
> index 631e6f6c..9f94f3e 100644
> --- a/arch/arm/boot/dts/lpc18xx.dtsi
> +++ b/arch/arm/boot/dts/lpc18xx.dtsi
> @@ -81,6 +81,14 @@
>  			status = "disabled";
>  		};
>  
> +		boot_rom: firmware at 10400000 {
> +			compatible = "nxp,lpc1850-boot-rom";
> +			reg = <0x10400000 0x10000>;
> +			syscon = <&creg>;
> +			nvmem-cells = <&part_id>;

nitpicking, this change has a compile time dependency on yours
"nvmem: add lpc18xx OTP memory driver" series, I haven't noticed
this info stated, but it may be an overlook on my part.

> +			nvmem-cell-names = "PartID";
> +		};
> +
>  		dmac: dma-controller at 40002000 {
>  			compatible = "arm,pl080", "arm,primecell";
>  			arm,primecell-periphid = <0x00041080>;
> 

Tested-by: Vladimir Zapolskiy <vz@mleia.com>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>

--
With best wishes,
Vladimir

^ permalink raw reply

* [PATCH v2 2/2] ARM: dts: rockchip: Add rk3066 MK808 board
From: Shawn Lin @ 2016-10-07  2:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b63a0ad452a487beb1d0c07addb9208cc3b3eeef.1475774981.git.paweljarosz3691@gmail.com>

Hi Pawe? ,

On 2016/10/7 1:38, Pawe? Jarosz wrote:
> MK808 is a tv stick which has rockchip rk3066 CPU inside, two usb ports
> - host and otg, micro sd card slot and onboard wifi RK901.
>
> Signed-off-by: Pawe? Jarosz <paweljarosz3691@gmail.com>
> ---
>
> Changes in v2:
> - included Heiko sugestion.
>
>  Documentation/devicetree/bindings/arm/rockchip.txt |   4 +
>  arch/arm/boot/dts/Makefile                         |   1 +
>  arch/arm/boot/dts/rk3066a-mk808.dts                | 184 +++++++++++++++++++++
>  3 files changed, 189 insertions(+)
>  create mode 100644 arch/arm/boot/dts/rk3066a-mk808.dts
>
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
> index 55f388f..c09595b 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.txt
> +++ b/Documentation/devicetree/bindings/arm/rockchip.txt
> @@ -17,6 +17,10 @@ Rockchip platforms device tree bindings
>      Required root node properties:
>        - compatible = "chipspark,rayeager-px2", "rockchip,rk3066a";
>
> +- Rikomagic MK808 v1 board:
> +    Required root node properties:
> +      - compatible = "rikomagic,mk808", "rockchip,rk3066a";
> +
>  - Radxa Rock board:
>      Required root node properties:
>        - compatible = "radxa,rock", "rockchip,rk3188";
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index befcd26..f19cc1d 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -639,6 +639,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
>  	rk3036-kylin.dtb \
>  	rk3066a-bqcurie2.dtb \
>  	rk3066a-marsboard.dtb \
> +	rk3066a-mk808.dtb \
>  	rk3066a-rayeager.dtb \
>  	rk3188-radxarock.dtb \
>  	rk3228-evb.dtb \
> diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
> new file mode 100644
> index 0000000..2878562
> --- /dev/null
> +++ b/arch/arm/boot/dts/rk3066a-mk808.dts
> @@ -0,0 +1,184 @@
> +/*
> + * Copyright (c) 2016 Pawe? Jarosz <paweljarosz3691@gmail.com>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +#include "rk3066a.dtsi"
> +
> +/ {
> +	model = "Rikomagic MK808";
> +	compatible = "rikomagic,mk808", "rockchip,rk3066a";
> +
> +	chosen {
> +		stdout-path = "serial2:115200n8";
> +	};
> +
> +	memory at 60000000 {
> +		device_type = "memory";
> +		reg = <0x60000000 0x40000000>;
> +	};
> +
> +	gpio-leds {
> +		compatible = "gpio-leds";
> +
> +		blue {
> +			label = "mk808:blue:power";
> +			gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +			linux,default-trigger = "default-on";
> +		};
> +	};
> +
> +	mmc_pwrseq: mmc-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&sdmmc_pwr>;

sd slot does not contain a reset pin. So the power pin should be
enough. just add sdmmc_pwr to mmc0's pinctrl-0 and let mmc driver
control it should be enough. Typically pwrseq is for emmc and sdio.
We don't need a pwerseq to control power for sd slot..

But it seems sdmmc_pwr is a GPIO, but not functional port.
So I am interesting that why MK808 board doesn't use the mmc
controller's default power pin but chosing another gpio, so finally
we have to add thses code for your DT.

> +		reset-gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>;
> +	};
> +
> +	sdio_pwrseq: sdio-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&wifi_pwr>;
> +		reset-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
> +	};
> +
> +	vcc_io: vcc-io {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_io";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;

Are you sure it should be fixed to 5V? I ask this since I see
the mmc use this as vmmc which should be 3V~3V3 in principle.

> +		regulator-always-on;

I'm not sure whether you need this. The regulator would maintain
the user_count there. So from this patch, I think it should be turned
off since we possible don't enable usb and mmc?

Moreover, the always-on power supply is depreciated by vmmc since it
cause some problem to a certain degree.

> +	};
> +
> +	vcc_host: usb-host-regulator {
> +		compatible = "regulator-fixed";
> +		gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
> +		pinctrl-0 = <&host_drv>;
> +		pinctrl-names = "default";
> +		regulator-always-on;
> +		regulator-name = "host-pwr";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		startup-delay-us = <100000>;
> +		vin-supply = <&vcc_io>;
> +	};
> +
> +	vcc_otg: usb-otg-regulator {
> +		compatible = "regulator-fixed";
> +		gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
> +		pinctrl-0 = <&otg_drv>;
> +		pinctrl-names = "default";
> +		regulator-always-on;
> +		regulator-name = "vcc_otg";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		startup-delay-us = <100000>;
> +		vin-supply = <&vcc_io>;
> +	};
> +};

Same concern for these above.

> +
> +&mmc0 {
> +	bus-width = <4>;
> +	cap-mmc-highspeed;
> +	cap-sd-highspeed;
> +	mmc-pwrseq = <&mmc_pwrseq>;

Removed this could make SD works?

Also do you need disable-wp for sd slot?

> +	num-slots = <1>;
> +	status = "okay";
> +	vmmc-supply = <&vcc_io>;
> +};
> +
> +&mmc1 {
> +	bus-width = <4>;
> +	disable-wp;
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +	non-removable;
> +	num-slots = <1>;
> +	status = "okay";
> +	vmmc-supply = <&vcc_io>;
> +};
> +
> +&pinctrl {
> +	usb-host {
> +		host_drv: host-drv {
> +			rockchip,pins = <RK_GPIO0 6 RK_FUNC_GPIO &pcfg_pull_default>;
> +		};
> +	};
> +
> +	usb-otg {
> +		otg_drv: otg-drv {
> +			rockchip,pins = <RK_GPIO0 5 RK_FUNC_GPIO &pcfg_pull_default>;
> +		};
> +	};
> +
> +	sdmmc {
> +		sdmmc_pwr: sdmmc-pwr {
> +			rockchip,pins = <RK_GPIO3 7 RK_FUNC_GPIO &pcfg_pull_default>;
> +		};
> +	};
> +
> +	sdio {
> +		wifi_pwr: wifi-pwr {
> +			rockchip,pins = <RK_GPIO3 24 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +};
> +
> +&uart2 {
> +	status = "okay";
> +};
> +
> +&usb_host {
> +	status = "okay";
> +};
> +
> +&usb_otg {
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	status = "okay";
> +};
> +
> +&wdt {
> +	status = "okay";
> +};
> +
>


-- 
Best Regards
Shawn Lin

^ permalink raw reply

* [PATCH 1/3] fpga manager: Add cyclonespi driver for Altera fpgas
From: Moritz Fischer @ 2016-10-07  2:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4b4432c04b4ea92a2af814e3d7866c33f2eb12ea.1475783742.git.stillcompiling@gmail.com>

Hi Joshua,

couple of nits inline below:

On Thu, Oct 6, 2016 at 1:34 PM, Joshua Clayton <stillcompiling@gmail.com> wrote:

> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index cd84934..ccad5b1 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -13,6 +13,12 @@ config FPGA
>
>  if FPGA
>
> +config FPGA_MGR_CYCLONE_SPI
> +       tristate "Altera Cyclone V SPI"
> +       depends on SPI
> +       help
> +         FPGA manager driver support for Altera Cyclone V over SPI
> +
>  config FPGA_MGR_SOCFPGA
>         tristate "Altera SOCFPGA FPGA Manager"
>         depends on ARCH_SOCFPGA
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 8d83fc6..c03f40de 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -6,5 +6,6 @@
>  obj-$(CONFIG_FPGA)                     += fpga-mgr.o
>
>  # FPGA Manager Drivers
> +obj-$(CONFIG_FPGA_MGR_CYCLONE_SPI)     += cyclonespi.o
>  obj-$(CONFIG_FPGA_MGR_SOCFPGA)         += socfpga.o
>  obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)       += zynq-fpga.o
> diff --git a/drivers/fpga/cyclonespi.c b/drivers/fpga/cyclonespi.c
> new file mode 100644
> index 0000000..1ffa67c
> --- /dev/null
> +++ b/drivers/fpga/cyclonespi.c
> @@ -0,0 +1,173 @@
> +/**
> + * Copyright (c) 2015 United Western Technologies, Corporation
> + *
> + * Joshua Clayton <stillcompiling@gmail.com>
> + *
> + * Manage Altera fpga firmware that is loaded over spi.
> + * Firmware must be in binary "rbf" format.
> + * Works on Cyclone V. Should work on cyclone series.
> + * May work on other Altera fpgas.

I think at one point we decided it's gonna be 'FPGA' to be consistent.

> +
> +static const struct of_device_id of_ef_match[] = {
> +       { .compatible = "altr,cyclonespi-fpga-mgr", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, of_ef_match);
> +
> +static enum fpga_mgr_states cyclonespi_state(struct fpga_manager *mgr)
> +{
> +       return mgr->state;
> +}
> +
> +static inline u32 revbit8x4(u32 n)
> +{
> +       n = ((n & 0xF0F0F0F0UL) >> 4) | ((n & 0x0F0F0F0FUL) << 4);
> +       n = ((n & 0xCCCCCCCCUL) >> 2) | ((n & 0x33333333UL) << 2);
> +       n = ((n & 0xAAAAAAAAUL) >> 1) | ((n & 0x55555555UL) << 1);
> +       return n;
> +}

During the Zynq FPGA manager reviews we decided that manipulating the bitstream
to be consumable by the driver is userland's job.

> +
> +static int cyclonespi_write_init(struct fpga_manager *mgr, u32 flags,
> +                               const char *buf, size_t count)
> +{
> +       struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
> +       u32 *fw32 = (u32 *)buf;
> +       const u32 *fw_end = (u32 *)(buf + count);
> +
> +       if (flags & FPGA_MGR_PARTIAL_RECONFIG) {
> +               dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
> +               return -EINVAL;

-ENOTSUPP?
> +       }
> +
> +       gpiod_set_value(conf->reset, 0);
> +       udelay(50);

Should that value either be configurable, or a named constant?
> +       msleep(1);

See above.

> +       /* set buffer to lsb first */
> +       while (fw32 < fw_end) {
> +               *fw32 = revbit8x4(*fw32);
> +               fw32++;
> +       }

See above.
> +
> +       return 0;
> +}
> +
> +static int cyclonespi_write(struct fpga_manager *mgr, const char *buf,
> +                          size_t count)
> +{
> +       struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
> +       const char *fw_data = buf;
> +       const char *fw_data_end = fw_data + count;
> +
> +       while (fw_data < fw_data_end) {
> +               int ret;
> +               int stride = fw_data_end - fw_data;
> +
> +               if (stride > SZ_4K)
> +                       stride = SZ_4K;
> +
> +               ret = spi_write(conf->spi, fw_data, stride);
> +               if (ret) {
> +                       dev_err(&mgr->dev, "spi error in firmware write: %d\n",
> +                                       ret);
> +                       return ret;
> +               }
> +               fw_data += stride;
> +       }
> +
> +       return 0;
> +}
> +
> +static int cyclonespi_write_complete(struct fpga_manager *mgr, u32 flags)
> +{
> +       struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
> +
> +       if (gpiod_get_value(conf->status) == 0) {
> +               dev_err(&mgr->dev, "Error during configuration.\n");
> +               return -EIO;
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct fpga_manager_ops cyclonespi_ops = {
> +       .state = cyclonespi_state,
> +       .write_init = cyclonespi_write_init,
> +       .write = cyclonespi_write,
> +       .write_complete = cyclonespi_write_complete,
> +};
> +
> +static int cyclonespi_probe(struct spi_device *spi)
> +{
> +       struct cyclonespi_conf *conf = devm_kzalloc(&spi->dev, sizeof(*conf),
> +                                               GFP_KERNEL);
> +
> +       if (!conf)
> +               return -ENOMEM;
> +
> +       conf->spi = spi;
> +       conf->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW);
> +       if (IS_ERR(conf->reset)) {
> +               dev_err(&spi->dev, "Failed to get reset gpio: %ld\n",
> +                       PTR_ERR(conf->reset));
> +               return PTR_ERR(conf->reset);
> +       }
> +
> +       conf->status = devm_gpiod_get(&spi->dev, "status", GPIOD_IN);
> +       if (IS_ERR(conf->status)) {
> +               dev_err(&spi->dev, "Failed to get status gpio: %ld\n",
> +                               PTR_ERR(conf->status));
> +               return PTR_ERR(conf->status);
> +       }
> +
> +       return fpga_mgr_register(&spi->dev, "Altera SPI FPGA Manager",
> +                                &cyclonespi_ops, conf);

Nit: Altera >Cyclone< SPI FPGA Manager

Thanks ... reminds me I wanted to submit my patch for the icoboard ;-)

Moritz

^ permalink raw reply

* [PATCH 2/3] doc: dt: add cyclone-spi binding document
From: Moritz Fischer @ 2016-10-07  2:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8d89e70475e8e1c3ce5117a0367c8444c11c61e3.1475783742.git.stillcompiling@gmail.com>

Hi Joshua,

On Thu, Oct 6, 2016 at 1:34 PM, Joshua Clayton <stillcompiling@gmail.com> wrote:
> Describe a cyclonespi devicetree entry, required features
>
> Signed-off-by: Joshua Clayton <stillcompiling@gmail.com>
> ---
>  .../bindings/fpga/cyclone-spi-fpga-mgr.txt         | 23 ++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-spi-fpga-mgr.txt
>
> diff --git a/Documentation/devicetree/bindings/fpga/cyclone-spi-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/cyclone-spi-fpga-mgr.txt
> new file mode 100644
> index 0000000..8de34db
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/cyclone-spi-fpga-mgr.txt
> @@ -0,0 +1,23 @@
> +Altera SOCFPGA FPGA Manager

Copy & Paste? :)

> +Altera cyclone FPGAs support a method of loading the bitstream over what is

cyclone->Cyclone

> +referred to as "passive serial".
> +The passive serial link is not technically spi, and might require extra
> +circuits in order to play nicely with other spi slaves on the same bus.
> +
> +See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf
> +
> +Required properties:
> +- compatible  : should contain "altr,cyclonespi-fpga-mgr"

Alan, do you guys have any input on the compat string?

I think generally the bindings should go before the actual usage in
your patch series. Meaning you wanna document the binding
before you use it. I think this patch should be [1/3].

Cheers,

Moritz

^ permalink raw reply

* [PATCH v3 04/11] ARM: dts: r8a7743: initial SoC device tree
From: Simon Horman @ 2016-10-07  3:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2883940.Oo8sg10L7m@wasted.cogentembedded.com>

Hi Sergei,

On Thu, Oct 06, 2016 at 12:38:18AM +0300, Sergei Shtylyov wrote:
> The  initial R8A7743 SoC device tree including CPU cores, GIC, timer, SYSC,
> CPG, and the required clock descriptions.
> 
> Based on the original (and large) patch by Dmitry Shifrin
> <dmitry.shifrin@cogentembedded.com>.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

I notice that this patch enables two CPUs. Have you tested SMP and:
- CPU hotplug
- Suspend to RAM

^ permalink raw reply

* [PATCH v3 03/11] ARM: shmobile: r8a7743: basic SoC support
From: Simon Horman @ 2016-10-07  3:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <15557770.lH5aPepOeZ@wasted.cogentembedded.com>

On Thu, Oct 06, 2016 at 12:37:08AM +0300, Sergei Shtylyov wrote:
> Add minimal support for the RZ/G1M (R8A7743) SoC.
> 
> Based on the original (and large) patch by Dmitry Shifrin
> <dmitry.shifrin@cogentembedded.com>.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Thanks, I have queued this up.

^ permalink raw reply

* [PATCH 0/2] ARM: shmobile: alt/gose: Add board part number to DT bindings
From: Simon Horman @ 2016-10-07  3:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475587248-13670-1-git-send-email-geert+renesas@glider.be>

On Tue, Oct 04, 2016 at 03:20:46PM +0200, Geert Uytterhoeven wrote:
> 	Hi Simon, Magnus,
> 
> This series at the missing board part numbers for r8a7794/alt and
> r8a7793/gose to the DT binding documentation, like is done for the other
> boards.
> 
> Thanks for applying!
> 
> Geert Uytterhoeven (2):
>   ARM: shmobile: r8a7794/alt: Add board part number to DT bindings
>   ARM: shmobile: r8a7793/gose: Add board part number to DT bindings

Thanks, I have queued these up.

^ permalink raw reply

* [PATCH] ARM: dts: r8a7794: Fix W=1 dtc warnings
From: Simon Horman @ 2016-10-07  3:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475587908-22151-1-git-send-email-geert+renesas@glider.be>

On Tue, Oct 04, 2016 at 03:31:48PM +0200, Geert Uytterhoeven wrote:
> Warning (unit_address_vs_reg): Node /sound at ec500000/rcar_sound,dvc/dvc at 0 has a unit name, but no reg property

...

> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
>  arch/arm/boot/dts/r8a7794.dtsi | 58 +++++++++++++++++++++---------------------
>  1 file changed, 29 insertions(+), 29 deletions(-)

Thanks, I have queued this up.

^ permalink raw reply

* [PATCH v2 2/6] pwm: core: make the PWM_POLARITY flag in DTB optional
From: Bhuvanchandra DV @ 2016-10-07  4:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161006083642.6a28a629@jawa>

Hi Lukasz,

On 10/06/16 12:06, Lukasz Majewski wrote:

> Hi Bhuvanchandra,
>
>> From: Lothar Wassmann <LW@KARO-electronics.de>
>>
>> Change the pwm chip driver registration, so that a chip driver that
>> supports polarity inversion can still be used with DTBs that don't
>> provide the 'PWM_POLARITY' flag.
>>
>> This is done to provide polarity inversion support for the pwm-imx
>> driver without having to modify all existing DTS files.
>>
>> Signed-off-by: Lothar Wassmann <LW@KARO-electronics.de>
>> Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
>> Suggested-by: Thierry Reding <thierry.reding@gmail.com>
>> ---
>>   drivers/pwm/core.c | 27 ++++++++++++++++-----------
>>   1 file changed, 16 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
>> index 195373e..aae8db3 100644
>> --- a/drivers/pwm/core.c
>> +++ b/drivers/pwm/core.c
>> @@ -137,9 +137,14 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc,
>> const struct of_phandle_args *args) {
>>   	struct pwm_device *pwm;
>>   
>> +	/* check, whether the driver supports a third cell for flags
>> */ if (pc->of_pwm_n_cells < 3)
>>   		return ERR_PTR(-EINVAL);
>>   
>> +	/* flags in the third cell are optional */
>> +	if (args->args_count < 2)
>> +		return ERR_PTR(-EINVAL);
>> +
>>   	if (args->args[0] >= pc->npwm)
>>   		return ERR_PTR(-EINVAL);
>>   
>> @@ -149,10 +154,12 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc,
>> const struct of_phandle_args *args)
>>   	pwm->args.period = args->args[1];
>>   
>> -	if (args->args[2] & PWM_POLARITY_INVERTED)
>> -		pwm->args.polarity = PWM_POLARITY_INVERSED;
>> -	else
>> -		pwm->args.polarity = PWM_POLARITY_NORMAL;
>> +	if (args->args_count > 2) {
>> +		if (args->args[2] & PWM_POLARITY_INVERTED)
>> +			pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
> 			^^^^^^^^^^^^^^^^
> 			here we should set pwm->args.polarity, since
> 			the pwm_set_polarity() calls pwm_apply_state()
> 			which requires duty_cycle and period to be set.
>
> 			In this particular moment it is not yet set and
> 			polarity is not properly configured.

Agreed. Will do a clean v3 patchset along with the patch you sent
(pwm: core: Use pwm->args.polarity to setup PWM_POLARITY_INVERSED).

--
Bhuvan

>
> Patch fixing this will be sent as a reply to this e-mail. Please just
> squash it and test on your platform.
>
> Best regards,
> ?ukasz Majewski
>
>> +		else
>> +			pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
>> +	}
>>   
>>   	return pwm;
>>   }
>> @@ -163,9 +170,14 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const
>> struct of_phandle_args *args) {
>>   	struct pwm_device *pwm;
>>   
>> +	/* sanity check driver support */
>>   	if (pc->of_pwm_n_cells < 2)
>>   		return ERR_PTR(-EINVAL);
>>   
>> +	/* all cells are required */
>> +	if (args->args_count != pc->of_pwm_n_cells)
>> +		return ERR_PTR(-EINVAL);
>> +
>>   	if (args->args[0] >= pc->npwm)
>>   		return ERR_PTR(-EINVAL);
>>   
>> @@ -672,13 +684,6 @@ struct pwm_device *of_pwm_get(struct device_node
>> *np, const char *con_id) goto put;
>>   	}
>>   
>> -	if (args.args_count != pc->of_pwm_n_cells) {
>> -		pr_debug("%s: wrong #pwm-cells for %s\n",
>> np->full_name,
>> -			 args.np->full_name);
>> -		pwm = ERR_PTR(-EINVAL);
>> -		goto put;
>> -	}
>> -
>>   	pwm = pc->of_xlate(pc, &args);
>>   	if (IS_ERR(pwm))
>>   		goto put;

^ permalink raw reply

* [PATCH v2 5/6] arm: dts: imx7-colibri: Use pwm polarity control
From: Bhuvanchandra DV @ 2016-10-07  4:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161006084007.44c5cbae@jawa>

On 10/06/16 12:10, Lukasz Majewski wrote:

> On Sat, 1 Oct 2016 15:42:34 +0530
> Bhuvanchandra DV <bhuvanchandra.dv@toradex.com> wrote:
>
>> Configure PWM polarity control.
>>
>> Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
>> ---
>>   arch/arm/boot/dts/imx7-colibri.dtsi | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi
>> b/arch/arm/boot/dts/imx7-colibri.dtsi index a9cc657..2af5e3e 100644
>> --- a/arch/arm/boot/dts/imx7-colibri.dtsi
>> +++ b/arch/arm/boot/dts/imx7-colibri.dtsi
>> @@ -43,7 +43,7 @@
>>   / {
>>   	bl: backlight {
>>   		compatible = "pwm-backlight";
>> -		pwms = <&pwm1 0 5000000>;
>> +		pwms = <&pwm1 0 5000000 0>;
> My recommendation would be to add:
> #include <dt-bindings/pwm/pwm.h>
>
> and then define pwms as:
>
> pwms = <&pwm1 0 5000000 PWM_POLARITY_NORMAL>;
>
> It would be more readable

Ok, will add that.

--
Bhuvan

>
> Best regards,
> ?ukasz Majewski
>
>>   	};
>>   
>>   	reg_module_3v3: regulator-module-3v3 {

^ permalink raw reply

* [PATCH v5 2/5] drm/bridge: Add RGB to VGA bridge support
From: Archit Taneja @ 2016-10-07  4:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1757833.hOePAQC2sg@avalon>



On 10/07/2016 02:34 AM, Laurent Pinchart wrote:
> Hi Sean,
>
> On Thursday 06 Oct 2016 15:53:28 Sean Paul wrote:
>> On Thu, Oct 6, 2016 at 1:27 PM, Laurent Pinchart wrote:
>>> On Thursday 06 Oct 2016 17:09:57 Archit Taneja wrote:
>>>> On 10/06/2016 12:51 PM, Maxime Ripard wrote:
>>>>> On Mon, Oct 03, 2016 at 04:40:57PM +0530, Archit Taneja wrote:
>>>>>> On 09/30/2016 08:07 PM, Maxime Ripard wrote:
>>>>>>> Some boards have an entirely passive RGB to VGA bridge, based on
>>>>>>> either DACs or resistor ladders.
>>>>>>>
>>>>>>> Those might or might not have an i2c bus routed to the VGA connector
>>>>>>> in order to access the screen EDIDs.
>>>>>>>
>>>>>>> Add a bridge that doesn't do anything but expose the modes available
>>>>>>> on the screen, either based on the EDIDs if available, or based on
>>>>>>> the XGA standards.
>>>>>>>
>>>>>>> Acked-by: Rob Herring <robh@kernel.org>
>>>>>>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>>>>> ---
>>>>>>> .../bindings/display/bridge/rgb-to-vga-bridge.txt  |  48 +++++
>>>>>>> drivers/gpu/drm/bridge/Kconfig                     |   7 +
>>>>>>> drivers/gpu/drm/bridge/Makefile                    |   1 +
>>>>>>> drivers/gpu/drm/bridge/rgb-to-vga.c                | 229 +++++++++++++
>>>>>>> 4 files changed, 285 insertions(+)
>>>>>>> create mode 100644
>>>>>>> Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.tx
>>>>>>> t
>>>>>>> create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c
>>>>>>>
>>>>>>> diff --git
>>>>>>> a/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.
>>>>>>> txt
>>>>>>> b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.
>>>>>>> txt
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..a8375bc1f9cb
>>>>>>> --- /dev/null
>>>>>>> +++
>>>>>>> b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.
>>>>>>> tx
>>>>>>> t @@ -0,0 +1,48 @@
>>>>>>> +Dumb RGB to VGA bridge
>>>>>>> +----------------------
>>>>>>> +
>>>>>>> +This binding is aimed for dumb RGB to VGA bridges that do not
>>>>>>> require
>>>>>>> +any configuration.
>>>>>>> +
>>>>>>> +Required properties:
>>>>>>> +
>>>>>>> +- compatible: Must be "rgb-to-vga-bridge"
>>>>>>
>>>>>> I'd talked to Laurent on IRC if he's okay with this. And I guess you
>>>>>> to had discussed it during XDC too. He's suggested that it'd be better
>>>>>> to have the compatible string as "simple-vga-dac".
>>>>>
>>>>> I just wished this bikeshedding had taken place publicly and be
>>>>> actually part of that discussion, but yeah, ok.
>>>>
>>>> Sorry about that. I'd pinged him for an Ack, the discussion went
>>>> more than that :)
>>>>
>>>>>> Some of the reasons behind having this:
>>>>>>
>>>>>> - We don't need to specify "rgb" in the compatible string since most
>>>>>> simple VGA DACs can only work with an RGB input.
>>>>>
>>>>> Ok.
>>>>>
>>>>>> - Also, with "dac" specified in the string, we don't need to
>>>>>> specifically mention "bridge" in the string. Also, bridge is a drm
>>>>>> specific term.
>>>>>>
>>>>>> - "simple" is considered because it's an unconfigurable bridge, and it
>>>>>> might be misleading for other VGA DACs to not use "vga-dac".
>>>>>
>>>>> All those "simple" bindings are just the biggest lie we ever
>>>>> told. It's simple when you introduce it, and then grows into something
>>>>> much more complicated than a non-simple implementation.
>>>>
>>>> "simple" here is supposed to mean that it's an unconfigurable RGB to
>>>> VGA DAC. This isn't supposed to follow the simple-panel model, where
>>>> you add the "simple-panel" string in the compatible node, along with
>>>> you chip specific compatible string.
>>>
>>> I agree with Maxime, I don't like the word "simple". My preference would
>>> be "vga-dac" for a lack of a better qualifier than "simple" to describe
>>> the fact that the device requires no configuration. My only concern with
>>> "vga-dac" is that we would restrict usage of that compatible string for a
>>> subset of VGA DACs, with more complex devices not being compatible with
>>> "vga-dac" even though they are VGA DACs. That's a problem I can live with
>>> though.
>>
>> While we're bikeshedding (feel free to ignore my input on this), I
>> think Maxime's initial "dumb" qualifier was better than "simple".
>
> I think I agree.
>
>> I think "passive" also gets the point across better than "simple", which
>> we've already established as something else in drm.
>
> To my electrical engineer's ear, passive refers to a component or combination
> of components that is not capable of power gain. The resistors ladder VGA DAC
> that Maxime is trying to support is a passive system, but the ADV7123 VGA DAC
> that equally requires no configuration is an active component.

If no one has any more objections within the next day, I'll pull in
Maxime's v5 RGB to VGA bridge driver, and change the compatible to
"dumb-vga-dac".

Thanks,
Archit


>
>> Now that I've gotten that out of the way, this patch looks good to me
>> regardless of the name.
>>
>> Reviewed-by: Sean Paul <seanpaul@chromium.org>
>>
>> Sean
>>
>>>> In other words, this driver shouldn't be touched again in the future :)
>>>> If someone wants to write a RGB to VGA driver which is even
>>>> slightly configurable, they'll need to write a new bridge driver.
>>>
>>> I'm sure that won't be true. I can certainly foresee the addition of
>>> regulators support for instance. It's unfortunately never black and white.
>>>
>>>>>> What do you think about this? If you think it's good, would it be
>>>>>> possible for you to change this? I guess it's okay for the rest of
>>>>>> the patch to stay the same.
>>>>>
>>>>> I'll update and respin the serie.
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH V5 00/10] dmaengine: qcom_hidma: add MSI interrupt support
From: Sinan Kaya @ 2016-10-07  5:25 UTC (permalink / raw)
  To: linux-arm-kernel

The new version of the HW supports MSI interrupts instead of wired
interrupts. The MSI interrupts are especially useful for the guest machine
execution. The wired interrupts usually trap to the hypervisor and then are
relayed to the actual interrupt.

The MSI interrupts can be directly fed into the interrupt controller.

Adding a new OF compat string (qcom,hidma-1.1) and ACPI string (QCOM8062)
to distinguish newer HW from the older ones.

v5:
* dmaengine: qcom_hidma: add MSI support for interrupts
** Return MSI interrupts before calling platform_msi_domain_free_irqs.
Also cleanup MSI interrupts on the error path.
** Free the legacy IRQ only if MSI is disabled
* add dmaengine: qcom_hidma: break completion processing on error
in order to break the completions if an error is observed while servicing
completed work.
* drop dmaengine: qcom_hidma: make error and success path common
as the success path assumes that we'll get the number of notifications for
the
jobs queued. This is not true under error conditions.
* simplify dmaengine: qcom_hidma: protect common data structures. We just
need to protect the TRE processed offset. It is the variable that keeps
track
of outstanding requests.
* document assumptions about of_msi_configure routine call.

v4:
http://www.spinics.net/lists/devicetree/msg144563.html
* device tree binding update to refer to msi.txt

v3:
* day 0 fix for when ACPI is not compiled in
* https://www.spinics.net/lists/arm-kernel/msg532179.html

v2:
https://patchwork.kernel.org/patch/9326399/
* Documentation update for DT bindings
* Rebased to slave-next
* Dropped dmaengine: qcom_hidma: eliminate processed variables. Replaced it
  with dmaengine: qcom_hidma: protect common data structures

v1:
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/444167.html
* initial implementation

Sinan Kaya (10):
  Documentation: DT: qcom_hidma: update binding for MSI
  Documentation: DT: qcom_hidma: correct spelling mistakes
  of: irq: make of_msi_configure accessible from modules
  dmaengine: qcom_hidma: configure DMA and MSI for OF
  dmaengine: qcom_hidma: make pending_tre_count atomic
  dmaengine: qcom_hidma: bring out interrupt cause
  dmaengine: qcom_hidma: add a common API to setup the interrupt
  dmaengine: qcom_hidma: protect common data structures
  dmaengine: qcom_hidma: break completion processing on error
  dmaengine: qcom_hidma: add MSI support for interrupts

 .../devicetree/bindings/dma/qcom_hidma_mgmt.txt    |  12 +-
 drivers/dma/qcom/hidma.c                           | 143 ++++++++++++++++++-
 drivers/dma/qcom/hidma.h                           |   6 +-
 drivers/dma/qcom/hidma_dbg.c                       |   3 +-
 drivers/dma/qcom/hidma_ll.c                        | 156 ++++++++++++---------
 drivers/dma/qcom/hidma_mgmt.c                      |   9 +-
 drivers/of/irq.c                                   |   1 +
 7 files changed, 250 insertions(+), 80 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH V5 01/10] Documentation: DT: qcom_hidma: update binding for MSI
From: Sinan Kaya @ 2016-10-07  5:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475817915-11976-1-git-send-email-okaya@codeaurora.org>

Adding a new binding for qcom,hidma-1.1 to distinguish HW supporting
MSI interrupts from the older revision.

Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
 Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
index fd5618b..2c5e4b8 100644
--- a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
@@ -47,12 +47,18 @@ When the OS is not in control of the management interface (i.e. it's a guest),
 the channel nodes appear on their own, not under a management node.
 
 Required properties:
-- compatible: must contain "qcom,hidma-1.0"
+- compatible: must contain "qcom,hidma-1.0" for initial HW or "qcom,hidma-1.1"
+for MSI capable HW.
 - reg: Addresses for the transfer and event channel
 - interrupts: Should contain the event interrupt
 - desc-count: Number of asynchronous requests this channel can handle
 - iommus: required a iommu node
 
+Optional properties for MSI:
+- msi-parent : See the generic MSI binding described in
+ devicetree/bindings/interrupt-controller/msi.txt for a description of the
+ msi-parent property.
+
 Example:
 
 Hypervisor OS configuration:
-- 
1.9.1

^ permalink raw reply related

* [PATCH V5 02/10] Documentation: DT: qcom_hidma: correct spelling mistakes
From: Sinan Kaya @ 2016-10-07  5:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475817915-11976-1-git-send-email-okaya@codeaurora.org>

Fix the spelling mistakes and extra and statements in the sentences.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
 Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
index 2c5e4b8..55492c2 100644
--- a/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
+++ b/Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
@@ -5,13 +5,13 @@ memcpy and memset capabilities. It has been designed for virtualized
 environments.
 
 Each HIDMA HW instance consists of multiple DMA channels. These channels
-share the same bandwidth. The bandwidth utilization can be parititioned
+share the same bandwidth. The bandwidth utilization can be partitioned
 among channels based on the priority and weight assignments.
 
 There are only two priority levels and 15 weigh assignments possible.
 
 Other parameters here determine how much of the system bus this HIDMA
-instance can use like maximum read/write request and and number of bytes to
+instance can use like maximum read/write request and number of bytes to
 read/write in a single burst.
 
 Main node required properties:
-- 
1.9.1

^ permalink raw reply related

* [PATCH V5 03/10] of: irq: make of_msi_configure accessible from modules
From: Sinan Kaya @ 2016-10-07  5:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475817915-11976-1-git-send-email-okaya@codeaurora.org>

The of_msi_configure routine is only accessible by the built-in
kernel drivers. Export this function so that modules can use it
too.

This function is useful for configuring MSI on child device tree
nodes on hierarchical objects.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
---
 drivers/of/irq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index a2e68f7..20c09e0 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -767,3 +767,4 @@ void of_msi_configure(struct device *dev, struct device_node *np)
 	dev_set_msi_domain(dev,
 			   of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));
 }
+EXPORT_SYMBOL_GPL(of_msi_configure);
-- 
1.9.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox