forked from mirrors/linux
Merge branch 'fixes' into for-next
Resolve conflicts in dell/alienware-wmi-wmax and asus-wmi, and enable applying a few amd/hsmp patches that depend on changes in the fixes branch.
This commit is contained in:
commit
593ee93aa7
25 changed files with 384 additions and 131 deletions
|
|
@ -138,6 +138,10 @@ input data, the meaning of which depends on the subfeature being accessed.
|
|||
The output buffer contains a single byte which signals success or failure (``0x00`` on failure)
|
||||
and 31 bytes of output data, the meaning if which depends on the subfeature being accessed.
|
||||
|
||||
.. note::
|
||||
The ACPI control method responsible for handling the WMI method calls is not thread-safe.
|
||||
This is a firmware bug that needs to be handled inside the driver itself.
|
||||
|
||||
WMI method Get_EC()
|
||||
-------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -333,9 +333,9 @@ static ssize_t secure_boot_fuse_state_show(struct device *dev,
|
|||
else
|
||||
status = valid ? "Invalid" : "Free";
|
||||
}
|
||||
buf_len += sysfs_emit(buf + buf_len, "%d:%s ", key, status);
|
||||
buf_len += sysfs_emit_at(buf, buf_len, "%d:%s ", key, status);
|
||||
}
|
||||
buf_len += sysfs_emit(buf + buf_len, "\n");
|
||||
buf_len += sysfs_emit_at(buf, buf_len, "\n");
|
||||
|
||||
return buf_len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@
|
|||
|
||||
#include "hsmp.h"
|
||||
|
||||
#define DRIVER_NAME "amd_hsmp"
|
||||
#define DRIVER_NAME "hsmp_acpi"
|
||||
#define DRIVER_VERSION "2.3"
|
||||
#define ACPI_HSMP_DEVICE_HID "AMDI0097"
|
||||
|
||||
/* These are the strings specified in ACPI table */
|
||||
#define MSG_IDOFF_STR "MsgIdOffset"
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#define HSMP_CDEV_NAME "hsmp_cdev"
|
||||
#define HSMP_DEVNODE_NAME "hsmp"
|
||||
#define ACPI_HSMP_DEVICE_HID "AMDI0097"
|
||||
|
||||
struct hsmp_mbaddr_info {
|
||||
u32 base_addr;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <asm/amd_hsmp.h>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
|
|
@ -266,7 +267,7 @@ static bool legacy_hsmp_support(void)
|
|||
}
|
||||
case 0x1A:
|
||||
switch (boot_cpu_data.x86_model) {
|
||||
case 0x00 ... 0x1F:
|
||||
case 0x00 ... 0x0F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
@ -288,6 +289,9 @@ static int __init hsmp_plt_init(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (acpi_dev_present(ACPI_HSMP_DEVICE_HID, NULL, -1))
|
||||
return -ENODEV;
|
||||
|
||||
hsmp_pdev = get_hsmp_pdev();
|
||||
if (!hsmp_pdev)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -217,6 +217,13 @@ static const struct dmi_system_id fwbug_list[] = {
|
|||
DMI_MATCH(DMI_BIOS_VERSION, "03.05"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.ident = "MECHREVO Wujie 14X (GX4HRXL)",
|
||||
.driver_data = &quirk_spurious_8042,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "WUJIE14-GX4HRXL"),
|
||||
}
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -644,10 +644,9 @@ static void amd_pmc_s2idle_check(void)
|
|||
struct smu_metrics table;
|
||||
int rc;
|
||||
|
||||
/* CZN: Ensure that future s0i3 entry attempts at least 10ms passed */
|
||||
if (pdev->cpu_id == AMD_CPU_ID_CZN && !get_metrics_table(pdev, &table) &&
|
||||
table.s0i3_last_entry_status)
|
||||
usleep_range(10000, 20000);
|
||||
/* Avoid triggering OVP */
|
||||
if (!get_metrics_table(pdev, &table) && table.s0i3_last_entry_status)
|
||||
msleep(2500);
|
||||
|
||||
/* Dump the IdleMask before we add to the STB */
|
||||
amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ static void amd_pmf_set_automode(struct amd_pmf_dev *dev, int idx,
|
|||
amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pwr_ctrl->sppt_apu_only, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pwr_ctrl->stt_min, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
|
||||
pwr_ctrl->stt_skin_temp[STT_TEMP_APU], NULL);
|
||||
fixp_q88_fromint(pwr_ctrl->stt_skin_temp[STT_TEMP_APU]), NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
|
||||
pwr_ctrl->stt_skin_temp[STT_TEMP_HS2], NULL);
|
||||
fixp_q88_fromint(pwr_ctrl->stt_skin_temp[STT_TEMP_HS2]), NULL);
|
||||
|
||||
if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
|
||||
apmf_update_fan_idx(dev, config_store.mode_set[idx].fan_control.manual,
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ static int amd_pmf_set_cnqf(struct amd_pmf_dev *dev, int src, int idx,
|
|||
amd_pmf_send_cmd(dev, SET_SPPT, false, pc->sppt, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pc->sppt_apu_only, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pc->stt_min, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, pc->stt_skin_temp[STT_TEMP_APU],
|
||||
NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, pc->stt_skin_temp[STT_TEMP_HS2],
|
||||
NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
|
||||
fixp_q88_fromint(pc->stt_skin_temp[STT_TEMP_APU]), NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
|
||||
fixp_q88_fromint(pc->stt_skin_temp[STT_TEMP_HS2]), NULL);
|
||||
|
||||
if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
|
||||
apmf_update_fan_idx(dev,
|
||||
|
|
|
|||
|
|
@ -176,6 +176,20 @@ static void __maybe_unused amd_pmf_dump_registers(struct amd_pmf_dev *dev)
|
|||
dev_dbg(dev->dev, "AMD_PMF_REGISTER_MESSAGE:%x\n", value);
|
||||
}
|
||||
|
||||
/**
|
||||
* fixp_q88_fromint: Convert integer to Q8.8
|
||||
* @val: input value
|
||||
*
|
||||
* Converts an integer into binary fixed point format where 8 bits
|
||||
* are used for integer and 8 bits are used for the decimal.
|
||||
*
|
||||
* Return: unsigned integer converted to Q8.8 format
|
||||
*/
|
||||
u32 fixp_q88_fromint(u32 val)
|
||||
{
|
||||
return val << 8;
|
||||
}
|
||||
|
||||
int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data)
|
||||
{
|
||||
int rc;
|
||||
|
|
|
|||
|
|
@ -777,6 +777,7 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev);
|
|||
int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
|
||||
int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer);
|
||||
int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag);
|
||||
u32 fixp_q88_fromint(u32 val);
|
||||
|
||||
/* SPS Layer */
|
||||
int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);
|
||||
|
|
|
|||
|
|
@ -198,9 +198,11 @@ static void amd_pmf_update_slider_v2(struct amd_pmf_dev *dev, int idx)
|
|||
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,
|
||||
apts_config_store.val[idx].stt_min_limit, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
|
||||
apts_config_store.val[idx].stt_skin_temp_limit_apu, NULL);
|
||||
fixp_q88_fromint(apts_config_store.val[idx].stt_skin_temp_limit_apu),
|
||||
NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
|
||||
apts_config_store.val[idx].stt_skin_temp_limit_hs2, NULL);
|
||||
fixp_q88_fromint(apts_config_store.val[idx].stt_skin_temp_limit_hs2),
|
||||
NULL);
|
||||
}
|
||||
|
||||
void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,
|
||||
|
|
@ -217,9 +219,11 @@ void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,
|
|||
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,
|
||||
config_store.prop[src][idx].stt_min, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
|
||||
config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU], NULL);
|
||||
fixp_q88_fromint(config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU]),
|
||||
NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
|
||||
config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2], NULL);
|
||||
fixp_q88_fromint(config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2]),
|
||||
NULL);
|
||||
} else if (op == SLIDER_OP_GET) {
|
||||
amd_pmf_send_cmd(dev, GET_SPL, true, ARG_NONE, &table->prop[src][idx].spl);
|
||||
amd_pmf_send_cmd(dev, GET_FPPT, true, ARG_NONE, &table->prop[src][idx].fppt);
|
||||
|
|
|
|||
|
|
@ -123,7 +123,8 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_
|
|||
|
||||
case PMF_POLICY_STT_SKINTEMP_APU:
|
||||
if (dev->prev_data->stt_skintemp_apu != val) {
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, val, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
|
||||
fixp_q88_fromint(val), NULL);
|
||||
dev_dbg(dev->dev, "update STT_SKINTEMP_APU: %u\n", val);
|
||||
dev->prev_data->stt_skintemp_apu = val;
|
||||
}
|
||||
|
|
@ -131,7 +132,8 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_
|
|||
|
||||
case PMF_POLICY_STT_SKINTEMP_HS2:
|
||||
if (dev->prev_data->stt_skintemp_hs2 != val) {
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, val, NULL);
|
||||
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
|
||||
fixp_q88_fromint(val), NULL);
|
||||
dev_dbg(dev->dev, "update STT_SKINTEMP_HS2: %u\n", val);
|
||||
dev->prev_data->stt_skintemp_hs2 = val;
|
||||
}
|
||||
|
|
@ -332,6 +334,11 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool amd_pmf_pb_valid(struct amd_pmf_dev *dev)
|
||||
{
|
||||
return memchr_inv(dev->policy_buf, 0xff, dev->policy_sz);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AMD_PMF_DEBUG
|
||||
static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev)
|
||||
{
|
||||
|
|
@ -359,12 +366,22 @@ static ssize_t amd_pmf_get_pb_data(struct file *filp, const char __user *buf,
|
|||
dev->policy_buf = new_policy_buf;
|
||||
dev->policy_sz = length;
|
||||
|
||||
if (!amd_pmf_pb_valid(dev)) {
|
||||
ret = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
amd_pmf_hex_dump_pb(dev);
|
||||
ret = amd_pmf_start_policy_engine(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto cleanup;
|
||||
|
||||
return length;
|
||||
|
||||
cleanup:
|
||||
kfree(dev->policy_buf);
|
||||
dev->policy_buf = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations pb_fops = {
|
||||
|
|
@ -526,6 +543,12 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
|
|||
|
||||
memcpy_fromio(dev->policy_buf, dev->policy_base, dev->policy_sz);
|
||||
|
||||
if (!amd_pmf_pb_valid(dev)) {
|
||||
dev_info(dev->dev, "No Smart PC policy present\n");
|
||||
ret = -EINVAL;
|
||||
goto err_free_policy;
|
||||
}
|
||||
|
||||
amd_pmf_hex_dump_pb(dev);
|
||||
|
||||
dev->prev_data = kzalloc(sizeof(*dev->prev_data), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -426,11 +426,14 @@ static int asus_pega_lucid_set(struct asus_laptop *asus, int unit, bool enable)
|
|||
|
||||
static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
|
||||
{
|
||||
unsigned long long val = (unsigned long long)curr;
|
||||
acpi_status status;
|
||||
int i, delta;
|
||||
unsigned long long val;
|
||||
for (i = 0; i < PEGA_ACC_RETRIES; i++) {
|
||||
acpi_evaluate_integer(asus->handle, method, NULL, &val);
|
||||
|
||||
for (i = 0; i < PEGA_ACC_RETRIES; i++) {
|
||||
status = acpi_evaluate_integer(asus->handle, method, NULL, &val);
|
||||
if (ACPI_FAILURE(status))
|
||||
continue;
|
||||
/* The output is noisy. From reading the ASL
|
||||
* dissassembly, timeout errors are returned with 1's
|
||||
* in the high word, and the lack of locking around
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ struct asus_wmi {
|
|||
|
||||
u32 kbd_rgb_dev;
|
||||
bool kbd_rgb_state_available;
|
||||
bool oobe_state_available;
|
||||
|
||||
u8 throttle_thermal_policy_mode;
|
||||
u32 throttle_thermal_policy_dev;
|
||||
|
|
@ -1868,7 +1869,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE)) {
|
||||
if (asus->oobe_state_available) {
|
||||
/*
|
||||
* Disable OOBE state, so that e.g. the keyboard backlight
|
||||
* works.
|
||||
|
|
@ -4780,6 +4781,7 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||
asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
|
||||
asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
|
||||
asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
|
||||
asus->oobe_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_OOBE);
|
||||
|
||||
if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE))
|
||||
asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE;
|
||||
|
|
@ -4832,7 +4834,8 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||
goto fail_leds;
|
||||
|
||||
asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
|
||||
if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
|
||||
if ((result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) ==
|
||||
(ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
|
||||
asus->driver->wlan_ctrl_by_user = 1;
|
||||
|
||||
if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) {
|
||||
|
|
@ -4997,6 +5000,13 @@ static int asus_hotk_restore(struct device *device)
|
|||
}
|
||||
if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
|
||||
kbd_led_update(asus);
|
||||
if (asus->oobe_state_available) {
|
||||
/*
|
||||
* Disable OOBE state, so that e.g. the keyboard backlight
|
||||
* works.
|
||||
*/
|
||||
asus_wmi_set_devstate(ASUS_WMI_DEVID_OOBE, 1, NULL);
|
||||
}
|
||||
|
||||
if (asus_wmi_has_fnlock_key(asus))
|
||||
asus_wmi_fnlock_update(asus);
|
||||
|
|
|
|||
|
|
@ -89,12 +89,44 @@ static struct awcc_quirks generic_quirks = {
|
|||
static struct awcc_quirks empty_quirks;
|
||||
|
||||
static const struct dmi_system_id awcc_dmi_table[] __initconst = {
|
||||
{
|
||||
.ident = "Alienware Area-51m R2",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware Area-51m R2"),
|
||||
},
|
||||
.driver_data = &generic_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Alienware m15 R7",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m15 R7"),
|
||||
},
|
||||
.driver_data = &generic_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Alienware m16 R1",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1"),
|
||||
},
|
||||
.driver_data = &g_series_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Alienware m16 R1 AMD",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),
|
||||
},
|
||||
.driver_data = &g_series_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Alienware m16 R2",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R2"),
|
||||
},
|
||||
.driver_data = &generic_quirks,
|
||||
},
|
||||
{
|
||||
|
|
@ -121,6 +153,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {
|
|||
},
|
||||
.driver_data = &generic_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Alienware x15 R2",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R2"),
|
||||
},
|
||||
.driver_data = &generic_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Alienware x17 R2",
|
||||
.matches = {
|
||||
|
|
@ -153,6 +193,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {
|
|||
},
|
||||
.driver_data = &g_series_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Dell Inc. G16 7630",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Dell G16 7630"),
|
||||
},
|
||||
.driver_data = &g_series_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Dell Inc. G3 3500",
|
||||
.matches = {
|
||||
|
|
@ -177,6 +225,14 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = {
|
|||
},
|
||||
.driver_data = &g_series_quirks,
|
||||
},
|
||||
{
|
||||
.ident = "Dell Inc. G5 5505",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "G5 5505"),
|
||||
},
|
||||
.driver_data = &g_series_quirks,
|
||||
},
|
||||
};
|
||||
|
||||
enum AWCC_GET_FAN_SENSORS_OPERATIONS {
|
||||
|
|
@ -1241,14 +1297,14 @@ static int awcc_platform_profile_probe(void *drvdata, unsigned long *choices)
|
|||
|
||||
for (unsigned int i = 0; i < priv->profile_count; i++) {
|
||||
ret = awcc_op_get_resource_id(priv->wdev, i + offset, &id);
|
||||
if (ret == -EIO)
|
||||
return ret;
|
||||
/*
|
||||
* Some devices report an incorrect number of thermal profiles
|
||||
* so the resource ID list may end prematurely
|
||||
*/
|
||||
if (ret == -EBADRQC)
|
||||
break;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!is_awcc_thermal_profile_id(id)) {
|
||||
dev_dbg(&priv->wdev->dev, "Unmapped thermal profile ID 0x%02x\n", id);
|
||||
|
|
|
|||
|
|
@ -1294,6 +1294,16 @@ static const struct key_entry ideapad_keymap[] = {
|
|||
/* Specific to some newer models */
|
||||
{ KE_KEY, 0x3e | IDEAPAD_WMI_KEY, { KEY_MICMUTE } },
|
||||
{ KE_KEY, 0x3f | IDEAPAD_WMI_KEY, { KEY_RFKILL } },
|
||||
/* Star- (User Assignable Key) */
|
||||
{ KE_KEY, 0x44 | IDEAPAD_WMI_KEY, { KEY_PROG1 } },
|
||||
/* Eye */
|
||||
{ KE_KEY, 0x45 | IDEAPAD_WMI_KEY, { KEY_PROG3 } },
|
||||
/* Performance toggle also Fn+Q, handled inside ideapad_wmi_notify() */
|
||||
{ KE_KEY, 0x3d | IDEAPAD_WMI_KEY, { KEY_PROG4 } },
|
||||
/* shift + prtsc */
|
||||
{ KE_KEY, 0x2d | IDEAPAD_WMI_KEY, { KEY_CUT } },
|
||||
{ KE_KEY, 0x29 | IDEAPAD_WMI_KEY, { KEY_TOUCHPAD_TOGGLE } },
|
||||
{ KE_KEY, 0x2a | IDEAPAD_WMI_KEY, { KEY_ROOT_MENU } },
|
||||
|
||||
{ KE_END },
|
||||
};
|
||||
|
|
@ -2080,6 +2090,12 @@ static void ideapad_wmi_notify(struct wmi_device *wdev, union acpi_object *data)
|
|||
dev_dbg(&wdev->dev, "WMI fn-key event: 0x%llx\n",
|
||||
data->integer.value);
|
||||
|
||||
/* performance button triggered by 0x3d */
|
||||
if (data->integer.value == 0x3d && priv->dytc) {
|
||||
platform_profile_cycle();
|
||||
break;
|
||||
}
|
||||
|
||||
/* 0x02 FnLock, 0x03 Esc */
|
||||
if (data->integer.value == 0x02 || data->integer.value == 0x03)
|
||||
ideapad_fn_lock_led_notify(priv, data->integer.value == 0x02);
|
||||
|
|
|
|||
|
|
@ -44,16 +44,17 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_AUTHOR("Alex Hung");
|
||||
|
||||
static const struct acpi_device_id intel_hid_ids[] = {
|
||||
{"INT33D5", 0},
|
||||
{"INTC1051", 0},
|
||||
{"INTC1054", 0},
|
||||
{"INTC1070", 0},
|
||||
{"INTC1076", 0},
|
||||
{"INTC1077", 0},
|
||||
{"INTC1078", 0},
|
||||
{"INTC107B", 0},
|
||||
{"INTC10CB", 0},
|
||||
{"", 0},
|
||||
{ "INT33D5" },
|
||||
{ "INTC1051" },
|
||||
{ "INTC1054" },
|
||||
{ "INTC1070" },
|
||||
{ "INTC1076" },
|
||||
{ "INTC1077" },
|
||||
{ "INTC1078" },
|
||||
{ "INTC107B" },
|
||||
{ "INTC10CB" },
|
||||
{ "INTC10CC" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
|
||||
|
||||
|
|
|
|||
|
|
@ -146,15 +146,13 @@ static int uncore_event_cpu_online(unsigned int cpu)
|
|||
{
|
||||
struct uncore_data *data;
|
||||
int target;
|
||||
int ret;
|
||||
|
||||
/* Check if there is an online cpu in the package for uncore MSR */
|
||||
target = cpumask_any_and(&uncore_cpu_mask, topology_die_cpumask(cpu));
|
||||
if (target < nr_cpu_ids)
|
||||
return 0;
|
||||
|
||||
/* Use this CPU on this die as a control CPU */
|
||||
cpumask_set_cpu(cpu, &uncore_cpu_mask);
|
||||
|
||||
data = uncore_get_instance(cpu);
|
||||
if (!data)
|
||||
return 0;
|
||||
|
|
@ -163,7 +161,14 @@ static int uncore_event_cpu_online(unsigned int cpu)
|
|||
data->die_id = topology_die_id(cpu);
|
||||
data->domain_id = UNCORE_DOMAIN_ID_INVALID;
|
||||
|
||||
return uncore_freq_add_entry(data, cpu);
|
||||
ret = uncore_freq_add_entry(data, cpu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Use this CPU on this die as a control CPU */
|
||||
cpumask_set_cpu(cpu, &uncore_cpu_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uncore_event_cpu_offline(unsigned int cpu)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/device/driver.h>
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
#include <linux/hwmon.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/types.h>
|
||||
|
|
@ -76,8 +78,13 @@ enum msi_wmi_platform_method {
|
|||
MSI_PLATFORM_GET_WMI = 0x1d,
|
||||
};
|
||||
|
||||
struct msi_wmi_platform_debugfs_data {
|
||||
struct msi_wmi_platform_data {
|
||||
struct wmi_device *wdev;
|
||||
struct mutex wmi_lock; /* Necessary when calling WMI methods */
|
||||
};
|
||||
|
||||
struct msi_wmi_platform_debugfs_data {
|
||||
struct msi_wmi_platform_data *data;
|
||||
enum msi_wmi_platform_method method;
|
||||
struct rw_semaphore buffer_lock; /* Protects debugfs buffer */
|
||||
size_t length;
|
||||
|
|
@ -132,8 +139,9 @@ static int msi_wmi_platform_parse_buffer(union acpi_object *obj, u8 *output, siz
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int msi_wmi_platform_query(struct wmi_device *wdev, enum msi_wmi_platform_method method,
|
||||
u8 *input, size_t input_length, u8 *output, size_t output_length)
|
||||
static int msi_wmi_platform_query(struct msi_wmi_platform_data *data,
|
||||
enum msi_wmi_platform_method method, u8 *input,
|
||||
size_t input_length, u8 *output, size_t output_length)
|
||||
{
|
||||
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
struct acpi_buffer in = {
|
||||
|
|
@ -147,9 +155,15 @@ static int msi_wmi_platform_query(struct wmi_device *wdev, enum msi_wmi_platform
|
|||
if (!input_length || !output_length)
|
||||
return -EINVAL;
|
||||
|
||||
status = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
/*
|
||||
* The ACPI control method responsible for handling the WMI method calls
|
||||
* is not thread-safe. Because of this we have to do the locking ourself.
|
||||
*/
|
||||
scoped_guard(mutex, &data->wmi_lock) {
|
||||
status = wmidev_evaluate_method(data->wdev, 0x0, method, &in, &out);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
obj = out.pointer;
|
||||
if (!obj)
|
||||
|
|
@ -170,22 +184,22 @@ static umode_t msi_wmi_platform_is_visible(const void *drvdata, enum hwmon_senso
|
|||
static int msi_wmi_platform_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
|
||||
int channel, long *val)
|
||||
{
|
||||
struct wmi_device *wdev = dev_get_drvdata(dev);
|
||||
struct msi_wmi_platform_data *data = dev_get_drvdata(dev);
|
||||
u8 input[32] = { 0 };
|
||||
u8 output[32];
|
||||
u16 data;
|
||||
u16 value;
|
||||
int ret;
|
||||
|
||||
ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_FAN, input, sizeof(input), output,
|
||||
ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_FAN, input, sizeof(input), output,
|
||||
sizeof(output));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data = get_unaligned_be16(&output[channel * 2 + 1]);
|
||||
if (!data)
|
||||
value = get_unaligned_be16(&output[channel * 2 + 1]);
|
||||
if (!value)
|
||||
*val = 0;
|
||||
else
|
||||
*val = 480000 / data;
|
||||
*val = 480000 / value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -231,7 +245,7 @@ static ssize_t msi_wmi_platform_write(struct file *fp, const char __user *input,
|
|||
return ret;
|
||||
|
||||
down_write(&data->buffer_lock);
|
||||
ret = msi_wmi_platform_query(data->wdev, data->method, payload, data->length, data->buffer,
|
||||
ret = msi_wmi_platform_query(data->data, data->method, payload, data->length, data->buffer,
|
||||
data->length);
|
||||
up_write(&data->buffer_lock);
|
||||
|
||||
|
|
@ -277,17 +291,17 @@ static void msi_wmi_platform_debugfs_remove(void *data)
|
|||
debugfs_remove_recursive(dir);
|
||||
}
|
||||
|
||||
static void msi_wmi_platform_debugfs_add(struct wmi_device *wdev, struct dentry *dir,
|
||||
static void msi_wmi_platform_debugfs_add(struct msi_wmi_platform_data *drvdata, struct dentry *dir,
|
||||
const char *name, enum msi_wmi_platform_method method)
|
||||
{
|
||||
struct msi_wmi_platform_debugfs_data *data;
|
||||
struct dentry *entry;
|
||||
|
||||
data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
data = devm_kzalloc(&drvdata->wdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
data->wdev = wdev;
|
||||
data->data = drvdata;
|
||||
data->method = method;
|
||||
init_rwsem(&data->buffer_lock);
|
||||
|
||||
|
|
@ -298,82 +312,82 @@ static void msi_wmi_platform_debugfs_add(struct wmi_device *wdev, struct dentry
|
|||
|
||||
entry = debugfs_create_file(name, 0600, dir, data, &msi_wmi_platform_debugfs_fops);
|
||||
if (IS_ERR(entry))
|
||||
devm_kfree(&wdev->dev, data);
|
||||
devm_kfree(&drvdata->wdev->dev, data);
|
||||
}
|
||||
|
||||
static void msi_wmi_platform_debugfs_init(struct wmi_device *wdev)
|
||||
static void msi_wmi_platform_debugfs_init(struct msi_wmi_platform_data *data)
|
||||
{
|
||||
struct dentry *dir;
|
||||
char dir_name[64];
|
||||
int ret, method;
|
||||
|
||||
scnprintf(dir_name, ARRAY_SIZE(dir_name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));
|
||||
scnprintf(dir_name, ARRAY_SIZE(dir_name), "%s-%s", DRIVER_NAME, dev_name(&data->wdev->dev));
|
||||
|
||||
dir = debugfs_create_dir(dir_name, NULL);
|
||||
if (IS_ERR(dir))
|
||||
return;
|
||||
|
||||
ret = devm_add_action_or_reset(&wdev->dev, msi_wmi_platform_debugfs_remove, dir);
|
||||
ret = devm_add_action_or_reset(&data->wdev->dev, msi_wmi_platform_debugfs_remove, dir);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
for (method = MSI_PLATFORM_GET_PACKAGE; method <= MSI_PLATFORM_GET_WMI; method++)
|
||||
msi_wmi_platform_debugfs_add(wdev, dir, msi_wmi_platform_debugfs_names[method - 1],
|
||||
msi_wmi_platform_debugfs_add(data, dir, msi_wmi_platform_debugfs_names[method - 1],
|
||||
method);
|
||||
}
|
||||
|
||||
static int msi_wmi_platform_hwmon_init(struct wmi_device *wdev)
|
||||
static int msi_wmi_platform_hwmon_init(struct msi_wmi_platform_data *data)
|
||||
{
|
||||
struct device *hdev;
|
||||
|
||||
hdev = devm_hwmon_device_register_with_info(&wdev->dev, "msi_wmi_platform", wdev,
|
||||
hdev = devm_hwmon_device_register_with_info(&data->wdev->dev, "msi_wmi_platform", data,
|
||||
&msi_wmi_platform_chip_info, NULL);
|
||||
|
||||
return PTR_ERR_OR_ZERO(hdev);
|
||||
}
|
||||
|
||||
static int msi_wmi_platform_ec_init(struct wmi_device *wdev)
|
||||
static int msi_wmi_platform_ec_init(struct msi_wmi_platform_data *data)
|
||||
{
|
||||
u8 input[32] = { 0 };
|
||||
u8 output[32];
|
||||
u8 flags;
|
||||
int ret;
|
||||
|
||||
ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_EC, input, sizeof(input), output,
|
||||
ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_EC, input, sizeof(input), output,
|
||||
sizeof(output));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
flags = output[MSI_PLATFORM_EC_FLAGS_OFFSET];
|
||||
|
||||
dev_dbg(&wdev->dev, "EC RAM version %lu.%lu\n",
|
||||
dev_dbg(&data->wdev->dev, "EC RAM version %lu.%lu\n",
|
||||
FIELD_GET(MSI_PLATFORM_EC_MAJOR_MASK, flags),
|
||||
FIELD_GET(MSI_PLATFORM_EC_MINOR_MASK, flags));
|
||||
dev_dbg(&wdev->dev, "EC firmware version %.28s\n",
|
||||
dev_dbg(&data->wdev->dev, "EC firmware version %.28s\n",
|
||||
&output[MSI_PLATFORM_EC_VERSION_OFFSET]);
|
||||
|
||||
if (!(flags & MSI_PLATFORM_EC_IS_TIGERLAKE)) {
|
||||
if (!force)
|
||||
return -ENODEV;
|
||||
|
||||
dev_warn(&wdev->dev, "Loading on a non-Tigerlake platform\n");
|
||||
dev_warn(&data->wdev->dev, "Loading on a non-Tigerlake platform\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msi_wmi_platform_init(struct wmi_device *wdev)
|
||||
static int msi_wmi_platform_init(struct msi_wmi_platform_data *data)
|
||||
{
|
||||
u8 input[32] = { 0 };
|
||||
u8 output[32];
|
||||
int ret;
|
||||
|
||||
ret = msi_wmi_platform_query(wdev, MSI_PLATFORM_GET_WMI, input, sizeof(input), output,
|
||||
ret = msi_wmi_platform_query(data, MSI_PLATFORM_GET_WMI, input, sizeof(input), output,
|
||||
sizeof(output));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&wdev->dev, "WMI interface version %u.%u\n",
|
||||
dev_dbg(&data->wdev->dev, "WMI interface version %u.%u\n",
|
||||
output[MSI_PLATFORM_WMI_MAJOR_OFFSET],
|
||||
output[MSI_PLATFORM_WMI_MINOR_OFFSET]);
|
||||
|
||||
|
|
@ -381,7 +395,8 @@ static int msi_wmi_platform_init(struct wmi_device *wdev)
|
|||
if (!force)
|
||||
return -ENODEV;
|
||||
|
||||
dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u.%u)\n",
|
||||
dev_warn(&data->wdev->dev,
|
||||
"Loading despite unsupported WMI interface version (%u.%u)\n",
|
||||
output[MSI_PLATFORM_WMI_MAJOR_OFFSET],
|
||||
output[MSI_PLATFORM_WMI_MINOR_OFFSET]);
|
||||
}
|
||||
|
|
@ -391,19 +406,31 @@ static int msi_wmi_platform_init(struct wmi_device *wdev)
|
|||
|
||||
static int msi_wmi_platform_probe(struct wmi_device *wdev, const void *context)
|
||||
{
|
||||
struct msi_wmi_platform_data *data;
|
||||
int ret;
|
||||
|
||||
ret = msi_wmi_platform_init(wdev);
|
||||
data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->wdev = wdev;
|
||||
dev_set_drvdata(&wdev->dev, data);
|
||||
|
||||
ret = devm_mutex_init(&wdev->dev, &data->wmi_lock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = msi_wmi_platform_ec_init(wdev);
|
||||
ret = msi_wmi_platform_init(data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
msi_wmi_platform_debugfs_init(wdev);
|
||||
ret = msi_wmi_platform_ec_init(data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return msi_wmi_platform_hwmon_init(wdev);
|
||||
msi_wmi_platform_debugfs_init(data);
|
||||
|
||||
return msi_wmi_platform_hwmon_init(data);
|
||||
}
|
||||
|
||||
static const struct wmi_device_id msi_wmi_platform_id_table[] = {
|
||||
|
|
|
|||
|
|
@ -11519,6 +11519,8 @@ static int __must_check __init get_thinkpad_model_data(
|
|||
tp->vendor = PCI_VENDOR_ID_IBM;
|
||||
else if (dmi_name_in_vendors("LENOVO"))
|
||||
tp->vendor = PCI_VENDOR_ID_LENOVO;
|
||||
else if (dmi_name_in_vendors("NEC"))
|
||||
tp->vendor = PCI_VENDOR_ID_LENOVO;
|
||||
else
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,18 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
|
|||
},
|
||||
.driver_data = (void *)&peaq_c1010_info,
|
||||
},
|
||||
{
|
||||
/* Vexia Edu Atla 10 tablet 5V version */
|
||||
.matches = {
|
||||
/* Having all 3 of these not set is somewhat unique */
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."),
|
||||
/* Above strings are too generic, also match on BIOS date */
|
||||
DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"),
|
||||
},
|
||||
.driver_data = (void *)&vexia_edu_atla10_5v_info,
|
||||
},
|
||||
{
|
||||
/* Vexia Edu Atla 10 tablet 9V version */
|
||||
.matches = {
|
||||
|
|
@ -187,7 +199,7 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = {
|
|||
/* Above strings are too generic, also match on BIOS date */
|
||||
DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
|
||||
},
|
||||
.driver_data = (void *)&vexia_edu_atla10_info,
|
||||
.driver_data = (void *)&vexia_edu_atla10_9v_info,
|
||||
},
|
||||
{
|
||||
/* Whitelabel (sold as various brands) TM800A550L */
|
||||
|
|
|
|||
|
|
@ -599,62 +599,122 @@ const struct x86_dev_info whitelabel_tm800a550l_info __initconst = {
|
|||
};
|
||||
|
||||
/*
|
||||
* Vexia EDU ATLA 10 tablet, Android 4.2 / 4.4 + Guadalinex Ubuntu tablet
|
||||
* Vexia EDU ATLA 10 tablet 5V, Android 4.4 + Guadalinex Ubuntu tablet
|
||||
* distributed to schools in the Spanish Andalucía region.
|
||||
*/
|
||||
static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" };
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_ulpmc_props[] = {
|
||||
PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_ulpmc_node = {
|
||||
.properties = vexia_edu_atla10_ulpmc_props,
|
||||
};
|
||||
|
||||
static const char * const vexia_edu_atla10_accel_mount_matrix[] = {
|
||||
"0", "-1", "0",
|
||||
"1", "0", "0",
|
||||
"0", "0", "1"
|
||||
};
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_accel_props[] = {
|
||||
PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_accel_mount_matrix),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_accel_node = {
|
||||
.properties = vexia_edu_atla10_accel_props,
|
||||
};
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_touchscreen_props[] = {
|
||||
static const struct property_entry vexia_edu_atla10_5v_touchscreen_props[] = {
|
||||
PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000),
|
||||
PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_touchscreen_node = {
|
||||
.properties = vexia_edu_atla10_touchscreen_props,
|
||||
static const struct software_node vexia_edu_atla10_5v_touchscreen_node = {
|
||||
.properties = vexia_edu_atla10_5v_touchscreen_props,
|
||||
};
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_pmic_props[] = {
|
||||
static const struct x86_i2c_client_info vexia_edu_atla10_5v_i2c_clients[] __initconst = {
|
||||
{
|
||||
/* kxcjk1013 accelerometer */
|
||||
.board_info = {
|
||||
.type = "kxcjk1013",
|
||||
.addr = 0x0f,
|
||||
.dev_name = "kxcjk1013",
|
||||
},
|
||||
.adapter_path = "\\_SB_.I2C3",
|
||||
}, {
|
||||
/* touchscreen controller */
|
||||
.board_info = {
|
||||
.type = "hid-over-i2c",
|
||||
.addr = 0x38,
|
||||
.dev_name = "FTSC1000",
|
||||
.swnode = &vexia_edu_atla10_5v_touchscreen_node,
|
||||
},
|
||||
.adapter_path = "\\_SB_.I2C4",
|
||||
.irq_data = {
|
||||
.type = X86_ACPI_IRQ_TYPE_APIC,
|
||||
.index = 0x44,
|
||||
.trigger = ACPI_LEVEL_SENSITIVE,
|
||||
.polarity = ACPI_ACTIVE_HIGH,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table vexia_edu_atla10_5v_ft5416_gpios = {
|
||||
.dev_id = "i2c-FTSC1000",
|
||||
.table = {
|
||||
GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW),
|
||||
{ }
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table * const vexia_edu_atla10_5v_gpios[] = {
|
||||
&vexia_edu_atla10_5v_ft5416_gpios,
|
||||
NULL
|
||||
};
|
||||
|
||||
const struct x86_dev_info vexia_edu_atla10_5v_info __initconst = {
|
||||
.i2c_client_info = vexia_edu_atla10_5v_i2c_clients,
|
||||
.i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_5v_i2c_clients),
|
||||
.gpiod_lookup_tables = vexia_edu_atla10_5v_gpios,
|
||||
};
|
||||
|
||||
/*
|
||||
* Vexia EDU ATLA 10 tablet 9V, Android 4.2 + Guadalinex Ubuntu tablet
|
||||
* distributed to schools in the Spanish Andalucía region.
|
||||
*/
|
||||
static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" };
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_9v_ulpmc_props[] = {
|
||||
PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_9v_ulpmc_node = {
|
||||
.properties = vexia_edu_atla10_9v_ulpmc_props,
|
||||
};
|
||||
|
||||
static const char * const vexia_edu_atla10_9v_accel_mount_matrix[] = {
|
||||
"0", "-1", "0",
|
||||
"1", "0", "0",
|
||||
"0", "0", "1"
|
||||
};
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_9v_accel_props[] = {
|
||||
PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_9v_accel_mount_matrix),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_9v_accel_node = {
|
||||
.properties = vexia_edu_atla10_9v_accel_props,
|
||||
};
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_9v_touchscreen_props[] = {
|
||||
PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000),
|
||||
PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_9v_touchscreen_node = {
|
||||
.properties = vexia_edu_atla10_9v_touchscreen_props,
|
||||
};
|
||||
|
||||
static const struct property_entry vexia_edu_atla10_9v_pmic_props[] = {
|
||||
PROPERTY_ENTRY_BOOL("linux,register-pwrsrc-power_supply"),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node vexia_edu_atla10_pmic_node = {
|
||||
.properties = vexia_edu_atla10_pmic_props,
|
||||
static const struct software_node vexia_edu_atla10_9v_pmic_node = {
|
||||
.properties = vexia_edu_atla10_9v_pmic_props,
|
||||
};
|
||||
|
||||
static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initconst = {
|
||||
static const struct x86_i2c_client_info vexia_edu_atla10_9v_i2c_clients[] __initconst = {
|
||||
{
|
||||
/* I2C attached embedded controller, used to access fuel-gauge */
|
||||
.board_info = {
|
||||
.type = "vexia_atla10_ec",
|
||||
.addr = 0x76,
|
||||
.dev_name = "ulpmc",
|
||||
.swnode = &vexia_edu_atla10_ulpmc_node,
|
||||
.swnode = &vexia_edu_atla10_9v_ulpmc_node,
|
||||
},
|
||||
.adapter_path = "0000:00:18.1",
|
||||
}, {
|
||||
|
|
@ -679,7 +739,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon
|
|||
.type = "kxtj21009",
|
||||
.addr = 0x0f,
|
||||
.dev_name = "kxtj21009",
|
||||
.swnode = &vexia_edu_atla10_accel_node,
|
||||
.swnode = &vexia_edu_atla10_9v_accel_node,
|
||||
},
|
||||
.adapter_path = "0000:00:18.5",
|
||||
}, {
|
||||
|
|
@ -688,7 +748,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon
|
|||
.type = "hid-over-i2c",
|
||||
.addr = 0x38,
|
||||
.dev_name = "FTSC1000",
|
||||
.swnode = &vexia_edu_atla10_touchscreen_node,
|
||||
.swnode = &vexia_edu_atla10_9v_touchscreen_node,
|
||||
},
|
||||
.adapter_path = "0000:00:18.6",
|
||||
.irq_data = {
|
||||
|
|
@ -703,7 +763,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon
|
|||
.type = "intel_soc_pmic_crc",
|
||||
.addr = 0x6e,
|
||||
.dev_name = "intel_soc_pmic_crc",
|
||||
.swnode = &vexia_edu_atla10_pmic_node,
|
||||
.swnode = &vexia_edu_atla10_9v_pmic_node,
|
||||
},
|
||||
.adapter_path = "0000:00:18.7",
|
||||
.irq_data = {
|
||||
|
|
@ -715,7 +775,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon
|
|||
}
|
||||
};
|
||||
|
||||
static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = {
|
||||
static const struct x86_serdev_info vexia_edu_atla10_9v_serdevs[] __initconst = {
|
||||
{
|
||||
.ctrl.pci.devfn = PCI_DEVFN(0x1e, 3),
|
||||
.ctrl_devname = "serial0",
|
||||
|
|
@ -723,7 +783,7 @@ static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = {
|
||||
static struct gpiod_lookup_table vexia_edu_atla10_9v_ft5416_gpios = {
|
||||
.dev_id = "i2c-FTSC1000",
|
||||
.table = {
|
||||
GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_LOW),
|
||||
|
|
@ -731,12 +791,12 @@ static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table * const vexia_edu_atla10_gpios[] = {
|
||||
&vexia_edu_atla10_ft5416_gpios,
|
||||
static struct gpiod_lookup_table * const vexia_edu_atla10_9v_gpios[] = {
|
||||
&vexia_edu_atla10_9v_ft5416_gpios,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int __init vexia_edu_atla10_init(struct device *dev)
|
||||
static int __init vexia_edu_atla10_9v_init(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
int ret;
|
||||
|
|
@ -760,13 +820,13 @@ static int __init vexia_edu_atla10_init(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const struct x86_dev_info vexia_edu_atla10_info __initconst = {
|
||||
.i2c_client_info = vexia_edu_atla10_i2c_clients,
|
||||
.i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_i2c_clients),
|
||||
.serdev_info = vexia_edu_atla10_serdevs,
|
||||
.serdev_count = ARRAY_SIZE(vexia_edu_atla10_serdevs),
|
||||
.gpiod_lookup_tables = vexia_edu_atla10_gpios,
|
||||
.init = vexia_edu_atla10_init,
|
||||
const struct x86_dev_info vexia_edu_atla10_9v_info __initconst = {
|
||||
.i2c_client_info = vexia_edu_atla10_9v_i2c_clients,
|
||||
.i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_9v_i2c_clients),
|
||||
.serdev_info = vexia_edu_atla10_9v_serdevs,
|
||||
.serdev_count = ARRAY_SIZE(vexia_edu_atla10_9v_serdevs),
|
||||
.gpiod_lookup_tables = vexia_edu_atla10_9v_gpios,
|
||||
.init = vexia_edu_atla10_9v_init,
|
||||
.use_pci = true,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -127,7 +127,8 @@ extern const struct x86_dev_info nextbook_ares8_info;
|
|||
extern const struct x86_dev_info nextbook_ares8a_info;
|
||||
extern const struct x86_dev_info peaq_c1010_info;
|
||||
extern const struct x86_dev_info whitelabel_tm800a550l_info;
|
||||
extern const struct x86_dev_info vexia_edu_atla10_info;
|
||||
extern const struct x86_dev_info vexia_edu_atla10_5v_info;
|
||||
extern const struct x86_dev_info vexia_edu_atla10_9v_info;
|
||||
extern const struct x86_dev_info xiaomi_mipad2_info;
|
||||
extern const struct dmi_system_id x86_android_tablet_ids[];
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct pmc_ipc_rbuf {
|
|||
*/
|
||||
static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object params[PMC_IPCS_PARAM_COUNT] = {
|
||||
{.type = ACPI_TYPE_INTEGER,},
|
||||
|
|
@ -89,6 +90,9 @@ static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf
|
|||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -ENODEV;
|
||||
#endif /* CONFIG_ACPI */
|
||||
}
|
||||
|
||||
#endif /* INTEL_PMC_IPC_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue