Skip to content

Commit 273b5a4

Browse files
committed
Merge branch 'acpi-pmic'
* acpi-pmic: ACPI / PMIC: remove modular references from non-modular code ACPI / PMIC: intel: initialize result to 0 ACPI / PMIC: intel: add REGS operation region support ACPI / PMIC: Add opregion driver for Intel BXT WhiskeyCove PMIC ACPI / PMIC: modify the pen function signature to take bit field Conflicts: drivers/acpi/Makefile
2 parents 6149dff + 6d3ef8d commit 273b5a4

File tree

7 files changed

+509
-19
lines changed

7 files changed

+509
-19
lines changed

drivers/acpi/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ config XPOWER_PMIC_OPREGION
526526
help
527527
This config adds ACPI operation region support for XPower AXP288 PMIC.
528528

529+
config BXT_WC_PMIC_OPREGION
530+
bool "ACPI operation region support for BXT WhiskeyCove PMIC"
531+
depends on INTEL_SOC_PMIC
532+
help
533+
This config adds ACPI operation region support for BXT WhiskeyCove PMIC.
534+
529535
endif
530536

531537
config ACPI_CONFIGFS

drivers/acpi/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o
9999
obj-$(CONFIG_PMIC_OPREGION) += pmic/intel_pmic.o
100100
obj-$(CONFIG_CRC_PMIC_OPREGION) += pmic/intel_pmic_crc.o
101101
obj-$(CONFIG_XPOWER_PMIC_OPREGION) += pmic/intel_pmic_xpower.o
102+
obj-$(CONFIG_BXT_WC_PMIC_OPREGION) += pmic/intel_pmic_bxtwc.o
103+
102104
obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o
103105

104106
video-objs += acpi_video.o video_detect.o

drivers/acpi/pmic/intel_pmic.c

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,27 @@
1313
* GNU General Public License for more details.
1414
*/
1515

16-
#include <linux/module.h>
16+
#include <linux/export.h>
1717
#include <linux/acpi.h>
1818
#include <linux/regmap.h>
1919
#include <acpi/acpi_lpat.h>
2020
#include "intel_pmic.h"
2121

2222
#define PMIC_POWER_OPREGION_ID 0x8d
2323
#define PMIC_THERMAL_OPREGION_ID 0x8c
24+
#define PMIC_REGS_OPREGION_ID 0x8f
25+
26+
struct intel_pmic_regs_handler_ctx {
27+
unsigned int val;
28+
u16 addr;
29+
};
2430

2531
struct intel_pmic_opregion {
2632
struct mutex lock;
2733
struct acpi_lpat_conversion_table *lpat_table;
2834
struct regmap *regmap;
2935
struct intel_pmic_opregion_data *data;
36+
struct intel_pmic_regs_handler_ctx ctx;
3037
};
3138

3239
static int pmic_get_reg_bit(int address, struct pmic_table *table,
@@ -131,7 +138,7 @@ static int pmic_thermal_aux(struct intel_pmic_opregion *opregion, int reg,
131138
}
132139

133140
static int pmic_thermal_pen(struct intel_pmic_opregion *opregion, int reg,
134-
u32 function, u64 *value)
141+
int bit, u32 function, u64 *value)
135142
{
136143
struct intel_pmic_opregion_data *d = opregion->data;
137144
struct regmap *regmap = opregion->regmap;
@@ -140,12 +147,12 @@ static int pmic_thermal_pen(struct intel_pmic_opregion *opregion, int reg,
140147
return -ENXIO;
141148

142149
if (function == ACPI_READ)
143-
return d->get_policy(regmap, reg, value);
150+
return d->get_policy(regmap, reg, bit, value);
144151

145152
if (*value != 0 && *value != 1)
146153
return -EINVAL;
147154

148-
return d->update_policy(regmap, reg, *value);
155+
return d->update_policy(regmap, reg, bit, *value);
149156
}
150157

151158
static bool pmic_thermal_is_temp(int address)
@@ -170,13 +177,13 @@ static acpi_status intel_pmic_thermal_handler(u32 function,
170177
{
171178
struct intel_pmic_opregion *opregion = region_context;
172179
struct intel_pmic_opregion_data *d = opregion->data;
173-
int reg, result;
180+
int reg, bit, result;
174181

175182
if (bits != 32 || !value64)
176183
return AE_BAD_PARAMETER;
177184

178185
result = pmic_get_reg_bit(address, d->thermal_table,
179-
d->thermal_table_count, &reg, NULL);
186+
d->thermal_table_count, &reg, &bit);
180187
if (result == -ENOENT)
181188
return AE_BAD_PARAMETER;
182189

@@ -187,7 +194,8 @@ static acpi_status intel_pmic_thermal_handler(u32 function,
187194
else if (pmic_thermal_is_aux(address))
188195
result = pmic_thermal_aux(opregion, reg, function, value64);
189196
else if (pmic_thermal_is_pen(address))
190-
result = pmic_thermal_pen(opregion, reg, function, value64);
197+
result = pmic_thermal_pen(opregion, reg, bit,
198+
function, value64);
191199
else
192200
result = -EINVAL;
193201

@@ -203,6 +211,48 @@ static acpi_status intel_pmic_thermal_handler(u32 function,
203211
return AE_OK;
204212
}
205213

214+
static acpi_status intel_pmic_regs_handler(u32 function,
215+
acpi_physical_address address, u32 bits, u64 *value64,
216+
void *handler_context, void *region_context)
217+
{
218+
struct intel_pmic_opregion *opregion = region_context;
219+
int result = 0;
220+
221+
switch (address) {
222+
case 0:
223+
return AE_OK;
224+
case 1:
225+
opregion->ctx.addr |= (*value64 & 0xff) << 8;
226+
return AE_OK;
227+
case 2:
228+
opregion->ctx.addr |= *value64 & 0xff;
229+
return AE_OK;
230+
case 3:
231+
opregion->ctx.val = *value64 & 0xff;
232+
return AE_OK;
233+
case 4:
234+
if (*value64) {
235+
result = regmap_write(opregion->regmap, opregion->ctx.addr,
236+
opregion->ctx.val);
237+
} else {
238+
result = regmap_read(opregion->regmap, opregion->ctx.addr,
239+
&opregion->ctx.val);
240+
if (result == 0)
241+
*value64 = opregion->ctx.val;
242+
}
243+
memset(&opregion->ctx, 0x00, sizeof(opregion->ctx));
244+
}
245+
246+
if (result < 0) {
247+
if (result == -EINVAL)
248+
return AE_BAD_PARAMETER;
249+
else
250+
return AE_ERROR;
251+
}
252+
253+
return AE_OK;
254+
}
255+
206256
int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle,
207257
struct regmap *regmap,
208258
struct intel_pmic_opregion_data *d)
@@ -242,16 +292,30 @@ int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle,
242292
acpi_remove_address_space_handler(handle, PMIC_POWER_OPREGION_ID,
243293
intel_pmic_power_handler);
244294
ret = -ENODEV;
245-
goto out_error;
295+
goto out_remove_power_handler;
296+
}
297+
298+
status = acpi_install_address_space_handler(handle,
299+
PMIC_REGS_OPREGION_ID, intel_pmic_regs_handler, NULL,
300+
opregion);
301+
if (ACPI_FAILURE(status)) {
302+
ret = -ENODEV;
303+
goto out_remove_thermal_handler;
246304
}
247305

248306
opregion->data = d;
249307
return 0;
250308

309+
out_remove_thermal_handler:
310+
acpi_remove_address_space_handler(handle, PMIC_THERMAL_OPREGION_ID,
311+
intel_pmic_thermal_handler);
312+
313+
out_remove_power_handler:
314+
acpi_remove_address_space_handler(handle, PMIC_POWER_OPREGION_ID,
315+
intel_pmic_power_handler);
316+
251317
out_error:
252318
acpi_lpat_free_conversion_table(opregion->lpat_table);
253319
return ret;
254320
}
255321
EXPORT_SYMBOL_GPL(intel_pmic_install_opregion_handler);
256-
257-
MODULE_LICENSE("GPL");

drivers/acpi/pmic/intel_pmic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ struct intel_pmic_opregion_data {
1212
int (*update_power)(struct regmap *r, int reg, int bit, bool on);
1313
int (*get_raw_temp)(struct regmap *r, int reg);
1414
int (*update_aux)(struct regmap *r, int reg, int raw_temp);
15-
int (*get_policy)(struct regmap *r, int reg, u64 *value);
16-
int (*update_policy)(struct regmap *r, int reg, int enable);
15+
int (*get_policy)(struct regmap *r, int reg, int bit, u64 *value);
16+
int (*update_policy)(struct regmap *r, int reg, int bit, int enable);
1717
struct pmic_table *power_table;
1818
int power_table_count;
1919
struct pmic_table *thermal_table;

0 commit comments

Comments
 (0)