summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-peci16
-rw-r--r--drivers/peci/Makefile2
-rw-r--r--drivers/peci/core.c3
-rw-r--r--drivers/peci/device.c1
-rw-r--r--drivers/peci/internal.h5
-rw-r--r--drivers/peci/sysfs.c82
6 files changed, 107 insertions, 2 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-peci b/Documentation/ABI/testing/sysfs-bus-peci
new file mode 100644
index 000000000000..87454ec5d981
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-peci
@@ -0,0 +1,16 @@
+What: /sys/bus/peci/rescan
+Date: July 2021
+KernelVersion: 5.18
+Contact: Iwona Winiarska <iwona.winiarska@intel.com>
+Description:
+ Writing a non-zero value to this attribute will
+ initiate scan for PECI devices on all PECI controllers
+ in the system.
+
+What: /sys/bus/peci/devices/<controller_id>-<device_addr>/remove
+Date: July 2021
+KernelVersion: 5.18
+Contact: Iwona Winiarska <iwona.winiarska@intel.com>
+Description:
+ Writing a non-zero value to this attribute will
+ remove the PECI device and any of its children.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index c5f9d3fe21bb..917f689e147a 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
# Core functionality
-peci-y := core.o request.o device.o
+peci-y := core.o request.o device.o sysfs.o
obj-$(CONFIG_PECI) += peci.o
# Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index c3361e6e043a..e993615cf521 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -29,7 +29,7 @@ struct device_type peci_controller_type = {
.release = peci_controller_dev_release,
};
-static int peci_controller_scan_devices(struct peci_controller *controller)
+int peci_controller_scan_devices(struct peci_controller *controller)
{
int ret;
u8 addr;
@@ -162,6 +162,7 @@ EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
struct bus_type peci_bus_type = {
.name = "peci",
+ .bus_groups = peci_bus_groups,
};
static int __init peci_init(void)
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index 2b3a2d893aaf..d10ed1cfcd48 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -116,5 +116,6 @@ static void peci_device_release(struct device *dev)
}
struct device_type peci_device_type = {
+ .groups = peci_device_groups,
.release = peci_device_release,
};
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 57d11a902c5d..978e12c8e1d3 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,7 @@
#include <linux/types.h>
struct peci_controller;
+struct attribute_group;
struct peci_device;
struct peci_request;
@@ -19,12 +20,16 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u
void peci_request_free(struct peci_request *req);
extern struct device_type peci_device_type;
+extern const struct attribute_group *peci_device_groups[];
int peci_device_create(struct peci_controller *controller, u8 addr);
void peci_device_destroy(struct peci_device *device);
extern struct bus_type peci_bus_type;
+extern const struct attribute_group *peci_bus_groups[];
extern struct device_type peci_controller_type;
+int peci_controller_scan_devices(struct peci_controller *controller);
+
#endif /* __PECI_INTERNAL_H */
diff --git a/drivers/peci/sysfs.c b/drivers/peci/sysfs.c
new file mode 100644
index 000000000000..db9ef05776e3
--- /dev/null
+++ b/drivers/peci/sysfs.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/peci.h>
+
+#include "internal.h"
+
+static int rescan_controller(struct device *dev, void *data)
+{
+ if (dev->type != &peci_controller_type)
+ return 0;
+
+ return peci_controller_scan_devices(to_peci_controller(dev));
+}
+
+static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count)
+{
+ bool res;
+ int ret;
+
+ ret = kstrtobool(buf, &res);
+ if (ret)
+ return ret;
+
+ if (!res)
+ return count;
+
+ ret = bus_for_each_dev(&peci_bus_type, NULL, NULL, rescan_controller);
+ if (ret)
+ return ret;
+
+ return count;
+}
+static BUS_ATTR_WO(rescan);
+
+static struct attribute *peci_bus_attrs[] = {
+ &bus_attr_rescan.attr,
+ NULL
+};
+
+static const struct attribute_group peci_bus_group = {
+ .attrs = peci_bus_attrs,
+};
+
+const struct attribute_group *peci_bus_groups[] = {
+ &peci_bus_group,
+ NULL
+};
+
+static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct peci_device *device = to_peci_device(dev);
+ bool res;
+ int ret;
+
+ ret = kstrtobool(buf, &res);
+ if (ret)
+ return ret;
+
+ if (res && device_remove_file_self(dev, attr))
+ peci_device_destroy(device);
+
+ return count;
+}
+static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, remove_store);
+
+static struct attribute *peci_device_attrs[] = {
+ &dev_attr_remove.attr,
+ NULL
+};
+
+static const struct attribute_group peci_device_group = {
+ .attrs = peci_device_attrs,
+};
+
+const struct attribute_group *peci_device_groups[] = {
+ &peci_device_group,
+ NULL
+};