/** * get_int_value: Retrieve integer values from ACPI Object * @obj: acpi_object pointer which has the integer value * @out: output pointer will get integer value * * Function is used to retrieve integer value from acpi object. * * Return: * * 0 on success * * -EIO if there is an issue in acpi_object passed.
*/ staticint get_int_value(union acpi_object *obj, int *out)
{ if (!obj || obj->type != ACPI_TYPE_INTEGER) return -EIO;
*out = (int)obj->integer.value; return 0;
}
/** * update_sar_data: sar data is updated based on regulatory mode * @context: pointer to driver context structure * * sar_data is updated based on regulatory value * context->reg_value will never exceed MAX_REGULATORY
*/ staticvoid update_sar_data(struct wwan_sar_context *context)
{ struct wwan_device_mode_configuration *config =
&context->config_data[context->reg_value];
if (config->device_mode_info &&
context->sar_data.device_mode < config->total_dev_mode) { int itr = 0;
for (itr = 0; itr < config->total_dev_mode; itr++) { if (context->sar_data.device_mode ==
config->device_mode_info[itr].device_mode) { struct wwan_device_mode_info *dev_mode =
&config->device_mode_info[itr];
/** * parse_package: parse acpi package for retrieving SAR information * @context: pointer to driver context structure * @item : acpi_object pointer * * Given acpi_object is iterated to retrieve information for each device mode. * If a given package corresponding to a specific device mode is faulty, it is * skipped and the specific entry in context structure will have the default value * of zero. Decoding of subsequent device modes is realized by having "continue" * statements in the for loop on encountering error in parsing given device mode. * * Return: * AE_OK if success * AE_ERROR on error
*/ static acpi_status parse_package(struct wwan_sar_context *context, union acpi_object *item)
{ struct wwan_device_mode_configuration *data; int value, itr, reg; union acpi_object *num;
num = &item->package.elements[0]; if (get_int_value(num, &value) || value < 0 || value >= MAX_REGULATORY) return AE_ERROR;
reg = value;
data = &context->config_data[reg]; if (data->total_dev_mode > MAX_DEV_MODES || data->total_dev_mode == 0 ||
item->package.count <= data->total_dev_mode) return AE_ERROR;
data->device_mode_info = kmalloc_array(data->total_dev_mode, sizeof(struct wwan_device_mode_info), GFP_KERNEL); if (!data->device_mode_info) return AE_ERROR;
num = &item->package.elements[itr + 1]; if (num->type != ACPI_TYPE_PACKAGE || num->package.count < TOTAL_DATA) continue; if (get_int_value(&num->package.elements[0], &temp.device_mode)) continue; if (get_int_value(&num->package.elements[1], &temp.bandtable_index)) continue; if (get_int_value(&num->package.elements[2], &temp.antennatable_index)) continue; if (get_int_value(&num->package.elements[3], &temp.sartable_index)) continue;
data->device_mode_info[itr] = temp;
} return AE_OK;
}
/** * sar_get_device_mode: Extraction of information from BIOS via DSM calls * @device: ACPI device for which to retrieve the data * * Retrieve the current device mode information from the BIOS. * * Return: * AE_OK on success * AE_ERROR on error
*/ static acpi_status sar_get_device_mode(struct platform_device *device)
{ struct wwan_sar_context *context = dev_get_drvdata(&device->dev);
acpi_status status = AE_OK; union acpi_object *out;
u32 rev = 0;
out = acpi_evaluate_dsm_typed(context->handle, &context->guid, rev,
COMMAND_ID_DEV_MODE, NULL, ACPI_TYPE_INTEGER); if (!out) {
dev_err(&device->dev, "DSM cmd:%d Failed to retrieve value\n", COMMAND_ID_DEV_MODE);
status = AE_ERROR; goto dev_mode_error;
}
context->sar_data.device_mode = out->integer.value;
update_sar_data(context);
sysfs_notify(&device->dev.kobj, NULL, SYSFS_DATANAME);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.