From: Jan Glauber <jglauber@cavium.com> To: Mark Brown <broonie@kernel.org> Cc: linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, David Daney <david.daney@cavium.com>, "Steven J . Hill" <steven.hill@cavium.com>, Jan Glauber <jglauber@cavium.com> Subject: [PATCH v2 2/2] spi: octeon: Add thunderx driver Date: Thu, 28 Jul 2016 10:31:44 +0200 [thread overview] Message-ID: <20160728083144.16625-3-jglauber@cavium.com> (raw) In-Reply-To: <20160728083144.16625-1-jglauber@cavium.com> 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 | 140 ++++++++++++++++++++++++++++++++++++++ drivers/spi/spi-cavium.h | 3 + 4 files changed, 152 insertions(+) create mode 100644 drivers/spi/spi-cavium-thunderx.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4b931ec..e0ee112 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 (ARM64 || CONFIG_TEST) && 64BIT && PCI + 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..28c3dcc --- /dev/null +++ b/drivers/spi/spi-cavium-thunderx.c @@ -0,0 +1,140 @@ +/* + * 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 /* 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 = -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; + + p->clk = devm_clk_get(dev, NULL); + if (IS_ERR(p->clk)) + goto out_unmap; + + ret = clk_prepare_enable(p->clk); + if (ret) + goto out_clock_devm; + + 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) { + dev_err(&pdev->dev, "Register master failed: %d\n", ret); + goto out_clock; + } + + return 0; + +out_clock: + clk_disable_unprepare(p->clk); +out_clock_devm: + devm_clk_put(dev, p->clk); +out_unmap: + 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)); + + clk_disable_unprepare(p->clk); + devm_clk_put(&pdev->dev, p->clk); + iounmap(p->register_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +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"); 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
WARNING: multiple messages have this Message-ID (diff)
From: Jan Glauber <jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> To: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>, "Steven J . Hill" <steven.hill-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>, Jan Glauber <jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> Subject: [PATCH v2 2/2] spi: octeon: Add thunderx driver Date: Thu, 28 Jul 2016 10:31:44 +0200 [thread overview] Message-ID: <20160728083144.16625-3-jglauber@cavium.com> (raw) In-Reply-To: <20160728083144.16625-1-jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> 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-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> --- drivers/spi/Kconfig | 7 ++ drivers/spi/Makefile | 2 + drivers/spi/spi-cavium-thunderx.c | 140 ++++++++++++++++++++++++++++++++++++++ drivers/spi/spi-cavium.h | 3 + 4 files changed, 152 insertions(+) create mode 100644 drivers/spi/spi-cavium-thunderx.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4b931ec..e0ee112 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 (ARM64 || CONFIG_TEST) && 64BIT && PCI + 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..28c3dcc --- /dev/null +++ b/drivers/spi/spi-cavium-thunderx.c @@ -0,0 +1,140 @@ +/* + * Cavium ThunderX SPI driver. + * + * Copyright (C) 2016 Cavium Inc. + * Authors: Jan Glauber <jglauber-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org> + */ + +#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 /* 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 = -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; + + p->clk = devm_clk_get(dev, NULL); + if (IS_ERR(p->clk)) + goto out_unmap; + + ret = clk_prepare_enable(p->clk); + if (ret) + goto out_clock_devm; + + 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) { + dev_err(&pdev->dev, "Register master failed: %d\n", ret); + goto out_clock; + } + + return 0; + +out_clock: + clk_disable_unprepare(p->clk); +out_clock_devm: + devm_clk_put(dev, p->clk); +out_unmap: + 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)); + + clk_disable_unprepare(p->clk); + devm_clk_put(&pdev->dev, p->clk); + iounmap(p->register_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +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"); 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 -- 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
next prev parent reply other threads:[~2016-07-28 8:32 UTC|newest] Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-07-28 8:31 [PATCH v2 0/2] SPI ThunderX driver Jan Glauber 2016-07-28 8:31 ` Jan Glauber 2016-07-28 8:31 ` [PATCH v2 1/2] spi: octeon: Split driver into Octeon specific and common parts Jan Glauber 2016-08-01 17:36 ` Mark Brown 2016-08-01 17:36 ` Mark Brown 2016-07-28 8:31 ` Jan Glauber [this message] 2016-07-28 8:31 ` [PATCH v2 2/2] spi: octeon: Add thunderx driver Jan Glauber 2016-08-01 17:28 ` Mark Brown 2016-08-01 17:28 ` Mark Brown 2016-08-01 18:31 ` David Daney 2016-08-01 18:49 ` Mark Brown 2016-08-01 18:49 ` Mark Brown 2016-08-01 19:02 ` David Daney 2016-08-01 19:02 ` David Daney 2016-08-02 21:30 ` Mark Brown 2016-08-02 21:30 ` Mark Brown 2016-08-02 21:49 ` David Daney
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20160728083144.16625-3-jglauber@cavium.com \ --to=jglauber@cavium.com \ --cc=broonie@kernel.org \ --cc=david.daney@cavium.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-spi@vger.kernel.org \ --cc=steven.hill@cavium.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.