summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2012-04-24 12:53:19 -0700
committerPatrick Georgi <patrick@georgi-clan.de>2012-05-01 20:02:21 +0200
commit8049fc91ded9d780b9f6d5c40bc43ad3242b7a3b (patch)
treea2e4295afbe11c4838d1ec303a78b778eab154df
parent599e204efc5a55eb388a2ff11afb0e2196c21875 (diff)
Allow device ID arrays in the PCI driver structure
Many PCI devices share the very same driver despite having different PCI device IDs, which causes a lot of copy and paste of driver definitions. This change introduces a way to specify the array of acceptable device IDs in a single driver entry. As an example the Intel {Sandy|Ivy} Bridge SATA driver is being modified to use a single driver structure for all different SATA controller flavors, a few more Ivy Bridge IDs are being added as well. BUG=none TEST=manual . modified coreboot brought up an Ivy Bridge platform all the way to Linux login screen. Change-Id: I761c5611b93ef946053783f7a755e6c456dd6991 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: http://review.coreboot.org/982 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
-rw-r--r--src/devices/pci_device.c24
-rw-r--r--src/include/device/pci.h1
-rw-r--r--src/southbridge/intel/bd82x6x/sata.c27
3 files changed, 28 insertions, 24 deletions
diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c
index c0559956b3..c9af7c4cc8 100644
--- a/src/devices/pci_device.c
+++ b/src/devices/pci_device.c
@@ -796,6 +796,28 @@ static struct device_operations *get_pci_bridge_ops(device_t dev)
}
/**
+ * Check if a device id matches a PCI driver entry.
+ *
+ * The driver entry can either point at a zero terminated array of acceptable
+ * device IDs, or include a single device ID.
+ *
+ * @driver pointer to the PCI driver entry being checked
+ * @device_id PCI device ID of the device being matched
+ */
+static int device_id_match(struct pci_driver *driver, unsigned short device_id)
+{
+ if (driver->devices) {
+ unsigned short check_id;
+ const unsigned short *device_list = driver->devices;
+ while ((check_id = *device_list++) != 0)
+ if (check_id == device_id)
+ return 1;
+ }
+
+ return (driver->device == device_id);
+}
+
+/**
* Set up PCI device operation.
*
* Check if it already has a driver. If not, use find_device_operations(),
@@ -817,7 +839,7 @@ static void set_pci_ops(struct device *dev)
*/
for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) {
if ((driver->vendor == dev->vendor) &&
- (driver->device == dev->device)) {
+ device_id_match(driver, dev->device)) {
dev->ops = (struct device_operations *)driver->ops;
printk(BIOS_SPEW, "%s [%04x/%04x] %sops\n",
dev_path(dev), driver->vendor, driver->device,
diff --git a/src/include/device/pci.h b/src/include/device/pci.h
index d4cfb8558c..e864d6d47f 100644
--- a/src/include/device/pci.h
+++ b/src/include/device/pci.h
@@ -42,6 +42,7 @@ struct pci_driver {
const struct device_operations *ops;
unsigned short vendor;
unsigned short device;
+ const unsigned short *devices;
};
#define __pci_driver __attribute__ ((used,__section__(".rodata.pci_driver")))
diff --git a/src/southbridge/intel/bd82x6x/sata.c b/src/southbridge/intel/bd82x6x/sata.c
index 057b8825b0..fef12cd80b 100644
--- a/src/southbridge/intel/bd82x6x/sata.c
+++ b/src/southbridge/intel/bd82x6x/sata.c
@@ -215,32 +215,13 @@ static struct device_operations sata_ops = {
.ops_pci = &sata_pci_ops,
};
+static const unsigned short all_dev_ids[] = { 0x1c00, 0x1c01, 0x1c02, 0x1c03,
+ 0x1e00, 0x1e01, 0x1e02, 0x1e03,
+ 0 };
/* Non-AHCI and Non-RAID Mode */
static const struct pci_driver pch_sata_normal_driver __pci_driver = {
.ops = &sata_ops,
.vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x1c00,
-};
-static const struct pci_driver pch_sata_mobile_normal_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x1c01,
-};
-
-/* AHCI Mode */
-static const struct pci_driver pch_sata_ahci_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x1c02,
-};
-static const struct pci_driver pch_sata_mobile_ahci_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x1c03,
-};
-static const struct pci_driver pch_sata_mobile_ahci_driver_a __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x1e03,
+ .devices = all_dev_ids,
};