From 743485ea3bee852fa816a2ec6c64b3d500e39895 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 4 Jul 2016 12:44:24 +0300 Subject: spi: pxa2xx-pci: Do a specific setup in a separate function Move LPSS specific setup to a separate function. It makes ->probe() cleaner as well as allows extend the driver for different variation of hardware in the future, e.g. for Intel Merrifield. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 77 +++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 33 deletions(-) (limited to 'drivers/spi/spi-pxa2xx-pci.c') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 5202de94f792..8d58598c325d 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -29,8 +29,11 @@ struct pxa_spi_info { unsigned long max_clk_rate; /* DMA channel request parameters */ + bool (*dma_filter)(struct dma_chan *chan, void *param); void *tx_param; void *rx_param; + + int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c); }; static struct dw_dma_slave byt_tx_param = { .dst_id = 0 }; @@ -57,6 +60,35 @@ static bool lpss_dma_filter(struct dma_chan *chan, void *param) return true; } +static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) +{ + struct pci_dev *dma_dev; + + c->num_chipselect = 1; + c->max_clk_rate = 50000000; + + dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + + if (c->tx_param) { + struct dw_dma_slave *slave = c->tx_param; + + slave->dma_dev = &dma_dev->dev; + slave->m_master = 0; + slave->p_master = 1; + } + + if (c->rx_param) { + struct dw_dma_slave *slave = c->rx_param; + + slave->dma_dev = &dma_dev->dev; + slave->m_master = 0; + slave->p_master = 1; + } + + c->dma_filter = lpss_dma_filter; + return 0; +} + static struct pxa_spi_info spi_info_configs[] = { [PORT_CE4100] = { .type = PXA25x_SSP, @@ -67,32 +99,28 @@ static struct pxa_spi_info spi_info_configs[] = { [PORT_BYT] = { .type = LPSS_BYT_SSP, .port_id = 0, - .num_chipselect = 1, - .max_clk_rate = 50000000, + .setup = lpss_spi_setup, .tx_param = &byt_tx_param, .rx_param = &byt_rx_param, }, [PORT_BSW0] = { .type = LPSS_BYT_SSP, .port_id = 0, - .num_chipselect = 1, - .max_clk_rate = 50000000, + .setup = lpss_spi_setup, .tx_param = &bsw0_tx_param, .rx_param = &bsw0_rx_param, }, [PORT_BSW1] = { .type = LPSS_BYT_SSP, .port_id = 1, - .num_chipselect = 1, - .max_clk_rate = 50000000, + .setup = lpss_spi_setup, .tx_param = &bsw1_tx_param, .rx_param = &bsw1_rx_param, }, [PORT_BSW2] = { .type = LPSS_BYT_SSP, .port_id = 2, - .num_chipselect = 1, - .max_clk_rate = 50000000, + .setup = lpss_spi_setup, .tx_param = &bsw2_tx_param, .rx_param = &bsw2_rx_param, }, @@ -105,8 +133,7 @@ static struct pxa_spi_info spi_info_configs[] = { [PORT_LPT] = { .type = LPSS_LPT_SSP, .port_id = 0, - .num_chipselect = 1, - .max_clk_rate = 50000000, + .setup = lpss_spi_setup, .tx_param = &lpt_tx_param, .rx_param = &lpt_rx_param, }, @@ -122,7 +149,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, struct ssp_device *ssp; struct pxa_spi_info *c; char buf[40]; - struct pci_dev *dma_dev; ret = pcim_enable_device(dev); if (ret) @@ -133,30 +159,15 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, return ret; c = &spi_info_configs[ent->driver_data]; - - memset(&spi_pdata, 0, sizeof(spi_pdata)); - spi_pdata.num_chipselect = (c->num_chipselect > 0) ? - c->num_chipselect : dev->devfn; - - dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); - - if (c->tx_param) { - struct dw_dma_slave *slave = c->tx_param; - - slave->dma_dev = &dma_dev->dev; - slave->m_master = 0; - slave->p_master = 1; - } - - if (c->rx_param) { - struct dw_dma_slave *slave = c->rx_param; - - slave->dma_dev = &dma_dev->dev; - slave->m_master = 0; - slave->p_master = 1; + if (c->setup) { + ret = c->setup(dev, c); + if (ret) + return ret; } - spi_pdata.dma_filter = lpss_dma_filter; + memset(&spi_pdata, 0, sizeof(spi_pdata)); + spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn; + spi_pdata.dma_filter = c->dma_filter; spi_pdata.tx_param = c->tx_param; spi_pdata.rx_param = c->rx_param; spi_pdata.enable_dma = c->rx_param && c->tx_param; -- cgit v1.2.3 From 4f4709109ef7e1248b5515c68df4b9c5ad39fbdf Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 4 Jul 2016 12:44:25 +0300 Subject: spi: pxa2xx-pci: Enable SPI on Intel Merrifield The SPI controllers used on Intel Merrifield are PXA2XX compatible. This patch enables them. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/spi/spi-pxa2xx-pci.c') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 8d58598c325d..b025eaf14f0f 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -15,6 +15,7 @@ enum { PORT_CE4100, PORT_BYT, + PORT_MRFLD, PORT_BSW0, PORT_BSW1, PORT_BSW2, @@ -89,6 +90,27 @@ static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) return 0; } +static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) +{ + switch (PCI_FUNC(dev->devfn)) { + case 0: + c->port_id = 3; + c->num_chipselect = 1; + break; + case 1: + c->port_id = 5; + c->num_chipselect = 4; + break; + case 2: + c->port_id = 6; + c->num_chipselect = 1; + break; + default: + return -ENODEV; + } + return 0; +} + static struct pxa_spi_info spi_info_configs[] = { [PORT_CE4100] = { .type = PXA25x_SSP, @@ -124,6 +146,11 @@ static struct pxa_spi_info spi_info_configs[] = { .tx_param = &bsw2_tx_param, .rx_param = &bsw2_rx_param, }, + [PORT_MRFLD] = { + .type = PXA27x_SSP, + .max_clk_rate = 25000000, + .setup = mrfld_spi_setup, + }, [PORT_QUARK_X1000] = { .type = QUARK_X1000_SSP, .port_id = -1, @@ -222,6 +249,7 @@ static const struct pci_device_id pxa2xx_spi_pci_devices[] = { { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, + { PCI_VDEVICE(INTEL, 0x1194), PORT_MRFLD }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 }, -- cgit v1.2.3 From 21ddba19ce851d322172a1f006d27e4f6ff3059d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 4 Jul 2016 12:44:26 +0300 Subject: spi: pxa2xx-pci: Remove unused code pcim_iomap_table() can't fail when called after pcim_iomap_regions(). Moreover, we already dereference returned value and kernel will crash if it is not correct. Remove obvious leftover of commit 0202775bc3a2 ("spi/pxa2xx-pci: switch to use pcim_* interfaces"). Cc: Mika Westerberg Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/spi/spi-pxa2xx-pci.c') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index b025eaf14f0f..4e3c5a7d9a96 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -202,10 +202,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ssp = &spi_pdata.ssp; ssp->phys_base = pci_resource_start(dev, 0); ssp->mmio_base = pcim_iomap_table(dev)[0]; - if (!ssp->mmio_base) { - dev_err(&dev->dev, "failed to ioremap() registers\n"); - return -EIO; - } ssp->irq = dev->irq; ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->type = c->type; -- cgit v1.2.3 From e379d2cd35ca0a9e2a2578f40cf75632266f5741 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 4 Jul 2016 12:44:27 +0300 Subject: spi: pxa2xx-pci: Sort header block alphabetically Simply sort header block alphabetically. While here, sort devices by PCI ID and add a copyright line for Intel. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/spi/spi-pxa2xx-pci.c') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 4e3c5a7d9a96..5953edc86ec8 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -1,25 +1,26 @@ /* * CE4100's SPI device is more or less the same one as found on PXA * + * Copyright (C) 2016, Intel Corporation */ +#include +#include +#include #include #include -#include -#include #include -#include #include #include enum { - PORT_CE4100, + PORT_QUARK_X1000, PORT_BYT, PORT_MRFLD, PORT_BSW0, PORT_BSW1, PORT_BSW2, - PORT_QUARK_X1000, + PORT_CE4100, PORT_LPT, }; @@ -242,13 +243,13 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) } static const struct pci_device_id pxa2xx_spi_pci_devices[] = { - { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 }, { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, { PCI_VDEVICE(INTEL, 0x1194), PORT_MRFLD }, { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 }, { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 }, + { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, { PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT }, { }, }; -- cgit v1.2.3 From ca80ef718b12eebe247b776d4b97a5e571bb489d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 5 Jul 2016 23:12:05 +0300 Subject: spi: pxa2xx-pci: Support both chipselects on Braswell The commit 30f3a6ab44d8 ("spi: pxa2xx: Add support for both chip selects on Intel Braswell") introduces a support of chipselects for Intel Braswell SPI host controller. Though it missed to convert the PCI part of the driver. Do conversion here which enables both chipselects on Intel Braswell when enumerated via PCI. We don't care about num_chipselect value since it is overrided inside core driver. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/spi/spi-pxa2xx-pci.c') diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 5953edc86ec8..f3df522db93b 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -127,21 +127,21 @@ static struct pxa_spi_info spi_info_configs[] = { .rx_param = &byt_rx_param, }, [PORT_BSW0] = { - .type = LPSS_BYT_SSP, + .type = LPSS_BSW_SSP, .port_id = 0, .setup = lpss_spi_setup, .tx_param = &bsw0_tx_param, .rx_param = &bsw0_rx_param, }, [PORT_BSW1] = { - .type = LPSS_BYT_SSP, + .type = LPSS_BSW_SSP, .port_id = 1, .setup = lpss_spi_setup, .tx_param = &bsw1_tx_param, .rx_param = &bsw1_rx_param, }, [PORT_BSW2] = { - .type = LPSS_BYT_SSP, + .type = LPSS_BSW_SSP, .port_id = 2, .setup = lpss_spi_setup, .tx_param = &bsw2_tx_param, -- cgit v1.2.3