Merge remote-tracking branches 'spi/topic/atmel', 'spi/topic/bcm-qspi', 'spi/topic/bcm2835aux', 'spi/topic/dw' and 'spi/topic/gpio' into spi-next

This commit is contained in:
Mark Brown 2018-04-02 15:56:34 +01:00
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0
17 changed files with 313 additions and 325 deletions

View file

@ -768,14 +768,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
rxdesc = dmaengine_prep_slave_single(rxchan,
as->dma_addr_rx_bbuf,
xfer->len,
DMA_FROM_DEVICE,
DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT |
DMA_CTRL_ACK);
} else {
rxdesc = dmaengine_prep_slave_sg(rxchan,
xfer->rx_sg.sgl,
xfer->rx_sg.nents,
DMA_FROM_DEVICE,
DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT |
DMA_CTRL_ACK);
}
@ -787,14 +787,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
memcpy(as->addr_tx_bbuf, xfer->tx_buf, xfer->len);
txdesc = dmaengine_prep_slave_single(txchan,
as->dma_addr_tx_bbuf,
xfer->len, DMA_TO_DEVICE,
xfer->len, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT |
DMA_CTRL_ACK);
} else {
txdesc = dmaengine_prep_slave_sg(txchan,
xfer->tx_sg.sgl,
xfer->tx_sg.nents,
DMA_TO_DEVICE,
DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT |
DMA_CTRL_ACK);
}

View file

@ -1247,7 +1247,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->base[MSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[MSPI])) {
ret = PTR_ERR(qspi->base[MSPI]);
goto qspi_probe_err;
goto qspi_resource_err;
}
} else {
goto qspi_resource_err;
@ -1258,7 +1258,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi->base[BSPI] = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->base[BSPI])) {
ret = PTR_ERR(qspi->base[BSPI]);
goto qspi_probe_err;
goto qspi_resource_err;
}
qspi->bspi_mode = true;
} else {

View file

@ -321,7 +321,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
unsigned long spi_hz, clk_hz, speed;
unsigned long spi_used_hz;
unsigned long long xfer_time_us;
/* calculate the registers to handle
*
@ -358,20 +357,21 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master,
bs->rx_len = tfr->len;
bs->pending = 0;
/* calculate the estimated time in us the transfer runs
* note that there are are 2 idle clocks after each
* chunk getting transferred - in our case the chunk size
* is 3 bytes, so we approximate this by 9 bits/byte
/* Calculate the estimated time in us the transfer runs. Note that
* there are are 2 idle clocks cycles after each chunk getting
* transferred - in our case the chunk size is 3 bytes, so we
* approximate this by 9 cycles/byte. This is used to find the number
* of Hz per byte per polling limit. E.g., we can transfer 1 byte in
* 30 µs per 300,000 Hz of bus clock.
*/
xfer_time_us = tfr->len * 9 * 1000000;
do_div(xfer_time_us, spi_used_hz);
#define HZ_PER_BYTE ((9 * 1000000) / BCM2835_AUX_SPI_POLLING_LIMIT_US)
/* run in polling mode for short transfers */
if (xfer_time_us < BCM2835_AUX_SPI_POLLING_LIMIT_US)
if (tfr->len < spi_used_hz / HZ_PER_BYTE)
return bcm2835aux_spi_transfer_one_poll(master, spi, tfr);
/* run in interrupt mode for all others */
return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
#undef HZ_PER_BYTE
}
static int bcm2835aux_spi_prepare_message(struct spi_master *master,

View file

@ -112,10 +112,10 @@ static irqreturn_t dma_transfer(struct dw_spi *dws)
return IRQ_HANDLED;
}
static bool mid_spi_can_dma(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *xfer)
static bool mid_spi_can_dma(struct spi_controller *master,
struct spi_device *spi, struct spi_transfer *xfer)
{
struct dw_spi *dws = spi_master_get_devdata(master);
struct dw_spi *dws = spi_controller_get_devdata(master);
if (!dws->dma_inited)
return false;

View file

@ -135,7 +135,7 @@ static inline void dw_spi_debugfs_remove(struct dw_spi *dws)
static void dw_spi_set_cs(struct spi_device *spi, bool enable)
{
struct dw_spi *dws = spi_master_get_devdata(spi->master);
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
struct chip_data *chip = spi_get_ctldata(spi);
/* Chip select logic is inverted from spi_set_cs() */
@ -250,8 +250,8 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
static irqreturn_t dw_spi_irq(int irq, void *dev_id)
{
struct spi_master *master = dev_id;
struct dw_spi *dws = spi_master_get_devdata(master);
struct spi_controller *master = dev_id;
struct dw_spi *dws = spi_controller_get_devdata(master);
u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f;
if (!irq_status)
@ -277,10 +277,10 @@ static int poll_transfer(struct dw_spi *dws)
return 0;
}
static int dw_spi_transfer_one(struct spi_master *master,
static int dw_spi_transfer_one(struct spi_controller *master,
struct spi_device *spi, struct spi_transfer *transfer)
{
struct dw_spi *dws = spi_master_get_devdata(master);
struct dw_spi *dws = spi_controller_get_devdata(master);
struct chip_data *chip = spi_get_ctldata(spi);
u8 imask = 0;
u16 txlevel = 0;
@ -383,10 +383,10 @@ static int dw_spi_transfer_one(struct spi_master *master,
return 1;
}
static void dw_spi_handle_err(struct spi_master *master,
static void dw_spi_handle_err(struct spi_controller *master,
struct spi_message *msg)
{
struct dw_spi *dws = spi_master_get_devdata(master);
struct dw_spi *dws = spi_controller_get_devdata(master);
if (dws->dma_mapped)
dws->dma_ops->dma_stop(dws);
@ -471,7 +471,7 @@ static void spi_hw_init(struct device *dev, struct dw_spi *dws)
int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
{
struct spi_master *master;
struct spi_controller *master;
int ret;
BUG_ON(dws == NULL);
@ -518,8 +518,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
}
}
spi_master_set_devdata(master, dws);
ret = devm_spi_register_master(dev, master);
spi_controller_set_devdata(master, dws);
ret = devm_spi_register_controller(dev, master);
if (ret) {
dev_err(&master->dev, "problem registering spi master\n");
goto err_dma_exit;
@ -534,7 +534,7 @@ err_dma_exit:
spi_enable_chip(dws, 0);
free_irq(dws->irq, master);
err_free_master:
spi_master_put(master);
spi_controller_put(master);
return ret;
}
EXPORT_SYMBOL_GPL(dw_spi_add_host);
@ -556,7 +556,7 @@ int dw_spi_suspend_host(struct dw_spi *dws)
{
int ret;
ret = spi_master_suspend(dws->master);
ret = spi_controller_suspend(dws->master);
if (ret)
return ret;
@ -570,7 +570,7 @@ int dw_spi_resume_host(struct dw_spi *dws)
int ret;
spi_hw_init(&dws->master->dev, dws);
ret = spi_master_resume(dws->master);
ret = spi_controller_resume(dws->master);
if (ret)
dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);
return ret;

View file

@ -93,14 +93,14 @@ struct dw_spi_dma_ops {
int (*dma_init)(struct dw_spi *dws);
void (*dma_exit)(struct dw_spi *dws);
int (*dma_setup)(struct dw_spi *dws, struct spi_transfer *xfer);
bool (*can_dma)(struct spi_master *master, struct spi_device *spi,
bool (*can_dma)(struct spi_controller *master, struct spi_device *spi,
struct spi_transfer *xfer);
int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer);
void (*dma_stop)(struct dw_spi *dws);
};
struct dw_spi {
struct spi_master *master;
struct spi_controller *master;
enum dw_ssi_type type;
void __iomem *regs;

View file

@ -2,6 +2,7 @@
* SPI master driver using generic bitbanged GPIO
*
* Copyright (C) 2006,2008 David Brownell
* Copyright (C) 2017 Linus Walleij
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,10 +17,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@ -44,7 +44,11 @@ struct spi_gpio {
struct spi_bitbang bitbang;
struct spi_gpio_platform_data pdata;
struct platform_device *pdev;
unsigned long cs_gpios[0];
struct gpio_desc *sck;
struct gpio_desc *miso;
struct gpio_desc *mosi;
struct gpio_desc **cs_gpios;
bool has_cs;
};
/*----------------------------------------------------------------------*/
@ -77,13 +81,6 @@ struct spi_gpio {
#define GENERIC_BITBANG /* vs tight inlines */
/* all functions referencing these symbols must define pdata */
#define SPI_MISO_GPIO ((pdata)->miso)
#define SPI_MOSI_GPIO ((pdata)->mosi)
#define SPI_SCK_GPIO ((pdata)->sck)
#define SPI_N_CHIPSEL ((pdata)->num_chipselect)
#endif
/*----------------------------------------------------------------------*/
@ -105,25 +102,27 @@ spi_to_pdata(const struct spi_device *spi)
return &spi_to_spi_gpio(spi)->pdata;
}
/* this is #defined to avoid unused-variable warnings when inlining */
#define pdata spi_to_pdata(spi)
/* These helpers are in turn called by the bitbang inlines */
static inline void setsck(const struct spi_device *spi, int is_on)
{
gpio_set_value_cansleep(SPI_SCK_GPIO, is_on);
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
gpiod_set_value_cansleep(spi_gpio->sck, is_on);
}
static inline void setmosi(const struct spi_device *spi, int is_on)
{
gpio_set_value_cansleep(SPI_MOSI_GPIO, is_on);
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
gpiod_set_value_cansleep(spi_gpio->mosi, is_on);
}
static inline int getmiso(const struct spi_device *spi)
{
return !!gpio_get_value_cansleep(SPI_MISO_GPIO);
}
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
#undef pdata
return !!gpiod_get_value_cansleep(spi_gpio->miso);
}
/*
* NOTE: this clocks "as fast as we can". It "should" be a function of the
@ -216,123 +215,89 @@ static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
/* set initial clock polarity */
/* set initial clock line level */
if (is_active)
setsck(spi, spi->mode & SPI_CPOL);
gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL);
if (cs != SPI_GPIO_NO_CHIPSELECT) {
/* SPI is normally active-low */
gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
/* Drive chip select line, if we have one */
if (spi_gpio->has_cs) {
struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select];
/* SPI chip selects are normally active-low */
gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
}
}
static int spi_gpio_setup(struct spi_device *spi)
{
unsigned long cs;
struct gpio_desc *cs;
int status = 0;
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
struct device_node *np = spi->master->dev.of_node;
if (np) {
/*
* In DT environments, the CS GPIOs have already been
* initialized from the "cs-gpios" property of the node.
*/
cs = spi_gpio->cs_gpios[spi->chip_select];
} else {
/*
* ... otherwise, take it from spi->controller_data
*/
cs = (uintptr_t) spi->controller_data;
}
/*
* The CS GPIOs have already been
* initialized from the descriptor lookup.
*/
cs = spi_gpio->cs_gpios[spi->chip_select];
if (!spi->controller_state && cs)
status = gpiod_direction_output(cs,
!(spi->mode & SPI_CS_HIGH));
if (!spi->controller_state) {
if (cs != SPI_GPIO_NO_CHIPSELECT) {
status = gpio_request(cs, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cs,
!(spi->mode & SPI_CS_HIGH));
}
}
if (!status) {
/* in case it was initialized from static board data */
spi_gpio->cs_gpios[spi->chip_select] = cs;
if (!status)
status = spi_bitbang_setup(spi);
}
if (status) {
if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT)
gpio_free(cs);
}
return status;
}
static void spi_gpio_cleanup(struct spi_device *spi)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
if (cs != SPI_GPIO_NO_CHIPSELECT)
gpio_free(cs);
spi_bitbang_cleanup(spi);
}
static int spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
/*
* It can be convenient to use this driver with pins that have alternate
* functions associated with a "native" SPI controller if a driver for that
* controller is not available, or is missing important functionality.
*
* On platforms which can do so, configure MISO with a weak pullup unless
* there's an external pullup on that signal. That saves power by avoiding
* floating signals. (A weak pulldown would save power too, but many
* drivers expect to see all-ones data as the no slave "response".)
*/
static int spi_gpio_request(struct device *dev,
struct spi_gpio *spi_gpio,
unsigned int num_chipselects,
u16 *mflags)
{
int value;
int i;
value = gpio_request(pin, label);
if (value == 0) {
if (is_in)
value = gpio_direction_input(pin);
else
value = gpio_direction_output(pin, 0);
}
return value;
}
static int spi_gpio_request(struct spi_gpio_platform_data *pdata,
const char *label, u16 *res_flags)
{
int value;
/* NOTE: SPI_*_GPIO symbols may reference "pdata" */
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) {
value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
if (value)
goto done;
} else {
spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW);
if (IS_ERR(spi_gpio->mosi))
return PTR_ERR(spi_gpio->mosi);
if (!spi_gpio->mosi)
/* HW configuration without MOSI pin */
*res_flags |= SPI_MASTER_NO_TX;
}
*mflags |= SPI_MASTER_NO_TX;
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) {
value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
if (value)
goto free_mosi;
} else {
spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN);
if (IS_ERR(spi_gpio->miso))
return PTR_ERR(spi_gpio->miso);
if (!spi_gpio->miso)
/* HW configuration without MISO pin */
*res_flags |= SPI_MASTER_NO_RX;
*mflags |= SPI_MASTER_NO_RX;
spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
if (IS_ERR(spi_gpio->mosi))
return PTR_ERR(spi_gpio->mosi);
for (i = 0; i < num_chipselects; i++) {
spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
i, GPIOD_OUT_HIGH);
if (IS_ERR(spi_gpio->cs_gpios[i]))
return PTR_ERR(spi_gpio->cs_gpios[i]);
}
value = spi_gpio_alloc(SPI_SCK_GPIO, label, false);
if (value)
goto free_miso;
goto done;
free_miso:
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
gpio_free(SPI_MISO_GPIO);
free_mosi:
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
gpio_free(SPI_MOSI_GPIO);
done:
return value;
return 0;
}
#ifdef CONFIG_OF
@ -358,26 +323,6 @@ static int spi_gpio_probe_dt(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
ret = of_get_named_gpio(np, "gpio-sck", 0);
if (ret < 0) {
dev_err(&pdev->dev, "gpio-sck property not found\n");
goto error_free;
}
pdata->sck = ret;
ret = of_get_named_gpio(np, "gpio-miso", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-miso property not found, switching to no-rx mode\n");
pdata->miso = SPI_GPIO_NO_MISO;
} else
pdata->miso = ret;
ret = of_get_named_gpio(np, "gpio-mosi", 0);
if (ret < 0) {
dev_info(&pdev->dev, "gpio-mosi property not found, switching to no-tx mode\n");
pdata->mosi = SPI_GPIO_NO_MOSI;
} else
pdata->mosi = ret;
ret = of_property_read_u32(np, "num-chipselects", &tmp);
if (ret < 0) {
@ -409,7 +354,6 @@ static int spi_gpio_probe(struct platform_device *pdev)
struct spi_gpio_platform_data *pdata;
u16 master_flags = 0;
bool use_of = 0;
int num_devices;
status = spi_gpio_probe_dt(pdev);
if (status < 0)
@ -423,59 +367,41 @@ static int spi_gpio_probe(struct platform_device *pdev)
return -ENODEV;
#endif
if (use_of && !SPI_N_CHIPSEL)
num_devices = 1;
else
num_devices = SPI_N_CHIPSEL;
master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio));
if (!master)
return -ENOMEM;
status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
if (status < 0)
return status;
master = spi_alloc_master(&pdev->dev, sizeof(*spi_gpio) +
(sizeof(unsigned long) * num_devices));
if (!master) {
status = -ENOMEM;
goto gpio_free;
}
spi_gpio = spi_master_get_devdata(master);
spi_gpio->cs_gpios = devm_kzalloc(&pdev->dev,
pdata->num_chipselect * sizeof(*spi_gpio->cs_gpios),
GFP_KERNEL);
if (!spi_gpio->cs_gpios)
return -ENOMEM;
platform_set_drvdata(pdev, spi_gpio);
/* Determine if we have chip selects connected */
spi_gpio->has_cs = !!pdata->num_chipselect;
spi_gpio->pdev = pdev;
if (pdata)
spi_gpio->pdata = *pdata;
status = spi_gpio_request(&pdev->dev, spi_gpio,
pdata->num_chipselect, &master_flags);
if (status)
return status;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->flags = master_flags;
master->bus_num = pdev->id;
master->num_chipselect = num_devices;
/* The master needs to think there is a chipselect even if not connected */
master->num_chipselect = spi_gpio->has_cs ? pdata->num_chipselect : 1;
master->setup = spi_gpio_setup;
master->cleanup = spi_gpio_cleanup;
#ifdef CONFIG_OF
master->dev.of_node = pdev->dev.of_node;
if (use_of) {
int i;
struct device_node *np = pdev->dev.of_node;
/*
* In DT environments, take the CS GPIO from the "cs-gpios"
* property of the node.
*/
if (!SPI_N_CHIPSEL)
spi_gpio->cs_gpios[0] = SPI_GPIO_NO_CHIPSELECT;
else
for (i = 0; i < SPI_N_CHIPSEL; i++) {
status = of_get_named_gpio(np, "cs-gpios", i);
if (status < 0) {
dev_err(&pdev->dev,
"invalid cs-gpios property\n");
goto gpio_free;
}
spi_gpio->cs_gpios[i] = status;
}
}
#endif
spi_gpio->bitbang.master = master;
@ -496,15 +422,8 @@ static int spi_gpio_probe(struct platform_device *pdev)
spi_gpio->bitbang.flags = SPI_CS_HIGH;
status = spi_bitbang_start(&spi_gpio->bitbang);
if (status < 0) {
gpio_free:
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
gpio_free(SPI_MISO_GPIO);
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
if (status)
spi_master_put(master);
}
return status;
}
@ -520,11 +439,6 @@ static int spi_gpio_remove(struct platform_device *pdev)
/* stop() unregisters child devices too */
spi_bitbang_stop(&spi_gpio->bitbang);
if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
gpio_free(SPI_MISO_GPIO);
if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
spi_master_put(spi_gpio->bitbang.master);
return 0;