diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2007-04-24 10:48:14 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-04-25 02:00:27 -0400 |
commit | 7252374a39d794879f5e47bcfa0a16e7599b27b5 (patch) | |
tree | f6a0801099b74b9d78ea1240d725b7aa2f6c6a0b /drivers | |
parent | 176750d68801bfa4a88d1cf54174aa0347d7e5d8 (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 86 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 21 |
2 files changed, 102 insertions, 5 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index a31d00d570cb..ca6d15cdc5f0 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -520,12 +520,8 @@ static ssize_t tpacpi_driver_debug_store(struct device_driver *drv, | |||
520 | const char *buf, size_t count) | 520 | const char *buf, size_t count) |
521 | { | 521 | { |
522 | unsigned long t; | 522 | unsigned long t; |
523 | char *endp; | ||
524 | 523 | ||
525 | t = simple_strtoul(buf, &endp, 0); | 524 | if (parse_strtoul(buf, 0xffff, &t)) |
526 | while (*endp && isspace(*endp)) | ||
527 | endp++; | ||
528 | if (*endp) | ||
529 | return -EINVAL; | 525 | return -EINVAL; |
530 | 526 | ||
531 | dbg_level = t; | 527 | dbg_level = t; |
@@ -575,6 +571,86 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) | |||
575 | driver_remove_file(drv, tpacpi_driver_attributes[i]); | 571 | driver_remove_file(drv, tpacpi_driver_attributes[i]); |
576 | } | 572 | } |
577 | 573 | ||
574 | /************************************************************************* | ||
575 | * sysfs support helpers | ||
576 | */ | ||
577 | |||
578 | struct attribute_set_obj { | ||
579 | struct attribute_set s; | ||
580 | struct attribute *a; | ||
581 | } __attribute__((packed)); | ||
582 | |||
583 | static struct attribute_set *create_attr_set(unsigned int max_members, | ||
584 | const char* name) | ||
585 | { | ||
586 | struct attribute_set_obj *sobj; | ||
587 | |||
588 | if (max_members == 0) | ||
589 | return NULL; | ||
590 | |||
591 | /* Allocates space for implicit NULL at the end too */ | ||
592 | sobj = kzalloc(sizeof(struct attribute_set_obj) + | ||
593 | max_members * sizeof(struct attribute *), | ||
594 | GFP_KERNEL); | ||
595 | if (!sobj) | ||
596 | return NULL; | ||
597 | sobj->s.max_members = max_members; | ||
598 | sobj->s.group.attrs = &sobj->a; | ||
599 | sobj->s.group.name = name; | ||
600 | |||
601 | return &sobj->s; | ||
602 | } | ||
603 | |||
604 | /* not multi-threaded safe, use it in a single thread per set */ | ||
605 | static int add_to_attr_set(struct attribute_set* s, struct attribute *attr) | ||
606 | { | ||
607 | if (!s || !attr) | ||
608 | return -EINVAL; | ||
609 | |||
610 | if (s->members >= s->max_members) | ||
611 | return -ENOMEM; | ||
612 | |||
613 | s->group.attrs[s->members] = attr; | ||
614 | s->members++; | ||
615 | |||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int add_many_to_attr_set(struct attribute_set* s, | ||
620 | struct attribute **attr, | ||
621 | unsigned int count) | ||
622 | { | ||
623 | int i, res; | ||
624 | |||
625 | for (i = 0; i < count; i++) { | ||
626 | res = add_to_attr_set(s, attr[i]); | ||
627 | if (res) | ||
628 | return res; | ||
629 | } | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | static void delete_attr_set(struct attribute_set* s, struct kobject *kobj) | ||
635 | { | ||
636 | sysfs_remove_group(kobj, &s->group); | ||
637 | destroy_attr_set(s); | ||
638 | } | ||
639 | |||
640 | static int parse_strtoul(const char *buf, | ||
641 | unsigned long max, unsigned long *value) | ||
642 | { | ||
643 | char *endp; | ||
644 | |||
645 | *value = simple_strtoul(buf, &endp, 0); | ||
646 | while (*endp && isspace(*endp)) | ||
647 | endp++; | ||
648 | if (*endp || *value > max) | ||
649 | return -EINVAL; | ||
650 | |||
651 | return 0; | ||
652 | } | ||
653 | |||
578 | /**************************************************************************** | 654 | /**************************************************************************** |
579 | **************************************************************************** | 655 | **************************************************************************** |
580 | * | 656 | * |
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 37860582956f..84fdefe0d200 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -134,6 +134,27 @@ static int dispatch_procfs_write(struct file *file, | |||
134 | unsigned long count, void *data); | 134 | unsigned long count, void *data); |
135 | static char *next_cmd(char **cmds); | 135 | static char *next_cmd(char **cmds); |
136 | 136 | ||
137 | /* sysfs support */ | ||
138 | struct attribute_set { | ||
139 | unsigned int members, max_members; | ||
140 | struct attribute_group group; | ||
141 | }; | ||
142 | |||
143 | static struct attribute_set *create_attr_set(unsigned int max_members, | ||
144 | const char* name); | ||
145 | #define destroy_attr_set(_set) \ | ||
146 | kfree(_set); | ||
147 | static int add_to_attr_set(struct attribute_set* s, struct attribute *attr); | ||
148 | static int add_many_to_attr_set(struct attribute_set* s, | ||
149 | struct attribute **attr, | ||
150 | unsigned int count); | ||
151 | #define register_attr_set_with_sysfs(_attr_set, _kobj) \ | ||
152 | sysfs_create_group(_kobj, &_attr_set->group) | ||
153 | static void delete_attr_set(struct attribute_set* s, struct kobject *kobj); | ||
154 | |||
155 | static int parse_strtoul(const char *buf, unsigned long max, | ||
156 | unsigned long *value); | ||
157 | |||
137 | /* Device model */ | 158 | /* Device model */ |
138 | static struct platform_device *tpacpi_pdev; | 159 | static struct platform_device *tpacpi_pdev; |
139 | static struct class_device *tpacpi_hwmon; | 160 | static struct class_device *tpacpi_hwmon; |