aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 02:45:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 02:45:53 -0500
commitd1e41ff11941784f469f17795a4d9425c2eb4b7a (patch)
tree9cf7a381919282de65744329f61807ba49a83ad7
parent2f4bf528eca5b2d9eef12b6d323c040254f8f67c (diff)
parentd2f20619942fe4618160a7fa3dbdcbac335cff59 (diff)
Merge tag 'platform-drivers-x86-v4.4-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86
Pull x86 platform driver update from Darren Hart: "Various toshiba hotkey and keyboard related fixes and a new WMI driver. Several intel_scu_ipc cleanups and a locking fix. A spattering of small single fixes across various platforms. I was asked to pick up an OLPC cleanup as the driver appeared unmaintained and it seemed similar to what is maintained in platform/drivers/x86. I have included the patch and an update to the MAINTAINERS file. toshiba_acpi: - Initialize hotkey_event_type variable - Remove unneeded u32 variables from *setup_keyboard - Add 0x prefix to available_kbd_modes_show function - Change default Hotkey enabling value - Unify hotkey enabling functions toshiba-wmi: - Toshiba WMI Hotkey Driver intel_scu_ipc: - Protect dev member assignment on ->remove() - Switch to use module_pci_driver() macro - Convert to use struct device * - Propagate pointer to struct intel_scu_ipc_dev - Fix error path by turning to devm_* / pcim_* acer-wmi: - remove threeg and interface sysfs interfaces OLPC: - Use %*ph specifier instead of passing direct values MAINTAINERS: - Add drivers/platform/olpc to drivers/platform/x86 sony-laptop: - Fix handling sony_nc_hotkeys_decode result intel_mid_powerbtn: - Remove misuse of IRQF_NO_SUSPEND flag compal-laptop: - Add charge control limit asus-wmi: - restore kbd led level after resume" * tag 'platform-drivers-x86-v4.4-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: toshiba_acpi: Initialize hotkey_event_type variable intel_scu_ipc: Protect dev member assignment on ->remove() intel_scu_ipc: Switch to use module_pci_driver() macro intel_scu_ipc: Convert to use struct device * intel_scu_ipc: Propagate pointer to struct intel_scu_ipc_dev intel_scu_ipc: Fix error path by turning to devm_* / pcim_* acer-wmi: remove threeg and interface sysfs interfaces OLPC: Use %*ph specifier instead of passing direct values MAINTAINERS: Add drivers/platform/olpc to drivers/platform/x86 platform/x86: Toshiba WMI Hotkey Driver sony-laptop: Fix handling sony_nc_hotkeys_decode result intel_mid_powerbtn: Remove misuse of IRQF_NO_SUSPEND flag compal-laptop: Add charge control limit asus-wmi: restore kbd led level after resume toshiba_acpi: Remove unneeded u32 variables from *setup_keyboard toshiba_acpi: Add 0x prefix to available_kbd_modes_show function toshiba_acpi: Change default Hotkey enabling value toshiba_acpi: Unify hotkey enabling functions
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/platform/olpc/olpc-ec.c13
-rw-r--r--drivers/platform/x86/Kconfig22
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c92
-rw-r--r--drivers/platform/x86/asus-wmi.c19
-rw-r--r--drivers/platform/x86/compal-laptop.c43
-rw-r--r--drivers/platform/x86/intel_mid_powerbtn.c10
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c189
-rw-r--r--drivers/platform/x86/sony-laptop.c13
-rw-r--r--drivers/platform/x86/toshiba-wmi.c138
-rw-r--r--drivers/platform/x86/toshiba_acpi.c63
12 files changed, 358 insertions, 252 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 7301ae17ec63..15c38961d6ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10699,6 +10699,12 @@ L: platform-driver-x86@vger.kernel.org
10699S: Maintained 10699S: Maintained
10700F: drivers/platform/x86/toshiba_haps.c 10700F: drivers/platform/x86/toshiba_haps.c
10701 10701
10702TOSHIBA WMI HOTKEYS DRIVER
10703M: Azael Avalos <coproscefalo@gmail.com>
10704L: platform-driver-x86@vger.kernel.org
10705S: Maintained
10706F: drivers/platform/x86/toshiba-wmi.c
10707
10702TOSHIBA SMM DRIVER 10708TOSHIBA SMM DRIVER
10703M: Jonathan Buzzard <jonathan@buzzard.org.uk> 10709M: Jonathan Buzzard <jonathan@buzzard.org.uk>
10704W: http://www.buzzard.org.uk/toshiba/ 10710W: http://www.buzzard.org.uk/toshiba/
@@ -11621,6 +11627,7 @@ L: platform-driver-x86@vger.kernel.org
11621T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git 11627T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git
11622S: Maintained 11628S: Maintained
11623F: drivers/platform/x86/ 11629F: drivers/platform/x86/
11630F: drivers/platform/olpc/
11624 11631
11625X86 MCE INFRASTRUCTURE 11632X86 MCE INFRASTRUCTURE
11626M: Tony Luck <tony.luck@intel.com> 11633M: Tony Luck <tony.luck@intel.com>
diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c
index f9119525f557..f99b183d5296 100644
--- a/drivers/platform/olpc/olpc-ec.c
+++ b/drivers/platform/olpc/olpc-ec.c
@@ -192,18 +192,15 @@ static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf,
192 for (i = 0; i <= ec_cmd_bytes; i++) 192 for (i = 0; i <= ec_cmd_bytes; i++)
193 ec_cmd[i] = ec_cmd_int[i]; 193 ec_cmd[i] = ec_cmd_int[i];
194 194
195 pr_debug("olpc-ec: debugfs cmd 0x%02x with %d args %02x %02x %02x %02x %02x, want %d returns\n", 195 pr_debug("olpc-ec: debugfs cmd 0x%02x with %d args %5ph, want %d returns\n",
196 ec_cmd[0], ec_cmd_bytes, ec_cmd[1], ec_cmd[2], 196 ec_cmd[0], ec_cmd_bytes, ec_cmd + 1,
197 ec_cmd[3], ec_cmd[4], ec_cmd[5], ec_dbgfs_resp_bytes); 197 ec_dbgfs_resp_bytes);
198 198
199 olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1], 199 olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1],
200 ec_cmd_bytes, ec_dbgfs_resp, ec_dbgfs_resp_bytes); 200 ec_cmd_bytes, ec_dbgfs_resp, ec_dbgfs_resp_bytes);
201 201
202 pr_debug("olpc-ec: response %02x %02x %02x %02x %02x %02x %02x %02x (%d bytes expected)\n", 202 pr_debug("olpc-ec: response %8ph (%d bytes expected)\n",
203 ec_dbgfs_resp[0], ec_dbgfs_resp[1], ec_dbgfs_resp[2], 203 ec_dbgfs_resp, ec_dbgfs_resp_bytes);
204 ec_dbgfs_resp[3], ec_dbgfs_resp[4], ec_dbgfs_resp[5],
205 ec_dbgfs_resp[6], ec_dbgfs_resp[7],
206 ec_dbgfs_resp_bytes);
207 204
208out: 205out:
209 mutex_unlock(&ec_dbgfs_lock); 206 mutex_unlock(&ec_dbgfs_lock);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index c69bb703f483..7b492d9b3ec4 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -309,8 +309,8 @@ config COMPAL_LAPTOP
309 This is a driver for laptops built by Compal, and some models by 309 This is a driver for laptops built by Compal, and some models by
310 other brands (e.g. Dell, Toshiba). 310 other brands (e.g. Dell, Toshiba).
311 311
312 It adds support for rfkill, Bluetooth, WLAN and LCD brightness 312 It adds support for rfkill, Bluetooth, WLAN, LCD brightness, hwmon
313 control. 313 and battery charging level control.
314 314
315 For a (possibly incomplete) list of supported laptops, please refer 315 For a (possibly incomplete) list of supported laptops, please refer
316 to: Documentation/platform/x86-laptop-drivers.txt 316 to: Documentation/platform/x86-laptop-drivers.txt
@@ -700,6 +700,24 @@ config TOSHIBA_HAPS
700 If you have a recent Toshiba laptop with a built-in accelerometer 700 If you have a recent Toshiba laptop with a built-in accelerometer
701 device, say Y. 701 device, say Y.
702 702
703config TOSHIBA_WMI
704 tristate "Toshiba WMI Hotkeys Driver (EXPERIMENTAL)"
705 default n
706 depends on ACPI_WMI
707 depends on INPUT
708 select INPUT_SPARSEKMAP
709 ---help---
710 This driver adds hotkey monitoring support to some Toshiba models
711 that manage the hotkeys via WMI events.
712
713 WARNING: This driver is incomplete as it lacks a proper keymap and the
714 *notify function only prints the ACPI event type value. Be warned that
715 you will need to provide some information if you have a Toshiba model
716 with WMI event hotkeys and want to help with the develpment of this
717 driver.
718
719 If you have a WMI-based hotkeys Toshiba laptop, say Y or M here.
720
703config ACPI_CMPC 721config ACPI_CMPC
704 tristate "CMPC Laptop Extras" 722 tristate "CMPC Laptop Extras"
705 depends on X86 && ACPI 723 depends on X86 && ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ada512819028..3ca78a3eb6f8 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
40 40
41obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o 41obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
42obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o 42obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o
43obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.o
43obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o 44obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
44obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o 45obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
45obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o 46obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index d773b9dc48a0..1062fa42ff26 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1662,58 +1662,6 @@ static void acer_rfkill_exit(void)
1662 return; 1662 return;
1663} 1663}
1664 1664
1665/*
1666 * sysfs interface
1667 */
1668static ssize_t show_bool_threeg(struct device *dev,
1669 struct device_attribute *attr, char *buf)
1670{
1671 u32 result; \
1672 acpi_status status;
1673
1674 pr_info("This threeg sysfs will be removed in 2014 - used by: %s\n",
1675 current->comm);
1676 status = get_u32(&result, ACER_CAP_THREEG);
1677 if (ACPI_SUCCESS(status))
1678 return sprintf(buf, "%u\n", result);
1679 return sprintf(buf, "Read error\n");
1680}
1681
1682static ssize_t set_bool_threeg(struct device *dev,
1683 struct device_attribute *attr, const char *buf, size_t count)
1684{
1685 u32 tmp = simple_strtoul(buf, NULL, 10);
1686 acpi_status status = set_u32(tmp, ACER_CAP_THREEG);
1687 pr_info("This threeg sysfs will be removed in 2014 - used by: %s\n",
1688 current->comm);
1689 if (ACPI_FAILURE(status))
1690 return -EINVAL;
1691 return count;
1692}
1693static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg,
1694 set_bool_threeg);
1695
1696static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
1697 char *buf)
1698{
1699 pr_info("This interface sysfs will be removed in 2014 - used by: %s\n",
1700 current->comm);
1701 switch (interface->type) {
1702 case ACER_AMW0:
1703 return sprintf(buf, "AMW0\n");
1704 case ACER_AMW0_V2:
1705 return sprintf(buf, "AMW0 v2\n");
1706 case ACER_WMID:
1707 return sprintf(buf, "WMID\n");
1708 case ACER_WMID_v2:
1709 return sprintf(buf, "WMID v2\n");
1710 default:
1711 return sprintf(buf, "Error!\n");
1712 }
1713}
1714
1715static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
1716
1717static void acer_wmi_notify(u32 value, void *context) 1665static void acer_wmi_notify(u32 value, void *context)
1718{ 1666{
1719 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 1667 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -2127,39 +2075,6 @@ static struct platform_driver acer_platform_driver = {
2127 2075
2128static struct platform_device *acer_platform_device; 2076static struct platform_device *acer_platform_device;
2129 2077
2130static int remove_sysfs(struct platform_device *device)
2131{
2132 if (has_cap(ACER_CAP_THREEG))
2133 device_remove_file(&device->dev, &dev_attr_threeg);
2134
2135 device_remove_file(&device->dev, &dev_attr_interface);
2136
2137 return 0;
2138}
2139
2140static int __init create_sysfs(void)
2141{
2142 int retval = -ENOMEM;
2143
2144 if (has_cap(ACER_CAP_THREEG)) {
2145 retval = device_create_file(&acer_platform_device->dev,
2146 &dev_attr_threeg);
2147 if (retval)
2148 goto error_sysfs;
2149 }
2150
2151 retval = device_create_file(&acer_platform_device->dev,
2152 &dev_attr_interface);
2153 if (retval)
2154 goto error_sysfs;
2155
2156 return 0;
2157
2158error_sysfs:
2159 remove_sysfs(acer_platform_device);
2160 return retval;
2161}
2162
2163static void remove_debugfs(void) 2078static void remove_debugfs(void)
2164{ 2079{
2165 debugfs_remove(interface->debug.devices); 2080 debugfs_remove(interface->debug.devices);
@@ -2290,10 +2205,6 @@ static int __init acer_wmi_init(void)
2290 if (err) 2205 if (err)
2291 goto error_device_add; 2206 goto error_device_add;
2292 2207
2293 err = create_sysfs();
2294 if (err)
2295 goto error_create_sys;
2296
2297 if (wmi_has_guid(WMID_GUID2)) { 2208 if (wmi_has_guid(WMID_GUID2)) {
2298 interface->debug.wmid_devices = get_wmid_devices(); 2209 interface->debug.wmid_devices = get_wmid_devices();
2299 err = create_debugfs(); 2210 err = create_debugfs();
@@ -2307,8 +2218,6 @@ static int __init acer_wmi_init(void)
2307 return 0; 2218 return 0;
2308 2219
2309error_create_debugfs: 2220error_create_debugfs:
2310 remove_sysfs(acer_platform_device);
2311error_create_sys:
2312 platform_device_del(acer_platform_device); 2221 platform_device_del(acer_platform_device);
2313error_device_add: 2222error_device_add:
2314 platform_device_put(acer_platform_device); 2223 platform_device_put(acer_platform_device);
@@ -2331,7 +2240,6 @@ static void __exit acer_wmi_exit(void)
2331 if (has_cap(ACER_CAP_ACCEL)) 2240 if (has_cap(ACER_CAP_ACCEL))
2332 acer_wmi_accel_destroy(); 2241 acer_wmi_accel_destroy();
2333 2242
2334 remove_sysfs(acer_platform_device);
2335 remove_debugfs(); 2243 remove_debugfs();
2336 platform_device_unregister(acer_platform_device); 2244 platform_device_unregister(acer_platform_device);
2337 platform_driver_unregister(&acer_platform_driver); 2245 platform_driver_unregister(&acer_platform_driver);
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index efbc3f0c592b..1f7d80ff8cb4 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -582,7 +582,7 @@ static void asus_wmi_led_exit(struct asus_wmi *asus)
582 582
583static int asus_wmi_led_init(struct asus_wmi *asus) 583static int asus_wmi_led_init(struct asus_wmi *asus)
584{ 584{
585 int rv = 0; 585 int rv = 0, led_val;
586 586
587 asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); 587 asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
588 if (!asus->led_workqueue) 588 if (!asus->led_workqueue)
@@ -602,9 +602,11 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
602 goto error; 602 goto error;
603 } 603 }
604 604
605 if (kbd_led_read(asus, NULL, NULL) >= 0) { 605 led_val = kbd_led_read(asus, NULL, NULL);
606 if (led_val >= 0) {
606 INIT_WORK(&asus->kbd_led_work, kbd_led_update); 607 INIT_WORK(&asus->kbd_led_work, kbd_led_update);
607 608
609 asus->kbd_led_wk = led_val;
608 asus->kbd_led.name = "asus::kbd_backlight"; 610 asus->kbd_led.name = "asus::kbd_backlight";
609 asus->kbd_led.brightness_set = kbd_led_set; 611 asus->kbd_led.brightness_set = kbd_led_set;
610 asus->kbd_led.brightness_get = kbd_led_get; 612 asus->kbd_led.brightness_get = kbd_led_get;
@@ -2160,6 +2162,16 @@ static int asus_hotk_thaw(struct device *device)
2160 return 0; 2162 return 0;
2161} 2163}
2162 2164
2165static int asus_hotk_resume(struct device *device)
2166{
2167 struct asus_wmi *asus = dev_get_drvdata(device);
2168
2169 if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
2170 queue_work(asus->led_workqueue, &asus->kbd_led_work);
2171
2172 return 0;
2173}
2174
2163static int asus_hotk_restore(struct device *device) 2175static int asus_hotk_restore(struct device *device)
2164{ 2176{
2165 struct asus_wmi *asus = dev_get_drvdata(device); 2177 struct asus_wmi *asus = dev_get_drvdata(device);
@@ -2190,6 +2202,8 @@ static int asus_hotk_restore(struct device *device)
2190 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB); 2202 bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB);
2191 rfkill_set_sw_state(asus->uwb.rfkill, bl); 2203 rfkill_set_sw_state(asus->uwb.rfkill, bl);
2192 } 2204 }
2205 if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
2206 queue_work(asus->led_workqueue, &asus->kbd_led_work);
2193 2207
2194 return 0; 2208 return 0;
2195} 2209}
@@ -2197,6 +2211,7 @@ static int asus_hotk_restore(struct device *device)
2197static const struct dev_pm_ops asus_pm_ops = { 2211static const struct dev_pm_ops asus_pm_ops = {
2198 .thaw = asus_hotk_thaw, 2212 .thaw = asus_hotk_thaw,
2199 .restore = asus_hotk_restore, 2213 .restore = asus_hotk_restore,
2214 .resume = asus_hotk_resume,
2200}; 2215};
2201 2216
2202static int asus_wmi_probe(struct platform_device *pdev) 2217static int asus_wmi_probe(struct platform_device *pdev)
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index f2706d27adff..e1c2b6d4b24a 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -151,6 +151,8 @@
151#define BAT_STATUS2 0xF1 151#define BAT_STATUS2 0xF1
152#define BAT_STOP_CHARGE1 0xF2 152#define BAT_STOP_CHARGE1 0xF2
153#define BAT_STOP_CHARGE2 0xF3 153#define BAT_STOP_CHARGE2 0xF3
154#define BAT_CHARGE_LIMIT 0x03
155#define BAT_CHARGE_LIMIT_MAX 100
154 156
155#define BAT_S0_DISCHARGE (1 << 0) 157#define BAT_S0_DISCHARGE (1 << 0)
156#define BAT_S0_DISCHRG_CRITICAL (1 << 2) 158#define BAT_S0_DISCHRG_CRITICAL (1 << 2)
@@ -601,6 +603,12 @@ static int bat_get_property(struct power_supply *psy,
601 case POWER_SUPPLY_PROP_CHARGE_NOW: 603 case POWER_SUPPLY_PROP_CHARGE_NOW:
602 val->intval = ec_read_u16(BAT_CHARGE_NOW) * 1000; 604 val->intval = ec_read_u16(BAT_CHARGE_NOW) * 1000;
603 break; 605 break;
606 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
607 val->intval = ec_read_u8(BAT_CHARGE_LIMIT);
608 break;
609 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
610 val->intval = BAT_CHARGE_LIMIT_MAX;
611 break;
604 case POWER_SUPPLY_PROP_CAPACITY: 612 case POWER_SUPPLY_PROP_CAPACITY:
605 val->intval = ec_read_u8(BAT_CAPACITY); 613 val->intval = ec_read_u8(BAT_CAPACITY);
606 break; 614 break;
@@ -634,6 +642,36 @@ static int bat_get_property(struct power_supply *psy,
634 return 0; 642 return 0;
635} 643}
636 644
645static int bat_set_property(struct power_supply *psy,
646 enum power_supply_property psp,
647 const union power_supply_propval *val)
648{
649 int level;
650
651 switch (psp) {
652 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
653 level = val->intval;
654 if (level < 0 || level > BAT_CHARGE_LIMIT_MAX)
655 return -EINVAL;
656 if (ec_write(BAT_CHARGE_LIMIT, level) < 0)
657 return -EIO;
658 break;
659 default:
660 break;
661 }
662 return 0;
663}
664
665static int bat_writeable_property(struct power_supply *psy,
666 enum power_supply_property psp)
667{
668 switch (psp) {
669 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
670 return 1;
671 default:
672 return 0;
673 }
674}
637 675
638 676
639 677
@@ -726,6 +764,8 @@ static enum power_supply_property compal_bat_properties[] = {
726 POWER_SUPPLY_PROP_POWER_NOW, 764 POWER_SUPPLY_PROP_POWER_NOW,
727 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 765 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
728 POWER_SUPPLY_PROP_CHARGE_NOW, 766 POWER_SUPPLY_PROP_CHARGE_NOW,
767 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
768 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
729 POWER_SUPPLY_PROP_CAPACITY, 769 POWER_SUPPLY_PROP_CAPACITY,
730 POWER_SUPPLY_PROP_CAPACITY_LEVEL, 770 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
731 POWER_SUPPLY_PROP_TEMP, 771 POWER_SUPPLY_PROP_TEMP,
@@ -880,11 +920,12 @@ static const struct power_supply_desc psy_bat_desc = {
880 .properties = compal_bat_properties, 920 .properties = compal_bat_properties,
881 .num_properties = ARRAY_SIZE(compal_bat_properties), 921 .num_properties = ARRAY_SIZE(compal_bat_properties),
882 .get_property = bat_get_property, 922 .get_property = bat_get_property,
923 .set_property = bat_set_property,
924 .property_is_writeable = bat_writeable_property,
883}; 925};
884 926
885static void initialize_power_supply_data(struct compal_data *data) 927static void initialize_power_supply_data(struct compal_data *data)
886{ 928{
887
888 ec_read_sequence(BAT_MANUFACTURER_NAME_ADDR, 929 ec_read_sequence(BAT_MANUFACTURER_NAME_ADDR,
889 data->bat_manufacturer_name, 930 data->bat_manufacturer_name,
890 BAT_MANUFACTURER_NAME_LEN); 931 BAT_MANUFACTURER_NAME_LEN);
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
index 22606d6b2af3..1fc0de870ff8 100644
--- a/drivers/platform/x86/intel_mid_powerbtn.c
+++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/input.h> 25#include <linux/input.h>
26#include <linux/mfd/intel_msic.h> 26#include <linux/mfd/intel_msic.h>
27#include <linux/pm_wakeirq.h>
27 28
28#define DRIVER_NAME "msic_power_btn" 29#define DRIVER_NAME "msic_power_btn"
29 30
@@ -76,14 +77,17 @@ static int mfld_pb_probe(struct platform_device *pdev)
76 77
77 input_set_capability(input, EV_KEY, KEY_POWER); 78 input_set_capability(input, EV_KEY, KEY_POWER);
78 79
79 error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND, 80 error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0,
80 DRIVER_NAME, input); 81 DRIVER_NAME, input);
81 if (error) { 82 if (error) {
82 dev_err(&pdev->dev, "Unable to request irq %d for mfld power" 83 dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
83 "button\n", irq); 84 "button\n", irq);
84 goto err_free_input; 85 goto err_free_input;
85 } 86 }
86 87
88 device_init_wakeup(&pdev->dev, true);
89 dev_pm_set_wake_irq(&pdev->dev, irq);
90
87 error = input_register_device(input); 91 error = input_register_device(input);
88 if (error) { 92 if (error) {
89 dev_err(&pdev->dev, "Unable to register input dev, error " 93 dev_err(&pdev->dev, "Unable to register input dev, error "
@@ -124,6 +128,8 @@ static int mfld_pb_remove(struct platform_device *pdev)
124 struct input_dev *input = platform_get_drvdata(pdev); 128 struct input_dev *input = platform_get_drvdata(pdev);
125 int irq = platform_get_irq(pdev, 0); 129 int irq = platform_get_irq(pdev, 0);
126 130
131 dev_pm_clear_wake_irq(&pdev->dev);
132 device_init_wakeup(&pdev->dev, false);
127 free_irq(irq, input); 133 free_irq(irq, input);
128 input_unregister_device(input); 134 input_unregister_device(input);
129 135
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 187d1086d15c..f94b730540e2 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -92,11 +92,8 @@ static struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
92 .irq_mode = 0, 92 .irq_mode = 0,
93}; 93};
94 94
95static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id);
96static void ipc_remove(struct pci_dev *pdev);
97
98struct intel_scu_ipc_dev { 95struct intel_scu_ipc_dev {
99 struct pci_dev *pdev; 96 struct device *dev;
100 void __iomem *ipc_base; 97 void __iomem *ipc_base;
101 void __iomem *i2c_base; 98 void __iomem *i2c_base;
102 struct completion cmd_complete; 99 struct completion cmd_complete;
@@ -118,28 +115,30 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */
118static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ 115static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
119 116
120/* 117/*
118 * Send ipc command
121 * Command Register (Write Only): 119 * Command Register (Write Only):
122 * A write to this register results in an interrupt to the SCU core processor 120 * A write to this register results in an interrupt to the SCU core processor
123 * Format: 121 * Format:
124 * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)| 122 * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)|
125 */ 123 */
126static inline void ipc_command(u32 cmd) /* Send ipc command */ 124static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd)
127{ 125{
128 if (ipcdev.irq_mode) { 126 if (scu->irq_mode) {
129 reinit_completion(&ipcdev.cmd_complete); 127 reinit_completion(&scu->cmd_complete);
130 writel(cmd | IPC_IOC, ipcdev.ipc_base); 128 writel(cmd | IPC_IOC, scu->ipc_base);
131 } 129 }
132 writel(cmd, ipcdev.ipc_base); 130 writel(cmd, scu->ipc_base);
133} 131}
134 132
135/* 133/*
134 * Write ipc data
136 * IPC Write Buffer (Write Only): 135 * IPC Write Buffer (Write Only):
137 * 16-byte buffer for sending data associated with IPC command to 136 * 16-byte buffer for sending data associated with IPC command to
138 * SCU. Size of the data is specified in the IPC_COMMAND_REG register 137 * SCU. Size of the data is specified in the IPC_COMMAND_REG register
139 */ 138 */
140static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ 139static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32 offset)
141{ 140{
142 writel(data, ipcdev.ipc_base + 0x80 + offset); 141 writel(data, scu->ipc_base + 0x80 + offset);
143} 142}
144 143
145/* 144/*
@@ -149,35 +148,37 @@ static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */
149 * Format: 148 * Format:
150 * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| 149 * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)|
151 */ 150 */
152static inline u8 ipc_read_status(void) 151static inline u8 ipc_read_status(struct intel_scu_ipc_dev *scu)
153{ 152{
154 return __raw_readl(ipcdev.ipc_base + 0x04); 153 return __raw_readl(scu->ipc_base + 0x04);
155} 154}
156 155
157static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */ 156/* Read ipc byte data */
157static inline u8 ipc_data_readb(struct intel_scu_ipc_dev *scu, u32 offset)
158{ 158{
159 return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 159 return readb(scu->ipc_base + IPC_READ_BUFFER + offset);
160} 160}
161 161
162static inline u32 ipc_data_readl(u32 offset) /* Read ipc u32 data */ 162/* Read ipc u32 data */
163static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
163{ 164{
164 return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 165 return readl(scu->ipc_base + IPC_READ_BUFFER + offset);
165} 166}
166 167
167/* Wait till scu status is busy */ 168/* Wait till scu status is busy */
168static inline int busy_loop(void) 169static inline int busy_loop(struct intel_scu_ipc_dev *scu)
169{ 170{
170 u32 status = ipc_read_status(); 171 u32 status = ipc_read_status(scu);
171 u32 loop_count = 100000; 172 u32 loop_count = 100000;
172 173
173 /* break if scu doesn't reset busy bit after huge retry */ 174 /* break if scu doesn't reset busy bit after huge retry */
174 while ((status & BIT(0)) && --loop_count) { 175 while ((status & BIT(0)) && --loop_count) {
175 udelay(1); /* scu processing time is in few u secods */ 176 udelay(1); /* scu processing time is in few u secods */
176 status = ipc_read_status(); 177 status = ipc_read_status(scu);
177 } 178 }
178 179
179 if (status & BIT(0)) { 180 if (status & BIT(0)) {
180 dev_err(&ipcdev.pdev->dev, "IPC timed out"); 181 dev_err(scu->dev, "IPC timed out");
181 return -ETIMEDOUT; 182 return -ETIMEDOUT;
182 } 183 }
183 184
@@ -188,31 +189,31 @@ static inline int busy_loop(void)
188} 189}
189 190
190/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */ 191/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
191static inline int ipc_wait_for_interrupt(void) 192static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
192{ 193{
193 int status; 194 int status;
194 195
195 if (!wait_for_completion_timeout(&ipcdev.cmd_complete, 3 * HZ)) { 196 if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) {
196 struct device *dev = &ipcdev.pdev->dev; 197 dev_err(scu->dev, "IPC timed out\n");
197 dev_err(dev, "IPC timed out\n");
198 return -ETIMEDOUT; 198 return -ETIMEDOUT;
199 } 199 }
200 200
201 status = ipc_read_status(); 201 status = ipc_read_status(scu);
202 if (status & BIT(1)) 202 if (status & BIT(1))
203 return -EIO; 203 return -EIO;
204 204
205 return 0; 205 return 0;
206} 206}
207 207
208static int intel_scu_ipc_check_status(void) 208static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
209{ 209{
210 return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop(); 210 return scu->irq_mode ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
211} 211}
212 212
213/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ 213/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
214static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) 214static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
215{ 215{
216 struct intel_scu_ipc_dev *scu = &ipcdev;
216 int nc; 217 int nc;
217 u32 offset = 0; 218 u32 offset = 0;
218 int err; 219 int err;
@@ -223,7 +224,7 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
223 224
224 mutex_lock(&ipclock); 225 mutex_lock(&ipclock);
225 226
226 if (ipcdev.pdev == NULL) { 227 if (scu->dev == NULL) {
227 mutex_unlock(&ipclock); 228 mutex_unlock(&ipclock);
228 return -ENODEV; 229 return -ENODEV;
229 } 230 }
@@ -235,27 +236,27 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
235 236
236 if (id == IPC_CMD_PCNTRL_R) { 237 if (id == IPC_CMD_PCNTRL_R) {
237 for (nc = 0, offset = 0; nc < count; nc++, offset += 4) 238 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
238 ipc_data_writel(wbuf[nc], offset); 239 ipc_data_writel(scu, wbuf[nc], offset);
239 ipc_command((count * 2) << 16 | id << 12 | 0 << 8 | op); 240 ipc_command(scu, (count * 2) << 16 | id << 12 | 0 << 8 | op);
240 } else if (id == IPC_CMD_PCNTRL_W) { 241 } else if (id == IPC_CMD_PCNTRL_W) {
241 for (nc = 0; nc < count; nc++, offset += 1) 242 for (nc = 0; nc < count; nc++, offset += 1)
242 cbuf[offset] = data[nc]; 243 cbuf[offset] = data[nc];
243 for (nc = 0, offset = 0; nc < count; nc++, offset += 4) 244 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
244 ipc_data_writel(wbuf[nc], offset); 245 ipc_data_writel(scu, wbuf[nc], offset);
245 ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); 246 ipc_command(scu, (count * 3) << 16 | id << 12 | 0 << 8 | op);
246 } else if (id == IPC_CMD_PCNTRL_M) { 247 } else if (id == IPC_CMD_PCNTRL_M) {
247 cbuf[offset] = data[0]; 248 cbuf[offset] = data[0];
248 cbuf[offset + 1] = data[1]; 249 cbuf[offset + 1] = data[1];
249 ipc_data_writel(wbuf[0], 0); /* Write wbuff */ 250 ipc_data_writel(scu, wbuf[0], 0); /* Write wbuff */
250 ipc_command(4 << 16 | id << 12 | 0 << 8 | op); 251 ipc_command(scu, 4 << 16 | id << 12 | 0 << 8 | op);
251 } 252 }
252 253
253 err = intel_scu_ipc_check_status(); 254 err = intel_scu_ipc_check_status(scu);
254 if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ 255 if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
255 /* Workaround: values are read as 0 without memcpy_fromio */ 256 /* Workaround: values are read as 0 without memcpy_fromio */
256 memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16); 257 memcpy_fromio(cbuf, scu->ipc_base + 0x90, 16);
257 for (nc = 0; nc < count; nc++) 258 for (nc = 0; nc < count; nc++)
258 data[nc] = ipc_data_readb(nc); 259 data[nc] = ipc_data_readb(scu, nc);
259 } 260 }
260 mutex_unlock(&ipclock); 261 mutex_unlock(&ipclock);
261 return err; 262 return err;
@@ -436,15 +437,16 @@ EXPORT_SYMBOL(intel_scu_ipc_update_register);
436 */ 437 */
437int intel_scu_ipc_simple_command(int cmd, int sub) 438int intel_scu_ipc_simple_command(int cmd, int sub)
438{ 439{
440 struct intel_scu_ipc_dev *scu = &ipcdev;
439 int err; 441 int err;
440 442
441 mutex_lock(&ipclock); 443 mutex_lock(&ipclock);
442 if (ipcdev.pdev == NULL) { 444 if (scu->dev == NULL) {
443 mutex_unlock(&ipclock); 445 mutex_unlock(&ipclock);
444 return -ENODEV; 446 return -ENODEV;
445 } 447 }
446 ipc_command(sub << 12 | cmd); 448 ipc_command(scu, sub << 12 | cmd);
447 err = intel_scu_ipc_check_status(); 449 err = intel_scu_ipc_check_status(scu);
448 mutex_unlock(&ipclock); 450 mutex_unlock(&ipclock);
449 return err; 451 return err;
450} 452}
@@ -465,23 +467,24 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command);
465int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, 467int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
466 u32 *out, int outlen) 468 u32 *out, int outlen)
467{ 469{
470 struct intel_scu_ipc_dev *scu = &ipcdev;
468 int i, err; 471 int i, err;
469 472
470 mutex_lock(&ipclock); 473 mutex_lock(&ipclock);
471 if (ipcdev.pdev == NULL) { 474 if (scu->dev == NULL) {
472 mutex_unlock(&ipclock); 475 mutex_unlock(&ipclock);
473 return -ENODEV; 476 return -ENODEV;
474 } 477 }
475 478
476 for (i = 0; i < inlen; i++) 479 for (i = 0; i < inlen; i++)
477 ipc_data_writel(*in++, 4 * i); 480 ipc_data_writel(scu, *in++, 4 * i);
478 481
479 ipc_command((inlen << 16) | (sub << 12) | cmd); 482 ipc_command(scu, (inlen << 16) | (sub << 12) | cmd);
480 err = intel_scu_ipc_check_status(); 483 err = intel_scu_ipc_check_status(scu);
481 484
482 if (!err) { 485 if (!err) {
483 for (i = 0; i < outlen; i++) 486 for (i = 0; i < outlen; i++)
484 *out++ = ipc_data_readl(4 * i); 487 *out++ = ipc_data_readl(scu, 4 * i);
485 } 488 }
486 489
487 mutex_unlock(&ipclock); 490 mutex_unlock(&ipclock);
@@ -507,25 +510,26 @@ EXPORT_SYMBOL(intel_scu_ipc_command);
507 */ 510 */
508int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) 511int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
509{ 512{
513 struct intel_scu_ipc_dev *scu = &ipcdev;
510 u32 cmd = 0; 514 u32 cmd = 0;
511 515
512 mutex_lock(&ipclock); 516 mutex_lock(&ipclock);
513 if (ipcdev.pdev == NULL) { 517 if (scu->dev == NULL) {
514 mutex_unlock(&ipclock); 518 mutex_unlock(&ipclock);
515 return -ENODEV; 519 return -ENODEV;
516 } 520 }
517 cmd = (addr >> 24) & 0xFF; 521 cmd = (addr >> 24) & 0xFF;
518 if (cmd == IPC_I2C_READ) { 522 if (cmd == IPC_I2C_READ) {
519 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); 523 writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
520 /* Write not getting updated without delay */ 524 /* Write not getting updated without delay */
521 mdelay(1); 525 mdelay(1);
522 *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); 526 *data = readl(scu->i2c_base + I2C_DATA_ADDR);
523 } else if (cmd == IPC_I2C_WRITE) { 527 } else if (cmd == IPC_I2C_WRITE) {
524 writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR); 528 writel(*data, scu->i2c_base + I2C_DATA_ADDR);
525 mdelay(1); 529 mdelay(1);
526 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); 530 writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
527 } else { 531 } else {
528 dev_err(&ipcdev.pdev->dev, 532 dev_err(scu->dev,
529 "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd); 533 "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
530 534
531 mutex_unlock(&ipclock); 535 mutex_unlock(&ipclock);
@@ -545,63 +549,65 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
545 */ 549 */
546static irqreturn_t ioc(int irq, void *dev_id) 550static irqreturn_t ioc(int irq, void *dev_id)
547{ 551{
548 if (ipcdev.irq_mode) 552 struct intel_scu_ipc_dev *scu = dev_id;
549 complete(&ipcdev.cmd_complete); 553
554 if (scu->irq_mode)
555 complete(&scu->cmd_complete);
550 556
551 return IRQ_HANDLED; 557 return IRQ_HANDLED;
552} 558}
553 559
554/** 560/**
555 * ipc_probe - probe an Intel SCU IPC 561 * ipc_probe - probe an Intel SCU IPC
556 * @dev: the PCI device matching 562 * @pdev: the PCI device matching
557 * @id: entry in the match table 563 * @id: entry in the match table
558 * 564 *
559 * Enable and install an intel SCU IPC. This appears in the PCI space 565 * Enable and install an intel SCU IPC. This appears in the PCI space
560 * but uses some hard coded addresses as well. 566 * but uses some hard coded addresses as well.
561 */ 567 */
562static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) 568static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
563{ 569{
570 int platform; /* Platform type */
564 int err; 571 int err;
572 struct intel_scu_ipc_dev *scu = &ipcdev;
565 struct intel_scu_ipc_pdata_t *pdata; 573 struct intel_scu_ipc_pdata_t *pdata;
566 resource_size_t base;
567 574
568 if (ipcdev.pdev) /* We support only one SCU */ 575 platform = intel_mid_identify_cpu();
576 if (platform == 0)
577 return -ENODEV;
578
579 if (scu->dev) /* We support only one SCU */
569 return -EBUSY; 580 return -EBUSY;
570 581
571 pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data; 582 pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data;
572 583
573 ipcdev.pdev = pci_dev_get(dev); 584 scu->dev = &pdev->dev;
574 ipcdev.irq_mode = pdata->irq_mode; 585 scu->irq_mode = pdata->irq_mode;
575 586
576 err = pci_enable_device(dev); 587 err = pcim_enable_device(pdev);
577 if (err) 588 if (err)
578 return err; 589 return err;
579 590
580 err = pci_request_regions(dev, "intel_scu_ipc"); 591 err = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
581 if (err) 592 if (err)
582 return err; 593 return err;
583 594
584 base = pci_resource_start(dev, 0); 595 init_completion(&scu->cmd_complete);
585 if (!base)
586 return -ENOMEM;
587 596
588 init_completion(&ipcdev.cmd_complete); 597 err = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_scu_ipc",
598 scu);
599 if (err)
600 return err;
589 601
590 if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) 602 scu->ipc_base = pcim_iomap_table(pdev)[0];
591 return -EBUSY;
592 603
593 ipcdev.ipc_base = ioremap_nocache(base, pci_resource_len(dev, 0)); 604 scu->i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
594 if (!ipcdev.ipc_base) 605 if (!scu->i2c_base)
595 return -ENOMEM; 606 return -ENOMEM;
596 607
597 ipcdev.i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
598 if (!ipcdev.i2c_base) {
599 iounmap(ipcdev.ipc_base);
600 return -ENOMEM;
601 }
602
603 intel_scu_devices_create(); 608 intel_scu_devices_create();
604 609
610 pci_set_drvdata(pdev, scu);
605 return 0; 611 return 0;
606} 612}
607 613
@@ -617,12 +623,13 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
617 */ 623 */
618static void ipc_remove(struct pci_dev *pdev) 624static void ipc_remove(struct pci_dev *pdev)
619{ 625{
620 free_irq(pdev->irq, &ipcdev); 626 struct intel_scu_ipc_dev *scu = pci_get_drvdata(pdev);
621 pci_release_regions(pdev); 627
622 pci_dev_put(ipcdev.pdev); 628 mutex_lock(&ipclock);
623 iounmap(ipcdev.ipc_base); 629 scu->dev = NULL;
624 iounmap(ipcdev.i2c_base); 630 mutex_unlock(&ipclock);
625 ipcdev.pdev = NULL; 631
632 iounmap(scu->i2c_base);
626 intel_scu_devices_destroy(); 633 intel_scu_devices_destroy();
627} 634}
628 635
@@ -652,24 +659,8 @@ static struct pci_driver ipc_driver = {
652 .remove = ipc_remove, 659 .remove = ipc_remove,
653}; 660};
654 661
655static int __init intel_scu_ipc_init(void) 662module_pci_driver(ipc_driver);
656{
657 int platform; /* Platform type */
658
659 platform = intel_mid_identify_cpu();
660 if (platform == 0)
661 return -ENODEV;
662 return pci_register_driver(&ipc_driver);
663}
664
665static void __exit intel_scu_ipc_exit(void)
666{
667 pci_unregister_driver(&ipc_driver);
668}
669 663
670MODULE_AUTHOR("Sreedhara DS <sreedhara.ds@intel.com>"); 664MODULE_AUTHOR("Sreedhara DS <sreedhara.ds@intel.com>");
671MODULE_DESCRIPTION("Intel SCU IPC driver"); 665MODULE_DESCRIPTION("Intel SCU IPC driver");
672MODULE_LICENSE("GPL"); 666MODULE_LICENSE("GPL");
673
674module_init(intel_scu_ipc_init);
675module_exit(intel_scu_ipc_exit);
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index aeb80d1c2b07..f73c29558cd3 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1204,6 +1204,8 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1204{ 1204{
1205 u32 real_ev = event; 1205 u32 real_ev = event;
1206 u8 ev_type = 0; 1206 u8 ev_type = 0;
1207 int ret;
1208
1207 dprintk("sony_nc_notify, event: 0x%.2x\n", event); 1209 dprintk("sony_nc_notify, event: 0x%.2x\n", event);
1208 1210
1209 if (event >= 0x90) { 1211 if (event >= 0x90) {
@@ -1225,13 +1227,12 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1225 case 0x0100: 1227 case 0x0100:
1226 case 0x0127: 1228 case 0x0127:
1227 ev_type = HOTKEY; 1229 ev_type = HOTKEY;
1228 real_ev = sony_nc_hotkeys_decode(event, handle); 1230 ret = sony_nc_hotkeys_decode(event, handle);
1229 1231
1230 if (real_ev > 0) 1232 if (ret > 0) {
1231 sony_laptop_report_input_event(real_ev); 1233 sony_laptop_report_input_event(ret);
1232 else 1234 real_ev = ret;
1233 /* restore the original event for reporting */ 1235 }
1234 real_ev = event;
1235 1236
1236 break; 1237 break;
1237 1238
diff --git a/drivers/platform/x86/toshiba-wmi.c b/drivers/platform/x86/toshiba-wmi.c
new file mode 100644
index 000000000000..feac4576b837
--- /dev/null
+++ b/drivers/platform/x86/toshiba-wmi.c
@@ -0,0 +1,138 @@
1/*
2 * toshiba_wmi.c - Toshiba WMI Hotkey Driver
3 *
4 * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/types.h>
24#include <linux/acpi.h>
25#include <linux/input.h>
26#include <linux/input/sparse-keymap.h>
27
28MODULE_AUTHOR("Azael Avalos");
29MODULE_DESCRIPTION("Toshiba WMI Hotkey Driver");
30MODULE_LICENSE("GPL");
31
32#define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100"
33
34MODULE_ALIAS("wmi:"TOSHIBA_WMI_EVENT_GUID);
35
36static struct input_dev *toshiba_wmi_input_dev;
37
38static const struct key_entry toshiba_wmi_keymap[] __initconst = {
39 /* TODO: Add keymap values once found... */
40 /*{ KE_KEY, 0x00, { KEY_ } },*/
41 { KE_END, 0 }
42};
43
44static void toshiba_wmi_notify(u32 value, void *context)
45{
46 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
47 union acpi_object *obj;
48 acpi_status status;
49
50 status = wmi_get_event_data(value, &response);
51 if (ACPI_FAILURE(status)) {
52 pr_err("Bad event status 0x%x\n", status);
53 return;
54 }
55
56 obj = (union acpi_object *)response.pointer;
57 if (!obj)
58 return;
59
60 /* TODO: Add proper checks once we have data */
61 pr_debug("Unknown event received, obj type %x\n", obj->type);
62
63 kfree(response.pointer);
64}
65
66static int __init toshiba_wmi_input_setup(void)
67{
68 acpi_status status;
69 int err;
70
71 toshiba_wmi_input_dev = input_allocate_device();
72 if (!toshiba_wmi_input_dev)
73 return -ENOMEM;
74
75 toshiba_wmi_input_dev->name = "Toshiba WMI hotkeys";
76 toshiba_wmi_input_dev->phys = "wmi/input0";
77 toshiba_wmi_input_dev->id.bustype = BUS_HOST;
78
79 err = sparse_keymap_setup(toshiba_wmi_input_dev,
80 toshiba_wmi_keymap, NULL);
81 if (err)
82 goto err_free_dev;
83
84 status = wmi_install_notify_handler(TOSHIBA_WMI_EVENT_GUID,
85 toshiba_wmi_notify, NULL);
86 if (ACPI_FAILURE(status)) {
87 err = -EIO;
88 goto err_free_keymap;
89 }
90
91 err = input_register_device(toshiba_wmi_input_dev);
92 if (err)
93 goto err_remove_notifier;
94
95 return 0;
96
97 err_remove_notifier:
98 wmi_remove_notify_handler(TOSHIBA_WMI_EVENT_GUID);
99 err_free_keymap:
100 sparse_keymap_free(toshiba_wmi_input_dev);
101 err_free_dev:
102 input_free_device(toshiba_wmi_input_dev);
103 return err;
104}
105
106static void toshiba_wmi_input_destroy(void)
107{
108 wmi_remove_notify_handler(TOSHIBA_WMI_EVENT_GUID);
109 sparse_keymap_free(toshiba_wmi_input_dev);
110 input_unregister_device(toshiba_wmi_input_dev);
111}
112
113static int __init toshiba_wmi_init(void)
114{
115 int ret;
116
117 if (!wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
118 return -ENODEV;
119
120 ret = toshiba_wmi_input_setup();
121 if (ret) {
122 pr_err("Failed to setup input device\n");
123 return ret;
124 }
125
126 pr_info("Toshiba WMI Hotkey Driver\n");
127
128 return 0;
129}
130
131static void __exit toshiba_wmi_exit(void)
132{
133 if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
134 toshiba_wmi_input_destroy();
135}
136
137module_init(toshiba_wmi_init);
138module_exit(toshiba_wmi_exit);
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index f2372f400ddb..c01302989ee4 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -131,7 +131,7 @@ MODULE_LICENSE("GPL");
131/* Field definitions */ 131/* Field definitions */
132#define HCI_ACCEL_MASK 0x7fff 132#define HCI_ACCEL_MASK 0x7fff
133#define HCI_HOTKEY_DISABLE 0x0b 133#define HCI_HOTKEY_DISABLE 0x0b
134#define HCI_HOTKEY_ENABLE 0x09 134#define HCI_HOTKEY_ENABLE 0x01
135#define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10 135#define HCI_HOTKEY_SPECIAL_FUNCTIONS 0x10
136#define HCI_LCD_BRIGHTNESS_BITS 3 136#define HCI_LCD_BRIGHTNESS_BITS 3
137#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) 137#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS)
@@ -198,6 +198,7 @@ struct toshiba_acpi_dev {
198 unsigned int panel_power_on_supported:1; 198 unsigned int panel_power_on_supported:1;
199 unsigned int usb_three_supported:1; 199 unsigned int usb_three_supported:1;
200 unsigned int sysfs_created:1; 200 unsigned int sysfs_created:1;
201 unsigned int special_functions;
201 202
202 bool kbd_led_registered; 203 bool kbd_led_registered;
203 bool illumination_led_registered; 204 bool illumination_led_registered;
@@ -1668,10 +1669,10 @@ static ssize_t available_kbd_modes_show(struct device *dev,
1668 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); 1669 struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev);
1669 1670
1670 if (toshiba->kbd_type == 1) 1671 if (toshiba->kbd_type == 1)
1671 return sprintf(buf, "%x %x\n", 1672 return sprintf(buf, "0x%x 0x%x\n",
1672 SCI_KBD_MODE_FNZ, SCI_KBD_MODE_AUTO); 1673 SCI_KBD_MODE_FNZ, SCI_KBD_MODE_AUTO);
1673 1674
1674 return sprintf(buf, "%x %x %x\n", 1675 return sprintf(buf, "0x%x 0x%x 0x%x\n",
1675 SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF); 1676 SCI_KBD_MODE_AUTO, SCI_KBD_MODE_ON, SCI_KBD_MODE_OFF);
1676} 1677}
1677static DEVICE_ATTR_RO(available_kbd_modes); 1678static DEVICE_ATTR_RO(available_kbd_modes);
@@ -2253,7 +2254,16 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev)
2253 if (ACPI_FAILURE(status)) 2254 if (ACPI_FAILURE(status))
2254 return -ENODEV; 2255 return -ENODEV;
2255 2256
2256 result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE); 2257 /*
2258 * Enable the "Special Functions" mode only if they are
2259 * supported and if they are activated.
2260 */
2261 if (dev->kbd_function_keys_supported && dev->special_functions)
2262 result = hci_write(dev, HCI_HOTKEY_EVENT,
2263 HCI_HOTKEY_SPECIAL_FUNCTIONS);
2264 else
2265 result = hci_write(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE);
2266
2257 if (result == TOS_FAILURE) 2267 if (result == TOS_FAILURE)
2258 return -EIO; 2268 return -EIO;
2259 else if (result == TOS_NOT_SUPPORTED) 2269 else if (result == TOS_NOT_SUPPORTED)
@@ -2262,20 +2272,6 @@ static int toshiba_acpi_enable_hotkeys(struct toshiba_acpi_dev *dev)
2262 return 0; 2272 return 0;
2263} 2273}
2264 2274
2265static void toshiba_acpi_enable_special_functions(struct toshiba_acpi_dev *dev)
2266{
2267 u32 result;
2268
2269 /*
2270 * Re-activate the hotkeys, but this time, we are using the
2271 * "Special Functions" mode.
2272 */
2273 result = hci_write(dev, HCI_HOTKEY_EVENT,
2274 HCI_HOTKEY_SPECIAL_FUNCTIONS);
2275 if (result != TOS_SUCCESS)
2276 pr_err("Could not enable the Special Function mode\n");
2277}
2278
2279static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, 2275static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
2280 struct serio *port) 2276 struct serio *port)
2281{ 2277{
@@ -2385,8 +2381,6 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
2385{ 2381{
2386 const struct key_entry *keymap = toshiba_acpi_keymap; 2382 const struct key_entry *keymap = toshiba_acpi_keymap;
2387 acpi_handle ec_handle; 2383 acpi_handle ec_handle;
2388 u32 events_type;
2389 u32 hci_result;
2390 int error; 2384 int error;
2391 2385
2392 if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) { 2386 if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) {
@@ -2398,11 +2392,9 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
2398 if (error) 2392 if (error)
2399 return error; 2393 return error;
2400 2394
2401 if (toshiba_hotkey_event_type_get(dev, &events_type)) 2395 if (toshiba_hotkey_event_type_get(dev, &dev->hotkey_event_type))
2402 pr_notice("Unable to query Hotkey Event Type\n"); 2396 pr_notice("Unable to query Hotkey Event Type\n");
2403 2397
2404 dev->hotkey_event_type = events_type;
2405
2406 dev->hotkey_dev = input_allocate_device(); 2398 dev->hotkey_dev = input_allocate_device();
2407 if (!dev->hotkey_dev) 2399 if (!dev->hotkey_dev)
2408 return -ENOMEM; 2400 return -ENOMEM;
@@ -2411,14 +2403,15 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
2411 dev->hotkey_dev->phys = "toshiba_acpi/input0"; 2403 dev->hotkey_dev->phys = "toshiba_acpi/input0";
2412 dev->hotkey_dev->id.bustype = BUS_HOST; 2404 dev->hotkey_dev->id.bustype = BUS_HOST;
2413 2405
2414 if (events_type == HCI_SYSTEM_TYPE1 || 2406 if (dev->hotkey_event_type == HCI_SYSTEM_TYPE1 ||
2415 !dev->kbd_function_keys_supported) 2407 !dev->kbd_function_keys_supported)
2416 keymap = toshiba_acpi_keymap; 2408 keymap = toshiba_acpi_keymap;
2417 else if (events_type == HCI_SYSTEM_TYPE2 || 2409 else if (dev->hotkey_event_type == HCI_SYSTEM_TYPE2 ||
2418 dev->kbd_function_keys_supported) 2410 dev->kbd_function_keys_supported)
2419 keymap = toshiba_acpi_alt_keymap; 2411 keymap = toshiba_acpi_alt_keymap;
2420 else 2412 else
2421 pr_info("Unknown event type received %x\n", events_type); 2413 pr_info("Unknown event type received %x\n",
2414 dev->hotkey_event_type);
2422 error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL); 2415 error = sparse_keymap_setup(dev->hotkey_dev, keymap, NULL);
2423 if (error) 2416 if (error)
2424 goto err_free_dev; 2417 goto err_free_dev;
@@ -2449,11 +2442,8 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
2449 */ 2442 */
2450 if (acpi_has_method(dev->acpi_dev->handle, "INFO")) 2443 if (acpi_has_method(dev->acpi_dev->handle, "INFO"))
2451 dev->info_supported = 1; 2444 dev->info_supported = 1;
2452 else { 2445 else if (hci_write(dev, HCI_SYSTEM_EVENT, 1) == TOS_SUCCESS)
2453 hci_result = hci_write(dev, HCI_SYSTEM_EVENT, 1); 2446 dev->system_event_supported = 1;
2454 if (hci_result == TOS_SUCCESS)
2455 dev->system_event_supported = 1;
2456 }
2457 2447
2458 if (!dev->info_supported && !dev->system_event_supported) { 2448 if (!dev->info_supported && !dev->system_event_supported) {
2459 pr_warn("No hotkey query interface found\n"); 2449 pr_warn("No hotkey query interface found\n");
@@ -2631,7 +2621,6 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
2631{ 2621{
2632 struct toshiba_acpi_dev *dev; 2622 struct toshiba_acpi_dev *dev;
2633 const char *hci_method; 2623 const char *hci_method;
2634 u32 special_functions;
2635 u32 dummy; 2624 u32 dummy;
2636 int ret = 0; 2625 int ret = 0;
2637 2626
@@ -2673,9 +2662,10 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
2673 * with the new keyboard layout, query for its presence to help 2662 * with the new keyboard layout, query for its presence to help
2674 * determine the keymap layout to use. 2663 * determine the keymap layout to use.
2675 */ 2664 */
2676 ret = toshiba_function_keys_get(dev, &special_functions); 2665 ret = toshiba_function_keys_get(dev, &dev->special_functions);
2677 dev->kbd_function_keys_supported = !ret; 2666 dev->kbd_function_keys_supported = !ret;
2678 2667
2668 dev->hotkey_event_type = 0;
2679 if (toshiba_acpi_setup_keyboard(dev)) 2669 if (toshiba_acpi_setup_keyboard(dev))
2680 pr_info("Unable to activate hotkeys\n"); 2670 pr_info("Unable to activate hotkeys\n");
2681 2671
@@ -2748,13 +2738,6 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
2748 2738
2749 print_supported_features(dev); 2739 print_supported_features(dev);
2750 2740
2751 /*
2752 * Enable the "Special Functions" mode only if they are
2753 * supported and if they are activated.
2754 */
2755 if (dev->kbd_function_keys_supported && special_functions)
2756 toshiba_acpi_enable_special_functions(dev);
2757
2758 ret = sysfs_create_group(&dev->acpi_dev->dev.kobj, 2741 ret = sysfs_create_group(&dev->acpi_dev->dev.kobj,
2759 &toshiba_attr_group); 2742 &toshiba_attr_group);
2760 if (ret) { 2743 if (ret) {