Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI / LPAT: Common table processing functions

Since LPAT table processing is also required for other thermal drivers,
moved LPAT table related functions from intel PMIC driver (intel_pmic.c)
to a stand alonge module with exported interfaces.
In this way there will be no code duplication.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>

authored by

Srinivas Pandruvada and committed by
Zhang Rui
c55d6282 acebf7ee

+227
+1
drivers/acpi/Makefile
··· 55 55 ifdef CONFIG_ACPI_VIDEO 56 56 acpi-y += video_detect.o 57 57 endif 58 + acpi-y += acpi_lpat.o 58 59 59 60 # These are (potentially) separate modules 60 61
+161
drivers/acpi/acpi_lpat.c
··· 1 + /* 2 + * acpi_lpat.c - LPAT table processing functions 3 + * 4 + * Copyright (C) 2015 Intel Corporation. All rights reserved. 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License version 8 + * 2 as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/module.h> 17 + #include <linux/acpi.h> 18 + #include <acpi/acpi_lpat.h> 19 + 20 + /** 21 + * acpi_lpat_raw_to_temp(): Return temperature from raw value through 22 + * LPAT conversion table 23 + * 24 + * @lpat_table: the temperature_raw mapping table structure 25 + * @raw: the raw value, used as a key to get the temerature from the 26 + * above mapping table 27 + * 28 + * A positive converted temperarure value will be returned on success, 29 + * a negative errno will be returned in error cases. 30 + */ 31 + int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table *lpat_table, 32 + int raw) 33 + { 34 + int i, delta_temp, delta_raw, temp; 35 + struct acpi_lpat *lpat = lpat_table->lpat; 36 + 37 + for (i = 0; i < lpat_table->lpat_count - 1; i++) { 38 + if ((raw >= lpat[i].raw && raw <= lpat[i+1].raw) || 39 + (raw <= lpat[i].raw && raw >= lpat[i+1].raw)) 40 + break; 41 + } 42 + 43 + if (i == lpat_table->lpat_count - 1) 44 + return -ENOENT; 45 + 46 + delta_temp = lpat[i+1].temp - lpat[i].temp; 47 + delta_raw = lpat[i+1].raw - lpat[i].raw; 48 + temp = lpat[i].temp + (raw - lpat[i].raw) * delta_temp / delta_raw; 49 + 50 + return temp; 51 + } 52 + EXPORT_SYMBOL_GPL(acpi_lpat_raw_to_temp); 53 + 54 + /** 55 + * acpi_lpat_temp_to_raw(): Return raw value from temperature through 56 + * LPAT conversion table 57 + * 58 + * @lpat: the temperature_raw mapping table 59 + * @temp: the temperature, used as a key to get the raw value from the 60 + * above mapping table 61 + * 62 + * A positive converted temperature value will be returned on success, 63 + * a negative errno will be returned in error cases. 64 + */ 65 + int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table *lpat_table, 66 + int temp) 67 + { 68 + int i, delta_temp, delta_raw, raw; 69 + struct acpi_lpat *lpat = lpat_table->lpat; 70 + 71 + for (i = 0; i < lpat_table->lpat_count - 1; i++) { 72 + if (temp >= lpat[i].temp && temp <= lpat[i+1].temp) 73 + break; 74 + } 75 + 76 + if (i == lpat_table->lpat_count - 1) 77 + return -ENOENT; 78 + 79 + delta_temp = lpat[i+1].temp - lpat[i].temp; 80 + delta_raw = lpat[i+1].raw - lpat[i].raw; 81 + raw = lpat[i].raw + (temp - lpat[i].temp) * delta_raw / delta_temp; 82 + 83 + return raw; 84 + } 85 + EXPORT_SYMBOL_GPL(acpi_lpat_temp_to_raw); 86 + 87 + /** 88 + * acpi_lpat_get_conversion_table(): Parse ACPI LPAT table if present. 89 + * 90 + * @handle: Handle to acpi device 91 + * 92 + * Parse LPAT table to a struct of type acpi_lpat_table. On success 93 + * it returns a pointer to newly allocated table. This table must 94 + * be freed by the caller when finished processing, using a call to 95 + * acpi_lpat_free_conversion_table. 96 + */ 97 + struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table(acpi_handle 98 + handle) 99 + { 100 + struct acpi_lpat_conversion_table *lpat_table = NULL; 101 + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 102 + union acpi_object *obj_p, *obj_e; 103 + int *lpat, i; 104 + acpi_status status; 105 + 106 + status = acpi_evaluate_object(handle, "LPAT", NULL, &buffer); 107 + if (ACPI_FAILURE(status)) 108 + return NULL; 109 + 110 + obj_p = (union acpi_object *)buffer.pointer; 111 + if (!obj_p || (obj_p->type != ACPI_TYPE_PACKAGE) || 112 + (obj_p->package.count % 2) || (obj_p->package.count < 4)) 113 + goto out; 114 + 115 + lpat = kcalloc(obj_p->package.count, sizeof(int), GFP_KERNEL); 116 + if (!lpat) 117 + goto out; 118 + 119 + for (i = 0; i < obj_p->package.count; i++) { 120 + obj_e = &obj_p->package.elements[i]; 121 + if (obj_e->type != ACPI_TYPE_INTEGER) { 122 + kfree(lpat); 123 + goto out; 124 + } 125 + lpat[i] = (s64)obj_e->integer.value; 126 + } 127 + 128 + lpat_table = kzalloc(sizeof(*lpat_table), GFP_KERNEL); 129 + if (!lpat_table) { 130 + kfree(lpat); 131 + goto out; 132 + } 133 + 134 + lpat_table->lpat = (struct acpi_lpat *)lpat; 135 + lpat_table->lpat_count = obj_p->package.count / 2; 136 + 137 + out: 138 + kfree(buffer.pointer); 139 + return lpat_table; 140 + } 141 + EXPORT_SYMBOL_GPL(acpi_lpat_get_conversion_table); 142 + 143 + /** 144 + * acpi_lpat_free_conversion_table(): Free LPAT table. 145 + * 146 + * @lpat_table: the temperature_raw mapping table structure 147 + * 148 + * Frees the LPAT table previously allocated by a call to 149 + * acpi_lpat_get_conversion_table. 150 + */ 151 + void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table 152 + *lpat_table) 153 + { 154 + if (lpat_table) { 155 + kfree(lpat_table->lpat); 156 + kfree(lpat_table); 157 + } 158 + } 159 + EXPORT_SYMBOL_GPL(acpi_lpat_free_conversion_table); 160 + 161 + MODULE_LICENSE("GPL");
+65
include/acpi/acpi_lpat.h
··· 1 + /* 2 + * acpi_lpat.h - LPAT table processing functions 3 + * 4 + * Copyright (C) 2015 Intel Corporation. All rights reserved. 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License version 8 + * 2 as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #ifndef ACPI_LPAT_H 17 + #define ACPI_LPAT_H 18 + 19 + struct acpi_lpat { 20 + int temp; 21 + int raw; 22 + }; 23 + 24 + struct acpi_lpat_conversion_table { 25 + struct acpi_lpat *lpat; 26 + int lpat_count; 27 + }; 28 + 29 + #ifdef CONFIG_ACPI 30 + 31 + int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table *lpat_table, 32 + int raw); 33 + int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table *lpat_table, 34 + int temp); 35 + struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table(acpi_handle 36 + handle); 37 + void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table 38 + *lpat_table); 39 + 40 + #else 41 + static int acpi_lpat_raw_to_temp(struct acpi_lpat_conversion_table *lpat_table, 42 + int raw) 43 + { 44 + return 0; 45 + } 46 + 47 + static int acpi_lpat_temp_to_raw(struct acpi_lpat_conversion_table *lpat_table, 48 + int temp) 49 + { 50 + return 0; 51 + } 52 + 53 + static struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table( 54 + acpi_handle handle) 55 + { 56 + return NULL; 57 + } 58 + 59 + static void acpi_lpat_free_conversion_table(struct acpi_lpat_conversion_table 60 + *lpat_table) 61 + { 62 + } 63 + 64 + #endif 65 + #endif