Discussion:
[ORLinux] [PATCH 00/12] Modernize opencores simple spi driver
Stefan Kristiansson
2013-09-01 07:12:35 UTC
Permalink
This set of patches brings the OpenCores simple SPI driver up to date
with the current practices used in the SPI subsystem.

A special note is required for the last two patches ("use clock framework to
obtain spi clock" and "remove dependency on OPENRISC for spi-oc-simple").
When used together with OpenRISC, there are two prerequisite patches.

1) openrisc: select COMMON_CLK
https://patchwork.kernel.org/patch/2852461/

2) clk: add generic driver for fixed rate clock
https://patchwork.kernel.org/patch/2852460/

The first goes without comment, the second is needed since we
don't have any board specific init code, but only rely on the device
tree description to setup our boards.
With those two applied, the clock for the spi driver can be described as
below in the dts file.

...
wb_clk: wb_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
clock-output-names = "wb_clk";
};
...
spi0: spi0 at b0000000 {
compatible = "opencores,spi-simple";
reg = <0xb0000000 0x5>;
clocks = <&wb_clk>;
...
};

The rest of the patches can be applied without concerns.

Stefan Kristiansson (12):
spi/spi_opencores: rename to spi-oc-simple
spi/spi-oc-simple: update driver names in file header
spi/spi-oc-simple: remove __devinit, __devexit, __init and __exit
spi/spi-oc-simple: include module.h
spi/spi-oc-simple: whitespace and format cleanup
spi/spi-oc-simple: remove dead and commented out code
spi/spi-oc-simple: remove unused variables
spi/spi-oc-simple: use the SPI framework queue
spi/spi-oc-simple: use platform_{get,set}_drvdata()
spi/spi-oc-simple: use module_platform_driver to register driver
spi/spi-oc-simple: use clock framework to obtain spi clock
spi: remove dependency on OPENRISC for spi-oc-simple

drivers/spi/Kconfig | 1 -
drivers/spi/Makefile | 2 +-
drivers/spi/spi-oc-simple.c | 490 ++++++++++++++++++++++++++++++
drivers/spi/spi_opencores.c | 707 --------------------------------------------
4 files changed, 491 insertions(+), 709 deletions(-)
create mode 100644 drivers/spi/spi-oc-simple.c
delete mode 100644 drivers/spi/spi_opencores.c
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:36 UTC
Permalink
This is more inline with the current naming convention of the
other spi drivers and better reflect the name of the core.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/Makefile | 2 +-
drivers/spi/{spi_opencores.c => spi-oc-simple.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename drivers/spi/{spi_opencores.c => spi-oc-simple.c} (100%)

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 2c72f76..a80e9f3 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -41,7 +41,7 @@ obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
-obj-$(CONFIG_SPI_OCSIMPLE) += spi_opencores.o
+obj-$(CONFIG_SPI_OCSIMPLE) += spi-oc-simple.o
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
diff --git a/drivers/spi/spi_opencores.c b/drivers/spi/spi-oc-simple.c
similarity index 100%
rename from drivers/spi/spi_opencores.c
rename to drivers/spi/spi-oc-simple.c
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:37 UTC
Permalink
Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index 699a1c7..cae6270 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -1,10 +1,10 @@
/*
- * spi_opencores.c -- OpenCores SPI controller driver
+ * spi-oc-simple.c -- OpenCores SPI controller driver
*
* Author: Jonas Bonn <jonas at southpole.se>
* Copyright (C) 2010 South Pole AB
*
- * Derived from orion_spi.c
+ * Derived from spi-orion.c
*
* 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
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:38 UTC
Permalink
__devinit and __devexit was removed with CONFIG_HOTPLUG.
__init and __exit has never been correct on probe/remove
related functions.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index cae6270..92daa1d 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -449,7 +449,7 @@ msg_done:
spin_unlock_irq(&ocspi->lock);
}

-static int __init ocspi_reset(struct ocspi *ocspi)
+static int ocspi_reset(struct ocspi *ocspi)
{
/* Verify that the CS is deasserted */
ocspi_set_cs(ocspi, 0);
@@ -566,7 +566,7 @@ msg_rejected:
return -EINVAL;
}

-static int __devinit ocspi_probe(struct platform_device *pdev)
+static int ocspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct ocspi *spi;
@@ -635,7 +635,7 @@ out:
return status;
}

-static int __devexit ocspi_remove(struct platform_device *pdev)
+static int ocspi_remove(struct platform_device *pdev)
{
struct spi_master *master;
struct ocspi *spi;
@@ -662,7 +662,7 @@ MODULE_ALIAS("platform:" DRIVER_NAME);

static struct platform_driver ocspi_driver = {
.probe = ocspi_probe,
- .remove = __devexit_p(ocspi_remove),
+ .remove = ocspi_remove,
/* .suspend = ocspi_suspend,
.resume = ocspi_resume,
*/
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:39 UTC
Permalink
This is needed by the MODULE_ macros used in this driver.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index 92daa1d..6b0dc54 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/io.h>
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:40 UTC
Permalink
Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 121 ++++++++++++++++++++++----------------------
1 file changed, 61 insertions(+), 60 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index 6b0dc54..f03d5b1 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -24,7 +24,7 @@

#define DRIVER_NAME "oc_spi_simple"

-#define OCSPI_NUM_CHIPSELECTS 8
+#define OCSPI_NUM_CHIPSELECTS 8
#define OCSPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */

#define OCSPI_REG_SPCR 0x0
@@ -83,8 +83,9 @@ ocspi_set_transfer_size(struct ocspi *ocspi, unsigned int size)
return -EINVAL;
}

- /* Nothing to do */
- /* If we were using interrupts we would probably set the
+ /*
+ * Nothing to do
+ * If we were using interrupts we would probably set the
* ICNT bits of the SPER register here... but we're not!
*/

@@ -128,7 +129,7 @@ static inline void
ocspi_set_mode_bits(u8* spcr, int mode)
{
if (mode & SPI_CPHA) {
- *spcr |= OCSPI_SPCR_CPHA;
+ *spcr |= OCSPI_SPCR_CPHA;
} else {
*spcr &= ~OCSPI_SPCR_CPHA;
}
@@ -170,7 +171,6 @@ ocspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
ocspi_write(ocspi, OCSPI_REG_SPCR, spcr);
ocspi_write(ocspi, OCSPI_REG_SPER, sper);

-
return ocspi_set_transfer_size(ocspi, bits_per_word);
}

@@ -227,7 +227,7 @@ ocspi_write_read(struct spi_device *spi,
if (ocspi_wait_till_ready(ocspi) < 0) {
dev_err(&spi->dev, "TXS timed out\n");
return -1;
- }
+ }

if (rx_buf && *rx_buf) {
while (!ocspi_read(ocspi, OCSPI_REG_SPSR) & OCSPI_SPSR_RDEMPTY) {
@@ -308,38 +308,38 @@ ocspi_write_read_16bit(struct spi_device *spi,
static unsigned int
ocspi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
{
- struct ocspi *ocspi;
- unsigned int count;
- int word_len;
+ struct ocspi *ocspi;
+ unsigned int count;
+ int word_len;

- ocspi = spi_master_get_devdata(spi->master);
- word_len = spi->bits_per_word;
- count = xfer->len;
+ ocspi = spi_master_get_devdata(spi->master);
+ word_len = spi->bits_per_word;
+ count = xfer->len;

// printk("Writing transfer: length = %d\n", count);

- if (word_len == 8) {
- const u8 *tx = xfer->tx_buf;
- u8 *rx = xfer->rx_buf;
-
- do {
- if (ocspi_write_read_8bit(spi, &tx, &rx) < 0)
- goto out;
- count--;
- } while (count);
- } else if (word_len == 16) {
- const u8 *tx = xfer->tx_buf;
- u8 *rx = xfer->rx_buf;
-
- do {
- if (ocspi_write_read_16bit(spi, &tx, &rx) < 0)
- goto out;
- count -= 2;
- } while (count);
- }
+ if (word_len == 8) {
+ const u8 *tx = xfer->tx_buf;
+ u8 *rx = xfer->rx_buf;
+
+ do {
+ if (ocspi_write_read_8bit(spi, &tx, &rx) < 0)
+ goto out;
+ count--;
+ } while (count);
+ } else if (word_len == 16) {
+ const u8 *tx = xfer->tx_buf;
+ u8 *rx = xfer->rx_buf;
+
+ do {
+ if (ocspi_write_read_16bit(spi, &tx, &rx) < 0)
+ goto out;
+ count -= 2;
+ } while (count);
+ }

out:
- return xfer->len - count;
+ return xfer->len - count;
}

#if 0
@@ -468,7 +468,6 @@ static int ocspi_reset(struct ocspi *ocspi)
* this controller. This function may be called at any time and should
* not touch registers.
*/
-
static int ocspi_setup(struct spi_device *spi)
{
struct ocspi *ocspi;
@@ -496,7 +495,6 @@ static int ocspi_setup(struct spi_device *spi)
* spi_device. May be called at any time and should thus not touch
* registers.
*/
-
static int ocspi_transfer(struct spi_device *spi, struct spi_message *m)
{
struct ocspi *ocspi;
@@ -523,25 +521,26 @@ static int ocspi_transfer(struct spi_device *spi, struct spi_message *m)
goto msg_rejected;
}

- if ((t != NULL) && t->bits_per_word)
- bits_per_word = t->bits_per_word;
-
- if ((bits_per_word != 8) && (bits_per_word != 16)) {
- dev_err(&spi->dev,
- "message rejected : "
- "invalid transfer bits_per_word (%d bits)\n",
- bits_per_word);
- goto msg_rejected;
- }
-
- /*make sure buffer length is even when working in 16 bit mode*/
- if ((t != NULL) && (t->bits_per_word == 16) && (t->len & 1)) {
- dev_err(&spi->dev,
- "message rejected : "
- "odd data length (%d) while in 16 bit mode\n",
- t->len);
- goto msg_rejected;
- }
+ if ((t != NULL) && t->bits_per_word)
+ bits_per_word = t->bits_per_word;
+
+ if ((bits_per_word != 8) && (bits_per_word != 16)) {
+ dev_err(&spi->dev,
+ "message rejected : "
+ "invalid transfer bits_per_word (%d bits)\n",
+ bits_per_word);
+ goto msg_rejected;
+ }
+
+ /* make sure buffer length is even when working in 16 bit
+ mode */
+ if ((t != NULL) && (t->bits_per_word == 16) && (t->len & 1)) {
+ dev_err(&spi->dev,
+ "message rejected : "
+ "odd data length (%d) while in 16 bit mode\n",
+ t->len);
+ goto msg_rejected;
+ }

if (t->speed_hz && t->speed_hz < ocspi->min_speed) {
dev_err(&spi->dev,
@@ -585,8 +584,9 @@ static int ocspi_probe(struct platform_device *pdev)

master->bus_num = -1;

- /* we support only mode 0 for now, and no options...
- * but we can support CPHA setting -- to be implemented
+ /*
+ * we support only mode 0 for now, and no options...
+ * but we can support CPHA setting -- to be implemented
*/
master->mode_bits = SPI_MODE_3;

@@ -616,7 +616,8 @@ static int ocspi_probe(struct platform_device *pdev)
status = -EBUSY;
goto out;
}
- spi->base = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r));
+ spi->base = devm_ioremap_nocache(&pdev->dev, r->start,
+ resource_size(r));

INIT_WORK(&spi->work, ocspi_work);

@@ -652,10 +653,10 @@ static int ocspi_remove(struct platform_device *pdev)
}

static struct of_device_id ocspi_match[] = {
- {
- .compatible = "opencores,spi-simple",
- },
- {},
+ {
+ .compatible = "opencores,spi-simple",
+ },
+ {},
};
MODULE_DEVICE_TABLE(of, ocspi_match);
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:41 UTC
Permalink
This also make the driver reject any bits_per_word not equal
to 8, since the handling of bits_per_word == 16 was non
functional.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 144 +-------------------------------------------
1 file changed, 1 insertion(+), 143 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index f03d5b1..dea1e27 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -192,55 +192,11 @@ ocspi_wait_till_ready(struct ocspi *ocspi)
return 1;
else
usleep_range(1,1);
- //udelay(1);
}

return -1;
}
-#if 0
-static inline int
-ocspi_write_read(struct spi_device *spi,
- const u8 **tx_buf, u8 **rx_buf, int length)
-{
- struct ocspi *ocspi;
- u8 v;
-
- ocspi = spi_master_get_devdata(spi->master);
-
- /* If there's any garbage left over in the read buffer, delete it */
- while (!ocspi_read(ocspi, OCSPI_REG_SPSR) & OCSPI_SPSR_RDEMPTY) {
- ocspi_read(ocspi, OCSPI_REG_SPDR);
- }
-
- count = length;

- /* Write four bytes at a time and read them back */
- do {
- int i;
- i = 0
- while (count > 0 && i != 4) {
- ocspi_write(ocspi, OCSPI_REG_SPDR, *(*tx_buf)++);
- count--;
- i++;
- }
-
- if (ocspi_wait_till_ready(ocspi) < 0) {
- dev_err(&spi->dev, "TXS timed out\n");
- return -1;
- }
-
- if (rx_buf && *rx_buf) {
- while (!ocspi_read(ocspi, OCSPI_REG_SPSR) & OCSPI_SPSR_RDEMPTY) {
- *(*rx_buf)++ = ocspi_read(ocspi, OCSPI_REG_SPDR);
- } else {
- while (!ocspi_read(ocspi, OCSPI_REG_SPSR) & OCSPI_SPSR_RDEMPTY) {
- ocspi_read(ocspi, OCSPI_REG_SPDR);
- }
- } while (count > 0);
-
- return length;
-}
-#endif
static inline int
ocspi_write_read_8bit(struct spi_device *spi,
const u8 **tx_buf, u8 **rx_buf)
@@ -270,41 +226,6 @@ ocspi_write_read_8bit(struct spi_device *spi,
return 1;
}

-static inline int
-ocspi_write_read_16bit(struct spi_device *spi,
- const u8 **tx_buf, u8 **rx_buf)
-{
-#if 0
- u8 __iomem *datareg;
- struct ocspi *ocspi;
-
- ocspi = spi_master_get_devdata(spi->master);
- datareg = spi_reg(ocspi, OCSPI_REG_SPDR);
-
- if (tx_buf && *tx_buf) {
- iowrite8(*(*tx_buf)++, datareg);
- iowrite8(*(*tx_buf)++, datareg);
- } else {
- iowrite8(0, datareg);
- iowrite8(0, datareg);
- }
-
- if (ocspi_wait_till_ready(ocspi) < 0) {
- dev_err(&spi->dev, "TXS timed out\n");
- return -1;
- }
-
- if (rx_buf && *rx_buf) {
- *(*rx_buf)++ = ioread8(datareg);
- *(*rx_buf)++ = ioread8(datareg);
- } else {
- ioread8(datareg);
- ioread8(datareg);
- }
-#endif
- return 1;
-}
-
static unsigned int
ocspi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
{
@@ -316,8 +237,6 @@ ocspi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
word_len = spi->bits_per_word;
count = xfer->len;

-// printk("Writing transfer: length = %d\n", count);
-
if (word_len == 8) {
const u8 *tx = xfer->tx_buf;
u8 *rx = xfer->rx_buf;
@@ -327,60 +246,12 @@ ocspi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
goto out;
count--;
} while (count);
- } else if (word_len == 16) {
- const u8 *tx = xfer->tx_buf;
- u8 *rx = xfer->rx_buf;
-
- do {
- if (ocspi_write_read_16bit(spi, &tx, &rx) < 0)
- goto out;
- count -= 2;
- } while (count);
}

out:
return xfer->len - count;
}

-#if 0
-static irqreturn_t
-ocspi_interrupt(int irq, void *dev_id)
-{
- /* Disable interrupt */
- ocspi_clrbits(ocspi, OCSPI_REG_CTRL, OCSPI_CTRL_IE);
-
- return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t
-ocspi_interrupt_thread(int irq, void *dev_id)
-{
- struct ocspi *ocspi = (struct ocspi*) dev_id;
-
- if (current_xfer) {
- current_xfer->rx_buf
-
-
- }
-
- spin_lock_irq(&ocspi->lock);
- if (list_empty(&ocspi->msq_queue)) {
- /* No more messages to send */
- spin_unlock_irq(&ocspi->lock);
- return IRQ_HANDLED;
- }
-
- msg = container_of(ocspi->msq_queue.next, struct spi_message, queue);
-
-
-
- /* Reenable interrupt */
- ocspi_setbits(ocspi, OCSPI_REG_CTRL, OCSPI_CTRL_IE);
-
- return IRQ_HANDLED;
-}
-#endif
-
static void ocspi_work(struct work_struct *work)
{
struct ocspi *ocspi =
@@ -524,7 +395,7 @@ static int ocspi_transfer(struct spi_device *spi, struct spi_message *m)
if ((t != NULL) && t->bits_per_word)
bits_per_word = t->bits_per_word;

- if ((bits_per_word != 8) && (bits_per_word != 16)) {
+ if (bits_per_word != 8) {
dev_err(&spi->dev,
"message rejected : "
"invalid transfer bits_per_word (%d bits)\n",
@@ -532,16 +403,6 @@ static int ocspi_transfer(struct spi_device *spi, struct spi_message *m)
goto msg_rejected;
}

- /* make sure buffer length is even when working in 16 bit
- mode */
- if ((t != NULL) && (t->bits_per_word == 16) && (t->len & 1)) {
- dev_err(&spi->dev,
- "message rejected : "
- "odd data length (%d) while in 16 bit mode\n",
- t->len);
- goto msg_rejected;
- }
-
if (t->speed_hz && t->speed_hz < ocspi->min_speed) {
dev_err(&spi->dev,
"message rejected : "
@@ -665,9 +526,6 @@ MODULE_ALIAS("platform:" DRIVER_NAME);
static struct platform_driver ocspi_driver = {
.probe = ocspi_probe,
.remove = ocspi_remove,
-/* .suspend = ocspi_suspend,
- .resume = ocspi_resume,
-*/
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:42 UTC
Permalink
Those are probably remainders from spi-orion, removing
them purge a couple of compile warnings.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index dea1e27..3c8e9b9 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -151,7 +151,6 @@ ocspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
struct ocspi *ocspi;
unsigned int speed = spi->max_speed_hz;
unsigned int bits_per_word = spi->bits_per_word;
- int rc;
u8 spcr, sper;

ocspi = spi_master_get_devdata(spi->master);
@@ -202,7 +201,6 @@ ocspi_write_read_8bit(struct spi_device *spi,
const u8 **tx_buf, u8 **rx_buf)
{
struct ocspi *ocspi;
- u8 v;

ocspi = spi_master_get_devdata(spi->master);
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:43 UTC
Permalink
Replaces the deprecated master->transfer function with
master->transfer_one_message and let the SPI subsystem do the
message queueing instead of doing it locally.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 223 ++++++++++++++------------------------------
1 file changed, 71 insertions(+), 152 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index 3c8e9b9..3938a26 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -51,20 +51,12 @@
#define OCSPI_SPER_ESPR 0x03

struct ocspi {
- struct work_struct work;
-
- /* Lock access to transfer list. */
- spinlock_t lock;
-
- struct list_head msg_queue;
struct spi_master *master;
void __iomem *base;
unsigned int max_speed;
unsigned int min_speed;
};

-static struct workqueue_struct *ocspi_wq;
-
static inline u8
ocspi_read(struct ocspi* ocspi, unsigned int reg) {
return ioread8(ocspi->base + reg);
@@ -250,73 +242,90 @@ out:
return xfer->len - count;
}

-static void ocspi_work(struct work_struct *work)
+static int ocspi_transfer_one_message(struct spi_master *master,
+ struct spi_message *m)
{
- struct ocspi *ocspi =
- container_of(work, struct ocspi, work);
+ struct ocspi *ocspi = spi_master_get_devdata(master);
+ struct spi_device *spi = m->spi;
+ struct spi_transfer *t = NULL;
+ int par_override = 0;
+ int status = 0;
+ int cs_active = 0;
+

- spin_lock_irq(&ocspi->lock);
- while (!list_empty(&ocspi->msg_queue)) {
- struct spi_message *m;
- struct spi_device *spi;
- struct spi_transfer *t = NULL;
- int par_override = 0;
- int status = 0;
- int cs_active = 0;
+ /* Load defaults */
+ status = ocspi_setup_transfer(spi, NULL);

- m = container_of(ocspi->msg_queue.next, struct spi_message,
- queue);
+ if (status < 0)
+ goto msg_done;

- list_del_init(&m->queue);
- spin_unlock_irq(&ocspi->lock);
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ unsigned int bits_per_word = spi->bits_per_word;

- spi = m->spi;
+ if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
+ dev_err(&spi->dev,
+ "message rejected : "
+ "invalid transfer data buffers\n");
+ status = -EIO;
+ goto msg_done;
+ }

- /* Load defaults */
- status = ocspi_setup_transfer(spi, NULL);
+ if ((t != NULL) && t->bits_per_word)
+ bits_per_word = t->bits_per_word;

- if (status < 0)
+ if ((bits_per_word != 8)) {
+ dev_err(&spi->dev,
+ "message rejected : "
+ "invalid transfer bits_per_word (%d bits)\n",
+ bits_per_word);
+ status = -EIO;
goto msg_done;
+ }

- list_for_each_entry(t, &m->transfers, transfer_list) {
- if (par_override || t->speed_hz || t->bits_per_word) {
- par_override = 1;
- status = ocspi_setup_transfer(spi, t);
- if (status < 0)
- break;
- if (!t->speed_hz && !t->bits_per_word)
- par_override = 0;
- }
-
- if (!cs_active) {
- ocspi_set_cs(ocspi, (1 << spi->chip_select));
- cs_active = 1;
- }
-
- if (t->len)
- m->actual_length +=
- ocspi_write_read(spi, t);
-
- if (t->delay_usecs)
- udelay(t->delay_usecs);
-
- if (t->cs_change) {
- ocspi_set_cs(ocspi, 0);
- cs_active = 0;
- }
+ if (t->speed_hz && t->speed_hz < ocspi->min_speed) {
+ dev_err(&spi->dev,
+ "message rejected : "
+ "device min speed (%d Hz) exceeds "
+ "required transfer speed (%d Hz)\n",
+ ocspi->min_speed, t->speed_hz);
+ status = -EIO;
+ goto msg_done;
}

-msg_done:
- if (cs_active)
- ocspi_set_cs(ocspi, 0);
+ if (par_override || t->speed_hz || t->bits_per_word) {
+ par_override = 1;
+ status = ocspi_setup_transfer(spi, t);
+ if (status < 0)
+ break;
+ if (!t->speed_hz && !t->bits_per_word)
+ par_override = 0;
+ }

- m->status = status;
- m->complete(m->context);
+ if (!cs_active) {
+ ocspi_set_cs(ocspi, (1 << spi->chip_select));
+ cs_active = 1;
+ }
+
+ if (t->len)
+ m->actual_length += ocspi_write_read(spi, t);
+
+ if (t->delay_usecs)
+ udelay(t->delay_usecs);

- spin_lock_irq(&ocspi->lock);
+ if (t->cs_change) {
+ ocspi_set_cs(ocspi, 0);
+ cs_active = 0;
+ }
}

- spin_unlock_irq(&ocspi->lock);
+msg_done:
+ if (cs_active)
+ ocspi_set_cs(ocspi, 0);
+
+ m->status = status;
+ spi_finalize_current_message(master);
+
+ return 0;
}

static int ocspi_reset(struct ocspi *ocspi)
@@ -359,72 +368,6 @@ static int ocspi_setup(struct spi_device *spi)
return 0;
}

-/*
- * The transfer function enqueues a message for sending to the
- * spi_device. May be called at any time and should thus not touch
- * registers.
- */
-static int ocspi_transfer(struct spi_device *spi, struct spi_message *m)
-{
- struct ocspi *ocspi;
- struct spi_transfer *t = NULL;
- unsigned long flags;
-
- m->actual_length = 0;
- m->status = 0;
-
- /* reject invalid messages and transfers */
- if (list_empty(&m->transfers) || !m->complete) {
- return -EINVAL;
- }
-
- ocspi = spi_master_get_devdata(spi->master);
-
- list_for_each_entry(t, &m->transfers, transfer_list) {
- unsigned int bits_per_word = spi->bits_per_word;
-
- if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
- dev_err(&spi->dev,
- "message rejected : "
- "invalid transfer data buffers\n");
- goto msg_rejected;
- }
-
- if ((t != NULL) && t->bits_per_word)
- bits_per_word = t->bits_per_word;
-
- if (bits_per_word != 8) {
- dev_err(&spi->dev,
- "message rejected : "
- "invalid transfer bits_per_word (%d bits)\n",
- bits_per_word);
- goto msg_rejected;
- }
-
- if (t->speed_hz && t->speed_hz < ocspi->min_speed) {
- dev_err(&spi->dev,
- "message rejected : "
- "device min speed (%d Hz) exceeds "
- "required transfer speed (%d Hz)\n",
- ocspi->min_speed, t->speed_hz);
- goto msg_rejected;
- }
- }
-
- spin_lock_irqsave(&ocspi->lock, flags);
- list_add_tail(&m->queue, &ocspi->msg_queue);
- queue_work(ocspi_wq, &ocspi->work);
- spin_unlock_irqrestore(&ocspi->lock, flags);
-
- return 0;
-msg_rejected:
- /* Message rejected and not queued */
- m->status = -EINVAL;
- if (m->complete)
- m->complete(m->context);
- return -EINVAL;
-}
-
static int ocspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
@@ -450,7 +393,7 @@ static int ocspi_probe(struct platform_device *pdev)
master->mode_bits = SPI_MODE_3;

master->setup = ocspi_setup;
- master->transfer = ocspi_transfer;
+ master->transfer_one_message = ocspi_transfer_one_message;
master->num_chipselect = OCSPI_NUM_CHIPSELECTS;
#ifdef CONFIG_OF
master->dev.of_node = pdev->dev.of_node;
@@ -478,11 +421,6 @@ static int ocspi_probe(struct platform_device *pdev)
spi->base = devm_ioremap_nocache(&pdev->dev, r->start,
resource_size(r));

- INIT_WORK(&spi->work, ocspi_work);
-
- spin_lock_init(&spi->lock);
- INIT_LIST_HEAD(&spi->msg_queue);
-
ocspi_reset(spi);

status = spi_register_master(master);
@@ -504,8 +442,6 @@ static int ocspi_remove(struct platform_device *pdev)
master = dev_get_drvdata(&pdev->dev);
spi = spi_master_get_devdata(master);

- cancel_work_sync(&spi->work);
-
spi_unregister_master(master);

return 0;
@@ -533,30 +469,13 @@ static struct platform_driver ocspi_driver = {

static int __init ocspi_init(void)
{
- int status;
-
- ocspi_wq = create_singlethread_workqueue(
- ocspi_driver.driver.name);
-
- if (ocspi_wq == NULL)
- return -ENOMEM;
-
- status = platform_driver_register(&ocspi_driver);
-
- if (status) {
- destroy_workqueue(ocspi_wq);
- };
-
- return status;
+ return platform_driver_register(&ocspi_driver);
}
module_init(ocspi_init);

static void __exit ocspi_exit(void)
{
- flush_workqueue(ocspi_wq);
platform_driver_unregister(&ocspi_driver);
-
- destroy_workqueue(ocspi_wq);
}
module_exit(ocspi_exit);
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:44 UTC
Permalink
Use the wrapper functions for getting and setting the driver data using
platform_device instead of using dev_{get,set}_drvdata() with &pdev>dev,
so we can directly pass a struct platform_device.

see 24b5a82cf5709a4bc577f42fdaa61b23a7f58f08
spi: use platform_{get,set}_drvdata() for the upstream commit
that does this SPI subsystem wide.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index 3938a26..4326107 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -399,7 +399,7 @@ static int ocspi_probe(struct platform_device *pdev)
master->dev.of_node = pdev->dev.of_node;
#endif

- dev_set_drvdata(&pdev->dev, master);
+ platform_set_drvdata(pdev, master);

spi = spi_master_get_devdata(master);
spi->master = master;
@@ -439,7 +439,7 @@ static int ocspi_remove(struct platform_device *pdev)
struct spi_master *master;
struct ocspi *spi;

- master = dev_get_drvdata(&pdev->dev);
+ master = platform_get_drvdata(pdev);
spi = spi_master_get_devdata(master);

spi_unregister_master(master);
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:45 UTC
Permalink
Removes boilerplate folded into the module_platform_driver macro.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index 4326107..c9376c8 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -466,18 +466,7 @@ static struct platform_driver ocspi_driver = {
.of_match_table = ocspi_match
}
};
-
-static int __init ocspi_init(void)
-{
- return platform_driver_register(&ocspi_driver);
-}
-module_init(ocspi_init);
-
-static void __exit ocspi_exit(void)
-{
- platform_driver_unregister(&ocspi_driver);
-}
-module_exit(ocspi_exit);
+module_platform_driver(ocspi_driver);

MODULE_DESCRIPTION("OpenCores Simple SPI driver");
MODULE_AUTHOR("Jonas Bonn <jonas at southpole.se>");
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:46 UTC
Permalink
Instead of relying on the cpu clock as the clock source for the
spi device, obtain the clock from the clock framework.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/spi-oc-simple.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi-oc-simple.c b/drivers/spi/spi-oc-simple.c
index c9376c8..ae6263b 100644
--- a/drivers/spi/spi-oc-simple.c
+++ b/drivers/spi/spi-oc-simple.c
@@ -19,8 +19,8 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/spi/spi.h>
+#include <linux/clk.h>
#include <asm/unaligned.h>
-#include <asm/cpuinfo.h>

#define DRIVER_NAME "oc_spi_simple"

@@ -55,6 +55,7 @@ struct ocspi {
void __iomem *base;
unsigned int max_speed;
unsigned int min_speed;
+ struct clk *clk;
};

static inline u8
@@ -85,16 +86,18 @@ ocspi_set_transfer_size(struct ocspi *ocspi, unsigned int size)
}

static inline void
-ocspi_set_baudrate_bits(u8* spcr, u8* sper, unsigned int speed)
+ocspi_set_baudrate_bits(u8* spcr, u8* sper, unsigned int speed,
+ unsigned int clk_freq)
{
int i;

for (i = 0; i <= 11; i++) {
- if ((cpuinfo.clock_frequency >> (1+i)) <= speed)
+ if ((clk_freq >> (1+i)) <= speed)
break;
}

- pr_debug("Established baudrate %d, wanted %d (i=%d)", cpuinfo.clock_frequency >> (1+i), speed, i);
+ pr_debug("Established baudrate %d, wanted %d (i=%d)",
+ clk_freq >> (1+i), speed, i);

/* The register values for some cases are weird... fix here */
switch (i) {
@@ -146,7 +149,6 @@ ocspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
u8 spcr, sper;

ocspi = spi_master_get_devdata(spi->master);
-
if ((t != NULL) && t->speed_hz)
speed = t->speed_hz;

@@ -156,7 +158,7 @@ ocspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
spcr = ocspi_read(ocspi, OCSPI_REG_SPCR);
sper = ocspi_read(ocspi, OCSPI_REG_SPER);

- ocspi_set_baudrate_bits(&spcr, &sper, speed);
+ ocspi_set_baudrate_bits(&spcr, &sper, speed, clk_get_rate(ocspi->clk));
ocspi_set_mode_bits(&spcr, spi->mode);

ocspi_write(ocspi, OCSPI_REG_SPCR, spcr);
@@ -374,6 +376,7 @@ static int ocspi_probe(struct platform_device *pdev)
struct ocspi *spi;
struct resource *r;
int status = 0;
+ unsigned int clk_freq;

master = spi_alloc_master(&pdev->dev, sizeof *spi);
if (master == NULL) {
@@ -404,19 +407,28 @@ static int ocspi_probe(struct platform_device *pdev)
spi = spi_master_get_devdata(master);
spi->master = master;

- spi->max_speed = cpuinfo.clock_frequency >> 1;
- spi->min_speed = cpuinfo.clock_frequency >> 12;
+ spi->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(spi->clk)) {
+ status = PTR_ERR(spi->clk);
+ goto out;
+ }
+ clk_prepare(spi->clk);
+ clk_enable(spi->clk);
+
+ clk_freq = clk_get_rate(spi->clk);
+ spi->max_speed = clk_freq >> 1;
+ spi->min_speed = clk_freq >> 12;

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
status = -ENODEV;
- goto out;
+ goto out_rel_clk;
}

if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
dev_name(&pdev->dev))) {
status = -EBUSY;
- goto out;
+ goto out_rel_clk;
}
spi->base = devm_ioremap_nocache(&pdev->dev, r->start,
resource_size(r));
@@ -429,6 +441,9 @@ static int ocspi_probe(struct platform_device *pdev)

return status;

+out_rel_clk:
+ clk_disable_unprepare(spi->clk);
+ clk_put(spi->clk);
out:
spi_master_put(master);
return status;
@@ -441,6 +456,8 @@ static int ocspi_remove(struct platform_device *pdev)

master = platform_get_drvdata(pdev);
spi = spi_master_get_devdata(master);
+ clk_disable_unprepare(spi->clk);
+ clk_put(spi->clk);

spi_unregister_master(master);
--
1.8.1.2
Stefan Kristiansson
2013-09-01 07:12:47 UTC
Permalink
With the clock frequency derivation from the cpuinfo struct removed from
the driver, this dependency is also actively removed.

Signed-off-by: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
---
drivers/spi/Kconfig | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index fae46d7..3b11f08 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -259,7 +259,6 @@ config SPI_FSL_ESPI

config SPI_OCSIMPLE
tristate "OpenCores Simple SPI Controller"
- depends on OPENRISC
help
Driver for Simple SPI core from OpenCores.org
--
1.8.1.2
Jonas Bonn
2013-09-01 13:07:26 UTC
Permalink
Hi Stefan,
Cool! Glad to see that you're on this track now... the SPI driver
changes look really good in general.

That said, I've been working on the common clock bits, too... see:

http://git.openrisc.net/cgit.cgi/jonas/linux/commit/?h=wip&id=913eedad91fe4ad082d7198174a414b436f51482

That's on a branch with the very descriptive name "wip" in my git
repo. The following commit is relevant, too.

The trouble I've been having is how to get BASE_BAUD to work with
these changes. Without that, we lose the early serial console. Not a
big deal for production use, but annoying for development.

As you've probably figured out by my lack of responsiveness, I'm a bit
pressed for time at the moment and don't have time right now to dig
into this in any depth. It would be great if you could grab those two
patches from my tree, squash them together, and massage your changes
on top of that. The jist of it is that the CPU frequency is also
driven by the oscillator and the bus frequency is a function thereof,
the details of which come entirely from the device tree description.

The SPI driver is not upstream... once we have the common clk bits in
place, that driver becomes arch independent and it should go upstream
via the SPI maintainer.

Your comments are welcome. I'll try to comment on your individual
patches if I get a spare moment.

/Jonas


On 1 September 2013 09:12, Stefan Kristiansson
Post by Stefan Kristiansson
This set of patches brings the OpenCores simple SPI driver up to date
with the current practices used in the SPI subsystem.
A special note is required for the last two patches ("use clock framework to
obtain spi clock" and "remove dependency on OPENRISC for spi-oc-simple").
When used together with OpenRISC, there are two prerequisite patches.
1) openrisc: select COMMON_CLK
https://patchwork.kernel.org/patch/2852461/
2) clk: add generic driver for fixed rate clock
https://patchwork.kernel.org/patch/2852460/
The first goes without comment, the second is needed since we
don't have any board specific init code, but only rely on the device
tree description to setup our boards.
With those two applied, the clock for the spi driver can be described as
below in the dts file.
...
wb_clk: wb_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
clock-output-names = "wb_clk";
};
...
spi0: spi0 at b0000000 {
compatible = "opencores,spi-simple";
reg = <0xb0000000 0x5>;
clocks = <&wb_clk>;
...
};
The rest of the patches can be applied without concerns.
spi/spi_opencores: rename to spi-oc-simple
spi/spi-oc-simple: update driver names in file header
spi/spi-oc-simple: remove __devinit, __devexit, __init and __exit
spi/spi-oc-simple: include module.h
spi/spi-oc-simple: whitespace and format cleanup
spi/spi-oc-simple: remove dead and commented out code
spi/spi-oc-simple: remove unused variables
spi/spi-oc-simple: use the SPI framework queue
spi/spi-oc-simple: use platform_{get,set}_drvdata()
spi/spi-oc-simple: use module_platform_driver to register driver
spi/spi-oc-simple: use clock framework to obtain spi clock
spi: remove dependency on OPENRISC for spi-oc-simple
drivers/spi/Kconfig | 1 -
drivers/spi/Makefile | 2 +-
drivers/spi/spi-oc-simple.c | 490 ++++++++++++++++++++++++++++++
drivers/spi/spi_opencores.c | 707 --------------------------------------------
4 files changed, 491 insertions(+), 709 deletions(-)
create mode 100644 drivers/spi/spi-oc-simple.c
delete mode 100644 drivers/spi/spi_opencores.c
--
1.8.1.2
_______________________________________________
Linux mailing list
Linux at lists.openrisc.net
http://lists.openrisc.net/listinfo/linux
--
Jonas Bonn
Stockholm, Sweden
Stefan Kristiansson
2013-09-01 20:04:48 UTC
Permalink
Post by Jonas Bonn
Hi Stefan,
Cool! Glad to see that you're on this track now... the SPI driver
changes look really good in general.
http://git.openrisc.net/cgit.cgi/jonas/linux/commit/?h=wip&id=913eedad91fe4ad082d7198174a414b436f51482
Heh, seems I'm stepping a bit on your toes there, well better that two persons
try to solve the same problem than none =)
Post by Jonas Bonn
That's on a branch with the very descriptive name "wip" in my git
repo. The following commit is relevant, too.
The trouble I've been having is how to get BASE_BAUD to work with
these changes. Without that, we lose the early serial console. Not a
big deal for production use, but annoying for development.
As you've probably figured out by my lack of responsiveness, I'm a bit
pressed for time at the moment and don't have time right now to dig
into this in any depth. It would be great if you could grab those two
patches from my tree, squash them together, and massage your changes
on top of that. The jist of it is that the CPU frequency is also
driven by the oscillator and the bus frequency is a function thereof,
the details of which come entirely from the device tree description.
I took a quick look, and your changes are not really clashing with the driver
patch I sent to lkml, but they *do* render it needless for OpenRISC.
(All it does is essentially what you do in kernel/time.c, but as a driver
with "fixed-clk" in the match table).
I have to still say that it's a bit backwards how it currently works in the
kernel, defining a fixed-clock in the dts should, IMO, just work(tm).
Without any arch/soc/board needing to initialize it.
So perhaps that patch has a place anyways, in that form or another.
Let's see if there will be any comments on it, or if it'll just be ignored ;)

I'll be happy to poke around your wip and see what falls out from it,
because you're absolutely right what you said in the other mail, it'd
be really great to have our common clock setup sorted out.
I've got a couple of other things in the pipeline (you're not the only one
that is busy =)) that I'm going to give higher priority, but this will
still be among the top ones.
Post by Jonas Bonn
The SPI driver is not upstream... once we have the common clk bits in
place, that driver becomes arch independent and it should go upstream
via the SPI maintainer.
Actually, for the driver itself, there's no question marks regarding
how it handles the common clock framework. That is not going to change
whatever way we come up with to define the clocks within OpenRISC.
So I'd say it's in pretty good shape for upstreaming, as of today.
But as you indicated in the other mail, after a bit more test usage.
I have tested it on my de0 nano board together with a touch screen controller
and a spi flash, that have worked flawlessly so far.

Stefan

Jonas Bonn
2013-09-01 13:24:29 UTC
Permalink
I pushed patches 1-10 to master since they look good and I trust
Stefan to have tested all this! :)

That said, I haven't even tried to compile it and don't currently have
any hardware to test this on anyway, so please send patches that fix
regressions if you find any and I'll blindly pull those, too! :)

Thanks, Stefan. Nice work. Just the common clk bits to sort out
which will be a major improvement on more fronts than just this
driver.

/Jonas

On 1 September 2013 09:12, Stefan Kristiansson
Post by Stefan Kristiansson
This set of patches brings the OpenCores simple SPI driver up to date
with the current practices used in the SPI subsystem.
A special note is required for the last two patches ("use clock framework to
obtain spi clock" and "remove dependency on OPENRISC for spi-oc-simple").
When used together with OpenRISC, there are two prerequisite patches.
1) openrisc: select COMMON_CLK
https://patchwork.kernel.org/patch/2852461/
2) clk: add generic driver for fixed rate clock
https://patchwork.kernel.org/patch/2852460/
The first goes without comment, the second is needed since we
don't have any board specific init code, but only rely on the device
tree description to setup our boards.
With those two applied, the clock for the spi driver can be described as
below in the dts file.
...
wb_clk: wb_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
clock-output-names = "wb_clk";
};
...
spi0: spi0 at b0000000 {
compatible = "opencores,spi-simple";
reg = <0xb0000000 0x5>;
clocks = <&wb_clk>;
...
};
The rest of the patches can be applied without concerns.
spi/spi_opencores: rename to spi-oc-simple
spi/spi-oc-simple: update driver names in file header
spi/spi-oc-simple: remove __devinit, __devexit, __init and __exit
spi/spi-oc-simple: include module.h
spi/spi-oc-simple: whitespace and format cleanup
spi/spi-oc-simple: remove dead and commented out code
spi/spi-oc-simple: remove unused variables
spi/spi-oc-simple: use the SPI framework queue
spi/spi-oc-simple: use platform_{get,set}_drvdata()
spi/spi-oc-simple: use module_platform_driver to register driver
spi/spi-oc-simple: use clock framework to obtain spi clock
spi: remove dependency on OPENRISC for spi-oc-simple
drivers/spi/Kconfig | 1 -
drivers/spi/Makefile | 2 +-
drivers/spi/spi-oc-simple.c | 490 ++++++++++++++++++++++++++++++
drivers/spi/spi_opencores.c | 707 --------------------------------------------
4 files changed, 491 insertions(+), 709 deletions(-)
create mode 100644 drivers/spi/spi-oc-simple.c
delete mode 100644 drivers/spi/spi_opencores.c
--
1.8.1.2
_______________________________________________
Linux mailing list
Linux at lists.openrisc.net
http://lists.openrisc.net/listinfo/linux
--
Jonas Bonn
Stockholm, Sweden
Loading...