summaryrefslogtreecommitdiff
path: root/drivers/peci/core.c
diff options
context:
space:
mode:
authorIwona Winiarska <iwona.winiarska@intel.com>2022-02-08 16:36:32 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-02-09 08:04:44 +0100
commit52857e6828e260b16ac569578705f83cf2a71ac1 (patch)
treee468e1dbeef61906b3457d1d1d13af7690cdab6e /drivers/peci/core.c
parenta85e4c52086cd8da6399447a92bf0250d8e634c2 (diff)
peci: Add device detection
Since PECI devices are discoverable, we can dynamically detect devices that are actually available in the system. This change complements the earlier implementation by rescanning PECI bus to detect available devices. For this purpose, it also introduces the minimal API for PECI requests. Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Acked-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com> Link: https://lore.kernel.org/r/20220208153639.255278-7-iwona.winiarska@intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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: