aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2011-05-02 15:09:42 -0400
committerChris Metcalf <cmetcalf@tilera.com>2011-05-04 14:39:53 -0400
commit398fa5a9319797e43f67b215337afe62e39475ef (patch)
tree44d966997a6baa6b75a176526d981e3ffb32e471 /arch/tile
parent313ce674d3cbc2d48ed34a9462427920ac54f4ad (diff)
arch/tile: improve support for PCI hotplug
Note that this is not complete hot-plug support; hot-unplug is not included. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/Kconfig8
-rw-r--r--arch/tile/include/asm/pci.h3
-rw-r--r--arch/tile/kernel/pci.c207
3 files changed, 127 insertions, 91 deletions
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index e32b0c23c4c..635e1bfb1c5 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -339,6 +339,14 @@ config NO_IOPORT
339 339
340source "drivers/pci/Kconfig" 340source "drivers/pci/Kconfig"
341 341
342config HOTPLUG
343 bool "Support for hot-pluggable devices"
344 ---help---
345 Say Y here if you want to plug devices into your computer while
346 the system is running, and be able to use them quickly. In many
347 cases, the devices can likewise be unplugged at any time too.
348 One well-known example of this is USB.
349
342source "drivers/pci/hotplug/Kconfig" 350source "drivers/pci/hotplug/Kconfig"
343 351
344endmenu 352endmenu
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index c3fc458a0d3..7f03cefed1b 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -46,7 +46,8 @@ struct pci_controller {
46 */ 46 */
47#define PCI_DMA_BUS_IS_PHYS 1 47#define PCI_DMA_BUS_IS_PHYS 1
48 48
49int __init tile_pci_init(void); 49int __devinit tile_pci_init(void);
50int __devinit pcibios_init(void);
50 51
51void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); 52void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
52static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} 53static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index ea38f0c9ec7..65add0270bb 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -59,6 +59,7 @@ int __write_once tile_plx_gen1;
59 59
60static struct pci_controller controllers[TILE_NUM_PCIE]; 60static struct pci_controller controllers[TILE_NUM_PCIE];
61static int num_controllers; 61static int num_controllers;
62static int pci_scan_flags[TILE_NUM_PCIE];
62 63
63static struct pci_ops tile_cfg_ops; 64static struct pci_ops tile_cfg_ops;
64 65
@@ -79,7 +80,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
79 * controller_id is the controller number, config type is 0 or 1 for 80 * controller_id is the controller number, config type is 0 or 1 for
80 * config0 or config1 operations. 81 * config0 or config1 operations.
81 */ 82 */
82static int __init tile_pcie_open(int controller_id, int config_type) 83static int __devinit tile_pcie_open(int controller_id, int config_type)
83{ 84{
84 char filename[32]; 85 char filename[32];
85 int fd; 86 int fd;
@@ -95,7 +96,7 @@ static int __init tile_pcie_open(int controller_id, int config_type)
95/* 96/*
96 * Get the IRQ numbers from the HV and set up the handlers for them. 97 * Get the IRQ numbers from the HV and set up the handlers for them.
97 */ 98 */
98static int __init tile_init_irqs(int controller_id, 99static int __devinit tile_init_irqs(int controller_id,
99 struct pci_controller *controller) 100 struct pci_controller *controller)
100{ 101{
101 char filename[32]; 102 char filename[32];
@@ -139,71 +140,80 @@ static int __init tile_init_irqs(int controller_id,
139 * 140 *
140 * Returns the number of controllers discovered. 141 * Returns the number of controllers discovered.
141 */ 142 */
142int __init tile_pci_init(void) 143int __devinit tile_pci_init(void)
143{ 144{
144 int i; 145 int i;
145 146
146 pr_info("PCI: Searching for controllers...\n"); 147 pr_info("PCI: Searching for controllers...\n");
147 148
149 /* Re-init number of PCIe controllers to support hot-plug feature. */
150 num_controllers = 0;
151
148 /* Do any configuration we need before using the PCIe */ 152 /* Do any configuration we need before using the PCIe */
149 153
150 for (i = 0; i < TILE_NUM_PCIE; i++) { 154 for (i = 0; i < TILE_NUM_PCIE; i++) {
151 int hv_cfg_fd0 = -1;
152 int hv_cfg_fd1 = -1;
153 int hv_mem_fd = -1;
154 char name[32];
155 struct pci_controller *controller;
156
157 /* 155 /*
158 * Open the fd to the HV. If it fails then this 156 * To see whether we need a real config op based on
159 * device doesn't exist. 157 * the results of pcibios_init(), to support PCIe hot-plug.
160 */ 158 */
161 hv_cfg_fd0 = tile_pcie_open(i, 0); 159 if (pci_scan_flags[i] == 0) {
162 if (hv_cfg_fd0 < 0) 160 int hv_cfg_fd0 = -1;
163 continue; 161 int hv_cfg_fd1 = -1;
164 hv_cfg_fd1 = tile_pcie_open(i, 1); 162 int hv_mem_fd = -1;
165 if (hv_cfg_fd1 < 0) { 163 char name[32];
166 pr_err("PCI: Couldn't open config fd to HV " 164 struct pci_controller *controller;
167 "for controller %d\n", i); 165
168 goto err_cont; 166 /*
169 } 167 * Open the fd to the HV. If it fails then this
168 * device doesn't exist.
169 */
170 hv_cfg_fd0 = tile_pcie_open(i, 0);
171 if (hv_cfg_fd0 < 0)
172 continue;
173 hv_cfg_fd1 = tile_pcie_open(i, 1);
174 if (hv_cfg_fd1 < 0) {
175 pr_err("PCI: Couldn't open config fd to HV "
176 "for controller %d\n", i);
177 goto err_cont;
178 }
170 179
171 sprintf(name, "pcie/%d/mem", i); 180 sprintf(name, "pcie/%d/mem", i);
172 hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0); 181 hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
173 if (hv_mem_fd < 0) { 182 if (hv_mem_fd < 0) {
174 pr_err("PCI: Could not open mem fd to HV!\n"); 183 pr_err("PCI: Could not open mem fd to HV!\n");
175 goto err_cont; 184 goto err_cont;
176 } 185 }
177 186
178 pr_info("PCI: Found PCI controller #%d\n", i); 187 pr_info("PCI: Found PCI controller #%d\n", i);
179 188
180 controller = &controllers[num_controllers]; 189 controller = &controllers[i];
181 190
182 if (tile_init_irqs(i, controller)) { 191 if (tile_init_irqs(i, controller)) {
183 pr_err("PCI: Could not initialize " 192 pr_err("PCI: Could not initialize "
184 "IRQs, aborting.\n"); 193 "IRQs, aborting.\n");
185 goto err_cont; 194 goto err_cont;
186 } 195 }
187 196
188 controller->index = num_controllers; 197 controller->index = i;
189 controller->hv_cfg_fd[0] = hv_cfg_fd0; 198 controller->hv_cfg_fd[0] = hv_cfg_fd0;
190 controller->hv_cfg_fd[1] = hv_cfg_fd1; 199 controller->hv_cfg_fd[1] = hv_cfg_fd1;
191 controller->hv_mem_fd = hv_mem_fd; 200 controller->hv_mem_fd = hv_mem_fd;
192 controller->first_busno = 0; 201 controller->first_busno = 0;
193 controller->last_busno = 0xff; 202 controller->last_busno = 0xff;
194 controller->ops = &tile_cfg_ops; 203 controller->ops = &tile_cfg_ops;
195 204
196 num_controllers++; 205 num_controllers++;
197 continue; 206 continue;
198 207
199err_cont: 208err_cont:
200 if (hv_cfg_fd0 >= 0) 209 if (hv_cfg_fd0 >= 0)
201 hv_dev_close(hv_cfg_fd0); 210 hv_dev_close(hv_cfg_fd0);
202 if (hv_cfg_fd1 >= 0) 211 if (hv_cfg_fd1 >= 0)
203 hv_dev_close(hv_cfg_fd1); 212 hv_dev_close(hv_cfg_fd1);
204 if (hv_mem_fd >= 0) 213 if (hv_mem_fd >= 0)
205 hv_dev_close(hv_mem_fd); 214 hv_dev_close(hv_mem_fd);
206 continue; 215 continue;
216 }
207 } 217 }
208 218
209 /* 219 /*
@@ -232,7 +242,7 @@ static int tile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
232} 242}
233 243
234 244
235static void __init fixup_read_and_payload_sizes(void) 245static void __devinit fixup_read_and_payload_sizes(void)
236{ 246{
237 struct pci_dev *dev = NULL; 247 struct pci_dev *dev = NULL;
238 int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */ 248 int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */
@@ -282,7 +292,7 @@ static void __init fixup_read_and_payload_sizes(void)
282 * The controllers have been set up by the time we get here, by a call to 292 * The controllers have been set up by the time we get here, by a call to
283 * tile_pci_init. 293 * tile_pci_init.
284 */ 294 */
285static int __init pcibios_init(void) 295int __devinit pcibios_init(void)
286{ 296{
287 int i; 297 int i;
288 298
@@ -296,25 +306,31 @@ static int __init pcibios_init(void)
296 mdelay(250); 306 mdelay(250);
297 307
298 /* Scan all of the recorded PCI controllers. */ 308 /* Scan all of the recorded PCI controllers. */
299 for (i = 0; i < num_controllers; i++) { 309 for (i = 0; i < TILE_NUM_PCIE; i++) {
300 struct pci_controller *controller = &controllers[i];
301 struct pci_bus *bus;
302
303 pr_info("PCI: initializing controller #%d\n", i);
304
305 /* 310 /*
306 * This comes from the generic Linux PCI driver. 311 * Do real pcibios init ops if the controller is initialized
307 * 312 * by tile_pci_init() successfully and not initialized by
308 * It reads the PCI tree for this bus into the Linux 313 * pcibios_init() yet to support PCIe hot-plug.
309 * data structures.
310 *
311 * This is inlined in linux/pci.h and calls into
312 * pci_scan_bus_parented() in probe.c.
313 */ 314 */
314 bus = pci_scan_bus(0, controller->ops, controller); 315 if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
315 controller->root_bus = bus; 316 struct pci_controller *controller = &controllers[i];
316 controller->last_busno = bus->subordinate; 317 struct pci_bus *bus;
317 318
319 pr_info("PCI: initializing controller #%d\n", i);
320
321 /*
322 * This comes from the generic Linux PCI driver.
323 *
324 * It reads the PCI tree for this bus into the Linux
325 * data structures.
326 *
327 * This is inlined in linux/pci.h and calls into
328 * pci_scan_bus_parented() in probe.c.
329 */
330 bus = pci_scan_bus(0, controller->ops, controller);
331 controller->root_bus = bus;
332 controller->last_busno = bus->subordinate;
333 }
318 } 334 }
319 335
320 /* Do machine dependent PCI interrupt routing */ 336 /* Do machine dependent PCI interrupt routing */
@@ -326,34 +342,45 @@ static int __init pcibios_init(void)
326 * It allocates all of the resources (I/O memory, etc) 342 * It allocates all of the resources (I/O memory, etc)
327 * associated with the devices read in above. 343 * associated with the devices read in above.
328 */ 344 */
329
330 pci_assign_unassigned_resources(); 345 pci_assign_unassigned_resources();
331 346
332 /* Configure the max_read_size and max_payload_size values. */ 347 /* Configure the max_read_size and max_payload_size values. */
333 fixup_read_and_payload_sizes(); 348 fixup_read_and_payload_sizes();
334 349
335 /* Record the I/O resources in the PCI controller structure. */ 350 /* Record the I/O resources in the PCI controller structure. */
336 for (i = 0; i < num_controllers; i++) { 351 for (i = 0; i < TILE_NUM_PCIE; i++) {
337 struct pci_bus *root_bus = controllers[i].root_bus; 352 /*
338 struct pci_bus *next_bus; 353 * Do real pcibios init ops if the controller is initialized
339 struct pci_dev *dev; 354 * by tile_pci_init() successfully and not initialized by
340 355 * pcibios_init() yet to support PCIe hot-plug.
341 list_for_each_entry(dev, &root_bus->devices, bus_list) { 356 */
342 /* Find the PCI host controller, ie. the 1st bridge. */ 357 if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
343 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && 358 struct pci_bus *root_bus = controllers[i].root_bus;
344 (PCI_SLOT(dev->devfn) == 0)) { 359 struct pci_bus *next_bus;
345 next_bus = dev->subordinate; 360 struct pci_dev *dev;
346 controllers[i].mem_resources[0] = 361
347 *next_bus->resource[0]; 362 list_for_each_entry(dev, &root_bus->devices, bus_list) {
348 controllers[i].mem_resources[1] = 363 /*
349 *next_bus->resource[1]; 364 * Find the PCI host controller, ie. the 1st
350 controllers[i].mem_resources[2] = 365 * bridge.
351 *next_bus->resource[2]; 366 */
352 367 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
353 break; 368 (PCI_SLOT(dev->devfn) == 0)) {
369 next_bus = dev->subordinate;
370 controllers[i].mem_resources[0] =
371 *next_bus->resource[0];
372 controllers[i].mem_resources[1] =
373 *next_bus->resource[1];
374 controllers[i].mem_resources[2] =
375 *next_bus->resource[2];
376
377 /* Setup flags. */
378 pci_scan_flags[i] = 1;
379
380 break;
381 }
354 } 382 }
355 } 383 }
356
357 } 384 }
358 385
359 return 0; 386 return 0;
@@ -381,7 +408,7 @@ char __devinit *pcibios_setup(char *str)
381/* 408/*
382 * This is called from the generic Linux layer. 409 * This is called from the generic Linux layer.
383 */ 410 */
384void __init pcibios_update_irq(struct pci_dev *dev, int irq) 411void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
385{ 412{
386 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 413 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
387} 414}