Commit dbbdf54c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'platform-drivers-x86-v5.1-1' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform driver updates from Darren Hart:

 - use MODULE_DEVICE_TABLE across several wmi drivers, keeping
   wmi_device_id and MODULE_ALIAS() declarations in sync

 - add several Ideapad models to the no_hw_rfkill list

 - add support for new Mellanox platforms, including new fan and LED
   functionality

 - address Dell keyboard backlight change event and power button release
   issues

 - update dell_rbu to use appropriate memory allocation mechanisms

 - several small fixes and Ice Lake support for intel_pmc_core

 - fix a suspend regression for Cherry Trail based devices in
   intel_int0002_vgpio

 - a few other routine fixes

* tag 'platform-drivers-x86-v5.1-1' of git://git.infradead.org/linux-platform-drivers-x86: (50 commits)
  MAINTAINERS: Include mlxreg.h in Mellanox Platform Driver files
  platform/x86: ideapad-laptop: Add S130-14IGM to no_hw_rfkill list
  platform/x86: mlx-platform: Fix access mode for fan_dir attribute
  platform/x86: mlx-platform: Add UID LED for the next generation systems
  platform/x86: mlx-platform: Add extra CPLD for next generation systems
  platform/x86: wmi-bmof: use MODULE_DEVICE_TABLE() instead of MODULE_ALIAS()
  platform/x86: intel-wmi-thunderbolt: use MODULE_DEVICE_TABLE() instead of MODULE_ALIAS()
  platform/x86: huawei-wmi: use MODULE_DEVICE_TABLE() instead of MODULE_ALIAS()
  platform/x86: dell-wmi: use MODULE_DEVICE_TABLE() instead of MODULE_ALIAS()
  platform/x86: dell-wmi-descriptor: use MODULE_DEVICE_TABLE() instead of MODULE_ALIAS()
  platform/x86: dell-smbios-wmi: use MODULE_DEVICE_TABLE() instead of MODULE_ALIAS()
  platform/x86: wmi: add WMI support to MODULE_DEVICE_TABLE()
  platform/x86: wmi: move struct wmi_device_id to mod_devicetable.h
  modpost: file2alias: define size of alias
  platform/x86: touchscreen_dmi: Add info for the CHUWI Hi10 Air tablet
  platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list
  platform/x86: ideapad-laptop: Add Yoga C930 to no_hw_rfkill_list
  platform/x86: intel_pmc_core: Quirk to ignore XTAL shutdown
  platform/x86: intel_pmc_core: Add Package cstates residency info
  platform/x86: intel_pmc_core: Add ICL platform support
  ...
parents 45ba8d5d 9c22cc02
...@@ -21,7 +21,19 @@ Description: These files show with which CPLD versions have been burned ...@@ -21,7 +21,19 @@ Description: These files show with which CPLD versions have been burned
The files are read only. The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/ What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/
cpld3_version fan_dir
Date: December 2018
KernelVersion: 5.0
Contact: Vadim Pasternak <vadimpmellanox.com>
Description: This file shows the system fans direction:
forward direction - relevant bit is set 0;
reversed direction - relevant bit is set 1.
The files are read only.
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/
jtag_enable
Date: November 2018 Date: November 2018
KernelVersion: 5.0 KernelVersion: 5.0
......
...@@ -9900,6 +9900,7 @@ M: Vadim Pasternak <vadimp@mellanox.com> ...@@ -9900,6 +9900,7 @@ M: Vadim Pasternak <vadimp@mellanox.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
S: Supported S: Supported
F: drivers/platform/mellanox/ F: drivers/platform/mellanox/
F: include/linux/platform_data/mlxreg.h
MELLANOX MLX4 core VPI driver MELLANOX MLX4 core VPI driver
M: Tariq Toukan <tariqt@mellanox.com> M: Tariq Toukan <tariqt@mellanox.com>
......
...@@ -1545,6 +1545,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) ...@@ -1545,6 +1545,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
*/ */
static const struct acpi_device_id i2c_multi_instantiate_ids[] = { static const struct acpi_device_id i2c_multi_instantiate_ids[] = {
{"BSG1160", }, {"BSG1160", },
{"BSG2150", },
{"INT33FE", }, {"INT33FE", },
{"INT3515", }, {"INT3515", },
{} {}
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define MLXREG_LED_AMBER_SOLID 0x09 /* Solid amber */ #define MLXREG_LED_AMBER_SOLID 0x09 /* Solid amber */
#define MLXREG_LED_BLINK_3HZ 167 /* ~167 msec off/on - HW support */ #define MLXREG_LED_BLINK_3HZ 167 /* ~167 msec off/on - HW support */
#define MLXREG_LED_BLINK_6HZ 83 /* ~83 msec off/on - HW support */ #define MLXREG_LED_BLINK_6HZ 83 /* ~83 msec off/on - HW support */
#define MLXREG_LED_CAPABILITY_CLEAR GENMASK(31, 8) /* Clear mask */
/** /**
* struct mlxreg_led_data - led control data: * struct mlxreg_led_data - led control data:
...@@ -187,6 +188,7 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv) ...@@ -187,6 +188,7 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv)
struct mlxreg_led_data *led_data; struct mlxreg_led_data *led_data;
struct led_classdev *led_cdev; struct led_classdev *led_cdev;
enum led_brightness brightness; enum led_brightness brightness;
u32 regval;
int i; int i;
int err; int err;
...@@ -196,6 +198,23 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv) ...@@ -196,6 +198,23 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv)
if (!led_data) if (!led_data)
return -ENOMEM; return -ENOMEM;
if (data->capability) {
err = regmap_read(led_pdata->regmap, data->capability,
&regval);
if (err) {
dev_err(&priv->pdev->dev, "Failed to query capability register\n");
return err;
}
if (!(regval & data->bit))
continue;
/*
* Field "bit" can contain one capability bit in 0 byte
* and offset bit in 1-3 bytes. Clear capability bit and
* keep only offset bit.
*/
data->bit &= MLXREG_LED_CAPABILITY_CLEAR;
}
led_cdev = &led_data->led_cdev; led_cdev = &led_data->led_cdev;
led_data->data_parent = priv; led_data->data_parent = priv;
if (strstr(data->label, "red") || if (strstr(data->label, "red") ||
......
...@@ -248,7 +248,8 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv, ...@@ -248,7 +248,8 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
struct mlxreg_core_item *item) struct mlxreg_core_item *item)
{ {
struct mlxreg_core_data *data; struct mlxreg_core_data *data;
u32 asserted, regval, bit; unsigned long asserted;
u32 regval, bit;
int ret; int ret;
/* /*
...@@ -281,7 +282,7 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv, ...@@ -281,7 +282,7 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
asserted = item->cache ^ regval; asserted = item->cache ^ regval;
item->cache = regval; item->cache = regval;
for_each_set_bit(bit, (unsigned long *)&asserted, 8) { for_each_set_bit(bit, &asserted, 8) {
data = item->data + bit; data = item->data + bit;
if (regval & BIT(bit)) { if (regval & BIT(bit)) {
if (item->inversed) if (item->inversed)
...@@ -495,7 +496,9 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv) ...@@ -495,7 +496,9 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
{ {
struct mlxreg_core_hotplug_platform_data *pdata; struct mlxreg_core_hotplug_platform_data *pdata;
struct mlxreg_core_item *item; struct mlxreg_core_item *item;
int i, ret; struct mlxreg_core_data *data;
u32 regval;
int i, j, ret;
pdata = dev_get_platdata(&priv->pdev->dev); pdata = dev_get_platdata(&priv->pdev->dev);
item = pdata->items; item = pdata->items;
...@@ -507,6 +510,25 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv) ...@@ -507,6 +510,25 @@ static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
if (ret) if (ret)
goto out; goto out;
/*
* Verify if hardware configuration requires to disable
* interrupt capability for some of components.
*/
data = item->data;
for (j = 0; j < item->count; j++, data++) {
/* Verify if the attribute has capability register. */
if (data->capability) {
/* Read capability register. */
ret = regmap_read(priv->regmap,
data->capability, &regval);
if (ret)
goto out;
if (!(regval & data->bit))
item->mask &= ~BIT(j);
}
}
/* Set group initial status as mask and unmask group event. */ /* Set group initial status as mask and unmask group event. */
if (item->inversed) { if (item->inversed) {
item->cache = item->mask; item->cache = item->mask;
......
...@@ -2265,12 +2265,12 @@ static int asus_wmi_probe(struct platform_device *pdev) ...@@ -2265,12 +2265,12 @@ static int asus_wmi_probe(struct platform_device *pdev)
int ret; int ret;
if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
pr_warn("Management GUID not found\n"); pr_warn("ASUS Management GUID not found\n");
return -ENODEV; return -ENODEV;
} }
if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
pr_warn("Event GUID not found\n"); pr_warn("ASUS Event GUID not found\n");
return -ENODEV; return -ENODEV;
} }
...@@ -2320,11 +2320,6 @@ EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver); ...@@ -2320,11 +2320,6 @@ EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
static int __init asus_wmi_init(void) static int __init asus_wmi_init(void)
{ {
if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
pr_info("Asus Management GUID not found\n");
return -ENODEV;
}
pr_info("ASUS WMI generic driver loaded\n"); pr_info("ASUS WMI generic driver loaded\n");
return 0; return 0;
} }
......
...@@ -277,4 +277,4 @@ void exit_dell_smbios_wmi(void) ...@@ -277,4 +277,4 @@ void exit_dell_smbios_wmi(void)
wmi_driver_unregister(&dell_smbios_wmi_driver); wmi_driver_unregister(&dell_smbios_wmi_driver);
} }
MODULE_ALIAS("wmi:" DELL_WMI_SMBIOS_GUID); MODULE_DEVICE_TABLE(wmi, dell_smbios_wmi_id_table);
...@@ -207,7 +207,7 @@ static struct wmi_driver dell_wmi_descriptor_driver = { ...@@ -207,7 +207,7 @@ static struct wmi_driver dell_wmi_descriptor_driver = {
module_wmi_driver(dell_wmi_descriptor_driver); module_wmi_driver(dell_wmi_descriptor_driver);
MODULE_ALIAS("wmi:" DELL_WMI_DESCRIPTOR_GUID); MODULE_DEVICE_TABLE(wmi, dell_wmi_descriptor_id_table);
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>"); MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
MODULE_DESCRIPTION("Dell WMI descriptor driver"); MODULE_DESCRIPTION("Dell WMI descriptor driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -50,8 +50,6 @@ MODULE_LICENSE("GPL"); ...@@ -50,8 +50,6 @@ MODULE_LICENSE("GPL");
static bool wmi_requires_smbios_request; static bool wmi_requires_smbios_request;
MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
struct dell_wmi_priv { struct dell_wmi_priv {
struct input_dev *input_dev; struct input_dev *input_dev;
u32 interface_version; u32 interface_version;
...@@ -267,6 +265,9 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = { ...@@ -267,6 +265,9 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = {
/* Fn-lock switched to multimedia keys */ /* Fn-lock switched to multimedia keys */
{ KE_IGNORE, 0x1, { KEY_RESERVED } }, { KE_IGNORE, 0x1, { KEY_RESERVED } },
/* Keyboard backlight change notification */
{ KE_IGNORE, 0x3f, { KEY_RESERVED } },
/* Mic mute */ /* Mic mute */
{ KE_KEY, 0x150, { KEY_MICMUTE } }, { KE_KEY, 0x150, { KEY_MICMUTE } },
...@@ -738,3 +739,5 @@ static void __exit dell_wmi_exit(void) ...@@ -738,3 +739,5 @@ static void __exit dell_wmi_exit(void)
wmi_driver_unregister(&dell_wmi_driver); wmi_driver_unregister(&dell_wmi_driver);
} }
module_exit(dell_wmi_exit); module_exit(dell_wmi_exit);
MODULE_DEVICE_TABLE(wmi, dell_wmi_id_table);
...@@ -59,7 +59,6 @@ static struct _rbu_data { ...@@ -59,7 +59,6 @@ static struct _rbu_data {
unsigned long image_update_buffer_size; unsigned long image_update_buffer_size;
unsigned long bios_image_size; unsigned long bios_image_size;
int image_update_ordernum; int image_update_ordernum;
int dma_alloc;
spinlock_t lock; spinlock_t lock;
unsigned long packet_read_count; unsigned long packet_read_count;
unsigned long num_packets; unsigned long num_packets;
...@@ -89,7 +88,6 @@ static struct packet_data packet_data_head; ...@@ -89,7 +88,6 @@ static struct packet_data packet_data_head;
static struct platform_device *rbu_device; static struct platform_device *rbu_device;
static int context; static int context;
static dma_addr_t dell_rbu_dmaaddr;
static void init_packet_head(void) static void init_packet_head(void)
{ {
...@@ -380,10 +378,6 @@ static void img_update_free(void) ...@@ -380,10 +378,6 @@ static void img_update_free(void)
*/ */
memset(rbu_data.image_update_buffer, 0, memset(rbu_data.image_update_buffer, 0,
rbu_data.image_update_buffer_size); rbu_data.image_update_buffer_size);
if (rbu_data.dma_alloc == 1)
dma_free_coherent(NULL, rbu_data.bios_image_size,
rbu_data.image_update_buffer, dell_rbu_dmaaddr);
else
free_pages((unsigned long) rbu_data.image_update_buffer, free_pages((unsigned long) rbu_data.image_update_buffer,
rbu_data.image_update_ordernum); rbu_data.image_update_ordernum);
...@@ -394,7 +388,6 @@ static void img_update_free(void) ...@@ -394,7 +388,6 @@ static void img_update_free(void)
rbu_data.image_update_buffer = NULL; rbu_data.image_update_buffer = NULL;
rbu_data.image_update_buffer_size = 0; rbu_data.image_update_buffer_size = 0;
rbu_data.bios_image_size = 0; rbu_data.bios_image_size = 0;
rbu_data.dma_alloc = 0;
} }
/* /*
...@@ -410,10 +403,8 @@ static void img_update_free(void) ...@@ -410,10 +403,8 @@ static void img_update_free(void)
static int img_update_realloc(unsigned long size) static int img_update_realloc(unsigned long size)
{ {
unsigned char *image_update_buffer = NULL; unsigned char *image_update_buffer = NULL;
unsigned long rc;
unsigned long img_buf_phys_addr; unsigned long img_buf_phys_addr;
int ordernum; int ordernum;
int dma_alloc = 0;
/* /*
* check if the buffer of sufficient size has been * check if the buffer of sufficient size has been
...@@ -444,36 +435,23 @@ static int img_update_realloc(unsigned long size) ...@@ -444,36 +435,23 @@ static int img_update_realloc(unsigned long size)
ordernum = get_order(size); ordernum = get_order(size);
image_update_buffer = image_update_buffer =
(unsigned char *) __get_free_pages(GFP_KERNEL, ordernum); (unsigned char *)__get_free_pages(GFP_DMA32, ordernum);
spin_lock(&rbu_data.lock);
img_buf_phys_addr = if (!image_update_buffer) {
(unsigned long) virt_to_phys(image_update_buffer); pr_debug("Not enough memory for image update:"
"size = %ld\n", size);
if (img_buf_phys_addr > BIOS_SCAN_LIMIT) { return -ENOMEM;
free_pages((unsigned long) image_update_buffer, ordernum);
ordernum = -1;
image_update_buffer = dma_alloc_coherent(NULL, size,
&dell_rbu_dmaaddr, GFP_KERNEL);
dma_alloc = 1;
} }
spin_lock(&rbu_data.lock); img_buf_phys_addr = (unsigned long)virt_to_phys(image_update_buffer);
if (WARN_ON_ONCE(img_buf_phys_addr > BIOS_SCAN_LIMIT))
return -EINVAL; /* can't happen per definition */
if (image_update_buffer != NULL) {
rbu_data.image_update_buffer = image_update_buffer; rbu_data.image_update_buffer = image_update_buffer;
rbu_data.image_update_buffer_size = size; rbu_data.image_update_buffer_size = size;
rbu_data.bios_image_size = rbu_data.bios_image_size = rbu_data.image_update_buffer_size;
rbu_data.image_update_buffer_size;
rbu_data.image_update_ordernum = ordernum; rbu_data.image_update_ordernum = ordernum;
rbu_data.dma_alloc = dma_alloc; return 0;
rc = 0;
} else {
pr_debug("Not enough memory for image update:"
"size = %ld\n", size);
rc = -ENOMEM;
}
return rc;
} }
static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count) static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
......
...@@ -201,8 +201,7 @@ static struct wmi_driver huawei_wmi_driver = { ...@@ -201,8 +201,7 @@ static struct wmi_driver huawei_wmi_driver = {
module_wmi_driver(huawei_wmi_driver); module_wmi_driver(huawei_wmi_driver);
MODULE_ALIAS("wmi:"WMI0_EVENT_GUID); MODULE_DEVICE_TABLE(wmi, huawei_wmi_id_table);
MODULE_ALIAS("wmi:"AMW0_EVENT_GUID);
MODULE_AUTHOR("Ayman Bagabas <ayman.bagabas@gmail.com>"); MODULE_AUTHOR("Ayman Bagabas <ayman.bagabas@gmail.com>");
MODULE_DESCRIPTION("Huawei WMI hotkeys"); MODULE_DESCRIPTION("Huawei WMI hotkeys");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -159,6 +159,14 @@ static const struct i2c_inst_data bsg1160_data[] = { ...@@ -159,6 +159,14 @@ static const struct i2c_inst_data bsg1160_data[] = {
{} {}
}; };
static const struct i2c_inst_data bsg2150_data[] = {
{ "bmc150_accel", IRQ_RESOURCE_GPIO, 0 },
{ "bmc150_magn" },
/* The resources describe a 3th client, but it is not really there. */
{ "bsg2150_dummy_dev" },
{}
};
static const struct i2c_inst_data int3515_data[] = { static const struct i2c_inst_data int3515_data[] = {
{ "tps6598x", IRQ_RESOURCE_APIC, 0 }, { "tps6598x", IRQ_RESOURCE_APIC, 0 },
{ "tps6598x", IRQ_RESOURCE_APIC, 1 }, { "tps6598x", IRQ_RESOURCE_APIC, 1 },
...@@ -173,6 +181,7 @@ static const struct i2c_inst_data int3515_data[] = { ...@@ -173,6 +181,7 @@ static const struct i2c_inst_data int3515_data[] = {
*/ */
static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = { static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = {
{ "BSG1160", (unsigned long)bsg1160_data }, { "BSG1160", (unsigned long)bsg1160_data },
{ "BSG2150", (unsigned long)bsg2150_data },
{ "INT3515", (unsigned long)int3515_data }, { "INT3515", (unsigned long)int3515_data },
{ } { }
}; };
......
...@@ -989,7 +989,7 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { ...@@ -989,7 +989,7 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
.ident = "Lenovo RESCUER R720-15IKBN", .ident = "Lenovo RESCUER R720-15IKBN",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_BOARD_NAME, "80WW"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo R720-15IKBN"),
}, },
}, },
{ {
...@@ -1090,6 +1090,27 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { ...@@ -1090,6 +1090,27 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15ISK"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15ISK"),
}, },
}, },
{
.ident = "Lenovo ideapad 330-15ICH",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 330-15ICH"),
},
},
{
.ident = "Lenovo ideapad 530S-14ARR",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 530S-14ARR"),
},
},
{
.ident = "Lenovo ideapad S130-14IGM",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad S130-14IGM"),
},
},
{ {
.ident = "Lenovo ideapad Y700-14ISK", .ident = "Lenovo ideapad Y700-14ISK",
.matches = { .matches = {
...@@ -1153,6 +1174,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { ...@@ -1153,6 +1174,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion Y530-15ICH"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion Y530-15ICH"),
}, },
}, },
{
.ident = "Lenovo Legion Y530-15ICH-1060",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion Y530-15ICH-1060"),
},
},
{ {
.ident = "Lenovo Legion Y720-15IKB", .ident = "Lenovo Legion Y720-15IKB",
.matches = { .matches = {
...@@ -1244,6 +1272,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { ...@@ -1244,6 +1272,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920-13IKB"), DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920-13IKB"),
}, },
}, },
{
.ident = "Lenovo YOGA C930-13IKB",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA C930-13IKB"),
},
},
{ {
.ident = "Lenovo Zhaoyang E42-80", .ident = "Lenovo Zhaoyang E42-80",
.matches = { .matches = {
......
...@@ -363,7 +363,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) ...@@ -363,7 +363,7 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
* the 5-button array, but still send notifies with power button * the 5-button array, but still send notifies with power button
* event code to this device object on power button actions. * event code to this device object on power button actions.
* *
* Report the power button press; catch and ignore the button release. * Report the power button press and release.
*/ */
if (!priv->array) { if (!priv->array) {
if (event == 0xce) { if (event == 0xce) {
...@@ -372,9 +372,12 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) ...@@ -372,9 +372,12 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
return; return;
} }
if (event == 0xcf) if (event == 0xcf) {
input_report_key(priv->input_dev, KEY_POWER, 0);
input_sync(priv->input_dev);
return; return;
} }
}
/* 0xC0 is for HID events, other values are for 5 button array */ /* 0xC0 is for HID events, other values are for 5 button array */
if (event != 0xc0) { if (event != 0xc0) {
......
...@@ -88,7 +88,7 @@ static struct wmi_driver intel_wmi_thunderbolt_driver = { ...@@ -88,7 +88,7 @@ static struct wmi_driver intel_wmi_thunderbolt_driver = {
module_wmi_driver(intel_wmi_thunderbolt_driver); module_wmi_driver(intel_wmi_thunderbolt_driver);
MODULE_ALIAS("wmi:" INTEL_WMI_THUNDERBOLT_GUID); MODULE_DEVICE_TABLE(wmi, intel_wmi_thunderbolt_id_table);
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>"); MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver"); MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -51,11 +51,14 @@ ...@@ -51,11 +51,14 @@
#define GPE0A_STS_PORT 0x420 #define GPE0A_STS_PORT 0x420
#define GPE0A_EN_PORT 0x428 #define GPE0A_EN_PORT 0x428
#define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } #define BAYTRAIL 0x01
#define CHERRYTRAIL 0x02
#define ICPU(model, data) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, data }
static const struct x86_cpu_id int0002_cpu_ids[] = { static const struct x86_cpu_id int0002_cpu_ids[] = {
ICPU(INTEL_FAM6_ATOM_SILVERMONT), /* Valleyview, Bay Trail */ ICPU(INTEL_FAM6_ATOM_SILVERMONT, BAYTRAIL), /* Valleyview, Bay Trail */
ICPU(INTEL_FAM6_ATOM_AIRMONT), /* Braswell, Cherry Trail */ ICPU(INTEL_FAM6_ATOM_AIRMONT, CHERRYTRAIL), /* Braswell, Cherry Trail */
{} {}
}; };
...@@ -135,7 +138,7 @@ static irqreturn_t int0002_irq(int irq, void *data) ...@@ -135,7 +138,7 @@ static irqreturn_t int0002_irq(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static struct irq_chip int0002_irqchip = { static struct irq_chip int0002_byt_irqchip = {
.name = DRV_NAME, .name = DRV_NAME,
.irq_ack = int0002_irq_ack, .irq_ack = int0002_irq_ack,
.irq_mask = int0002_irq_mask, .irq_mask = int0002_irq_mask,
...@@ -143,10 +146,22 @@ static struct irq_chip int0002_irqchip = { ...@@ -143,10 +146,22 @@ static struct irq_chip int0002_irqchip = {
.irq_set_wake = int0002_irq_set_wake, .irq_set_wake = int0002_irq_set_wake,
}; };
static struct irq_chip int0002_cht_irqchip = {
.name = DRV_NAME,
.irq_ack = int0002_irq_ack,
.irq_mask = int0002_irq_mask,
.irq_unmask = int0002_irq_unmask,
/*
* No set_wake, on CHT the IRQ is typically shared with the ACPI SCI
* and we don't want to mess with the ACPI SCI irq settings.
*/
};
static int int0002_probe(struct platform_device *pdev) static int int0002_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct x86_cpu_id *cpu_id; const struct x86_cpu_id *cpu_id;
struct irq_chip *irq_chip;
struct gpio_chip *chip; struct gpio_chip *chip;
int irq, ret; int irq, ret;
...@@ -195,14 +210,19 @@ static int int0002_probe(struct platform_device *pdev) ...@@ -195,14 +210,19 @@ static int int0002_probe(struct platform_device *pdev)
return ret; return ret;
} }
ret = gpiochip_irqchip_add(chip, &int0002_irqchip, 0, handle_edge_irq, if (cpu_id->driver_data == BAYTRAIL)
irq_chip = &int0002_byt_irqchip;
else
irq_chip = &int0002_cht_irqchip;
ret = gpiochip_irqchip_add(chip, irq_chip, 0, handle_edge_irq,
IRQ_TYPE_NONE); IRQ_TYPE_NONE);
if (ret) { if (ret) {
dev_err(dev, "Error adding irqchip: %d\n", ret); dev_err(dev, "Error adding irqchip: %d\n", ret);
return ret; return ret;
} }
gpiochip_set_chained_irqchip(chip, &int0002_irqchip, irq, NULL); gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL);
return 0; return 0;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -22,14 +23,24 @@ ...@@ -22,14 +23,24 @@
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/intel-family.h> #include <asm/intel-family.h>
#include <asm/msr.h>
#include "intel_pmc_core.h" #include "intel_pmc_core.h"
#define ICPU(model, data) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (kernel_ulong_t)data }
static struct pmc_dev pmc; static struct pmc_dev pmc;
/* PKGC MSRs are common across Intel Core SoCs */
static const struct pmc_bit_map msr_map[] = {
{"Package C2", MSR_PKG_C2_RESIDENCY},
{"Package C3", MSR_PKG_C3_RESIDENCY},
{"Package C6", MSR_PKG_C6_RESIDENCY},
{"Package C7", MSR_PKG_C7_RESIDENCY},
{"Package C8", MSR_PKG_C8_RESIDENCY},
{"Package C9", MSR_PKG_C9_RESIDENCY},
{"Package C10", MSR_PKG_C10_RESIDENCY},
{}
};
static const struct pmc_bit_map spt_pll_map[] = { static const struct pmc_bit_map spt_pll_map[] = {
{"MIPI PLL", SPT_PMC_BIT_MPHY_CMN_LANE0}, {"MIPI PLL", SPT_PMC_BIT_MPHY_CMN_LANE0},
{"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1}, {"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1},
...@@ -108,6 +119,7 @@ static const struct pmc_bit_map spt_ltr_show_map[] = { ...@@ -108,6 +119,7 @@ static const struct pmc_bit_map spt_ltr_show_map[] = {
{"SATA", SPT_PMC_LTR_SATA}, {"SATA", SPT_PMC_LTR_SATA},
{"GIGABIT_ETHERNET", SPT_PMC_LTR_GBE}, {"GIGABIT_ETHERNET", SPT_PMC_LTR_GBE},
{"XHCI", SPT_PMC_LTR_XHCI}, {"XHCI", SPT_PMC_LTR_XHCI},
{"Reserved", SPT_PMC_LTR_RESERVED},
{"ME", SPT_PMC_LTR_ME}, {"ME", SPT_PMC_LTR_ME},
/* EVA is Enterprise Value Add, doesn't really exist on PCH */ /* EVA is Enterprise Value Add, doesn't really exist on PCH */
{"EVA", SPT_PMC_LTR_EVA}, {"EVA", SPT_PMC_LTR_EVA},
...@@ -131,6 +143,7 @@ static const struct pmc_reg_map spt_reg_map = { ...@@ -131,6 +143,7 @@ static const struct pmc_reg_map spt_reg_map = {
.mphy_sts = spt_mphy_map, .mphy_sts = spt_mphy_map,
.pll_sts = spt_pll_map, .pll_sts = spt_pll_map,
.ltr_show_sts = spt_ltr_show_map, .ltr_show_sts = spt_ltr_show_map,
.msr_sts = msr_map,
.slp_s0_offset = SPT_PMC_SLP_S0_RES_COUNTER_OFFSET, .slp_s0_offset = SPT_PMC_SLP_S0_RES_COUNTER_OFFSET,
.ltr_ignore_offset = SPT_PMC_LTR_IGNORE_OFFSET, .ltr_ignore_offset = SPT_PMC_LTR_IGNORE_OFFSET,
.regmap_length = SPT_PMC_MMIO_REG_LEN, .regmap_length = SPT_PMC_MMIO_REG_LEN,
...@@ -139,6 +152,7 @@ static const struct pmc_reg_map spt_reg_map = { ...@@ -139,6 +152,7 @@ static const struct pmc_reg_map spt_reg_map = {
.pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT,
.ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED,
.pm_vric1_offset = SPT_PMC_VRIC1_OFFSET,
}; };
/* Cannonlake: PGD PFET Enable Ack Status Register(s) bitmap */ /* Cannonlake: PGD PFET Enable Ack Status Register(s) bitmap */
...@@ -168,25 +182,26 @@ static const struct pmc_bit_map cnp_pfear_map[] = { ...@@ -168,25 +182,26 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"SDX", BIT(4)}, {"SDX", BIT(4)},
{"SPE", BIT(5)}, {"SPE", BIT(5)},
{"Fuse", BIT(6)}, {"Fuse", BIT(6)},
{"Res_23", BIT(7)}, /* Reserved for Cannonlake but valid for Icelake */
{"SBR8", BIT(7)},
{"CSME_FSC", BIT(0)}, {"CSME_FSC", BIT(0)},
{"USB3_OTG", BIT(1)}, {"USB3_OTG", BIT(1)},
{"EXI", BIT(2)}, {"EXI", BIT(2)},
{"CSE", BIT(3)}, {"CSE", BIT(3)},
{"csme_kvm", BIT(4)}, {"CSME_KVM", BIT(4)},
{"csme_pmt", BIT(5)}, {"CSME_PMT", BIT(5)},
{"csme_clink", BIT(6)}, {"CSME_CLINK", BIT(6)},
{"csme_ptio", BIT(7)}, {"CSME_PTIO", BIT(7)},
{"csme_usbr", BIT(0)}, {"CSME_USBR", BIT(0)},
{"csme_susram", BIT(1)}, {"CSME_SUSRAM", BIT(1)},
{"csme_smt1", BIT(2)}, {"CSME_SMT1", BIT(2)},
{"CSME_SMT4", BIT(3)}, {"CSME_SMT4", BIT(3)},
{"csme_sms2", BIT(4)}, {"CSME_SMS2", BIT(4)},
{"csme_sms1", BIT(5)}, {"CSME_SMS1", BIT(5)},
{"csme_rtc", BIT(6)}, {"CSME_RTC", BIT(6)},
{"csme_psf", BIT(7)}, {"CSME_PSF", BIT(7)},
{"SBR0", BIT(0)}, {"SBR0", BIT(0)},
{"SBR1", BIT(1)}, {"SBR1", BIT(1)},
...@@ -203,7 +218,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = { ...@@ -203,7 +218,7 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"CNVI", BIT(3)}, {"CNVI", BIT(3)},
{"UFS0", BIT(4)}, {"UFS0", BIT(4)},
{"EMMC", BIT(5)}, {"EMMC", BIT(5)},
{"Res_6", BIT(6)}, {"SPF", BIT(6)},
{"SBR6", BIT(7)}, {"SBR6", BIT(7)},
{"SBR7", BIT(0)}, {"SBR7", BIT(0)},
...@@ -211,6 +226,20 @@ static const struct pmc_bit_map cnp_pfear_map[] = { ...@@ -211,6 +226,20 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
{"HDA_PGD4", BIT(2)}, {"HDA_PGD4", BIT(2)},
{"HDA_PGD5", BIT(3)}, {"HDA_PGD5", BIT(3)},
{"HDA_PGD6", BIT(4)}, {"HDA_PGD6", BIT(4)},
/* Reserved for Cannonlake but valid for Icelake */
{"PSF6", BIT(5)},
{"PSF7", BIT(6)},
{"PSF8", BIT(7)},
/* Icelake generation onwards only */
{"RES_65", BIT(0)},
{"RES_66", BIT(1)},
{"RES_67", BIT(2)},
{"TAM", BIT(3)},
{"GBETSN", BIT(4)},
{"TBTLSX", BIT(5)},
{"RES_71", BIT(6)},
{"RES_72", BIT(7)},
{} {}
}; };
...@@ -276,6 +305,7 @@ static const struct pmc_bit_map cnp_ltr_show_map[] = { ...@@ -276,6 +305,7 @@ static const struct pmc_bit_map cnp_ltr_show_map[] = {
{"SATA", CNP_PMC_LTR_SATA}, {"SATA", CNP_PMC_LTR_SATA},
{"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE}, {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE},
{"XHCI", CNP_PMC_LTR_XHCI}, {"XHCI", CNP_PMC_LTR_XHCI},
{"Reserved", CNP_PMC_LTR_RESERVED},
{"ME", CNP_PMC_LTR_ME}, {"ME", CNP_PMC_LTR_ME},
/* EVA is Enterprise Value Add, doesn't really exist on PCH */ /* EVA is Enterprise Value Add, doesn't really exist on PCH */
{"EVA", CNP_PMC_LTR_EVA}, {"EVA", CNP_PMC_LTR_EVA},
...@@ -291,6 +321,8 @@ static const struct pmc_bit_map cnp_ltr_show_map[] = { ...@@ -291,6 +321,8 @@ static const struct pmc_bit_map cnp_ltr_show_map[] = {
{"ISH", CNP_PMC_LTR_ISH}, {"ISH", CNP_PMC_LTR_ISH},
{"UFSX2", CNP_PMC_LTR_UFSX2}, {"UFSX2", CNP_PMC_LTR_UFSX2},
{"EMMC", CNP_PMC_LTR_EMMC}, {"EMMC", CNP_PMC_LTR_EMMC},
/* Reserved for Cannonlake but valid for Icelake */
{"WIGIG", ICL_PMC_LTR_WIGIG},
/* Below two cannot be used for LTR_IGNORE */ /* Below two cannot be used for LTR_IGNORE */
{"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT},
{"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT}, {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT},
...@@ -302,6 +334,7 @@ static const struct pmc_reg_map cnp_reg_map = { ...@@ -302,6 +334,7 @@ static const struct pmc_reg_map cnp_reg_map = {
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps, .slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map, .ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map,
.slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET, .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
.regmap_length = CNP_PMC_MMIO_REG_LEN, .regmap_length = CNP_PMC_MMIO_REG_LEN,
...@@ -312,6 +345,22 @@ static const struct pmc_reg_map cnp_reg_map = { ...@@ -312,6 +345,22 @@ static const struct pmc_reg_map cnp_reg_map = {
.ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED,
}; };
static const struct pmc_reg_map icl_reg_map = {
.pfear_sts = cnp_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slps0_dbg_maps = cnp_slps0_dbg_maps,
.ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map,
.slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
.regmap_length = CNP_PMC_MMIO_REG_LEN,
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
.ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
.ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED,
};
static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset) static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
{ {
return readb(pmcdev->regbase + offset); return readb(pmcdev->regbase + offset);
...@@ -328,9 +377,9 @@ static inline void pmc_core_reg_write(struct pmc_dev *pmcdev, int ...@@ -328,9 +377,9 @@ static inline void pmc_core_reg_write(struct pmc_dev *pmcdev, int
writel(val, pmcdev->regbase + reg_offset); writel(val, pmcdev->regbase + reg_offset);
} }
static inline u32 pmc_core_adjust_slp_s0_step(u32 value) static inline u64 pmc_core_adjust_slp_s0_step(u32 value)
{ {
return value * SPT_PMC_SLP_S0_RES_COUNTER_STEP; return (u64)value * SPT_PMC_SLP_S0_RES_COUNTER_STEP;
} }
static int pmc_core_dev_state_get(void *data, u64 *val) static int pmc_core_dev_state_get(void *data, u64 *val)
...@@ -380,7 +429,8 @@ static int pmc_core_ppfear_show(struct seq_file *s, void *unused) ...@@ -380,7 +429,8 @@ static int pmc_core_ppfear_show(struct seq_file *s, void *unused)
index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++) index < PPFEAR_MAX_NUM_ENTRIES; index++, iter++)
pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter); pf_regs[index] = pmc_core_reg_read_byte(pmcdev, iter);
for (index = 0; map[index].name; index++) for (index = 0; map[index].name &&
index < pmcdev->map->ppfear_buckets * 8; index++)
pmc_core_display_map(s, index, pf_regs[index / 8], map); pmc_core_display_map(s, index, pf_regs[index / 8], map);
return 0; return 0;
...@@ -677,6 +727,25 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused) ...@@ -677,6 +727,25 @@ static int pmc_core_ltr_show(struct seq_file *s, void *unused)
} }
DEFINE_SHOW_ATTRIBUTE(pmc_core_ltr); DEFINE_SHOW_ATTRIBUTE(pmc_core_ltr);
static int pmc_core_pkgc_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
const struct pmc_bit_map *map = pmcdev->map->msr_sts;
u64 pcstate_count;
int index;
for (index = 0; map[index].name ; index++) {
if (rdmsrl_safe(map[index].bit_mask, &pcstate_count))
continue;
seq_printf(s, "%-8s : 0x%llx\n", map[index].name,
pcstate_count);
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_pkgc);
static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
{ {
debugfs_remove_recursive(pmcdev->dbgfs_dir); debugfs_remove_recursive(pmcdev->dbgfs_dir);
...@@ -701,7 +770,10 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev) ...@@ -701,7 +770,10 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
debugfs_create_file("ltr_ignore", 0644, dir, pmcdev, debugfs_create_file("ltr_ignore", 0644, dir, pmcdev,
&pmc_core_ltr_ignore_ops); &pmc_core_ltr_ignore_ops);
debugfs_create_file("ltr_show", 0644, dir, pmcdev, &pmc_core_ltr_fops); debugfs_create_file("ltr_show", 0444, dir, pmcdev, &pmc_core_ltr_fops);
debugfs_create_file("package_cstate_show", 0444, dir, pmcdev,
&pmc_core_pkgc_fops);
if (pmcdev->map->pll_sts) if (pmcdev->map->pll_sts)
debugfs_create_file("pll_status", 0444, dir, pmcdev, debugfs_create_file("pll_status", 0444, dir, pmcdev,
...@@ -735,11 +807,12 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) ...@@ -735,11 +807,12 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
static const struct x86_cpu_id intel_pmc_core_ids[] = { static const struct x86_cpu_id intel_pmc_core_ids[] = {
ICPU(INTEL_FAM6_SKYLAKE_MOBILE, &spt_reg_map), INTEL_CPU_FAM6(SKYLAKE_MOBILE, spt_reg_map),
ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, &spt_reg_map), INTEL_CPU_FAM6(SKYLAKE_DESKTOP, spt_reg_map),
ICPU(INTEL_FAM6_KABYLAKE_MOBILE, &spt_reg_map), INTEL_CPU_FAM6(KABYLAKE_MOBILE, spt_reg_map),
ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, &spt_reg_map), INTEL_CPU_FAM6(KABYLAKE_DESKTOP, spt_reg_map),
ICPU(INTEL_FAM6_CANNONLAKE_MOBILE, &cnp_reg_map), INTEL_CPU_FAM6(CANNONLAKE_MOBILE, cnp_reg_map),
INTEL_CPU_FAM6(ICELAKE_MOBILE, icl_reg_map),
{} {}
}; };
...@@ -750,6 +823,37 @@ static const struct pci_device_id pmc_pci_ids[] = { ...@@ -750,6 +823,37 @@ static const struct pci_device_id pmc_pci_ids[] = {
{ 0, }, { 0, },
}; };
/*
* This quirk can be used on those platforms where
* the platform BIOS enforces 24Mhx Crystal to shutdown
* before PMC can assert SLP_S0#.
*/
int quirk_xtal_ignore(const struct dmi_system_id *id)
{
struct pmc_dev *pmcdev = &pmc;
u32 value;
value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_vric1_offset);
/* 24MHz Crystal Shutdown Qualification Disable */
value |= SPT_PMC_VRIC1_XTALSDQDIS;
/* Low Voltage Mode Enable */
value &= ~SPT_PMC_VRIC1_SLPS0LVEN;
pmc_core_reg_write(pmcdev, pmcdev->map->pm_vric1_offset, value);
return 0;
}
static const struct dmi_system_id pmc_core_dmi_table[] = {
{
.callback = quirk_xtal_ignore,
.ident = "HP Elite x2 1013 G3",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite x2 1013 G3"),
},
},
{}
};
static int __init pmc_core_probe(void) static int __init pmc_core_probe(void)
{ {
struct pmc_dev *pmcdev = &pmc; struct pmc_dev *pmcdev = &pmc;
...@@ -768,7 +872,7 @@ static int __init pmc_core_probe(void) ...@@ -768,7 +872,7 @@ static int __init pmc_core_probe(void)
* Sunrisepoint PCH regmap can't be used. Use Cannonlake PCH regmap * Sunrisepoint PCH regmap can't be used. Use Cannonlake PCH regmap
* in this case. * in this case.
*/ */
if (!pci_dev_present(pmc_pci_ids)) if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids))
pmcdev->map = &cnp_reg_map; pmcdev->map = &cnp_reg_map;
if (lpit_read_residency_count_address(&slp_s0_addr)) if (lpit_read_residency_count_address(&slp_s0_addr))
...@@ -791,6 +895,7 @@ static int __init pmc_core_probe(void) ...@@ -791,6 +895,7 @@ static int __init pmc_core_probe(void)
return err; return err;
} }
dmi_check_system(pmc_core_dmi_table);
pr_info(" initialized\n"); pr_info(" initialized\n");
return 0; return 0;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define SPT_PMC_MTPMC_OFFSET 0x20 #define SPT_PMC_MTPMC_OFFSET 0x20
#define SPT_PMC_MFPMC_OFFSET 0x38 #define SPT_PMC_MFPMC_OFFSET 0x38
#define SPT_PMC_LTR_IGNORE_OFFSET 0x30C #define SPT_PMC_LTR_IGNORE_OFFSET 0x30C
#define SPT_PMC_VRIC1_OFFSET 0x31c
#define SPT_PMC_MPHY_CORE_STS_0 0x1143 #define SPT_PMC_MPHY_CORE_STS_0 0x1143
#define SPT_PMC_MPHY_CORE_STS_1 0x1142 #define SPT_PMC_MPHY_CORE_STS_1 0x1142
#define SPT_PMC_MPHY_COM_STS_0 0x1155 #define SPT_PMC_MPHY_COM_STS_0 0x1155
...@@ -32,7 +33,7 @@ ...@@ -32,7 +33,7 @@
#define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64 #define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x64
#define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1) #define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1)
#define MTPMC_MASK 0xffff0000 #define MTPMC_MASK 0xffff0000
#define PPFEAR_MAX_NUM_ENTRIES 5 #define PPFEAR_MAX_NUM_ENTRIES 12
#define SPT_PPFEAR_NUM_ENTRIES 5 #define SPT_PPFEAR_NUM_ENTRIES 5
#define SPT_PMC_READ_DISABLE_BIT 0x16 #define SPT_PMC_READ_DISABLE_BIT 0x16
#define SPT_PMC_MSG_FULL_STS_BIT 0x18 #define SPT_PMC_MSG_FULL_STS_BIT 0x18
...@@ -46,6 +47,7 @@ ...@@ -46,6 +47,7 @@
#define SPT_PMC_LTR_SATA 0x368 #define SPT_PMC_LTR_SATA 0x368
#define SPT_PMC_LTR_GBE 0x36C #define SPT_PMC_LTR_GBE 0x36C
#define SPT_PMC_LTR_XHCI 0x370 #define SPT_PMC_LTR_XHCI 0x370
#define SPT_PMC_LTR_RESERVED 0x374
#define SPT_PMC_LTR_ME 0x378 #define SPT_PMC_LTR_ME 0x378
#define SPT_PMC_LTR_EVA 0x37C #define SPT_PMC_LTR_EVA 0x37C
#define SPT_PMC_LTR_SPC 0x380 #define SPT_PMC_LTR_SPC 0x380
...@@ -135,6 +137,9 @@ enum ppfear_regs { ...@@ -135,6 +137,9 @@ enum ppfear_regs {
#define SPT_PMC_BIT_MPHY_CMN_LANE2 BIT(2) #define SPT_PMC_BIT_MPHY_CMN_LANE2 BIT(2)
#define SPT_PMC_BIT_MPHY_CMN_LANE3 BIT(3) #define SPT_PMC_BIT_MPHY_CMN_LANE3 BIT(3)
#define SPT_PMC_VRIC1_SLPS0LVEN BIT(13)
#define SPT_PMC_VRIC1_XTALSDQDIS BIT(22)
/* Cannonlake Power Management Controller register offsets */ /* Cannonlake Power Management Controller register offsets */
#define CNP_PMC_SLPS0_DBG_OFFSET 0x10B4 #define CNP_PMC_SLPS0_DBG_OFFSET 0x10B4
#define CNP_PMC_PM_CFG_OFFSET 0x1818 #define CNP_PMC_PM_CFG_OFFSET 0x1818
...@@ -156,6 +161,7 @@ enum ppfear_regs { ...@@ -156,6 +161,7 @@ enum ppfear_regs {
#define CNP_PMC_LTR_SATA 0x1B68 #define CNP_PMC_LTR_SATA 0x1B68
#define CNP_PMC_LTR_GBE 0x1B6C #define CNP_PMC_LTR_GBE 0x1B6C
#define CNP_PMC_LTR_XHCI 0x1B70 #define CNP_PMC_LTR_XHCI 0x1B70
#define CNP_PMC_LTR_RESERVED 0x1B74
#define CNP_PMC_LTR_ME 0x1B78 #define CNP_PMC_LTR_ME 0x1B78
#define CNP_PMC_LTR_EVA 0x1B7C #define CNP_PMC_LTR_EVA 0x1B7C
#define CNP_PMC_LTR_SPC 0x1B80 #define CNP_PMC_LTR_SPC 0x1B80
...@@ -176,6 +182,10 @@ enum ppfear_regs { ...@@ -176,6 +182,10 @@ enum ppfear_regs {
#define LTR_REQ_SNOOP BIT(15) #define LTR_REQ_SNOOP BIT(15)
#define LTR_REQ_NONSNOOP BIT(31) #define LTR_REQ_NONSNOOP BIT(31)
#define ICL_PPFEAR_NUM_ENTRIES 9
#define ICL_NUM_IP_IGN_ALLOWED 20
#define ICL_PMC_LTR_WIGIG 0x1BFC
struct pmc_bit_map { struct pmc_bit_map {
const char *name; const char *name;
u32 bit_mask; u32 bit_mask;
...@@ -208,6 +218,7 @@ struct pmc_reg_map { ...@@ -208,6 +218,7 @@ struct pmc_reg_map {
const struct pmc_bit_map *pll_sts; const struct pmc_bit_map *pll_sts;
const struct pmc_bit_map **slps0_dbg_maps; const struct pmc_bit_map **slps0_dbg_maps;
const struct pmc_bit_map *ltr_show_sts; const struct pmc_bit_map *ltr_show_sts;
const struct pmc_bit_map *msr_sts;
const u32 slp_s0_offset; const u32 slp_s0_offset;
const u32 ltr_ignore_offset; const u32 ltr_ignore_offset;
const int regmap_length; const int regmap_length;
...@@ -217,6 +228,7 @@ struct pmc_reg_map { ...@@ -217,6 +228,7 @@ struct pmc_reg_map {
const int pm_read_disable_bit; const int pm_read_disable_bit;
const u32 slps0_dbg_offset; const u32 slps0_dbg_offset;
const u32 ltr_ignore_max; const u32 ltr_ignore_max;
const u32 pm_vric1_offset;
}; };
/** /**
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00 #define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00
#define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01 #define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01
#define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02 #define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02
#define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET 0x03
#define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d #define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d
#define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e
#define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f #define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
#define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22 #define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22
#define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23 #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23
#define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24 #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24
#define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION 0x2a
#define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET 0x30 #define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET 0x30
#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31 #define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32 #define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
...@@ -67,6 +69,9 @@ ...@@ -67,6 +69,9 @@
#define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xee #define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xee
#define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xef #define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xef
#define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xf0 #define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xf0
#define MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET 0xf5
#define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET 0xf6
#define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET 0xf7
#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100 #define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
...@@ -584,36 +589,48 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = { ...@@ -584,36 +589,48 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = {
.label = "fan1", .label = "fan1",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
.mask = BIT(0), .mask = BIT(0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(0),
.hpdev.nr = MLXPLAT_CPLD_NR_NONE, .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
}, },
{ {
.label = "fan2", .label = "fan2",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
.mask = BIT(1), .mask = BIT(1),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(1),
.hpdev.nr = MLXPLAT_CPLD_NR_NONE, .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
}, },
{ {
.label = "fan3", .label = "fan3",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
.mask = BIT(2), .mask = BIT(2),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(2),
.hpdev.nr = MLXPLAT_CPLD_NR_NONE, .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
}, },
{ {
.label = "fan4", .label = "fan4",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
.mask = BIT(3), .mask = BIT(3),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(3),
.hpdev.nr = MLXPLAT_CPLD_NR_NONE, .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
}, },
{ {
.label = "fan5", .label = "fan5",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
.mask = BIT(4), .mask = BIT(4),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(4),
.hpdev.nr = MLXPLAT_CPLD_NR_NONE, .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
}, },
{ {
.label = "fan6", .label = "fan6",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
.mask = BIT(5), .mask = BIT(5),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(5),
.hpdev.nr = MLXPLAT_CPLD_NR_NONE, .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
}, },
}; };
...@@ -816,61 +833,90 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = { ...@@ -816,61 +833,90 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
.label = "fan1:green", .label = "fan1:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(0),
}, },
{ {
.label = "fan1:orange", .label = "fan1:orange",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(0),
}, },
{ {
.label = "fan2:green", .label = "fan2:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(1),
}, },
{ {
.label = "fan2:orange", .label = "fan2:orange",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(1),
}, },
{ {
.label = "fan3:green", .label = "fan3:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(2),
}, },
{ {
.label = "fan3:orange", .label = "fan3:orange",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(2),
}, },
{ {
.label = "fan4:green", .label = "fan4:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(3),
}, },
{ {
.label = "fan4:orange", .label = "fan4:orange",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(3),
}, },
{ {
.label = "fan5:green", .label = "fan5:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(4),
}, },
{ {
.label = "fan5:orange", .label = "fan5:orange",
.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(4),
}, },
{ {
.label = "fan6:green", .label = "fan6:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(5),
}, },
{ {
.label = "fan6:orange", .label = "fan6:orange",
.reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK, .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(5),
},
{
.label = "uid:blue",
.reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
}, },
}; };
...@@ -1099,6 +1145,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { ...@@ -1099,6 +1145,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
.bit = GENMASK(7, 0), .bit = GENMASK(7, 0),
.mode = 0444, .mode = 0444,
}, },
{
.label = "cpld4_version",
.reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
.bit = GENMASK(7, 0),
.mode = 0444,
},
{ {
.label = "reset_long_pb", .label = "reset_long_pb",
.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
...@@ -1184,6 +1236,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = { ...@@ -1184,6 +1236,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
.bit = 1, .bit = 1,
.mode = 0444, .mode = 0444,
}, },
{
.label = "fan_dir",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
.bit = GENMASK(7, 0),
.mode = 0444,
},
}; };
static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = { static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = {
...@@ -1201,61 +1259,85 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = { ...@@ -1201,61 +1259,85 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
.label = "tacho1", .label = "tacho1",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(0),
}, },
{ {
.label = "tacho2", .label = "tacho2",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(1),
}, },
{ {
.label = "tacho3", .label = "tacho3",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(2),
}, },
{ {
.label = "tacho4", .label = "tacho4",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(3),
}, },
{ {
.label = "tacho5", .label = "tacho5",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(4),
}, },
{ {
.label = "tacho6", .label = "tacho6",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(5),
}, },
{ {
.label = "tacho7", .label = "tacho7",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(6),
}, },
{ {
.label = "tacho8", .label = "tacho8",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
.bit = BIT(7),
}, },
{ {
.label = "tacho9", .label = "tacho9",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
.bit = BIT(0),
}, },
{ {
.label = "tacho10", .label = "tacho10",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
.bit = BIT(1),
}, },
{ {
.label = "tacho11", .label = "tacho11",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
.bit = BIT(2),
}, },
{ {
.label = "tacho12", .label = "tacho12",
.reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET, .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
.mask = GENMASK(7, 0), .mask = GENMASK(7, 0),
.capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
.bit = BIT(3),
}, },
}; };
...@@ -1299,6 +1381,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) ...@@ -1299,6 +1381,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET: case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET: case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET: case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET: case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
...@@ -1307,6 +1390,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) ...@@ -1307,6 +1390,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET: case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET: case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET: case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET: case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET: case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
...@@ -1341,6 +1425,9 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg) ...@@ -1341,6 +1425,9 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET: case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET: case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
return true; return true;
} }
return false; return false;
...@@ -1352,6 +1439,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) ...@@ -1352,6 +1439,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET: case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET: case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET: case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET: case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET: case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET: case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
...@@ -1360,6 +1448,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) ...@@ -1360,6 +1448,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET: case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET: case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET: case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET: case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET: case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET: case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
...@@ -1392,6 +1481,9 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg) ...@@ -1392,6 +1481,9 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET: case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET: case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET: case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
return true; return true;
} }
return false; return false;
...@@ -1613,6 +1705,13 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = { ...@@ -1613,6 +1705,13 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"), DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"),
}, },
}, },
{
.callback = mlxplat_dmi_qmb7xx_matched,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"),
},
},
{ {
.callback = mlxplat_dmi_default_matched, .callback = mlxplat_dmi_default_matched,
.matches = { .matches = {
...@@ -1643,6 +1742,12 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = { ...@@ -1643,6 +1742,12 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"), DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
}, },
}, },
{
.callback = mlxplat_dmi_qmb7xx_matched,
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "VMOD0007"),
},
},
{ } { }
}; };
......
...@@ -41,6 +41,20 @@ static const struct ts_dmi_data chuwi_hi8_data = { ...@@ -41,6 +41,20 @@ static const struct ts_dmi_data chuwi_hi8_data = {
.properties = chuwi_hi8_props, .properties = chuwi_hi8_props,
}; };
static const struct property_entry chuwi_hi8_air_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-hi8-air.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ }
};
static const struct ts_dmi_data chuwi_hi8_air_data = {
.acpi_name = "MSSL1680:00",
.properties = chuwi_hi8_air_props,
};
static const struct property_entry chuwi_hi8_pro_props[] = { static const struct property_entry chuwi_hi8_pro_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 6), PROPERTY_ENTRY_U32("touchscreen-min-x", 6),
PROPERTY_ENTRY_U32("touchscreen-min-y", 3), PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
...@@ -58,6 +72,25 @@ static const struct ts_dmi_data chuwi_hi8_pro_data = { ...@@ -58,6 +72,25 @@ static const struct ts_dmi_data chuwi_hi8_pro_data = {
.properties = chuwi_hi8_pro_props, .properties = chuwi_hi8_pro_props,
}; };
static const struct property_entry chuwi_hi10_air_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1981),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1271),
PROPERTY_ENTRY_U32("touchscreen-min-x", 99),
PROPERTY_ENTRY_U32("touchscreen-min-y", 9),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_U32("touchscreen-fuzz-x", 5),
PROPERTY_ENTRY_U32("touchscreen-fuzz-y", 4),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-air.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
static const struct ts_dmi_data chuwi_hi10_air_data = {
.acpi_name = "MSSL1680:00",
.properties = chuwi_hi10_air_props,
};
static const struct property_entry chuwi_vi8_props[] = { static const struct property_entry chuwi_vi8_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 4), PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
PROPERTY_ENTRY_U32("touchscreen-min-y", 6), PROPERTY_ENTRY_U32("touchscreen-min-y", 6),
...@@ -369,6 +402,24 @@ static const struct ts_dmi_data pov_mobii_wintab_p800w_v21_data = { ...@@ -369,6 +402,24 @@ static const struct ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
.properties = pov_mobii_wintab_p800w_v21_props, .properties = pov_mobii_wintab_p800w_v21_props,
}; };
static const struct property_entry pov_mobii_wintab_p1006w_v10_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 1),
PROPERTY_ENTRY_U32("touchscreen-min-y", 3),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1984),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1520),
PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
PROPERTY_ENTRY_STRING("firmware-name",
"gsl3692-pov-mobii-wintab-p1006w-v10.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
static const struct ts_dmi_data pov_mobii_wintab_p1006w_v10_data = {
.acpi_name = "MSSL1680:00",
.properties = pov_mobii_wintab_p1006w_v10_props,
};
static const struct property_entry teclast_x3_plus_props[] = { static const struct property_entry teclast_x3_plus_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
...@@ -497,6 +548,15 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -497,6 +548,15 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"), DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
}, },
}, },
{
/* Chuwi Hi8 Air (CWI543) */
.driver_data = (void *)&chuwi_hi8_air_data,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Default string"),
DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
DMI_MATCH(DMI_PRODUCT_NAME, "Hi8 Air"),
},
},
{ {
/* Chuwi Hi8 Pro (CWI513) */ /* Chuwi Hi8 Pro (CWI513) */
.driver_data = (void *)&chuwi_hi8_pro_data, .driver_data = (void *)&chuwi_hi8_pro_data,
...@@ -505,6 +565,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -505,6 +565,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"), DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
}, },
}, },
{
/* Chuwi Hi10 Air */
.driver_data = (void *)&chuwi_hi10_air_data,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
DMI_MATCH(DMI_PRODUCT_SKU, "P1W6_C109D_B"),
},
},
{ {
/* Chuwi Vi8 (CWI506) */ /* Chuwi Vi8 (CWI506) */
.driver_data = (void *)&chuwi_vi8_data, .driver_data = (void *)&chuwi_vi8_data,
...@@ -706,6 +774,17 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { ...@@ -706,6 +774,17 @@ static const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"), DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
}, },
}, },
{
/* Point of View mobii wintab p1006w (v1.0) */
.driver_data = (void *)&pov_mobii_wintab_p1006w_v10_data,
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
/* Note 105b is Foxcon's USB/PCI vendor id */
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
},
},
{ {
/* Teclast X3 Plus */ /* Teclast X3 Plus */
.driver_data = (void *)&teclast_x3_plus_data, .driver_data = (void *)&teclast_x3_plus_data,
......
...@@ -119,7 +119,7 @@ static struct wmi_driver wmi_bmof_driver = { ...@@ -119,7 +119,7 @@ static struct wmi_driver wmi_bmof_driver = {
module_wmi_driver(wmi_bmof_driver); module_wmi_driver(wmi_bmof_driver);
MODULE_ALIAS("wmi:" WMI_BMOF_GUID); MODULE_DEVICE_TABLE(wmi, wmi_bmof_id_table);
MODULE_AUTHOR("Andrew Lutomirski <luto@kernel.org>"); MODULE_AUTHOR("Andrew Lutomirski <luto@kernel.org>");
MODULE_DESCRIPTION("WMI embedded Binary MOF driver"); MODULE_DESCRIPTION("WMI embedded Binary MOF driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -768,7 +768,10 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) ...@@ -768,7 +768,10 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
struct wmi_block *wblock = dev_to_wblock(dev); struct wmi_block *wblock = dev_to_wblock(dev);
const struct wmi_device_id *id = wmi_driver->id_table; const struct wmi_device_id *id = wmi_driver->id_table;
while (id->guid_string) { if (id == NULL)
return 0;
while (*id->guid_string) {
uuid_le driver_guid; uuid_le driver_guid;
if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid))) if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid)))
......
...@@ -788,4 +788,16 @@ struct tee_client_device_id { ...@@ -788,4 +788,16 @@ struct tee_client_device_id {
uuid_t uuid; uuid_t uuid;
}; };
/* WMI */
#define WMI_MODULE_PREFIX "wmi:"
/**
* struct wmi_device_id - WMI device identifier
* @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
*/
struct wmi_device_id {
const char guid_string[UUID_STRING_LEN+1];
};
#endif /* LINUX_MOD_DEVICETABLE_H */ #endif /* LINUX_MOD_DEVICETABLE_H */
...@@ -61,6 +61,7 @@ struct mlxreg_hotplug_device { ...@@ -61,6 +61,7 @@ struct mlxreg_hotplug_device {
* @reg: attribute register; * @reg: attribute register;
* @mask: attribute access mask; * @mask: attribute access mask;
* @bit: attribute effective bit; * @bit: attribute effective bit;
* @capability: attribute capability register;
* @mode: access mode; * @mode: access mode;
* @np - pointer to node platform associated with attribute; * @np - pointer to node platform associated with attribute;
* @hpdev - hotplug device data; * @hpdev - hotplug device data;
...@@ -72,6 +73,7 @@ struct mlxreg_core_data { ...@@ -72,6 +73,7 @@ struct mlxreg_core_data {
u32 reg; u32 reg;
u32 mask; u32 mask;
u32 bit; u32 bit;
u32 capability;
umode_t mode; umode_t mode;
struct device_node *np; struct device_node *np;
struct mlxreg_hotplug_device hpdev; struct mlxreg_hotplug_device hpdev;
...@@ -107,9 +109,9 @@ struct mlxreg_core_item { ...@@ -107,9 +109,9 @@ struct mlxreg_core_item {
/** /**
* struct mlxreg_core_platform_data - platform data: * struct mlxreg_core_platform_data - platform data:
* *
* @led_data: led private data; * @data: instance private data;
* @regmap: register map of parent device; * @regmap: register map of parent device;
* @counter: number of led instances; * @counter: number of instances;
*/ */
struct mlxreg_core_platform_data { struct mlxreg_core_platform_data {
struct mlxreg_core_data *data; struct mlxreg_core_data *data;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#include <uapi/linux/wmi.h> #include <uapi/linux/wmi.h>
struct wmi_device { struct wmi_device {
...@@ -39,10 +40,6 @@ extern union acpi_object *wmidev_block_query(struct wmi_device *wdev, ...@@ -39,10 +40,6 @@ extern union acpi_object *wmidev_block_query(struct wmi_device *wdev,
extern int set_required_buffer_size(struct wmi_device *wdev, u64 length); extern int set_required_buffer_size(struct wmi_device *wdev, u64 length);
struct wmi_device_id {
const char *guid_string;
};
struct wmi_driver { struct wmi_driver {
struct device_driver driver; struct device_driver driver;
const struct wmi_device_id *id_table; const struct wmi_device_id *id_table;
......
...@@ -228,5 +228,8 @@ int main(void) ...@@ -228,5 +228,8 @@ int main(void)
DEVID(tee_client_device_id); DEVID(tee_client_device_id);
DEVID_FIELD(tee_client_device_id, uuid); DEVID_FIELD(tee_client_device_id, uuid);
DEVID(wmi_device_id);
DEVID_FIELD(wmi_device_id, guid_string);
return 0; return 0;
} }
...@@ -40,6 +40,7 @@ typedef struct { ...@@ -40,6 +40,7 @@ typedef struct {
typedef struct { typedef struct {
__u8 b[16]; __u8 b[16];
} uuid_t; } uuid_t;
#define UUID_STRING_LEN 36
/* Big exception to the "don't include kernel headers into userspace, which /* Big exception to the "don't include kernel headers into userspace, which
* even potentially has different endianness and word sizes, since * even potentially has different endianness and word sizes, since
...@@ -53,6 +54,9 @@ struct devtable { ...@@ -53,6 +54,9 @@ struct devtable {
int (*do_entry)(const char *filename, void *symval, char *alias); int (*do_entry)(const char *filename, void *symval, char *alias);
}; };
/* Size of alias provided to do_entry functions */
#define ALIAS_SIZE 500
/* Define a variable f that holds the value of field f of struct devid /* Define a variable f that holds the value of field f of struct devid
* based at address m. * based at address m.
*/ */
...@@ -1305,6 +1309,27 @@ static int do_tee_entry(const char *filename, void *symval, char *alias) ...@@ -1305,6 +1309,27 @@ static int do_tee_entry(const char *filename, void *symval, char *alias)
return 1; return 1;
} }
/* Looks like: wmi:guid */
static int do_wmi_entry(const char *filename, void *symval, char *alias)
{
int len;
DEF_FIELD_ADDR(symval, wmi_device_id, guid_string);
if (strlen(*guid_string) != UUID_STRING_LEN) {
warn("Invalid WMI device id 'wmi:%s' in '%s'\n",
*guid_string, filename);
return 0;
}
len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string);
if (len < 0 || len >= ALIAS_SIZE) {
warn("Could not generate all MODULE_ALIAS's in '%s'\n",
filename);
return 0;
}
return 1;
}
/* Does namelen bytes of name exactly match the symbol? */ /* Does namelen bytes of name exactly match the symbol? */
static bool sym_is(const char *name, unsigned namelen, const char *symbol) static bool sym_is(const char *name, unsigned namelen, const char *symbol)
{ {
...@@ -1321,7 +1346,7 @@ static void do_table(void *symval, unsigned long size, ...@@ -1321,7 +1346,7 @@ static void do_table(void *symval, unsigned long size,
struct module *mod) struct module *mod)
{ {
unsigned int i; unsigned int i;
char alias[500]; char alias[ALIAS_SIZE];
device_id_check(mod->name, device_id, size, id_size, symval); device_id_check(mod->name, device_id, size, id_size, symval);
/* Leave last one: it's the terminator. */ /* Leave last one: it's the terminator. */
...@@ -1376,6 +1401,7 @@ static const struct devtable devtable[] = { ...@@ -1376,6 +1401,7 @@ static const struct devtable devtable[] = {
{"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry},
{"typec", SIZE_typec_device_id, do_typec_entry}, {"typec", SIZE_typec_device_id, do_typec_entry},
{"tee", SIZE_tee_client_device_id, do_tee_entry}, {"tee", SIZE_tee_client_device_id, do_tee_entry},
{"wmi", SIZE_wmi_device_id, do_wmi_entry},
}; };
/* Create MODULE_ALIAS() statements. /* Create MODULE_ALIAS() statements.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment