Blame view

drivers/spi/spi-dw-pci.c 3.48 KB
2025cf9e1   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
e24c74527   Feng Tang   spi: controller d...
2
  /*
ca632f556   Grant Likely   spi: reorganize d...
3
   * PCI interface driver for DW SPI Core
e24c74527   Feng Tang   spi: controller d...
4
   *
5dc23c442   Andy Shevchenko   spi: dw-pci: remo...
5
   * Copyright (c) 2009, 2014 Intel Corporation.
e24c74527   Feng Tang   spi: controller d...
6
7
8
9
   */
  
  #include <linux/interrupt.h>
  #include <linux/pci.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
10
  #include <linux/slab.h>
e24c74527   Feng Tang   spi: controller d...
11
  #include <linux/spi/spi.h>
d7614de42   Paul Gortmaker   spi: Add module.h...
12
  #include <linux/module.h>
e24c74527   Feng Tang   spi: controller d...
13

ca632f556   Grant Likely   spi: reorganize d...
14
  #include "spi-dw.h"
568a60eda   Grant Likely   spi/dw_spi: move ...
15

e24c74527   Feng Tang   spi: controller d...
16
  #define DRIVER_NAME "dw_spi_pci"
c95791b6a   Andy Shevchenko   spi: dw-pci: prov...
17
18
  struct spi_pci_desc {
  	int	(*setup)(struct dw_spi *);
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
19
20
  	u16	num_cs;
  	u16	bus_num;
52718908c   Jarkko Nikula   spi: dw-pci: Add ...
21
  	u32	max_freq;
c95791b6a   Andy Shevchenko   spi: dw-pci: prov...
22
  };
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
23
  static struct spi_pci_desc spi_pci_mid_desc_1 = {
c95791b6a   Andy Shevchenko   spi: dw-pci: prov...
24
  	.setup = dw_spi_mid_init,
307ed83c8   Andy Shevchenko   spi: dw-pci: corr...
25
  	.num_cs = 5,
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
26
27
28
29
30
  	.bus_num = 0,
  };
  
  static struct spi_pci_desc spi_pci_mid_desc_2 = {
  	.setup = dw_spi_mid_init,
307ed83c8   Andy Shevchenko   spi: dw-pci: corr...
31
  	.num_cs = 2,
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
32
  	.bus_num = 1,
c95791b6a   Andy Shevchenko   spi: dw-pci: prov...
33
  };
52718908c   Jarkko Nikula   spi: dw-pci: Add ...
34
35
36
37
38
  static struct spi_pci_desc spi_pci_ehl_desc = {
  	.num_cs = 1,
  	.bus_num = -1,
  	.max_freq = 100000000,
  };
c95791b6a   Andy Shevchenko   spi: dw-pci: prov...
39
  static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
e24c74527   Feng Tang   spi: controller d...
40
  {
e24c74527   Feng Tang   spi: controller d...
41
  	struct dw_spi *dws;
c95791b6a   Andy Shevchenko   spi: dw-pci: prov...
42
  	struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data;
e24c74527   Feng Tang   spi: controller d...
43
44
  	int pci_bar = 0;
  	int ret;
04f421e7b   Baruch Siach   spi: dw: use mana...
45
  	ret = pcim_enable_device(pdev);
e24c74527   Feng Tang   spi: controller d...
46
47
  	if (ret)
  		return ret;
1c2df9653   Andy Shevchenko   spi: dw-pci: remo...
48
49
  	dws = devm_kzalloc(&pdev->dev, sizeof(*dws), GFP_KERNEL);
  	if (!dws)
04f421e7b   Baruch Siach   spi: dw: use mana...
50
  		return -ENOMEM;
e24c74527   Feng Tang   spi: controller d...
51

e24c74527   Feng Tang   spi: controller d...
52
53
  	/* Get basic io resource and map it */
  	dws->paddr = pci_resource_start(pdev, pci_bar);
e24c74527   Feng Tang   spi: controller d...
54

ceb86de9d   Andy Shevchenko   spi: dw-pci: appl...
55
  	ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev));
e24c74527   Feng Tang   spi: controller d...
56
  	if (ret)
04f421e7b   Baruch Siach   spi: dw: use mana...
57
  		return ret;
e24c74527   Feng Tang   spi: controller d...
58

c9d5d6fe1   Andy Shevchenko   spi: dw-pci: fix ...
59
  	dws->regs = pcim_iomap_table(pdev)[pci_bar];
e24c74527   Feng Tang   spi: controller d...
60
  	dws->irq = pdev->irq;
7063c0d94   Feng Tang   spi/dw_spi: add D...
61
62
  
  	/*
3208a1ccb   Geert Uytterhoeven   spi: dw-pci: Spel...
63
  	 * Specific handling for platforms, like dma setup,
7063c0d94   Feng Tang   spi/dw_spi: add D...
64
65
  	 * clock rate, FIFO depth.
  	 */
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
66
  	if (desc) {
d9c14743a   Andy Shevchenko   spi: dw-mid: get ...
67
68
  		dws->num_cs = desc->num_cs;
  		dws->bus_num = desc->bus_num;
52718908c   Jarkko Nikula   spi: dw-pci: Add ...
69
  		dws->max_freq = desc->max_freq;
d9c14743a   Andy Shevchenko   spi: dw-mid: get ...
70

d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
71
72
73
74
75
  		if (desc->setup) {
  			ret = desc->setup(dws);
  			if (ret)
  				return ret;
  		}
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
76
77
  	} else {
  		return -ENODEV;
7063c0d94   Feng Tang   spi/dw_spi: add D...
78
  	}
e24c74527   Feng Tang   spi: controller d...
79

04f421e7b   Baruch Siach   spi: dw: use mana...
80
  	ret = dw_spi_add_host(&pdev->dev, dws);
e24c74527   Feng Tang   spi: controller d...
81
  	if (ret)
04f421e7b   Baruch Siach   spi: dw: use mana...
82
  		return ret;
e24c74527   Feng Tang   spi: controller d...
83
84
  
  	/* PCI hook and SPI hook use the same drv data */
1c2df9653   Andy Shevchenko   spi: dw-pci: remo...
85
  	pci_set_drvdata(pdev, dws);
e24c74527   Feng Tang   spi: controller d...
86

fcf0af445   Andy Shevchenko   spi: dw-pci: move...
87
88
89
  	dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)
  ",
  		pdev->vendor, pdev->device);
04f421e7b   Baruch Siach   spi: dw: use mana...
90
  	return 0;
e24c74527   Feng Tang   spi: controller d...
91
  }
fd4a319bc   Grant Likely   spi: Remove HOTPL...
92
  static void spi_pci_remove(struct pci_dev *pdev)
e24c74527   Feng Tang   spi: controller d...
93
  {
1c2df9653   Andy Shevchenko   spi: dw-pci: remo...
94
  	struct dw_spi *dws = pci_get_drvdata(pdev);
e24c74527   Feng Tang   spi: controller d...
95

1c2df9653   Andy Shevchenko   spi: dw-pci: remo...
96
  	dw_spi_remove_host(dws);
e24c74527   Feng Tang   spi: controller d...
97
  }
35f2d4136   Andy Shevchenko   spi: dw-pci: conv...
98
99
  #ifdef CONFIG_PM_SLEEP
  static int spi_suspend(struct device *dev)
e24c74527   Feng Tang   spi: controller d...
100
  {
2a3b6f7b0   Chuhong Yuan   spi: dw-pci: Use ...
101
  	struct dw_spi *dws = dev_get_drvdata(dev);
e24c74527   Feng Tang   spi: controller d...
102

1c2df9653   Andy Shevchenko   spi: dw-pci: remo...
103
  	return dw_spi_suspend_host(dws);
e24c74527   Feng Tang   spi: controller d...
104
  }
35f2d4136   Andy Shevchenko   spi: dw-pci: conv...
105
  static int spi_resume(struct device *dev)
e24c74527   Feng Tang   spi: controller d...
106
  {
2a3b6f7b0   Chuhong Yuan   spi: dw-pci: Use ...
107
  	struct dw_spi *dws = dev_get_drvdata(dev);
e24c74527   Feng Tang   spi: controller d...
108

1c2df9653   Andy Shevchenko   spi: dw-pci: remo...
109
  	return dw_spi_resume_host(dws);
e24c74527   Feng Tang   spi: controller d...
110
  }
e24c74527   Feng Tang   spi: controller d...
111
  #endif
35f2d4136   Andy Shevchenko   spi: dw-pci: conv...
112
  static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume);
9a21e4770   Jingoo Han   spi: remove DEFIN...
113
  static const struct pci_device_id pci_ids[] = {
7063c0d94   Feng Tang   spi/dw_spi: add D...
114
  	/* Intel MID platform SPI controller 0 */
d58cf5ff6   Andy Shevchenko   spi: dw-pci: desc...
115
116
117
118
119
120
121
122
  	/*
  	 * The access to the device 8086:0801 is disabled by HW, since it's
  	 * exclusively used by SCU to communicate with MSIC.
  	 */
  	/* Intel MID platform SPI controller 1 */
  	{ PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc_1},
  	/* Intel MID platform SPI controller 2 */
  	{ PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&spi_pci_mid_desc_2},
52718908c   Jarkko Nikula   spi: dw-pci: Add ...
123
124
125
126
127
  	/* Intel Elkhart Lake PSE SPI controllers */
  	{ PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&spi_pci_ehl_desc},
  	{ PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&spi_pci_ehl_desc},
  	{ PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&spi_pci_ehl_desc},
  	{ PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&spi_pci_ehl_desc},
e24c74527   Feng Tang   spi: controller d...
128
129
  	{},
  };
94e9c0f52   Jarkko Nikula   spi: dw-pci: Add ...
130
  MODULE_DEVICE_TABLE(pci, pci_ids);
e24c74527   Feng Tang   spi: controller d...
131
132
133
134
135
  
  static struct pci_driver dw_spi_driver = {
  	.name =		DRIVER_NAME,
  	.id_table =	pci_ids,
  	.probe =	spi_pci_probe,
fd4a319bc   Grant Likely   spi: Remove HOTPL...
136
  	.remove =	spi_pci_remove,
35f2d4136   Andy Shevchenko   spi: dw-pci: conv...
137
138
139
  	.driver         = {
  		.pm     = &dw_spi_pm_ops,
  	},
e24c74527   Feng Tang   spi: controller d...
140
  };
8ebb35fd7   Axel Lin   spi: use module_p...
141
  module_pci_driver(dw_spi_driver);
e24c74527   Feng Tang   spi: controller d...
142
143
144
145
  
  MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
  MODULE_DESCRIPTION("PCI interface driver for DW SPI Core");
  MODULE_LICENSE("GPL v2");