Commit f3b5020e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull x86 platform driver updates from Darren Hart:
 "Several incremental improvements including new keycodes, new models,
  new quirks, and related documentation. Adds LED platform driver
  activation for Mellanox systems. Some minor optimizations and
  cleanups. Includes several bug fixes, message silencing, mostly minor

  Automated summary:

  acer-wmi:
   -  add another KEY_POWER keycode

  apple-gmux:
   -  fix gmux_get_client_id()'s return type

  asus-laptop:
   -  Simplify getting .drvdata

  asus-wireless:
   -  Fix format specifier

  dell-laptop:
   -  Fix keyboard backlight timeout on XPS 13 9370

  dell-smbios:
   -  Match on www.dell.com in OEM strings too

  dell-wmi:
   -  Ignore new rfkill and fn-lock events
   -  Set correct keycode for Fn + left arrow

  fujitsu-laptop:
   -  Simplify soft key handling

  ideapad-laptop:
   -  Add E42-80 to no_hw_rfkill
   -  Add fn-lock setting
   -  Add MIIX 720-12IKB to no_hw_rfkill

  lib/string_helpers:
   -  Add missed declaration of struct task_struct

  intel_scu_ipc:
   -  Replace mdelay with usleep_range in intel_scu_ipc_i2c_cntrl

  mlx-platform:
   -  Add LED platform driver activation

  platform/mellanox:
   -  Add new ODM system types to mlx-platform
   -  mlxreg-hotplug: add extra cycle for hotplug work queue
   -  mlxreg-hotplug: Document fixes for hotplug private data

  platform_data/mlxreg:
   -  Document fixes for hotplug device

  silead_dmi:
   -  Add entry for Chuwi Hi8 tablet touchscreen
   -  Add touchscreen info for the Onda V891w tablet
   -  Add info for the PoV mobii TAB-P800W (v2.0)
   -  Add touchscreen info for the Jumper EZpad 6 Pro

  thinkpad_acpi:
   -  silence false-positive-prone pr_warn
   -  do not report thermal sensor state for tablet mode switch
   -  silence HKEY 0x6032, 0x60f0, 0x6030"

* tag 'platform-drivers-x86-v4.18-1' of git://git.infradead.org/linux-platform-drivers-x86: (30 commits)
  platform/x86: silead_dmi: Add entry for Chuwi Hi8 tablet touchscreen
  platform/x86: dell-laptop: Fix keyboard backlight timeout on XPS 13 9370
  platform/x86: dell-wmi: Ignore new rfkill and fn-lock events
  platform/x86: mlx-platform: Add LED platform driver activation
  platform/mellanox: Add new ODM system types to mlx-platform
  platform/mellanox: mlxreg-hotplug: add extra cycle for hotplug work queue
  platform/x86: ideapad-laptop: Add E42-80 to no_hw_rfkill
  platform/x86: silead_dmi: Add touchscreen info for the Onda V891w tablet
  platform/x86: silead_dmi: Add info for the PoV mobii TAB-P800W (v2.0)
  platform/x86: silead_dmi: Add touchscreen info for the Jumper EZpad 6 Pro
  platform/x86: asus-wireless: Fix format specifier
  platform/x86: asus-wmi: Fix NULL pointer dereference
  platform/x86: dell-wmi: Set correct keycode for Fn + left arrow
  platform/x86: acer-wmi: add another KEY_POWER keycode
  platform/x86: ideapad-laptop: Add fn-lock setting
  platform/x86: ideapad-laptop: Add MIIX 720-12IKB to no_hw_rfkill
  lib/string_helpers: Add missed declaration of struct task_struct
  platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS
  platform/mellanox: mlxreg-hotplug: Document fixes for hotplug private data
  platform_data/mlxreg: Document fixes for hotplug device
  ...
parents 4b4bb99b 26ed9d1c
......@@ -25,3 +25,16 @@ Description:
Control touchpad mode.
* 1 -> Switched On
* 0 -> Switched Off
What: /sys/bus/pci/devices/<bdf>/<device>/VPC2004:00/fn_lock
Date: May 2018
KernelVersion: 4.18
Contact: "Oleg Keri <ezhi99@gmail.com>"
Description:
Control fn-lock mode.
* 1 -> Switched On
* 0 -> Switched Off
For example:
# echo "0" > \
/sys/bus/pci/devices/0000:00:1f.0/PNP0C09:00/VPC2004:00/fn_lock
......@@ -540,8 +540,10 @@ Events that are propagated by the driver to userspace:
0x6021 ALARM: a sensor is too hot
0x6022 ALARM: a sensor is extremely hot
0x6030 System thermal table changed
0x6032 Thermal Control command set completion (DYTC, Windows)
0x6040 Nvidia Optimus/AC adapter related (TO BE VERIFIED)
0x60C0 X1 Yoga 2016, Tablet mode status changed
0x60F0 Thermal Transformation changed (GMTS, Windows)
Battery nearly empty alarms are a last resort attempt to get the
operating system to hibernate or shutdown cleanly (0x2313), or shutdown
......
......@@ -55,13 +55,16 @@
#define MLXREG_HOTPLUG_RST_CNTR 3
#define MLXREG_HOTPLUG_ATTRS_MAX 24
#define MLXREG_HOTPLUG_NOT_ASSERT 3
/**
* struct mlxreg_hotplug_priv_data - platform private data:
* @irq: platform device interrupt number;
* @dev: basic device;
* @pdev: platform device;
* @plat: platform data;
* @dwork: delayed work template;
* @regmap: register map handle;
* @dwork_irq: delayed work template;
* @lock: spin lock;
* @hwmon: hwmon device;
* @mlxreg_hotplug_attr: sysfs attributes array;
......@@ -71,6 +74,8 @@
* @cell: location of top aggregation interrupt register;
* @mask: top aggregation interrupt common mask;
* @aggr_cache: last value of aggregation register status;
* @after_probe: flag indication probing completion;
* @not_asserted: number of entries in workqueue with no signal assertion;
*/
struct mlxreg_hotplug_priv_data {
int irq;
......@@ -79,7 +84,6 @@ struct mlxreg_hotplug_priv_data {
struct mlxreg_hotplug_platform_data *plat;
struct regmap *regmap;
struct delayed_work dwork_irq;
struct delayed_work dwork;
spinlock_t lock; /* sync with interrupt */
struct device *hwmon;
struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_MAX + 1];
......@@ -91,6 +95,7 @@ struct mlxreg_hotplug_priv_data {
u32 mask;
u32 aggr_cache;
bool after_probe;
u8 not_asserted;
};
static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
......@@ -409,6 +414,18 @@ static void mlxreg_hotplug_work_handler(struct work_struct *work)
aggr_asserted = priv->aggr_cache ^ regval;
priv->aggr_cache = regval;
/*
* Handler is invoked, but no assertion is detected at top aggregation
* status level. Set aggr_asserted to mask value to allow handler extra
* run over all relevant signals to recover any missed signal.
*/
if (priv->not_asserted == MLXREG_HOTPLUG_NOT_ASSERT) {
priv->not_asserted = 0;
aggr_asserted = pdata->mask;
}
if (!aggr_asserted)
goto unmask_event;
/* Handle topology and health configuration changes. */
for (i = 0; i < pdata->counter; i++, item++) {
if (aggr_asserted & item->aggr_mask) {
......@@ -419,27 +436,26 @@ static void mlxreg_hotplug_work_handler(struct work_struct *work)
}
}
if (aggr_asserted) {
spin_lock_irqsave(&priv->lock, flags);
spin_lock_irqsave(&priv->lock, flags);
/*
* It is possible, that some signals have been inserted, while
* interrupt has been masked by mlxreg_hotplug_work_handler.
* In this case such signals will be missed. In order to handle
* these signals delayed work is canceled and work task
* re-scheduled for immediate execution. It allows to handle
* missed signals, if any. In other case work handler just
* validates that no new signals have been received during
* masking.
*/
cancel_delayed_work(&priv->dwork_irq);
schedule_delayed_work(&priv->dwork_irq, 0);
/*
* It is possible, that some signals have been inserted, while
* interrupt has been masked by mlxreg_hotplug_work_handler. In this
* case such signals will be missed. In order to handle these signals
* delayed work is canceled and work task re-scheduled for immediate
* execution. It allows to handle missed signals, if any. In other case
* work handler just validates that no new signals have been received
* during masking.
*/
cancel_delayed_work(&priv->dwork_irq);
schedule_delayed_work(&priv->dwork_irq, 0);
spin_unlock_irqrestore(&priv->lock, flags);
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
return;
unmask_event:
priv->not_asserted++;
/* Unmask aggregation event (no need acknowledge). */
ret = regmap_write(priv->regmap, pdata->cell +
MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
......
......@@ -129,6 +129,7 @@ static const struct key_entry acer_wmi_keymap[] __initconst = {
{KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
{KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} },
{KE_KEY, 0x86, {KEY_WLAN} },
{KE_KEY, 0x87, {KEY_POWER} },
{KE_END, 0}
};
......
......@@ -495,7 +495,7 @@ static int gmux_set_power_state(enum vga_switcheroo_client_id id,
return gmux_set_discrete_state(apple_gmux_data, state);
}
static int gmux_get_client_id(struct pci_dev *pdev)
static enum vga_switcheroo_client_id gmux_get_client_id(struct pci_dev *pdev)
{
/*
* Early Macbook Pros with switchable graphics use nvidia
......
......@@ -1593,8 +1593,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
int idx)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct platform_device *pdev = to_platform_device(dev);
struct asus_laptop *asus = platform_get_drvdata(pdev);
struct asus_laptop *asus = dev_get_drvdata(dev);
acpi_handle handle = asus->handle;
bool supported;
......
......@@ -72,7 +72,7 @@ static u64 asus_wireless_method(acpi_handle handle, const char *method,
acpi_handle_err(handle,
"Failed to eval method %s, param %#x (%d)\n",
method, param, s);
acpi_handle_debug(handle, "%s returned %#x\n", method, (uint) ret);
acpi_handle_debug(handle, "%s returned %#llx\n", method, ret);
return ret;
}
......
......@@ -1875,8 +1875,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
struct attribute *attr, int idx)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct platform_device *pdev = to_platform_device(dev);
struct asus_wmi *asus = platform_get_drvdata(pdev);
struct asus_wmi *asus = dev_get_drvdata(dev);
bool ok = true;
int devid = -1;
......
......@@ -38,6 +38,7 @@
struct quirk_entry {
bool touchpad_led;
bool kbd_led_levels_off_1;
bool kbd_missing_ac_tag;
bool needs_kbd_timeouts;
/*
......@@ -68,6 +69,10 @@ static struct quirk_entry quirk_dell_xps13_9333 = {
.kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },
};
static struct quirk_entry quirk_dell_xps13_9370 = {
.kbd_missing_ac_tag = true,
};
static struct quirk_entry quirk_dell_latitude_e6410 = {
.kbd_led_levels_off_1 = true,
};
......@@ -291,6 +296,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
},
.driver_data = &quirk_dell_xps13_9333,
},
{
.callback = dmi_matched,
.ident = "Dell XPS 13 9370",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9370"),
},
.driver_data = &quirk_dell_xps13_9370,
},
{
.callback = dmi_matched,
.ident = "Dell Latitude E6410",
......@@ -1401,7 +1415,8 @@ static inline int kbd_init_info(void)
* timeout value which is shared for both battery and AC power
* settings. So do not try to set AC values on old models.
*/
if (dell_smbios_find_token(KBD_LED_AC_TOKEN))
if ((quirks && quirks->kbd_missing_ac_tag) ||
dell_smbios_find_token(KBD_LED_AC_TOKEN))
kbd_timeout_ac_supported = true;
kbd_get_state(&state);
......
......@@ -555,11 +555,10 @@ static void free_group(struct platform_device *pdev)
static int __init dell_smbios_init(void)
{
const struct dmi_device *valid;
int ret, wmi, smm;
valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL);
if (!valid) {
if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) &&
!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) {
pr_err("Unable to run on non-Dell system\n");
return -ENODEV;
}
......
......@@ -233,7 +233,7 @@ static const u16 bios_to_linux_keycode[256] = {
[18] = KEY_PROG1,
[19] = KEY_BRIGHTNESSDOWN,
[20] = KEY_BRIGHTNESSUP,
[21] = KEY_UNKNOWN,
[21] = KEY_BRIGHTNESS_AUTO,
[22] = KEY_KBDILLUMTOGGLE,
[23] = KEY_UNKNOWN,
[24] = KEY_SWITCHVIDEOMODE,
......@@ -261,6 +261,12 @@ static const u16 bios_to_linux_keycode[256] = {
* override them.
*/
static const struct key_entry dell_wmi_keymap_type_0010[] = {
/* Fn-lock switched to function keys */
{ KE_IGNORE, 0x0, { KEY_RESERVED } },
/* Fn-lock switched to multimedia keys */
{ KE_IGNORE, 0x1, { KEY_RESERVED } },
/* Mic mute */
{ KE_KEY, 0x150, { KEY_MICMUTE } },
......@@ -296,6 +302,14 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = {
{ KE_KEY, 0x851, { KEY_PROG2 } },
{ KE_KEY, 0x852, { KEY_PROG3 } },
/*
* Radio disable (notify only -- there is no model for which the
* WMI event is supposed to trigger an action).
*/
{ KE_IGNORE, 0xe008, { KEY_RFKILL } },
/* Fn-lock */
{ KE_IGNORE, 0xe035, { KEY_RESERVED } },
};
/*
......
......@@ -91,6 +91,9 @@
#define FLAG_RFKILL BIT(5)
#define FLAG_LID BIT(8)
#define FLAG_DOCK BIT(9)
#define FLAG_TOUCHPAD_TOGGLE BIT(26)
#define FLAG_MICMUTE BIT(29)
#define FLAG_SOFTKEYS (FLAG_RFKILL | FLAG_TOUCHPAD_TOGGLE | FLAG_MICMUTE)
/* FUNC interface - LED control */
#define FUNC_LED_OFF BIT(0)
......@@ -456,14 +459,15 @@ static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event)
/* ACPI device for hotkey handling */
static const struct key_entry keymap_default[] = {
{ KE_KEY, KEY1_CODE, { KEY_PROG1 } },
{ KE_KEY, KEY2_CODE, { KEY_PROG2 } },
{ KE_KEY, KEY3_CODE, { KEY_PROG3 } },
{ KE_KEY, KEY4_CODE, { KEY_PROG4 } },
{ KE_KEY, KEY5_CODE, { KEY_RFKILL } },
{ KE_KEY, BIT(5), { KEY_RFKILL } },
{ KE_KEY, BIT(26), { KEY_TOUCHPAD_TOGGLE } },
{ KE_KEY, BIT(29), { KEY_MICMUTE } },
{ KE_KEY, KEY1_CODE, { KEY_PROG1 } },
{ KE_KEY, KEY2_CODE, { KEY_PROG2 } },
{ KE_KEY, KEY3_CODE, { KEY_PROG3 } },
{ KE_KEY, KEY4_CODE, { KEY_PROG4 } },
{ KE_KEY, KEY5_CODE, { KEY_RFKILL } },
/* Soft keys read from status flags */
{ KE_KEY, FLAG_RFKILL, { KEY_RFKILL } },
{ KE_KEY, FLAG_TOUCHPAD_TOGGLE, { KEY_TOUCHPAD_TOGGLE } },
{ KE_KEY, FLAG_MICMUTE, { KEY_MICMUTE } },
{ KE_END, 0 }
};
......@@ -903,7 +907,8 @@ static void acpi_fujitsu_laptop_release(struct acpi_device *device)
static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
{
struct fujitsu_laptop *priv = acpi_driver_data(device);
int scancode, i = 0, ret;
unsigned long flags;
int scancode, i = 0;
unsigned int irb;
if (event != ACPI_FUJITSU_NOTIFY_CODE) {
......@@ -930,21 +935,17 @@ static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event)
"Unknown GIRB result [%x]\n", irb);
}
/* On some models (first seen on the Skylake-based Lifebook
* E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is
* handled in software; its state is queried using FUNC_FLAGS
/*
* First seen on the Skylake-based Lifebook E736/E746/E756), the
* touchpad toggle hotkey (Fn+F4) is handled in software. Other models
* have since added additional "soft keys". These are reported in the
* status flags queried using FUNC_FLAGS.
*/
if (priv->flags_supported & (BIT(5) | BIT(26) | BIT(29))) {
ret = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
if (ret & BIT(5))
sparse_keymap_report_event(priv->input,
BIT(5), 1, true);
if (ret & BIT(26))
sparse_keymap_report_event(priv->input,
BIT(26), 1, true);
if (ret & BIT(29))
sparse_keymap_report_event(priv->input,
BIT(29), 1, true);
if (priv->flags_supported & (FLAG_SOFTKEYS)) {
flags = call_fext_func(device, FUNC_FLAGS, 0x1, 0x0, 0x0);
flags &= (FLAG_SOFTKEYS);
for_each_set_bit(i, &flags, BITS_PER_LONG)
sparse_keymap_report_event(priv->input, BIT(i), 1, true);
}
}
......
......@@ -43,6 +43,7 @@
#define IDEAPAD_RFKILL_DEV_NUM (3)
#define BM_CONSERVATION_BIT (5)
#define HA_FNLOCK_BIT (10)
#define CFG_BT_BIT (16)
#define CFG_3G_BIT (17)
......@@ -59,6 +60,8 @@ static const char *const ideapad_wmi_fnesc_events[] = {
enum {
BMCMD_CONSERVATION_ON = 3,
BMCMD_CONSERVATION_OFF = 5,
HACMD_FNLOCK_ON = 0xe,
HACMD_FNLOCK_OFF = 0xf,
};
enum {
......@@ -139,11 +142,11 @@ static int method_gbmd(acpi_handle handle, unsigned long *ret)
return result;
}
static int method_sbmc(acpi_handle handle, int cmd)
static int method_int1(acpi_handle handle, char *method, int cmd)
{
acpi_status status;
status = acpi_execute_simple_method(handle, "SBMC", cmd);
status = acpi_execute_simple_method(handle, method, cmd);
return ACPI_FAILURE(status) ? -1 : 0;
}
......@@ -487,7 +490,7 @@ static ssize_t conservation_mode_store(struct device *dev,
if (ret)
return ret;
ret = method_sbmc(priv->adev->handle, state ?
ret = method_int1(priv->adev->handle, "SBMC", state ?
BMCMD_CONSERVATION_ON :
BMCMD_CONSERVATION_OFF);
if (ret < 0)
......@@ -497,11 +500,51 @@ static ssize_t conservation_mode_store(struct device *dev,
static DEVICE_ATTR_RW(conservation_mode);
static ssize_t fn_lock_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
unsigned long result;
int hals;
int fail = read_method_int(priv->adev->handle, "HALS", &hals);
if (fail)
return sprintf(buf, "-1\n");
result = hals;
return sprintf(buf, "%u\n", test_bit(HA_FNLOCK_BIT, &result));
}
static ssize_t fn_lock_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct ideapad_private *priv = dev_get_drvdata(dev);
bool state;
int ret;
ret = kstrtobool(buf, &state);
if (ret)
return ret;
ret = method_int1(priv->adev->handle, "SALS", state ?
HACMD_FNLOCK_ON :
HACMD_FNLOCK_OFF);
if (ret < 0)
return -EIO;
return count;
}
static DEVICE_ATTR_RW(fn_lock);
static struct attribute *ideapad_attributes[] = {
&dev_attr_camera_power.attr,
&dev_attr_fan_mode.attr,
&dev_attr_touchpad.attr,
&dev_attr_conservation_mode.attr,
&dev_attr_fn_lock.attr,
NULL
};
......@@ -522,6 +565,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
} else if (attr == &dev_attr_conservation_mode.attr) {
supported = acpi_has_method(priv->adev->handle, "GBMD") &&
acpi_has_method(priv->adev->handle, "SBMC");
} else if (attr == &dev_attr_fn_lock.attr) {
supported = acpi_has_method(priv->adev->handle, "HALS") &&
acpi_has_method(priv->adev->handle, "SALS");
} else
supported = true;
......@@ -1079,6 +1125,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-17ISK"),
},
},
{
.ident = "Lenovo ideapad MIIX 720-12IKB",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 720-12IKB"),
},
},
{
.ident = "Lenovo Legion Y520-15IKBN",
.matches = {
......@@ -1163,6 +1216,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 920-13IKB"),
},
},
{
.ident = "Lenovo Zhaoyang E42-80",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ZHAOYANG E42-80"),
},
},
{}
};
......
......@@ -584,11 +584,11 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
if (cmd == IPC_I2C_READ) {
writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
/* Write not getting updated without delay */
mdelay(1);
usleep_range(1000, 2000);
*data = readl(scu->i2c_base + I2C_DATA_ADDR);
} else if (cmd == IPC_I2C_WRITE) {
writel(*data, scu->i2c_base + I2C_DATA_ADDR);
mdelay(1);
usleep_range(1000, 2000);
writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
} else {
dev_err(scu->dev,
......
......@@ -47,6 +47,11 @@
/* LPC bus IO offsets */
#define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
#define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
#define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET 0x20
#define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET 0x21
#define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22
#define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23
#define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24
#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
......@@ -84,6 +89,8 @@
#define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0)
#define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0)
#define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(5, 0)
#define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4)
#define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0)
/* Default I2C parent bus number */
#define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
......@@ -114,11 +121,13 @@
* @pdev_i2c - i2c controller platform device
* @pdev_mux - array of mux platform devices
* @pdev_hotplug - hotplug platform devices
* @pdev_led - led platform devices
*/
struct mlxplat_priv {
struct platform_device *pdev_i2c;
struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
struct platform_device *pdev_hotplug;
struct platform_device *pdev_led;
};
/* Regions for LPC I2C controller and LPC base register space */
......@@ -592,9 +601,227 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
};
/* Platform led default data */
static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
{
.label = "status:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
},
{
.label = "status:red",
.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
},
{
.label = "psu:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
},
{
.label = "psu:red",
.reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
},
{
.label = "fan1:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
},
{
.label = "fan1:red",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
},
{
.label = "fan2:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
},
{
.label = "fan2:red",
.reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
},
{
.label = "fan3:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
},
{
.label = "fan3:red",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
},
{
.label = "fan4:green",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
},
{
.label = "fan4:red",
.reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
.mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
},
};
static struct mlxreg_core_platform_data mlxplat_default_led_data = {
.data = mlxplat_mlxcpld_default_led_data,
.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
};
/* Platform led MSN21xx system family data */
static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {