aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/peci/core.c
diff options
context:
space:
mode:
authorIwona Winiarska <iwona.winiarska@intel.com>2022-02-08 16:36:34 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-02-09 08:04:44 +0100
commit6b8145b054b27319dddaad4abbb5184e343375da (patch)
tree605b9acd203fc0d5be14fa6c498bbaf4b900e472 /drivers/peci/core.c
parentpeci: Add sysfs interface for PECI bus (diff)
downloadlinux-dev-6b8145b054b27319dddaad4abbb5184e343375da.tar.xz
linux-dev-6b8145b054b27319dddaad4abbb5184e343375da.zip
peci: Add support for PECI device drivers
Add support for PECI device drivers, which unlike PECI controller drivers are actually able to provide functionalities to userspace. Also, extend peci_request API to allow querying more details about PECI device (e.g. model/family), that's going to be used to find a compatible peci_driver. 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-9-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.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index e993615cf521..9c8cf07e51c7 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -160,8 +160,52 @@ err_put:
}
EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
+static const struct peci_device_id *
+peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *device)
+{
+ while (id->family != 0) {
+ if (id->family == device->info.family &&
+ id->model == device->info.model)
+ return id;
+ id++;
+ }
+
+ return NULL;
+}
+
+static int peci_bus_device_match(struct device *dev, struct device_driver *drv)
+{
+ struct peci_device *device = to_peci_device(dev);
+ struct peci_driver *peci_drv = to_peci_driver(drv);
+
+ if (dev->type != &peci_device_type)
+ return 0;
+
+ return !!peci_bus_match_device_id(peci_drv->id_table, device);
+}
+
+static int peci_bus_device_probe(struct device *dev)
+{
+ struct peci_device *device = to_peci_device(dev);
+ struct peci_driver *driver = to_peci_driver(dev->driver);
+
+ return driver->probe(device, peci_bus_match_device_id(driver->id_table, device));
+}
+
+static void peci_bus_device_remove(struct device *dev)
+{
+ struct peci_device *device = to_peci_device(dev);
+ struct peci_driver *driver = to_peci_driver(dev->driver);
+
+ if (driver->remove)
+ driver->remove(device);
+}
+
struct bus_type peci_bus_type = {
.name = "peci",
+ .match = peci_bus_device_match,
+ .probe = peci_bus_device_probe,
+ .remove = peci_bus_device_remove,
.bus_groups = peci_bus_groups,
};