aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-pxa2xx.c59
-rw-r--r--include/linux/pxa2xx_ssp.h1
2 files changed, 56 insertions, 4 deletions
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 7293d6d875c5..2c9fa409d2bf 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -21,6 +21,7 @@
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/pci.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/spi/pxa2xx_spi.h> 26#include <linux/spi/pxa2xx_spi.h>
26#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
@@ -97,6 +98,15 @@ static const struct lpss_config lpss_platforms[] = {
97 .tx_threshold_lo = 160, 98 .tx_threshold_lo = 160,
98 .tx_threshold_hi = 224, 99 .tx_threshold_hi = 224,
99 }, 100 },
101 { /* LPSS_SPT_SSP */
102 .offset = 0x200,
103 .reg_general = -1,
104 .reg_ssp = 0x20,
105 .reg_cs_ctrl = 0x24,
106 .rx_threshold = 1,
107 .tx_threshold_lo = 32,
108 .tx_threshold_hi = 56,
109 },
100}; 110};
101 111
102static inline const struct lpss_config 112static inline const struct lpss_config
@@ -110,6 +120,7 @@ static bool is_lpss_ssp(const struct driver_data *drv_data)
110 switch (drv_data->ssp_type) { 120 switch (drv_data->ssp_type) {
111 case LPSS_LPT_SSP: 121 case LPSS_LPT_SSP:
112 case LPSS_BYT_SSP: 122 case LPSS_BYT_SSP:
123 case LPSS_SPT_SSP:
113 return true; 124 return true;
114 default: 125 default:
115 return false; 126 return false;
@@ -1107,6 +1118,7 @@ static int setup(struct spi_device *spi)
1107 break; 1118 break;
1108 case LPSS_LPT_SSP: 1119 case LPSS_LPT_SSP:
1109 case LPSS_BYT_SSP: 1120 case LPSS_BYT_SSP:
1121 case LPSS_SPT_SSP:
1110 config = lpss_get_config(drv_data); 1122 config = lpss_get_config(drv_data);
1111 tx_thres = config->tx_threshold_lo; 1123 tx_thres = config->tx_threshold_lo;
1112 tx_hi_thres = config->tx_threshold_hi; 1124 tx_hi_thres = config->tx_threshold_hi;
@@ -1276,6 +1288,30 @@ static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {
1276}; 1288};
1277MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); 1289MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match);
1278 1290
1291/*
1292 * PCI IDs of compound devices that integrate both host controller and private
1293 * integrated DMA engine. Please note these are not used in module
1294 * autoloading and probing in this module but matching the LPSS SSP type.
1295 */
1296static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
1297 /* SPT-LP */
1298 { PCI_VDEVICE(INTEL, 0x9d29), LPSS_SPT_SSP },
1299 { PCI_VDEVICE(INTEL, 0x9d2a), LPSS_SPT_SSP },
1300 /* SPT-H */
1301 { PCI_VDEVICE(INTEL, 0xa129), LPSS_SPT_SSP },
1302 { PCI_VDEVICE(INTEL, 0xa12a), LPSS_SPT_SSP },
1303};
1304
1305static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)
1306{
1307 struct device *dev = param;
1308
1309 if (dev != chan->device->dev->parent)
1310 return false;
1311
1312 return true;
1313}
1314
1279static struct pxa2xx_spi_master * 1315static struct pxa2xx_spi_master *
1280pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) 1316pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
1281{ 1317{
@@ -1283,16 +1319,25 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
1283 struct acpi_device *adev; 1319 struct acpi_device *adev;
1284 struct ssp_device *ssp; 1320 struct ssp_device *ssp;
1285 struct resource *res; 1321 struct resource *res;
1286 const struct acpi_device_id *id; 1322 const struct acpi_device_id *adev_id = NULL;
1323 const struct pci_device_id *pcidev_id = NULL;
1287 int devid, type; 1324 int devid, type;
1288 1325
1289 if (!ACPI_HANDLE(&pdev->dev) || 1326 if (!ACPI_HANDLE(&pdev->dev) ||
1290 acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) 1327 acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev))
1291 return NULL; 1328 return NULL;
1292 1329
1293 id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); 1330 if (dev_is_pci(pdev->dev.parent))
1294 if (id) 1331 pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match,
1295 type = (int)id->driver_data; 1332 to_pci_dev(pdev->dev.parent));
1333 else
1334 adev_id = acpi_match_device(pdev->dev.driver->acpi_match_table,
1335 &pdev->dev);
1336
1337 if (adev_id)
1338 type = (int)adev_id->driver_data;
1339 else if (pcidev_id)
1340 type = (int)pcidev_id->driver_data;
1296 else 1341 else
1297 return NULL; 1342 return NULL;
1298 1343
@@ -1311,6 +1356,12 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
1311 if (IS_ERR(ssp->mmio_base)) 1356 if (IS_ERR(ssp->mmio_base))
1312 return NULL; 1357 return NULL;
1313 1358
1359 if (pcidev_id) {
1360 pdata->tx_param = pdev->dev.parent;
1361 pdata->rx_param = pdev->dev.parent;
1362 pdata->dma_filter = pxa2xx_spi_idma_filter;
1363 }
1364
1314 ssp->clk = devm_clk_get(&pdev->dev, NULL); 1365 ssp->clk = devm_clk_get(&pdev->dev, NULL);
1315 ssp->irq = platform_get_irq(pdev, 0); 1366 ssp->irq = platform_get_irq(pdev, 0);
1316 ssp->type = type; 1367 ssp->type = type;
diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h
index 0485bab061fd..92273776bce6 100644
--- a/include/linux/pxa2xx_ssp.h
+++ b/include/linux/pxa2xx_ssp.h
@@ -197,6 +197,7 @@ enum pxa_ssp_type {
197 QUARK_X1000_SSP, 197 QUARK_X1000_SSP,
198 LPSS_LPT_SSP, /* Keep LPSS types sorted with lpss_platforms[] */ 198 LPSS_LPT_SSP, /* Keep LPSS types sorted with lpss_platforms[] */
199 LPSS_BYT_SSP, 199 LPSS_BYT_SSP,
200 LPSS_SPT_SSP,
200}; 201};
201 202
202struct ssp_device { 203struct ssp_device {