summaryrefslogtreecommitdiff
path: root/drivers/peci/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/peci/core.c')
-rw-r--r--drivers/peci/core.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index 73ad0a47fa9d..c3361e6e043a 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -29,6 +29,20 @@ struct device_type peci_controller_type = {
.release = peci_controller_dev_release,
};
+static int peci_controller_scan_devices(struct peci_controller *controller)
+{
+ int ret;
+ u8 addr;
+
+ for (addr = PECI_BASE_ADDR; addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX; addr++) {
+ ret = peci_device_create(controller, addr);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static struct peci_controller *peci_controller_alloc(struct device *dev,
struct peci_controller_ops *ops)
{
@@ -64,10 +78,23 @@ err:
return ERR_PTR(ret);
}
+static int unregister_child(struct device *dev, void *dummy)
+{
+ peci_device_destroy(to_peci_device(dev));
+
+ return 0;
+}
+
static void unregister_controller(void *_controller)
{
struct peci_controller *controller = _controller;
+ /*
+ * Detach any active PECI devices. This can't fail, thus we do not
+ * check the returned value.
+ */
+ device_for_each_child_reverse(&controller->dev, NULL, unregister_child);
+
device_unregister(&controller->dev);
fwnode_handle_put(controller->dev.fwnode);
@@ -113,6 +140,12 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
if (ret)
return ERR_PTR(ret);
+ /*
+ * Ignoring retval since failures during scan are non-critical for
+ * controller itself.
+ */
+ peci_controller_scan_devices(controller);
+
return controller;
err_fwnode: