* [PATCH 0/6] SPI ThunderX driver
@ 2016-07-23 10:42 ` Jan Glauber
0 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
Hi Mark,
This series adds support for SPI on Cavium's ThunderX (arm64). The SPI
hardware is the same as on MIPS Octeon, the only difference is that the
device appears as a PCI device. To avoid copy and paste of the Octeon
driver I've moved the common parts into a shared file.
Patches #1-5 prepare the Octeon driver for re-use.
Patch #6 adds the ThunderX driver.
The series was tested on MIPS (Edge Router PRO and cn71xx) and ThunderX.
Feedback welcome!
thanks,
Jan
Jan Glauber (5):
spi: octeon: Store system clock freqency in struct octeon_spi
spi: octeon: Put register offsets into a struct
spi: octeon: Move include file from arch/mips to drivers/spi
spi: octeon: Split driver into Octeon specific and common parts
spi: octeon: Add thunderx driver
Steven J. Hill (1):
spi: octeon: Convert driver to use readq()/writeq() functions
drivers/spi/Kconfig | 7 +
drivers/spi/Makefile | 3 +
drivers/spi/spi-cavium-octeon.c | 104 +++++++++
drivers/spi/spi-cavium-thunderx.c | 158 +++++++++++++
drivers/spi/spi-cavium.c | 151 ++++++++++++
.../cvmx-mpi-defs.h => drivers/spi/spi-cavium.h | 62 ++---
drivers/spi/spi-octeon.c | 255 ---------------------
7 files changed, 456 insertions(+), 284 deletions(-)
create mode 100644 drivers/spi/spi-cavium-octeon.c
create mode 100644 drivers/spi/spi-cavium-thunderx.c
create mode 100644 drivers/spi/spi-cavium.c
rename arch/mips/include/asm/octeon/cvmx-mpi-defs.h => drivers/spi/spi-cavium.h (84%)
delete mode 100644 drivers/spi/spi-octeon.c
--
2.9.0.rc0.21.g7777322
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 1/6] spi: octeon: Convert driver to use readq()/writeq() functions
2016-07-23 10:42 ` Jan Glauber
(?)
@ 2016-07-23 10:42 ` Jan Glauber
-1 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
From: "Steven J. Hill" <steven.hill@cavium.com>
Remove all calls to cvmx_read_csr()/cvmx_write_csr() and use
the portable readq()/writeq() functions.
Signed-off-by: Steven J. Hill <steven.hill@cavium.com>
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/spi/spi-octeon.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c
index 3b17009..b53ba53 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-octeon.c
@@ -27,7 +27,7 @@
#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
struct octeon_spi {
- u64 register_base;
+ void __iomem *register_base;
u64 last_cfg;
u64 cs_enax;
};
@@ -40,7 +40,7 @@ static void octeon_spi_wait_ready(struct octeon_spi *p)
do {
if (loops++)
__delay(500);
- mpi_sts.u64 = cvmx_read_csr(p->register_base + OCTEON_SPI_STS);
+ mpi_sts.u64 = readq(p->register_base + OCTEON_SPI_STS);
} while (mpi_sts.s.busy);
}
@@ -85,7 +85,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
if (mpi_cfg.u64 != p->last_cfg) {
p->last_cfg = mpi_cfg.u64;
- cvmx_write_csr(p->register_base + OCTEON_SPI_CFG, mpi_cfg.u64);
+ writeq(mpi_cfg.u64, p->register_base + OCTEON_SPI_CFG);
}
tx_buf = xfer->tx_buf;
rx_buf = xfer->rx_buf;
@@ -97,19 +97,19 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
d = *tx_buf++;
else
d = 0;
- cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
+ writeq(d, p->register_base + OCTEON_SPI_DAT0 + (8 * i));
}
mpi_tx.u64 = 0;
mpi_tx.s.csid = spi->chip_select;
mpi_tx.s.leavecs = 1;
mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
- cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
+ writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX);
octeon_spi_wait_ready(p);
if (rx_buf)
for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
- u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ u64 v = readq(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
*rx_buf++ = (u8)v;
}
len -= OCTEON_SPI_MAX_BYTES;
@@ -121,7 +121,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
d = *tx_buf++;
else
d = 0;
- cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
+ writeq(d, p->register_base + OCTEON_SPI_DAT0 + (8 * i));
}
mpi_tx.u64 = 0;
@@ -132,12 +132,12 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
mpi_tx.s.leavecs = !xfer->cs_change;
mpi_tx.s.txnum = tx_buf ? len : 0;
mpi_tx.s.totnum = len;
- cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
+ writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX);
octeon_spi_wait_ready(p);
if (rx_buf)
for (i = 0; i < len; i++) {
- u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ u64 v = readq(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
*rx_buf++ = (u8)v;
}
@@ -193,7 +193,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
goto fail;
}
- p->register_base = (u64)reg_base;
+ p->register_base = reg_base;
master->num_chipselect = 4;
master->mode_bits = SPI_CPHA |
@@ -225,10 +225,9 @@ static int octeon_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct octeon_spi *p = spi_master_get_devdata(master);
- u64 register_base = p->register_base;
/* Clear the CSENA* and put everything in a known state. */
- cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
+ writeq(0, p->register_base + OCTEON_SPI_CFG);
return 0;
}
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 2/6] spi: octeon: Store system clock freqency in struct octeon_spi
2016-07-23 10:42 ` Jan Glauber
(?)
(?)
@ 2016-07-23 10:42 ` Jan Glauber
-1 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
Storing the system clock frequency in struct octeon_spi avoids
calling the MIPS specific octeon_get_io_clock_rate() for every transfer.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
Tested-by: Steven J. Hill <steven.hill@cavium.com>
---
drivers/spi/spi-octeon.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c
index b53ba53..e722040 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-octeon.c
@@ -30,6 +30,7 @@ struct octeon_spi {
void __iomem *register_base;
u64 last_cfg;
u64 cs_enax;
+ int sys_freq;
};
static void octeon_spi_wait_ready(struct octeon_spi *p)
@@ -53,7 +54,6 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
union cvmx_mpi_cfg mpi_cfg;
union cvmx_mpi_tx mpi_tx;
unsigned int clkdiv;
- unsigned int speed_hz;
int mode;
bool cpha, cpol;
const u8 *tx_buf;
@@ -65,9 +65,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
cpha = mode & SPI_CPHA;
cpol = mode & SPI_CPOL;
- speed_hz = xfer->speed_hz;
-
- clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz);
+ clkdiv = p->sys_freq / (2 * xfer->speed_hz);
mpi_cfg.u64 = 0;
@@ -194,6 +192,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
}
p->register_base = reg_base;
+ p->sys_freq = octeon_get_io_clock_rate();
master->num_chipselect = 4;
master->mode_bits = SPI_CPHA |
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 3/6] spi: octeon: Put register offsets into a struct
2016-07-23 10:42 ` Jan Glauber
` (2 preceding siblings ...)
(?)
@ 2016-07-23 10:42 ` Jan Glauber
-1 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
Instead of hard-coding the register offsets put them into a struct
and set them in the probe function.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
Tested-by: Steven J. Hill <steven.hill@cavium.com>
---
drivers/spi/spi-octeon.c | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c
index e722040..209eddc 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-octeon.c
@@ -17,22 +17,30 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-mpi-defs.h>
-#define OCTEON_SPI_CFG 0
-#define OCTEON_SPI_STS 0x08
-#define OCTEON_SPI_TX 0x10
-#define OCTEON_SPI_DAT0 0x80
-
#define OCTEON_SPI_MAX_BYTES 9
#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
+struct octeon_spi_regs {
+ int config;
+ int status;
+ int tx;
+ int data;
+};
+
struct octeon_spi {
void __iomem *register_base;
u64 last_cfg;
u64 cs_enax;
int sys_freq;
+ struct octeon_spi_regs regs;
};
+#define OCTEON_SPI_CFG(x) (x->regs.config)
+#define OCTEON_SPI_STS(x) (x->regs.status)
+#define OCTEON_SPI_TX(x) (x->regs.tx)
+#define OCTEON_SPI_DAT0(x) (x->regs.data)
+
static void octeon_spi_wait_ready(struct octeon_spi *p)
{
union cvmx_mpi_sts mpi_sts;
@@ -41,7 +49,7 @@ static void octeon_spi_wait_ready(struct octeon_spi *p)
do {
if (loops++)
__delay(500);
- mpi_sts.u64 = readq(p->register_base + OCTEON_SPI_STS);
+ mpi_sts.u64 = readq(p->register_base + OCTEON_SPI_STS(p));
} while (mpi_sts.s.busy);
}
@@ -83,7 +91,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
if (mpi_cfg.u64 != p->last_cfg) {
p->last_cfg = mpi_cfg.u64;
- writeq(mpi_cfg.u64, p->register_base + OCTEON_SPI_CFG);
+ writeq(mpi_cfg.u64, p->register_base + OCTEON_SPI_CFG(p));
}
tx_buf = xfer->tx_buf;
rx_buf = xfer->rx_buf;
@@ -95,19 +103,19 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
d = *tx_buf++;
else
d = 0;
- writeq(d, p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
}
mpi_tx.u64 = 0;
mpi_tx.s.csid = spi->chip_select;
mpi_tx.s.leavecs = 1;
mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
- writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX);
+ writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
octeon_spi_wait_ready(p);
if (rx_buf)
for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
- u64 v = readq(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
*rx_buf++ = (u8)v;
}
len -= OCTEON_SPI_MAX_BYTES;
@@ -119,7 +127,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
d = *tx_buf++;
else
d = 0;
- writeq(d, p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
}
mpi_tx.u64 = 0;
@@ -130,12 +138,12 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
mpi_tx.s.leavecs = !xfer->cs_change;
mpi_tx.s.txnum = tx_buf ? len : 0;
mpi_tx.s.totnum = len;
- writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX);
+ writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
octeon_spi_wait_ready(p);
if (rx_buf)
for (i = 0; i < len; i++) {
- u64 v = readq(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+ u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
*rx_buf++ = (u8)v;
}
@@ -194,6 +202,11 @@ static int octeon_spi_probe(struct platform_device *pdev)
p->register_base = reg_base;
p->sys_freq = octeon_get_io_clock_rate();
+ p->regs.config = 0;
+ p->regs.status = 0x08;
+ p->regs.tx = 0x10;
+ p->regs.data = 0x80;
+
master->num_chipselect = 4;
master->mode_bits = SPI_CPHA |
SPI_CPOL |
@@ -226,7 +239,7 @@ static int octeon_spi_remove(struct platform_device *pdev)
struct octeon_spi *p = spi_master_get_devdata(master);
/* Clear the CSENA* and put everything in a known state. */
- writeq(0, p->register_base + OCTEON_SPI_CFG);
+ writeq(0, p->register_base + OCTEON_SPI_CFG(p));
return 0;
}
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 4/6] spi: octeon: Move include file from arch/mips to drivers/spi
2016-07-23 10:42 ` Jan Glauber
` (3 preceding siblings ...)
(?)
@ 2016-07-23 10:42 ` Jan Glauber
-1 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
Move the register definitions to the drivers directory because they
are only used there.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
Tested-by: Steven J. Hill <steven.hill@cavium.com>
---
.../cvmx-mpi-defs.h => drivers/spi/spi-cavium.h | 32 +---------------------
drivers/spi/spi-octeon.c | 3 +-
2 files changed, 3 insertions(+), 32 deletions(-)
rename arch/mips/include/asm/octeon/cvmx-mpi-defs.h => drivers/spi/spi-cavium.h (84%)
diff --git a/arch/mips/include/asm/octeon/cvmx-mpi-defs.h b/drivers/spi/spi-cavium.h
similarity index 84%
rename from arch/mips/include/asm/octeon/cvmx-mpi-defs.h
rename to drivers/spi/spi-cavium.h
index 4615b10..d41dba5 100644
--- a/arch/mips/include/asm/octeon/cvmx-mpi-defs.h
+++ b/drivers/spi/spi-cavium.h
@@ -1,32 +1,4 @@
-/***********************license start***************
- * Author: Cavium Networks
- *
- * Contact: support@caviumnetworks.com
- * This file is part of the OCTEON SDK
- *
- * Copyright (c) 2003-2012 Cavium Networks
- *
- * This file 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 file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- * or visit http://www.gnu.org/licenses/.
- *
- * This file may also be available under a different license from Cavium.
- * Contact Cavium Networks for more information
- ***********************license end**************************************/
-
-#ifndef __CVMX_MPI_DEFS_H__
-#define __CVMX_MPI_DEFS_H__
+/* MPI register descriptions */
#define CVMX_MPI_CFG (CVMX_ADD_IO_SEG(0x0001070000001000ull))
#define CVMX_MPI_DATX(offset) (CVMX_ADD_IO_SEG(0x0001070000001080ull) + ((offset) & 15) * 8)
@@ -324,5 +296,3 @@ union cvmx_mpi_tx {
struct cvmx_mpi_tx_s cn66xx;
struct cvmx_mpi_tx_cn61xx cnf71xx;
};
-
-#endif
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c
index 209eddc..2180176 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-octeon.c
@@ -15,7 +15,8 @@
#include <linux/of.h>
#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-mpi-defs.h>
+
+#include "spi-cavium.h"
#define OCTEON_SPI_MAX_BYTES 9
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts
2016-07-23 10:42 ` Jan Glauber
` (4 preceding siblings ...)
(?)
@ 2016-07-23 10:42 ` Jan Glauber
2016-07-24 18:38 ` Paul Gortmaker
[not found] ` <edfc55f3653fedd5e13a8bd1282e089b269a4e61.1469174814.git.jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
-1 siblings, 2 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
Separate driver probing from SPI transfer functions.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
Tested-by: Steven J. Hill <steven.hill@cavium.com>
---
drivers/spi/Makefile | 1 +
drivers/spi/spi-cavium-octeon.c | 104 +++++++++++++++++++++++++
drivers/spi/{spi-octeon.c => spi-cavium.c} | 120 +----------------------------
drivers/spi/spi-cavium.h | 31 ++++++++
4 files changed, 138 insertions(+), 118 deletions(-)
create mode 100644 drivers/spi/spi-cavium-octeon.c
rename drivers/spi/{spi-octeon.c => spi-cavium.c} (55%)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3c74d00..185367e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
+spi-octeon-objs := spi-cavium.o spi-cavium-octeon.o
obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o
diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c
new file mode 100644
index 0000000..ee4703e
--- /dev/null
+++ b/drivers/spi/spi-cavium-octeon.c
@@ -0,0 +1,104 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "spi-cavium.h"
+
+static int octeon_spi_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ void __iomem *reg_base;
+ struct spi_master *master;
+ struct octeon_spi *p;
+ int err = -ENOENT;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
+ if (!master)
+ return -ENOMEM;
+ p = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, master);
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (IS_ERR(reg_base)) {
+ err = PTR_ERR(reg_base);
+ goto fail;
+ }
+
+ p->register_base = reg_base;
+ p->sys_freq = octeon_get_io_clock_rate();
+
+ p->regs.config = 0;
+ p->regs.status = 0x08;
+ p->regs.tx = 0x10;
+ p->regs.data = 0x80;
+
+ master->num_chipselect = 4;
+ master->mode_bits = SPI_CPHA |
+ SPI_CPOL |
+ SPI_CS_HIGH |
+ SPI_LSB_FIRST |
+ SPI_3WIRE;
+
+ master->transfer_one_message = octeon_spi_transfer_one_message;
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
+ master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
+
+ master->dev.of_node = pdev->dev.of_node;
+ err = devm_spi_register_master(&pdev->dev, master);
+ if (err) {
+ dev_err(&pdev->dev, "register master failed: %d\n", err);
+ goto fail;
+ }
+
+ dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
+
+ return 0;
+fail:
+ spi_master_put(master);
+ return err;
+}
+
+static int octeon_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct octeon_spi *p = spi_master_get_devdata(master);
+
+ /* Clear the CSENA* and put everything in a known state. */
+ writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ return 0;
+}
+
+static const struct of_device_id octeon_spi_match[] = {
+ { .compatible = "cavium,octeon-3010-spi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_spi_match);
+
+static struct platform_driver octeon_spi_driver = {
+ .driver = {
+ .name = "spi-octeon",
+ .of_match_table = octeon_spi_match,
+ },
+ .probe = octeon_spi_probe,
+ .remove = octeon_spi_remove,
+};
+
+module_platform_driver(octeon_spi_driver);
+
+MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-cavium.c
similarity index 55%
rename from drivers/spi/spi-octeon.c
rename to drivers/spi/spi-cavium.c
index 2180176..5aaf215 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-cavium.c
@@ -6,42 +6,13 @@
* Copyright (C) 2011, 2012 Cavium, Inc.
*/
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/of.h>
-
-#include <asm/octeon/octeon.h>
#include "spi-cavium.h"
-#define OCTEON_SPI_MAX_BYTES 9
-
-#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
-
-struct octeon_spi_regs {
- int config;
- int status;
- int tx;
- int data;
-};
-
-struct octeon_spi {
- void __iomem *register_base;
- u64 last_cfg;
- u64 cs_enax;
- int sys_freq;
- struct octeon_spi_regs regs;
-};
-
-#define OCTEON_SPI_CFG(x) (x->regs.config)
-#define OCTEON_SPI_STS(x) (x->regs.status)
-#define OCTEON_SPI_TX(x) (x->regs.tx)
-#define OCTEON_SPI_DAT0(x) (x->regs.data)
-
static void octeon_spi_wait_ready(struct octeon_spi *p)
{
union cvmx_mpi_sts mpi_sts;
@@ -154,8 +125,8 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
return xfer->len;
}
-static int octeon_spi_transfer_one_message(struct spi_master *master,
- struct spi_message *msg)
+int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg)
{
struct octeon_spi *p = spi_master_get_devdata(master);
unsigned int total_len = 0;
@@ -178,90 +149,3 @@ err:
spi_finalize_current_message(master);
return status;
}
-
-static int octeon_spi_probe(struct platform_device *pdev)
-{
- struct resource *res_mem;
- void __iomem *reg_base;
- struct spi_master *master;
- struct octeon_spi *p;
- int err = -ENOENT;
-
- master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
- if (!master)
- return -ENOMEM;
- p = spi_master_get_devdata(master);
- platform_set_drvdata(pdev, master);
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
- if (IS_ERR(reg_base)) {
- err = PTR_ERR(reg_base);
- goto fail;
- }
-
- p->register_base = reg_base;
- p->sys_freq = octeon_get_io_clock_rate();
-
- p->regs.config = 0;
- p->regs.status = 0x08;
- p->regs.tx = 0x10;
- p->regs.data = 0x80;
-
- master->num_chipselect = 4;
- master->mode_bits = SPI_CPHA |
- SPI_CPOL |
- SPI_CS_HIGH |
- SPI_LSB_FIRST |
- SPI_3WIRE;
-
- master->transfer_one_message = octeon_spi_transfer_one_message;
- master->bits_per_word_mask = SPI_BPW_MASK(8);
- master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
-
- master->dev.of_node = pdev->dev.of_node;
- err = devm_spi_register_master(&pdev->dev, master);
- if (err) {
- dev_err(&pdev->dev, "register master failed: %d\n", err);
- goto fail;
- }
-
- dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
-
- return 0;
-fail:
- spi_master_put(master);
- return err;
-}
-
-static int octeon_spi_remove(struct platform_device *pdev)
-{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct octeon_spi *p = spi_master_get_devdata(master);
-
- /* Clear the CSENA* and put everything in a known state. */
- writeq(0, p->register_base + OCTEON_SPI_CFG(p));
-
- return 0;
-}
-
-static const struct of_device_id octeon_spi_match[] = {
- { .compatible = "cavium,octeon-3010-spi", },
- {},
-};
-MODULE_DEVICE_TABLE(of, octeon_spi_match);
-
-static struct platform_driver octeon_spi_driver = {
- .driver = {
- .name = "spi-octeon",
- .of_match_table = octeon_spi_match,
- },
- .probe = octeon_spi_probe,
- .remove = octeon_spi_remove,
-};
-
-module_platform_driver(octeon_spi_driver);
-
-MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
-MODULE_AUTHOR("David Daney");
-MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-cavium.h b/drivers/spi/spi-cavium.h
index d41dba5..88c5f36 100644
--- a/drivers/spi/spi-cavium.h
+++ b/drivers/spi/spi-cavium.h
@@ -1,3 +1,32 @@
+#ifndef __SPI_CAVIUM_H
+#define __SPI_CAVIUM_H
+
+#define OCTEON_SPI_MAX_BYTES 9
+#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
+
+struct octeon_spi_regs {
+ int config;
+ int status;
+ int tx;
+ int data;
+};
+
+struct octeon_spi {
+ void __iomem *register_base;
+ u64 last_cfg;
+ u64 cs_enax;
+ int sys_freq;
+ struct octeon_spi_regs regs;
+};
+
+#define OCTEON_SPI_CFG(x) (x->regs.config)
+#define OCTEON_SPI_STS(x) (x->regs.status)
+#define OCTEON_SPI_TX(x) (x->regs.tx)
+#define OCTEON_SPI_DAT0(x) (x->regs.data)
+
+int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg);
+
/* MPI register descriptions */
#define CVMX_MPI_CFG (CVMX_ADD_IO_SEG(0x0001070000001000ull))
@@ -296,3 +325,5 @@ union cvmx_mpi_tx {
struct cvmx_mpi_tx_s cn66xx;
struct cvmx_mpi_tx_cn61xx cnf71xx;
};
+
+#endif /* __SPI_CAVIUM_H */
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts
2016-07-23 10:42 ` [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts Jan Glauber
@ 2016-07-24 18:38 ` Paul Gortmaker
[not found] ` <CAP=VYLrQDwCfYFCkxd0N4PfgP-2U+pcw_Gm0Yo_8m0=0o3pBrA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[not found] ` <edfc55f3653fedd5e13a8bd1282e089b269a4e61.1469174814.git.jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
1 sibling, 1 reply; 38+ messages in thread
From: Paul Gortmaker @ 2016-07-24 18:38 UTC (permalink / raw)
To: Jan Glauber; +Cc: Mark Brown, LKML, linux-spi, Steven J. Hill, David Daney
On Sat, Jul 23, 2016 at 6:42 AM, Jan Glauber <jglauber@cavium.com> wrote:
> Separate driver probing from SPI transfer functions.
>
> Signed-off-by: Jan Glauber <jglauber@cavium.com>
> Tested-by: Steven J. Hill <steven.hill@cavium.com>
> ---
> drivers/spi/Makefile | 1 +
> drivers/spi/spi-cavium-octeon.c | 104 +++++++++++++++++++++++++
> drivers/spi/{spi-octeon.c => spi-cavium.c} | 120 +----------------------------
> drivers/spi/spi-cavium.h | 31 ++++++++
> 4 files changed, 138 insertions(+), 118 deletions(-)
> create mode 100644 drivers/spi/spi-cavium-octeon.c
> rename drivers/spi/{spi-octeon.c => spi-cavium.c} (55%)
>
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 3c74d00..185367e 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -56,6 +56,7 @@ obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
> obj-$(CONFIG_SPI_MXS) += spi-mxs.o
> obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
> obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
> +spi-octeon-objs := spi-cavium.o spi-cavium-octeon.o
> obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
> obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
> obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o
> diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c
> new file mode 100644
> index 0000000..ee4703e
> --- /dev/null
> +++ b/drivers/spi/spi-cavium-octeon.c
> @@ -0,0 +1,104 @@
> +/*
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file "COPYING" in the main directory of this archive
> + * for more details.
> + *
> + * Copyright (C) 2011, 2012 Cavium, Inc.
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/spi/spi.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
[...]
> +MODULE_DEVICE_TABLE(of, octeon_spi_match);
> +
> +static struct platform_driver octeon_spi_driver = {
> + .driver = {
> + .name = "spi-octeon",
> + .of_match_table = octeon_spi_match,
> + },
> + .probe = octeon
_spi_probe,
> + .remove = octeon_spi_remove,
> +};
> +
> +module_platform_driver(octeon_spi_driver);
> +
> +MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
> +MODULE_AUTHOR("David Daney");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-cavium.c
> similarity index 55%
> rename from drivers/spi/spi-octeon.c
> rename to drivers/spi/spi-cavium.c
> index 2180176..5aaf215 100644
> --- a/drivers/spi/spi-octeon.c
> +++ b/drivers/spi/spi-cavium.c
> @@ -6,42 +6,13 @@
> * Copyright (C) 2011, 2012 Cavium, Inc.
> */
>
> -#include <linux/platform_device.h>
> -#include <linux/interrupt.h>
> #include <linux/spi/spi.h>
> #include <linux/module.h>
It almost looks like all the modular stuff got moved to the new file and
maybe the above module.h isn't needed in the original file anymore?
Paul.
--
> #include <linux/delay.h>
> #include <linux/io.h>
> -#include <linux/of.h>
> -
> -#include <asm/octeon/octeon.h>
>
> #include "spi-cavium.h"
[...]
^ permalink raw reply [flat|nested] 38+ messages in thread[parent not found: <edfc55f3653fedd5e13a8bd1282e089b269a4e61.1469174814.git.jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>]
* Re: [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts
2016-07-23 10:42 ` [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts Jan Glauber
@ 2016-07-24 20:54 ` Mark Brown
[not found] ` <edfc55f3653fedd5e13a8bd1282e089b269a4e61.1469174814.git.jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
1 sibling, 0 replies; 38+ messages in thread
From: Mark Brown @ 2016-07-24 20:54 UTC (permalink / raw)
To: Jan Glauber
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA, Steven J. Hill, David Daney
[-- Attachment #1: Type: text/plain, Size: 147 bytes --]
On Sat, Jul 23, 2016 at 12:42:54PM +0200, Jan Glauber wrote:
> + dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
This is just noise, remove it.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts
@ 2016-07-24 20:54 ` Mark Brown
0 siblings, 0 replies; 38+ messages in thread
From: Mark Brown @ 2016-07-24 20:54 UTC (permalink / raw)
To: Jan Glauber; +Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney
[-- Attachment #1: Type: text/plain, Size: 147 bytes --]
On Sat, Jul 23, 2016 at 12:42:54PM +0200, Jan Glauber wrote:
> + dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
This is just noise, remove it.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
[parent not found: <20160724205416.GA6345-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>]
* Re: [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts
2016-07-24 20:54 ` Mark Brown
@ 2016-07-25 11:37 ` Jan Glauber
-1 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-25 11:37 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA, Steven J. Hill, David Daney
On Sun, Jul 24, 2016 at 09:54:16PM +0100, Mark Brown wrote:
> On Sat, Jul 23, 2016 at 12:42:54PM +0200, Jan Glauber wrote:
>
> > + dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
>
> This is just noise, remove it.
I'll remove these in both drivers.
Thanks,
Jan
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 5/6] spi: octeon: Split driver into Octeon specific and common parts
@ 2016-07-25 11:37 ` Jan Glauber
0 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-25 11:37 UTC (permalink / raw)
To: Mark Brown; +Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney
On Sun, Jul 24, 2016 at 09:54:16PM +0100, Mark Brown wrote:
> On Sat, Jul 23, 2016 at 12:42:54PM +0200, Jan Glauber wrote:
>
> > + dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
>
> This is just noise, remove it.
I'll remove these in both drivers.
Thanks,
Jan
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH v2] spi: octeon: Split driver into Octeon specific and common parts
2016-07-24 20:54 ` Mark Brown
@ 2016-07-25 17:49 ` Jan Glauber
-1 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-25 17:49 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-spi-u79uwXL29TY76Z2rM5mHXA, David Daney, Steven J . Hill,
Paul Gortmaker, Jan Glauber
Separate driver probing from SPI transfer functions.
Signed-off-by: Jan Glauber <jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
drivers/spi/Makefile | 1 +
drivers/spi/spi-cavium-octeon.c | 102 ++++++++++++++++++++++++
drivers/spi/{spi-octeon.c => spi-cavium.c} | 122 +----------------------------
drivers/spi/spi-cavium.h | 31 ++++++++
4 files changed, 136 insertions(+), 120 deletions(-)
create mode 100644 drivers/spi/spi-cavium-octeon.c
rename drivers/spi/{spi-octeon.c => spi-cavium.c} (54%)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3c74d00..185367e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
+spi-octeon-objs := spi-cavium.o spi-cavium-octeon.o
obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o
diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c
new file mode 100644
index 0000000..97310c1
--- /dev/null
+++ b/drivers/spi/spi-cavium-octeon.c
@@ -0,0 +1,102 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "spi-cavium.h"
+
+static int octeon_spi_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ void __iomem *reg_base;
+ struct spi_master *master;
+ struct octeon_spi *p;
+ int err = -ENOENT;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
+ if (!master)
+ return -ENOMEM;
+ p = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, master);
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (IS_ERR(reg_base)) {
+ err = PTR_ERR(reg_base);
+ goto fail;
+ }
+
+ p->register_base = reg_base;
+ p->sys_freq = octeon_get_io_clock_rate();
+
+ p->regs.config = 0;
+ p->regs.status = 0x08;
+ p->regs.tx = 0x10;
+ p->regs.data = 0x80;
+
+ master->num_chipselect = 4;
+ master->mode_bits = SPI_CPHA |
+ SPI_CPOL |
+ SPI_CS_HIGH |
+ SPI_LSB_FIRST |
+ SPI_3WIRE;
+
+ master->transfer_one_message = octeon_spi_transfer_one_message;
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
+ master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
+
+ master->dev.of_node = pdev->dev.of_node;
+ err = devm_spi_register_master(&pdev->dev, master);
+ if (err) {
+ dev_err(&pdev->dev, "register master failed: %d\n", err);
+ goto fail;
+ }
+
+ return 0;
+fail:
+ spi_master_put(master);
+ return err;
+}
+
+static int octeon_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct octeon_spi *p = spi_master_get_devdata(master);
+
+ /* Clear the CSENA* and put everything in a known state. */
+ writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ return 0;
+}
+
+static const struct of_device_id octeon_spi_match[] = {
+ { .compatible = "cavium,octeon-3010-spi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_spi_match);
+
+static struct platform_driver octeon_spi_driver = {
+ .driver = {
+ .name = "spi-octeon",
+ .of_match_table = octeon_spi_match,
+ },
+ .probe = octeon_spi_probe,
+ .remove = octeon_spi_remove,
+};
+
+module_platform_driver(octeon_spi_driver);
+
+MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-cavium.c
similarity index 54%
rename from drivers/spi/spi-octeon.c
rename to drivers/spi/spi-cavium.c
index 2180176..8857e7d 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-cavium.c
@@ -6,42 +6,11 @@
* Copyright (C) 2011, 2012 Cavium, Inc.
*/
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
#include <linux/spi/spi.h>
-#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/of.h>
-
-#include <asm/octeon/octeon.h>
#include "spi-cavium.h"
-#define OCTEON_SPI_MAX_BYTES 9
-
-#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
-
-struct octeon_spi_regs {
- int config;
- int status;
- int tx;
- int data;
-};
-
-struct octeon_spi {
- void __iomem *register_base;
- u64 last_cfg;
- u64 cs_enax;
- int sys_freq;
- struct octeon_spi_regs regs;
-};
-
-#define OCTEON_SPI_CFG(x) (x->regs.config)
-#define OCTEON_SPI_STS(x) (x->regs.status)
-#define OCTEON_SPI_TX(x) (x->regs.tx)
-#define OCTEON_SPI_DAT0(x) (x->regs.data)
-
static void octeon_spi_wait_ready(struct octeon_spi *p)
{
union cvmx_mpi_sts mpi_sts;
@@ -154,8 +123,8 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
return xfer->len;
}
-static int octeon_spi_transfer_one_message(struct spi_master *master,
- struct spi_message *msg)
+int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg)
{
struct octeon_spi *p = spi_master_get_devdata(master);
unsigned int total_len = 0;
@@ -178,90 +147,3 @@ err:
spi_finalize_current_message(master);
return status;
}
-
-static int octeon_spi_probe(struct platform_device *pdev)
-{
- struct resource *res_mem;
- void __iomem *reg_base;
- struct spi_master *master;
- struct octeon_spi *p;
- int err = -ENOENT;
-
- master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
- if (!master)
- return -ENOMEM;
- p = spi_master_get_devdata(master);
- platform_set_drvdata(pdev, master);
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
- if (IS_ERR(reg_base)) {
- err = PTR_ERR(reg_base);
- goto fail;
- }
-
- p->register_base = reg_base;
- p->sys_freq = octeon_get_io_clock_rate();
-
- p->regs.config = 0;
- p->regs.status = 0x08;
- p->regs.tx = 0x10;
- p->regs.data = 0x80;
-
- master->num_chipselect = 4;
- master->mode_bits = SPI_CPHA |
- SPI_CPOL |
- SPI_CS_HIGH |
- SPI_LSB_FIRST |
- SPI_3WIRE;
-
- master->transfer_one_message = octeon_spi_transfer_one_message;
- master->bits_per_word_mask = SPI_BPW_MASK(8);
- master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
-
- master->dev.of_node = pdev->dev.of_node;
- err = devm_spi_register_master(&pdev->dev, master);
- if (err) {
- dev_err(&pdev->dev, "register master failed: %d\n", err);
- goto fail;
- }
-
- dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
-
- return 0;
-fail:
- spi_master_put(master);
- return err;
-}
-
-static int octeon_spi_remove(struct platform_device *pdev)
-{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct octeon_spi *p = spi_master_get_devdata(master);
-
- /* Clear the CSENA* and put everything in a known state. */
- writeq(0, p->register_base + OCTEON_SPI_CFG(p));
-
- return 0;
-}
-
-static const struct of_device_id octeon_spi_match[] = {
- { .compatible = "cavium,octeon-3010-spi", },
- {},
-};
-MODULE_DEVICE_TABLE(of, octeon_spi_match);
-
-static struct platform_driver octeon_spi_driver = {
- .driver = {
- .name = "spi-octeon",
- .of_match_table = octeon_spi_match,
- },
- .probe = octeon_spi_probe,
- .remove = octeon_spi_remove,
-};
-
-module_platform_driver(octeon_spi_driver);
-
-MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
-MODULE_AUTHOR("David Daney");
-MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-cavium.h b/drivers/spi/spi-cavium.h
index d41dba5..88c5f36 100644
--- a/drivers/spi/spi-cavium.h
+++ b/drivers/spi/spi-cavium.h
@@ -1,3 +1,32 @@
+#ifndef __SPI_CAVIUM_H
+#define __SPI_CAVIUM_H
+
+#define OCTEON_SPI_MAX_BYTES 9
+#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
+
+struct octeon_spi_regs {
+ int config;
+ int status;
+ int tx;
+ int data;
+};
+
+struct octeon_spi {
+ void __iomem *register_base;
+ u64 last_cfg;
+ u64 cs_enax;
+ int sys_freq;
+ struct octeon_spi_regs regs;
+};
+
+#define OCTEON_SPI_CFG(x) (x->regs.config)
+#define OCTEON_SPI_STS(x) (x->regs.status)
+#define OCTEON_SPI_TX(x) (x->regs.tx)
+#define OCTEON_SPI_DAT0(x) (x->regs.data)
+
+int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg);
+
/* MPI register descriptions */
#define CVMX_MPI_CFG (CVMX_ADD_IO_SEG(0x0001070000001000ull))
@@ -296,3 +325,5 @@ union cvmx_mpi_tx {
struct cvmx_mpi_tx_s cn66xx;
struct cvmx_mpi_tx_cn61xx cnf71xx;
};
+
+#endif /* __SPI_CAVIUM_H */
--
2.9.0.rc0.21.g7777322
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH v2] spi: octeon: Split driver into Octeon specific and common parts
@ 2016-07-25 17:49 ` Jan Glauber
0 siblings, 0 replies; 38+ messages in thread
From: Jan Glauber @ 2016-07-25 17:49 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, David Daney, Steven J . Hill,
Paul Gortmaker, Jan Glauber
Separate driver probing from SPI transfer functions.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/spi/Makefile | 1 +
drivers/spi/spi-cavium-octeon.c | 102 ++++++++++++++++++++++++
drivers/spi/{spi-octeon.c => spi-cavium.c} | 122 +----------------------------
drivers/spi/spi-cavium.h | 31 ++++++++
4 files changed, 136 insertions(+), 120 deletions(-)
create mode 100644 drivers/spi/spi-cavium-octeon.c
rename drivers/spi/{spi-octeon.c => spi-cavium.c} (54%)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3c74d00..185367e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
+spi-octeon-objs := spi-cavium.o spi-cavium-octeon.o
obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o
obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o
diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c
new file mode 100644
index 0000000..97310c1
--- /dev/null
+++ b/drivers/spi/spi-cavium-octeon.c
@@ -0,0 +1,102 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "spi-cavium.h"
+
+static int octeon_spi_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ void __iomem *reg_base;
+ struct spi_master *master;
+ struct octeon_spi *p;
+ int err = -ENOENT;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
+ if (!master)
+ return -ENOMEM;
+ p = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, master);
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (IS_ERR(reg_base)) {
+ err = PTR_ERR(reg_base);
+ goto fail;
+ }
+
+ p->register_base = reg_base;
+ p->sys_freq = octeon_get_io_clock_rate();
+
+ p->regs.config = 0;
+ p->regs.status = 0x08;
+ p->regs.tx = 0x10;
+ p->regs.data = 0x80;
+
+ master->num_chipselect = 4;
+ master->mode_bits = SPI_CPHA |
+ SPI_CPOL |
+ SPI_CS_HIGH |
+ SPI_LSB_FIRST |
+ SPI_3WIRE;
+
+ master->transfer_one_message = octeon_spi_transfer_one_message;
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
+ master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
+
+ master->dev.of_node = pdev->dev.of_node;
+ err = devm_spi_register_master(&pdev->dev, master);
+ if (err) {
+ dev_err(&pdev->dev, "register master failed: %d\n", err);
+ goto fail;
+ }
+
+ return 0;
+fail:
+ spi_master_put(master);
+ return err;
+}
+
+static int octeon_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct octeon_spi *p = spi_master_get_devdata(master);
+
+ /* Clear the CSENA* and put everything in a known state. */
+ writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ return 0;
+}
+
+static const struct of_device_id octeon_spi_match[] = {
+ { .compatible = "cavium,octeon-3010-spi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_spi_match);
+
+static struct platform_driver octeon_spi_driver = {
+ .driver = {
+ .name = "spi-octeon",
+ .of_match_table = octeon_spi_match,
+ },
+ .probe = octeon_spi_probe,
+ .remove = octeon_spi_remove,
+};
+
+module_platform_driver(octeon_spi_driver);
+
+MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-cavium.c
similarity index 54%
rename from drivers/spi/spi-octeon.c
rename to drivers/spi/spi-cavium.c
index 2180176..8857e7d 100644
--- a/drivers/spi/spi-octeon.c
+++ b/drivers/spi/spi-cavium.c
@@ -6,42 +6,11 @@
* Copyright (C) 2011, 2012 Cavium, Inc.
*/
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
#include <linux/spi/spi.h>
-#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/of.h>
-
-#include <asm/octeon/octeon.h>
#include "spi-cavium.h"
-#define OCTEON_SPI_MAX_BYTES 9
-
-#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
-
-struct octeon_spi_regs {
- int config;
- int status;
- int tx;
- int data;
-};
-
-struct octeon_spi {
- void __iomem *register_base;
- u64 last_cfg;
- u64 cs_enax;
- int sys_freq;
- struct octeon_spi_regs regs;
-};
-
-#define OCTEON_SPI_CFG(x) (x->regs.config)
-#define OCTEON_SPI_STS(x) (x->regs.status)
-#define OCTEON_SPI_TX(x) (x->regs.tx)
-#define OCTEON_SPI_DAT0(x) (x->regs.data)
-
static void octeon_spi_wait_ready(struct octeon_spi *p)
{
union cvmx_mpi_sts mpi_sts;
@@ -154,8 +123,8 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
return xfer->len;
}
-static int octeon_spi_transfer_one_message(struct spi_master *master,
- struct spi_message *msg)
+int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg)
{
struct octeon_spi *p = spi_master_get_devdata(master);
unsigned int total_len = 0;
@@ -178,90 +147,3 @@ err:
spi_finalize_current_message(master);
return status;
}
-
-static int octeon_spi_probe(struct platform_device *pdev)
-{
- struct resource *res_mem;
- void __iomem *reg_base;
- struct spi_master *master;
- struct octeon_spi *p;
- int err = -ENOENT;
-
- master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
- if (!master)
- return -ENOMEM;
- p = spi_master_get_devdata(master);
- platform_set_drvdata(pdev, master);
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
- if (IS_ERR(reg_base)) {
- err = PTR_ERR(reg_base);
- goto fail;
- }
-
- p->register_base = reg_base;
- p->sys_freq = octeon_get_io_clock_rate();
-
- p->regs.config = 0;
- p->regs.status = 0x08;
- p->regs.tx = 0x10;
- p->regs.data = 0x80;
-
- master->num_chipselect = 4;
- master->mode_bits = SPI_CPHA |
- SPI_CPOL |
- SPI_CS_HIGH |
- SPI_LSB_FIRST |
- SPI_3WIRE;
-
- master->transfer_one_message = octeon_spi_transfer_one_message;
- master->bits_per_word_mask = SPI_BPW_MASK(8);
- master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
-
- master->dev.of_node = pdev->dev.of_node;
- err = devm_spi_register_master(&pdev->dev, master);
- if (err) {
- dev_err(&pdev->dev, "register master failed: %d\n", err);
- goto fail;
- }
-
- dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
-
- return 0;
-fail:
- spi_master_put(master);
- return err;
-}
-
-static int octeon_spi_remove(struct platform_device *pdev)
-{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct octeon_spi *p = spi_master_get_devdata(master);
-
- /* Clear the CSENA* and put everything in a known state. */
- writeq(0, p->register_base + OCTEON_SPI_CFG(p));
-
- return 0;
-}
-
-static const struct of_device_id octeon_spi_match[] = {
- { .compatible = "cavium,octeon-3010-spi", },
- {},
-};
-MODULE_DEVICE_TABLE(of, octeon_spi_match);
-
-static struct platform_driver octeon_spi_driver = {
- .driver = {
- .name = "spi-octeon",
- .of_match_table = octeon_spi_match,
- },
- .probe = octeon_spi_probe,
- .remove = octeon_spi_remove,
-};
-
-module_platform_driver(octeon_spi_driver);
-
-MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
-MODULE_AUTHOR("David Daney");
-MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-cavium.h b/drivers/spi/spi-cavium.h
index d41dba5..88c5f36 100644
--- a/drivers/spi/spi-cavium.h
+++ b/drivers/spi/spi-cavium.h
@@ -1,3 +1,32 @@
+#ifndef __SPI_CAVIUM_H
+#define __SPI_CAVIUM_H
+
+#define OCTEON_SPI_MAX_BYTES 9
+#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
+
+struct octeon_spi_regs {
+ int config;
+ int status;
+ int tx;
+ int data;
+};
+
+struct octeon_spi {
+ void __iomem *register_base;
+ u64 last_cfg;
+ u64 cs_enax;
+ int sys_freq;
+ struct octeon_spi_regs regs;
+};
+
+#define OCTEON_SPI_CFG(x) (x->regs.config)
+#define OCTEON_SPI_STS(x) (x->regs.status)
+#define OCTEON_SPI_TX(x) (x->regs.tx)
+#define OCTEON_SPI_DAT0(x) (x->regs.data)
+
+int octeon_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *msg);
+
/* MPI register descriptions */
#define CVMX_MPI_CFG (CVMX_ADD_IO_SEG(0x0001070000001000ull))
@@ -296,3 +325,5 @@ union cvmx_mpi_tx {
struct cvmx_mpi_tx_s cn66xx;
struct cvmx_mpi_tx_cn61xx cnf71xx;
};
+
+#endif /* __SPI_CAVIUM_H */
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 6/6] spi: octeon: Add thunderx driver
2016-07-23 10:42 ` Jan Glauber
` (5 preceding siblings ...)
(?)
@ 2016-07-23 10:42 ` Jan Glauber
[not found] ` <f87d7a5ef8a713fb6e64c5d9471e7e5bf2051d18.1469174814.git.jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
-1 siblings, 1 reply; 38+ messages in thread
From: Jan Glauber @ 2016-07-23 10:42 UTC (permalink / raw)
To: Mark Brown
Cc: linux-kernel, linux-spi, Steven J. Hill, David Daney, Jan Glauber
Add ThunderX SPI driver using the shared part from the Octeon
driver. The main difference of the ThunderX driver is that it
is a PCI device so probing is different. The system clock settings
can be specified in device tree.
Signed-off-by: Jan Glauber <jglauber@cavium.com>
---
drivers/spi/Kconfig | 7 ++
drivers/spi/Makefile | 2 +
drivers/spi/spi-cavium-thunderx.c | 158 ++++++++++++++++++++++++++++++++++++++
drivers/spi/spi-cavium.h | 3 +
4 files changed, 170 insertions(+)
create mode 100644 drivers/spi/spi-cavium-thunderx.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4b931ec..db02ba7 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -630,6 +630,13 @@ config SPI_TEGRA20_SLINK
help
SPI driver for Nvidia Tegra20/Tegra30 SLINK Controller interface.
+config SPI_THUNDERX
+ tristate "Cavium ThunderX SPI controller"
+ depends on 64BIT && PCI && !CAVIUM_OCTEON_SOC
+ help
+ SPI host driver for the hardware found on Cavium ThunderX
+ SOCs.
+
config SPI_TOPCLIFF_PCH
tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI"
depends on PCI && (X86_32 || MIPS || COMPILE_TEST)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 185367e..133364b 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -91,6 +91,8 @@ obj-$(CONFIG_SPI_TEGRA114) += spi-tegra114.o
obj-$(CONFIG_SPI_TEGRA20_SFLASH) += spi-tegra20-sflash.o
obj-$(CONFIG_SPI_TEGRA20_SLINK) += spi-tegra20-slink.o
obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o
+spi-thunderx-objs := spi-cavium.o spi-cavium-thunderx.o
+obj-$(CONFIG_SPI_THUNDERX) += spi-thunderx.o
obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o
obj-$(CONFIG_SPI_TXX9) += spi-txx9.o
obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
diff --git a/drivers/spi/spi-cavium-thunderx.c b/drivers/spi/spi-cavium-thunderx.c
new file mode 100644
index 0000000..7eb9141
--- /dev/null
+++ b/drivers/spi/spi-cavium-thunderx.c
@@ -0,0 +1,158 @@
+/*
+ * Cavium ThunderX SPI driver.
+ *
+ * Copyright (C) 2016 Cavium Inc.
+ * Authors: Jan Glauber <jglauber@cavium.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spi/spi.h>
+
+#include "spi-cavium.h"
+
+#define DRV_NAME "spi-thunderx"
+
+#define SYS_FREQ_DEFAULT 700000000
+
+static void thunderx_spi_clock_enable(struct device *dev, struct octeon_spi *p)
+{
+ int ret;
+
+ p->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(p->clk)) {
+ p->clk = NULL;
+ goto skip;
+ }
+
+ ret = clk_prepare_enable(p->clk);
+ if (ret)
+ goto skip;
+ p->sys_freq = clk_get_rate(p->clk);
+
+skip:
+ if (!p->sys_freq)
+ p->sys_freq = SYS_FREQ_DEFAULT;
+
+ dev_info(dev, "Set system clock to %u\n", p->sys_freq);
+}
+
+static void thunderx_spi_clock_disable(struct device *dev, struct clk *clk)
+{
+ if (!clk)
+ return;
+ clk_disable_unprepare(clk);
+ devm_clk_put(dev, clk);
+}
+
+static int thunderx_spi_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct device *dev = &pdev->dev;
+ struct spi_master *master;
+ struct octeon_spi *p;
+ int ret = -ENOENT;
+
+ master = spi_alloc_master(dev, sizeof(struct octeon_spi));
+ if (!master)
+ return -ENOMEM;
+ p = spi_master_get_devdata(master);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(dev, "Failed to enable PCI device\n");
+ goto out_free;
+ }
+
+ ret = pci_request_regions(pdev, DRV_NAME);
+ if (ret) {
+ dev_err(dev, "PCI request regions failed 0x%x\n", ret);
+ goto out_disable;
+ }
+
+ p->register_base = pci_ioremap_bar(pdev, 0);
+ if (!p->register_base) {
+ dev_err(dev, "Cannot map reg base\n");
+ ret = -EINVAL;
+ goto out_region;
+ }
+
+ p->regs.config = 0x1000;
+ p->regs.status = 0x1008;
+ p->regs.tx = 0x1010;
+ p->regs.data = 0x1080;
+
+ thunderx_spi_clock_enable(dev, p);
+
+ master->num_chipselect = 4;
+ master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
+ SPI_LSB_FIRST | SPI_3WIRE;
+ master->transfer_one_message = octeon_spi_transfer_one_message;
+ master->bits_per_word_mask = SPI_BPW_MASK(8);
+ master->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
+ master->dev.of_node = pdev->dev.of_node;
+
+ pci_set_drvdata(pdev, master);
+ ret = devm_spi_register_master(dev, master);
+ if (ret) {
+ dev_err(&pdev->dev, "Register master failed: %d\n", ret);
+ goto out_unmap;
+ }
+
+ dev_info(&pdev->dev, "Cavium SPI bus driver probed\n");
+ return 0;
+
+out_unmap:
+ thunderx_spi_clock_disable(dev, p->clk);
+ iounmap(p->register_base);
+out_region:
+ pci_release_regions(pdev);
+out_disable:
+ pci_disable_device(pdev);
+out_free:
+ spi_master_put(master);
+ return ret;
+}
+
+static void thunderx_spi_remove(struct pci_dev *pdev)
+{
+ struct spi_master *master = pci_get_drvdata(pdev);
+ struct octeon_spi *p;
+
+ p = spi_master_get_devdata(master);
+ if (!p)
+ return;
+
+ /* Put everything in a known state. */
+ writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ thunderx_spi_clock_disable(&pdev->dev, p->clk);
+ iounmap(p->register_base);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+#define PCI_DEVICE_ID_THUNDERX_SPI 0xa00b
+
+static const struct pci_device_id thunderx_spi_pci_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDERX_SPI) },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, thunderx_spi_pci_id_table);
+
+static struct pci_driver thunderx_spi_driver = {
+ .name = DRV_NAME,
+ .id_table = thunderx_spi_pci_id_table,
+ .probe = thunderx_spi_probe,
+ .remove = thunderx_spi_remove,
+};
+
+module_pci_driver(thunderx_spi_driver);
+
+MODULE_DESCRIPTION("Cavium, Inc. ThunderX SPI bus driver");
+MODULE_AUTHOR("Jan Glauber");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-cavium.h b/drivers/spi/spi-cavium.h
index 88c5f36..1f91d61 100644
--- a/drivers/spi/spi-cavium.h
+++ b/drivers/spi/spi-cavium.h
@@ -1,6 +1,8 @@
#ifndef __SPI_CAVIUM_H
#define __SPI_CAVIUM_H
+#include <linux/clk.h>
+
#define OCTEON_SPI_MAX_BYTES 9
#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
@@ -17,6 +19,7 @@ struct octeon_spi {
u64 cs_enax;
int sys_freq;
struct octeon_spi_regs regs;
+ struct clk *clk;
};
#define OCTEON_SPI_CFG(x) (x->regs.config)
--
2.9.0.rc0.21.g7777322
^ permalink raw reply related [flat|nested] 38+ messages in thread