142bed52bSIwona Winiarska // SPDX-License-Identifier: GPL-2.0-only
242bed52bSIwona Winiarska // Copyright (c) 2021 Intel Corporation
342bed52bSIwona Winiarska
442bed52bSIwona Winiarska #include <linux/device.h>
542bed52bSIwona Winiarska #include <linux/kernel.h>
642bed52bSIwona Winiarska #include <linux/peci.h>
742bed52bSIwona Winiarska
842bed52bSIwona Winiarska #include "internal.h"
942bed52bSIwona Winiarska
rescan_controller(struct device * dev,void * data)1042bed52bSIwona Winiarska static int rescan_controller(struct device *dev, void *data)
1142bed52bSIwona Winiarska {
1242bed52bSIwona Winiarska if (dev->type != &peci_controller_type)
1342bed52bSIwona Winiarska return 0;
1442bed52bSIwona Winiarska
1542bed52bSIwona Winiarska return peci_controller_scan_devices(to_peci_controller(dev));
1642bed52bSIwona Winiarska }
1742bed52bSIwona Winiarska
rescan_store(const struct bus_type * bus,const char * buf,size_t count)18*75cff725SGreg Kroah-Hartman static ssize_t rescan_store(const struct bus_type *bus, const char *buf, size_t count)
1942bed52bSIwona Winiarska {
2042bed52bSIwona Winiarska bool res;
2142bed52bSIwona Winiarska int ret;
2242bed52bSIwona Winiarska
2342bed52bSIwona Winiarska ret = kstrtobool(buf, &res);
2442bed52bSIwona Winiarska if (ret)
2542bed52bSIwona Winiarska return ret;
2642bed52bSIwona Winiarska
2742bed52bSIwona Winiarska if (!res)
2842bed52bSIwona Winiarska return count;
2942bed52bSIwona Winiarska
3042bed52bSIwona Winiarska ret = bus_for_each_dev(&peci_bus_type, NULL, NULL, rescan_controller);
3142bed52bSIwona Winiarska if (ret)
3242bed52bSIwona Winiarska return ret;
3342bed52bSIwona Winiarska
3442bed52bSIwona Winiarska return count;
3542bed52bSIwona Winiarska }
3642bed52bSIwona Winiarska static BUS_ATTR_WO(rescan);
3742bed52bSIwona Winiarska
3842bed52bSIwona Winiarska static struct attribute *peci_bus_attrs[] = {
3942bed52bSIwona Winiarska &bus_attr_rescan.attr,
4042bed52bSIwona Winiarska NULL
4142bed52bSIwona Winiarska };
4242bed52bSIwona Winiarska
4342bed52bSIwona Winiarska static const struct attribute_group peci_bus_group = {
4442bed52bSIwona Winiarska .attrs = peci_bus_attrs,
4542bed52bSIwona Winiarska };
4642bed52bSIwona Winiarska
4742bed52bSIwona Winiarska const struct attribute_group *peci_bus_groups[] = {
4842bed52bSIwona Winiarska &peci_bus_group,
4942bed52bSIwona Winiarska NULL
5042bed52bSIwona Winiarska };
5142bed52bSIwona Winiarska
remove_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)5242bed52bSIwona Winiarska static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
5342bed52bSIwona Winiarska const char *buf, size_t count)
5442bed52bSIwona Winiarska {
5542bed52bSIwona Winiarska struct peci_device *device = to_peci_device(dev);
5642bed52bSIwona Winiarska bool res;
5742bed52bSIwona Winiarska int ret;
5842bed52bSIwona Winiarska
5942bed52bSIwona Winiarska ret = kstrtobool(buf, &res);
6042bed52bSIwona Winiarska if (ret)
6142bed52bSIwona Winiarska return ret;
6242bed52bSIwona Winiarska
6342bed52bSIwona Winiarska if (res && device_remove_file_self(dev, attr))
6442bed52bSIwona Winiarska peci_device_destroy(device);
6542bed52bSIwona Winiarska
6642bed52bSIwona Winiarska return count;
6742bed52bSIwona Winiarska }
6842bed52bSIwona Winiarska static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, remove_store);
6942bed52bSIwona Winiarska
7042bed52bSIwona Winiarska static struct attribute *peci_device_attrs[] = {
7142bed52bSIwona Winiarska &dev_attr_remove.attr,
7242bed52bSIwona Winiarska NULL
7342bed52bSIwona Winiarska };
7442bed52bSIwona Winiarska
7542bed52bSIwona Winiarska static const struct attribute_group peci_device_group = {
7642bed52bSIwona Winiarska .attrs = peci_device_attrs,
7742bed52bSIwona Winiarska };
7842bed52bSIwona Winiarska
7942bed52bSIwona Winiarska const struct attribute_group *peci_device_groups[] = {
8042bed52bSIwona Winiarska &peci_device_group,
8142bed52bSIwona Winiarska NULL
8242bed52bSIwona Winiarska };
83