ACPI: thinkpad-acpi: add infrastructure for the sysfs device attributes
Add infrastructure to deal with sysfs attributes and grouping, and helpers for common sysfs parsing. Switch driver attributes to use them. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Родитель
176750d688
Коммит
7252374a39
|
@ -520,12 +520,8 @@ static ssize_t tpacpi_driver_debug_store(struct device_driver *drv,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long t;
|
||||
char *endp;
|
||||
|
||||
t = simple_strtoul(buf, &endp, 0);
|
||||
while (*endp && isspace(*endp))
|
||||
endp++;
|
||||
if (*endp)
|
||||
if (parse_strtoul(buf, 0xffff, &t))
|
||||
return -EINVAL;
|
||||
|
||||
dbg_level = t;
|
||||
|
@ -575,6 +571,86 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
|
|||
driver_remove_file(drv, tpacpi_driver_attributes[i]);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* sysfs support helpers
|
||||
*/
|
||||
|
||||
struct attribute_set_obj {
|
||||
struct attribute_set s;
|
||||
struct attribute *a;
|
||||
} __attribute__((packed));
|
||||
|
||||
static struct attribute_set *create_attr_set(unsigned int max_members,
|
||||
const char* name)
|
||||
{
|
||||
struct attribute_set_obj *sobj;
|
||||
|
||||
if (max_members == 0)
|
||||
return NULL;
|
||||
|
||||
/* Allocates space for implicit NULL at the end too */
|
||||
sobj = kzalloc(sizeof(struct attribute_set_obj) +
|
||||
max_members * sizeof(struct attribute *),
|
||||
GFP_KERNEL);
|
||||
if (!sobj)
|
||||
return NULL;
|
||||
sobj->s.max_members = max_members;
|
||||
sobj->s.group.attrs = &sobj->a;
|
||||
sobj->s.group.name = name;
|
||||
|
||||
return &sobj->s;
|
||||
}
|
||||
|
||||
/* not multi-threaded safe, use it in a single thread per set */
|
||||
static int add_to_attr_set(struct attribute_set* s, struct attribute *attr)
|
||||
{
|
||||
if (!s || !attr)
|
||||
return -EINVAL;
|
||||
|
||||
if (s->members >= s->max_members)
|
||||
return -ENOMEM;
|
||||
|
||||
s->group.attrs[s->members] = attr;
|
||||
s->members++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_many_to_attr_set(struct attribute_set* s,
|
||||
struct attribute **attr,
|
||||
unsigned int count)
|
||||
{
|
||||
int i, res;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
res = add_to_attr_set(s, attr[i]);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void delete_attr_set(struct attribute_set* s, struct kobject *kobj)
|
||||
{
|
||||
sysfs_remove_group(kobj, &s->group);
|
||||
destroy_attr_set(s);
|
||||
}
|
||||
|
||||
static int parse_strtoul(const char *buf,
|
||||
unsigned long max, unsigned long *value)
|
||||
{
|
||||
char *endp;
|
||||
|
||||
*value = simple_strtoul(buf, &endp, 0);
|
||||
while (*endp && isspace(*endp))
|
||||
endp++;
|
||||
if (*endp || *value > max)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************
|
||||
*
|
||||
|
|
|
@ -134,6 +134,27 @@ static int dispatch_procfs_write(struct file *file,
|
|||
unsigned long count, void *data);
|
||||
static char *next_cmd(char **cmds);
|
||||
|
||||
/* sysfs support */
|
||||
struct attribute_set {
|
||||
unsigned int members, max_members;
|
||||
struct attribute_group group;
|
||||
};
|
||||
|
||||
static struct attribute_set *create_attr_set(unsigned int max_members,
|
||||
const char* name);
|
||||
#define destroy_attr_set(_set) \
|
||||
kfree(_set);
|
||||
static int add_to_attr_set(struct attribute_set* s, struct attribute *attr);
|
||||
static int add_many_to_attr_set(struct attribute_set* s,
|
||||
struct attribute **attr,
|
||||
unsigned int count);
|
||||
#define register_attr_set_with_sysfs(_attr_set, _kobj) \
|
||||
sysfs_create_group(_kobj, &_attr_set->group)
|
||||
static void delete_attr_set(struct attribute_set* s, struct kobject *kobj);
|
||||
|
||||
static int parse_strtoul(const char *buf, unsigned long max,
|
||||
unsigned long *value);
|
||||
|
||||
/* Device model */
|
||||
static struct platform_device *tpacpi_pdev;
|
||||
static struct class_device *tpacpi_hwmon;
|
||||
|
|
Загрузка…
Ссылка в новой задаче