summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/boot/hardwaremain.c4
-rw-r--r--src/devices/device.c20
-rw-r--r--src/include/device/device.h5
3 files changed, 28 insertions, 1 deletions
diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c
index 95dd988e16..206e82b066 100644
--- a/src/boot/hardwaremain.c
+++ b/src/boot/hardwaremain.c
@@ -82,6 +82,10 @@ void hardwaremain(int boot_complete)
init_timer();
timestamp_stash(TS_DEVICE_ENUMERATE);
+
+ /* Initialize chips early, they might disable unused devices. */
+ dev_initialize_chips();
+
/* Find the devices we don't have hard coded knowledge about. */
dev_enumerate();
post_code(POST_DEVICE_ENUMERATION_COMPLETE);
diff --git a/src/devices/device.c b/src/devices/device.c
index f021c9b3a3..03e7ea7c63 100644
--- a/src/devices/device.c
+++ b/src/devices/device.c
@@ -52,6 +52,26 @@ extern struct device *last_dev;
/** Linked list of free resources */
struct resource *free_resources = NULL;
+/**
+ * Initialize all chips of statically known devices.
+ *
+ * Will be called before bus enumeration to initialize chips stated in the
+ * device tree.
+ */
+void dev_initialize_chips(void)
+{
+ struct device *dev;
+
+ for (dev = all_devices; dev; dev = dev->next) {
+ /* Initialize chip if we haven't yet. */
+ if (dev->chip_ops && dev->chip_ops->init &&
+ !dev->chip_ops->initialized) {
+ dev->chip_ops->init(dev->chip_info);
+ dev->chip_ops->initialized = 1;
+ }
+ }
+}
+
DECLARE_SPIN_LOCK(dev_lock)
#if CONFIG_GFXUMA
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 1cd2a8b115..b248aafb7a 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -16,6 +16,8 @@ struct smbus_bus_operations;
/* Chip operations */
struct chip_operations {
void (*enable_dev)(struct device *dev);
+ void (*init)(void *chip_info);
+ unsigned int initialized : 1;
const char *name;
};
@@ -100,7 +102,7 @@ struct device {
struct device_operations *ops;
#ifndef __PRE_RAM__
- const struct chip_operations *chip_ops;
+ struct chip_operations *chip_ops;
const char *name;
#endif
ROMSTAGE_CONST void *chip_info;
@@ -125,6 +127,7 @@ extern uint64_t uma_memory_size;
/* Generic device interface functions */
device_t alloc_dev(struct bus *parent, struct device_path *path);
+void dev_initialize_chips(void);
void dev_enumerate(void);
void dev_configure(void);
void dev_enable(void);