diff options
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 59 | ||||
-rw-r--r-- | include/linux/pxa2xx_ssp.h | 1 |
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 | ||
102 | static inline const struct lpss_config | 112 | static 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 | }; |
1277 | MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); | 1289 | MODULE_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 | */ | ||
1296 | static 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 | |||
1305 | static 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 | |||
1279 | static struct pxa2xx_spi_master * | 1315 | static struct pxa2xx_spi_master * |
1280 | pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev) | 1316 | pxa2xx_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 | ||
202 | struct ssp_device { | 203 | struct ssp_device { |