/* * kernel/power/tuxonice_sysfs.h * * Copyright (C) 2004-2015 Nigel Cunningham (nigel at nigelcunningham com au) * * This file is released under the GPLv2. */ #include struct toi_sysfs_data { struct attribute attr; int type; int flags; union { struct { unsigned long *bit_vector; int bit; } bit; struct { int *variable; int minimum; int maximum; } integer; struct { long *variable; long minimum; long maximum; } a_long; struct { unsigned long *variable; unsigned long minimum; unsigned long maximum; } ul; struct { char *variable; int max_length; } string; struct { int (*read_sysfs) (const char *buffer, int count); int (*write_sysfs) (const char *buffer, int count); void *data; } special; } data; /* Side effects routine. Used, eg, for reparsing the * resume= entry when it changes */ void (*write_side_effect) (void); struct list_head sysfs_data_list; }; enum { TOI_SYSFS_DATA_NONE = 1, TOI_SYSFS_DATA_CUSTOM, TOI_SYSFS_DATA_BIT, TOI_SYSFS_DATA_INTEGER, TOI_SYSFS_DATA_UL, TOI_SYSFS_DATA_LONG, TOI_SYSFS_DATA_STRING }; #define SYSFS_WRITEONLY 0200 #define SYSFS_READONLY 0444 #define SYSFS_RW 0644 #define SYSFS_BIT(_name, _mode, _ul, _bit, _flags) { \ .attr = {.name = _name , .mode = _mode }, \ .type = TOI_SYSFS_DATA_BIT, \ .flags = _flags, \ .data = { .bit = { .bit_vector = _ul, .bit = _bit } } } #define SYSFS_INT(_name, _mode, _int, _min, _max, _flags, _wse) { \ .attr = {.name = _name , .mode = _mode }, \ .type = TOI_SYSFS_DATA_INTEGER, \ .flags = _flags, \ .data = { .integer = { .variable = _int, .minimum = _min, \ .maximum = _max } }, \ .write_side_effect = _wse } #define SYSFS_UL(_name, _mode, _ul, _min, _max, _flags) { \ .attr = {.name = _name , .mode = _mode }, \ .type = TOI_SYSFS_DATA_UL, \ .flags = _flags, \ .data = { .ul = { .variable = _ul, .minimum = _min, \ .maximum = _max } } } #define SYSFS_LONG(_name, _mode, _long, _min, _max, _flags) { \ .attr = {.name = _name , .mode = _mode }, \ .type = TOI_SYSFS_DATA_LONG, \ .flags = _flags, \ .data = { .a_long = { .variable = _long, .minimum = _min, \ .maximum = _max } } } #define SYSFS_STRING(_name, _mode, _string, _max_len, _flags, _wse) { \ .attr = {.name = _name , .mode = _mode }, \ .type = TOI_SYSFS_DATA_STRING, \ .flags = _flags, \ .data = { .string = { .variable = _string, .max_length = _max_len } }, \ .write_side_effect = _wse } #define SYSFS_CUSTOM(_name, _mode, _read, _write, _flags, _wse) { \ .attr = {.name = _name , .mode = _mode }, \ .type = TOI_SYSFS_DATA_CUSTOM, \ .flags = _flags, \ .data = { .special = { .read_sysfs = _read, .write_sysfs = _write } }, \ .write_side_effect = _wse } #define SYSFS_NONE(_name, _wse) { \ .attr = {.name = _name , .mode = SYSFS_WRITEONLY }, \ .type = TOI_SYSFS_DATA_NONE, \ .write_side_effect = _wse, \ } /* Flags */ #define SYSFS_NEEDS_SM_FOR_READ 1 #define SYSFS_NEEDS_SM_FOR_WRITE 2 #define SYSFS_HIBERNATE 4 #define SYSFS_RESUME 8 #define SYSFS_HIBERNATE_OR_RESUME (SYSFS_HIBERNATE | SYSFS_RESUME) #define SYSFS_HIBERNATING (SYSFS_HIBERNATE | SYSFS_NEEDS_SM_FOR_WRITE) #define SYSFS_RESUMING (SYSFS_RESUME | SYSFS_NEEDS_SM_FOR_WRITE) #define SYSFS_NEEDS_SM_FOR_BOTH \ (SYSFS_NEEDS_SM_FOR_READ | SYSFS_NEEDS_SM_FOR_WRITE) int toi_register_sysfs_file(struct kobject *kobj, struct toi_sysfs_data *toi_sysfs_data); void toi_unregister_sysfs_file(struct kobject *kobj, struct toi_sysfs_data *toi_sysfs_data); extern struct kobject *tuxonice_kobj; struct kobject *make_toi_sysdir(char *name); void remove_toi_sysdir(struct kobject *obj); extern void toi_cleanup_sysfs(void); extern int toi_sysfs_init(void); extern void toi_sysfs_exit(void);