diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 17:44:33 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 17:44:33 +0300 |
commit | 9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526 (patch) | |
tree | 3229206f8aa93ca4d34585b7eb4d3ed272397ae2 /drivers/staging | |
parent | 61be53f9ef37de2677cecb8f87b207e6f061e185 (diff) | |
parent | 2e5f081003f033d37be3faf052aaccc8b6a44aa5 (diff) | |
download | linux-9bff9dfc513bd5de72cb59f4bffb72cf0a5aa526.tar.xz |
Merge tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"One small feature was added this release but the bulk of the diffstat
and the changelog comes from the fact that several older drivers got
some fairly hefty reworks and a couple of new drivers were added:
- Support for detailed control of timing around chip selects from
Sowjanya Komatineni.
- A big set of fixes and imrovements for the Tegra114 driver from
Sowjanya Komatineni.
- A big simplification of the GPIO driver from Andrey Smirnov.
- DMA support and fixes for the Freescale LPSPI driver from Clark
Wang.
- Fixes and optimizations for the bcm2835aux from Martin Sparl.
- New drivers for Mediatek MT7621 (graduated from staging) and Zynq
QSPI"
[ This is a so-called "evil merge" that additionally removes a warning
due to an unused variable 'i' introduced by commit 1dfbf334f123 ("spi:
ep93xx: Convert to use CS GPIO descriptors") - Linus ]
* tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (127 commits)
spi: rspi: Fix handling of QSPI code when transmit and receive
spi: atmel-quadspi: fix crash while suspending
spi: stm32: return the get_irq error
spi: tegra114: fix PIO transfer
spi: pxa2xx: fix SCR (divisor) calculation
spi: Clear SPI_CS_HIGH flag from bad_bits for GPIO chip-select
spi: ep93xx: Convert to use CS GPIO descriptors
spi: AD ASoC: declare missing of table
spi: spi-mem: zynq-qspi: Fix build error on architectures missing readsl/writesl
spi: stm32-qspi: manage the get_irq error case
spi/spi-bcm2835: Split transfers that exceed DLEN
spi: expand mode support
dt-bindings: spi: spi-mt65xx: add support for MT8516
spi: pxa2xx: Add support for Intel Comet Lake
spi/trace: Cap buffer contents at 64 bytes
spi: Release spi_res after finalizing message
spi: Remove warning in spi_split_transfers_maxsize()
spi: Remove one needless transfer speed fall back case
spi: sh-msiof: Document r8a77470 bindings
spi: pxa2xx: use a module softdep for dw_dmac
...
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/mt7621-spi/Kconfig | 6 | ||||
-rw-r--r-- | drivers/staging/mt7621-spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/mt7621-spi/TODO | 5 | ||||
-rw-r--r-- | drivers/staging/mt7621-spi/spi-mt7621.c | 422 |
6 files changed, 0 insertions, 437 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 62951e836cbc..c7d7dc89deba 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -106,8 +106,6 @@ source "drivers/staging/mt7621-pci-phy/Kconfig" source "drivers/staging/mt7621-pinctrl/Kconfig" -source "drivers/staging/mt7621-spi/Kconfig" - source "drivers/staging/mt7621-dma/Kconfig" source "drivers/staging/ralink-gdma/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index d1b17ddcd354..19c0a25ff98b 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/ -obj-$(CONFIG_SPI_MT7621) += mt7621-spi/ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ obj-$(CONFIG_MTK_MMC) += mt7621-mmc/ diff --git a/drivers/staging/mt7621-spi/Kconfig b/drivers/staging/mt7621-spi/Kconfig deleted file mode 100644 index 0b90f4cfa426..000000000000 --- a/drivers/staging/mt7621-spi/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config SPI_MT7621 - tristate "MediaTek MT7621 SPI Controller" - depends on RALINK - help - This selects a driver for the MediaTek MT7621 SPI Controller. - diff --git a/drivers/staging/mt7621-spi/Makefile b/drivers/staging/mt7621-spi/Makefile deleted file mode 100644 index 3be508f63bac..000000000000 --- a/drivers/staging/mt7621-spi/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o diff --git a/drivers/staging/mt7621-spi/TODO b/drivers/staging/mt7621-spi/TODO deleted file mode 100644 index fdbc5002c32a..000000000000 --- a/drivers/staging/mt7621-spi/TODO +++ /dev/null @@ -1,5 +0,0 @@ - -- general code review and clean up -- ensure device-tree requirements are documented - -Cc: NeilBrown <neil@brown.name> diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c deleted file mode 100644 index b509f9fe3346..000000000000 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ /dev/null @@ -1,422 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * spi-mt7621.c -- MediaTek MT7621 SPI controller driver - * - * Copyright (C) 2011 Sergiy <piratfm@gmail.com> - * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name> - * - * Some parts are based on spi-orion.c: - * Author: Shadi Ammouri <shadi@marvell.com> - * Copyright (C) 2007-2008 Marvell Ltd. - */ - -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/of_device.h> -#include <linux/reset.h> -#include <linux/spi/spi.h> - -#define DRIVER_NAME "spi-mt7621" - -/* in usec */ -#define RALINK_SPI_WAIT_MAX_LOOP 2000 - -/* SPISTAT register bit field */ -#define SPISTAT_BUSY BIT(0) - -#define MT7621_SPI_TRANS 0x00 -#define SPITRANS_BUSY BIT(16) - -#define MT7621_SPI_OPCODE 0x04 -#define MT7621_SPI_DATA0 0x08 -#define MT7621_SPI_DATA4 0x18 -#define SPI_CTL_TX_RX_CNT_MASK 0xff -#define SPI_CTL_START BIT(8) - -#define MT7621_SPI_MASTER 0x28 -#define MASTER_MORE_BUFMODE BIT(2) -#define MASTER_FULL_DUPLEX BIT(10) -#define MASTER_RS_CLK_SEL GENMASK(27, 16) -#define MASTER_RS_CLK_SEL_SHIFT 16 -#define MASTER_RS_SLAVE_SEL GENMASK(31, 29) - -#define MT7621_SPI_MOREBUF 0x2c -#define MT7621_SPI_POLAR 0x38 -#define MT7621_SPI_SPACE 0x3c - -#define MT7621_CPHA BIT(5) -#define MT7621_CPOL BIT(4) -#define MT7621_LSB_FIRST BIT(3) - -struct mt7621_spi { - struct spi_master *master; - void __iomem *base; - unsigned int sys_freq; - unsigned int speed; - struct clk *clk; - int pending_write; - - struct mt7621_spi_ops *ops; -}; - -static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi) -{ - return spi_master_get_devdata(spi->master); -} - -static inline u32 mt7621_spi_read(struct mt7621_spi *rs, u32 reg) -{ - return ioread32(rs->base + reg); -} - -static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val) -{ - iowrite32(val, rs->base + reg); -} - -static void mt7621_spi_reset(struct mt7621_spi *rs) -{ - u32 master = mt7621_spi_read(rs, MT7621_SPI_MASTER); - - /* - * Select SPI device 7, enable "more buffer mode" and disable - * full-duplex (only half-duplex really works on this chip - * reliably) - */ - master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE; - master &= ~MASTER_FULL_DUPLEX; - - mt7621_spi_write(rs, MT7621_SPI_MASTER, master); - rs->pending_write = 0; -} - -static void mt7621_spi_set_cs(struct spi_device *spi, int enable) -{ - struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); - int cs = spi->chip_select; - u32 polar = 0; - - mt7621_spi_reset(rs); - if (enable) - polar = BIT(cs); - mt7621_spi_write(rs, MT7621_SPI_POLAR, polar); -} - -static int mt7621_spi_prepare(struct spi_device *spi, unsigned int speed) -{ - struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); - u32 rate; - u32 reg; - - dev_dbg(&spi->dev, "speed:%u\n", speed); - - rate = DIV_ROUND_UP(rs->sys_freq, speed); - dev_dbg(&spi->dev, "rate-1:%u\n", rate); - - if (rate > 4097) - return -EINVAL; - - if (rate < 2) - rate = 2; - - reg = mt7621_spi_read(rs, MT7621_SPI_MASTER); - reg &= ~MASTER_RS_CLK_SEL; - reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT; - rs->speed = speed; - - reg &= ~MT7621_LSB_FIRST; - if (spi->mode & SPI_LSB_FIRST) - reg |= MT7621_LSB_FIRST; - - /* - * This SPI controller seems to be tested on SPI flash only and some - * bits are swizzled under other SPI modes probably due to incorrect - * wiring inside the silicon. Only mode 0 works correctly. - */ - reg &= ~(MT7621_CPHA | MT7621_CPOL); - - mt7621_spi_write(rs, MT7621_SPI_MASTER, reg); - - return 0; -} - -static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) -{ - int i; - - for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) { - u32 status; - - status = mt7621_spi_read(rs, MT7621_SPI_TRANS); - if ((status & SPITRANS_BUSY) == 0) - return 0; - cpu_relax(); - udelay(1); - } - - return -ETIMEDOUT; -} - -static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, - int rx_len, u8 *buf) -{ - /* - * Combine with any pending write, and perform one or more half-duplex - * transactions reading 'len' bytes. Data to be written is already in - * MT7621_SPI_DATA. - */ - int tx_len = rs->pending_write; - - rs->pending_write = 0; - - while (rx_len || tx_len) { - int i; - u32 val = (min(tx_len, 4) * 8) << 24; - int rx = min(rx_len, 32); - - if (tx_len > 4) - val |= (tx_len - 4) * 8; - val |= (rx * 8) << 12; - mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val); - - tx_len = 0; - - val = mt7621_spi_read(rs, MT7621_SPI_TRANS); - val |= SPI_CTL_START; - mt7621_spi_write(rs, MT7621_SPI_TRANS, val); - - mt7621_spi_wait_till_ready(rs); - - for (i = 0; i < rx; i++) { - if ((i % 4) == 0) - val = mt7621_spi_read(rs, MT7621_SPI_DATA0 + i); - *buf++ = val & 0xff; - val >>= 8; - } - - rx_len -= i; - } -} - -static inline void mt7621_spi_flush(struct mt7621_spi *rs) -{ - mt7621_spi_read_half_duplex(rs, 0, NULL); -} - -static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs, - int tx_len, const u8 *buf) -{ - int val = 0; - int len = rs->pending_write; - - if (len & 3) { - val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3)); - if (len < 4) { - val <<= (4 - len) * 8; - val = swab32(val); - } - } - - while (tx_len > 0) { - if (len >= 36) { - rs->pending_write = len; - mt7621_spi_flush(rs); - len = 0; - } - - val |= *buf++ << (8 * (len & 3)); - len++; - if ((len & 3) == 0) { - if (len == 4) - /* The byte-order of the opcode is weird! */ - val = swab32(val); - mt7621_spi_write(rs, MT7621_SPI_OPCODE + len - 4, val); - val = 0; - } - tx_len -= 1; - } - if (len & 3) { - if (len < 4) { - val = swab32(val); - val >>= (4 - len) * 8; - } - mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val); - } - rs->pending_write = len; -} - -static int mt7621_spi_transfer_one_message(struct spi_master *master, - struct spi_message *m) -{ - struct mt7621_spi *rs = spi_master_get_devdata(master); - struct spi_device *spi = m->spi; - unsigned int speed = spi->max_speed_hz; - struct spi_transfer *t = NULL; - int status = 0; - - mt7621_spi_wait_till_ready(rs); - - list_for_each_entry(t, &m->transfers, transfer_list) - if (t->speed_hz < speed) - speed = t->speed_hz; - - if (mt7621_spi_prepare(spi, speed)) { - status = -EIO; - goto msg_done; - } - - mt7621_spi_set_cs(spi, 1); - m->actual_length = 0; - list_for_each_entry(t, &m->transfers, transfer_list) { - if ((t->rx_buf) && (t->tx_buf)) { - /* This controller will shift some extra data out - * of spi_opcode if (mosi_bit_cnt > 0) && - * (cmd_bit_cnt == 0). So the claimed full-duplex - * support is broken since we have no way to read - * the MISO value during that bit. - */ - status = -EIO; - goto msg_done; - } else if (t->rx_buf) { - mt7621_spi_read_half_duplex(rs, t->len, t->rx_buf); - } else if (t->tx_buf) { - mt7621_spi_write_half_duplex(rs, t->len, t->tx_buf); - } - m->actual_length += t->len; - } - mt7621_spi_flush(rs); - - mt7621_spi_set_cs(spi, 0); - -msg_done: - m->status = status; - spi_finalize_current_message(master); - - return 0; -} - -static int mt7621_spi_setup(struct spi_device *spi) -{ - struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); - - if ((spi->max_speed_hz == 0) || - (spi->max_speed_hz > (rs->sys_freq / 2))) - spi->max_speed_hz = (rs->sys_freq / 2); - - if (spi->max_speed_hz < (rs->sys_freq / 4097)) { - dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n", - spi->max_speed_hz); - return -EINVAL; - } - - return 0; -} - -static const struct of_device_id mt7621_spi_match[] = { - { .compatible = "ralink,mt7621-spi" }, - {}, -}; -MODULE_DEVICE_TABLE(of, mt7621_spi_match); - -static int mt7621_spi_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - struct spi_master *master; - struct mt7621_spi *rs; - void __iomem *base; - struct resource *r; - int status = 0; - struct clk *clk; - struct mt7621_spi_ops *ops; - int ret; - - match = of_match_device(mt7621_spi_match, &pdev->dev); - if (!match) - return -EINVAL; - ops = (struct mt7621_spi_ops *)match->data; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(base)) - return PTR_ERR(base); - - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", - status); - return PTR_ERR(clk); - } - - status = clk_prepare_enable(clk); - if (status) - return status; - - master = spi_alloc_master(&pdev->dev, sizeof(*rs)); - if (!master) { - dev_info(&pdev->dev, "master allocation failed\n"); - return -ENOMEM; - } - - master->mode_bits = SPI_LSB_FIRST; - - master->setup = mt7621_spi_setup; - master->transfer_one_message = mt7621_spi_transfer_one_message; - master->bits_per_word_mask = SPI_BPW_MASK(8); - master->dev.of_node = pdev->dev.of_node; - master->num_chipselect = 2; - - dev_set_drvdata(&pdev->dev, master); - - rs = spi_master_get_devdata(master); - rs->base = base; - rs->clk = clk; - rs->master = master; - rs->sys_freq = clk_get_rate(rs->clk); - rs->ops = ops; - rs->pending_write = 0; - dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq); - - ret = device_reset(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "SPI reset failed!\n"); - return ret; - } - - mt7621_spi_reset(rs); - - return spi_register_master(master); -} - -static int mt7621_spi_remove(struct platform_device *pdev) -{ - struct spi_master *master; - struct mt7621_spi *rs; - - master = dev_get_drvdata(&pdev->dev); - rs = spi_master_get_devdata(master); - - clk_disable(rs->clk); - spi_unregister_master(master); - - return 0; -} - -MODULE_ALIAS("platform:" DRIVER_NAME); - -static struct platform_driver mt7621_spi_driver = { - .driver = { - .name = DRIVER_NAME, - .of_match_table = mt7621_spi_match, - }, - .probe = mt7621_spi_probe, - .remove = mt7621_spi_remove, -}; - -module_platform_driver(mt7621_spi_driver); - -MODULE_DESCRIPTION("MT7621 SPI driver"); -MODULE_AUTHOR("Felix Fietkau <nbd@nbd.name>"); -MODULE_LICENSE("GPL"); |