Re: [PATCH 4/4] ste_dma40: implement support for scatterlist to scatterlist copy

2010-09-30 Thread Per Friden
On 09/29/2010 11:19 PM, Dan Williams wrote:
 On Mon, Sep 27, 2010 at 3:57 PM, Ira W. Snyder i...@ovro.caltech.edu wrote:
 Now that the DMAEngine API has support for scatterlist to scatterlist
 copy, implement support for the STE DMA40 DMA controller.

 Cc: Linus Walleij linus.ml.wall...@gmail.com
 Cc: Per Fridén per.fri...@stericsson.com
 Signed-off-by: Ira W. Snyder i...@ovro.caltech.edu
 ---
  drivers/dma/ste_dma40.c |   17 +
  1 files changed, 17 insertions(+), 0 deletions(-)

 diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
 index 17e2600..cd48859 100644
 --- a/drivers/dma/ste_dma40.c
 +++ b/drivers/dma/ste_dma40.c
 @@ -1857,6 +1857,18 @@ err:
return NULL;
  }

 +static struct dma_async_tx_descriptor *
 +d40_prep_sg(struct dma_chan *chan,
 +   struct scatterlist *dst_sg, unsigned int dst_nents,
 +   struct scatterlist *src_sg, unsigned int src_nents,
 +   unsigned long dma_flags)
 +{
 +   if (dst_nents != src_nents)
 +   return -EINVAL;
 
 I suspect you wanted return NULL; here.  I can fix that up.
 
 Linus, Per ack?
 
 --
 Dan
Thanks Dan. Acked by Per.

/Per
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 4/7] powerpc/of: add eSPI controller dts bindings and DTS modification

2010-09-30 Thread Mingkai Hu
Also modifiy the document of cell-index in SPI controller. Add the
SPI flash(s25fl128p01) support on p4080ds and mpc8536ds board.

Signed-off-by: Mingkai Hu mingkai...@freescale.com
---
v3:
 - Add fsl,p4080-espi compatible property.

 Documentation/powerpc/dts-bindings/fsl/spi.txt |   24 ++-
 arch/powerpc/boot/dts/mpc8536ds.dts|   52 
 arch/powerpc/boot/dts/p4080ds.dts  |   11 ++---
 3 files changed, 79 insertions(+), 8 deletions(-)

diff --git a/Documentation/powerpc/dts-bindings/fsl/spi.txt 
b/Documentation/powerpc/dts-bindings/fsl/spi.txt
index 80510c0..777abd7 100644
--- a/Documentation/powerpc/dts-bindings/fsl/spi.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/spi.txt
@@ -1,7 +1,9 @@
 * SPI (Serial Peripheral Interface)
 
 Required properties:
-- cell-index : SPI controller index.
+- cell-index : QE SPI subblock index.
+   0: QE subblock SPI1
+   1: QE subblock SPI2
 - compatible : should be fsl,spi.
 - mode : the SPI operation mode, it can be cpu or cpu-qe.
 - reg : Offset and length of the register set for the device
@@ -29,3 +31,23 @@ Example:
gpios = gpio 18 1 // device reg=0
 gpio 19 1;   // device reg=1
};
+
+
+* eSPI (Enhanced Serial Peripheral Interface)
+
+Required properties:
+- compatible : should be fsl,mpc8536-espi.
+- reg : Offset and length of the register set for the device.
+- interrupts : should contain eSPI interrupt, the device has one interrupt.
+- fsl,espi-num-chipselects : the number of the chipselect signals.
+
+Example:
+   s...@11 {
+   #address-cells = 1;
+   #size-cells = 0;
+   compatible = fsl,mpc8536-espi;
+   reg = 0x11 0x1000;
+   interrupts = 53 0x2;
+   interrupt-parent = mpic;
+   fsl,espi-num-chipselects = 4;
+   };
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts 
b/arch/powerpc/boot/dts/mpc8536ds.dts
index 815cebb..a75c10e 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -108,6 +108,58 @@
};
};
 
+   s...@7000 {
+   #address-cells = 1;
+   #size-cells = 0;
+   compatible = fsl,mpc8536-espi;
+   reg = 0x7000 0x1000;
+   interrupts = 59 0x2;
+   interrupt-parent = mpic;
+   fsl,espi-num-chipselects = 4;
+
+   fl...@0 {
+   #address-cells = 1;
+   #size-cells = 1;
+   compatible = spansion,s25sl12801;
+   reg = 0;
+   spi-max-frequency = 4000;
+   partit...@u-boot {
+   label = u-boot;
+   reg = 0x 0x0010;
+   read-only;
+   };
+   partit...@kernel {
+   label = kernel;
+   reg = 0x0010 0x0050;
+   read-only;
+   };
+   partit...@dtb {
+   label = dtb;
+   reg = 0x0060 0x0010;
+   read-only;
+   };
+   partit...@fs {
+   label = file system;
+   reg = 0x0070 0x0090;
+   };
+   };
+   fl...@1 {
+   compatible = spansion,s25sl12801;
+   reg = 1;
+   spi-max-frequency = 4000;
+   };
+   fl...@2 {
+   compatible = spansion,s25sl12801;
+   reg = 2;
+   spi-max-frequency = 4000;
+   };
+   fl...@3 {
+   compatible = spansion,s25sl12801;
+   reg = 3;
+   spi-max-frequency = 4000;
+   };
+   };
+
d...@21300 {
#address-cells = 1;
#size-cells = 1;
diff --git a/arch/powerpc/boot/dts/p4080ds.dts 
b/arch/powerpc/boot/dts/p4080ds.dts
index 2f0de24..5b7fc29 100644
--- a/arch/powerpc/boot/dts/p4080ds.dts
+++ b/arch/powerpc/boot/dts/p4080ds.dts
@@ -236,22 +236,19 @@
};
 
s...@11 {
-   

[PATCH v3 5/7] mtd: m25p80: add support to parse the SPI flash's partitions

2010-09-30 Thread Mingkai Hu
Signed-off-by: Mingkai Hu mingkai...@freescale.com
---
v3:
 - Move the SPI flash partition code to the probe function.

 drivers/mtd/devices/m25p80.c |   39 +++
 1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 6f512b5..47d53c7 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -772,7 +772,7 @@ static const struct spi_device_id *__devinit 
jedec_probe(struct spi_device *spi)
 static int __devinit m25p_probe(struct spi_device *spi)
 {
const struct spi_device_id  *id = spi_get_device_id(spi);
-   struct flash_platform_data  *data;
+   struct flash_platform_data  data, *pdata;
struct m25p *flash;
struct flash_info   *info;
unsignedi;
@@ -782,13 +782,27 @@ static int __devinit m25p_probe(struct spi_device *spi)
 * a chip ID, try the JEDEC id commands; they'll work for most
 * newer chips, even if we don't recognize the particular chip.
 */
-   data = spi-dev.platform_data;
-   if (data  data-type) {
+   pdata = spi-dev.platform_data;
+   if (!pdata  spi-dev.of_node) {
+   int nr_parts;
+   struct mtd_partition *parts;
+   struct device_node *np = spi-dev.of_node;
+
+   nr_parts = of_mtd_parse_partitions(spi-dev, np, parts);
+   if (nr_parts) {
+   pdata = data;
+   memset(pdata, 0, sizeof(*pdata));
+   pdata-parts = parts;
+   pdata-nr_parts = nr_parts;
+   }
+   }
+
+   if (pdata  pdata-type) {
const struct spi_device_id *plat_id;
 
for (i = 0; i  ARRAY_SIZE(m25p_ids) - 1; i++) {
plat_id = m25p_ids[i];
-   if (strcmp(data-type, plat_id-name))
+   if (strcmp(pdata-type, plat_id-name))
continue;
break;
}
@@ -796,7 +810,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
if (i  ARRAY_SIZE(m25p_ids) - 1)
id = plat_id;
else
-   dev_warn(spi-dev, unrecognized id %s\n, data-type);
+   dev_warn(spi-dev, unrecognized id %s\n,
+   pdata-type);
}
 
info = (void *)id-driver_data;
@@ -847,8 +862,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
write_sr(flash, 0);
}
 
-   if (data  data-name)
-   flash-mtd.name = data-name;
+   if (pdata  pdata-name)
+   flash-mtd.name = pdata-name;
else
flash-mtd.name = dev_name(spi-dev);
 
@@ -919,9 +934,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
part_probes, parts, 0);
}
 
-   if (nr_parts = 0  data  data-parts) {
-   parts = data-parts;
-   nr_parts = data-nr_parts;
+   if (nr_parts = 0  pdata  pdata-parts) {
+   parts = pdata-parts;
+   nr_parts = pdata-nr_parts;
}
 
if (nr_parts  0) {
@@ -937,9 +952,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash-partitioned = 1;
return add_mtd_partitions(flash-mtd, parts, nr_parts);
}
-   } else if (data  data-nr_parts)
+   } else if (pdata  pdata-nr_parts)
dev_warn(spi-dev, ignoring %d default partitions on %s\n,
-   data-nr_parts, data-name);
+   pdata-nr_parts, pdata-name);
 
return add_mtd_device(flash-mtd) == 1 ? -ENODEV : 0;
 }
-- 
1.6.4


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 2/7] spi/mpc8xxx: refactor the common code for SPI/eSPI controller

2010-09-30 Thread Mingkai Hu
Refactor the common code in file spi_fsl_spi.c to spi_fsl_lib.c used
by SPI/eSPI controller driver as a library, and leave the QE/CPM SPI
controller code in the SPI controller driver spi_fsl_spi.c.

Because the register map of the SPI controller and eSPI controller
is so different, also leave the code operated the register to the
driver code, not the common code.

Signed-off-by: Mingkai Hu mingkai...@freescale.com
---

v3:
 - Update to the latest kernel base.
 - Add a void *reg_base to compatible for SPI and eSPI register base.

 drivers/spi/Kconfig   |5 +
 drivers/spi/Makefile  |1 +
 drivers/spi/spi_fsl_lib.c |  237 +++
 drivers/spi/spi_fsl_lib.h |  119 ++
 drivers/spi/spi_fsl_spi.c |  552 +
 5 files changed, 522 insertions(+), 392 deletions(-)
 create mode 100644 drivers/spi/spi_fsl_lib.c
 create mode 100644 drivers/spi/spi_fsl_lib.h

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 6af34c6..79ad06f 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -182,9 +182,14 @@ config SPI_MPC512x_PSC
  This enables using the Freescale MPC5121 Programmable Serial
  Controller in SPI master mode.
 
+config SPI_FSL_LIB
+   tristate
+   depends on FSL_SOC
+
 config SPI_FSL_SPI
tristate Freescale SPI controller
depends on FSL_SOC
+   select SPI_FSL_LIB
help
  This enables using the Freescale SPI controllers in master mode.
  MPC83xx platform uses the controller in cpu mode or CPM/QE mode.
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 770817c..7974c21 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SPI_PL022)   += amba-pl022.o
 obj-$(CONFIG_SPI_MPC512x_PSC)  += mpc512x_psc_spi.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)  += mpc52xx_psc_spi.o
 obj-$(CONFIG_SPI_MPC52xx)  += mpc52xx_spi.o
+obj-$(CONFIG_SPI_FSL_LIB)  += spi_fsl_lib.o
 obj-$(CONFIG_SPI_FSL_SPI)  += spi_fsl_spi.o
 obj-$(CONFIG_SPI_PPC4xx)   += spi_ppc4xx.o
 obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
diff --git a/drivers/spi/spi_fsl_lib.c b/drivers/spi/spi_fsl_lib.c
new file mode 100644
index 000..5cd741f
--- /dev/null
+++ b/drivers/spi/spi_fsl_lib.c
@@ -0,0 +1,237 @@
+/*
+ * Freescale SPI/eSPI controller driver library.
+ *
+ * Maintainer: Kumar Gala
+ *
+ * Copyright (C) 2006 Polycom, Inc.
+ *
+ * CPM SPI and QE buffer descriptors mode support:
+ * Copyright (c) 2009  MontaVista Software, Inc.
+ * Author: Anton Vorontsov avoront...@ru.mvista.com
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include linux/kernel.h
+#include linux/interrupt.h
+#include linux/fsl_devices.h
+#include linux/dma-mapping.h
+#include linux/mm.h
+#include linux/of_platform.h
+#include linux/of_spi.h
+#include sysdev/fsl_soc.h
+
+#include spi_fsl_lib.h
+
+#define MPC8XXX_SPI_RX_BUF(type) \
+void mpc8xxx_spi_rx_buf_##type(u32 data, struct mpc8xxx_spi *mpc8xxx_spi) \
+{\
+   type *rx = mpc8xxx_spi-rx;   \
+   *rx++ = (type)(data  mpc8xxx_spi-rx_shift);\
+   mpc8xxx_spi-rx = rx; \
+}
+
+#define MPC8XXX_SPI_TX_BUF(type)   \
+u32 mpc8xxx_spi_tx_buf_##type(struct mpc8xxx_spi *mpc8xxx_spi) \
+{  \
+   u32 data;   \
+   const type *tx = mpc8xxx_spi-tx;   \
+   if (!tx)\
+   return 0;   \
+   data = *tx++  mpc8xxx_spi-tx_shift;  \
+   mpc8xxx_spi-tx = tx;   \
+   return data;\
+}
+
+MPC8XXX_SPI_RX_BUF(u8)
+MPC8XXX_SPI_RX_BUF(u16)
+MPC8XXX_SPI_RX_BUF(u32)
+MPC8XXX_SPI_TX_BUF(u8)
+MPC8XXX_SPI_TX_BUF(u16)
+MPC8XXX_SPI_TX_BUF(u32)
+
+struct mpc8xxx_spi_probe_info *to_of_pinfo(struct fsl_spi_platform_data *pdata)
+{
+   return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata);
+}
+
+void mpc8xxx_spi_work(struct work_struct *work)
+{
+   struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi,
+  work);
+
+   spin_lock_irq(mpc8xxx_spi-lock);
+   while (!list_empty(mpc8xxx_spi-queue)) {
+   struct spi_message *m = 

[PATCH v3 3/7] eSPI: add eSPI controller support

2010-09-30 Thread Mingkai Hu
Add eSPI controller support based on the library code spi_fsl_lib.c.

The eSPI controller is newer controller 85xx/Pxxx devices supported.
There're some differences comparing to the SPI controller:

1. Has different register map and different bit definition
   So leave the code operated the register to the driver code, not
   the common code.

2. Support 4 dedicated chip selects
   The software can't controll the chip selects directly, The SPCOM[CS]
   field is used to select which chip selects is used, and the
   SPCOM[TRANLEN] field is set to tell the controller how long the CS
   signal need to be asserted. So the driver doesn't need the chipselect
   related function when transfering data, just set corresponding register
   fields to controll the chipseclect.

3. Different Transmit/Receive FIFO access register behavior
   For SPI controller, the Tx/Rx FIFO access register can hold only
   one character regardless of the character length, but for eSPI
   controller, the register can hold 4 or 2 characters according to
   the character lengths. Access the Tx/Rx FIFO access register of the
   eSPI controller will shift out/in 4/2 characters one time. For SPI
   subsystem, the command and data are put into different transfers, so
   we need to combine all the transfers to one transfer in order to pass
   the transfer to eSPI controller.

Signed-off-by: Mingkai Hu mingkai...@freescale.com
---
v3:
 - Update to the latest kernel base.

 drivers/spi/Kconfig|9 +
 drivers/spi/Makefile   |1 +
 drivers/spi/spi_fsl_espi.c |  642 
 drivers/spi/spi_fsl_lib.h  |1 +
 4 files changed, 653 insertions(+), 0 deletions(-)
 create mode 100644 drivers/spi/spi_fsl_espi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 79ad06f..f6888af 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -195,6 +195,15 @@ config SPI_FSL_SPI
  MPC83xx platform uses the controller in cpu mode or CPM/QE mode.
  MPC8569 uses the controller in QE mode, MPC8610 in cpu mode.
 
+config SPI_FSL_ESPI
+   tristate Freescale eSPI controller
+   depends on FSL_SOC
+   select SPI_FSL_LIB
+   help
+ This enables using the Freescale eSPI controllers in master mode.
+ From MPC8536, 85xx platform uses the controller, and all P10xx,
+ P20xx, P30xx,P40xx, P50xx uses this controller.
+
 config SPI_OMAP_UWIRE
tristate OMAP1 MicroWire
depends on ARCH_OMAP1
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 7974c21..833d17e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += mpc512x_psc_spi.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)  += mpc52xx_psc_spi.o
 obj-$(CONFIG_SPI_MPC52xx)  += mpc52xx_spi.o
 obj-$(CONFIG_SPI_FSL_LIB)  += spi_fsl_lib.o
+obj-$(CONFIG_SPI_FSL_ESPI) += spi_fsl_espi.o
 obj-$(CONFIG_SPI_FSL_SPI)  += spi_fsl_spi.o
 obj-$(CONFIG_SPI_PPC4xx)   += spi_ppc4xx.o
 obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c
new file mode 100644
index 000..be98148
--- /dev/null
+++ b/drivers/spi/spi_fsl_espi.c
@@ -0,0 +1,642 @@
+/*
+ * Freescale eSPI controller driver.
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include linux/module.h
+#include linux/delay.h
+#include linux/irq.h
+#include linux/spi/spi.h
+#include linux/platform_device.h
+#include linux/fsl_devices.h
+#include linux/mm.h
+#include linux/of.h
+#include linux/of_platform.h
+#include linux/of_spi.h
+#include sysdev/fsl_soc.h
+#include linux/interrupt.h
+#include linux/err.h
+
+#include spi_fsl_lib.h
+
+/* eSPI Controller registers */
+struct fsl_espi_reg {
+   __be32 mode;/* 0x000 - eSPI mode register */
+   __be32 event;   /* 0x004 - eSPI event register */
+   __be32 mask;/* 0x008 - eSPI mask register */
+   __be32 command; /* 0x00c - eSPI command register */
+   __be32 transmit;/* 0x010 - eSPI transmit FIFO access register*/
+   __be32 receive; /* 0x014 - eSPI receive FIFO access register*/
+   u8 res[8];  /* 0x018 - 0x01c reserved */
+   __be32 csmode[4];   /* 0x020 - 0x02c eSPI cs mode register */
+};
+
+/* eSPI Controller mode register definitions */
+#define SPMODE_ENABLE  (1  31)
+#define SPMODE_LOOP(1  30)
+#define SPMODE_TXTHR(x)((x)  8)
+#define SPMODE_RXTHR(x)((x)  0)
+
+/* eSPI Controller CS mode register definitions */
+#define CSMODE_CI_INACTIVEHIGH (1  31)
+#define 

[PATCH v3 7/7] DTS: add fsl,spi-quirk-trans-len-limit property

2010-09-30 Thread Mingkai Hu
Signed-off-by: Mingkai Hu mingkai...@freescale.com
---
v3:
 - Add spi-quirk-trans-len-limit property to the board's dts.

 Documentation/powerpc/dts-bindings/fsl/spi.txt |3 +++
 arch/powerpc/boot/dts/mpc8536ds.dts|1 +
 arch/powerpc/boot/dts/p4080ds.dts  |1 +
 3 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/Documentation/powerpc/dts-bindings/fsl/spi.txt 
b/Documentation/powerpc/dts-bindings/fsl/spi.txt
index 777abd7..e1cb84e 100644
--- a/Documentation/powerpc/dts-bindings/fsl/spi.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/spi.txt
@@ -41,6 +41,9 @@ Required properties:
 - interrupts : should contain eSPI interrupt, the device has one interrupt.
 - fsl,espi-num-chipselects : the number of the chipselect signals.
 
+Optional properties:
+- fsl,spi-quirk-trans-len-limit : the max trans length is limited to 0x.
+
 Example:
s...@11 {
#address-cells = 1;
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts 
b/arch/powerpc/boot/dts/mpc8536ds.dts
index a75c10e..6911c76 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -116,6 +116,7 @@
interrupts = 59 0x2;
interrupt-parent = mpic;
fsl,espi-num-chipselects = 4;
+   fsl,spi-quirk-trans-len-limit;
 
fl...@0 {
#address-cells = 1;
diff --git a/arch/powerpc/boot/dts/p4080ds.dts 
b/arch/powerpc/boot/dts/p4080ds.dts
index 5b7fc29..060fc45 100644
--- a/arch/powerpc/boot/dts/p4080ds.dts
+++ b/arch/powerpc/boot/dts/p4080ds.dts
@@ -243,6 +243,7 @@
interrupts = 53 0x2;
interrupt-parent = mpic;
fsl,espi-num-chipselects = 4;
+   fsl,spi-quirk-trans-len-limit;
 
fl...@0 {
#address-cells = 1;
-- 
1.6.4


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by page

2010-09-30 Thread Grant Likely
On Thu, Sep 30, 2010 at 7:46 PM, David Brownell davi...@pacbell.net wrote:

 --- On Thu, 9/30/10, Mingkai Hu mingkai...@freescale.com wrote:

 From: Mingkai Hu mingkai...@freescale.com
 Subject: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by page

 NAK.

 We went over this before.

Yes, I agree with David on this.  If large transfers don't work, then
it is the SPI master driver that is buggy.

g.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by page

2010-09-30 Thread Grant Likely
On Thu, Sep 30, 2010 at 11:16 PM, Grant Likely
grant.lik...@secretlab.ca wrote:
 On Thu, Sep 30, 2010 at 7:46 PM, David Brownell davi...@pacbell.net wrote:

 --- On Thu, 9/30/10, Mingkai Hu mingkai...@freescale.com wrote:

 From: Mingkai Hu mingkai...@freescale.com
 Subject: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by 
 page

 NAK.

 We went over this before.

 Yes, I agree with David on this.  If large transfers don't work, then
 it is the SPI master driver that is buggy.

By the way, does this fix your problem?

https://patchwork.kernel.org/patch/184752/

g.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by page

2010-09-30 Thread Anton Vorontsov
On Thu, Sep 30, 2010 at 11:41:40PM +0900, Grant Likely wrote:
 On Thu, Sep 30, 2010 at 11:16 PM, Grant Likely
 grant.lik...@secretlab.ca wrote:
  On Thu, Sep 30, 2010 at 7:46 PM, David Brownell davi...@pacbell.net wrote:
 
  --- On Thu, 9/30/10, Mingkai Hu mingkai...@freescale.com wrote:
 
  From: Mingkai Hu mingkai...@freescale.com
  Subject: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by 
  page
 
  NAK.
 
  We went over this before.
 
  Yes, I agree with David on this.  If large transfers don't work, then
  it is the SPI master driver that is buggy.
 
 By the way, does this fix your problem?
 
 https://patchwork.kernel.org/patch/184752/

It shouldn't. AFAIK, eSPI is PIO-only controller, and the overrun
fix is for the DMA mode.

Thanks,

p.s. Btw, in patch 3/7, is_dma_mapped argument of fsl_espi_bufs()
is unneeded.

-- 
Anton Vorontsov
email: cbouatmai...@gmail.com
irc://irc.freenode.net/bd2
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections

2010-09-30 Thread Nathan Fontenot
On 09/29/2010 02:28 PM, Robin Holt wrote:
 On Tue, Sep 28, 2010 at 01:17:33PM -0500, Nathan Fontenot wrote:
 On 09/28/2010 07:38 AM, Robin Holt wrote:
 I was tasked with looking at a slowdown in similar sized SGI machines
 booting x86_64.  Jack Steiner had already looked into the memory_dev_init.
 I was looking at link_mem_sections().

 I made a dramatic improvement on a 16TB machine in that function by
 merely caching the most recent memory section and checking to see if
 the next memory section happens to be the subsequent in the linked list
 of kobjects.

 That simple cache reduced the time for link_mem_sections from 1 hour 27
 minutes down to 46 seconds.

 Nice!


 I would like to propose we implement something along those lines also,
 but I am currently swamped.  I can probably get you a patch tomorrow
 afternoon that applies at the end of this set.

 Should this be done as a separate patch?  This patch set concentrates on
 updates to the memory code with the node updates only being done due to the
 memory changes.

 I think its a good idea to do the caching and have no problem adding on to
 this patchset if no one else has any objections.
 
 I am sorry.  I had meant to include you on the Cc: list.  I just posted a
 set of patches (3 small patches) which implement the cache most recent bit
 I aluded to above.  Search for a subject of Speed up link_mem_sections
 during boot and you will find them.  I did add you to the Cc: list for
 the next time I end up sending the set.
 
 My next task is to implement a x86_64 SGI UV specific chunk of code
 to memory_block_size_bytes().  Would you consider adding that to your
 patch set?  I expect to have that either later today or early tomorrow.
 

No problem. I'm putting together a new patch set with updates from all of
the comments now so go ahead and send it to me when you have it ready.

-Nathan
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 0/8] v2 De-Couple sysfs memory directories from memory sections

2010-09-30 Thread Robin Holt
On Wed, Sep 29, 2010 at 02:28:30PM -0500, Robin Holt wrote:
 On Tue, Sep 28, 2010 at 01:17:33PM -0500, Nathan Fontenot wrote:
...
 My next task is to implement a x86_64 SGI UV specific chunk of code
 to memory_block_size_bytes().  Would you consider adding that to your
 patch set?  I expect to have that either later today or early tomorrow.

The patch is below.

I left things at a u32, but I would really like it if you changed to an
unsigned long and adjusted my patch for me.

Thanks,
Robin


Subject: [Patch] Implement memory_block_size_bytes for x86_64 when CONFIG_X86_UV


Nathan Fontenot has implemented a patch set for large memory configuration
systems which will combine drivers/base/memory.c memory sections
together into memory blocks with the default behavior being
unchanged from the current behavior.

In his patch set, he implements a memory_block_size_bytes() function
for PPC.  This is the equivalent patch for x86_64 when it has
CONFIG_X86_UV set.

Signed-off-by: Robin Holt h...@sgi.com
Signed-off-by: Jack Steiner stei...@sgi.com
To: Nathan Fontenot nf...@austin.ibm.com
Cc: Ingo Molnar mi...@elte.hu
Cc: Thomas Gleixner t...@linutronix.de
Cc: H. Peter Anvin h...@zytor.com
Cc: lkml linux-ker...@vger.kernel.org

---

 arch/x86/mm/init_64.c |   15 +++
 1 file changed, 15 insertions(+)

Index: memory_block/arch/x86/mm/init_64.c
===
--- memory_block.orig/arch/x86/mm/init_64.c 2010-09-29 14:46:50.711824616 
-0500
+++ memory_block/arch/x86/mm/init_64.c  2010-09-29 14:46:55.683997672 -0500
@@ -50,6 +50,7 @@
 #include asm/numa.h
 #include asm/cacheflush.h
 #include asm/init.h
+#include asm/uv/uv.h
 #include linux/bootmem.h
 
 static unsigned long dma_reserve __initdata;
@@ -928,6 +929,20 @@ const char *arch_vma_name(struct vm_area
return NULL;
 }
 
+#ifdef CONFIG_X86_UV
+#define MIN_MEMORY_BLOCK_SIZE   (1  SECTION_SIZE_BITS)
+
+u32 memory_block_size_bytes(void)
+{
+   if (is_uv_system()) {
+   printk(UV: memory block size 2GB\n);
+   return 2UL * 1024 * 1024 * 1024;
+   }
+   return MIN_MEMORY_BLOCK_SIZE;
+}
+#endif
+
+
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 /*
  * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] PPC4xx: ADMA separating SoC specific functions

2010-09-30 Thread Wolfgang Denk
Dear tma...@apm.com,

In message 1285865736-32074-1-git-send-email-tma...@apm.com you wrote:
 From: Tirumala Marri tma...@apm.com
 
 This patch separates the SoC specific functions and moved
 to different files.
 
 The reason for ppc440spe-adma.h is to define in-line functions which
 are called by both adma.c and ppc440spe-adma.c . 
 
 Where as ppc440spe-adma.c is to define functions are completely
 completely dependent on 440spe, also which are too big to define
 as in-line functions.

When reposting a patch, please always indicate that this is new
version by using something like [PATCH v2] in the Subject line.

 Signed-off-by: Tirumala R Marri tma...@apm.com
 Acked-by: Yuri Tikhonov y...@emcraft.com
 CC:  Dan Williams dan.j.willi...@intel.com
 CC:  Josh Boyer jwbo...@linux.vnet.ibm.com
 ---

Also, please include here (i. e. below the --- line, i. e. in the
comments section, a description of what was changed compared to the
previous version of this patch.

As is, you enforce us to rescan the whole patch again and check
manually if you have reacted to any of the comments sent before, and
how.  As is, you make reviewing your poatches harder than necessary.


 diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
 index 0d58a4a..a1053cb 100644
 --- a/drivers/dma/ppc4xx/adma.c
 +++ b/drivers/dma/ppc4xx/adma.c
...
 +#include ppc440spe-adma.h
 +
 +struct dma_async_tx_descriptor
 +*ppc440spe_adma_prep_dma_pq(struct dma_chan *chan,
 +dma_addr_t * dst,
 +dma_addr_t * src,
 +unsigned int src_cnt,
 +const unsigned char *scf,
 +size_t len,
 +unsigned long flags);
 +struct dma_async_tx_descriptor
 +*ppc440spe_adma_prep_dma_pqzero_sum(struct dma_chan *chan,

Should such 440SPe specific code not be removed here and placed into
ppc440spe-adma.c instead?

 +#if 0
  static void prep_dma_pq_dbg(int id, dma_addr_t *dst, dma_addr_t *src,
   unsigned int src_cnt)
  {
 @@ -213,8 +104,9 @@ static void prep_dma_pq_dbg(int id, dma_addr_t *dst, 
 dma_addr_t *src,
   for (i = 0; i  2; i++)
   pr_debug(\t0x%016llx , dst[i]);
  }
 +#endif

Please do not add dead code - remove the whole #if 0 block.


  
 /**
   * ADMA channel low-level routines
   
 **/
  
 -static u32
...
...
 -}
  
  
 /**
   * ADMA device level
   
 **/

It seems youremove all code, but leave the (now empty) comment
headers? This makes little sense to me.

...
  /**
   * ppc440spe_adma_free_slots - flags descriptor slots for reuse
   * @slot: Slot to free
   * Caller must hold ppc440spe_chan-lock while calling this function
   */

Again, all this is pretty low-level 440SPe specific code. Why do you
keep this in the common drive rfile instead of moving it into the new
440SPe specific file?


 diff --git a/drivers/dma/ppc4xx/ppc440spe-adma.c 
 b/drivers/dma/ppc4xx/ppc440spe-adma.c
 new file mode 100644
 index 000..da467b4
...
 + /*  In the current implementation of ppc440spe ADMA driver it
 +
 +
 +
 +  * makes sense to pick out only pq case, because it may be

Formatting problems?


 diff --git a/drivers/dma/ppc4xx/ppc440spe-adma.h 
 b/drivers/dma/ppc4xx/ppc440spe-adma.h
 new file mode 100644
 index 000..81a1f46
 --- /dev/null
 +++ b/drivers/dma/ppc4xx/ppc440spe-adma.h
...
 +/*
 + * ppc440spe_get_group_entry - get group entry with index idx
 + * @tdesc: is the last allocated slot in the group.
 + */
 +static struct ppc440spe_adma_desc_slot *ppc440spe_get_group_entry(struct
 + 
 ppc440spe_adma_desc_slot
 + *tdesc,
 + u32 entry_idx)
 +{
 + struct ppc440spe_adma_desc_slot *iter = tdesc-group_head;
 + int i = 0;
 +
 + if (entry_idx  0 || entry_idx = (tdesc-src_cnt + tdesc-dst_cnt)) {
 + printk(%s: entry_idx %d, src_cnt %d, dst_cnt %d\n,
 +__func__, entry_idx, tdesc-src_cnt, tdesc-dst_cnt);
 + BUG();
 + }
 +
 + list_for_each_entry(iter, tdesc-group_list, chain_node) {
 + if (i++ == entry_idx)
 + break;
 + }
 + return iter;
 +}

This is a header file, yet you add here literally thousands of lines of
code.


Note that more or less similar questions have been asked for the
previous version of this patch, but I fail to find any good
justification in your replies.


Selecting the architecture at build time is bad as it prevents using a
sinlge kernel image across a wide range of 

Re: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by page

2010-09-30 Thread Grant Likely
On Fri, Oct 1, 2010 at 12:06 AM, Anton Vorontsov cbouatmai...@gmail.com wrote:
 On Thu, Sep 30, 2010 at 11:41:40PM +0900, Grant Likely wrote:
 On Thu, Sep 30, 2010 at 11:16 PM, Grant Likely
 grant.lik...@secretlab.ca wrote:
  On Thu, Sep 30, 2010 at 7:46 PM, David Brownell davi...@pacbell.net 
  wrote:
 
  --- On Thu, 9/30/10, Mingkai Hu mingkai...@freescale.com wrote:
 
  From: Mingkai Hu mingkai...@freescale.com
  Subject: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by 
  page
 
  NAK.
 
  We went over this before.
 
  Yes, I agree with David on this.  If large transfers don't work, then
  it is the SPI master driver that is buggy.

 By the way, does this fix your problem?

 https://patchwork.kernel.org/patch/184752/

 It shouldn't. AFAIK, eSPI is PIO-only controller, and the overrun
 fix is for the DMA mode.

 Thanks,

 p.s. Btw, in patch 3/7, is_dma_mapped argument of fsl_espi_bufs()
 is unneeded.

Thanks Anton.  Please reply to that patch with this comment so that
patchwork records it and I don't forget about it.

Thanks,
g.


 --
 Anton Vorontsov
 email: cbouatmai...@gmail.com
 irc://irc.freenode.net/bd2




-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v3 5/7] mtd: m25p80: add support to parse the SPI flash's partitions

2010-09-30 Thread Grant Likely
On Thu, Sep 30, 2010 at 5:00 PM, Mingkai Hu mingkai...@freescale.com wrote:
 Signed-off-by: Mingkai Hu mingkai...@freescale.com
 ---
 v3:
  - Move the SPI flash partition code to the probe function.

  drivers/mtd/devices/m25p80.c |   39 +++
  1 files changed, 27 insertions(+), 12 deletions(-)

 diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
 index 6f512b5..47d53c7 100644
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 @@ -772,7 +772,7 @@ static const struct spi_device_id *__devinit 
 jedec_probe(struct spi_device *spi)
  static int __devinit m25p_probe(struct spi_device *spi)
  {
        const struct spi_device_id      *id = spi_get_device_id(spi);
 -       struct flash_platform_data      *data;
 +       struct flash_platform_data      data, *pdata;
        struct m25p                     *flash;
        struct flash_info               *info;
        unsigned                        i;
 @@ -782,13 +782,27 @@ static int __devinit m25p_probe(struct spi_device *spi)
         * a chip ID, try the JEDEC id commands; they'll work for most
         * newer chips, even if we don't recognize the particular chip.
         */
 -       data = spi-dev.platform_data;
 -       if (data  data-type) {
 +       pdata = spi-dev.platform_data;
 +       if (!pdata  spi-dev.of_node) {
 +               int nr_parts;
 +               struct mtd_partition *parts;
 +               struct device_node *np = spi-dev.of_node;
 +
 +               nr_parts = of_mtd_parse_partitions(spi-dev, np, parts);
 +               if (nr_parts) {
 +                       pdata = data;
 +                       memset(pdata, 0, sizeof(*pdata));
 +                       pdata-parts = parts;
 +                       pdata-nr_parts = nr_parts;
 +               }
 +       }

Yes, this is the correct way to go about adding the partitions.
However, this patch can be made simpler by not renaming 'data' to
'pdata' and by moving the above code down to just before the partition
information is actually used.  in the OF case, only the parts and the
nr_parts values written into data, and those values aren't used until
the last part of the probe function.

Regardless, in principle this patch is correct:

Acked-by: Grant Likely grant.lik...@secretlab.ca

 +
 +       if (pdata  pdata-type) {
                const struct spi_device_id *plat_id;

                for (i = 0; i  ARRAY_SIZE(m25p_ids) - 1; i++) {
                        plat_id = m25p_ids[i];
 -                       if (strcmp(data-type, plat_id-name))
 +                       if (strcmp(pdata-type, plat_id-name))
                                continue;
                        break;
                }
 @@ -796,7 +810,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
                if (i  ARRAY_SIZE(m25p_ids) - 1)
                        id = plat_id;
                else
 -                       dev_warn(spi-dev, unrecognized id %s\n, 
 data-type);
 +                       dev_warn(spi-dev, unrecognized id %s\n,
 +                                       pdata-type);
        }

        info = (void *)id-driver_data;
 @@ -847,8 +862,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
                write_sr(flash, 0);
        }

 -       if (data  data-name)
 -               flash-mtd.name = data-name;
 +       if (pdata  pdata-name)
 +               flash-mtd.name = pdata-name;
        else
                flash-mtd.name = dev_name(spi-dev);

 @@ -919,9 +934,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
                                        part_probes, parts, 0);
                }

 -               if (nr_parts = 0  data  data-parts) {
 -                       parts = data-parts;
 -                       nr_parts = data-nr_parts;
 +               if (nr_parts = 0  pdata  pdata-parts) {
 +                       parts = pdata-parts;
 +                       nr_parts = pdata-nr_parts;
                }

As per my comment earlier; since parts and nr_parts isn't needed
before this point, this block could simply be:

if (nr_parts = 0  data  data-parts) {
parts = data-parts;
nr_parts = data-nr_parts;
}
if (nr_parts = 0  spi-dev.of_node)
        nr_parts = of_mtd_parse_partitions(spi-dev, np, parts);

And most of the other changes to this file goes away.  Simpler, yes?

g.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v3 6/7] mtd: m25p80: add a read function to read page by page

2010-09-30 Thread Grant Likely
Hmmm for some reason the previous replies didn't get picked up by
patchwork, so I'm replying with my comment again for the public
record.

In this case the eSPI controller driver is buggy and needs to be
fixed.  If the hardware can only support small transfers, then it is
the responsibilty of the driver to chain up smaller chunks into one
big transfer, and make sure that the CS line doesn't go low in the
middle of it.

g.

On Thu, Sep 30, 2010 at 5:00 PM, Mingkai Hu mingkai...@freescale.com wrote:
 For Freescale's eSPI controller, the max transaction length one time
 is limitted by the SPCOM[TRANSLEN] field which is 0x. When used
 mkfs.ext2 command to create ext2 filesystem on the flash, the read
 length will exceed the max value of the SPCOM[TRANSLEN] field, so
 change the read function to read page by page.

 For other SPI flash driver, also needed to supply the read function
 if used the eSPI controller.

 Signed-off-by: Mingkai Hu mingkai...@freescale.com
 ---
 v3:
  - Add a quirks member for the SPI master to handle the contrains of the
   SPI controller. I can't think of other method. :-(

  drivers/mtd/devices/m25p80.c |   78 
 ++
  drivers/spi/spi_fsl_lib.c    |    4 ++
  include/linux/spi/spi.h      |    5 +++
  3 files changed, 87 insertions(+), 0 deletions(-)

 diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
 index 47d53c7..f65cca8 100644
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
 @@ -377,6 +377,81 @@ static int m25p80_read(struct mtd_info *mtd, loff_t 
 from, size_t len,
  }

  /*
 + * Read an address range from the flash chip page by page.
 + * Some controller has transaction length limitation such as the
 + * Freescale's eSPI controller can only trasmit 0x bytes one
 + * time, so we have to read page by page if the len is more than
 + * the limitation.
 + */
 +static int m25p80_page_read(struct mtd_info *mtd, loff_t from, size_t len,
 +       size_t *retlen, u_char *buf)
 +{
 +       struct m25p *flash = mtd_to_m25p(mtd);
 +       struct spi_transfer t[2];
 +       struct spi_message m;
 +       u32 i, page_size = 0;
 +
 +       DEBUG(MTD_DEBUG_LEVEL2, %s: %s %s 0x%08x, len %zd\n,
 +                       dev_name(flash-spi-dev), __func__, from,
 +                       (u32)from, len);
 +
 +       /* sanity checks */
 +       if (!len)
 +               return 0;
 +
 +       if (from + len  flash-mtd.size)
 +               return -EINVAL;
 +
 +       spi_message_init(m);
 +       memset(t, 0, (sizeof t));
 +
 +       /* NOTE:
 +        * OPCODE_FAST_READ (if available) is faster.
 +        * Should add 1 byte DUMMY_BYTE.
 +        */
 +       t[0].tx_buf = flash-command;
 +       t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE;
 +       spi_message_add_tail(t[0], m);
 +
 +       t[1].rx_buf = buf;
 +       spi_message_add_tail(t[1], m);
 +
 +       /* Byte count starts at zero. */
 +       if (retlen)
 +               *retlen = 0;
 +
 +       mutex_lock(flash-lock);
 +
 +       /* Wait till previous write/erase is done. */
 +       if (wait_till_ready(flash)) {
 +               /* REVISIT status return?? */
 +               mutex_unlock(flash-lock);
 +               return 1;
 +       }
 +
 +       /* Set up the write data buffer. */
 +       flash-command[0] = OPCODE_READ;
 +
 +       for (i = page_size; i  len; i += page_size) {
 +               page_size = len - i;
 +               if (page_size  flash-page_size)
 +                       page_size = flash-page_size;
 +               m25p_addr2cmd(flash, from + i, flash-command);
 +               t[1].len = page_size;
 +               t[1].rx_buf = buf + i;
 +
 +               spi_sync(flash-spi, m);
 +
 +               *retlen += m.actual_length - m25p_cmdsz(flash)
 +                       - FAST_READ_DUMMY_BYTE;
 +       }
 +
 +       mutex_unlock(flash-lock);
 +
 +       return 0;
 +}
 +
 +/*
  * Write an address range to the flash chip.  Data must be written in
  * FLASH_PAGESIZE chunks.  The address range may be any size provided
  * it is within the physical boundaries.
 @@ -874,6 +949,9 @@ static int __devinit m25p_probe(struct spi_device *spi)
        flash-mtd.erase = m25p80_erase;
        flash-mtd.read = m25p80_read;

 +       if (spi-master-quirks  SPI_QUIRK_TRANS_LEN_LIMIT)
 +               flash-mtd.read = m25p80_page_read;
 +
        /* sst flash chips use AAI word program */
        if (info-jedec_id  16 == 0xbf)
                flash-mtd.write = sst_write;
 diff --git a/drivers/spi/spi_fsl_lib.c b/drivers/spi/spi_fsl_lib.c
 index 5cd741f..c8d8c2d 100644
 --- a/drivers/spi/spi_fsl_lib.c
 +++ b/drivers/spi/spi_fsl_lib.c
 @@ -135,6 +135,10 @@ int mpc8xxx_spi_probe(struct device *dev, struct 
 resource *mem,
        master-cleanup = mpc8xxx_spi_cleanup;
        master-dev.of_node = dev-of_node;

 +       if (of_get_property(dev-of_node,
 +                               fsl,spi-quirk-trans-len-limit, NULL))
 +          

[PATCH v4 2/4] fsldma: implement support for scatterlist to scatterlist copy

2010-09-30 Thread Ira W. Snyder
Now that the DMAEngine API has support for scatterlist to scatterlist
copy, implement support for the Freescale DMA controller.

Signed-off-by: Ira W. Snyder i...@ovro.caltech.edu
---
 drivers/dma/fsldma.c |  128 -
 1 files changed, 125 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index cea08be..1ed29d1 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -38,6 +38,8 @@
 #include asm/fsldma.h
 #include fsldma.h
 
+static const char msg_ld_oom[] = No free memory for link descriptor\n;
+
 static void dma_init(struct fsldma_chan *chan)
 {
/* Reset the channel */
@@ -499,7 +501,7 @@ fsl_dma_prep_interrupt(struct dma_chan *dchan, unsigned 
long flags)
 
new = fsl_dma_alloc_descriptor(chan);
if (!new) {
-   dev_err(chan-dev, No free memory for link descriptor\n);
+   dev_err(chan-dev, msg_ld_oom);
return NULL;
}
 
@@ -536,8 +538,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
/* Allocate the link descriptor from DMA pool */
new = fsl_dma_alloc_descriptor(chan);
if (!new) {
-   dev_err(chan-dev,
-   No free memory for link descriptor\n);
+   dev_err(chan-dev, msg_ld_oom);
goto fail;
}
 #ifdef FSL_DMA_LD_DEBUG
@@ -583,6 +584,125 @@ fail:
return NULL;
 }
 
+static struct dma_async_tx_descriptor *fsl_dma_prep_sg(struct dma_chan *dchan,
+   struct scatterlist *dst_sg, unsigned int dst_nents,
+   struct scatterlist *src_sg, unsigned int src_nents,
+   unsigned long flags)
+{
+   struct fsl_desc_sw *first = NULL, *prev = NULL, *new = NULL;
+   struct fsldma_chan *chan = to_fsl_chan(dchan);
+   size_t dst_avail, src_avail;
+   dma_addr_t dst, src;
+   size_t len;
+
+   /* basic sanity checks */
+   if (dst_nents == 0 || src_nents == 0)
+   return NULL;
+
+   if (dst_sg == NULL || src_sg == NULL)
+   return NULL;
+
+   /*
+* TODO: should we check that both scatterlists have the same
+* TODO: number of bytes in total? Is that really an error?
+*/
+
+   /* get prepared for the loop */
+   dst_avail = sg_dma_len(dst_sg);
+   src_avail = sg_dma_len(src_sg);
+
+   /* run until we are out of scatterlist entries */
+   while (true) {
+
+   /* create the largest transaction possible */
+   len = min_t(size_t, src_avail, dst_avail);
+   len = min_t(size_t, len, FSL_DMA_BCR_MAX_CNT);
+   if (len == 0)
+   goto fetch;
+
+   dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) - dst_avail;
+   src = sg_dma_address(src_sg) + sg_dma_len(src_sg) - src_avail;
+
+   /* allocate and populate the descriptor */
+   new = fsl_dma_alloc_descriptor(chan);
+   if (!new) {
+   dev_err(chan-dev, msg_ld_oom);
+   goto fail;
+   }
+#ifdef FSL_DMA_LD_DEBUG
+   dev_dbg(chan-dev, new link desc alloc %p\n, new);
+#endif
+
+   set_desc_cnt(chan, new-hw, len);
+   set_desc_src(chan, new-hw, src);
+   set_desc_dst(chan, new-hw, dst);
+
+   if (!first)
+   first = new;
+   else
+   set_desc_next(chan, prev-hw, new-async_tx.phys);
+
+   new-async_tx.cookie = 0;
+   async_tx_ack(new-async_tx);
+   prev = new;
+
+   /* Insert the link descriptor to the LD ring */
+   list_add_tail(new-node, first-tx_list);
+
+   /* update metadata */
+   dst_avail -= len;
+   src_avail -= len;
+
+fetch:
+   /* fetch the next dst scatterlist entry */
+   if (dst_avail == 0) {
+
+   /* no more entries: we're done */
+   if (dst_nents == 0)
+   break;
+
+   /* fetch the next entry: if there are no more: done */
+   dst_sg = sg_next(dst_sg);
+   if (dst_sg == NULL)
+   break;
+
+   dst_nents--;
+   dst_avail = sg_dma_len(dst_sg);
+   }
+
+   /* fetch the next src scatterlist entry */
+   if (src_avail == 0) {
+
+   /* no more entries: we're done */
+   if (src_nents == 0)
+   break;
+
+   /* fetch the next entry: if there are no more: done */
+   src_sg = sg_next(src_sg);
+   if (src_sg == NULL)
+   break;
+
+   

[PATCH v4 0/4] dma: add support for scatterlist to scatterlist copy

2010-09-30 Thread Ira W. Snyder
This series adds support for scatterlist to scatterlist copies to the
generic DMAEngine API. Both the fsldma and ste_dma40 drivers currently
implement a similar API using different, non-generic methods. This series
converts both of them to the new, standardized API.

By doing this as part of the core DMAEngine API, the individual drivers
have control over how to chain their descriptors together. In addition,
this makes graceful failure much easier to support.

The fsldma implementation has been tested on real hardware, using slightly
modified versions of the patches posted a few weeks ago, titled:
[PATCH RFCv2 0/5] CARMA Board Support

These patches will be re-submitted with the appropriate changes after we're
happy with this series.

Thanks to all that provided input!
Ira

Changes since v3:
- ste40_dma's implementation now returns NULL (thanks Dan!)
- fsldma now uses a custom command for external control
- fsldma now uses the standard struct dma_slave_config
- tested on real hardware

Ira W. Snyder (4):
  dma: add support for scatterlist to scatterlist copy
  fsldma: implement support for scatterlist to scatterlist copy
  fsldma: improved DMA_SLAVE support
  ste_dma40: implement support for scatterlist to scatterlist copy

 arch/powerpc/include/asm/fsldma.h |  137 ---
 drivers/dma/dmaengine.c   |2 +
 drivers/dma/fsldma.c  |  328 ++---
 drivers/dma/ste_dma40.c   |   17 ++
 include/linux/dmaengine.h |9 +
 5 files changed, 184 insertions(+), 309 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/fsldma.h

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v4 3/4] fsldma: improved DMA_SLAVE support

2010-09-30 Thread Ira W. Snyder
Now that the generic DMAEngine API has support for scatterlist to
scatterlist copying, the device_prep_slave_sg() portion of the
DMA_SLAVE API is no longer necessary and has been removed.

However, the device_control() portion of the DMA_SLAVE API is still
useful to control device specific parameters, such as externally
controlled DMA transfers and maximum burst length.

A special dma_ctrl_cmd has been added to enable externally controlled
DMA transfers. This is currently specific to the Freescale DMA
controller, but can easily be made generic when another user is found.

Signed-off-by: Ira W. Snyder i...@ovro.caltech.edu
---
 arch/powerpc/include/asm/fsldma.h |  137 --
 drivers/dma/fsldma.c  |  226 +++-
 include/linux/dmaengine.h |3 +
 3 files changed, 47 insertions(+), 319 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/fsldma.h

diff --git a/arch/powerpc/include/asm/fsldma.h 
b/arch/powerpc/include/asm/fsldma.h
deleted file mode 100644
index debc5ed..000
--- a/arch/powerpc/include/asm/fsldma.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Freescale MPC83XX / MPC85XX DMA Controller
- *
- * Copyright (c) 2009 Ira W. Snyder i...@ovro.caltech.edu
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed as is without any warranty of any
- * kind, whether express or implied.
- */
-
-#ifndef __ARCH_POWERPC_ASM_FSLDMA_H__
-#define __ARCH_POWERPC_ASM_FSLDMA_H__
-
-#include linux/slab.h
-#include linux/dmaengine.h
-
-/*
- * Definitions for the Freescale DMA controller's DMA_SLAVE implemention
- *
- * The Freescale DMA_SLAVE implementation was designed to handle many-to-many
- * transfers. An example usage would be an accelerated copy between two
- * scatterlists. Another example use would be an accelerated copy from
- * multiple non-contiguous device buffers into a single scatterlist.
- *
- * A DMA_SLAVE transaction is defined by a struct fsl_dma_slave. This
- * structure contains a list of hardware addresses that should be copied
- * to/from the scatterlist passed into device_prep_slave_sg(). The structure
- * also has some fields to enable hardware-specific features.
- */
-
-/**
- * struct fsl_dma_hw_addr
- * @entry: linked list entry
- * @address: the hardware address
- * @length: length to transfer
- *
- * Holds a single physical hardware address / length pair for use
- * with the DMAEngine DMA_SLAVE API.
- */
-struct fsl_dma_hw_addr {
-   struct list_head entry;
-
-   dma_addr_t address;
-   size_t length;
-};
-
-/**
- * struct fsl_dma_slave
- * @addresses: a linked list of struct fsl_dma_hw_addr structures
- * @request_count: value for DMA request count
- * @src_loop_size: setup and enable constant source-address DMA transfers
- * @dst_loop_size: setup and enable constant destination address DMA transfers
- * @external_start: enable externally started DMA transfers
- * @external_pause: enable externally paused DMA transfers
- *
- * Holds a list of address / length pairs for use with the DMAEngine
- * DMA_SLAVE API implementation for the Freescale DMA controller.
- */
-struct fsl_dma_slave {
-
-   /* List of hardware address/length pairs */
-   struct list_head addresses;
-
-   /* Support for extra controller features */
-   unsigned int request_count;
-   unsigned int src_loop_size;
-   unsigned int dst_loop_size;
-   bool external_start;
-   bool external_pause;
-};
-
-/**
- * fsl_dma_slave_append - add an address/length pair to a struct fsl_dma_slave
- * @slave: the struct fsl_dma_slave to add to
- * @address: the hardware address to add
- * @length: the length of bytes to transfer from @address
- *
- * Add a hardware address/length pair to a struct fsl_dma_slave. Returns 0 on
- * success, -ERRNO otherwise.
- */
-static inline int fsl_dma_slave_append(struct fsl_dma_slave *slave,
-  dma_addr_t address, size_t length)
-{
-   struct fsl_dma_hw_addr *addr;
-
-   addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
-   if (!addr)
-   return -ENOMEM;
-
-   INIT_LIST_HEAD(addr-entry);
-   addr-address = address;
-   addr-length = length;
-
-   list_add_tail(addr-entry, slave-addresses);
-   return 0;
-}
-
-/**
- * fsl_dma_slave_free - free a struct fsl_dma_slave
- * @slave: the struct fsl_dma_slave to free
- *
- * Free a struct fsl_dma_slave and all associated address/length pairs
- */
-static inline void fsl_dma_slave_free(struct fsl_dma_slave *slave)
-{
-   struct fsl_dma_hw_addr *addr, *tmp;
-
-   if (slave) {
-   list_for_each_entry_safe(addr, tmp, slave-addresses, entry) {
-   list_del(addr-entry);
-   kfree(addr);
-   }
-
-   kfree(slave);
-   }
-}
-
-/**
- * fsl_dma_slave_alloc - allocate a struct fsl_dma_slave
- * @gfp: the flags to pass to kmalloc when 

Re: [PATCH] PPC4xx: ADMA separating SoC specific functions

2010-09-30 Thread Dan Williams
On Thu, Sep 30, 2010 at 12:08 PM, Wolfgang Denk w...@denx.de wrote:
[snip other valid review comments]

 This is a header file, yet you add here literally thousands of lines of
 code.

Yes, these functions are entirely too large to be inlined.  It looks
like you are trying to borrow too heavily from the iop-adma model.
The differences between iop13xx and iop33x from a adma perspective are
just in descriptor format and channel capabilities.  If you look at
the routines implemented in:
arch/arm/include/asm/hardware/iop3xx-adma.h
arch/arm/mach-iop13xx/include/mach/adma.h
...they are just simple helpers that abstract the descriptor details.
For example:

iop_adma_prep_dma_xor()
{
[snip]
spin_lock_bh(iop_chan-lock);
slot_cnt = iop_chan_xor_slot_count(len, src_cnt, slots_per_op);
sw_desc = iop_adma_alloc_slots(iop_chan, slot_cnt, slots_per_op);
if (sw_desc) {
grp_start = sw_desc-group_head;
iop_desc_init_xor(grp_start, src_cnt, flags);
iop_desc_set_byte_count(grp_start, iop_chan, len);
iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest);
sw_desc-unmap_src_cnt = src_cnt;
sw_desc-unmap_len = len;
sw_desc-async_tx.flags = flags;
while (src_cnt--)
iop_desc_set_xor_src_addr(grp_start, src_cnt,
  dma_src[src_cnt]);
}
spin_unlock_bh(iop_chan-lock);

return sw_desc ? sw_desc-async_tx : NULL;
}

Where  iop_adma_alloc_slots() is implemented differently between
iop13xx and iop3xx.  In this case why does ppc440spe-adma.h exist?  If
it has code specific to ppe440spe it should just live in the ppe440spe
C file.  If it is truly generic it should move to the base adma.c
implementation.  If you want to reuse a ppe440spe routine just link to
it.

 Selecting the architecture at build time is bad as it prevents using a
 sinlge kernel image across a wide range of boards.  You only replied
 We select the architecture at build time. without any explanation if
 there is a pressing technical reason to do it this way, or if this was
 just a arbitrary decision.

I agree I have yet to see any indication that this driver needs to
have an architecture selected at build time.

A potential compromise a first step would be to have a common C file
that is shared between two driver modules until such point that they
can be unified into a common module.

--
Dan
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


RE: [PATCH] PPC4xx: ADMA separating SoC specific functions

2010-09-30 Thread Tirumala Marri

 When reposting a patch, please always indicate that this is new
 version by using something like [PATCH v2] in the Subject line.
[Marri] I know, but this patch is not modification of previous patch.
It is complete brand new from scratch again. In that case isn't this
 will be first version ?


  ---

 Also, please include here (i. e. below the --- line, i. e. in the
 comments section, a description of what was changed compared to the
 previous version of this patch.

 As is, you enforce us to rescan the whole patch again and check
 manually if you have reacted to any of the comments sent before, and
 how.  As is, you make reviewing your poatches harder than necessary.

[Marri} I will include comments in the further versions of this patch.



  diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c
  index 0d58a4a..a1053cb 100644
  --- a/drivers/dma/ppc4xx/adma.c
  +++ b/drivers/dma/ppc4xx/adma.c
 ...
  +#include ppc440spe-adma.h
  +
  +struct dma_async_tx_descriptor
  +*ppc440spe_adma_prep_dma_pq(struct dma_chan *chan,
  +  dma_addr_t * dst,
  +  dma_addr_t * src,
  +  unsigned int src_cnt,
  +  const unsigned char *scf,
  +  size_t len,
  +  unsigned long flags);
  +struct dma_async_tx_descriptor
  +*ppc440spe_adma_prep_dma_pqzero_sum(struct dma_chan *chan,

 Should such 440SPe specific code not be removed here and placed into
 ppc440spe-adma.c instead?
[Marri] It is 440SPe specific. Definition is moved ppc440spe-adma.c



  +#if 0
   static void prep_dma_pq_dbg(int id, dma_addr_t *dst, dma_addr_t
 *src,
  unsigned int src_cnt)
   {
  @@ -213,8 +104,9 @@ static void prep_dma_pq_dbg(int id, dma_addr_t
 *dst, dma_addr_t *src,
  for (i = 0; i  2; i++)
  pr_debug(\t0x%016llx , dst[i]);
   }
  +#endif

 Please do not add dead code - remove the whole #if 0 block.
[Marri] Will remove it.


 ***/

 It seems youremove all code, but leave the (now empty) comment
 headers? This makes little sense to me.

[Marri] Will clean up in the next version.
 ...
   /**
* ppc440spe_adma_free_slots - flags descriptor slots for reuse
* @slot: Slot to free
* Caller must hold ppc440spe_chan-lock while calling this
 function
*/

 Again, all this is pretty low-level 440SPe specific code. Why do you
 keep this in the common drive rfile instead of moving it into the new
 440SPe specific file?
[Marri]. With name change it can be used With any SoC ADMA driver.




  diff --git a/drivers/dma/ppc4xx/ppc440spe-adma.c
 b/drivers/dma/ppc4xx/ppc440spe-adma.c
  new file mode 100644
  index 000..da467b4
 ...
  +   /*  In the current implementation of ppc440spe ADMA driver it
  +
  +
  +
  +* makes sense to pick out only pq case, because it may be

 Formatting problems?
[Marri] Will fix in next version.



  diff --git a/drivers/dma/ppc4xx/ppc440spe-adma.h
 b/drivers/dma/ppc4xx/ppc440spe-adma.h
  new file mode 100644
  index 000..81a1f46
  --- /dev/null
  +++ b/drivers/dma/ppc4xx/ppc440spe-adma.h
 ...
  +/*
  + * ppc440spe_get_group_entry - get group entry with index idx
  + * @tdesc: is the last allocated slot in the group.
  + */
  +static struct ppc440spe_adma_desc_slot
 *ppc440spe_get_group_entry(struct
  +
ppc440spe_adma_desc_slot
  +   *tdesc,
  +   u32 entry_idx)
  +{
  +   struct ppc440spe_adma_desc_slot *iter = tdesc-group_head;
  +   int i = 0;
  +
  +   if (entry_idx  0 || entry_idx = (tdesc-src_cnt + tdesc-
 dst_cnt)) {
  +   printk(%s: entry_idx %d, src_cnt %d, dst_cnt %d\n,
  +  __func__, entry_idx, tdesc-src_cnt, tdesc-
 dst_cnt);
  +   BUG();
  +   }
  +
  +   list_for_each_entry(iter, tdesc-group_list, chain_node) {
  +   if (i++ == entry_idx)
  +   break;
  +   }
  +   return iter;
  +}

 This is a header file, yet you add here literally thousands of lines of
 code.


 Note that more or less similar questions have been asked for the
 previous version of this patch, but I fail to find any good
 justification in your replies.
[Marri] Reason for some functions in lined is 1) They are small enough
To be in lined 2) If keep them in ppc440spe-adma.c I will have to make
them
Non static to avoid Used but not defined warnings. With too many
functions
Non static might cause name space pollution in the kernel ?



 Selecting the architecture at build time is bad as it prevents using a
 sinlge kernel image across a wide range of boards.  You only replied
 We select the architecture at build time. without any explanation if
 there is a pressing technical reason to do it this way, or if this was
 just a arbitrary decision.
[Marri] Build time separation is only for entirely different SoC DMA
engine.
For example 440spe and 460sx has engierely different DMA 

RE: [PATCH] PPC4xx: ADMA separating SoC specific functions

2010-09-30 Thread Tirumala Marri
 On Thu, Sep 30, 2010 at 12:08 PM, Wolfgang Denk w...@denx.de wrote:
 [snip other valid review comments]
 
  This is a header file, yet you add here literally thousands of lines
 of
  code.

 Yes, these functions are entirely too large to be inlined.  It looks
 like you are trying to borrow too heavily from the iop-adma model.
 The differences between iop13xx and iop33x from a adma perspective are
 just in descriptor format and channel capabilities.  If you look at
 the routines implemented in:
 arch/arm/include/asm/hardware/iop3xx-adma.h
 arch/arm/mach-iop13xx/include/mach/adma.h
 ...they are just simple helpers that abstract the descriptor details.
 For example:

 iop_adma_prep_dma_xor()
 {
 [snip]
 spin_lock_bh(iop_chan-lock);
 slot_cnt = iop_chan_xor_slot_count(len, src_cnt,
 slots_per_op);
 sw_desc = iop_adma_alloc_slots(iop_chan, slot_cnt,
 slots_per_op);
 if (sw_desc) {
 grp_start = sw_desc-group_head;
 iop_desc_init_xor(grp_start, src_cnt, flags);
 iop_desc_set_byte_count(grp_start, iop_chan, len);
 iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest);
 sw_desc-unmap_src_cnt = src_cnt;
 sw_desc-unmap_len = len;
 sw_desc-async_tx.flags = flags;
 while (src_cnt--)
 iop_desc_set_xor_src_addr(grp_start, src_cnt,
   dma_src[src_cnt]);
 }
 spin_unlock_bh(iop_chan-lock);

 return sw_desc ? sw_desc-async_tx : NULL;
 }

 Where  iop_adma_alloc_slots() is implemented differently between
 iop13xx and iop3xx.  In this case why does ppc440spe-adma.h exist?  If
 it has code specific to ppe440spe it should just live in the ppe440spe
 C file.  If it is truly generic it should move to the base adma.c
 implementation.  If you want to reuse a ppe440spe routine just link to
 it.
[Marri]That is how I started changing the code. And I see tons of warnings
Saying Used but not defined or Defined but not used. How should I
suppress
Some functions from adma.c are used in ppc440spe-adma.c and some from
ppc440spe-adma.c
Are used in adma.c. So I created intermediate file ppc440spe-adma.h with
inlined
Functions. In future this will be converted into ppc4xx_adma.h and move
existing
SoC specific stuff to ppc440spe-adma.c file.


  Selecting the architecture at build time is bad as it prevents using
 a
  sinlge kernel image across a wide range of boards.  You only replied
  We select the architecture at build time. without any explanation
 if
  there is a pressing technical reason to do it this way, or if this
 was
  just a arbitrary decision.

 I agree I have yet to see any indication that this driver needs to
 have an architecture selected at build time.

 A potential compromise a first step would be to have a common C file
 that is shared between two driver modules until such point that they
 can be unified into a common module.

As I responded to Mr. Wolfgang in previous email, similar SoC DMA engines
will
Be resolved at run time. Whereas completely different architectures will
be
Resolved at build time.

Regards,
Marri
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH] PPC4xx: ADMA separating SoC specific functions

2010-09-30 Thread Dan Williams
[ adding Greg ]

On Thu, Sep 30, 2010 at 5:16 PM, Tirumala Marri tma...@apm.com wrote:
 Where  iop_adma_alloc_slots() is implemented differently between
 iop13xx and iop3xx.  In this case why does ppc440spe-adma.h exist?  If
 it has code specific to ppe440spe it should just live in the ppe440spe
 C file.  If it is truly generic it should move to the base adma.c
 implementation.  If you want to reuse a ppe440spe routine just link to
 it.
 [Marri]That is how I started changing the code. And I see tons of warnings
 Saying Used but not defined or Defined but not used. How should I
 suppress
 Some functions from adma.c are used in ppc440spe-adma.c and some from
 ppc440spe-adma.c
 Are used in adma.c.

This is part of defining a common interface.  Maybe look at the
linkages of how the common ioat_probe() routine is used to support all
three versions of its dma hardware.

 So I created intermediate file ppc440spe-adma.h with
 inlined
 Functions. In future this will be converted into ppc4xx_adma.h and move
 existing
 SoC specific stuff to ppc440spe-adma.c file.

You definitely need to be able to resolve used but not defined and
defined but not used warnings before tackling a driver conversion
like this.  In light of this comment I wonder if it would be
appropriate to submit your original driver, that just duplicated
routines from the ppc440spe driver, to the -staging tree.  Then it
would be available for someone familiar with driver conversions to
take a shot at unifying.

Greg, is this an appropriate use of -staging?

--
Dan
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev