1 // SPDX-License-Identifier: GPL-2.0
3 * Functions corresponding to integer type attributes under BIOS Integer GUID for use with
6 * Copyright (c) 2020 Dell Inc.
9 #include "dell-wmi-sysman.h"
11 enum int_properties
{MIN_VALUE
= 6, MAX_VALUE
, SCALAR_INCR
};
13 get_instance_id(integer
);
15 static ssize_t
current_value_show(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
17 int instance_id
= get_integer_instance_id(kobj
);
18 union acpi_object
*obj
;
24 /* need to use specific instance_id and guid combination to get right data */
25 obj
= get_wmiobj_pointer(instance_id
, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID
);
28 if (obj
->package
.elements
[CURRENT_VAL
].type
!= ACPI_TYPE_INTEGER
) {
32 ret
= snprintf(buf
, PAGE_SIZE
, "%lld\n", obj
->package
.elements
[CURRENT_VAL
].integer
.value
);
38 * validate_integer_input() - Validate input of current_value against lower and upper bound
39 * @instance_id: The instance on which input is validated
42 static int validate_integer_input(int instance_id
, char *buf
)
47 ret
= kstrtoint(buf
, 0, &in_val
);
50 if (in_val
< wmi_priv
.integer_data
[instance_id
].min_value
||
51 in_val
> wmi_priv
.integer_data
[instance_id
].max_value
)
54 /* workaround for BIOS error.
55 * validate input to avoid setting 0 when integer input passed with + sign
58 memmove(buf
, (buf
+ 1), strlen(buf
+ 1) + 1);
63 attribute_s_property_show(display_name_language_code
, integer
);
64 static struct kobj_attribute integer_displ_langcode
=
65 __ATTR_RO(display_name_language_code
);
67 attribute_s_property_show(display_name
, integer
);
68 static struct kobj_attribute integer_displ_name
=
69 __ATTR_RO(display_name
);
71 attribute_n_property_show(default_value
, integer
);
72 static struct kobj_attribute integer_default_val
=
73 __ATTR_RO(default_value
);
75 attribute_property_store(current_value
, integer
);
76 static struct kobj_attribute integer_current_val
=
77 __ATTR_RW_MODE(current_value
, 0600);
79 attribute_s_property_show(dell_modifier
, integer
);
80 static struct kobj_attribute integer_modifier
=
81 __ATTR_RO(dell_modifier
);
83 attribute_n_property_show(min_value
, integer
);
84 static struct kobj_attribute integer_lower_bound
=
87 attribute_n_property_show(max_value
, integer
);
88 static struct kobj_attribute integer_upper_bound
=
91 attribute_n_property_show(scalar_increment
, integer
);
92 static struct kobj_attribute integer_scalar_increment
=
93 __ATTR_RO(scalar_increment
);
95 static ssize_t
type_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
98 return sprintf(buf
, "integer\n");
100 static struct kobj_attribute integer_type
=
103 static struct attribute
*integer_attrs
[] = {
104 &integer_displ_langcode
.attr
,
105 &integer_displ_name
.attr
,
106 &integer_default_val
.attr
,
107 &integer_current_val
.attr
,
108 &integer_modifier
.attr
,
109 &integer_lower_bound
.attr
,
110 &integer_upper_bound
.attr
,
111 &integer_scalar_increment
.attr
,
116 static const struct attribute_group integer_attr_group
= {
117 .attrs
= integer_attrs
,
120 int alloc_int_data(void)
124 wmi_priv
.integer_instances_count
= get_instance_count(DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID
);
125 wmi_priv
.integer_data
= kcalloc(wmi_priv
.integer_instances_count
,
126 sizeof(struct integer_data
), GFP_KERNEL
);
127 if (!wmi_priv
.integer_data
) {
128 wmi_priv
.integer_instances_count
= 0;
135 * populate_int_data() - Populate all properties of an instance under integer attribute
136 * @integer_obj: ACPI object with integer data
137 * @instance_id: The instance to enumerate
138 * @attr_name_kobj: The parent kernel object
140 int populate_int_data(union acpi_object
*integer_obj
, int instance_id
,
141 struct kobject
*attr_name_kobj
)
143 wmi_priv
.integer_data
[instance_id
].attr_name_kobj
= attr_name_kobj
;
144 strlcpy_attr(wmi_priv
.integer_data
[instance_id
].attribute_name
,
145 integer_obj
[ATTR_NAME
].string
.pointer
);
146 strlcpy_attr(wmi_priv
.integer_data
[instance_id
].display_name_language_code
,
147 integer_obj
[DISPL_NAME_LANG_CODE
].string
.pointer
);
148 strlcpy_attr(wmi_priv
.integer_data
[instance_id
].display_name
,
149 integer_obj
[DISPLAY_NAME
].string
.pointer
);
150 wmi_priv
.integer_data
[instance_id
].default_value
=
151 (uintptr_t)integer_obj
[DEFAULT_VAL
].string
.pointer
;
152 strlcpy_attr(wmi_priv
.integer_data
[instance_id
].dell_modifier
,
153 integer_obj
[MODIFIER
].string
.pointer
);
154 wmi_priv
.integer_data
[instance_id
].min_value
=
155 (uintptr_t)integer_obj
[MIN_VALUE
].string
.pointer
;
156 wmi_priv
.integer_data
[instance_id
].max_value
=
157 (uintptr_t)integer_obj
[MAX_VALUE
].string
.pointer
;
158 wmi_priv
.integer_data
[instance_id
].scalar_increment
=
159 (uintptr_t)integer_obj
[SCALAR_INCR
].string
.pointer
;
161 return sysfs_create_group(attr_name_kobj
, &integer_attr_group
);
165 * exit_int_attributes() - Clear all attribute data
167 * Clears all data allocated for this group of attributes
169 void exit_int_attributes(void)
173 for (instance_id
= 0; instance_id
< wmi_priv
.integer_instances_count
; instance_id
++) {
174 if (wmi_priv
.integer_data
[instance_id
].attr_name_kobj
)
175 sysfs_remove_group(wmi_priv
.integer_data
[instance_id
].attr_name_kobj
,
176 &integer_attr_group
);
178 kfree(wmi_priv
.integer_data
);