blob: 41daa0d6eba4fa1f0a5a72cb359f57bb862b10f9 [file] [log] [blame]
Simon Glassff3e0772015-03-05 12:25:25 -07001/*
2 * Copyright (c) 2014 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <errno.h>
11#include <fdtdec.h>
12#include <inttypes.h>
13#include <pci.h>
14#include <dm/lists.h>
15#include <dm/root.h>
16#include <dm/device-internal.h>
17
18DECLARE_GLOBAL_DATA_PTR;
19
20struct pci_controller *pci_bus_to_hose(int busnum)
21{
22 struct udevice *bus;
23 int ret;
24
25 ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
26 if (ret) {
27 debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret);
28 return NULL;
29 }
30 return dev_get_uclass_priv(bus);
31}
32
33/**
34 * pci_get_bus_max() - returns the bus number of the last active bus
35 *
36 * @return last bus number, or -1 if no active buses
37 */
38static int pci_get_bus_max(void)
39{
40 struct udevice *bus;
41 struct uclass *uc;
42 int ret = -1;
43
44 ret = uclass_get(UCLASS_PCI, &uc);
45 uclass_foreach_dev(bus, uc) {
46 if (bus->seq > ret)
47 ret = bus->seq;
48 }
49
50 debug("%s: ret=%d\n", __func__, ret);
51
52 return ret;
53}
54
55int pci_last_busno(void)
56{
57 struct pci_controller *hose;
58 struct udevice *bus;
59 struct uclass *uc;
60 int ret;
61
62 debug("pci_last_busno\n");
63 ret = uclass_get(UCLASS_PCI, &uc);
64 if (ret || list_empty(&uc->dev_head))
65 return -1;
66
67 /* Probe the last bus */
68 bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
69 debug("bus = %p, %s\n", bus, bus->name);
70 assert(bus);
71 ret = device_probe(bus);
72 if (ret)
73 return ret;
74
75 /* If that bus has bridges, we may have new buses now. Get the last */
76 bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
77 hose = dev_get_uclass_priv(bus);
78 debug("bus = %s, hose = %p\n", bus->name, hose);
79
80 return hose->last_busno;
81}
82
83int pci_get_ff(enum pci_size_t size)
84{
85 switch (size) {
86 case PCI_SIZE_8:
87 return 0xff;
88 case PCI_SIZE_16:
89 return 0xffff;
90 default:
91 return 0xffffffff;
92 }
93}
94
95int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
96 struct udevice **devp)
97{
98 struct udevice *dev;
99
100 for (device_find_first_child(bus, &dev);
101 dev;
102 device_find_next_child(&dev)) {
103 struct pci_child_platdata *pplat;
104
105 pplat = dev_get_parent_platdata(dev);
106 if (pplat && pplat->devfn == find_devfn) {
107 *devp = dev;
108 return 0;
109 }
110 }
111
112 return -ENODEV;
113}
114
115int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
116{
117 struct udevice *bus;
118 int ret;
119
120 ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
121 if (ret)
122 return ret;
123 return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
124}
125
126static int pci_device_matches_ids(struct udevice *dev,
127 struct pci_device_id *ids)
128{
129 struct pci_child_platdata *pplat;
130 int i;
131
132 pplat = dev_get_parent_platdata(dev);
133 if (!pplat)
134 return -EINVAL;
135 for (i = 0; ids[i].vendor != 0; i++) {
136 if (pplat->vendor == ids[i].vendor &&
137 pplat->device == ids[i].device)
138 return i;
139 }
140
141 return -EINVAL;
142}
143
144int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
145 int *indexp, struct udevice **devp)
146{
147 struct udevice *dev;
148
149 /* Scan all devices on this bus */
150 for (device_find_first_child(bus, &dev);
151 dev;
152 device_find_next_child(&dev)) {
153 if (pci_device_matches_ids(dev, ids) >= 0) {
154 if ((*indexp)-- <= 0) {
155 *devp = dev;
156 return 0;
157 }
158 }
159 }
160
161 return -ENODEV;
162}
163
164int pci_find_device_id(struct pci_device_id *ids, int index,
165 struct udevice **devp)
166{
167 struct udevice *bus;
168
169 /* Scan all known buses */
170 for (uclass_first_device(UCLASS_PCI, &bus);
171 bus;
172 uclass_next_device(&bus)) {
173 if (!pci_bus_find_devices(bus, ids, &index, devp))
174 return 0;
175 }
176 *devp = NULL;
177
178 return -ENODEV;
179}
180
181int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
182 unsigned long value, enum pci_size_t size)
183{
184 struct dm_pci_ops *ops;
185
186 ops = pci_get_ops(bus);
187 if (!ops->write_config)
188 return -ENOSYS;
189 return ops->write_config(bus, bdf, offset, value, size);
190}
191
192int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
193 enum pci_size_t size)
194{
195 struct udevice *bus;
196 int ret;
197
198 ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
199 if (ret)
200 return ret;
201
202 return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value,
203 size);
204}
205
206int pci_write_config32(pci_dev_t bdf, int offset, u32 value)
207{
208 return pci_write_config(bdf, offset, value, PCI_SIZE_32);
209}
210
211int pci_write_config16(pci_dev_t bdf, int offset, u16 value)
212{
213 return pci_write_config(bdf, offset, value, PCI_SIZE_16);
214}
215
216int pci_write_config8(pci_dev_t bdf, int offset, u8 value)
217{
218 return pci_write_config(bdf, offset, value, PCI_SIZE_8);
219}
220
221int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
222 unsigned long *valuep, enum pci_size_t size)
223{
224 struct dm_pci_ops *ops;
225
226 ops = pci_get_ops(bus);
227 if (!ops->read_config)
228 return -ENOSYS;
229 return ops->read_config(bus, bdf, offset, valuep, size);
230}
231
232int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
233 enum pci_size_t size)
234{
235 struct udevice *bus;
236 int ret;
237
238 ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
239 if (ret)
240 return ret;
241
242 return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep,
243 size);
244}
245
246int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
247{
248 unsigned long value;
249 int ret;
250
251 ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32);
252 if (ret)
253 return ret;
254 *valuep = value;
255
256 return 0;
257}
258
259int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep)
260{
261 unsigned long value;
262 int ret;
263
264 ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16);
265 if (ret)
266 return ret;
267 *valuep = value;
268
269 return 0;
270}
271
272int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep)
273{
274 unsigned long value;
275 int ret;
276
277 ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8);
278 if (ret)
279 return ret;
280 *valuep = value;
281
282 return 0;
283}
284
285int pci_auto_config_devices(struct udevice *bus)
286{
287 struct pci_controller *hose = bus->uclass_priv;
288 unsigned int sub_bus;
289 struct udevice *dev;
290 int ret;
291
292 sub_bus = bus->seq;
293 debug("%s: start\n", __func__);
294 pciauto_config_init(hose);
295 for (ret = device_find_first_child(bus, &dev);
296 !ret && dev;
297 ret = device_find_next_child(&dev)) {
298 struct pci_child_platdata *pplat;
Simon Glassaec241d2015-06-07 08:50:40 -0600299 struct pci_controller *ctlr_hose;
Simon Glassff3e0772015-03-05 12:25:25 -0700300
301 pplat = dev_get_parent_platdata(dev);
302 unsigned int max_bus;
303 pci_dev_t bdf;
304
305 bdf = PCI_ADD_BUS(bus->seq, pplat->devfn);
306 debug("%s: device %s\n", __func__, dev->name);
Simon Glassaec241d2015-06-07 08:50:40 -0600307
308 /* The root controller has the region information */
309 ctlr_hose = hose->ctlr->uclass_priv;
310 max_bus = pciauto_config_device(ctlr_hose, bdf);
Simon Glassff3e0772015-03-05 12:25:25 -0700311 sub_bus = max(sub_bus, max_bus);
312 }
313 debug("%s: done\n", __func__);
314
315 return sub_bus;
316}
317
318int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
319{
320 struct udevice *parent, *bus;
321 int sub_bus;
322 int ret;
323
324 debug("%s\n", __func__);
325 parent = hose->bus;
326
327 /* Find the bus within the parent */
328 ret = pci_bus_find_devfn(parent, bdf, &bus);
329 if (ret) {
330 debug("%s: Cannot find device %x on bus %s: %d\n", __func__,
331 bdf, parent->name, ret);
332 return ret;
333 }
334
335 sub_bus = pci_get_bus_max() + 1;
336 debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
Simon Glass5afeb4b2015-06-07 08:50:41 -0600337 pciauto_prescan_setup_bridge(hose, bdf, sub_bus);
Simon Glassff3e0772015-03-05 12:25:25 -0700338
339 ret = device_probe(bus);
340 if (ret) {
341 debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name,
342 ret);
343 return ret;
344 }
345 if (sub_bus != bus->seq) {
346 printf("%s: Internal error, bus '%s' got seq %d, expected %d\n",
347 __func__, bus->name, bus->seq, sub_bus);
348 return -EPIPE;
349 }
350 sub_bus = pci_get_bus_max();
351 pciauto_postscan_setup_bridge(hose, bdf, sub_bus);
352
353 return sub_bus;
354}
355
Simon Glassaba92962015-07-06 16:47:44 -0600356/**
357 * pci_match_one_device - Tell if a PCI device structure has a matching
358 * PCI device id structure
359 * @id: single PCI device id structure to match
360 * @dev: the PCI device structure to match against
361 *
362 * Returns the matching pci_device_id structure or %NULL if there is no match.
363 */
364static bool pci_match_one_id(const struct pci_device_id *id,
365 const struct pci_device_id *find)
366{
367 if ((id->vendor == PCI_ANY_ID || id->vendor == find->vendor) &&
368 (id->device == PCI_ANY_ID || id->device == find->device) &&
369 (id->subvendor == PCI_ANY_ID || id->subvendor == find->subvendor) &&
370 (id->subdevice == PCI_ANY_ID || id->subdevice == find->subdevice) &&
371 !((id->class ^ find->class) & id->class_mask))
372 return true;
373
374 return false;
375}
376
377/**
378 * pci_find_and_bind_driver() - Find and bind the right PCI driver
379 *
380 * This only looks at certain fields in the descriptor.
381 */
382static int pci_find_and_bind_driver(struct udevice *parent,
383 struct pci_device_id *find_id, int devfn,
384 struct udevice **devp)
385{
386 struct pci_driver_entry *start, *entry;
387 const char *drv;
388 int n_ents;
389 int ret;
390 char name[30], *str;
391
392 *devp = NULL;
393
394 debug("%s: Searching for driver: vendor=%x, device=%x\n", __func__,
395 find_id->vendor, find_id->device);
396 start = ll_entry_start(struct pci_driver_entry, pci_driver_entry);
397 n_ents = ll_entry_count(struct pci_driver_entry, pci_driver_entry);
398 for (entry = start; entry != start + n_ents; entry++) {
399 const struct pci_device_id *id;
400 struct udevice *dev;
401 const struct driver *drv;
402
403 for (id = entry->match;
404 id->vendor || id->subvendor || id->class_mask;
405 id++) {
406 if (!pci_match_one_id(id, find_id))
407 continue;
408
409 drv = entry->driver;
410 /*
411 * We could pass the descriptor to the driver as
412 * platdata (instead of NULL) and allow its bind()
413 * method to return -ENOENT if it doesn't support this
414 * device. That way we could continue the search to
415 * find another driver. For now this doesn't seem
416 * necesssary, so just bind the first match.
417 */
418 ret = device_bind(parent, drv, drv->name, NULL, -1,
419 &dev);
420 if (ret)
421 goto error;
422 debug("%s: Match found: %s\n", __func__, drv->name);
423 dev->driver_data = find_id->driver_data;
424 *devp = dev;
425 return 0;
426 }
427 }
428
429 /* Bind a generic driver so that the device can be used */
430 sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(devfn),
431 PCI_FUNC(devfn));
432 str = strdup(name);
433 if (!str)
434 return -ENOMEM;
435 drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" :
436 "pci_generic_drv";
437 ret = device_bind_driver(parent, drv, str, devp);
438 if (ret) {
439 debug("%s: Failed to bind generic driver: %d", __func__, ret);
440 return ret;
441 }
442 debug("%s: No match found: bound generic driver instead\n", __func__);
443
444 return 0;
445
446error:
447 debug("%s: No match found: error %d\n", __func__, ret);
448 return ret;
449}
450
Simon Glassff3e0772015-03-05 12:25:25 -0700451int pci_bind_bus_devices(struct udevice *bus)
452{
453 ulong vendor, device;
454 ulong header_type;
455 pci_dev_t devfn, end;
456 bool found_multi;
457 int ret;
458
459 found_multi = false;
460 end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1);
461 for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) {
462 struct pci_child_platdata *pplat;
463 struct udevice *dev;
464 ulong class;
465
466 if (PCI_FUNC(devfn) && !found_multi)
467 continue;
468 /* Check only the first access, we don't expect problems */
469 ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE,
470 &header_type, PCI_SIZE_8);
471 if (ret)
472 goto error;
473 pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor,
474 PCI_SIZE_16);
475 if (vendor == 0xffff || vendor == 0x0000)
476 continue;
477
478 if (!PCI_FUNC(devfn))
479 found_multi = header_type & 0x80;
480
481 debug("%s: bus %d/%s: found device %x, function %d\n", __func__,
482 bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn));
483 pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device,
484 PCI_SIZE_16);
Simon Glassaba92962015-07-06 16:47:44 -0600485 pci_bus_read_config(bus, devfn, PCI_CLASS_REVISION, &class,
486 PCI_SIZE_32);
487 class >>= 8;
Simon Glassff3e0772015-03-05 12:25:25 -0700488
489 /* Find this device in the device tree */
490 ret = pci_bus_find_devfn(bus, devfn, &dev);
491
Simon Glassaba92962015-07-06 16:47:44 -0600492 /* Search for a driver */
493
Simon Glassff3e0772015-03-05 12:25:25 -0700494 /* If nothing in the device tree, bind a generic device */
495 if (ret == -ENODEV) {
Simon Glassaba92962015-07-06 16:47:44 -0600496 struct pci_device_id find_id;
497 ulong val;
Simon Glassff3e0772015-03-05 12:25:25 -0700498
Simon Glassaba92962015-07-06 16:47:44 -0600499 memset(&find_id, '\0', sizeof(find_id));
500 find_id.vendor = vendor;
501 find_id.device = device;
502 find_id.class = class;
503 if ((header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) {
504 pci_bus_read_config(bus, devfn,
505 PCI_SUBSYSTEM_VENDOR_ID,
506 &val, PCI_SIZE_32);
507 find_id.subvendor = val & 0xffff;
508 find_id.subdevice = val >> 16;
509 }
510 ret = pci_find_and_bind_driver(bus, &find_id, devfn,
511 &dev);
Simon Glassff3e0772015-03-05 12:25:25 -0700512 }
513 if (ret)
514 return ret;
515
516 /* Update the platform data */
517 pplat = dev_get_parent_platdata(dev);
518 pplat->devfn = devfn;
519 pplat->vendor = vendor;
520 pplat->device = device;
521 pplat->class = class;
522 }
523
524 return 0;
525error:
526 printf("Cannot read bus configuration: %d\n", ret);
527
528 return ret;
529}
530
531static int pci_uclass_post_bind(struct udevice *bus)
532{
533 /*
534 * Scan the device tree for devices. This does not probe the PCI bus,
535 * as this is not permitted while binding. It just finds devices
536 * mentioned in the device tree.
537 *
538 * Before relocation, only bind devices marked for pre-relocation
539 * use.
540 */
541 return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset,
542 gd->flags & GD_FLG_RELOC ? false : true);
543}
544
545static int decode_regions(struct pci_controller *hose, const void *blob,
546 int parent_node, int node)
547{
548 int pci_addr_cells, addr_cells, size_cells;
549 int cells_per_record;
Simon Glassb9da5082015-07-03 18:28:27 -0600550 phys_addr_t addr;
Simon Glassff3e0772015-03-05 12:25:25 -0700551 const u32 *prop;
552 int len;
553 int i;
554
555 prop = fdt_getprop(blob, node, "ranges", &len);
556 if (!prop)
557 return -EINVAL;
558 pci_addr_cells = fdt_address_cells(blob, node);
559 addr_cells = fdt_address_cells(blob, parent_node);
560 size_cells = fdt_size_cells(blob, node);
561
562 /* PCI addresses are always 3-cells */
563 len /= sizeof(u32);
564 cells_per_record = pci_addr_cells + addr_cells + size_cells;
565 hose->region_count = 0;
566 debug("%s: len=%d, cells_per_record=%d\n", __func__, len,
567 cells_per_record);
568 for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) {
569 u64 pci_addr, addr, size;
570 int space_code;
571 u32 flags;
572 int type;
573
574 if (len < cells_per_record)
575 break;
576 flags = fdt32_to_cpu(prop[0]);
577 space_code = (flags >> 24) & 3;
578 pci_addr = fdtdec_get_number(prop + 1, 2);
579 prop += pci_addr_cells;
580 addr = fdtdec_get_number(prop, addr_cells);
581 prop += addr_cells;
582 size = fdtdec_get_number(prop, size_cells);
583 prop += size_cells;
584 debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64
585 ", size=%" PRIx64 ", space_code=%d\n", __func__,
586 hose->region_count, pci_addr, addr, size, space_code);
587 if (space_code & 2) {
588 type = flags & (1U << 30) ? PCI_REGION_PREFETCH :
589 PCI_REGION_MEM;
590 } else if (space_code & 1) {
591 type = PCI_REGION_IO;
592 } else {
593 continue;
594 }
595 debug(" - type=%d\n", type);
596 pci_set_region(hose->regions + hose->region_count++, pci_addr,
597 addr, size, type);
598 }
599
600 /* Add a region for our local memory */
Simon Glassb9da5082015-07-03 18:28:27 -0600601 addr = gd->ram_size;
602 if (gd->pci_ram_top && gd->pci_ram_top < addr)
603 addr = gd->pci_ram_top;
604 pci_set_region(hose->regions + hose->region_count++, 0, 0, addr,
605 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
Simon Glassff3e0772015-03-05 12:25:25 -0700606
607 return 0;
608}
609
610static int pci_uclass_pre_probe(struct udevice *bus)
611{
612 struct pci_controller *hose;
613 int ret;
614
615 debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name,
616 bus->parent->name);
617 hose = bus->uclass_priv;
618
619 /* For bridges, use the top-level PCI controller */
620 if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) {
621 hose->ctlr = bus;
622 ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
623 bus->of_offset);
624 if (ret) {
625 debug("%s: Cannot decode regions\n", __func__);
626 return ret;
627 }
628 } else {
629 struct pci_controller *parent_hose;
630
631 parent_hose = dev_get_uclass_priv(bus->parent);
632 hose->ctlr = parent_hose->bus;
633 }
634 hose->bus = bus;
635 hose->first_busno = bus->seq;
636 hose->last_busno = bus->seq;
637
638 return 0;
639}
640
641static int pci_uclass_post_probe(struct udevice *bus)
642{
643 int ret;
644
645 /* Don't scan buses before relocation */
646 if (!(gd->flags & GD_FLG_RELOC))
647 return 0;
648
649 debug("%s: probing bus %d\n", __func__, bus->seq);
650 ret = pci_bind_bus_devices(bus);
651 if (ret)
652 return ret;
653
654#ifdef CONFIG_PCI_PNP
655 ret = pci_auto_config_devices(bus);
656#endif
657
658 return ret < 0 ? ret : 0;
659}
660
661static int pci_uclass_child_post_bind(struct udevice *dev)
662{
663 struct pci_child_platdata *pplat;
664 struct fdt_pci_addr addr;
665 int ret;
666
667 if (dev->of_offset == -1)
668 return 0;
669
670 /*
671 * We could read vendor, device, class if available. But for now we
672 * just check the address.
673 */
674 pplat = dev_get_parent_platdata(dev);
675 ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
676 FDT_PCI_SPACE_CONFIG, "reg", &addr);
677
678 if (ret) {
679 if (ret != -ENOENT)
680 return -EINVAL;
681 } else {
682 /* extract the bdf from fdt_pci_addr */
683 pplat->devfn = addr.phys_hi & 0xffff00;
684 }
685
686 return 0;
687}
688
689int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset,
690 ulong *valuep, enum pci_size_t size)
691{
692 struct pci_controller *hose = bus->uclass_priv;
693 pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
694
695 return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size);
696}
697
698int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset,
699 ulong value, enum pci_size_t size)
700{
701 struct pci_controller *hose = bus->uclass_priv;
702 pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
703
704 return pci_bus_write_config(hose->ctlr, bdf, offset, value, size);
705}
706
707UCLASS_DRIVER(pci) = {
708 .id = UCLASS_PCI,
709 .name = "pci",
Simon Glass2bb02e42015-05-10 21:08:06 -0600710 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glassff3e0772015-03-05 12:25:25 -0700711 .post_bind = pci_uclass_post_bind,
712 .pre_probe = pci_uclass_pre_probe,
713 .post_probe = pci_uclass_post_probe,
714 .child_post_bind = pci_uclass_child_post_bind,
715 .per_device_auto_alloc_size = sizeof(struct pci_controller),
716 .per_child_platdata_auto_alloc_size =
717 sizeof(struct pci_child_platdata),
718};
719
720static const struct dm_pci_ops pci_bridge_ops = {
721 .read_config = pci_bridge_read_config,
722 .write_config = pci_bridge_write_config,
723};
724
725static const struct udevice_id pci_bridge_ids[] = {
726 { .compatible = "pci-bridge" },
727 { }
728};
729
730U_BOOT_DRIVER(pci_bridge_drv) = {
731 .name = "pci_bridge_drv",
732 .id = UCLASS_PCI,
733 .of_match = pci_bridge_ids,
734 .ops = &pci_bridge_ops,
735};
736
737UCLASS_DRIVER(pci_generic) = {
738 .id = UCLASS_PCI_GENERIC,
739 .name = "pci_generic",
740};
741
742static const struct udevice_id pci_generic_ids[] = {
743 { .compatible = "pci-generic" },
744 { }
745};
746
747U_BOOT_DRIVER(pci_generic_drv) = {
748 .name = "pci_generic_drv",
749 .id = UCLASS_PCI_GENERIC,
750 .of_match = pci_generic_ids,
751};