From c7a26f121df611caa47576a169627bfd1c3d1b38 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 2 Feb 2014 10:59:48 +0400 Subject: [PATCH 01/23] spi: clps711x: Simplify handling of RX & TX buffers Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 374ba4a48a9e..89e5ea843fd0 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -32,7 +32,6 @@ struct spi_clps711x_data { u8 *tx_buf; u8 *rx_buf; - int count; int len; int chipselect[0]; @@ -93,11 +92,12 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, struct spi_clps711x_data *hw = spi_master_get_devdata(master); struct spi_transfer *xfer; int status = 0, cs = hw->chipselect[msg->spi->chip_select]; - u32 data; spi_clps711x_setup_mode(msg->spi); list_for_each_entry(xfer, &msg->transfers, transfer_list) { + u8 data; + if (spi_clps711x_setup_xfer(msg->spi, xfer)) { status = -EINVAL; goto out_xfr; @@ -107,13 +107,12 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, reinit_completion(&hw->done); - hw->count = 0; hw->len = xfer->len; hw->tx_buf = (u8 *)xfer->tx_buf; hw->rx_buf = (u8 *)xfer->rx_buf; /* Initiate transfer */ - data = hw->tx_buf ? hw->tx_buf[hw->count] : 0; + data = hw->tx_buf ? *hw->tx_buf++ : 0; clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); wait_for_completion(&hw->done); @@ -138,18 +137,16 @@ out_xfr: static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) { struct spi_clps711x_data *hw = (struct spi_clps711x_data *)dev_id; - u32 data; + u8 data; /* Handle RX */ data = clps_readb(SYNCIO); if (hw->rx_buf) - hw->rx_buf[hw->count] = (u8)data; - - hw->count++; + *hw->rx_buf++ = data; /* Handle TX */ - if (hw->count < hw->len) { - data = hw->tx_buf ? hw->tx_buf[hw->count] : 0; + if (--hw->len > 0) { + data = hw->tx_buf ? *hw->tx_buf++ : 0; clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); } else complete(&hw->done); From 8dda9d9a48baa4a4e0ff6ac9d8f1672f3bf6dfa5 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 2 Feb 2014 10:59:49 +0400 Subject: [PATCH 02/23] spi: clps711x: Add support for 1-8 BPW transfers This patch adds support for 1 to 8 BPW to driver and removes excess BPW validation since this is already checked by SPI core. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 39 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 89e5ea843fd0..89fef4712e9b 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -32,6 +32,7 @@ struct spi_clps711x_data { u8 *tx_buf; u8 *rx_buf; + unsigned int bpw; int len; int chipselect[0]; @@ -57,18 +58,12 @@ static void spi_clps711x_setup_mode(struct spi_device *spi) clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); } -static int spi_clps711x_setup_xfer(struct spi_device *spi, - struct spi_transfer *xfer) +static void spi_clps711x_setup_xfer(struct spi_device *spi, + struct spi_transfer *xfer) { u32 speed = xfer->speed_hz ? : spi->max_speed_hz; - u8 bpw = xfer->bits_per_word; struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); - if (bpw != 8) { - dev_err(&spi->dev, "Unsupported master bus width %i\n", bpw); - return -EINVAL; - } - /* Setup SPI frequency divider */ if (!speed || (speed >= hw->max_speed_hz)) clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | @@ -82,38 +77,36 @@ static int spi_clps711x_setup_xfer(struct spi_device *spi, else clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | SYSCON1_ADCKSEL(0), SYSCON1); - - return 0; } static int spi_clps711x_transfer_one_message(struct spi_master *master, struct spi_message *msg) { struct spi_clps711x_data *hw = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; struct spi_transfer *xfer; - int status = 0, cs = hw->chipselect[msg->spi->chip_select]; + int cs = hw->chipselect[spi->chip_select]; - spi_clps711x_setup_mode(msg->spi); + spi_clps711x_setup_mode(spi); list_for_each_entry(xfer, &msg->transfers, transfer_list) { u8 data; - if (spi_clps711x_setup_xfer(msg->spi, xfer)) { - status = -EINVAL; - goto out_xfr; - } + spi_clps711x_setup_xfer(spi, xfer); - gpio_set_value(cs, !!(msg->spi->mode & SPI_CS_HIGH)); + gpio_set_value(cs, !!(spi->mode & SPI_CS_HIGH)); reinit_completion(&hw->done); hw->len = xfer->len; + hw->bpw = xfer->bits_per_word ? : spi->bits_per_word; hw->tx_buf = (u8 *)xfer->tx_buf; hw->rx_buf = (u8 *)xfer->rx_buf; /* Initiate transfer */ data = hw->tx_buf ? *hw->tx_buf++ : 0; - clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); + clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, + SYNCIO); wait_for_completion(&hw->done); @@ -122,13 +115,12 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, if (xfer->cs_change || list_is_last(&xfer->transfer_list, &msg->transfers)) - gpio_set_value(cs, !(msg->spi->mode & SPI_CS_HIGH)); + gpio_set_value(cs, !(spi->mode & SPI_CS_HIGH)); msg->actual_length += xfer->len; } -out_xfr: - msg->status = status; + msg->status = 0; spi_finalize_current_message(master); return 0; @@ -147,7 +139,8 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) /* Handle TX */ if (--hw->len > 0) { data = hw->tx_buf ? *hw->tx_buf++ : 0; - clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); + clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, + SYNCIO); } else complete(&hw->done); @@ -181,7 +174,7 @@ static int spi_clps711x_probe(struct platform_device *pdev) master->bus_num = pdev->id; master->mode_bits = SPI_CPHA | SPI_CS_HIGH; - master->bits_per_word_mask = SPI_BPW_MASK(8); + master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8); master->num_chipselect = pdata->num_chipselect; master->setup = spi_clps711x_setup; master->transfer_one_message = spi_clps711x_transfer_one_message; From 3e9ea4b4d51d6fce449427bb411debaa4d52397d Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 2 Feb 2014 10:59:50 +0400 Subject: [PATCH 03/23] spi: clps711x: Use SPI-core "cs_gpios" property for storing GPIOs Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index 89fef4712e9b..df086ee4cdaa 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -34,17 +34,12 @@ struct spi_clps711x_data { u8 *rx_buf; unsigned int bpw; int len; - - int chipselect[0]; }; static int spi_clps711x_setup(struct spi_device *spi) { - struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); - /* We are expect that SPI-device is not selected */ - gpio_direction_output(hw->chipselect[spi->chip_select], - !(spi->mode & SPI_CS_HIGH)); + gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); return 0; } @@ -85,7 +80,6 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, struct spi_clps711x_data *hw = spi_master_get_devdata(master); struct spi_device *spi = msg->spi; struct spi_transfer *xfer; - int cs = hw->chipselect[spi->chip_select]; spi_clps711x_setup_mode(spi); @@ -94,7 +88,7 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, spi_clps711x_setup_xfer(spi, xfer); - gpio_set_value(cs, !!(spi->mode & SPI_CS_HIGH)); + gpio_set_value(spi->cs_gpio, !!(spi->mode & SPI_CS_HIGH)); reinit_completion(&hw->done); @@ -115,7 +109,7 @@ static int spi_clps711x_transfer_one_message(struct spi_master *master, if (xfer->cs_change || list_is_last(&xfer->transfer_list, &msg->transfers)) - gpio_set_value(cs, !(spi->mode & SPI_CS_HIGH)); + gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); msg->actual_length += xfer->len; } @@ -164,12 +158,15 @@ static int spi_clps711x_probe(struct platform_device *pdev) return -EINVAL; } - master = spi_alloc_master(&pdev->dev, - sizeof(struct spi_clps711x_data) + - sizeof(int) * pdata->num_chipselect); - if (!master) { - dev_err(&pdev->dev, "SPI allocating memory error\n"); + master = spi_alloc_master(&pdev->dev, sizeof(*hw)); + if (!master) return -ENOMEM; + + master->cs_gpios = devm_kzalloc(&pdev->dev, sizeof(int) * + pdata->num_chipselect, GFP_KERNEL); + if (!master->cs_gpios) { + ret = -ENOMEM; + goto err_out; } master->bus_num = pdev->id; @@ -182,13 +179,13 @@ static int spi_clps711x_probe(struct platform_device *pdev) hw = spi_master_get_devdata(master); for (i = 0; i < master->num_chipselect; i++) { - hw->chipselect[i] = pdata->chipselect[i]; - if (!gpio_is_valid(hw->chipselect[i])) { + master->cs_gpios[i] = pdata->chipselect[i]; + if (!gpio_is_valid(master->cs_gpios[i])) { dev_err(&pdev->dev, "Invalid CS GPIO %i\n", i); ret = -EINVAL; goto err_out; } - if (devm_gpio_request(&pdev->dev, hw->chipselect[i], NULL)) { + if (devm_gpio_request(&pdev->dev, master->cs_gpios[i], NULL)) { dev_err(&pdev->dev, "Can't get CS GPIO %i\n", i); ret = -EINVAL; goto err_out; From 91cfe7e73b484703baf353d3915823210a417d77 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 6 Feb 2014 10:52:21 +0800 Subject: [PATCH 04/23] spi: davinci: Remove unneeded NULL checking for dspi and dspi->bitbang.master spi_master_get_devdata() never returns NULL when spi_alloc_master() success, so remove NULL test for dspi. We have ensured master is not NULL before assigning it to dspi->bitbang.master. So also remove NULL test for dspi->bitbang.master. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 5e7389faa2a0..04d69b650328 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -864,10 +864,6 @@ static int davinci_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); dspi = spi_master_get_devdata(master); - if (dspi == NULL) { - ret = -ENOENT; - goto free_master; - } if (dev_get_platdata(&pdev->dev)) { pdata = dev_get_platdata(&pdev->dev); @@ -908,10 +904,6 @@ static int davinci_spi_probe(struct platform_device *pdev) goto free_master; dspi->bitbang.master = master; - if (dspi->bitbang.master == NULL) { - ret = -ENODEV; - goto free_master; - } dspi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dspi->clk)) { From b53b34f042fe17df21a431abc76896a72dbc5670 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 6 Feb 2014 11:45:08 +0800 Subject: [PATCH 05/23] spi: davinci: Use of_match_ptr at appropriate place It's pointless to use of_match_ptr within CONFIG_OF guard. Use of_match_ptr around davinci_spi_of_match when setting .of_match_table. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 04d69b650328..50f750989258 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -802,8 +802,7 @@ static int spi_davinci_get_pdata(struct platform_device *pdev, pdata = &dspi->pdata; pdata->version = SPI_VERSION_1; - match = of_match_device(of_match_ptr(davinci_spi_of_match), - &pdev->dev); + match = of_match_device(davinci_spi_of_match, &pdev->dev); if (!match) return -ENODEV; @@ -824,7 +823,6 @@ static int spi_davinci_get_pdata(struct platform_device *pdev, return 0; } #else -#define davinci_spi_of_match NULL static struct davinci_spi_platform_data *spi_davinci_get_pdata(struct platform_device *pdev, struct davinci_spi *dspi) @@ -1032,7 +1030,7 @@ static struct platform_driver davinci_spi_driver = { .driver = { .name = "spi_davinci", .owner = THIS_MODULE, - .of_match_table = davinci_spi_of_match, + .of_match_table = of_match_ptr(davinci_spi_of_match), }, .probe = davinci_spi_probe, .remove = davinci_spi_remove, From aa0fe82629f19efba5c870bc9be089a4f8056a75 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 9 Feb 2014 11:06:04 +0800 Subject: [PATCH 06/23] spi: Use reinit_completion at appropriate places Calling init_completion() once is enough. For the rest of the iterations, call reinit_completion() instead. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx-hsspi.c | 3 ++- drivers/spi/spi-bcm63xx.c | 3 ++- drivers/spi/spi-efm32.c | 3 ++- drivers/spi/spi-imx.c | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index b528f9fc8bc0..3ad3e0c59992 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c @@ -180,7 +180,7 @@ static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, struct spi_transfer *t) while (pending > 0) { int curr_step = min_t(int, step_size, pending); - init_completion(&bs->done); + reinit_completion(&bs->done); if (tx) { memcpy_toio(bs->fifo + HSSPI_OPCODE_LEN, tx, curr_step); tx += curr_step; @@ -369,6 +369,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); mutex_init(&bs->bus_mutex); + init_completion(&bs->done); master->bus_num = HSSPI_BUS_NUM; master->num_chipselect = 8; diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 77286aef2adf..161c7910a818 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -169,7 +169,7 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, transfer_list); } - init_completion(&bs->done); + reinit_completion(&bs->done); /* Fill in the Message control register */ msg_ctl = (len << SPI_BYTE_CNT_SHIFT); @@ -353,6 +353,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) } bs = spi_master_get_devdata(master); + init_completion(&bs->done); platform_set_drvdata(pdev, master); bs->pdev = pdev; diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index d4d3cc534792..03cbb5eb33d6 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -198,7 +198,7 @@ static int efm32_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) efm32_spi_filltx(ddata); - init_completion(&ddata->done); + reinit_completion(&ddata->done); efm32_spi_write32(ddata, REG_IF_TXBL | REG_IF_RXDATAV, REG_IEN); @@ -349,6 +349,7 @@ static int efm32_spi_probe(struct platform_device *pdev) ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs; spin_lock_init(&ddata->lock); + init_completion(&ddata->done); ddata->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ddata->clk)) { diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index a5474ef9d2a0..6bb0b693c98c 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -741,7 +741,7 @@ static int spi_imx_transfer(struct spi_device *spi, spi_imx->count = transfer->len; spi_imx->txfifo = 0; - init_completion(&spi_imx->xfer_done); + reinit_completion(&spi_imx->xfer_done); spi_imx_push(spi_imx); From 052eb2d49006fe53bc5f62a196dce23345d4a907 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 Feb 2014 00:08:05 +0800 Subject: [PATCH 07/23] spi: core: Set max_speed_hz of spi_device default to max_speed_hz of controller In __spi_validate(), xfer->speed_hz is set to be spi->max_speed_hz if it is not set for this transfer. However, if spi->max_speed_hz is also not set, xfer->speed_hz is 0. Some drivers (e.g. au1550, tegra114, tegra20-sflash, tegra20-slink, etc.) then use below code to avoid setting xfer->speed_hz to 0. /* Set speed to the spi max fequency if spi device has not set */ spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency; Let's handle it in spi core. If spi->max_speed_hz is not set, make it default to spi->master->max_speed_hz. So In __spi_validate() if both xfer->speed_hz and spi->max_speed_hz are not set, xfer->speed_hz will be set to spi->master->max_speed_hz. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 23756b0f9036..e727ddda78bf 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1599,6 +1599,9 @@ int spi_setup(struct spi_device *spi) if (!spi->bits_per_word) spi->bits_per_word = 8; + if (!spi->max_speed_hz) + spi->max_speed_hz = spi->master->max_speed_hz; + if (spi->master->setup) status = spi->master->setup(spi); From 383840d92f8e5e4c3ab4090e5d8f2ca5cf893802 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 Feb 2014 21:48:16 +0800 Subject: [PATCH 08/23] spi: tegra114: Convert to use master->max_speed_hz Use master->max_speed_hz instead of tspi->spi_max_frequency, so spi core will handle checking transfer speed. In additional, since commit 052eb2d49006 'spi: core: Set max_speed_hz of spi_device default to max_speed_hz of controller', spi core will also set default spi->max_speed_hz if it is not set. So remove the duplicate code in tegra_spi_setup. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-tegra114.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 413c71843492..d8c71b81165a 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -172,7 +172,6 @@ struct tegra_spi_data { void __iomem *base; phys_addr_t phys; unsigned irq; - u32 spi_max_frequency; u32 cur_speed; struct spi_device *cur_spi; @@ -763,9 +762,6 @@ static int tegra_spi_setup(struct spi_device *spi) BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - /* Set speed to the spi max fequency if spi device has not set */ - spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency; - ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); @@ -1019,16 +1015,6 @@ static irqreturn_t tegra_spi_isr(int irq, void *context_data) return IRQ_WAKE_THREAD; } -static void tegra_spi_parse_dt(struct platform_device *pdev, - struct tegra_spi_data *tspi) -{ - struct device_node *np = pdev->dev.of_node; - - if (of_property_read_u32(np, "spi-max-frequency", - &tspi->spi_max_frequency)) - tspi->spi_max_frequency = 25000000; /* 25MHz */ -} - static struct of_device_id tegra_spi_of_match[] = { { .compatible = "nvidia,tegra114-spi", }, {} @@ -1050,8 +1036,9 @@ static int tegra_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); tspi = spi_master_get_devdata(master); - /* Parse DT */ - tegra_spi_parse_dt(pdev, tspi); + if (of_property_read_u32(pdev->dev.of_node, "spi-max-frequency", + &master->max_speed_hz)) + master->max_speed_hz = 25000000; /* 25MHz */ /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; From 44830b4c2f978a1bc667d1557d26277a7e593cf5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 Feb 2014 21:49:49 +0800 Subject: [PATCH 09/23] spi: tegra20-sflash: Convert to use master->max_speed_hz Use master->max_speed_hz instead of tspi->spi_max_frequency, so spi core will handle checking transfer speed. In additional, since commit 052eb2d49006 'spi: core: Set max_speed_hz of spi_device default to max_speed_hz of controller', spi core will also set default spi->max_speed_hz if it is not set. So remove tegra_sflash_setup(). Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-tegra20-sflash.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 08794977f21a..c60d5df054ee 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -121,7 +121,6 @@ struct tegra_sflash_data { struct reset_control *rst; void __iomem *base; unsigned irq; - u32 spi_max_frequency; u32 cur_speed; struct spi_device *cur_spi; @@ -315,15 +314,6 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi, return tegra_sflash_start_cpu_based_transfer(tsd, t); } -static int tegra_sflash_setup(struct spi_device *spi) -{ - struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master); - - /* Set speed to the spi max fequency if spi device has not set */ - spi->max_speed_hz = spi->max_speed_hz ? : tsd->spi_max_frequency; - return 0; -} - static int tegra_sflash_transfer_one_message(struct spi_master *master, struct spi_message *msg) { @@ -430,15 +420,6 @@ static irqreturn_t tegra_sflash_isr(int irq, void *context_data) return handle_cpu_based_xfer(tsd); } -static void tegra_sflash_parse_dt(struct tegra_sflash_data *tsd) -{ - struct device_node *np = tsd->dev->of_node; - - if (of_property_read_u32(np, "spi-max-frequency", - &tsd->spi_max_frequency)) - tsd->spi_max_frequency = 25000000; /* 25MHz */ -} - static struct of_device_id tegra_sflash_of_match[] = { { .compatible = "nvidia,tegra20-sflash", }, {} @@ -467,7 +448,6 @@ static int tegra_sflash_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA; - master->setup = tegra_sflash_setup; master->transfer_one_message = tegra_sflash_transfer_one_message; master->auto_runtime_pm = true; master->num_chipselect = MAX_CHIP_SELECT; @@ -479,7 +459,9 @@ static int tegra_sflash_probe(struct platform_device *pdev) tsd->dev = &pdev->dev; spin_lock_init(&tsd->lock); - tegra_sflash_parse_dt(tsd); + if (of_property_read_u32(tsd->dev->of_node, "spi-max-frequency", + &master->max_speed_hz)) + master->max_speed_hz = 25000000; /* 25MHz */ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); tsd->base = devm_ioremap_resource(&pdev->dev, r); From 3c604de496d7568b3fddb9f2531630aa89908186 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 Feb 2014 21:51:13 +0800 Subject: [PATCH 10/23] spi: tegra20-slink: Convert to use master->max_speed_hz Use master->max_speed_hz instead of tspi->spi_max_frequency, so spi core will handle checking transfer speed. In additional, since commit 052eb2d49006 'spi: core: Set max_speed_hz of spi_device default to max_speed_hz of controller', spi core will also set default spi->max_speed_hz if it is not set. So remove the duplicate code in tegra_slink_setup. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-tegra20-slink.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index be3a069879c3..9da14f2e2818 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -171,7 +171,6 @@ struct tegra_slink_data { void __iomem *base; phys_addr_t phys; unsigned irq; - u32 spi_max_frequency; u32 cur_speed; struct spi_device *cur_spi; @@ -763,8 +762,6 @@ static int tegra_slink_setup(struct spi_device *spi) BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - /* Set speed to the spi max fequency if spi device has not set */ - spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency; ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); @@ -999,15 +996,6 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data) return IRQ_WAKE_THREAD; } -static void tegra_slink_parse_dt(struct tegra_slink_data *tspi) -{ - struct device_node *np = tspi->dev->of_node; - - if (of_property_read_u32(np, "spi-max-frequency", - &tspi->spi_max_frequency)) - tspi->spi_max_frequency = 25000000; /* 25MHz */ -} - static const struct tegra_slink_chip_data tegra30_spi_cdata = { .cs_hold_time = true, }; @@ -1062,7 +1050,9 @@ static int tegra_slink_probe(struct platform_device *pdev) tspi->chip_data = cdata; spin_lock_init(&tspi->lock); - tegra_slink_parse_dt(tspi); + if (of_property_read_u32(tspi->dev->of_node, "spi-max-frequency", + &master->max_speed_hz)) + master->max_speed_hz = 25000000; /* 25MHz */ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { From 354312f16e49add1da78f0cfb2bcb633709d0071 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 11 Feb 2014 22:07:30 +0800 Subject: [PATCH 11/23] spi: Remove duplicate code to check chip_select In spi_add_device(), we have the code to validate spi->chip_select. So remove the duplicate code in various drivers. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 7 ------- drivers/spi/spi-coldfire-qspi.c | 6 ------ drivers/spi/spi-falcon.c | 3 --- drivers/spi/spi-mpc52xx.c | 3 --- drivers/spi/spi-omap-uwire.c | 6 ------ drivers/spi/spi-tegra114.c | 2 -- drivers/spi/spi-tegra20-slink.c | 2 -- 7 files changed, 29 deletions(-) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index b0842f751016..5488ab86312f 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -993,13 +993,6 @@ static int atmel_spi_setup(struct spi_device *spi) as = spi_master_get_devdata(spi->master); - if (spi->chip_select > spi->master->num_chipselect) { - dev_dbg(&spi->dev, - "setup: invalid chipselect %u (%u defined)\n", - spi->chip_select, spi->master->num_chipselect); - return -EINVAL; - } - /* see notes above re chipselect */ if (!atmel_spi_is_v2(as) && spi->chip_select == 0 diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index cabed8f9119e..0ab2c55575dd 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -356,12 +356,6 @@ static int mcfqspi_transfer_one_message(struct spi_master *master, static int mcfqspi_setup(struct spi_device *spi) { - if (spi->chip_select >= spi->master->num_chipselect) { - dev_dbg(&spi->dev, "%d chip select is out of range\n", - spi->chip_select); - return -EINVAL; - } - mcfqspi_cs_deselect(spi_master_get_devdata(spi->master), spi->chip_select, spi->mode & SPI_CS_HIGH); diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index dd5bd468e962..0ae7f45e24a5 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -312,9 +312,6 @@ static int falcon_sflash_setup(struct spi_device *spi) unsigned int i; unsigned long flags; - if (spi->chip_select > 0) - return -ENODEV; - spin_lock_irqsave(&ebu_lock, flags); if (spi->max_speed_hz >= CLOCK_100M) { diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 7c675fe83101..e3d29a56d70a 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -365,9 +365,6 @@ static int mpc52xx_spi_setup(struct spi_device *spi) if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) return -EINVAL; - if (spi->chip_select >= spi->master->num_chipselect) - return -EINVAL; - return 0; } diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 9313fd3b413d..462ddd458217 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -332,12 +332,6 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) uwire = spi_master_get_devdata(spi->master); - if (spi->chip_select > 3) { - pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select); - status = -ENODEV; - goto done; - } - bits = spi->bits_per_word; if (t != NULL && t->bits_per_word) bits = t->bits_per_word; diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index d8c71b81165a..22905b5d2546 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -760,8 +760,6 @@ static int tegra_spi_setup(struct spi_device *spi) spi->mode & SPI_CPHA ? "" : "~", spi->max_speed_hz); - BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 9da14f2e2818..593e823d6c21 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -760,8 +760,6 @@ static int tegra_slink_setup(struct spi_device *spi) spi->mode & SPI_CPHA ? "" : "~", spi->max_speed_hz); - BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); From 78e39523b8c9721250b54b7fd930aeced56cf511 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 11 Feb 2014 22:10:19 +0800 Subject: [PATCH 12/23] spi: Remove explictly set bus_num and num_chipselect to default setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The purpose of commit 1e8a52e18cfb "spi: By default setup spi_masters with 1 chipselect and dynamics bus number" is to avoid setting default value for bus_num and num_chipselect in spi master drivers. So let's remove the duplicate code. Signed-off-by: Axel Lin Acked-by: Uwe Kleine-König Acked-By: David Daney Acked-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-bcm2835.c | 1 - drivers/spi/spi-efm32.c | 4 ---- drivers/spi/spi-falcon.c | 2 -- drivers/spi/spi-octeon.c | 2 -- drivers/spi/spi-sh-hspi.c | 1 - drivers/spi/spi-tegra114.c | 1 - drivers/spi/spi-tegra20-sflash.c | 1 - drivers/spi/spi-tegra20-slink.c | 1 - drivers/spi/spi-ti-qspi.c | 1 - 9 files changed, 14 deletions(-) diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 8a89dd1f2654..69167456ec1e 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -315,7 +315,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev) master->mode_bits = BCM2835_SPI_MODE_BITS; master->bits_per_word_mask = SPI_BPW_MASK(8); - master->bus_num = -1; master->num_chipselect = 3; master->transfer_one_message = bcm2835_spi_transfer_one; master->dev.of_node = pdev->dev.of_node; diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index d4d3cc534792..7199d2fd2b0b 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -308,10 +308,6 @@ static int efm32_spi_probe_dt(struct platform_device *pdev, } ddata->pdata.location = location; - - /* spi core takes care about the bus number using an alias */ - master->bus_num = -1; - return 0; } diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c index dd5bd468e962..ccd257b6e2a8 100644 --- a/drivers/spi/spi-falcon.c +++ b/drivers/spi/spi-falcon.c @@ -422,9 +422,7 @@ static int falcon_sflash_probe(struct platform_device *pdev) priv->master = master; master->mode_bits = SPI_MODE_3; - master->num_chipselect = 1; master->flags = SPI_MASTER_HALF_DUPLEX; - master->bus_num = -1; master->setup = falcon_sflash_setup; master->prepare_transfer_hardware = falcon_sflash_prepare_xfer; master->transfer_one_message = falcon_sflash_xfer_one; diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index 67249a48b391..e31f6d833951 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -257,8 +257,6 @@ static int octeon_spi_probe(struct platform_device *pdev) p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start, resource_size(res_mem)); - /* Dynamic bus numbering */ - master->bus_num = -1; master->num_chipselect = 4; master->mode_bits = SPI_CPHA | SPI_CPOL | diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 82d2f922ffa0..755d7cc9e72f 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -298,7 +298,6 @@ static int hspi_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - master->num_chipselect = 1; master->bus_num = pdev->id; master->setup = hspi_setup; master->cleanup = hspi_cleanup; diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 413c71843492..1e399ad3cc49 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -1058,7 +1058,6 @@ static int tegra_spi_probe(struct platform_device *pdev) master->setup = tegra_spi_setup; master->transfer_one_message = tegra_spi_transfer_one_message; master->num_chipselect = MAX_CHIP_SELECT; - master->bus_num = -1; master->auto_runtime_pm = true; tspi->master = master; diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index 08794977f21a..44e00dba1e79 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c @@ -471,7 +471,6 @@ static int tegra_sflash_probe(struct platform_device *pdev) master->transfer_one_message = tegra_sflash_transfer_one_message; master->auto_runtime_pm = true; master->num_chipselect = MAX_CHIP_SELECT; - master->bus_num = -1; platform_set_drvdata(pdev, master); tsd = spi_master_get_devdata(master); diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index be3a069879c3..b06ea31c1699 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -1053,7 +1053,6 @@ static int tegra_slink_probe(struct platform_device *pdev) master->unprepare_message = tegra_slink_unprepare_message; master->auto_runtime_pm = true; master->num_chipselect = MAX_CHIP_SELECT; - master->bus_num = -1; platform_set_drvdata(pdev, master); tspi = spi_master_get_devdata(master); diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 3d09265b5133..de9920e9d3f8 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -429,7 +429,6 @@ static int ti_qspi_probe(struct platform_device *pdev) master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD; - master->bus_num = -1; master->flags = SPI_MASTER_HALF_DUPLEX; master->setup = ti_qspi_setup; master->auto_runtime_pm = true; From bf5c2e27036cffda6e20f445391a4d4e1ccc232e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 18 Feb 2014 17:15:54 +0800 Subject: [PATCH 13/23] spi: clps711x: Refactor to use core message parsing Convert to use default implementation of transfer_one_message() which provides standard handling of delays and chip select management. Signed-off-by: Axel Lin Tested-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 88 ++++++++++++++------------------------ 1 file changed, 33 insertions(+), 55 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index df086ee4cdaa..eda7472ceefa 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -25,8 +25,6 @@ #define DRIVER_NAME "spi-clps711x" struct spi_clps711x_data { - struct completion done; - struct clk *spi_clk; u32 max_speed_hz; @@ -44,15 +42,6 @@ static int spi_clps711x_setup(struct spi_device *spi) return 0; } -static void spi_clps711x_setup_mode(struct spi_device *spi) -{ - /* Setup edge for transfer */ - if (spi->mode & SPI_CPHA) - clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3); - else - clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); -} - static void spi_clps711x_setup_xfer(struct spi_device *spi, struct spi_transfer *xfer) { @@ -74,55 +63,44 @@ static void spi_clps711x_setup_xfer(struct spi_device *spi, SYSCON1_ADCKSEL(0), SYSCON1); } -static int spi_clps711x_transfer_one_message(struct spi_master *master, - struct spi_message *msg) +static int spi_clps711x_prepare_message(struct spi_master *master, + struct spi_message *msg) { - struct spi_clps711x_data *hw = spi_master_get_devdata(master); struct spi_device *spi = msg->spi; - struct spi_transfer *xfer; - spi_clps711x_setup_mode(spi); - - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - u8 data; - - spi_clps711x_setup_xfer(spi, xfer); - - gpio_set_value(spi->cs_gpio, !!(spi->mode & SPI_CS_HIGH)); - - reinit_completion(&hw->done); - - hw->len = xfer->len; - hw->bpw = xfer->bits_per_word ? : spi->bits_per_word; - hw->tx_buf = (u8 *)xfer->tx_buf; - hw->rx_buf = (u8 *)xfer->rx_buf; - - /* Initiate transfer */ - data = hw->tx_buf ? *hw->tx_buf++ : 0; - clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, - SYNCIO); - - wait_for_completion(&hw->done); - - if (xfer->delay_usecs) - udelay(xfer->delay_usecs); - - if (xfer->cs_change || - list_is_last(&xfer->transfer_list, &msg->transfers)) - gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); - - msg->actual_length += xfer->len; - } - - msg->status = 0; - spi_finalize_current_message(master); + /* Setup edge for transfer */ + if (spi->mode & SPI_CPHA) + clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3); + else + clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); return 0; } +static int spi_clps711x_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct spi_clps711x_data *hw = spi_master_get_devdata(master); + u8 data; + + spi_clps711x_setup_xfer(spi, xfer); + + hw->len = xfer->len; + hw->bpw = xfer->bits_per_word ? : spi->bits_per_word; + hw->tx_buf = (u8 *)xfer->tx_buf; + hw->rx_buf = (u8 *)xfer->rx_buf; + + /* Initiate transfer */ + data = hw->tx_buf ? *hw->tx_buf++ : 0; + clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, SYNCIO); + return 1; +} + static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) { - struct spi_clps711x_data *hw = (struct spi_clps711x_data *)dev_id; + struct spi_master *master = dev_id; + struct spi_clps711x_data *hw = spi_master_get_devdata(master); u8 data; /* Handle RX */ @@ -136,7 +114,7 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, SYNCIO); } else - complete(&hw->done); + spi_finalize_current_transfer(master); return IRQ_HANDLED; } @@ -174,7 +152,8 @@ static int spi_clps711x_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 8); master->num_chipselect = pdata->num_chipselect; master->setup = spi_clps711x_setup; - master->transfer_one_message = spi_clps711x_transfer_one_message; + master->prepare_message = spi_clps711x_prepare_message; + master->transfer_one = spi_clps711x_transfer_one; hw = spi_master_get_devdata(master); @@ -200,7 +179,6 @@ static int spi_clps711x_probe(struct platform_device *pdev) } hw->max_speed_hz = clk_get_rate(hw->spi_clk); - init_completion(&hw->done); platform_set_drvdata(pdev, master); /* Disable extended mode due hardware problems */ @@ -210,7 +188,7 @@ static int spi_clps711x_probe(struct platform_device *pdev) clps_readl(SYNCIO); ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0, - dev_name(&pdev->dev), hw); + dev_name(&pdev->dev), master); if (ret) { dev_err(&pdev->dev, "Can't request IRQ\n"); goto err_out; From 8bd313453736d8efa82afee01c899774b29362ac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 14 Feb 2014 09:54:25 +0800 Subject: [PATCH 14/23] spi: coldfire-qspi: Remove unused dev field from struct mcfqspi Also remove unused *res variable in mcfqspi_remove(). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-coldfire-qspi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index cabed8f9119e..e35294239034 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -77,8 +77,6 @@ struct mcfqspi { struct mcfqspi_cs_control *cs_control; wait_queue_head_t waitq; - - struct device *dev; }; static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) @@ -436,7 +434,6 @@ static int mcfqspi_probe(struct platform_device *pdev) } init_waitqueue_head(&mcfqspi->waitq); - mcfqspi->dev = &pdev->dev; master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); @@ -451,7 +448,7 @@ static int mcfqspi_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "spi_register_master failed\n"); goto fail2; } - pm_runtime_enable(mcfqspi->dev); + pm_runtime_enable(&pdev->dev); dev_info(&pdev->dev, "Coldfire QSPI bus driver\n"); @@ -473,9 +470,8 @@ static int mcfqspi_remove(struct platform_device *pdev) { struct spi_master *master = platform_get_drvdata(pdev); struct mcfqspi *mcfqspi = spi_master_get_devdata(master); - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pm_runtime_disable(mcfqspi->dev); + pm_runtime_disable(&pdev->dev); /* disable the hardware (set the baud rate to 0) */ mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); From 3531b717d05273e45efd2ab7903ea013aaec3fea Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 14 Feb 2014 09:55:55 +0800 Subject: [PATCH 15/23] spi: coldfire-qspi: Use core message handling Convert to use default implementation of transfer_one_message(). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-coldfire-qspi.c | 83 ++++++++++++++------------------- 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index e35294239034..8d594c6704ad 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -298,58 +298,44 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count, } } -static int mcfqspi_transfer_one_message(struct spi_master *master, - struct spi_message *msg) +static void mcfqspi_set_cs(struct spi_device *spi, bool enable) +{ + struct mcfqspi *mcfqspi = spi_master_get_devdata(spi->master); + bool cs_high = spi->mode & SPI_CS_HIGH; + + if (enable) + mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); + else + mcfqspi_cs_deselect(mcfqspi, spi->chip_select, cs_high); +} + +static int mcfqspi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *t) { struct mcfqspi *mcfqspi = spi_master_get_devdata(master); - struct spi_device *spi = msg->spi; - struct spi_transfer *t; - int status = 0; + u16 qmr = MCFQSPI_QMR_MSTR; - list_for_each_entry(t, &msg->transfers, transfer_list) { - bool cs_high = spi->mode & SPI_CS_HIGH; - u16 qmr = MCFQSPI_QMR_MSTR; + qmr |= t->bits_per_word << 10; + if (spi->mode & SPI_CPHA) + qmr |= MCFQSPI_QMR_CPHA; + if (spi->mode & SPI_CPOL) + qmr |= MCFQSPI_QMR_CPOL; + if (t->speed_hz) + qmr |= mcfqspi_qmr_baud(t->speed_hz); + else + qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); + mcfqspi_wr_qmr(mcfqspi, qmr); - qmr |= t->bits_per_word << 10; - if (spi->mode & SPI_CPHA) - qmr |= MCFQSPI_QMR_CPHA; - if (spi->mode & SPI_CPOL) - qmr |= MCFQSPI_QMR_CPOL; - if (t->speed_hz) - qmr |= mcfqspi_qmr_baud(t->speed_hz); - else - qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); - mcfqspi_wr_qmr(mcfqspi, qmr); - - mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); - - mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); - if (t->bits_per_word == 8) - mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, - t->rx_buf); - else - mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, - t->rx_buf); - mcfqspi_wr_qir(mcfqspi, 0); - - if (t->delay_usecs) - udelay(t->delay_usecs); - if (t->cs_change) { - if (!list_is_last(&t->transfer_list, &msg->transfers)) - mcfqspi_cs_deselect(mcfqspi, spi->chip_select, - cs_high); - } else { - if (list_is_last(&t->transfer_list, &msg->transfers)) - mcfqspi_cs_deselect(mcfqspi, spi->chip_select, - cs_high); - } - msg->actual_length += t->len; - } - msg->status = status; - spi_finalize_current_message(master); - - return status; + mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); + if (t->bits_per_word == 8) + mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, t->rx_buf); + else + mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, + t->rx_buf); + mcfqspi_wr_qir(mcfqspi, 0); + return 0; } static int mcfqspi_setup(struct spi_device *spi) @@ -438,7 +424,8 @@ static int mcfqspi_probe(struct platform_device *pdev) master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); master->setup = mcfqspi_setup; - master->transfer_one_message = mcfqspi_transfer_one_message; + master->set_cs = mcfqspi_set_cs; + master->transfer_one = mcfqspi_transfer_one; master->auto_runtime_pm = true; platform_set_drvdata(pdev, master); From 2aa237f4a1a72813f9684a0ce6e48288e75de479 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 26 Feb 2014 09:47:55 +0800 Subject: [PATCH 16/23] spi: coldfire-qspi: Enable clock before calling spi_master_resume This ensures clock has been enabled before calling spi_master_resume(). while at it, also add checking return value of spi_master_suspend and spi_master_resume because they may fail. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-coldfire-qspi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 8d594c6704ad..94d817523d5f 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -473,8 +473,11 @@ static int mcfqspi_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct mcfqspi *mcfqspi = spi_master_get_devdata(master); + int ret; - spi_master_suspend(master); + ret = spi_master_suspend(master); + if (ret) + return ret; clk_disable(mcfqspi->clk); @@ -486,11 +489,9 @@ static int mcfqspi_resume(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); struct mcfqspi *mcfqspi = spi_master_get_devdata(master); - spi_master_resume(master); - clk_enable(mcfqspi->clk); - return 0; + return spi_master_resume(master); } #endif From fcba212de9bdf1016d981c355df29ab169da8eae Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 4 Mar 2014 12:59:53 +0800 Subject: [PATCH 17/23] spi: clps711x: Provide label argument for devm_gpio_request The label argument was removed by commit 989847967cd762 spi: clps711x: Use devm_gpio_request(), add it back. This makes it easier to know the gpio usage in /sys/kernel/debug/gpio. Also remove unnecessary gpio_is_valid() checking, devm_gpio_request() returns error if the requested gpio is invalid. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index eda7472ceefa..a5938abacfb0 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -159,14 +159,10 @@ static int spi_clps711x_probe(struct platform_device *pdev) for (i = 0; i < master->num_chipselect; i++) { master->cs_gpios[i] = pdata->chipselect[i]; - if (!gpio_is_valid(master->cs_gpios[i])) { - dev_err(&pdev->dev, "Invalid CS GPIO %i\n", i); - ret = -EINVAL; - goto err_out; - } - if (devm_gpio_request(&pdev->dev, master->cs_gpios[i], NULL)) { + ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], + DRIVER_NAME); + if (ret) { dev_err(&pdev->dev, "Can't get CS GPIO %i\n", i); - ret = -EINVAL; goto err_out; } } From 2271cf124a2763b7252887814a7fc8a844767e8f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 9 Mar 2014 14:11:10 +0800 Subject: [PATCH 18/23] spi: coldfire-qspi: Prevent NULL pointer dereference If pdata->cs_control is NULL, we will hit NULL pointer dereference in mcfqspi_cs_select() and mcfqspi_cs_deselect(). Thus add NULL test for pdata->cs_control in probe(). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-coldfire-qspi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 94d817523d5f..6d78f96bdc55 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -133,13 +133,13 @@ static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select, static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi) { - return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ? + return (mcfqspi->cs_control->setup) ? mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0; } static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi) { - if (mcfqspi->cs_control && mcfqspi->cs_control->teardown) + if (mcfqspi->cs_control->teardown) mcfqspi->cs_control->teardown(mcfqspi->cs_control); } @@ -372,6 +372,11 @@ static int mcfqspi_probe(struct platform_device *pdev) return -ENOENT; } + if (!pdata->cs_control) { + dev_dbg(&pdev->dev, "pdata->cs_control is NULL\n"); + return -EINVAL; + } + master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi)); if (master == NULL) { dev_dbg(&pdev->dev, "spi_alloc_master failed\n"); From bed890b4310b1d3b33c88fb83e216a8182e8bbad Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 2 Mar 2014 23:24:18 +0800 Subject: [PATCH 19/23] spi: clps711x: Remove duplicate code to set default bits_per_word and max speed In the implementation of __spi_validate(), spi core will set transfer bits_per_word and max speed as spi device default if it is not set for this transfer. So we can remove the same logic in spi_clps711x_setup_xfer() and spi_clps711x_transfer_one(). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index a5938abacfb0..ab010c05dc5a 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -45,17 +45,16 @@ static int spi_clps711x_setup(struct spi_device *spi) static void spi_clps711x_setup_xfer(struct spi_device *spi, struct spi_transfer *xfer) { - u32 speed = xfer->speed_hz ? : spi->max_speed_hz; struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); /* Setup SPI frequency divider */ - if (!speed || (speed >= hw->max_speed_hz)) + if (!xfer->speed_hz || (xfer->speed_hz >= hw->max_speed_hz)) clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | SYSCON1_ADCKSEL(3), SYSCON1); - else if (speed >= (hw->max_speed_hz / 2)) + else if (xfer->speed_hz >= (hw->max_speed_hz / 2)) clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | SYSCON1_ADCKSEL(2), SYSCON1); - else if (speed >= (hw->max_speed_hz / 8)) + else if (xfer->speed_hz >= (hw->max_speed_hz / 8)) clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | SYSCON1_ADCKSEL(1), SYSCON1); else @@ -87,7 +86,7 @@ static int spi_clps711x_transfer_one(struct spi_master *master, spi_clps711x_setup_xfer(spi, xfer); hw->len = xfer->len; - hw->bpw = xfer->bits_per_word ? : spi->bits_per_word; + hw->bpw = xfer->bits_per_word; hw->tx_buf = (u8 *)xfer->tx_buf; hw->rx_buf = (u8 *)xfer->rx_buf; From 3dc925945b00c231419e12c00c998cdcc3a6b8cf Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 22 Mar 2014 10:57:35 +0400 Subject: [PATCH 20/23] spi: clps711x: Remove dependency This patch removes dependency. This is performed by replace hard coded used memory regions and interrupt to getting these values from resources passed to the driver. For the system-wide registers we now able to use SYSCON driver. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 94 +++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index ab010c05dc5a..d9eec4e3b246 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -17,14 +17,21 @@ #include #include #include +#include +#include +#include #include #include -#include - #define DRIVER_NAME "spi-clps711x" +#define SYNCIO_FRMLEN(x) ((x) << 8) +#define SYNCIO_TXFRMEN (1 << 14) + struct spi_clps711x_data { + void __iomem *syncio; + struct regmap *syscon; + struct regmap *syscon1; struct clk *spi_clk; u32 max_speed_hz; @@ -49,31 +56,29 @@ static void spi_clps711x_setup_xfer(struct spi_device *spi, /* Setup SPI frequency divider */ if (!xfer->speed_hz || (xfer->speed_hz >= hw->max_speed_hz)) - clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | - SYSCON1_ADCKSEL(3), SYSCON1); + regmap_update_bits(hw->syscon1, SYSCON_OFFSET, + SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(3)); else if (xfer->speed_hz >= (hw->max_speed_hz / 2)) - clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | - SYSCON1_ADCKSEL(2), SYSCON1); + regmap_update_bits(hw->syscon1, SYSCON_OFFSET, + SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(2)); else if (xfer->speed_hz >= (hw->max_speed_hz / 8)) - clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | - SYSCON1_ADCKSEL(1), SYSCON1); + regmap_update_bits(hw->syscon1, SYSCON_OFFSET, + SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(1)); else - clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | - SYSCON1_ADCKSEL(0), SYSCON1); + regmap_update_bits(hw->syscon1, SYSCON_OFFSET, + SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(0)); } static int spi_clps711x_prepare_message(struct spi_master *master, struct spi_message *msg) { + struct spi_clps711x_data *hw = spi_master_get_devdata(master); struct spi_device *spi = msg->spi; - /* Setup edge for transfer */ - if (spi->mode & SPI_CPHA) - clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3); - else - clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); - - return 0; + /* Setup mode for transfer */ + return regmap_update_bits(hw->syscon, SYSCON_OFFSET, SYSCON3_ADCCKNSEN, + (spi->mode & SPI_CPHA) ? + SYSCON3_ADCCKNSEN : 0); } static int spi_clps711x_transfer_one(struct spi_master *master, @@ -92,7 +97,8 @@ static int spi_clps711x_transfer_one(struct spi_master *master, /* Initiate transfer */ data = hw->tx_buf ? *hw->tx_buf++ : 0; - clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, SYNCIO); + writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, hw->syncio); + return 1; } @@ -103,15 +109,15 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) u8 data; /* Handle RX */ - data = clps_readb(SYNCIO); + data = readb(hw->syncio); if (hw->rx_buf) *hw->rx_buf++ = data; /* Handle TX */ if (--hw->len > 0) { data = hw->tx_buf ? *hw->tx_buf++ : 0; - clps_writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, - SYNCIO); + writel(data | SYNCIO_FRMLEN(hw->bpw) | SYNCIO_TXFRMEN, + hw->syncio); } else spi_finalize_current_transfer(master); @@ -120,10 +126,11 @@ static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) static int spi_clps711x_probe(struct platform_device *pdev) { - int i, ret; - struct spi_master *master; struct spi_clps711x_data *hw; struct spi_clps711x_pdata *pdata = dev_get_platdata(&pdev->dev); + struct spi_master *master; + struct resource *res; + int i, irq, ret; if (!pdata) { dev_err(&pdev->dev, "No platform data supplied\n"); @@ -135,6 +142,10 @@ static int spi_clps711x_probe(struct platform_device *pdev) return -EINVAL; } + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + master = spi_alloc_master(&pdev->dev, sizeof(*hw)); if (!master) return -ENOMEM; @@ -176,19 +187,36 @@ static int spi_clps711x_probe(struct platform_device *pdev) platform_set_drvdata(pdev, master); - /* Disable extended mode due hardware problems */ - clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCON, SYSCON3); - - /* Clear possible pending interrupt */ - clps_readl(SYNCIO); - - ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0, - dev_name(&pdev->dev), master); - if (ret) { - dev_err(&pdev->dev, "Can't request IRQ\n"); + hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3"); + if (IS_ERR(hw->syscon)) { + ret = PTR_ERR(hw->syscon); goto err_out; } + hw->syscon1 = syscon_regmap_lookup_by_pdevname("syscon.1"); + if (IS_ERR(hw->syscon1)) { + ret = PTR_ERR(hw->syscon1); + goto err_out; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hw->syncio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(hw->syncio)) { + ret = PTR_ERR(hw->syncio); + goto err_out; + } + + /* Disable extended mode due hardware problems */ + regmap_update_bits(hw->syscon, SYSCON_OFFSET, SYSCON3_ADCCON, 0); + + /* Clear possible pending interrupt */ + readl(hw->syncio); + + ret = devm_request_irq(&pdev->dev, irq, spi_clps711x_isr, 0, + dev_name(&pdev->dev), master); + if (ret) + goto err_out; + ret = devm_spi_register_master(&pdev->dev, master); if (!ret) { dev_info(&pdev->dev, From 8023d384ff5c55a431c1a9a84cd76648d43ba7d8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 20 Mar 2014 22:59:06 +0800 Subject: [PATCH 21/23] spi: coldfire-qspi: Simplify the code to set register bits for transfer speed spi core will use spi->max_speed_hz as transfer speed if the transfer speed was not set. So we don't need to test t->speed_hz in mcfqspi_transfer_one(). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-coldfire-qspi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 6d78f96bdc55..492ceb1654e5 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c @@ -321,10 +321,7 @@ static int mcfqspi_transfer_one(struct spi_master *master, qmr |= MCFQSPI_QMR_CPHA; if (spi->mode & SPI_CPOL) qmr |= MCFQSPI_QMR_CPOL; - if (t->speed_hz) - qmr |= mcfqspi_qmr_baud(t->speed_hz); - else - qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); + qmr |= mcfqspi_qmr_baud(t->speed_hz); mcfqspi_wr_qmr(mcfqspi, qmr); mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); From 5634dd8bf422e0e5b71bb9762ff079f01a5f9a83 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 26 Mar 2014 16:53:18 +0800 Subject: [PATCH 22/23] spi: clps711x: Enable driver compilation with COMPILE_TEST This helps increasing build testing coverage. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ba9310bc9acb..9b77b0f59b96 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -150,7 +150,7 @@ config SPI_BUTTERFLY config SPI_CLPS711X tristate "CLPS711X host SPI controller" - depends on ARCH_CLPS711X + depends on ARCH_CLPS711X || COMPILE_TEST help This enables dedicated general purpose SPI/Microwire1-compatible master mode interface (SSI1) for CLPS711X-based CPUs. From 6f50c6bc61d4f8cac9dfa21d2db3917deb9beb20 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 26 Mar 2014 23:44:18 +0800 Subject: [PATCH 23/23] spi: clps711x: Convert to use master->max_speed_hz Set highest transfer speed to master->max_speed_hz and then we can remove hw->max_speed. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/spi/spi-clps711x.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c index d9eec4e3b246..a2b8ef5d8c59 100644 --- a/drivers/spi/spi-clps711x.c +++ b/drivers/spi/spi-clps711x.c @@ -33,7 +33,6 @@ struct spi_clps711x_data { struct regmap *syscon; struct regmap *syscon1; struct clk *spi_clk; - u32 max_speed_hz; u8 *tx_buf; u8 *rx_buf; @@ -52,16 +51,17 @@ static int spi_clps711x_setup(struct spi_device *spi) static void spi_clps711x_setup_xfer(struct spi_device *spi, struct spi_transfer *xfer) { - struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); + struct spi_master *master = spi->master; + struct spi_clps711x_data *hw = spi_master_get_devdata(master); /* Setup SPI frequency divider */ - if (!xfer->speed_hz || (xfer->speed_hz >= hw->max_speed_hz)) + if (xfer->speed_hz >= master->max_speed_hz) regmap_update_bits(hw->syscon1, SYSCON_OFFSET, SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(3)); - else if (xfer->speed_hz >= (hw->max_speed_hz / 2)) + else if (xfer->speed_hz >= (master->max_speed_hz / 2)) regmap_update_bits(hw->syscon1, SYSCON_OFFSET, SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(2)); - else if (xfer->speed_hz >= (hw->max_speed_hz / 8)) + else if (xfer->speed_hz >= (master->max_speed_hz / 8)) regmap_update_bits(hw->syscon1, SYSCON_OFFSET, SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(1)); else @@ -183,7 +183,7 @@ static int spi_clps711x_probe(struct platform_device *pdev) ret = PTR_ERR(hw->spi_clk); goto err_out; } - hw->max_speed_hz = clk_get_rate(hw->spi_clk); + master->max_speed_hz = clk_get_rate(hw->spi_clk); platform_set_drvdata(pdev, master); @@ -221,7 +221,7 @@ static int spi_clps711x_probe(struct platform_device *pdev) if (!ret) { dev_info(&pdev->dev, "SPI bus driver initialized. Master clock %u Hz\n", - hw->max_speed_hz); + master->max_speed_hz); return 0; }