* [PATCH 11/12] scsi/ncr5380: Use correct types for DMA routines
From: Finn Thain @ 2016-10-04 4:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1475555997.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>
---
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 3f71556..d479e11 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 2024566..9481cc9 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 07/12] scsi/ncr5380: Store IO ports and addresses in host private data
From: Finn Thain @ 2016-10-04 4:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1475555997.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>
---
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 330668b..68092f7 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 8212efb6..5441970 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -220,6 +220,9 @@
struct NCR5380_hostdata {
NCR5380_implementation_fields; /* Board-specific data */
+ u8 __iomem *io; /* Remapped 5380 address */
+ u8 __iomem *pdma_io; /* Remapped PDMA address */
+ unsigned long io_port; /* Device IO port */
unsigned long poll_loops; /* Register polling limit */
spinlock_t lock; /* Protects this struct */
struct scsi_cmnd *connected; /* Currently connected cmnd */
@@ -239,6 +242,8 @@ 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 base; /* Device base address */
+ 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 10/12] scsi/ncr5380: Expedite register polling
From: Finn Thain @ 2016-10-04 4:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1475555997.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>
---
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 2950bc0..2024566 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 08/12] scsi/ncr5380: Use correct types for device register accessors
From: Finn Thain @ 2016-10-04 4:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1475555997.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>
---
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 68092f7..8e11ab7 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 5441970..79f8add 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 02/12] scsi/cumana_1: Remove unused cumanascsi_setup() function
From: Finn Thain @ 2016-10-04 4:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1475555997.git.fthain@telegraphics.com.au>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
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 v1 1/2] ARM: dts: vfxxx: Enable DMA for DSPI on Vybrid
From: maitysanchayan at gmail.com @ 2016-10-04 4:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <48b237c5d8709a67112465ea147f4c0c@agner.ch>
Hello Stefan,
On 16-10-03 11:05:59, Stefan Agner wrote:
> On 2016-10-03 05:50, Sanchayan Maity wrote:
> > Enable DMA for DSPI on Vybrid.
>
> Hm, we have that in 4.4 already, is that meant for 4.1?
Sorry?! I send this out for mainline and the patch series is based
on top of shawn's for-next branch. Did not intend it for our downstream
4.1.
Thanks.
Regards,
Stefan.
>
> >
> > Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
> > ---
> > arch/arm/boot/dts/vf-colibri.dtsi | 4 ++++
> > arch/arm/boot/dts/vfxxx.dtsi | 6 ++++++
> > 2 files changed, 10 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/vf-colibri.dtsi
> > b/arch/arm/boot/dts/vf-colibri.dtsi
> > index b741709..21bfef9 100644
> > --- a/arch/arm/boot/dts/vf-colibri.dtsi
> > +++ b/arch/arm/boot/dts/vf-colibri.dtsi
> > @@ -108,6 +108,10 @@
> > status = "okay";
> > };
> >
> > +&edma1 {
> > + status = "okay";
> > +};
> > +
> > &esdhc1 {
> > pinctrl-names = "default";
> > pinctrl-0 = <&pinctrl_esdhc1>;
> > diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> > index 2c13ec6..eac4213 100644
> > --- a/arch/arm/boot/dts/vfxxx.dtsi
> > +++ b/arch/arm/boot/dts/vfxxx.dtsi
> > @@ -194,6 +194,9 @@
> > clocks = <&clks VF610_CLK_DSPI0>;
> > clock-names = "dspi";
> > spi-num-chipselects = <6>;
> > + dmas = <&edma1 1 12>,
> > + <&edma1 1 13>;
> > + dma-names = "rx", "tx";
> > status = "disabled";
> > };
> >
> > @@ -206,6 +209,9 @@
> > clocks = <&clks VF610_CLK_DSPI1>;
> > clock-names = "dspi";
> > spi-num-chipselects = <4>;
> > + dmas = <&edma1 1 14>,
> > + <&edma1 1 15>;
> > + dma-names = "rx", "tx";
> > status = "disabled";
> > };
^ permalink raw reply
* [PATCH 05/12] ASoC: sun4i-codec: Add support for A31 playback through headphone output
From: Chen-Yu Tsai @ 2016-10-04 4:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161003114709.GC5228@lukather>
On Mon, Oct 3, 2016 at 7:47 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Mon, Oct 03, 2016 at 07:07:57PM +0800, Chen-Yu Tsai wrote:
>> The A31 has a similar codec to the A10/A20. The PCM parts are very
>> similar, with just different register offsets. The analog paths are
>> very different. There are more inputs and outputs.
>>
>> The quirks structure is expanded to include different register offsets
>> and separate callbacks for creating the ASoC card. Also the DMA burst
>> length is increased to 8. While the A10 DMA engine supports bursts of
>> 1, 4 and 8, the A31 engine only supports 1 and 8.
>>
>> This patch adds support for the basic playback path of the A31 codec,
>> from the DAC to the headphones. Headphone detection, microphone,
>> signaling, other inputs/outputs and capture will be added later.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>> .../devicetree/bindings/sound/sun4i-codec.txt | 6 +-
>> sound/soc/sunxi/sun4i-codec.c | 396 +++++++++++++++++----
>> 2 files changed, 334 insertions(+), 68 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
>> index 0dce690f78f5..1d2411cea98d 100644
>> --- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
>> +++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
>> @@ -1,8 +1,10 @@
>> * Allwinner A10 Codec
>>
>> Required properties:
>> -- compatible: must be either "allwinner,sun4i-a10-codec" or
>> - "allwinner,sun7i-a20-codec"
>> +- compatible: must be one of the following compatibles:
>> + - "allwinner,sun4i-a10-codec"
>> + - "allwinner,sun6i-a31-codec"
>> + - "allwinner,sun7i-a20-codec"
>
> I'm guessing it needs a reset line?
There isn't one. I know, weird.
>> - reg: must contain the registers location and length
>> - interrupts: must contain the codec interrupt
>> - dmas: DMA channels for tx and rx dma. See the DMA client binding,
>> diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
>> index e047ec06d538..9916714ecb71 100644
>> --- a/sound/soc/sunxi/sun4i-codec.c
>> +++ b/sound/soc/sunxi/sun4i-codec.c
>> @@ -3,6 +3,7 @@
>> * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
>> * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
>> * Copyright 2015 Adam Sampson <ats@offog.org>
>> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
>> *
>> * Based on the Allwinner SDK driver, released under the GPL.
>> *
>> @@ -24,8 +25,9 @@
>> #include <linux/delay.h>
>> #include <linux/slab.h>
>> #include <linux/of.h>
>> -#include <linux/of_platform.h>
>> #include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_platform.h>
>> #include <linux/clk.h>
>> #include <linux/regmap.h>
>> #include <linux/gpio/consumer.h>
>> @@ -55,6 +57,8 @@
>> #define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0)
>> #define SUN4I_CODEC_DAC_FIFOS (0x08)
>> #define SUN4I_CODEC_DAC_TXDATA (0x0c)
>> +
>> +/* Codec DAC side analog signal controls */
>> #define SUN4I_CODEC_DAC_ACTL (0x10)
>> #define SUN4I_CODEC_DAC_ACTL_DACAENR (31)
>> #define SUN4I_CODEC_DAC_ACTL_DACAENL (30)
>> @@ -81,6 +85,8 @@
>> #define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0)
>> #define SUN4I_CODEC_ADC_FIFOS (0x20)
>> #define SUN4I_CODEC_ADC_RXDATA (0x24)
>> +
>> +/* Codec ADC side analog signal controls */
>> #define SUN4I_CODEC_ADC_ACTL (0x28)
>> #define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31)
>> #define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30)
>> @@ -93,18 +99,106 @@
>> #define SUN4I_CODEC_ADC_ACTL_DDE (3)
>> #define SUN4I_CODEC_ADC_DEBUG (0x2c)
>>
>> -/* Other various ADC registers */
>> +/* FIFO counters */
>> #define SUN4I_CODEC_DAC_TXCNT (0x30)
>> #define SUN4I_CODEC_ADC_RXCNT (0x34)
>> +
>> +/* Other various ADC registers */
>> #define SUN7I_CODEC_AC_DAC_CAL (0x38)
>> #define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c)
>>
>> +/*** sun6i specific register offsets ***/
>> +#define SUN6I_CODEC_ADC_FIFOC (0x10)
>> +#define SUN6I_CODEC_ADC_FIFOC_EN_AD (28)
>> +#define SUN6I_CODEC_ADC_FIFOS (0x14)
>> +#define SUN6I_CODEC_ADC_RXDATA (0x18)
>> +#define SUN6I_CODEC_OM_DACA_CTRL (0x20)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_DACAREN (31)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_DACALEN (30)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIXEN (29)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIXEN (28)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1 (23)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2 (22)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONE (21)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONEP (20)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR (19)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR (18)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL (17)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1 (16)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2 (15)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONE (14)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONEN (13)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL (12)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL (11)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR (10)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RHPIS (9)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LHPIS (8)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE (7)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE (6)
>> +#define SUN6I_CODEC_OM_DACA_CTRL_HPVOL (0)
>> +#define SUN6I_CODEC_OM_PA_CTRL (0x24)
>> +#define SUN6I_CODEC_OM_PA_CTRL_HPPAEN (31)
>> +#define SUN6I_CODEC_OM_PA_CTRL_MIC1G (15)
>> +#define SUN6I_CODEC_OM_PA_CTRL_MIC2G (12)
>> +#define SUN6I_CODEC_OM_PA_CTRL_LINEING (9)
>> +#define SUN6I_CODEC_OM_PA_CTRL_PHONEG (6)
>> +#define SUN6I_CODEC_OM_PA_CTRL_PHONEPG (3)
>> +#define SUN6I_CODEC_OM_PA_CTRL_PHONENG (0)
>> +#define SUN6I_CODEC_MIC_CTRL (0x28)
>> +#define SUN6I_CODEC_MIC_CTRL_HBIASEN (31)
>> +#define SUN6I_CODEC_MIC_CTRL_MBIASEN (30)
>> +#define SUN6I_CODEC_MIC_CTRL_MIC1AMPEN (28)
>> +#define SUN6I_CODEC_MIC_CTRL_MIC1BOOST (25)
>> +#define SUN6I_CODEC_MIC_CTRL_MIC2AMPEN (24)
>> +#define SUN6I_CODEC_MIC_CTRL_MIC2BOOST (21)
>> +#define SUN6I_CODEC_MIC_CTRL_MIC2SLT (20)
>> +#define SUN6I_CODEC_MIC_CTRL_LINEOUTLEN (19)
>> +#define SUN6I_CODEC_MIC_CTRL_LINEOUTREN (18)
>> +#define SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC (17)
>> +#define SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC (16)
>> +#define SUN6I_CODEC_MIC_CTRL_LINEOUTVC (11)
>> +#define SUN6I_CODEC_MIC_CTRL_PHONEPREG (8)
>> +#define SUN6I_CODEC_ADC_ACTL (0x2c)
>> +#define SUN6I_CODEC_ADC_ACTL_ADCREN (31)
>> +#define SUN6I_CODEC_ADC_ACTL_ADCLEN (30)
>> +#define SUN6I_CODEC_ADC_ACTL_ADCRG (27)
>> +#define SUN6I_CODEC_ADC_ACTL_ADCLG (24)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1 (13)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2 (12)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONE (11)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONEP (10)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR (9)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR (8)
>> +#define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL (7)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1 (6)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2 (5)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONE (4)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONEN (3)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL (2)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL (1)
>> +#define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR (0)
>> +#define SUN6I_CODEC_ADDA_TUNE (0x30)
>> +#define SUN6I_CODEC_CALIBRATION (0x34)
>> +#define SUN6I_CODEC_DAC_TXCNT (0x40)
>> +#define SUN6I_CODEC_ADC_RXCNT (0x44)
>> +#define SUN6I_CODEC_HMIC_CTL (0x50)
>> +#define SUN6I_CODEC_HMIC_DATA (0x54)
>> +
>> +/* TODO sun6i DAP (Digital Audio Processing) bits */
>> +
>> +struct sun4i_codec_regs {
>> + u32 adc_fifoc;
>> + u32 adc_fifos;
>> + u32 adc_rxdata;
>> +};
>> +
>> struct sun4i_codec {
>> struct device *dev;
>> struct regmap *regmap;
>> struct clk *clk_apb;
>> struct clk *clk_module;
>> struct gpio_desc *gpio_pa;
>> + const struct sun4i_codec_regs *regs;
>
> You're reimplementing reg_field here.
Are you suggesting we do reg_fields for each register?
Or all the bit fields separately. The latter would add
quite a few pointers.
>>
>> struct snd_dmaengine_dai_dma_data capture_dma_data;
>> struct snd_dmaengine_dai_dma_data playback_dma_data;
>> @@ -134,7 +228,7 @@ static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
>> static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
>> {
>> /* Enable ADC DRQ */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
>> BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
>> }
>> @@ -142,7 +236,7 @@ static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
>> static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
>> {
>> /* Disable ADC DRQ */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
>> }
>>
>> @@ -186,13 +280,13 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
>>
>>
>> /* Flush RX FIFO */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
>> BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
>>
>>
>> /* Set RX FIFO trigger level */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
>> 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
>>
>> @@ -201,9 +295,12 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
>> * Allwinner's code mentions that it is related
>> * related to microphone gain
>> */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
>> - 0x3 << 25,
>> - 0x1 << 25);
>> + if (!of_device_is_compatible(scodec->dev->of_node,
>> + "allwinner,sun6i-a31-codec")) {
>> + regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
>> + 0x3 << 25,
>> + 0x1 << 25);
>> + }
>>
>> if (of_device_is_compatible(scodec->dev->of_node,
>> "allwinner,sun7i-a20-codec"))
>> @@ -213,7 +310,7 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
>> 0x1 << 8);
>>
>> /* Fill most significant bits with valid data MSB */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
>> BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
>>
>> @@ -342,17 +439,17 @@ static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
>> unsigned int hwrate)
>> {
>> /* Set ADC sample rate */
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
>> hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
>>
>> /* Set the number of channels we want to use */
>> if (params_channels(params) == 1)
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
>> BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
>> else
>> - regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
>> + regmap_update_bits(scodec->regmap, scodec->regs->adc_fifoc,
>> BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
>>
>> return 0;
>> @@ -385,7 +482,7 @@ static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
>> BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
>> BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
>>
>> - /* Set TX FIFO mode to padding the LSBs with 0 */
>> + /* Use higher 24 bits of TX FIFO */
>> regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
>> BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
>> 0);
>> @@ -396,7 +493,7 @@ static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
>> BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
>> 0);
>>
>> - /* Set TX FIFO mode to repeat the MSB */
>> + /* Use lower 16 bits of TX FIFO */
>> regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
>> BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
>> BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
>> @@ -502,7 +599,7 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
>> },
>> };
>>
>> -/*** Codec ***/
>> +/*** sun4i Codec ***/
>> static const struct snd_kcontrol_new sun4i_codec_pa_mute =
>> SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
>> SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
>> @@ -638,6 +735,114 @@ static struct snd_soc_codec_driver sun4i_codec_codec = {
>> },
>> };
>>
>> +/*** sun6i Codec ***/
>> +
>> +/* mixer controls */
>> +static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = {
>> + SOC_DAPM_DOUBLE("DAC Playback Switch",
>> + SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL,
>> + SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR, 1, 0),
>> + SOC_DAPM_DOUBLE("DAC Reversed Playback Switch",
>> + SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR,
>> + SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0),
>> +};
>> +
>> +/* headphone controls */
>> +static const char * const sun6i_codec_hp_src_enum_text[] = {
>> + "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
>> + SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
>> + SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
>> + sun6i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
>> + SOC_DAPM_ENUM("Headphone Source Playback Route", sun6i_codec_hp_src_enum),
>> +};
>> +
>> +/* volume / mute controls */
>> +static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
>> +static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
>> +
>> +static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
>> + SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
>> + SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
>> + sun6i_codec_dvol_scale),
>> + SOC_SINGLE_TLV("Headphone Playback Volume",
>> + SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0,
>> + sun6i_codec_hp_vol_scale),
>> + SOC_DOUBLE("Headphone Playback Switch",
>> + SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE,
>> + SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
>> +};
>> +
>> +static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = {
>> + /* Digital parts of the DACs */
>> + SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
>> + SUN4I_CODEC_DAC_DPC_EN_DA, 0,
>> + NULL, 0),
>> +
>> + /* Analog parts of the DACs */
>> + SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_DACALEN, 0),
>> + SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_DACAREN, 0),
>> +
>> + /* Mixers */
>> + SOC_MIXER_ARRAY("Left Mixer", SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_LMIXEN, 0,
>> + sun6i_codec_mixer_controls),
>> + SOC_MIXER_ARRAY("Right Mixer", SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_RMIXEN, 0,
>> + sun6i_codec_mixer_controls),
>> +
>> + /* Headphone output path */
>> + SND_SOC_DAPM_MUX("Headphone Source Playback Route",
>> + SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),
>> + SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN6I_CODEC_OM_PA_CTRL,
>> + SUN6I_CODEC_OM_PA_CTRL_HPPAEN, 0, NULL, 0),
>> + SND_SOC_DAPM_OUTPUT("HP"),
>> +};
>> +
>> +static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
>> + /* DAC Routes */
>> + { "Left DAC", NULL, "DAC Enable" },
>> + { "Right DAC", NULL, "DAC Enable" },
>> +
>> + /* Left Mixer Routes */
>> + { "Left Mixer", "DAC Playback Switch", "Left DAC" },
>> + { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
>> +
>> + /* Right Mixer Routes */
>> + { "Right Mixer", "DAC Playback Switch", "Right DAC" },
>> + { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
>> +
>> + /* Headphone Routes */
>> + { "Headphone Source Playback Route", "DAC", "Left DAC" },
>> + { "Headphone Source Playback Route", "DAC", "Right DAC" },
>> + { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
>> + { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
>> + { "Headphone Amp", NULL, "Headphone Source Playback Route" },
>> + { "HP", NULL, "Headphone Amp" },
>> +};
>> +
>> +static struct snd_soc_codec_driver sun6i_codec_codec = {
>> + .component_driver = {
>> + .controls = sun6i_codec_codec_widgets,
>> + .num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets),
>> + .dapm_widgets = sun6i_codec_codec_dapm_widgets,
>> + .num_dapm_widgets = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
>> + .dapm_routes = sun6i_codec_codec_dapm_routes,
>> + .num_dapm_routes = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
>> + },
>> +};
>> +
>> static const struct snd_soc_component_driver sun4i_codec_component = {
>> .name = "sun4i-codec",
>> };
>> @@ -678,45 +883,6 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
>> },
>> };
>>
>> -static const struct regmap_config sun4i_codec_regmap_config = {
>> - .reg_bits = 32,
>> - .reg_stride = 4,
>> - .val_bits = 32,
>> - .max_register = SUN4I_CODEC_ADC_RXCNT,
>> -};
>> -
>> -static const struct regmap_config sun7i_codec_regmap_config = {
>> - .reg_bits = 32,
>> - .reg_stride = 4,
>> - .val_bits = 32,
>> - .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL,
>> -};
>> -
>> -struct sun4i_codec_quirks {
>> - const struct regmap_config *regmap_config;
>> -};
>> -
>> -static const struct sun4i_codec_quirks sun4i_codec_quirks = {
>> - .regmap_config = &sun4i_codec_regmap_config,
>> -};
>> -
>> -static const struct sun4i_codec_quirks sun7i_codec_quirks = {
>> - .regmap_config = &sun7i_codec_regmap_config,
>> -};
>> -
>> -static const struct of_device_id sun4i_codec_of_match[] = {
>> - {
>> - .compatible = "allwinner,sun4i-a10-codec",
>> - .data = &sun4i_codec_quirks,
>> - },
>> - {
>> - .compatible = "allwinner,sun7i-a20-codec",
>> - .data = &sun7i_codec_quirks,
>> - },
>> - {}
>> -};
>> -MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
>> -
>> static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
>> int *num_links)
>> {
>> @@ -781,6 +947,102 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
>> return card;
>> };
>>
>> +static struct snd_soc_card *sun6i_codec_create_card(struct device *dev)
>> +{
>> + struct snd_soc_card *card;
>> +
>> + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
>> + if (!card)
>> + return NULL;
>> +
>> + card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
>> + if (!card->dai_link)
>> + return NULL;
>> +
>> + card->dev = dev;
>> + card->name = "sun4i-codec";
>> +
>> + return card;
>> +};
>> +
>> +static const struct regmap_config sun4i_codec_regmap_config = {
>> + .reg_bits = 32,
>> + .reg_stride = 4,
>> + .val_bits = 32,
>> + .max_register = SUN4I_CODEC_ADC_RXCNT,
>> +};
>> +
>> +static const struct regmap_config sun6i_codec_regmap_config = {
>> + .reg_bits = 32,
>> + .reg_stride = 4,
>> + .val_bits = 32,
>> + .max_register = SUN6I_CODEC_HMIC_DATA,
>> +};
>> +
>> +static const struct regmap_config sun7i_codec_regmap_config = {
>> + .reg_bits = 32,
>> + .reg_stride = 4,
>> + .val_bits = 32,
>> + .max_register = SUN7I_CODEC_AC_MIC_PHONE_CAL,
>> +};
>> +
>> +static const struct sun4i_codec_regs sun4i_codec_regs = {
>> + .adc_fifoc = SUN4I_CODEC_ADC_FIFOC,
>> + .adc_fifos = SUN4I_CODEC_ADC_FIFOS,
>> + .adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
>> +};
>> +
>> +static const struct sun4i_codec_regs sun6i_codec_regs = {
>> + .adc_fifoc = SUN6I_CODEC_ADC_FIFOC,
>> + .adc_fifos = SUN6I_CODEC_ADC_FIFOS,
>> + .adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
>> +};
>> +
>> +struct sun4i_codec_quirks {
>> + const struct regmap_config *regmap_config;
>> + const struct snd_soc_codec_driver *codec;
>> + const struct sun4i_codec_regs *regs;
>> + struct snd_soc_card * (*create_card)(struct device *dev);
>> +};
>> +
>> +static const struct sun4i_codec_quirks sun4i_codec_quirks = {
>> + .regmap_config = &sun4i_codec_regmap_config,
>> + .regs = &sun4i_codec_regs,
>> + .codec = &sun4i_codec_codec,
>> + .create_card = sun4i_codec_create_card,
>> +};
>> +
>> +static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = {
>> + .regmap_config = &sun6i_codec_regmap_config,
>> + .regs = &sun6i_codec_regs,
>> + .codec = &sun6i_codec_codec,
>> + .create_card = sun6i_codec_create_card,
>> +};
>> +
>> +static const struct sun4i_codec_quirks sun7i_codec_quirks = {
>> + .regmap_config = &sun7i_codec_regmap_config,
>> + .regs = &sun4i_codec_regs,
>> + .codec = &sun4i_codec_codec,
>> + .create_card = sun4i_codec_create_card,
>> +};
>> +
>> +static const struct of_device_id sun4i_codec_of_match[] = {
>> + {
>> + .compatible = "allwinner,sun4i-a10-codec",
>> + .data = &sun4i_codec_quirks,
>> + },
>> + {
>> + .compatible = "allwinner,sun6i-a31-codec",
>> + .data = &sun6i_a31_codec_quirks,
>> + },
>> + {
>> + .compatible = "allwinner,sun7i-a20-codec",
>> + .data = &sun7i_codec_quirks,
>> + },
>> + {}
>> +};
>> +MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
>> +
>
> I don't really like moving blocks of code over and over again,
> especially in the middle of an unrelated patch.
It's not completely unrelated. I want different create_card
functions for the different SoCs, and that has to be part of the
quirks, so the quirks and the of_match list have to be moved
below them. I suppose I could leave the regmap parts in place,
but keeping them together is nicer.
If I split out the addition of the .create_card field and
code movement into a separate patch, would that be OK?
Thanks
ChenYu
>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
^ permalink raw reply
* [PATCH v26 0/7] arm64: add kdump support
From: AKASHI Takahiro @ 2016-10-04 2:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1ae717d6-b2aa-105b-4f47-d879882ca5d3@caviumnetworks.com>
On Mon, Oct 03, 2016 at 06:11:40PM +0530, Manish Jaggi wrote:
>
>
> On 10/03/2016 04:34 PM, AKASHI Takahiro wrote:
> > Manish,
> >
> > On Mon, Oct 03, 2016 at 01:24:34PM +0530, Manish Jaggi wrote:
> >> Hi Akashi,
> >>
> >> On 09/07/2016 09:59 AM, AKASHI Takahiro wrote:
> >>> v26-specific note: After a comment from Rob[0], an idea of adding
> >>> "linux,usable-memory-range" was dropped. Instead, an existing
> >>> "reserved-memory" node will be used to limit usable memory ranges
> >>> on crash dump kernel.
> >>> This works not only on UEFI/ACPI systems but also on DT-only systems,
> >>> but if he really insists on using DT-specific "usable-memory" property,
> >>> I will post additional patches for kexec-tools. Those would be
> >>> redundant, though.
> >>> Even in that case, the kernel will not have to be changed.
> >>>
> >>> This patch series adds kdump support on arm64.
> >>> There are some prerequisite patches [1],[2].
> >>>
> >>> To load a crash-dump kernel to the systems, a series of patches to
> >>> kexec-tools, which have not yet been merged upstream, are needed.
> >>> Please always use my latest kdump patches, v3 [3].
> >>>
> >>> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
> >>> - crash utility (coming v7.1.6 or later) [4]
> >>> (Necessary patches have already been queued in the master.)
> >>>
> >>>
> >>> [0] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/452582.html
> >>> [1] "arm64: mark reserved memblock regions explicitly in iomem"
> >>> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/450433.html
> >>> [2] "efi: arm64: treat regions with WT/WC set but WB cleared as memory"
> >>> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-August/451491.html
> >>> [3] T.B.D.
> >>> [4] https://github.com/crash-utility/crash.git
> >>>
> >>
> >> With the v26 kdump and v3 kexec-tools and top of tree crash.git, below are the tests done
> >> Attached is a patch in crash.git (symbols.c) to make crash utility work on my setup.
> >> Can you please have a look and provide your comments.
> >>
> >> To generate a panic, i have a kernel module which on init calls panic.
> >>
> >> Observations:
> >> 1.1. Dump capture kernel shows different memory map.
> >> ---------------------------------------------------
> >> In dump capture kernel /proc/meminfo and /proc/iomem differ
> >>
> >> root at arm64:/home/ubuntu/CODE/crash#
> >> MemTotal: 65882432 kB
> >> MemFree: 65507136 kB
> >> MemAvailable: 60373632 kB
> >> Buffers: 29248 kB
> >> Cached: 46720 kB
> >> SwapCached: 0 kB
> >> Active: 63872 kB
> >> Inactive: 19776 kB
> >> Active(anon): 8256 kB
> >> Inactive(anon): 7616 kB
> >>
> >> First kernel is booted with mem=2G crashkernel=1G command line option.
> >> While the system has 64G memory.
> >>
> >> root at arm64:/home/ubuntu/CODE/crash# cat /proc/iomem
> >> 41400000-fffeffff : System RAM
> >> 41480000-420cffff : Kernel code
> >> 42490000-4278ffff : Kernel data
> >> ffff0000-ffffffff : reserved
> >> 100000000-ffaa7ffff : System RAM
> >> ffaa80000-ffaabffff : reserved
> >> ffaac0000-fffa6ffff : System RAM
> >> fffa70000-fffacffff : reserved
> >> fffad0000-fffffffff : System RAM
> >
> > Are you saying that "mem=..." doesn't have any effect?
> What I am saying it that If the first kernel is booted using mem= option and crashkernel= option
> the memory for second kernel has to be withing the crashkernel size.
> As per /proc/iomem System RAM the information is correct, but the /proc/meminfo is showing total memory
> much more than the first kernel had in first place.
> > What about if you don't specify "crashkernel=...?"
> >
> In that case the second kernel will not boot as kexec tools will complain that memory not reserved.
> >> 1.2 Live crash dump fails with error
> >> --------------------------------------
> >> $crash vmlinux
> >>
> >> crash 7.1.5++
> >> Copyright (C) 2002-2016 Red Hat, Inc.
> >> Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
> >> Copyright (C) 1999-2006 Hewlett-Packard Co
> >> Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
> >> Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
> >> Copyright (C) 2005, 2011 NEC Corporation
> >> Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
> >> Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
> >> This program is free software, covered by the GNU General Public License,
> >> and you are welcome to change it and/or distribute copies of it under
> >> certain conditions. Enter "help copying" to see the conditions.
> >> This program has absolutely no warranty. Enter "help warranty" for details.
> >>
> >> GNU gdb (GDB) 7.6
> >> Copyright (C) 2013 Free Software Foundation, Inc.
> >> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> >> This is free software: you are free to change and redistribute it.
> >> There is NO WARRANTY, to the extent permitted by law. Type "show copying"
> >> and "show warranty" for details.
> >> This GDB was configured as "aarch64-unknown-linux-gnu"...
> >>
> >> crash: read error: kernel virtual address: ffff800ffffffcc0 type: "pglist node_id"
> >
> > I have no ideas here.
> If I run with debug logs phys address accessed is > 64G. (10413ffcc0)
> Could be that somehow 64 + 1G + (addr) = 10413ffcc0 and actually addr was required.
> addr = 413ffcc0 which seems in line with 424b0c50
>
>
> Logs:
> <read_dev_mem: addr: ffff0000090b3008 paddr: 424b3008 cnt: 8>
> node_online_map: [1] -> nodes online: 1
> <readmem: ffff0000090b0c50, KVADDR, ""node_data"", 8, (ROE), ffffc330eb00>
> <read_dev_mem: addr: ffff0000090b0c50 paddr: 424b0c50 cnt: 8>
> <readmem: ffff800ffffffcc0, KVADDR, ""pglist node_id"", 4, (FOE), ffffc330f1e4>
> <read_dev_mem: addr: ffff800ffffffcc0 paddr: 10413ffcc0 cnt: 4>
> /dev/mem: Bad address
> crash: read(/dev/mem, 10413ffcc0, 4): 4294967295 (ffffffff)
> crash: read error: kernel virtual address: ffff800ffffffcc0 type: ""pglist node_id""
> "
> >
> >> Observation 2
> >> ------------
> >> If saved vmcore file is used
> >>
> >> $crash vmlinux vmcore_saved
> >> Got the below error.
> >>
> >> please wait... (gathering module symbol data)crash: malloc.c:2846: mremap_chunk: Assertion `((size + offset) & (_rtld_global_ro._dl_pagesize - 1)) == 0' failed.
> >> Aborted
> >
> > I have no ideas here.
> >
> >> Experiment 3
> >> ------------
> >> If crash.git is modified with a hack patch in symbols.c. Crash utility works fine log, bt commands work.
> >
> > In which case, "crash vmlinux" or "crash vmlinux vmcore_saved?"
> >
> vmcore_saved
> > I was able to reproduce this issue in the latter case
> > (but with a different error message).
> > It seems to be a crash util's bug.
> > Please report it to crash-util mailing list.
> > I will post a patch.
> The same patch as below ?
No.
> Can you please share your patch
I submitted a bug fix patch. See:
https://www.redhat.com/archives/crash-utility/2016-October/msg00000.html
-Takahiro AKASHI
> > Thanks,
> > -Takahiro AKASHI
> >
> >> -------------------
> >> Patch: symbols.c
> >> git diff symbols.c
> >> diff --git a/symbols.c b/symbols.c
> >> index 13282f4..f7c6cac 100644
> >> --- a/symbols.c
> >> +++ b/symbols.c
> >> @@ -2160,6 +2160,7 @@ store_module_kallsyms_v2(struct load_module *lm, int start
> >> FREEBUF(module_buf);
> >> return 0;
> >> }
> >> + lm->mod_init_size = 0;
> >>
> >> if (lm->mod_init_size > 0) {
> >> module_buf_init = GETBUF(lm->mod_init_size);
> >> ------------------
> >>
> >> $ crash vmlinux vmcore_saved
> >> KERNEL: /home/ubuntu/CODE/linux/vmlinux
> >> DUMPFILE: vm
> >> CPUS: 48 [OFFLINE: 46]
> >> DATE: Mon Oct 3 00:11:47 2016
> >> UPTIME: 00:02:41
> >> LOAD AVERAGE: 0.36, 0.14, 0.05
> >> TASKS: 171
> >> NODENAME: arm64
> >> RELEASE: 4.8.0-rc3-00044-g070a615-dirty
> >> VERSION: #63 SMP Sat Oct 1 01:39:45 PDT 2016
> >> MACHINE: aarch64 (unknown Mhz)
> >> MEMORY: 2 GB
> >> PANIC: "Kernel panic - not syncing: crash module starting"
> >> PID: 958
> >> COMMAND: "insmod"
> >> TASK: ffff800007859300 [THREAD_INFO: ffff80000c940000]
> >> CPU: 0
> >> STATE: TASK_RUNNING (PANIC)
> >>
> >> crash> bt
> >> PID: 958 TASK: ffff800007859300 CPU: 0 COMMAND: "insmod"
> >> #0 [ffff80000c943980] __crash_kexec at ffff000008144fe8
> >> #1 [ffff80000c943ae0] panic at ffff0000081ae704
> >> #2 [ffff80000c943ba0] init_module at ffff000000900014 [crash]
> >> #3 [ffff80000c943bb0] do_one_initcall at ffff000008083bb4
> >> #4 [ffff80000c943c40] do_init_module at ffff0000081af6f0
> >> #5 [ffff80000c943c70] load_module at ffff000008140b7c
> >> #6 [ffff80000c943e10] sys_finit_module at ffff000008141634
> >> #7 [ffff80000c943ed0] el0_svc_naked at ffff0000080833ec
> >> PC: 00000003 LR: ffffaca050a0 SP: ffffaca865a0 PSTATE: 00000111
> >> X12: ffffac941a5c X11: 00000080 X10: 00000004 X9: 00000030
> >> X8: ffffffff X7: fefefefefefeff40 X6: 00000111 X5: 00000001
> >> X4: 00000001 X3: 0002ed61 X2: 00000000 X1: 00000003
> >> X0: 00000000
> >> crash>
> >>
> >>
> >> ---
> >> Thanks,
> >> manish
> >>
^ permalink raw reply
* [PATCH 9/9] ARM: sunxi: Convert pinctrl nodes to generic bindings
From: Chen-Yu Tsai @ 2016-10-04 2:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1f67fc945364c4347108d5c82e50de3d2abe4e8d.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Now that we can handle the generic pinctrl bindings, convert our DT to it.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Same comment as the last 2 patches.
ChenYu
^ permalink raw reply
* [PATCH 8/9] ARM: sunxi: Remove useless allwinner,pull property
From: Chen-Yu Tsai @ 2016-10-04 2:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7b4c2580fc98e0877c14736b7edf3738128591ae.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The allwinner,pull property set to NO_PULL was really considered our
> default (and wasn't even changing the default value in the code).
>
> Remove these properties to make it obvious that we do not set anything in
> such a case.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Same comment as the last patch.
ChenYu
^ permalink raw reply
* [PATCH 7/9] ARM: sunxi: Remove useless allwinner,drive property
From: Chen-Yu Tsai @ 2016-10-04 2:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <01cd77ccced851276fcb3625b3d7805f5260fb59.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The allwinner,drive property set to 10mA was really considered as our
> default. Remove all those properties entirely to make that obvious.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Did you use sed or some other scripting tool to do this patch?
Including the command should make it easier to verify the result,
instead of having to go through the 93 files here.
ChenYu
^ permalink raw reply
* [PATCH 6/9] dt-bindings: pinctrl: Deprecate sunxi pinctrl bindings
From: Chen-Yu Tsai @ 2016-10-04 2:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <fad5a977d8ecdd43b37d7028b1bc32d8667b65a2.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> The generic pin configuration and multiplexing should be preferred now,
> even though we still support the old one.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt | 5 +++++
> 1 file changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
> index 69617220c5d6..e8b7cf64fdf1 100644
> --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
> @@ -36,6 +36,11 @@ pins it needs, and how they should be configured, with regard to muxer
> configuration, drive strength and pullups. If one of these options is
> not set, its actual value will be unspecified.
>
> +This driver supports the generic pin multiplexing and configuration
> +bindings.
Should we list which options are supported? We don't support them all.
ChenYu
> +
> +*** Deprecated pin configuration and multiplexing binding
> +
> Required subnode-properties:
>
> - allwinner,pins: List of strings containing the pin name.
> --
> git-series 0.8.10
^ permalink raw reply
* [PATCH 5/9] pinctrl: sunxi: Support generic binding
From: Chen-Yu Tsai @ 2016-10-04 2:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1b45160fb37e2dcabd855d2192fc403a1c4db324.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Our bindings are mostly irrelevant now that we have generic pinctrl
> bindings that cover exactly the same uses cases.
>
> Add support for the new ones, and obviously keep our old binding support in
> order to keep the ABI stable.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* [PATCH 4/9] pinctrl: sunxi: Deal with configless pins
From: Chen-Yu Tsai @ 2016-10-04 2:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8b72a134d957afdee6de48ec2c1891d8bba1b9e3.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Even though the our binding had the assumption that the allwinner,pull and
> allwinner,drive properties were optional, the code never took that into
> account.
>
> Fix that.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> drivers/pinctrl/sunxi/pinctrl-sunxi.c | 50 +++++++++++++++++++---------
> 1 file changed, 35 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index 6f6f1e0011e2..cec977fcf98c 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -218,20 +218,29 @@ static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node,
> {
> unsigned long *pinconfig;
> unsigned int configlen = 0, idx = 0;
> + int ret;
>
> if (sunxi_pctrl_has_drive_prop(node))
> configlen++;
> if (sunxi_pctrl_has_bias_prop(node))
> configlen++;
>
> + /*
> + * If we don't have any configuration, bail out
> + */
> + if (!configlen)
> + return NULL;
> +
> pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
> if (!pinconfig)
> - return NULL;
> + return ERR_PTR(-ENOMEM);
>
> if (sunxi_pctrl_has_drive_prop(node)) {
> int drive = sunxi_pctrl_parse_drive_prop(node);
> - if (drive < 0)
> + if (drive < 0) {
> + ret = -EINVAL;
Why not just pass the error code returned from the parse function?
> goto err_free;
> + }
>
> pinconfig[idx++] = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
> drive);
> @@ -239,8 +248,10 @@ static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node,
>
> if (sunxi_pctrl_has_bias_prop(node)) {
> int pull = sunxi_pctrl_parse_bias_prop(node);
> - if (pull < 0)
> + if (pull < 0) {
> + ret = -EINVAL;
Same here.
> goto err_free;
> + }
>
> pinconfig[idx++] = pinconf_to_config_packed(pull, 0);
> }
> @@ -251,7 +262,7 @@ static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node,
>
> err_free:
> kfree(pinconfig);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
> @@ -285,7 +296,10 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
>
> /*
> * We have two maps for each pin: one for the function, one
> - * for the configuration (bias, strength, etc)
> + * for the configuration (bias, strength, etc).
> + *
> + * We might be slightly overshooting, since we might not have
> + * any configuration.
> */
> nmaps = npins * 2;
> *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
> @@ -293,8 +307,8 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
> return -ENOMEM;
>
> pinconfig = sunxi_pctrl_build_pin_config(node, &configlen);
> - if (!pinconfig) {
> - ret = -EINVAL;
> + if (IS_ERR(pinconfig)) {
> + ret = PTR_ERR(pinconfig);
> goto err_free_map;
> }
>
> @@ -321,15 +335,16 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
>
> i++;
>
> - (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
> - (*map)[i].data.configs.group_or_pin = group;
> - (*map)[i].data.configs.configs = pinconfig;
> - (*map)[i].data.configs.num_configs = configlen;
> -
> - i++;
> + if (pinconfig) {
> + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
> + (*map)[i].data.configs.group_or_pin = group;
> + (*map)[i].data.configs.configs = pinconfig;
> + (*map)[i].data.configs.num_configs = configlen;
> + i++;
> + }
> }
>
> - *num_maps = nmaps;
> + *num_maps = i;
Thought: should we do a krealloc to shrink the array?
>
> return 0;
>
> @@ -342,8 +357,13 @@ static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
> struct pinctrl_map *map,
> unsigned num_maps)
> {
> + unsigned long *pinconfig;
> +
> /* All the maps have the same pin config, free only the first one */
> - kfree(map[0].data.configs.configs);
> + pinconfig = map[0].data.configs.configs;
> + if (pinconfig)
> + kfree(pinconfig);
Passing NULL to kfree is allowed. (It becomes a no-op.)
So you could leave this function alone.
ChenYu
> +
> kfree(map);
> }
>
> --
> git-series 0.8.10
^ permalink raw reply
* [PATCH 3/9] pinctrl: sunxi: Handle bias disable
From: Chen-Yu Tsai @ 2016-10-04 2:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f4de32e1b124b25c27e34efcadc1d332cb93ee59.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> So far, putting NO_PULL in allwinner,pull was ignored, behaving like if
> that property was not there at all.
>
> Obviously, this is not the right thing to do, and in that case, we really
> need to just disable the bias.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
I've done the same in my patches.
Acked-by: Chen-Yu Tsai <wens@csie.org>
> ---
> drivers/pinctrl/sunxi/pinctrl-sunxi.c | 8 ++++++++
> 1 file changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index 5be455d5e252..6f6f1e0011e2 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -166,6 +166,8 @@ static int sunxi_pctrl_parse_bias_prop(struct device_node *node)
> return -EINVAL;
>
> switch (val) {
> + case SUN4I_PINCTRL_NO_PULL:
> + return PIN_CONFIG_BIAS_DISABLE;
> case SUN4I_PINCTRL_PULL_UP:
> return PIN_CONFIG_BIAS_PULL_UP;
> case SUN4I_PINCTRL_PULL_DOWN:
> @@ -402,6 +404,12 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
> | dlevel << sunxi_dlevel_offset(pin),
> pctl->membase + sunxi_dlevel_reg(pin));
> break;
> + case PIN_CONFIG_BIAS_DISABLE:
> + val = readl(pctl->membase + sunxi_pull_reg(pin));
> + mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
> + writel((val & ~mask),
> + pctl->membase + sunxi_pull_reg(pin));
> + break;
> case PIN_CONFIG_BIAS_PULL_UP:
> val = readl(pctl->membase + sunxi_pull_reg(pin));
> mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
> --
> git-series 0.8.10
^ permalink raw reply
* [PATCH] ARM64: dts: meson-gxbb-odroidc2: Enable USB Nodes
From: Brian Kim @ 2016-10-04 2:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7h7f9tgzg8.fsf@baylibre.com>
On 2016? 10? 01? 00:49, Kevin Hilman wrote:
> Brian Kim <brian.kim@hardkernel.com> writes:
>
>> Enable both gxbb USB controller and add a 5V regulator for the OTG port
>> VBUS
>>
>> Signed-off-by: Brian Kim <brian.kim@hardkernel.com>
> Thanks for the patch.
>
> In the future, please state what branch the patch should apply to when
> not using mainline. Because of the sd_emmc nodes in your patch, I could
> tell that it was based on my integ branch so was able to figure it out,
> but it's very helpful to maintainers if you state the branch and/or any
> dependencies explicity.
Okay, I will do next time.
I guessed the branch is your latest working branch by the commit logs.
>
>> ---
>> .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 29 ++++++++++++++++++++++
>> 1 file changed, 29 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
>> index 8d89edc..997c671 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
>> @@ -64,6 +64,18 @@
>> reg = <0x0 0x0 0x0 0x80000000>;
>> };
>>
>> + usb_pwr: regulator-usb-pwrs {
> minor nit: since this is specific to the OTG part, can you call this
> usb_otg_pwr? ...
Sure.
>
>> + compatible = "regulator-fixed";
>> +
>> + regulator-name = "USB_PWR";
> ... and rename this also?
Yes, I will change the name to "USB_OTG_PWR".
>
>> + regulator-min-microvolt = <5000000>;
>> + regulator-max-microvolt = <5000000>;
>> +
>> + gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
>> + enable-active-high;
>> + };
>> +
> Thanks
>
> Kevin
>
^ permalink raw reply
* [PATCH 2/9] pinctrl: sunxi: Add bindings define
From: Chen-Yu Tsai @ 2016-10-04 1:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f56e271107221a2f41f256e2759a92cfe29624a8.1475489558.git-series.maxime.ripard@free-electrons.com>
On Mon, Oct 3, 2016 at 6:21 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Since we have some bindings header for our hardcoded flags, let's use them
> when we can.
"Use macros from bindings header file for DT parsing"
would make the subject clearer.
Otherwise,
Acked-by: Chen-Yu Tsai <wens@csie.org>
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> drivers/pinctrl/sunxi/pinctrl-sunxi.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index 64f7f6dcc027..5be455d5e252 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -28,6 +28,8 @@
> #include <linux/platform_device.h>
> #include <linux/slab.h>
>
> +#include <dt-bindings/pinctrl/sun4i-a10.h>
> +
> #include "../core.h"
> #include "../../gpio/gpiolib.h"
> #include "pinctrl-sunxi.h"
> @@ -164,9 +166,9 @@ static int sunxi_pctrl_parse_bias_prop(struct device_node *node)
> return -EINVAL;
>
> switch (val) {
> - case 1:
> + case SUN4I_PINCTRL_PULL_UP:
> return PIN_CONFIG_BIAS_PULL_UP;
> - case 2:
> + case SUN4I_PINCTRL_PULL_DOWN:
> return PIN_CONFIG_BIAS_PULL_DOWN;
> }
>
> --
> git-series 0.8.10
^ permalink raw reply
* [PATCH 3/3] pinctrl: sunxi: Make sunxi_pconf_group_set use sunxi_pconf_reg helper
From: Chen-Yu Tsai @ 2016-10-04 1:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161004015112.20833-1-wens@csie.org>
The sunxi_pconf_reg helper introduced in the last patch gives us the
chance to rework sunxi_pconf_group_set to have it match the structure
of sunxi_pconf_(group_)get and make it easier to understand.
For each config to set, it:
1. checks if the parameter is supported.
2. checks if the argument is within limits.
3. converts argument to the register value.
4. writes to the register with spinlock held.
As a result the function now blocks unsupported config parameters,
instead of silently ignoring them.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 65 +++++++++++++++++++----------------
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 1 -
2 files changed, 35 insertions(+), 31 deletions(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 236272a2339d..1f02c4cd55c7 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -364,23 +364,27 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
{
struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct sunxi_pinctrl_group *g = &pctl->groups[group];
- unsigned long flags;
unsigned pin = g->pin - pctl->desc->pin_base;
- u32 val, mask;
- u16 strength;
- u8 dlevel;
int i;
- spin_lock_irqsave(&pctl->lock, flags);
-
for (i = 0; i < num_configs; i++) {
- switch (pinconf_to_config_param(configs[i])) {
+ enum pin_config_param param;
+ unsigned long flags;
+ u32 offset, shift, mask, val;
+ u16 arg;
+ int ret;
+
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
+ if (ret < 0)
+ return ret;
+
+ switch (param) {
case PIN_CONFIG_DRIVE_STRENGTH:
- strength = pinconf_to_config_argument(configs[i]);
- if (strength > 40) {
- spin_unlock_irqrestore(&pctl->lock, flags);
+ if (arg < 10 || arg > 40)
return -EINVAL;
- }
/*
* We convert from mA to what the register expects:
* 0: 10mA
@@ -388,33 +392,34 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
* 2: 30mA
* 3: 40mA
*/
- dlevel = strength / 10 - 1;
- val = readl(pctl->membase + sunxi_dlevel_reg(pin));
- mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(pin);
- writel((val & ~mask)
- | dlevel << sunxi_dlevel_offset(pin),
- pctl->membase + sunxi_dlevel_reg(pin));
+ arg = arg / 10 - 1;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- val = readl(pctl->membase + sunxi_pull_reg(pin));
- mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
- writel((val & ~mask) | 1 << sunxi_pull_offset(pin),
- pctl->membase + sunxi_pull_reg(pin));
+ if (arg == 0)
+ return -EINVAL;
+ arg = 1;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- val = readl(pctl->membase + sunxi_pull_reg(pin));
- mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
- writel((val & ~mask) | 2 << sunxi_pull_offset(pin),
- pctl->membase + sunxi_pull_reg(pin));
+ if (arg == 0)
+ return -EINVAL;
+ arg = 2;
break;
- default:
+ case PIN_CONFIG_BIAS_DISABLE:
+ arg = 0;
break;
+
+ default:
+ /* sunxi_pconf_reg should catch anything unsupported */
+ WARN_ON(1);
+ return -ENOTSUPP;
}
- /* cache the config value */
- g->config = configs[i];
- } /* for each config */
- spin_unlock_irqrestore(&pctl->lock, flags);
+ spin_lock_irqsave(&pctl->lock, flags);
+ val = readl(pctl->membase + offset);
+ val &= ~(mask << shift);
+ writel(val | arg << shift, pctl->membase + offset);
+ spin_unlock_irqrestore(&pctl->lock, flags);
+ } /* for each config */
return 0;
}
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 0afce1ab12d0..a7efb31d6523 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -109,7 +109,6 @@ struct sunxi_pinctrl_function {
struct sunxi_pinctrl_group {
const char *name;
- unsigned long config;
unsigned pin;
};
--
2.9.3
^ permalink raw reply related
* [PATCH 2/3] pinctrl: sunxi: Fix PIN_CONFIG_BIAS_PULL_{DOWN, UP} argument
From: Chen-Yu Tsai @ 2016-10-04 1:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161004015112.20833-1-wens@csie.org>
According to pinconf-generic.h, the argument for
PIN_CONFIG_BIAS_PULL_{DOWN,UP} is non-zero if the bias is enabled
with a pull up/down resistor, zero if it is directly connected
to VDD or ground.
Since Allwinner hardware uses a weak pull resistor internally,
the argument should be 1.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 609843c9a65c..236272a2339d 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -234,7 +234,7 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
pull = PIN_CONFIG_BIAS_PULL_UP;
else if (val == 2)
pull = PIN_CONFIG_BIAS_PULL_DOWN;
- pinconfig[j++] = pinconf_to_config_packed(pull, 0);
+ pinconfig[j++] = pinconf_to_config_packed(pull, 1);
}
(*map)[i].data.configs.configs = pinconfig;
--
2.9.3
^ permalink raw reply related
* [PATCH 1/3] pinctrl: sunxi: Add support for fetching pinconf settings from hardware
From: Chen-Yu Tsai @ 2016-10-04 1:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161004015112.20833-1-wens@csie.org>
The sunxi pinctrl driver only caches whatever pinconf setting was last
set on a given pingroup. This is not particularly helpful, nor is it
correct.
Fix this by actually reading the hardware registers and returning
the correct results or error codes. Also filter out unsupported
pinconf settings. Since this driver has a peculiar setup of 1 pin
per group, we can support both pin and pingroup pinconf setting
read back with the same code. The sunxi_pconf_reg helper and code
structure is inspired by pinctrl-msm.
With this done we can also claim to support generic pinconf, by
setting .is_generic = true in pinconf_ops.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 85 +++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 54455af566ec..609843c9a65c 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -10,6 +10,7 @@
* warranty of any kind, whether express or implied.
*/
+#include <dt-bindings/pinctrl/sun4i-a10.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
@@ -269,15 +270,91 @@ static const struct pinctrl_ops sunxi_pctrl_ops = {
.get_group_pins = sunxi_pctrl_get_group_pins,
};
+static int sunxi_pconf_reg(unsigned pin, enum pin_config_param param,
+ u32 *offset, u32 *shift, u32 *mask)
+{
+ switch (param) {
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ *offset = sunxi_dlevel_reg(pin);
+ *shift = sunxi_dlevel_offset(pin);
+ *mask = DLEVEL_PINS_MASK;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_DISABLE:
+ *offset = sunxi_pull_reg(pin);
+ *shift = sunxi_pull_offset(pin);
+ *mask = PULL_PINS_MASK;
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int sunxi_pconf_get(struct pinctrl_dev *pctldev, unsigned pin,
+ unsigned long *config)
+{
+ struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 offset, shift, mask, val;
+ u16 arg;
+ int ret;
+
+ pin -= pctl->desc->pin_base;
+
+ ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
+ if (ret < 0)
+ return ret;
+
+ val = (readl(pctl->membase + offset) >> shift) & mask;
+
+ switch (pinconf_to_config_param(*config)) {
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ arg = (val + 1) * 10;
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (val != SUN4I_PINCTRL_PULL_UP)
+ return -EINVAL;
+ arg = 1; /* hardware is weak pull-up */
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (val != SUN4I_PINCTRL_PULL_DOWN)
+ return -EINVAL;
+ arg = 1; /* hardware is weak pull-down */
+ break;
+
+ case PIN_CONFIG_BIAS_DISABLE:
+ if (val != SUN4I_PINCTRL_NO_PULL)
+ return -EINVAL;
+ arg = 0;
+ break;
+
+ default:
+ /* sunxi_pconf_reg should catch anything unsupported */
+ WARN_ON(1);
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
unsigned group,
unsigned long *config)
{
struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct sunxi_pinctrl_group *g = &pctl->groups[group];
- *config = pctl->groups[group].config;
-
- return 0;
+ /* We only support 1 pin per group. Chain it to the pin callback */
+ return sunxi_pconf_get(pctldev, g->pin, config);
}
static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
@@ -343,6 +420,8 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
}
static const struct pinconf_ops sunxi_pconf_ops = {
+ .is_generic = true,
+ .pin_config_get = sunxi_pconf_get,
.pin_config_group_get = sunxi_pconf_group_get,
.pin_config_group_set = sunxi_pconf_group_set,
};
--
2.9.3
^ permalink raw reply related
* [PATCH 0/3] pinctrl: sunxi: Support generic pinconf functions
From: Chen-Yu Tsai @ 2016-10-04 1:51 UTC (permalink / raw)
To: linux-arm-kernel
Hi everyone,
This series fixes up generic pinconf support for the sunxi pinctrl driver
library. The driver was doing some bits wrong, like a) storing the pinconf
config value in its struct, and not actually reading the hardware to get
the current config, and b) not using the right arguments for the bias
parameters.
Patch 1 makes the driver read out pinconf settings from the hardware, and
returns the correct value for unsupported features and disable features.
With this in place it also declares itself as generic pinconf compatible,
which enables us to read the config through the debugfs pinconf interface.
Patch 2 fixes the pin bias parameter arguments.
Patch 3 makes the sunxi_pconf_group_set callback use the helper function
introduced in patch 1.
The patches will likely conflict with Maxime's generic pinctrl bindings
series. Lets figure something out.
Regards
ChenYu
Chen-Yu Tsai (3):
pinctrl: sunxi: Add support for fetching pinconf settings from
hardware
pinctrl: sunxi: Fix PIN_CONFIG_BIAS_PULL_{DOWN,UP} argument
pinctrl: sunxi: Make sunxi_pconf_group_set use sunxi_pconf_reg helper
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 152 ++++++++++++++++++++++++++--------
drivers/pinctrl/sunxi/pinctrl-sunxi.h | 1 -
2 files changed, 118 insertions(+), 35 deletions(-)
--
2.9.3
^ permalink raw reply
* [PATCH 7/8] pinctrl: aspeed-g4: Add mux configuration for all pins
From: Andrew Jeffery @ 2016-10-04 1:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161003190833.GA3065@rob-hp-laptop>
On Mon, 2016-10-03 at 14:08 -0500, Rob Herring wrote:
> On Wed, Sep 28, 2016 at 12:20:19AM +0930, Andrew Jeffery wrote:
> >
> > The patch introducing the g4 pinctrl driver implemented a smattering of
> > pins to flesh out the implementation of the core and provide bare-bones
> > support for some OpenPOWER platforms. Now, update the bindings document
> > to reflect the complete functionality and implement the necessary pin
> > configuration tables in the driver.
> We prefer bindings to be complete if possible where as drivers can be?
> expanded over time.
Noted.
>
> >
> >
> > Cc: Timothy Pearson <tpearson@raptorengineering.com>
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> > ?Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt |???19 +-
> Acked-by: Rob Herring <robh@kernel.org>
Thanks,
Andrew
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/746c8627/attachment.sig>
^ permalink raw reply
* [PATCH] efi/arm: fix absolute relocation detection for older toolchains
From: Matt Fleming @ 2016-10-03 20:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475276515-21801-1-git-send-email-ard.biesheuvel@linaro.org>
On Fri, 30 Sep, at 04:01:55PM, Ard Biesheuvel wrote:
>
> This is a workaround for now. We can revisit this when a need arises to copy
> more kernel code into the stub, by which time we could put in a more elaborate
> fix, or decide to no longer care about 'older' versions of objcopy.
>
> Since this fixes an ARM specific issue and only affects ARM specific Makefile
> variables, I am happy for this to go on top of the arm-soc patch that enables
> CONFIG_EFI for ARM's multi_v7_defconfig (queued for v4.9), given that we have
> no other changes queued in linux-efi that should conflict with this patch.
>
> Matt, any concerns?
Not with the patch, but could we clarify the user-visible effects of
not applying it? Are the absolute relocations harmless, or will they
lead to crashes?
^ permalink raw reply
* [PATCH v4 7/7] i2c: bcm2835: Add support for dynamic clock
From: Noralf Trønnes @ 2016-10-03 20:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475525174-28604-1-git-send-email-noralf@tronnes.org>
Support a dynamic clock by reading the frequency and setting the
divisor in the transfer function instead of during probe.
Signed-off-by: Noralf Tr?nnes <noralf@tronnes.org>
Reviewed-by: Martin Sperl <kernel@martin.sperl.org>
---
drivers/i2c/busses/i2c-bcm2835.c | 51 +++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index d2085dd..c3436f6 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -58,6 +58,7 @@ struct bcm2835_i2c_dev {
void __iomem *regs;
struct clk *clk;
int irq;
+ u32 bus_clk_rate;
struct i2c_adapter adapter;
struct completion completion;
struct i2c_msg *curr_msg;
@@ -78,6 +79,30 @@ static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg)
return readl(i2c_dev->regs + reg);
}
+static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
+{
+ u32 divider;
+
+ divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk),
+ i2c_dev->bus_clk_rate);
+ /*
+ * Per the datasheet, the register is always interpreted as an even
+ * number, by rounding down. In other words, the LSB is ignored. So,
+ * if the LSB is set, increment the divider to avoid any issue.
+ */
+ if (divider & 1)
+ divider++;
+ if ((divider < BCM2835_I2C_CDIV_MIN) ||
+ (divider > BCM2835_I2C_CDIV_MAX)) {
+ dev_err_ratelimited(i2c_dev->dev, "Invalid clock-frequency\n");
+ return -EINVAL;
+ }
+
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
+
+ return 0;
+}
+
static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev)
{
u32 val;
@@ -224,7 +249,7 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
{
struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
unsigned long time_left;
- int i;
+ int i, ret;
for (i = 0; i < (num - 1); i++)
if (msgs[i].flags & I2C_M_RD) {
@@ -233,6 +258,10 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
return -EOPNOTSUPP;
}
+ ret = bcm2835_i2c_set_divider(i2c_dev);
+ if (ret)
+ return ret;
+
i2c_dev->curr_msg = msgs;
i2c_dev->num_msgs = num;
reinit_completion(&i2c_dev->completion);
@@ -282,7 +311,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
{
struct bcm2835_i2c_dev *i2c_dev;
struct resource *mem, *irq;
- u32 bus_clk_rate, divider;
int ret;
struct i2c_adapter *adap;
@@ -306,27 +334,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
}
ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
- &bus_clk_rate);
+ &i2c_dev->bus_clk_rate);
if (ret < 0) {
dev_warn(&pdev->dev,
"Could not read clock-frequency property\n");
- bus_clk_rate = 100000;
- }
-
- divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), bus_clk_rate);
- /*
- * Per the datasheet, the register is always interpreted as an even
- * number, by rounding down. In other words, the LSB is ignored. So,
- * if the LSB is set, increment the divider to avoid any issue.
- */
- if (divider & 1)
- divider++;
- if ((divider < BCM2835_I2C_CDIV_MIN) ||
- (divider > BCM2835_I2C_CDIV_MAX)) {
- dev_err(&pdev->dev, "Invalid clock-frequency\n");
- return -ENODEV;
+ i2c_dev->bus_clk_rate = 100000;
}
- bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
--
2.8.2
^ permalink raw reply related
* [PATCH v4 6/7] i2c: bcm2835: Support i2c-dev ioctl I2C_TIMEOUT
From: Noralf Trønnes @ 2016-10-03 20:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475525174-28604-1-git-send-email-noralf@tronnes.org>
Use i2c_adapter->timeout for the completion timeout value. The core
default is 1 second.
Signed-off-by: Noralf Tr?nnes <noralf@tronnes.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
---
drivers/i2c/busses/i2c-bcm2835.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index 241e08a..d2085dd 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -53,8 +53,6 @@
#define BCM2835_I2C_CDIV_MIN 0x0002
#define BCM2835_I2C_CDIV_MAX 0xFFFE
-#define BCM2835_I2C_TIMEOUT (msecs_to_jiffies(1000))
-
struct bcm2835_i2c_dev {
struct device *dev;
void __iomem *regs;
@@ -242,7 +240,7 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
bcm2835_i2c_start_transfer(i2c_dev);
time_left = wait_for_completion_timeout(&i2c_dev->completion,
- BCM2835_I2C_TIMEOUT);
+ adap->timeout);
if (!time_left) {
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C,
BCM2835_I2C_C_CLEAR);
--
2.8.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox