Skip to content

Commit

Permalink
Merge remote-tracking branches 'spi/topic/octeon', 'spi/topic/pic32-s…
Browse files Browse the repository at this point in the history
…qi', 'spi/topic/pxa2xx' and 'spi/topic/qup' into spi-next
  • Loading branch information
Mark Brown committed Sep 30, 2016
5 parents e2df04e + 568852b + a3cfea0 + 089bd46 + 9d04d8b commit 66b5a33
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 67 deletions.
7 changes: 7 additions & 0 deletions drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,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 PCI && 64BIT && (ARM64 || COMPILE_TEST)
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)
Expand Down
2 changes: 2 additions & 0 deletions drivers/spi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,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
Expand Down
120 changes: 120 additions & 0 deletions drivers/spi/spi-cavium-thunderx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Cavium ThunderX SPI driver.
*
* Copyright (C) 2016 Cavium Inc.
* Authors: Jan Glauber <jglauber@cavium.com>
*/

#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 /* 700 Mhz */

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;

master = spi_alloc_master(dev, sizeof(struct octeon_spi));
if (!master)
return -ENOMEM;

p = spi_master_get_devdata(master);

ret = pcim_enable_device(pdev);
if (ret)
goto error;

ret = pci_request_regions(pdev, DRV_NAME);
if (ret)
goto error;

p->register_base = pcim_iomap(pdev, 0, pci_resource_len(pdev, 0));
if (!p->register_base) {
ret = -EINVAL;
goto error;
}

p->regs.config = 0x1000;
p->regs.status = 0x1008;
p->regs.tx = 0x1010;
p->regs.data = 0x1080;

p->clk = devm_clk_get(dev, NULL);
if (IS_ERR(p->clk)) {
ret = PTR_ERR(p->clk);
goto error;
}

ret = clk_prepare_enable(p->clk);
if (ret)
goto error;

p->sys_freq = clk_get_rate(p->clk);
if (!p->sys_freq)
p->sys_freq = SYS_FREQ_DEFAULT;
dev_info(dev, "Set system clock to %u\n", p->sys_freq);

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)
goto error;

return 0;

error:
clk_disable_unprepare(p->clk);
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;

clk_disable_unprepare(p->clk);
/* Put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
}

static const struct pci_device_id thunderx_spi_pci_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa00b) },
{ 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");
3 changes: 3 additions & 0 deletions drivers/spi/spi-cavium.h
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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)
Expand Down
6 changes: 2 additions & 4 deletions drivers/spi/spi-pic32-sqi.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,13 @@ static struct ring_desc *ring_desc_get(struct pic32_sqi *sqi)
return NULL;

rdesc = list_first_entry(&sqi->bd_list_free, struct ring_desc, list);
list_del(&rdesc->list);
list_add_tail(&rdesc->list, &sqi->bd_list_used);
list_move_tail(&rdesc->list, &sqi->bd_list_used);
return rdesc;
}

static void ring_desc_put(struct pic32_sqi *sqi, struct ring_desc *rdesc)
{
list_del(&rdesc->list);
list_add(&rdesc->list, &sqi->bd_list_free);
list_move(&rdesc->list, &sqi->bd_list_free);
}

static int pic32_sqi_one_transfer(struct pic32_sqi *sqi,
Expand Down
7 changes: 4 additions & 3 deletions drivers/spi/spi-pxa2xx-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
bool error)
{
struct spi_message *msg = drv_data->cur_msg;
struct spi_message *msg = drv_data->master->cur_msg;

/*
* It is possible that one CPU is handling ROR interrupt and other
Expand Down Expand Up @@ -76,7 +76,8 @@ static struct dma_async_tx_descriptor *
pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
enum dma_transfer_direction dir)
{
struct chip_data *chip = drv_data->cur_chip;
struct chip_data *chip =
spi_get_ctldata(drv_data->master->cur_msg->spi);
struct spi_transfer *xfer = drv_data->cur_transfer;
enum dma_slave_buswidth width;
struct dma_slave_config cfg;
Expand Down Expand Up @@ -146,7 +147,7 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst)
{
struct dma_async_tx_descriptor *tx_desc, *rx_desc;
int err = 0;
int err;

tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV);
if (!tx_desc) {
Expand Down
Loading

0 comments on commit 66b5a33

Please sign in to comment.