Re: [PATCH] spi: add spi controller master driver for Blackfin 6xx processor

2013-06-03 Thread Scott Jiang
2013/6/3 Viresh Kumar :
> On Tue, Jun 4, 2013 at 3:13 AM, Scott Jiang  
> wrote:
>> diff --git a/drivers/spi/spi-bfin6xx.c b/drivers/spi/spi-bfin6xx.c
>
>> +#include 
>
> Why do you need this?

Sorry, I forgot to remove this line when I converted to core queuing.

--
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


[PATCH V3] spi: Add SPI mux core and GPIO-based mux driver

2013-06-03 Thread Dries Van Puymbroeck
This patch contains the core functionality for a multiplexer on an
SPI bus. This can be useful if a board requires more SPI devices,
and thus more chip selects, than the SPI controller on the processor
has available.

The mux device is added in the device tree as a child node of the
SPI master. Then, devices can be added as children of the mux node.
The mux will appear as if it was a SPI master device, and child
nodes will appear as chip selects on the mux bus. A bindings file is
provided for the device tree bindings.

This patch also includes a driver for a GPIO-based multiplexer, which
makes use of the core code, as an example for others to follow when
implementing their own SPI mux.  A bindings file for the GPIO
implementation is also provided for the device tree bindings.

Signed-off-by: Dries Van Puymbroeck 
Tested-by: Dan Donahue 
---

Hi,

This is a re-submit from a previous patch.
The previous submit of this version (V2) can be found at
http://permalink.gmane.org/gmane.linux.kernel.spi.devel/13590
V1 and discussion about it on which the changes for V2 were based can be
found at http://comments.gmane.org/gmane.linux.kernel.spi.devel/12868

We've tested the core driver a bit more now, fixed 2 bugs, and removed all use
of the max speed setting of the mux. See the changelog for an overview.

I hope there is still interest in getting this to mainline? I'm still looking
forward to feedback on the changes, and if any more work is required. Let me
know also if I messed something up on the previous submits or if they just got
missed?

Thanks,

Dries Van Puymbroeck.

Change log:

Changes w.r.t. V2:
 - At driver startup, the mux would be set to "channel 0," but the child device
   settings were not copied. Fixed by adding a SPI_MUX_NO_CS define, which is
   used as the default now.

 - Compare of child max speed with mux max speed removed, as we've discussed
   that a max speed for the mux makes little sense. The DT property is still
   needed for the check in spi.c to pass, but the value is no longer used in
   the mux driver code.

 - Bug fixed which caused the lowest speed amongst all child devices to be used
   for each child device.

Changes w.r.t. V1:
 - Split the core mux functionality and the specific mux code. Core
   functionality now is in spi-mux.c, while the actual mux we use is
   in spi-barco-orka-mux-gpio.c. Using the latter as an example,
   other users should be able to add different mux implementations,
   reusing the parts in the core. spi-mux.h is also provided to be
   in include/linux/spi/

 - Changed the compatible string of the specific mux implementation
   to "barco,orka-spi-mux-gpio"

 - Changed device tree property "mux-gpios" to "gpios"

 - Changed the spi_mux_transfer_one_message and spi_mux_complete_cb
   functions according to feedback from Grant Likely: removed the
   wait queue, and call the spi_finalize_current_message call
   directly from the spi_mux_complete_cb. This removes xfer_complete
   and xfer_complete_wq, and moves child_mesg_complete
   child_mesg_context and child_mesg_dev into spi_mux_priv.

 - Renamed some structs and functions to be more in line with the
   naming in the code for I2C muxes.

 - Joined the spi_mux_gpio_probe_dt function with the
   spi_mux_gpio_probe function (and renamed to spi_add_mux)

 - Removed the values array per chip select in the specific mux code.
   The reg property is now directly used as chip select and bit mask
   for the gpio mux. (This also removes a bug where the values array
   was incorrectly allocated for sparse CS's

 - Removed of_match_ptr since driver is DT only.

Not changed w.r.t. V1:
 - spi-max-frequency is still a required DT property, even for the
   gpio mux, though it does not mean anything there. However, the
   check for this mandatory property is done by the spi core, before
   the probe function of the mux is called. This means that the mux
   code cannot get the property from its child devices before the
   check is done (and right now the core aborts the initialization if
   spi-max-frequency is not set). The only solution I see is to loosen
   the check in spi core, or requiring that muxes have this property
   too, even if it does not have meaning. If anyone has some ideas
   about this, I would appreciate them!
---
 .../bindings/spi/barco-orka-spi-mux-gpio.txt   |   35 
 Documentation/devicetree/bindings/spi/spi-mux.txt  |  106 ++
 drivers/spi/Kconfig|   96 -
 drivers/spi/Makefile   |   12 +-
 drivers/spi/spi-barco-orka-mux-gpio.c  |  142 +
 drivers/spi/spi-mux.c  |  219 
 include/linux/spi/spi-mux.h|   58 ++
 7 files changed, 607 insertions(+), 61 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/spi/barco-orka-spi-mux-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mux.txt
 create 

[SPAM] Ответ на:Каким образом обезопасить свой бизнес?

2013-06-03 Thread Жаннета
Здpавствуйте!

Отчет  на 512 cтpаницаx + СД c  oбpазцами докумeнтoв. Оcнoвы Безoпаcности 
Бизнecа.

Тиpах  oграничен. Экcклюзивная инфopмация.  Дocтавка куpьерoм пo Рoccии.  Супeр 
качeствeнная полигpафия.  Различныe cпocoбы оплаты. 
http://austiteach.narod2.ru/analiz-postupleniya-zemelnogo-naloga.html

Изданиe автopитeтнoгo адвоката в фoрматe  Kнига  +  СД  диск.

Очeнь пoлезная подбоpка  инфы управлeнцу.

Автoр-практикующий налoгoвый кoнcультант, спeциализиpующийcя на экспeртизe и 
пpeдзащите налогоcберегающих  сxем, а  также прeдставлении интepесов  
налогoплатeльщикoв на стадии  пpовeрoк и в  судаx.

Kнига вмecтe c инфоpмациeй, записаннoй  на прилагаeмoм к нeму СД-диcке,  
способен  дать необхoдимые  знания  в  oбласти защиты интеpесов фирмы пpи  
прoвeдeнии  пpoвeрoк  кoмпeтентными органами,  и защитить дирeктoра и  eгo 
сoтpудников от  необoснoванногo уголовногo пpeследoвания.

В Книге изложeны осoбеннocти  провeдения пpoвеpок и рeвизий компетентными  
оpганами пpи pасcлeдовании угoловных дeл, пpoведeнии  oпepативно-розыскной 
дeятельнoсти, админиcтpативныx и пoлицeйских провeрoк.

Удачи
--
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


Re: [PATCH] spi: add spi controller master driver for Blackfin 6xx processor

2013-06-03 Thread Viresh Kumar
On Tue, Jun 4, 2013 at 3:13 AM, Scott Jiang  wrote:
> diff --git a/drivers/spi/spi-bfin6xx.c b/drivers/spi/spi-bfin6xx.c

> +#include 

Why do you need this?

--
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


[PATCH v1 3/3] spi: mpc512x: use the SPI subsystem's message queue

2013-06-03 Thread Gerhard Sittig
the SPI subsystem recently grew support to queue messages before handing
them to the SPI master, and erroneously emitted deprecation warnings
when the SPI master's driver did not use the common logic (in fact the
master might queue messages, but implement the queue in the master
driver's source)

  [0.823015] mpc512x-psc-spi 80011400.psc: master is unqueued, this is 
deprecated
  [0.854913] mpc512x-psc-spi 80011500.psc: master is unqueued, this is 
deprecated

this change makes the MPC512x PSC SPI driver use the SPI subsystem's
support to queue SPI messages and removes the master driver's private
code for the queue support

Signed-off-by: Gerhard Sittig 
---
 drivers/spi/spi-mpc512x-psc.c |  183 -
 1 file changed, 73 insertions(+), 110 deletions(-)

diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index 53c7899..29fce6a 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -21,7 +21,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -39,15 +38,8 @@ struct mpc512x_psc_spi {
struct mpc512x_psc_fifo __iomem *fifo;
unsigned int irq;
u8 bits_per_word;
-   u8 busy;
u32 mclk;
 
-   struct workqueue_struct *workqueue;
-   struct work_struct work;
-
-   struct list_head queue;
-   spinlock_t lock;/* Message queue lock */
-
struct completion txisrdone;
 };
 
@@ -134,7 +126,6 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device 
*spi,
 struct spi_transfer *t)
 {
struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
-   struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
size_t tx_len = t->len;
size_t rx_len = t->len;
@@ -144,13 +135,6 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device 
*spi,
if (!tx_buf && !rx_buf && t->len)
return -EINVAL;
 
-   /* Zero MR2 */
-   in_8(&psc->mode);
-   out_8(&psc->mode, 0x0);
-
-   /* enable transmiter/receiver */
-   out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
-
while (rx_len || tx_len) {
size_t txcount;
u8 data;
@@ -275,76 +259,90 @@ static int mpc512x_psc_spi_transfer_rxtx(struct 
spi_device *spi,
}
 
}
-   /* disable transmiter/receiver and fifo interrupt */
-   out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
-   out_be32(&fifo->tximr, 0);
return 0;
 }
 
-static void mpc512x_psc_spi_work(struct work_struct *work)
+static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
+   struct spi_message *m)
 {
-   struct mpc512x_psc_spi *mps = container_of(work,
-  struct mpc512x_psc_spi,
-  work);
-
-   spin_lock_irq(&mps->lock);
-   mps->busy = 1;
-   while (!list_empty(&mps->queue)) {
-   struct spi_message *m;
-   struct spi_device *spi;
-   struct spi_transfer *t = NULL;
-   unsigned cs_change;
-   int status;
-
-   m = container_of(mps->queue.next, struct spi_message, queue);
-   list_del_init(&m->queue);
-   spin_unlock_irq(&mps->lock);
-
-   spi = m->spi;
-   cs_change = 1;
-   status = 0;
-   list_for_each_entry(t, &m->transfers, transfer_list) {
-   if (t->bits_per_word || t->speed_hz) {
-   status = mpc512x_psc_spi_transfer_setup(spi, t);
-   if (status < 0)
-   break;
-   }
-
-   if (cs_change)
-   mpc512x_psc_spi_activate_cs(spi);
-   cs_change = t->cs_change;
-
-   status = mpc512x_psc_spi_transfer_rxtx(spi, t);
-   if (status)
+   struct spi_device *spi;
+   unsigned cs_change;
+   int status;
+   struct spi_transfer *t;
+
+   spi = m->spi;
+   cs_change = 1;
+   status = 0;
+   list_for_each_entry(t, &m->transfers, transfer_list) {
+   if (t->bits_per_word || t->speed_hz) {
+   status = mpc512x_psc_spi_transfer_setup(spi, t);
+   if (status < 0)
break;
-   m->actual_length += t->len;
+   }
 
-   if (t->delay_usecs)
-   udelay(t->delay_usecs);
+   if (cs_change)
+   mpc512x_psc_spi_activate_cs(spi);
+   cs_change = t->cs_change;
 
-   if (cs_change)
-

[PATCH v1 0/3] spi: mpc512x: increase throughput, use subsystem queue

2013-06-03 Thread Gerhard Sittig
This change set modifies the MPC512x PSC SPI master driver:
- it increases SPI throughput by eliminating delays in the inner RX/TX
  routine during iteration over the transfer's data, and reducing delays
  at the very end of a transfer -- while the conditions for as well as
  the handling of previously handled exceptional situations are kept
- it makes the SPI master switch to the common subsystem's logic to
  queue messages between the callers' emission and the master's
  transmission (and drops the master's private queue mechanism)

Gerhard Sittig (3):
  spi: mpc512x: minor prep before feature change
  spi: mpc512x: improve throughput in the RX/TX func
  spi: mpc512x: use the SPI subsystem's message queue

 drivers/spi/spi-mpc512x-psc.c |  341 ++---
 1 file changed, 186 insertions(+), 155 deletions(-)


known issue:

the first patch raises a checkpatch warning because it merely renames
variables but keeps the code path and the existing diagnostics message
in place

a subsequent change in the second patch rephrases the RX/TX routine's
code path and changes the diagnostics message for that condition to
something which doesn't have the checkpatch issue (keeps the user
visible text on one line) and thus passes the test

  WARNING: quoted string split across lines
  #113: FILE: drivers/spi/spi-mpc512x-psc.c:193:
  dev_warn(&spi->dev, "expected %d bytes in rx fifo "
  +  "but got %d\n", txcount, rxcount);

  total: 0 errors, 1 warnings, 130 lines checked

-- 
1.7.10.4


--
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
___
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general


[PATCH v1 2/3] spi: mpc512x: improve throughput in the RX/TX func

2013-06-03 Thread Gerhard Sittig
change the MPC512x SPI controller's transmission routine to increase
throughput: allow the RX byte counter to "lag behind" the TX byte
counter while iterating over the transfer's data, only wait for the
remaining RX bytes at the very end of the transfer

this approach eliminates delays in the milliseconds range, transfer
times for e.g. 16MB of SPI flash data dropped from 31s to 9s, correct
operation was tested by continuously transferring and comparing data
from an SPI flash (more than 200GB in some 45 hours)

background information on the motivation:

one might assume that all the RX data should have been received when the
TX data was sent, given the fact that we are the SPI master and provide
all of the clock, but in practise there's a difference

the ISR is triggered when the TX FIFO became empty, while transmission
of the last item still occurs (from the TX hold and shift registers),
sampling RX data on the opposite clock edge compared to the TX data adds
another delay (half a bit period), and RX data needs to propagate from
the reception buffer to the RX FIFO depending on the specific SoC
implementation

to cut it short: a difference between TX and RX byte counters during
transmission is not just acceptable but should be considered the regular
case, only the very end of the transfer needs to make sure that all of
the RX data was received before deasserting the chip select and telling
the caller that transmission has completed

Signed-off-by: Gerhard Sittig 
---
 drivers/spi/spi-mpc512x-psc.c |  141 +++--
 1 file changed, 107 insertions(+), 34 deletions(-)


remaining style question:

shall this background information and the discussion on the motivation
be considered common knowledge which is not worth keeping around?  or
shall the comments at least not spread across the code but instead get
concentrated in a central spot (like right above the routine)?

I feel that the current form of inline comments is appropriate since it
closely relates the comments to the actions taken, but others might
disagree -- I'm fine with both approaches and happily accept feedback on
the matter


diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index 759a937..53c7899 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -137,6 +137,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device 
*spi,
struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
size_t tx_len = t->len;
+   size_t rx_len = t->len;
u8 *tx_buf = (u8 *)t->tx_buf;
u8 *rx_buf = (u8 *)t->rx_buf;
 
@@ -150,57 +151,129 @@ static int mpc512x_psc_spi_transfer_rxtx(struct 
spi_device *spi,
/* enable transmiter/receiver */
out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
 
-   while (tx_len) {
+   while (rx_len || tx_len) {
size_t txcount;
-   int i;
u8 data;
size_t fifosz;
size_t rxcount;
+   int rxtries;
 
/*
-* The number of bytes that can be sent at a time
-* depends on the fifo size.
+* send the TX bytes in as large a chunk as possible
+* but neither exceed the TX nor the RX FIFOs
 */
fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->txsz));
txcount = min(fifosz, tx_len);
+   fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->rxsz));
+   fifosz -= in_be32(&fifo->rxcnt) + 1;
+   txcount = min(fifosz, txcount);
+   if (txcount) {
+
+   /* fill the TX FIFO */
+   while (txcount-- > 0) {
+   data = tx_buf ? *tx_buf++ : 0;
+   if (tx_len == EOFBYTE && t->cs_change)
+   setbits32(&fifo->txcmd,
+ MPC512x_PSC_FIFO_EOF);
+   out_8(&fifo->txdata_8, data);
+   tx_len--;
+   }
 
-   for (i = txcount; i > 0; i--) {
-   data = tx_buf ? *tx_buf++ : 0;
-   if (tx_len == EOFBYTE && t->cs_change)
-   setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);
-   out_8(&fifo->txdata_8, data);
-   tx_len--;
+   /* have the ISR trigger when the TX FIFO is empty */
+   INIT_COMPLETION(mps->txisrdone);
+   out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
+   out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);
+   wait_for_completion(&mps->txisrdone);
}
 
-   INIT_COMPLETION(mps->txisrdone);
-
-   /* interrupt on tx fifo empty 

[PATCH v1 1/3] spi: mpc512x: minor prep before feature change

2013-06-03 Thread Gerhard Sittig
mechanical edits before changing functionality, to reduce diffs
- rename variables to later tell remaining TX and RX apart
- use size_t for the current TX and RX length
  (for better compatibility with the min() macro)
- remove unused members from the master data (sysclk, eofbyte)
- silence a checkpatch warning (braces around single statement)

Signed-off-by: Gerhard Sittig 
---
 drivers/spi/spi-mpc512x-psc.c |   43 ++---
 1 file changed, 19 insertions(+), 24 deletions(-)


this patch triggers a checkpatch warning which IMO is acceptable
(see the cover letter for the details)


diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c
index dfddf33..759a937 100644
--- a/drivers/spi/spi-mpc512x-psc.c
+++ b/drivers/spi/spi-mpc512x-psc.c
@@ -33,7 +33,6 @@
 
 struct mpc512x_psc_spi {
void (*cs_control)(struct spi_device *spi, bool on);
-   u32 sysclk;
 
/* driver internal data */
struct mpc52xx_psc __iomem *psc;
@@ -42,7 +41,6 @@ struct mpc512x_psc_spi {
u8 bits_per_word;
u8 busy;
u32 mclk;
-   u8 eofbyte;
 
struct workqueue_struct *workqueue;
struct work_struct work;
@@ -50,7 +48,7 @@ struct mpc512x_psc_spi {
struct list_head queue;
spinlock_t lock;/* Message queue lock */
 
-   struct completion done;
+   struct completion txisrdone;
 };
 
 /* controller state */
@@ -138,7 +136,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device 
*spi,
struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
struct mpc52xx_psc __iomem *psc = mps->psc;
struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
-   size_t len = t->len;
+   size_t tx_len = t->len;
u8 *tx_buf = (u8 *)t->tx_buf;
u8 *rx_buf = (u8 *)t->rx_buf;
 
@@ -152,58 +150,57 @@ static int mpc512x_psc_spi_transfer_rxtx(struct 
spi_device *spi,
/* enable transmiter/receiver */
out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
 
-   while (len) {
-   int count;
+   while (tx_len) {
+   size_t txcount;
int i;
u8 data;
size_t fifosz;
-   int rxcount;
+   size_t rxcount;
 
/*
 * The number of bytes that can be sent at a time
 * depends on the fifo size.
 */
fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->txsz));
-   count = min(fifosz, len);
+   txcount = min(fifosz, tx_len);
 
-   for (i = count; i > 0; i--) {
+   for (i = txcount; i > 0; i--) {
data = tx_buf ? *tx_buf++ : 0;
-   if (len == EOFBYTE && t->cs_change)
+   if (tx_len == EOFBYTE && t->cs_change)
setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);
out_8(&fifo->txdata_8, data);
-   len--;
+   tx_len--;
}
 
-   INIT_COMPLETION(mps->done);
+   INIT_COMPLETION(mps->txisrdone);
 
/* interrupt on tx fifo empty */
out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);
 
-   wait_for_completion(&mps->done);
+   wait_for_completion(&mps->txisrdone);
 
mdelay(1);
 
-   /* rx fifo should have count bytes in it */
+   /* rx fifo should have txcount bytes in it */
rxcount = in_be32(&fifo->rxcnt);
-   if (rxcount != count)
+   if (rxcount != txcount)
mdelay(1);
 
rxcount = in_be32(&fifo->rxcnt);
-   if (rxcount != count) {
+   if (rxcount != txcount) {
dev_warn(&spi->dev, "expected %d bytes in rx fifo "
-"but got %d\n", count, rxcount);
+"but got %d\n", txcount, rxcount);
}
 
-   rxcount = min(rxcount, count);
+   rxcount = min(rxcount, txcount);
for (i = rxcount; i > 0; i--) {
data = in_8(&fifo->rxdata_8);
if (rx_buf)
*rx_buf++ = data;
}
-   while (in_be32(&fifo->rxcnt)) {
+   while (in_be32(&fifo->rxcnt))
in_8(&fifo->rxdata_8);
-   }
}
/* disable transmiter/receiver and fifo interrupt */
out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
@@ -412,7 +409,7 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void 
*dev_id)
in_be32(&fifo->tximr) & MPC512x_PSC_FIFO_EMPTY) {
out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
out

[PATCH] spi: add spi controller master driver for Blackfin 6xx processor

2013-06-03 Thread Scott Jiang
New spi controller is integrated into Blackfin 6xx processor.
Comparing to bf5xx spi controller, we support 32 bits word size
and independent receive and transmit DMA channels now.
Also mode 0 and 2 (CPHA = 0) can get fully supported
becasue cs line may be controlled by the software.

Signed-off-by: Scott Jiang 
---
 drivers/spi/Kconfig   |8 +-
 drivers/spi/Makefile  |1 +
 drivers/spi/spi-bfin6xx.c | 1026 +
 3 files changed, 1034 insertions(+), 1 deletions(-)
 create mode 100644 drivers/spi/spi-bfin6xx.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 864d87f..d64bbeb 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -87,10 +87,16 @@ config SPI_BCM2835
 
 config SPI_BFIN5XX
tristate "SPI controller driver for ADI Blackfin5xx"
-   depends on BLACKFIN
+   depends on BLACKFIN && !BF60x
help
  This is the SPI controller master driver for Blackfin 5xx processor.
 
+config SPI_BFIN6XX
+   tristate "SPI controller driver for ADI Blackfin6xx"
+   depends on BF60x
+   help
+ This is the SPI controller master driver for Blackfin 6xx processor.
+
 config SPI_BFIN_SPORT
tristate "SPI bus via Blackfin SPORT"
depends on BLACKFIN
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 33f9c09..0114a26 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SPI_AU1550)  += spi-au1550.o
 obj-$(CONFIG_SPI_BCM2835)  += spi-bcm2835.o
 obj-$(CONFIG_SPI_BCM63XX)  += spi-bcm63xx.o
 obj-$(CONFIG_SPI_BFIN5XX)  += spi-bfin5xx.o
+obj-$(CONFIG_SPI_BFIN6XX)   += spi-bfin6xx.o
 obj-$(CONFIG_SPI_BFIN_SPORT)   += spi-bfin-sport.o
 obj-$(CONFIG_SPI_BITBANG)  += spi-bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)+= spi-butterfly.o
diff --git a/drivers/spi/spi-bfin6xx.c b/drivers/spi/spi-bfin6xx.c
new file mode 100644
index 000..bd38ff4
--- /dev/null
+++ b/drivers/spi/spi-bfin6xx.c
@@ -0,0 +1,1026 @@
+/*
+ * Analog Devices SPI3 controller driver
+ *
+ * Copyright (c) 2013 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define START_STATE((void *)0)
+#define RUNNING_STATE  ((void *)1)
+#define DONE_STATE ((void *)2)
+#define ERROR_STATE((void *)-1)
+
+struct bfin_spi_master;
+
+struct bfin_spi_transfer_ops {
+   void (*write) (struct bfin_spi_master *);
+   void (*read) (struct bfin_spi_master *);
+   void (*duplex) (struct bfin_spi_master *);
+};
+
+/* runtime info for spi master */
+struct bfin_spi_master {
+   /* SPI framework hookup */
+   struct spi_master *master;
+
+   /* Regs base of SPI controller */
+   struct bfin_spi_regs __iomem *regs;
+
+   /* Pin request list */
+   u16 *pin_req;
+
+   /* Message Transfer pump */
+   struct tasklet_struct pump_transfers;
+
+   /* Current message transfer state info */
+   struct spi_message *cur_msg;
+   struct spi_transfer *cur_transfer;
+   struct bfin_spi_device *cur_chip;
+   unsigned transfer_len;
+   unsigned cs_change;
+
+   /* transfer buffer */
+   void *tx;
+   void *tx_end;
+   void *rx;
+   void *rx_end;
+
+   /* dma info */
+   unsigned int tx_dma;
+   unsigned int rx_dma;
+   dma_addr_t tx_dma_addr;
+   dma_addr_t rx_dma_addr;
+   unsigned long dummy_buffer; /* used in unidirectional transfer */
+   unsigned long tx_dma_size;
+   unsigned long rx_dma_size;
+   int tx_num;
+   int rx_num;
+
+   /* store register value for suspend/resume */
+   u32 control;
+   u32 ssel;
+
+   const struct bfin_spi_transfer_ops *ops;
+};
+
+struct bfin_spi_device {
+   u32 control;
+   u32 clock;
+   u32 ssel;
+
+   u8 cs;
+   u16 cs_chg_udelay; /* Some devices require > 255usec delay */
+   u32 cs_gpio;
+   u32 tx_dummy_val; /* tx value for rx only transfer */
+   bool enable_dma;
+   const struct bfin_spi_transfer_ops *ops;
+};
+
+static void bfin_spi_enable(struct bfin_spi_master *drv_data)
+{
+   bfin_write_or(&drv_data->regs->control, SPI_CTL_EN);
+}
+
+static void bfin_spi_disable(struct bfin_spi_master *drv_data)
+{
+   bfin_write_and(&drv_data->regs->control, ~SPI_CTL_EN);
+}
+
+static