162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * PCI glue driver for SPI PXA2xx compatible controllers.
462306a36Sopenharmony_ci * CE4100's SPI device is more or less the same one as found on PXA.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2016, 2021 Intel Corporation
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/clk-provider.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <linux/pci.h>
1162306a36Sopenharmony_ci#include <linux/platform_device.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/spi/pxa2xx_spi.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/dmaengine.h>
1662306a36Sopenharmony_ci#include <linux/platform_data/dma-dw.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_QUARK_X1000		0x0935
1962306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_BYT			0x0f0e
2062306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_MRFLD		0x1194
2162306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_BSW0		0x228e
2262306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_BSW1		0x2290
2362306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_BSW2		0x22ac
2462306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_CE4100		0x2e6a
2562306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_LPT0_0		0x9c65
2662306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_LPT0_1		0x9c66
2762306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_LPT1_0		0x9ce5
2862306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_LPT1_1		0x9ce6
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistruct pxa_spi_info {
3162306a36Sopenharmony_ci	int (*setup)(struct pci_dev *pdev, struct pxa2xx_spi_controller *c);
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
3562306a36Sopenharmony_cistatic struct dw_dma_slave byt_rx_param = { .src_id = 1 };
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistatic struct dw_dma_slave mrfld3_tx_param = { .dst_id = 15 };
3862306a36Sopenharmony_cistatic struct dw_dma_slave mrfld3_rx_param = { .src_id = 14 };
3962306a36Sopenharmony_cistatic struct dw_dma_slave mrfld5_tx_param = { .dst_id = 13 };
4062306a36Sopenharmony_cistatic struct dw_dma_slave mrfld5_rx_param = { .src_id = 12 };
4162306a36Sopenharmony_cistatic struct dw_dma_slave mrfld6_tx_param = { .dst_id = 11 };
4262306a36Sopenharmony_cistatic struct dw_dma_slave mrfld6_rx_param = { .src_id = 10 };
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 };
4562306a36Sopenharmony_cistatic struct dw_dma_slave bsw0_rx_param = { .src_id = 1 };
4662306a36Sopenharmony_cistatic struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 };
4762306a36Sopenharmony_cistatic struct dw_dma_slave bsw1_rx_param = { .src_id = 7 };
4862306a36Sopenharmony_cistatic struct dw_dma_slave bsw2_tx_param = { .dst_id = 8 };
4962306a36Sopenharmony_cistatic struct dw_dma_slave bsw2_rx_param = { .src_id = 9 };
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic struct dw_dma_slave lpt1_tx_param = { .dst_id = 0 };
5262306a36Sopenharmony_cistatic struct dw_dma_slave lpt1_rx_param = { .src_id = 1 };
5362306a36Sopenharmony_cistatic struct dw_dma_slave lpt0_tx_param = { .dst_id = 2 };
5462306a36Sopenharmony_cistatic struct dw_dma_slave lpt0_rx_param = { .src_id = 3 };
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic void pxa2xx_spi_pci_clk_unregister(void *clk)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	clk_unregister(clk);
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic int pxa2xx_spi_pci_clk_register(struct pci_dev *dev, struct ssp_device *ssp,
6262306a36Sopenharmony_ci				       unsigned long rate)
6362306a36Sopenharmony_ci{
6462306a36Sopenharmony_ci	char buf[40];
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
6762306a36Sopenharmony_ci	ssp->clk = clk_register_fixed_rate(&dev->dev, buf, NULL, 0, rate);
6862306a36Sopenharmony_ci	if (IS_ERR(ssp->clk))
6962306a36Sopenharmony_ci		return PTR_ERR(ssp->clk);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	return devm_add_action_or_reset(&dev->dev, pxa2xx_spi_pci_clk_unregister, ssp->clk);
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic bool lpss_dma_filter(struct dma_chan *chan, void *param)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	struct dw_dma_slave *dws = param;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (dws->dma_dev != chan->device->dev)
7962306a36Sopenharmony_ci		return false;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	chan->private = dws;
8262306a36Sopenharmony_ci	return true;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic void lpss_dma_put_device(void *dma_dev)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	pci_dev_put(dma_dev);
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistatic int lpss_spi_setup(struct pci_dev *dev, struct pxa2xx_spi_controller *c)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	struct ssp_device *ssp = &c->ssp;
9362306a36Sopenharmony_ci	struct dw_dma_slave *tx, *rx;
9462306a36Sopenharmony_ci	struct pci_dev *dma_dev;
9562306a36Sopenharmony_ci	int ret;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	switch (dev->device) {
9862306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_BYT:
9962306a36Sopenharmony_ci		ssp->type = LPSS_BYT_SSP;
10062306a36Sopenharmony_ci		ssp->port_id = 0;
10162306a36Sopenharmony_ci		c->tx_param = &byt_tx_param;
10262306a36Sopenharmony_ci		c->rx_param = &byt_rx_param;
10362306a36Sopenharmony_ci		break;
10462306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_BSW0:
10562306a36Sopenharmony_ci		ssp->type = LPSS_BSW_SSP;
10662306a36Sopenharmony_ci		ssp->port_id = 0;
10762306a36Sopenharmony_ci		c->tx_param = &bsw0_tx_param;
10862306a36Sopenharmony_ci		c->rx_param = &bsw0_rx_param;
10962306a36Sopenharmony_ci		break;
11062306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_BSW1:
11162306a36Sopenharmony_ci		ssp->type = LPSS_BSW_SSP;
11262306a36Sopenharmony_ci		ssp->port_id = 1;
11362306a36Sopenharmony_ci		c->tx_param = &bsw1_tx_param;
11462306a36Sopenharmony_ci		c->rx_param = &bsw1_rx_param;
11562306a36Sopenharmony_ci		break;
11662306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_BSW2:
11762306a36Sopenharmony_ci		ssp->type = LPSS_BSW_SSP;
11862306a36Sopenharmony_ci		ssp->port_id = 2;
11962306a36Sopenharmony_ci		c->tx_param = &bsw2_tx_param;
12062306a36Sopenharmony_ci		c->rx_param = &bsw2_rx_param;
12162306a36Sopenharmony_ci		break;
12262306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_LPT0_0:
12362306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_LPT1_0:
12462306a36Sopenharmony_ci		ssp->type = LPSS_LPT_SSP;
12562306a36Sopenharmony_ci		ssp->port_id = 0;
12662306a36Sopenharmony_ci		c->tx_param = &lpt0_tx_param;
12762306a36Sopenharmony_ci		c->rx_param = &lpt0_rx_param;
12862306a36Sopenharmony_ci		break;
12962306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_LPT0_1:
13062306a36Sopenharmony_ci	case PCI_DEVICE_ID_INTEL_LPT1_1:
13162306a36Sopenharmony_ci		ssp->type = LPSS_LPT_SSP;
13262306a36Sopenharmony_ci		ssp->port_id = 1;
13362306a36Sopenharmony_ci		c->tx_param = &lpt1_tx_param;
13462306a36Sopenharmony_ci		c->rx_param = &lpt1_rx_param;
13562306a36Sopenharmony_ci		break;
13662306a36Sopenharmony_ci	default:
13762306a36Sopenharmony_ci		return -ENODEV;
13862306a36Sopenharmony_ci	}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	c->num_chipselect = 1;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	ret = pxa2xx_spi_pci_clk_register(dev, ssp, 50000000);
14362306a36Sopenharmony_ci	if (ret)
14462306a36Sopenharmony_ci		return ret;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
14762306a36Sopenharmony_ci	ret = devm_add_action_or_reset(&dev->dev, lpss_dma_put_device, dma_dev);
14862306a36Sopenharmony_ci	if (ret)
14962306a36Sopenharmony_ci		return ret;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	tx = c->tx_param;
15262306a36Sopenharmony_ci	tx->dma_dev = &dma_dev->dev;
15362306a36Sopenharmony_ci	tx->m_master = 0;
15462306a36Sopenharmony_ci	tx->p_master = 1;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	rx = c->rx_param;
15762306a36Sopenharmony_ci	rx->dma_dev = &dma_dev->dev;
15862306a36Sopenharmony_ci	rx->m_master = 0;
15962306a36Sopenharmony_ci	rx->p_master = 1;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	c->dma_filter = lpss_dma_filter;
16262306a36Sopenharmony_ci	c->dma_burst_size = 1;
16362306a36Sopenharmony_ci	c->enable_dma = 1;
16462306a36Sopenharmony_ci	return 0;
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic const struct pxa_spi_info lpss_info_config = {
16862306a36Sopenharmony_ci	.setup = lpss_spi_setup,
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistatic int ce4100_spi_setup(struct pci_dev *dev, struct pxa2xx_spi_controller *c)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	struct ssp_device *ssp = &c->ssp;
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	ssp->type = PXA25x_SSP;
17662306a36Sopenharmony_ci	ssp->port_id = dev->devfn;
17762306a36Sopenharmony_ci	c->num_chipselect = dev->devfn;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	return pxa2xx_spi_pci_clk_register(dev, ssp, 3686400);
18062306a36Sopenharmony_ci}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistatic const struct pxa_spi_info ce4100_info_config = {
18362306a36Sopenharmony_ci	.setup = ce4100_spi_setup,
18462306a36Sopenharmony_ci};
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistatic int mrfld_spi_setup(struct pci_dev *dev, struct pxa2xx_spi_controller *c)
18762306a36Sopenharmony_ci{
18862306a36Sopenharmony_ci	struct ssp_device *ssp = &c->ssp;
18962306a36Sopenharmony_ci	struct dw_dma_slave *tx, *rx;
19062306a36Sopenharmony_ci	struct pci_dev *dma_dev;
19162306a36Sopenharmony_ci	int ret;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	ssp->type = MRFLD_SSP;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	switch (PCI_FUNC(dev->devfn)) {
19662306a36Sopenharmony_ci	case 0:
19762306a36Sopenharmony_ci		ssp->port_id = 3;
19862306a36Sopenharmony_ci		c->num_chipselect = 1;
19962306a36Sopenharmony_ci		c->tx_param = &mrfld3_tx_param;
20062306a36Sopenharmony_ci		c->rx_param = &mrfld3_rx_param;
20162306a36Sopenharmony_ci		break;
20262306a36Sopenharmony_ci	case 1:
20362306a36Sopenharmony_ci		ssp->port_id = 5;
20462306a36Sopenharmony_ci		c->num_chipselect = 4;
20562306a36Sopenharmony_ci		c->tx_param = &mrfld5_tx_param;
20662306a36Sopenharmony_ci		c->rx_param = &mrfld5_rx_param;
20762306a36Sopenharmony_ci		break;
20862306a36Sopenharmony_ci	case 2:
20962306a36Sopenharmony_ci		ssp->port_id = 6;
21062306a36Sopenharmony_ci		c->num_chipselect = 1;
21162306a36Sopenharmony_ci		c->tx_param = &mrfld6_tx_param;
21262306a36Sopenharmony_ci		c->rx_param = &mrfld6_rx_param;
21362306a36Sopenharmony_ci		break;
21462306a36Sopenharmony_ci	default:
21562306a36Sopenharmony_ci		return -ENODEV;
21662306a36Sopenharmony_ci	}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	ret = pxa2xx_spi_pci_clk_register(dev, ssp, 25000000);
21962306a36Sopenharmony_ci	if (ret)
22062306a36Sopenharmony_ci		return ret;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0));
22362306a36Sopenharmony_ci	ret = devm_add_action_or_reset(&dev->dev, lpss_dma_put_device, dma_dev);
22462306a36Sopenharmony_ci	if (ret)
22562306a36Sopenharmony_ci		return ret;
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	tx = c->tx_param;
22862306a36Sopenharmony_ci	tx->dma_dev = &dma_dev->dev;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	rx = c->rx_param;
23162306a36Sopenharmony_ci	rx->dma_dev = &dma_dev->dev;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	c->dma_filter = lpss_dma_filter;
23462306a36Sopenharmony_ci	c->dma_burst_size = 8;
23562306a36Sopenharmony_ci	c->enable_dma = 1;
23662306a36Sopenharmony_ci	return 0;
23762306a36Sopenharmony_ci}
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_cistatic const struct pxa_spi_info mrfld_info_config = {
24062306a36Sopenharmony_ci	.setup = mrfld_spi_setup,
24162306a36Sopenharmony_ci};
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic int qrk_spi_setup(struct pci_dev *dev, struct pxa2xx_spi_controller *c)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	struct ssp_device *ssp = &c->ssp;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	ssp->type = QUARK_X1000_SSP;
24862306a36Sopenharmony_ci	ssp->port_id = dev->devfn;
24962306a36Sopenharmony_ci	c->num_chipselect = 1;
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	return pxa2xx_spi_pci_clk_register(dev, ssp, 50000000);
25262306a36Sopenharmony_ci}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic const struct pxa_spi_info qrk_info_config = {
25562306a36Sopenharmony_ci	.setup = qrk_spi_setup,
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_cistatic int pxa2xx_spi_pci_probe(struct pci_dev *dev,
25962306a36Sopenharmony_ci		const struct pci_device_id *ent)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	const struct pxa_spi_info *info;
26262306a36Sopenharmony_ci	struct platform_device_info pi;
26362306a36Sopenharmony_ci	int ret;
26462306a36Sopenharmony_ci	struct platform_device *pdev;
26562306a36Sopenharmony_ci	struct pxa2xx_spi_controller spi_pdata;
26662306a36Sopenharmony_ci	struct ssp_device *ssp;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	ret = pcim_enable_device(dev);
26962306a36Sopenharmony_ci	if (ret)
27062306a36Sopenharmony_ci		return ret;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	ret = pcim_iomap_regions(dev, 1 << 0, "PXA2xx SPI");
27362306a36Sopenharmony_ci	if (ret)
27462306a36Sopenharmony_ci		return ret;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	memset(&spi_pdata, 0, sizeof(spi_pdata));
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	ssp = &spi_pdata.ssp;
27962306a36Sopenharmony_ci	ssp->dev = &dev->dev;
28062306a36Sopenharmony_ci	ssp->phys_base = pci_resource_start(dev, 0);
28162306a36Sopenharmony_ci	ssp->mmio_base = pcim_iomap_table(dev)[0];
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	info = (struct pxa_spi_info *)ent->driver_data;
28462306a36Sopenharmony_ci	ret = info->setup(dev, &spi_pdata);
28562306a36Sopenharmony_ci	if (ret)
28662306a36Sopenharmony_ci		return ret;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	pci_set_master(dev);
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
29162306a36Sopenharmony_ci	if (ret < 0)
29262306a36Sopenharmony_ci		return ret;
29362306a36Sopenharmony_ci	ssp->irq = pci_irq_vector(dev, 0);
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	memset(&pi, 0, sizeof(pi));
29662306a36Sopenharmony_ci	pi.fwnode = dev_fwnode(&dev->dev);
29762306a36Sopenharmony_ci	pi.parent = &dev->dev;
29862306a36Sopenharmony_ci	pi.name = "pxa2xx-spi";
29962306a36Sopenharmony_ci	pi.id = ssp->port_id;
30062306a36Sopenharmony_ci	pi.data = &spi_pdata;
30162306a36Sopenharmony_ci	pi.size_data = sizeof(spi_pdata);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	pdev = platform_device_register_full(&pi);
30462306a36Sopenharmony_ci	if (IS_ERR(pdev))
30562306a36Sopenharmony_ci		return PTR_ERR(pdev);
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	pci_set_drvdata(dev, pdev);
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	return 0;
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_cistatic void pxa2xx_spi_pci_remove(struct pci_dev *dev)
31362306a36Sopenharmony_ci{
31462306a36Sopenharmony_ci	struct platform_device *pdev = pci_get_drvdata(dev);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	platform_device_unregister(pdev);
31762306a36Sopenharmony_ci}
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_cistatic const struct pci_device_id pxa2xx_spi_pci_devices[] = {
32062306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, QUARK_X1000, &qrk_info_config) },
32162306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, BYT, &lpss_info_config) },
32262306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, MRFLD, &mrfld_info_config) },
32362306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, BSW0, &lpss_info_config) },
32462306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, BSW1, &lpss_info_config) },
32562306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, BSW2, &lpss_info_config) },
32662306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, CE4100, &ce4100_info_config) },
32762306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, LPT0_0, &lpss_info_config) },
32862306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, LPT0_1, &lpss_info_config) },
32962306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, LPT1_0, &lpss_info_config) },
33062306a36Sopenharmony_ci	{ PCI_DEVICE_DATA(INTEL, LPT1_1, &lpss_info_config) },
33162306a36Sopenharmony_ci	{ }
33262306a36Sopenharmony_ci};
33362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, pxa2xx_spi_pci_devices);
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_cistatic struct pci_driver pxa2xx_spi_pci_driver = {
33662306a36Sopenharmony_ci	.name           = "pxa2xx_spi_pci",
33762306a36Sopenharmony_ci	.id_table       = pxa2xx_spi_pci_devices,
33862306a36Sopenharmony_ci	.probe          = pxa2xx_spi_pci_probe,
33962306a36Sopenharmony_ci	.remove         = pxa2xx_spi_pci_remove,
34062306a36Sopenharmony_ci};
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cimodule_pci_driver(pxa2xx_spi_pci_driver);
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ciMODULE_DESCRIPTION("CE4100/LPSS PCI-SPI glue code for PXA's driver");
34562306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
34662306a36Sopenharmony_ciMODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
347