mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'platform-drivers-x86-v5.5-1' of git://git.infradead.org/linux-platform-drivers-x86
Pull x86 platform driver updates from Andy Shevchenko: - New bootctl driver for Mellanox BlueField SoC. - New driver to support System76 laptops. - Temperature monitoring and fan control on Acer Aspire 7551 is now supported. - Previously the Huawei driver handled only hotkeys. After the conversion to WMI it has been expanded to support newer laptop models. - Big refactoring of intel-speed-select tools allows to use it on Intel CascadeLake-N systems. - Touchscreen support for ezpad 6 m4 and Schneider SCT101CTM tablets - Miscellaneous clean ups and fixes here and there. * tag 'platform-drivers-x86-v5.5-1' of git://git.infradead.org/linux-platform-drivers-x86: (59 commits) platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support to intel_pmc_core driver platform/x86: intel_pmc_core: Fix the SoC naming inconsistency platform/mellanox: Fix Kconfig indentation tools/power/x86/intel-speed-select: Display TRL buckets for just base config level tools/power/x86/intel-speed-select: Ignore missing config level platform/x86: touchscreen_dmi: Add info for the ezpad 6 m4 tablet tools/power/x86/intel-speed-select: Increment version tools/power/x86/intel-speed-select: Use core count for base-freq mask tools/power/x86/intel-speed-select: Support platform with limited Intel(R) Speed Select tools/power/x86/intel-speed-select: Use Frequency weight for CLOS tools/power/x86/intel-speed-select: Make CLOS frequency in MHz tools/power/x86/intel-speed-select: Use mailbox for CLOS_PM_QOS_CONFIG tools/power/x86/intel-speed-select: Auto mode for CLX tools/power/x86/intel-speed-select: Correct CLX-N frequency units tools/power/x86/intel-speed-select: Change display of "avx" to "avx2" tools/power/x86/intel-speed-select: Extend command set for perf-profile Add touchscreen platform data for the Schneider SCT101CTM tablet platform/x86: intel_int0002_vgpio: Pass irqchip when adding gpiochip ...
This commit is contained in:
58
Documentation/ABI/testing/sysfs-platform-mellanox-bootctl
Normal file
58
Documentation/ABI/testing/sysfs-platform-mellanox-bootctl
Normal file
@@ -0,0 +1,58 @@
|
||||
What: /sys/bus/platform/devices/MLNXBF04:00/driver/lifecycle_state
|
||||
Date: Oct 2019
|
||||
KernelVersion: 5.5
|
||||
Contact: "Liming Sun <lsun@mellanox.com>"
|
||||
Description:
|
||||
The Life-cycle state of the SoC, which could be one of the
|
||||
following values.
|
||||
Production - Production state and can be updated to secure
|
||||
GA Secured - Secure chip and not able to change state
|
||||
GA Non-Secured - Non-Secure chip and not able to change state
|
||||
RMA - Return Merchandise Authorization
|
||||
|
||||
What: /sys/bus/platform/devices/MLNXBF04:00/driver/post_reset_wdog
|
||||
Date: Oct 2019
|
||||
KernelVersion: 5.5
|
||||
Contact: "Liming Sun <lsun@mellanox.com>"
|
||||
Description:
|
||||
The watchdog setting in seconds for the next booting. It's used
|
||||
to reboot the chip and recover it to the old state if the new
|
||||
boot partition fails.
|
||||
|
||||
What: /sys/bus/platform/devices/MLNXBF04:00/driver/reset_action
|
||||
Date: Oct 2019
|
||||
KernelVersion: 5.5
|
||||
Contact: "Liming Sun <lsun@mellanox.com>"
|
||||
Description:
|
||||
The source of the boot stream for the next reset. It could be
|
||||
one of the following values.
|
||||
external - boot from external source (USB or PCIe)
|
||||
emmc - boot from the onchip eMMC
|
||||
emmc_legacy - boot from the onchip eMMC in legacy (slow) mode
|
||||
|
||||
What: /sys/bus/platform/devices/MLNXBF04:00/driver/second_reset_action
|
||||
Date: Oct 2019
|
||||
KernelVersion: 5.5
|
||||
Contact: "Liming Sun <lsun@mellanox.com>"
|
||||
Description:
|
||||
Update the source of the boot stream after next reset. It could
|
||||
be one of the following values and will be applied after next
|
||||
reset.
|
||||
external - boot from external source (USB or PCIe)
|
||||
emmc - boot from the onchip eMMC
|
||||
emmc_legacy - boot from the onchip eMMC in legacy (slow) mode
|
||||
swap_emmc - swap the primary / secondary boot partition
|
||||
none - cancel the action
|
||||
|
||||
What: /sys/bus/platform/devices/MLNXBF04:00/driver/secure_boot_fuse_state
|
||||
Date: Oct 2019
|
||||
KernelVersion: 5.5
|
||||
Contact: "Liming Sun <lsun@mellanox.com>"
|
||||
Description:
|
||||
The state of eFuse versions with the following values.
|
||||
InUse - burnt, valid and currently in use
|
||||
Used - burnt and valid
|
||||
Free - not burnt and free to use
|
||||
Skipped - not burnt but not free (skipped)
|
||||
Wasted - burnt and invalid
|
||||
Invalid - not burnt but marked as valid (error state).
|
||||
10
MAINTAINERS
10
MAINTAINERS
@@ -295,7 +295,7 @@ S: Maintained
|
||||
F: drivers/net/ethernet/alteon/acenic*
|
||||
|
||||
ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
|
||||
M: Peter Feuerer <peter@piie.net>
|
||||
M: Peter Kaestle <peter@piie.net>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
W: http://piie.net/?section=acerhdf
|
||||
S: Maintained
|
||||
@@ -10577,6 +10577,7 @@ M: Darren Hart <dvhart@infradead.org>
|
||||
M: Vadim Pasternak <vadimp@mellanox.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/ABI/testing/sysfs-platform-mellanox-bootctl
|
||||
F: drivers/platform/mellanox/
|
||||
F: include/linux/platform_data/mlxreg.h
|
||||
|
||||
@@ -15948,6 +15949,13 @@ F: drivers/hwtracing/stm/
|
||||
F: include/linux/stm.h
|
||||
F: include/uapi/linux/stm.h
|
||||
|
||||
SYSTEM76 ACPI DRIVER
|
||||
M: Jeremy Soller <jeremy@system76.com>
|
||||
M: System76 Product Development <productdev@system76.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/system76_acpi.c
|
||||
|
||||
SYSV FILESYSTEM
|
||||
M: Christoph Hellwig <hch@infradead.org>
|
||||
S: Maintained
|
||||
|
||||
@@ -41,7 +41,19 @@ config MLXBF_TMFIFO
|
||||
depends on VIRTIO_CONSOLE && VIRTIO_NET
|
||||
help
|
||||
Say y here to enable TmFifo support. The TmFifo driver provides
|
||||
platform driver support for the TmFifo which supports console
|
||||
and networking based on the virtio framework.
|
||||
platform driver support for the TmFifo which supports console
|
||||
and networking based on the virtio framework.
|
||||
|
||||
config MLXBF_BOOTCTL
|
||||
tristate "Mellanox BlueField Firmware Boot Control driver"
|
||||
depends on ARM64
|
||||
depends on ACPI
|
||||
help
|
||||
The Mellanox BlueField firmware implements functionality to
|
||||
request swapping the primary and alternate eMMC boot partition,
|
||||
and to set up a watchdog that can undo that swap if the system
|
||||
does not boot up correctly. This driver provides sysfs access
|
||||
to the userspace tools, to be used in conjunction with the eMMC
|
||||
device driver to do necessary initial swap of the boot partition.
|
||||
|
||||
endif # MELLANOX_PLATFORM
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Makefile for linux/drivers/platform/mellanox
|
||||
# Mellanox Platform-Specific Drivers
|
||||
#
|
||||
obj-$(CONFIG_MLXBF_BOOTCTL) += mlxbf-bootctl.o
|
||||
obj-$(CONFIG_MLXBF_TMFIFO) += mlxbf-tmfifo.o
|
||||
obj-$(CONFIG_MLXREG_HOTPLUG) += mlxreg-hotplug.o
|
||||
obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
|
||||
|
||||
321
drivers/platform/mellanox/mlxbf-bootctl.c
Normal file
321
drivers/platform/mellanox/mlxbf-bootctl.c
Normal file
@@ -0,0 +1,321 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Mellanox boot control driver
|
||||
*
|
||||
* This driver provides a sysfs interface for systems management
|
||||
* software to manage reset-time actions.
|
||||
*
|
||||
* Copyright (C) 2019 Mellanox Technologies
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "mlxbf-bootctl.h"
|
||||
|
||||
#define MLXBF_BOOTCTL_SB_SECURE_MASK 0x03
|
||||
#define MLXBF_BOOTCTL_SB_TEST_MASK 0x0c
|
||||
|
||||
#define MLXBF_SB_KEY_NUM 4
|
||||
|
||||
/* UUID used to probe ATF service. */
|
||||
static const char *mlxbf_bootctl_svc_uuid_str =
|
||||
"89c036b4-e7d7-11e6-8797-001aca00bfc4";
|
||||
|
||||
struct mlxbf_bootctl_name {
|
||||
u32 value;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static struct mlxbf_bootctl_name boot_names[] = {
|
||||
{ MLXBF_BOOTCTL_EXTERNAL, "external" },
|
||||
{ MLXBF_BOOTCTL_EMMC, "emmc" },
|
||||
{ MLNX_BOOTCTL_SWAP_EMMC, "swap_emmc" },
|
||||
{ MLXBF_BOOTCTL_EMMC_LEGACY, "emmc_legacy" },
|
||||
{ MLXBF_BOOTCTL_NONE, "none" },
|
||||
};
|
||||
|
||||
static const char * const mlxbf_bootctl_lifecycle_states[] = {
|
||||
[0] = "Production",
|
||||
[1] = "GA Secured",
|
||||
[2] = "GA Non-Secured",
|
||||
[3] = "RMA",
|
||||
};
|
||||
|
||||
/* ARM SMC call which is atomic and no need for lock. */
|
||||
static int mlxbf_bootctl_smc(unsigned int smc_op, int smc_arg)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
return res.a0;
|
||||
}
|
||||
|
||||
/* Return the action in integer or an error code. */
|
||||
static int mlxbf_bootctl_reset_action_to_val(const char *action)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(boot_names); i++)
|
||||
if (sysfs_streq(boot_names[i].name, action))
|
||||
return boot_names[i].value;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return the action in string. */
|
||||
static const char *mlxbf_bootctl_action_to_string(int action)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(boot_names); i++)
|
||||
if (boot_names[i].value == action)
|
||||
return boot_names[i].name;
|
||||
|
||||
return "invalid action";
|
||||
}
|
||||
|
||||
static ssize_t post_reset_wdog_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_POST_RESET_WDOG, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%d\n", ret);
|
||||
}
|
||||
|
||||
static ssize_t post_reset_wdog_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long value;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul(buf, 10, &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_SET_POST_RESET_WDOG, value);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t mlxbf_bootctl_show(int smc_op, char *buf)
|
||||
{
|
||||
int action;
|
||||
|
||||
action = mlxbf_bootctl_smc(smc_op, 0);
|
||||
if (action < 0)
|
||||
return action;
|
||||
|
||||
return sprintf(buf, "%s\n", mlxbf_bootctl_action_to_string(action));
|
||||
}
|
||||
|
||||
static int mlxbf_bootctl_store(int smc_op, const char *buf, size_t count)
|
||||
{
|
||||
int ret, action;
|
||||
|
||||
action = mlxbf_bootctl_reset_action_to_val(buf);
|
||||
if (action < 0)
|
||||
return action;
|
||||
|
||||
ret = mlxbf_bootctl_smc(smc_op, action);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t reset_action_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return mlxbf_bootctl_show(MLXBF_BOOTCTL_GET_RESET_ACTION, buf);
|
||||
}
|
||||
|
||||
static ssize_t reset_action_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
return mlxbf_bootctl_store(MLXBF_BOOTCTL_SET_RESET_ACTION, buf, count);
|
||||
}
|
||||
|
||||
static ssize_t second_reset_action_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return mlxbf_bootctl_show(MLXBF_BOOTCTL_GET_SECOND_RESET_ACTION, buf);
|
||||
}
|
||||
|
||||
static ssize_t second_reset_action_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
return mlxbf_bootctl_store(MLXBF_BOOTCTL_SET_SECOND_RESET_ACTION, buf,
|
||||
count);
|
||||
}
|
||||
|
||||
static ssize_t lifecycle_state_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
int lc_state;
|
||||
|
||||
lc_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
|
||||
MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
|
||||
if (lc_state < 0)
|
||||
return lc_state;
|
||||
|
||||
lc_state &=
|
||||
MLXBF_BOOTCTL_SB_TEST_MASK | MLXBF_BOOTCTL_SB_SECURE_MASK;
|
||||
|
||||
/*
|
||||
* If the test bits are set, we specify that the current state may be
|
||||
* due to using the test bits.
|
||||
*/
|
||||
if (lc_state & MLXBF_BOOTCTL_SB_TEST_MASK) {
|
||||
lc_state &= MLXBF_BOOTCTL_SB_SECURE_MASK;
|
||||
|
||||
return sprintf(buf, "%s(test)\n",
|
||||
mlxbf_bootctl_lifecycle_states[lc_state]);
|
||||
}
|
||||
|
||||
return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]);
|
||||
}
|
||||
|
||||
static ssize_t secure_boot_fuse_state_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int burnt, valid, key, key_state, buf_len = 0, upper_key_used = 0;
|
||||
const char *status;
|
||||
|
||||
key_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
|
||||
MLXBF_BOOTCTL_FUSE_STATUS_KEYS);
|
||||
if (key_state < 0)
|
||||
return key_state;
|
||||
|
||||
/*
|
||||
* key_state contains the bits for 4 Key versions, loaded from eFuses
|
||||
* after a hard reset. Lower 4 bits are a thermometer code indicating
|
||||
* key programming has started for key n (0000 = none, 0001 = version 0,
|
||||
* 0011 = version 1, 0111 = version 2, 1111 = version 3). Upper 4 bits
|
||||
* are a thermometer code indicating key programming has completed for
|
||||
* key n (same encodings as the start bits). This allows for detection
|
||||
* of an interruption in the progamming process which has left the key
|
||||
* partially programmed (and thus invalid). The process is to burn the
|
||||
* eFuse for the new key start bit, burn the key eFuses, then burn the
|
||||
* eFuse for the new key complete bit.
|
||||
*
|
||||
* For example 0000_0000: no key valid, 0001_0001: key version 0 valid,
|
||||
* 0011_0011: key 1 version valid, 0011_0111: key version 2 started
|
||||
* programming but did not complete, etc. The most recent key for which
|
||||
* both start and complete bit is set is loaded. On soft reset, this
|
||||
* register is not modified.
|
||||
*/
|
||||
for (key = MLXBF_SB_KEY_NUM - 1; key >= 0; key--) {
|
||||
burnt = key_state & BIT(key);
|
||||
valid = key_state & BIT(key + MLXBF_SB_KEY_NUM);
|
||||
|
||||
if (burnt && valid)
|
||||
upper_key_used = 1;
|
||||
|
||||
if (upper_key_used) {
|
||||
if (burnt)
|
||||
status = valid ? "Used" : "Wasted";
|
||||
else
|
||||
status = valid ? "Invalid" : "Skipped";
|
||||
} else {
|
||||
if (burnt)
|
||||
status = valid ? "InUse" : "Incomplete";
|
||||
else
|
||||
status = valid ? "Invalid" : "Free";
|
||||
}
|
||||
buf_len += sprintf(buf + buf_len, "%d:%s ", key, status);
|
||||
}
|
||||
buf_len += sprintf(buf + buf_len, "\n");
|
||||
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(post_reset_wdog);
|
||||
static DEVICE_ATTR_RW(reset_action);
|
||||
static DEVICE_ATTR_RW(second_reset_action);
|
||||
static DEVICE_ATTR_RO(lifecycle_state);
|
||||
static DEVICE_ATTR_RO(secure_boot_fuse_state);
|
||||
|
||||
static struct attribute *mlxbf_bootctl_attrs[] = {
|
||||
&dev_attr_post_reset_wdog.attr,
|
||||
&dev_attr_reset_action.attr,
|
||||
&dev_attr_second_reset_action.attr,
|
||||
&dev_attr_lifecycle_state.attr,
|
||||
&dev_attr_secure_boot_fuse_state.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
ATTRIBUTE_GROUPS(mlxbf_bootctl);
|
||||
|
||||
static const struct acpi_device_id mlxbf_bootctl_acpi_ids[] = {
|
||||
{"MLNXBF04", 0},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, mlxbf_bootctl_acpi_ids);
|
||||
|
||||
static bool mlxbf_bootctl_guid_match(const guid_t *guid,
|
||||
const struct arm_smccc_res *res)
|
||||
{
|
||||
guid_t id = GUID_INIT(res->a0, res->a1, res->a1 >> 16,
|
||||
res->a2, res->a2 >> 8, res->a2 >> 16,
|
||||
res->a2 >> 24, res->a3, res->a3 >> 8,
|
||||
res->a3 >> 16, res->a3 >> 24);
|
||||
|
||||
return guid_equal(guid, &id);
|
||||
}
|
||||
|
||||
static int mlxbf_bootctl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arm_smccc_res res = { 0 };
|
||||
guid_t guid;
|
||||
int ret;
|
||||
|
||||
/* Ensure we have the UUID we expect for this service. */
|
||||
arm_smccc_smc(MLXBF_BOOTCTL_SIP_SVC_UID, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
guid_parse(mlxbf_bootctl_svc_uuid_str, &guid);
|
||||
if (!mlxbf_bootctl_guid_match(&guid, &res))
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* When watchdog is used, it sets boot mode to MLXBF_BOOTCTL_SWAP_EMMC
|
||||
* in case of boot failures. However it doesn't clear the state if there
|
||||
* is no failure. Restore the default boot mode here to avoid any
|
||||
* unnecessary boot partition swapping.
|
||||
*/
|
||||
ret = mlxbf_bootctl_smc(MLXBF_BOOTCTL_SET_RESET_ACTION,
|
||||
MLXBF_BOOTCTL_EMMC);
|
||||
if (ret < 0)
|
||||
dev_warn(&pdev->dev, "Unable to reset the EMMC boot mode\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mlxbf_bootctl_driver = {
|
||||
.probe = mlxbf_bootctl_probe,
|
||||
.driver = {
|
||||
.name = "mlxbf-bootctl",
|
||||
.groups = mlxbf_bootctl_groups,
|
||||
.acpi_match_table = mlxbf_bootctl_acpi_ids,
|
||||
}
|
||||
};
|
||||
|
||||
module_platform_driver(mlxbf_bootctl_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Mellanox boot control driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Mellanox Technologies");
|
||||
103
drivers/platform/mellanox/mlxbf-bootctl.h
Normal file
103
drivers/platform/mellanox/mlxbf-bootctl.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2019, Mellanox Technologies. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MLXBF_BOOTCTL_H__
|
||||
#define __MLXBF_BOOTCTL_H__
|
||||
|
||||
/*
|
||||
* Request that the on-chip watchdog be enabled, or disabled, after
|
||||
* the next chip soft reset. This call does not affect the current
|
||||
* status of the on-chip watchdog. If non-zero, the argument
|
||||
* specifies the watchdog interval in seconds. If zero, the watchdog
|
||||
* will not be enabled after the next soft reset. Non-zero errors are
|
||||
* returned as documented below.
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_SET_POST_RESET_WDOG 0x82000000
|
||||
|
||||
/*
|
||||
* Query the status which has been requested for the on-chip watchdog
|
||||
* after the next chip soft reset. Returns the interval as set by
|
||||
* MLXBF_BOOTCTL_SET_POST_RESET_WDOG.
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_GET_POST_RESET_WDOG 0x82000001
|
||||
|
||||
/*
|
||||
* Request that a specific boot action be taken at the next soft
|
||||
* reset. By default, the boot action is set by external chip pins,
|
||||
* which are sampled on hard reset. Note that the boot action
|
||||
* requested by this call will persist on subsequent resets unless
|
||||
* this service, or the MLNX_SET_SECOND_RESET_ACTION service, is
|
||||
* invoked. See below for the available MLNX_BOOT_xxx parameter
|
||||
* values. Non-zero errors are returned as documented below.
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_SET_RESET_ACTION 0x82000002
|
||||
|
||||
/*
|
||||
* Return the specific boot action which will be taken at the next
|
||||
* soft reset. Returns the reset action (see below for the parameter
|
||||
* values for MLXBF_BOOTCTL_SET_RESET_ACTION).
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_GET_RESET_ACTION 0x82000003
|
||||
|
||||
/*
|
||||
* Request that a specific boot action be taken at the soft reset
|
||||
* after the next soft reset. For a specified valid boot mode, the
|
||||
* effect of this call is identical to that of invoking
|
||||
* MLXBF_BOOTCTL_SET_RESET_ACTION after the next chip soft reset; in
|
||||
* particular, after that reset, the action for the now next reset can
|
||||
* be queried with MLXBF_BOOTCTL_GET_RESET_ACTION and modified with
|
||||
* MLXBF_BOOTCTL_SET_RESET_ACTION. You may also specify the parameter as
|
||||
* MLNX_BOOT_NONE, which is equivalent to specifying that no call to
|
||||
* MLXBF_BOOTCTL_SET_RESET_ACTION be taken after the next chip soft reset.
|
||||
* This call does not affect the action to be taken at the next soft
|
||||
* reset. Non-zero errors are returned as documented below.
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_SET_SECOND_RESET_ACTION 0x82000004
|
||||
|
||||
/*
|
||||
* Return the specific boot action which will be taken at the soft
|
||||
* reset after the next soft reset; this will be one of the valid
|
||||
* actions for MLXBF_BOOTCTL_SET_SECOND_RESET_ACTION.
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_GET_SECOND_RESET_ACTION 0x82000005
|
||||
|
||||
/*
|
||||
* Return the fuse status of the current chip. The caller should specify
|
||||
* with the second argument if the state of the lifecycle fuses or the
|
||||
* version of secure boot fuse keys left should be returned.
|
||||
*/
|
||||
#define MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS 0x82000006
|
||||
|
||||
/* Reset eMMC by programming the RST_N register. */
|
||||
#define MLXBF_BOOTCTL_SET_EMMC_RST_N 0x82000007
|
||||
|
||||
#define MLXBF_BOOTCTL_GET_DIMM_INFO 0x82000008
|
||||
|
||||
/* SMC function IDs for SiP Service queries */
|
||||
#define MLXBF_BOOTCTL_SIP_SVC_CALL_COUNT 0x8200ff00
|
||||
#define MLXBF_BOOTCTL_SIP_SVC_UID 0x8200ff01
|
||||
#define MLXBF_BOOTCTL_SIP_SVC_VERSION 0x8200ff03
|
||||
|
||||
/* ARM Standard Service Calls version numbers */
|
||||
#define MLXBF_BOOTCTL_SVC_VERSION_MAJOR 0x0
|
||||
#define MLXBF_BOOTCTL_SVC_VERSION_MINOR 0x2
|
||||
|
||||
/* Number of svc calls defined. */
|
||||
#define MLXBF_BOOTCTL_NUM_SVC_CALLS 12
|
||||
|
||||
/* Valid reset actions for MLXBF_BOOTCTL_SET_RESET_ACTION. */
|
||||
#define MLXBF_BOOTCTL_EXTERNAL 0 /* Not boot from eMMC */
|
||||
#define MLXBF_BOOTCTL_EMMC 1 /* From primary eMMC boot partition */
|
||||
#define MLNX_BOOTCTL_SWAP_EMMC 2 /* Swap eMMC boot partitions and reboot */
|
||||
#define MLXBF_BOOTCTL_EMMC_LEGACY 3 /* From primary eMMC in legacy mode */
|
||||
|
||||
/* Valid arguments for requesting the fuse status. */
|
||||
#define MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE 0 /* Return lifecycle status. */
|
||||
#define MLXBF_BOOTCTL_FUSE_STATUS_KEYS 1 /* Return secure boot key status */
|
||||
|
||||
/* Additional value to disable the MLXBF_BOOTCTL_SET_SECOND_RESET_ACTION. */
|
||||
#define MLXBF_BOOTCTL_NONE 0x7fffffff /* Don't change next boot action */
|
||||
|
||||
#endif /* __MLXBF_BOOTCTL_H__ */
|
||||
@@ -94,7 +94,6 @@ config ASUS_LAPTOP
|
||||
depends on RFKILL || RFKILL = n
|
||||
depends on ACPI_VIDEO || ACPI_VIDEO = n
|
||||
select INPUT_SPARSEKMAP
|
||||
select INPUT_POLLDEV
|
||||
---help---
|
||||
This is a driver for Asus laptops, Lenovo SL and the Pegatron
|
||||
Lucid tablet. It may also support some MEDION, JVC or VICTOR
|
||||
@@ -623,7 +622,6 @@ config THINKPAD_ACPI_HOTKEY_POLL
|
||||
config SENSORS_HDAPS
|
||||
tristate "Thinkpad Hard Drive Active Protection System (hdaps)"
|
||||
depends on INPUT
|
||||
select INPUT_POLLDEV
|
||||
help
|
||||
This driver provides support for the IBM Hard Drive Active Protection
|
||||
System (hdaps), which provides an accelerometer and other misc. data.
|
||||
@@ -806,7 +804,6 @@ config PEAQ_WMI
|
||||
tristate "PEAQ 2-in-1 WMI hotkey driver"
|
||||
depends on ACPI_WMI
|
||||
depends on INPUT
|
||||
select INPUT_POLLDEV
|
||||
help
|
||||
Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
|
||||
|
||||
@@ -834,7 +831,6 @@ config ACPI_TOSHIBA
|
||||
depends on ACPI_VIDEO || ACPI_VIDEO = n
|
||||
depends on RFKILL || RFKILL = n
|
||||
depends on IIO
|
||||
select INPUT_POLLDEV
|
||||
select INPUT_SPARSEKMAP
|
||||
---help---
|
||||
This driver adds support for access to certain system settings
|
||||
@@ -931,14 +927,20 @@ config INTEL_CHT_INT33FE
|
||||
This driver add support for the INT33FE ACPI device found on
|
||||
some Intel Cherry Trail devices.
|
||||
|
||||
There are two kinds of INT33FE ACPI device possible: for hardware
|
||||
with USB Type-C and Micro-B connectors. This driver supports both.
|
||||
|
||||
The INT33FE ACPI device has a CRS table with I2cSerialBusV2
|
||||
resources for 3 devices: Maxim MAX17047 Fuel Gauge Controller,
|
||||
resources for Fuel Gauge Controller and (in the Type-C variant)
|
||||
FUSB302 USB Type-C Controller and PI3USB30532 USB switch.
|
||||
This driver instantiates i2c-clients for these, so that standard
|
||||
i2c drivers for these chips can bind to the them.
|
||||
|
||||
If you enable this driver it is advised to also select
|
||||
CONFIG_TYPEC_FUSB302=m and CONFIG_BATTERY_MAX17042=m.
|
||||
CONFIG_BATTERY_BQ27XXX=m or CONFIG_BATTERY_BQ27XXX_I2C=m for Micro-B
|
||||
device and CONFIG_TYPEC_FUSB302=m and CONFIG_BATTERY_MAX17042=m
|
||||
for Type-C device.
|
||||
|
||||
|
||||
config INTEL_INT0002_VGPIO
|
||||
tristate "Intel ACPI INT0002 Virtual GPIO driver"
|
||||
@@ -1305,7 +1307,8 @@ config INTEL_ATOMISP2_PM
|
||||
will be called intel_atomisp2_pm.
|
||||
|
||||
config HUAWEI_WMI
|
||||
tristate "Huawei WMI hotkeys driver"
|
||||
tristate "Huawei WMI laptop extras driver"
|
||||
depends on ACPI_BATTERY
|
||||
depends on ACPI_WMI
|
||||
depends on INPUT
|
||||
select INPUT_SPARSEKMAP
|
||||
@@ -1314,9 +1317,8 @@ config HUAWEI_WMI
|
||||
select LEDS_TRIGGER_AUDIO
|
||||
select NEW_LEDS
|
||||
help
|
||||
This driver provides support for Huawei WMI hotkeys.
|
||||
It enables the missing keys and adds support to the micmute
|
||||
LED found on some of these laptops.
|
||||
This driver provides support for Huawei WMI hotkeys, battery charge
|
||||
control, fn-lock, mic-mute LED, and other extra features.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called huawei-wmi.
|
||||
@@ -1337,6 +1339,19 @@ config PCENGINES_APU2
|
||||
|
||||
source "drivers/platform/x86/intel_speed_select_if/Kconfig"
|
||||
|
||||
config SYSTEM76_ACPI
|
||||
tristate "System76 ACPI Driver"
|
||||
depends on ACPI
|
||||
select NEW_LEDS
|
||||
select LEDS_CLASS
|
||||
select LEDS_TRIGGERS
|
||||
help
|
||||
This is a driver for System76 laptops running open firmware. It adds
|
||||
support for Fn-Fx key combinations, keyboard backlight, and airplane mode
|
||||
LEDs.
|
||||
|
||||
If you have a System76 laptop running open firmware, say Y or M here.
|
||||
|
||||
endif # X86_PLATFORM_DEVICES
|
||||
|
||||
config PMC_ATOM
|
||||
|
||||
@@ -61,6 +61,10 @@ obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
|
||||
obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o
|
||||
obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.o
|
||||
obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o
|
||||
intel_cht_int33fe-objs := intel_cht_int33fe_common.o \
|
||||
intel_cht_int33fe_typec.o \
|
||||
intel_cht_int33fe_microb.o
|
||||
|
||||
obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o
|
||||
obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o
|
||||
obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o
|
||||
@@ -100,3 +104,4 @@ obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
|
||||
obj-$(CONFIG_INTEL_ATOMISP2_PM) += intel_atomisp2_pm.o
|
||||
obj-$(CONFIG_PCENGINES_APU2) += pcengines-apuv2.o
|
||||
obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += intel_speed_select_if/
|
||||
obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* of the aspire one netbook, turns on/off the fan
|
||||
* as soon as the upper/lower threshold is reached.
|
||||
*
|
||||
* (C) 2009 - Peter Feuerer peter (a) piie.net
|
||||
* (C) 2009 - Peter Kaestle peter (a) piie.net
|
||||
* http://piie.net
|
||||
* 2009 Borislav Petkov bp (a) alien8.de
|
||||
*
|
||||
@@ -224,6 +224,8 @@ static const struct bios_settings bios_tbl[] __initconst = {
|
||||
{"Acer", "Aspire 5739G", "V1.3311", 0x55, 0x58, {0x20, 0x00}, 0},
|
||||
/* Acer TravelMate 7730 */
|
||||
{"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00}, 0},
|
||||
/* Acer Aspire 7551 */
|
||||
{"Acer", "Aspire 7551", "V1.18", 0x93, 0xa8, {0x14, 0x04}, 1},
|
||||
/* Acer TravelMate TM8573T */
|
||||
{"Acer", "TM8573T", "V1.13", 0x93, 0xa8, {0x14, 0x04}, 1},
|
||||
/* Gateway */
|
||||
@@ -801,7 +803,7 @@ static void __exit acerhdf_exit(void)
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Peter Feuerer");
|
||||
MODULE_AUTHOR("Peter Kaestle");
|
||||
MODULE_DESCRIPTION("Aspire One temperature and fan driver");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:");
|
||||
@@ -815,6 +817,7 @@ MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5739G:");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*One*753:");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*5315:");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:pnAspire*7551:");
|
||||
MODULE_ALIAS("dmi:*:*Acer*:TM8573T:");
|
||||
MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
|
||||
MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/sparse-keymap.h>
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/rfkill.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmi.h>
|
||||
@@ -244,7 +243,7 @@ struct asus_laptop {
|
||||
|
||||
struct input_dev *inputdev;
|
||||
struct key_entry *keymap;
|
||||
struct input_polled_dev *pega_accel_poll;
|
||||
struct input_dev *pega_accel_poll;
|
||||
|
||||
struct asus_led wled;
|
||||
struct asus_led bled;
|
||||
@@ -446,9 +445,9 @@ static int pega_acc_axis(struct asus_laptop *asus, int curr, char *method)
|
||||
return clamp_val((short)val, -PEGA_ACC_CLAMP, PEGA_ACC_CLAMP);
|
||||
}
|
||||
|
||||
static void pega_accel_poll(struct input_polled_dev *ipd)
|
||||
static void pega_accel_poll(struct input_dev *input)
|
||||
{
|
||||
struct device *parent = ipd->input->dev.parent;
|
||||
struct device *parent = input->dev.parent;
|
||||
struct asus_laptop *asus = dev_get_drvdata(parent);
|
||||
|
||||
/* In some cases, the very first call to poll causes a
|
||||
@@ -457,10 +456,10 @@ static void pega_accel_poll(struct input_polled_dev *ipd)
|
||||
* device, and perhaps a firmware bug. Fake the first report. */
|
||||
if (!asus->pega_acc_live) {
|
||||
asus->pega_acc_live = true;
|
||||
input_report_abs(ipd->input, ABS_X, 0);
|
||||
input_report_abs(ipd->input, ABS_Y, 0);
|
||||
input_report_abs(ipd->input, ABS_Z, 0);
|
||||
input_sync(ipd->input);
|
||||
input_report_abs(input, ABS_X, 0);
|
||||
input_report_abs(input, ABS_Y, 0);
|
||||
input_report_abs(input, ABS_Z, 0);
|
||||
input_sync(input);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -471,25 +470,24 @@ static void pega_accel_poll(struct input_polled_dev *ipd)
|
||||
/* Note transform, convert to "right/up/out" in the native
|
||||
* landscape orientation (i.e. the vector is the direction of
|
||||
* "real up" in the device's cartiesian coordinates). */
|
||||
input_report_abs(ipd->input, ABS_X, -asus->pega_acc_x);
|
||||
input_report_abs(ipd->input, ABS_Y, -asus->pega_acc_y);
|
||||
input_report_abs(ipd->input, ABS_Z, asus->pega_acc_z);
|
||||
input_sync(ipd->input);
|
||||
input_report_abs(input, ABS_X, -asus->pega_acc_x);
|
||||
input_report_abs(input, ABS_Y, -asus->pega_acc_y);
|
||||
input_report_abs(input, ABS_Z, asus->pega_acc_z);
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
static void pega_accel_exit(struct asus_laptop *asus)
|
||||
{
|
||||
if (asus->pega_accel_poll) {
|
||||
input_unregister_polled_device(asus->pega_accel_poll);
|
||||
input_free_polled_device(asus->pega_accel_poll);
|
||||
input_unregister_device(asus->pega_accel_poll);
|
||||
asus->pega_accel_poll = NULL;
|
||||
}
|
||||
asus->pega_accel_poll = NULL;
|
||||
}
|
||||
|
||||
static int pega_accel_init(struct asus_laptop *asus)
|
||||
{
|
||||
int err;
|
||||
struct input_polled_dev *ipd;
|
||||
struct input_dev *input;
|
||||
|
||||
if (!asus->is_pega_lucid)
|
||||
return -ENODEV;
|
||||
@@ -499,37 +497,39 @@ static int pega_accel_init(struct asus_laptop *asus)
|
||||
acpi_check_handle(asus->handle, METHOD_XLRZ, NULL))
|
||||
return -ENODEV;
|
||||
|
||||
ipd = input_allocate_polled_device();
|
||||
if (!ipd)
|
||||
input = input_allocate_device();
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
ipd->poll = pega_accel_poll;
|
||||
ipd->poll_interval = 125;
|
||||
ipd->poll_interval_min = 50;
|
||||
ipd->poll_interval_max = 2000;
|
||||
input->name = PEGA_ACCEL_DESC;
|
||||
input->phys = PEGA_ACCEL_NAME "/input0";
|
||||
input->dev.parent = &asus->platform_device->dev;
|
||||
input->id.bustype = BUS_HOST;
|
||||
|
||||
ipd->input->name = PEGA_ACCEL_DESC;
|
||||
ipd->input->phys = PEGA_ACCEL_NAME "/input0";
|
||||
ipd->input->dev.parent = &asus->platform_device->dev;
|
||||
ipd->input->id.bustype = BUS_HOST;
|
||||
|
||||
set_bit(EV_ABS, ipd->input->evbit);
|
||||
input_set_abs_params(ipd->input, ABS_X,
|
||||
input_set_abs_params(input, ABS_X,
|
||||
-PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
|
||||
input_set_abs_params(ipd->input, ABS_Y,
|
||||
input_set_abs_params(input, ABS_Y,
|
||||
-PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
|
||||
input_set_abs_params(ipd->input, ABS_Z,
|
||||
input_set_abs_params(input, ABS_Z,
|
||||
-PEGA_ACC_CLAMP, PEGA_ACC_CLAMP, 0, 0);
|
||||
|
||||
err = input_register_polled_device(ipd);
|
||||
err = input_setup_polling(input, pega_accel_poll);
|
||||
if (err)
|
||||
goto exit;
|
||||
|
||||
asus->pega_accel_poll = ipd;
|
||||
input_set_poll_interval(input, 125);
|
||||
input_set_min_poll_interval(input, 50);
|
||||
input_set_max_poll_interval(input, 2000);
|
||||
|
||||
err = input_register_device(input);
|
||||
if (err)
|
||||
goto exit;
|
||||
|
||||
asus->pega_accel_poll = input;
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
input_free_polled_device(ipd);
|
||||
input_free_device(input);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1550,8 +1550,7 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event)
|
||||
|
||||
/* Accelerometer "coarse orientation change" event */
|
||||
if (asus->pega_accel_poll && event == 0xEA) {
|
||||
kobject_uevent(&asus->pega_accel_poll->input->dev.kobj,
|
||||
KOBJ_CHANGE);
|
||||
kobject_uevent(&asus->pega_accel_poll->dev.kobj, KOBJ_CHANGE);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
struct quirk_entry {
|
||||
bool touchpad_led;
|
||||
bool kbd_led_not_present;
|
||||
bool kbd_led_levels_off_1;
|
||||
bool kbd_missing_ac_tag;
|
||||
|
||||
@@ -73,6 +74,10 @@ static struct quirk_entry quirk_dell_latitude_e6410 = {
|
||||
.kbd_led_levels_off_1 = true,
|
||||
};
|
||||
|
||||
static struct quirk_entry quirk_dell_inspiron_1012 = {
|
||||
.kbd_led_not_present = true,
|
||||
};
|
||||
|
||||
static struct platform_driver platform_driver = {
|
||||
.driver = {
|
||||
.name = "dell-laptop",
|
||||
@@ -310,6 +315,24 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
|
||||
},
|
||||
.driver_data = &quirk_dell_latitude_e6410,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "Dell Inspiron 1012",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
|
||||
},
|
||||
.driver_data = &quirk_dell_inspiron_1012,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "Dell Inspiron 1018",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1018"),
|
||||
},
|
||||
.driver_data = &quirk_dell_inspiron_1012,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -1493,6 +1516,9 @@ static void kbd_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (quirks && quirks->kbd_led_not_present)
|
||||
return;
|
||||
|
||||
ret = kbd_init_info();
|
||||
kbd_init_tokens();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input-polldev.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
@@ -59,7 +59,7 @@
|
||||
#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS)
|
||||
|
||||
static struct platform_device *pdev;
|
||||
static struct input_polled_dev *hdaps_idev;
|
||||
static struct input_dev *hdaps_idev;
|
||||
static unsigned int hdaps_invert;
|
||||
static u8 km_activity;
|
||||
static int rest_x;
|
||||
@@ -318,9 +318,8 @@ static void hdaps_calibrate(void)
|
||||
__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &rest_x, &rest_y);
|
||||
}
|
||||
|
||||
static void hdaps_mousedev_poll(struct input_polled_dev *dev)
|
||||
static void hdaps_mousedev_poll(struct input_dev *input_dev)
|
||||
{
|
||||
struct input_dev *input_dev = dev->input;
|
||||
int x, y;
|
||||
|
||||
mutex_lock(&hdaps_mtx);
|
||||
@@ -531,7 +530,6 @@ static const struct dmi_system_id hdaps_whitelist[] __initconst = {
|
||||
|
||||
static int __init hdaps_init(void)
|
||||
{
|
||||
struct input_dev *idev;
|
||||
int ret;
|
||||
|
||||
if (!dmi_check_system(hdaps_whitelist)) {
|
||||
@@ -559,31 +557,32 @@ static int __init hdaps_init(void)
|
||||
if (ret)
|
||||
goto out_device;
|
||||
|
||||
hdaps_idev = input_allocate_polled_device();
|
||||
hdaps_idev = input_allocate_device();
|
||||
if (!hdaps_idev) {
|
||||
ret = -ENOMEM;
|
||||
goto out_group;
|
||||
}
|
||||
|
||||
hdaps_idev->poll = hdaps_mousedev_poll;
|
||||
hdaps_idev->poll_interval = HDAPS_POLL_INTERVAL;
|
||||
|
||||
/* initial calibrate for the input device */
|
||||
hdaps_calibrate();
|
||||
|
||||
/* initialize the input class */
|
||||
idev = hdaps_idev->input;
|
||||
idev->name = "hdaps";
|
||||
idev->phys = "isa1600/input0";
|
||||
idev->id.bustype = BUS_ISA;
|
||||
idev->dev.parent = &pdev->dev;
|
||||
idev->evbit[0] = BIT_MASK(EV_ABS);
|
||||
input_set_abs_params(idev, ABS_X,
|
||||
hdaps_idev->name = "hdaps";
|
||||
hdaps_idev->phys = "isa1600/input0";
|
||||
hdaps_idev->id.bustype = BUS_ISA;
|
||||
hdaps_idev->dev.parent = &pdev->dev;
|
||||
input_set_abs_params(hdaps_idev, ABS_X,
|
||||
-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
|
||||
input_set_abs_params(idev, ABS_Y,
|
||||
input_set_abs_params(hdaps_idev, ABS_Y,
|
||||
-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
|
||||
|
||||
ret = input_register_polled_device(hdaps_idev);
|
||||
ret = input_setup_polling(hdaps_idev, hdaps_mousedev_poll);
|
||||
if (ret)
|
||||
goto out_idev;
|
||||
|
||||
input_set_poll_interval(hdaps_idev, HDAPS_POLL_INTERVAL);
|
||||
|
||||
ret = input_register_device(hdaps_idev);
|
||||
if (ret)
|
||||
goto out_idev;
|
||||
|
||||
@@ -591,7 +590,7 @@ static int __init hdaps_init(void)
|
||||
return 0;
|
||||
|
||||
out_idev:
|
||||
input_free_polled_device(hdaps_idev);
|
||||
input_free_device(hdaps_idev);
|
||||
out_group:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
|
||||
out_device:
|
||||
@@ -607,8 +606,7 @@ out:
|
||||
|
||||
static void __exit hdaps_exit(void)
|
||||
{
|
||||
input_unregister_polled_device(hdaps_idev);
|
||||
input_free_polled_device(hdaps_idev);
|
||||
input_unregister_device(hdaps_idev);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
|
||||
platform_device_unregister(pdev);
|
||||
platform_driver_unregister(&hdaps_driver);
|
||||
|
||||
@@ -65,7 +65,7 @@ struct bios_args {
|
||||
u32 command;
|
||||
u32 commandtype;
|
||||
u32 datasize;
|
||||
u32 data;
|
||||
u8 data[128];
|
||||
};
|
||||
|
||||
enum hp_wmi_commandtype {
|
||||
@@ -216,7 +216,7 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
|
||||
.command = command,
|
||||
.commandtype = query,
|
||||
.datasize = insize,
|
||||
.data = 0,
|
||||
.data = { 0 },
|
||||
};
|
||||
struct acpi_buffer input = { sizeof(struct bios_args), &args };
|
||||
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
@@ -228,7 +228,7 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
|
||||
|
||||
if (WARN_ON(insize > sizeof(args.data)))
|
||||
return -EINVAL;
|
||||
memcpy(&args.data, buffer, insize);
|
||||
memcpy(&args.data[0], buffer, insize);
|
||||
|
||||
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
|
||||
|
||||
@@ -380,7 +380,7 @@ static int hp_wmi_rfkill2_refresh(void)
|
||||
int err, i;
|
||||
|
||||
err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
|
||||
0, sizeof(state));
|
||||
sizeof(state), sizeof(state));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -778,7 +778,7 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
|
||||
int err, i;
|
||||
|
||||
err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state,
|
||||
0, sizeof(state));
|
||||
sizeof(state), sizeof(state));
|
||||
if (err)
|
||||
return err < 0 ? err : -EINVAL;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
147
drivers/platform/x86/intel_cht_int33fe_common.c
Normal file
147
drivers/platform/x86/intel_cht_int33fe_common.c
Normal file
@@ -0,0 +1,147 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Common code for Intel Cherry Trail ACPI INT33FE pseudo device drivers
|
||||
* (USB Micro-B and Type-C connector variants).
|
||||
*
|
||||
* Copyright (c) 2019 Yauhen Kharuzhy <jekhor@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "intel_cht_int33fe_common.h"
|
||||
|
||||
#define EXPECTED_PTYPE 4
|
||||
|
||||
static int cht_int33fe_i2c_res_filter(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct acpi_resource_i2c_serialbus *sb;
|
||||
int *count = data;
|
||||
|
||||
if (i2c_acpi_get_i2c_resource(ares, &sb))
|
||||
(*count)++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cht_int33fe_count_i2c_clients(struct device *dev)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
LIST_HEAD(resource_list);
|
||||
int count = 0;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev)
|
||||
return -EINVAL;
|
||||
|
||||
acpi_dev_get_resources(adev, &resource_list,
|
||||
cht_int33fe_i2c_res_filter, &count);
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int cht_int33fe_check_hw_type(struct device *dev)
|
||||
{
|
||||
unsigned long long ptyp;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(dev), "PTYP", NULL, &ptyp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(dev, "Error getting PTYPE\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* The same ACPI HID is used for different configurations check PTYP
|
||||
* to ensure that we are dealing with the expected config.
|
||||
*/
|
||||
if (ptyp != EXPECTED_PTYPE)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check presence of INT34D3 (hardware-rev 3) expected for ptype == 4 */
|
||||
if (!acpi_dev_present("INT34D3", "1", 3)) {
|
||||
dev_err(dev, "Error PTYPE == %d, but no INT34D3 device\n",
|
||||
EXPECTED_PTYPE);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = cht_int33fe_count_i2c_clients(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (ret) {
|
||||
case 2:
|
||||
return INT33FE_HW_MICROB;
|
||||
case 4:
|
||||
return INT33FE_HW_TYPEC;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
static int cht_int33fe_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cht_int33fe_data *data;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
ret = cht_int33fe_check_hw_type(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->dev = dev;
|
||||
|
||||
switch (ret) {
|
||||
case INT33FE_HW_MICROB:
|
||||
data->probe = cht_int33fe_microb_probe;
|
||||
data->remove = cht_int33fe_microb_remove;
|
||||
break;
|
||||
|
||||
case INT33FE_HW_TYPEC:
|
||||
data->probe = cht_int33fe_typec_probe;
|
||||
data->remove = cht_int33fe_typec_remove;
|
||||
break;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
return data->probe(data);
|
||||
}
|
||||
|
||||
static int cht_int33fe_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cht_int33fe_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
return data->remove(data);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id cht_int33fe_acpi_ids[] = {
|
||||
{ "INT33FE", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cht_int33fe_acpi_ids);
|
||||
|
||||
static struct platform_driver cht_int33fe_driver = {
|
||||
.driver = {
|
||||
.name = "Intel Cherry Trail ACPI INT33FE driver",
|
||||
.acpi_match_table = ACPI_PTR(cht_int33fe_acpi_ids),
|
||||
},
|
||||
.probe = cht_int33fe_probe,
|
||||
.remove = cht_int33fe_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cht_int33fe_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Intel Cherry Trail ACPI INT33FE pseudo device driver");
|
||||
MODULE_AUTHOR("Yauhen Kharuzhy <jekhor@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
41
drivers/platform/x86/intel_cht_int33fe_common.h
Normal file
41
drivers/platform/x86/intel_cht_int33fe_common.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Common code for Intel Cherry Trail ACPI INT33FE pseudo device drivers
|
||||
* (USB Micro-B and Type-C connector variants), header file
|
||||
*
|
||||
* Copyright (c) 2019 Yauhen Kharuzhy <jekhor@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _INTEL_CHT_INT33FE_COMMON_H
|
||||
#define _INTEL_CHT_INT33FE_COMMON_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
enum int33fe_hw_type {
|
||||
INT33FE_HW_MICROB,
|
||||
INT33FE_HW_TYPEC,
|
||||
};
|
||||
|
||||
struct cht_int33fe_data {
|
||||
struct device *dev;
|
||||
|
||||
int (*probe)(struct cht_int33fe_data *data);
|
||||
int (*remove)(struct cht_int33fe_data *data);
|
||||
|
||||
struct i2c_client *battery_fg;
|
||||
|
||||
/* Type-C only */
|
||||
struct i2c_client *fusb302;
|
||||
struct i2c_client *pi3usb30532;
|
||||
|
||||
struct fwnode_handle *dp;
|
||||
};
|
||||
|
||||
int cht_int33fe_microb_probe(struct cht_int33fe_data *data);
|
||||
int cht_int33fe_microb_remove(struct cht_int33fe_data *data);
|
||||
int cht_int33fe_typec_probe(struct cht_int33fe_data *data);
|
||||
int cht_int33fe_typec_remove(struct cht_int33fe_data *data);
|
||||
|
||||
#endif /* _INTEL_CHT_INT33FE_COMMON_H */
|
||||
57
drivers/platform/x86/intel_cht_int33fe_microb.c
Normal file
57
drivers/platform/x86/intel_cht_int33fe_microb.c
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Intel Cherry Trail ACPI INT33FE pseudo device driver for devices with
|
||||
* USB Micro-B connector (e.g. without of FUSB302 USB Type-C controller)
|
||||
*
|
||||
* Copyright (C) 2019 Yauhen Kharuzhy <jekhor@gmail.com>
|
||||
*
|
||||
* At least one Intel Cherry Trail based device which ship with Windows 10
|
||||
* (Lenovo YogaBook YB1-X91L/F tablet), have this weird INT33FE ACPI device
|
||||
* with a CRS table with 2 I2cSerialBusV2 resources, for 2 different chips
|
||||
* attached to various i2c busses:
|
||||
* 1. The Whiskey Cove PMIC, which is also described by the INT34D3 ACPI device
|
||||
* 2. TI BQ27542 Fuel Gauge Controller
|
||||
*
|
||||
* So this driver is a stub / pseudo driver whose only purpose is to
|
||||
* instantiate i2c-client for battery fuel gauge, so that standard i2c driver
|
||||
* for these chip can bind to the it.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb/pd.h>
|
||||
|
||||
#include "intel_cht_int33fe_common.h"
|
||||
|
||||
static const char * const bq27xxx_suppliers[] = { "bq25890-charger" };
|
||||
|
||||
static const struct property_entry bq27xxx_props[] = {
|
||||
PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq27xxx_suppliers),
|
||||
{ }
|
||||
};
|
||||
|
||||
int cht_int33fe_microb_probe(struct cht_int33fe_data *data)
|
||||
{
|
||||
struct device *dev = data->dev;
|
||||
struct i2c_board_info board_info;
|
||||
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strscpy(board_info.type, "bq27542", ARRAY_SIZE(board_info.type));
|
||||
board_info.dev_name = "bq27542";
|
||||
board_info.properties = bq27xxx_props;
|
||||
data->battery_fg = i2c_acpi_new_device(dev, 1, &board_info);
|
||||
|
||||
return PTR_ERR_OR_ZERO(data->battery_fg);
|
||||
}
|
||||
|
||||
int cht_int33fe_microb_remove(struct cht_int33fe_data *data)
|
||||
{
|
||||
i2c_unregister_device(data->battery_fg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -17,17 +17,15 @@
|
||||
* for these chips can bind to the them.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb/pd.h>
|
||||
|
||||
#define EXPECTED_PTYPE 4
|
||||
#include "intel_cht_int33fe_common.h"
|
||||
|
||||
enum {
|
||||
INT33FE_NODE_FUSB302,
|
||||
@@ -38,14 +36,6 @@ enum {
|
||||
INT33FE_NODE_MAX,
|
||||
};
|
||||
|
||||
struct cht_int33fe_data {
|
||||
struct i2c_client *max17047;
|
||||
struct i2c_client *fusb302;
|
||||
struct i2c_client *pi3usb30532;
|
||||
|
||||
struct fwnode_handle *dp;
|
||||
};
|
||||
|
||||
static const struct software_node nodes[];
|
||||
|
||||
static const struct software_node_ref_args pi3usb30532_ref = {
|
||||
@@ -251,43 +241,20 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data)
|
||||
strlcpy(board_info.type, "max17047", I2C_NAME_SIZE);
|
||||
board_info.dev_name = "max17047";
|
||||
board_info.fwnode = fwnode;
|
||||
data->max17047 = i2c_acpi_new_device(dev, 1, &board_info);
|
||||
data->battery_fg = i2c_acpi_new_device(dev, 1, &board_info);
|
||||
|
||||
return PTR_ERR_OR_ZERO(data->max17047);
|
||||
return PTR_ERR_OR_ZERO(data->battery_fg);
|
||||
}
|
||||
|
||||
static int cht_int33fe_probe(struct platform_device *pdev)
|
||||
int cht_int33fe_typec_probe(struct cht_int33fe_data *data)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device *dev = data->dev;
|
||||
struct i2c_board_info board_info;
|
||||
struct cht_int33fe_data *data;
|
||||
struct fwnode_handle *fwnode;
|
||||
struct regulator *regulator;
|
||||
unsigned long long ptyp;
|
||||
acpi_status status;
|
||||
int fusb302_irq;
|
||||
int ret;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(dev), "PTYP", NULL, &ptyp);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(dev, "Error getting PTYPE\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* The same ACPI HID is used for different configurations check PTYP
|
||||
* to ensure that we are dealing with the expected config.
|
||||
*/
|
||||
if (ptyp != EXPECTED_PTYPE)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check presence of INT34D3 (hardware-rev 3) expected for ptype == 4 */
|
||||
if (!acpi_dev_present("INT34D3", "1", 3)) {
|
||||
dev_err(dev, "Error PTYPE == %d, but no INT34D3 device\n",
|
||||
EXPECTED_PTYPE);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* We expect the WC PMIC to be paired with a TI bq24292i charger-IC.
|
||||
* We check for the bq24292i vbus regulator here, this has 2 purposes:
|
||||
@@ -317,10 +284,6 @@ static int cht_int33fe_probe(struct platform_device *pdev)
|
||||
return fusb302_irq;
|
||||
}
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = cht_int33fe_add_nodes(data);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -365,15 +328,13 @@ static int cht_int33fe_probe(struct platform_device *pdev)
|
||||
goto out_unregister_fusb302;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
return 0;
|
||||
|
||||
out_unregister_fusb302:
|
||||
i2c_unregister_device(data->fusb302);
|
||||
|
||||
out_unregister_max17047:
|
||||
i2c_unregister_device(data->max17047);
|
||||
i2c_unregister_device(data->battery_fg);
|
||||
|
||||
out_remove_nodes:
|
||||
cht_int33fe_remove_nodes(data);
|
||||
@@ -381,36 +342,13 @@ out_remove_nodes:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cht_int33fe_remove(struct platform_device *pdev)
|
||||
int cht_int33fe_typec_remove(struct cht_int33fe_data *data)
|
||||
{
|
||||
struct cht_int33fe_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
i2c_unregister_device(data->pi3usb30532);
|
||||
i2c_unregister_device(data->fusb302);
|
||||
i2c_unregister_device(data->max17047);
|
||||
i2c_unregister_device(data->battery_fg);
|
||||
|
||||
cht_int33fe_remove_nodes(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id cht_int33fe_acpi_ids[] = {
|
||||
{ "INT33FE", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cht_int33fe_acpi_ids);
|
||||
|
||||
static struct platform_driver cht_int33fe_driver = {
|
||||
.driver = {
|
||||
.name = "Intel Cherry Trail ACPI INT33FE driver",
|
||||
.acpi_match_table = ACPI_PTR(cht_int33fe_acpi_ids),
|
||||
},
|
||||
.probe = cht_int33fe_probe,
|
||||
.remove = cht_int33fe_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cht_int33fe_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Intel Cherry Trail ACPI INT33FE pseudo device driver");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -164,8 +164,8 @@ static int int0002_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct x86_cpu_id *cpu_id;
|
||||
struct irq_chip *irq_chip;
|
||||
struct gpio_chip *chip;
|
||||
struct gpio_irq_chip *girq;
|
||||
int irq, ret;
|
||||
|
||||
/* Menlow has a different INT0002 device? <sigh> */
|
||||
@@ -192,15 +192,11 @@ static int int0002_probe(struct platform_device *pdev)
|
||||
chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1;
|
||||
chip->irq.init_valid_mask = int0002_init_irq_valid_mask;
|
||||
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Error adding gpio chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* We manually request the irq here instead of passing a flow-handler
|
||||
* We directly request the irq here instead of passing a flow-handler
|
||||
* to gpiochip_set_chained_irqchip, because the irq is shared.
|
||||
* FIXME: augment this if we managed to pull handling of shared
|
||||
* IRQs into gpiolib.
|
||||
*/
|
||||
ret = devm_request_irq(dev, irq, int0002_irq,
|
||||
IRQF_SHARED, "INT0002", chip);
|
||||
@@ -209,17 +205,21 @@ static int int0002_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq_chip = (struct irq_chip *)cpu_id->driver_data;
|
||||
girq = &chip->irq;
|
||||
girq->chip = (struct irq_chip *)cpu_id->driver_data;
|
||||
/* This let us handle the parent IRQ in the driver */
|
||||
girq->parent_handler = NULL;
|
||||
girq->num_parents = 0;
|
||||
girq->parents = NULL;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_edge_irq;
|
||||
|
||||
ret = gpiochip_irqchip_add(chip, irq_chip, 0, handle_edge_irq,
|
||||
IRQ_TYPE_NONE);
|
||||
ret = devm_gpiochip_add_data(dev, chip, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Error adding irqchip: %d\n", ret);
|
||||
dev_err(dev, "Error adding gpio chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL);
|
||||
|
||||
device_init_wakeup(dev, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -158,8 +158,9 @@ static const struct pmc_reg_map spt_reg_map = {
|
||||
.pm_vric1_offset = SPT_PMC_VRIC1_OFFSET,
|
||||
};
|
||||
|
||||
/* Cannonlake: PGD PFET Enable Ack Status Register(s) bitmap */
|
||||
/* Cannon Lake: PGD PFET Enable Ack Status Register(s) bitmap */
|
||||
static const struct pmc_bit_map cnp_pfear_map[] = {
|
||||
/* Reserved for Cannon Lake but valid for Comet Lake */
|
||||
{"PMC", BIT(0)},
|
||||
{"OPI-DMI", BIT(1)},
|
||||
{"SPI/eSPI", BIT(2)},
|
||||
@@ -185,7 +186,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
|
||||
{"SDX", BIT(4)},
|
||||
{"SPE", BIT(5)},
|
||||
{"Fuse", BIT(6)},
|
||||
/* Reserved for Cannonlake but valid for Icelake */
|
||||
/* Reserved for Cannon Lake but valid for Ice Lake and Comet Lake */
|
||||
{"SBR8", BIT(7)},
|
||||
|
||||
{"CSME_FSC", BIT(0)},
|
||||
@@ -229,12 +230,12 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
|
||||
{"HDA_PGD4", BIT(2)},
|
||||
{"HDA_PGD5", BIT(3)},
|
||||
{"HDA_PGD6", BIT(4)},
|
||||
/* Reserved for Cannonlake but valid for Icelake */
|
||||
/* Reserved for Cannon Lake but valid for Ice Lake and Comet Lake */
|
||||
{"PSF6", BIT(5)},
|
||||
{"PSF7", BIT(6)},
|
||||
{"PSF8", BIT(7)},
|
||||
|
||||
/* Icelake generation onwards only */
|
||||
/* Ice Lake generation onwards only */
|
||||
{"RES_65", BIT(0)},
|
||||
{"RES_66", BIT(1)},
|
||||
{"RES_67", BIT(2)},
|
||||
@@ -324,7 +325,7 @@ static const struct pmc_bit_map cnp_ltr_show_map[] = {
|
||||
{"ISH", CNP_PMC_LTR_ISH},
|
||||
{"UFSX2", CNP_PMC_LTR_UFSX2},
|
||||
{"EMMC", CNP_PMC_LTR_EMMC},
|
||||
/* Reserved for Cannonlake but valid for Icelake */
|
||||
/* Reserved for Cannon Lake but valid for Ice Lake */
|
||||
{"WIGIG", ICL_PMC_LTR_WIGIG},
|
||||
/* Below two cannot be used for LTR_IGNORE */
|
||||
{"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT},
|
||||
@@ -813,6 +814,8 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
|
||||
INTEL_CPU_FAM6(CANNONLAKE_L, cnp_reg_map),
|
||||
INTEL_CPU_FAM6(ICELAKE_L, icl_reg_map),
|
||||
INTEL_CPU_FAM6(ICELAKE_NNPI, icl_reg_map),
|
||||
INTEL_CPU_FAM6(COMETLAKE, cnp_reg_map),
|
||||
INTEL_CPU_FAM6(COMETLAKE_L, cnp_reg_map),
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -871,8 +874,8 @@ static int pmc_core_probe(struct platform_device *pdev)
|
||||
pmcdev->map = (struct pmc_reg_map *)cpu_id->driver_data;
|
||||
|
||||
/*
|
||||
* Coffeelake has CPU ID of Kabylake and Cannonlake PCH. So here
|
||||
* Sunrisepoint PCH regmap can't be used. Use Cannonlake PCH regmap
|
||||
* Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here
|
||||
* Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap
|
||||
* in this case.
|
||||
*/
|
||||
if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user