aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-07-29 20:09:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-29 20:09:39 -0400
commit73bcc49959e4e40911dd0dd634bf1b353827df66 (patch)
tree6b0c1d440c490a65c51ab5cf5aee7095cb4089d3 /drivers/platform
parent8447c4d15e357a458c9051ddc84aa6c8b9c27000 (diff)
parent28a33cbc24e4256c143dce96c7d93bf423229f92 (diff)
Merge tag 'v3.5'
Linux 3.5 * tag 'v3.5': (1242 commits) Linux 3.5 Remove SYSTEM_SUSPEND_DISK system state kdb: Switch to nolock variants of kmsg_dump functions printk: Implement some unlocked kmsg_dump functions printk: Remove kdb_syslog_data kdb: Revive dmesg command dm raid1: set discard_zeroes_data_unsupported dm thin: do not send discards to shared blocks dm raid1: fix crash with mirror recovery and discard pnfs-obj: Fix __r4w_get_page when offset is beyond i_size pnfs-obj: don't leak objio_state if ore_write/read fails ore: Unlock r4w pages in exact reverse order of locking ore: Remove support of partial IO request (NFS crash) ore: Fix NFS crash by supporting any unaligned RAID IO UBIFS: fix a bug in empty space fix-up cx25821: Remove bad strcpy to read-only char* HID: hid-multitouch: add support for Zytronic panels MIPS: PCI: Move fixups from __init to __devinit. MIPS: Fix bug.h MIPS build regression MIPS: sync-r4k: remove redundant irq operation ...
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/ideapad-laptop.c6
-rw-r--r--drivers/platform/x86/intel_ips.c22
-rw-r--r--drivers/platform/x86/sony-laptop.c136
3 files changed, 114 insertions, 50 deletions
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 4f20f8dd3d7c..17f6dfd8dbfb 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -694,10 +694,10 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
694static int __devinit ideapad_acpi_add(struct acpi_device *adevice) 694static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
695{ 695{
696 int ret, i; 696 int ret, i;
697 unsigned long cfg; 697 int cfg;
698 struct ideapad_private *priv; 698 struct ideapad_private *priv;
699 699
700 if (read_method_int(adevice->handle, "_CFG", (int *)&cfg)) 700 if (read_method_int(adevice->handle, "_CFG", &cfg))
701 return -ENODEV; 701 return -ENODEV;
702 702
703 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 703 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -721,7 +721,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
721 goto input_failed; 721 goto input_failed;
722 722
723 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { 723 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) {
724 if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg)) 724 if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
725 ideapad_register_rfkill(adevice, i); 725 ideapad_register_rfkill(adevice, i);
726 else 726 else
727 priv->rfk[i] = NULL; 727 priv->rfk[i] = NULL;
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 0ffdb3cde2bb..9af4257d4901 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -72,6 +72,7 @@
72#include <linux/string.h> 72#include <linux/string.h>
73#include <linux/tick.h> 73#include <linux/tick.h>
74#include <linux/timer.h> 74#include <linux/timer.h>
75#include <linux/dmi.h>
75#include <drm/i915_drm.h> 76#include <drm/i915_drm.h>
76#include <asm/msr.h> 77#include <asm/msr.h>
77#include <asm/processor.h> 78#include <asm/processor.h>
@@ -1485,6 +1486,24 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = {
1485 1486
1486MODULE_DEVICE_TABLE(pci, ips_id_table); 1487MODULE_DEVICE_TABLE(pci, ips_id_table);
1487 1488
1489static int ips_blacklist_callback(const struct dmi_system_id *id)
1490{
1491 pr_info("Blacklisted intel_ips for %s\n", id->ident);
1492 return 1;
1493}
1494
1495static const struct dmi_system_id ips_blacklist[] = {
1496 {
1497 .callback = ips_blacklist_callback,
1498 .ident = "HP ProBook",
1499 .matches = {
1500 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1501 DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"),
1502 },
1503 },
1504 { } /* terminating entry */
1505};
1506
1488static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) 1507static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
1489{ 1508{
1490 u64 platform_info; 1509 u64 platform_info;
@@ -1494,6 +1513,9 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
1494 u16 htshi, trc, trc_required_mask; 1513 u16 htshi, trc, trc_required_mask;
1495 u8 tse; 1514 u8 tse;
1496 1515
1516 if (dmi_check_system(ips_blacklist))
1517 return -ENODEV;
1518
1497 ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); 1519 ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL);
1498 if (!ips) 1520 if (!ips)
1499 return -ENOMEM; 1521 return -ENOMEM;
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 210d4ae547c2..d456ff0c73b7 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -973,7 +973,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
973 struct device_attribute *attr, 973 struct device_attribute *attr,
974 const char *buffer, size_t count) 974 const char *buffer, size_t count)
975{ 975{
976 unsigned long value = 0; 976 int value;
977 int ret = 0; 977 int ret = 0;
978 struct sony_nc_value *item = 978 struct sony_nc_value *item =
979 container_of(attr, struct sony_nc_value, devattr); 979 container_of(attr, struct sony_nc_value, devattr);
@@ -984,7 +984,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
984 if (count > 31) 984 if (count > 31)
985 return -EINVAL; 985 return -EINVAL;
986 986
987 if (kstrtoul(buffer, 10, &value)) 987 if (kstrtoint(buffer, 10, &value))
988 return -EINVAL; 988 return -EINVAL;
989 989
990 if (item->validate) 990 if (item->validate)
@@ -994,7 +994,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
994 return value; 994 return value;
995 995
996 ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, 996 ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset,
997 (int *)&value, NULL); 997 &value, NULL);
998 if (ret < 0) 998 if (ret < 0)
999 return -EIO; 999 return -EIO;
1000 1000
@@ -1010,6 +1010,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev,
1010struct sony_backlight_props { 1010struct sony_backlight_props {
1011 struct backlight_device *dev; 1011 struct backlight_device *dev;
1012 int handle; 1012 int handle;
1013 int cmd_base;
1013 u8 offset; 1014 u8 offset;
1014 u8 maxlvl; 1015 u8 maxlvl;
1015}; 1016};
@@ -1037,7 +1038,7 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd)
1037 struct sony_backlight_props *sdev = 1038 struct sony_backlight_props *sdev =
1038 (struct sony_backlight_props *)bl_get_data(bd); 1039 (struct sony_backlight_props *)bl_get_data(bd);
1039 1040
1040 sony_call_snc_handle(sdev->handle, 0x0200, &result); 1041 sony_call_snc_handle(sdev->handle, sdev->cmd_base + 0x100, &result);
1041 1042
1042 return (result & 0xff) - sdev->offset; 1043 return (result & 0xff) - sdev->offset;
1043} 1044}
@@ -1049,7 +1050,8 @@ static int sony_nc_update_status_ng(struct backlight_device *bd)
1049 (struct sony_backlight_props *)bl_get_data(bd); 1050 (struct sony_backlight_props *)bl_get_data(bd);
1050 1051
1051 value = bd->props.brightness + sdev->offset; 1052 value = bd->props.brightness + sdev->offset;
1052 if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) 1053 if (sony_call_snc_handle(sdev->handle, sdev->cmd_base | (value << 0x10),
1054 &result))
1053 return -EIO; 1055 return -EIO;
1054 1056
1055 return value; 1057 return value;
@@ -1172,6 +1174,11 @@ static int sony_nc_hotkeys_decode(u32 event, unsigned int handle)
1172/* 1174/*
1173 * ACPI callbacks 1175 * ACPI callbacks
1174 */ 1176 */
1177enum event_types {
1178 HOTKEY = 1,
1179 KILLSWITCH,
1180 GFX_SWITCH
1181};
1175static void sony_nc_notify(struct acpi_device *device, u32 event) 1182static void sony_nc_notify(struct acpi_device *device, u32 event)
1176{ 1183{
1177 u32 real_ev = event; 1184 u32 real_ev = event;
@@ -1196,7 +1203,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1196 /* hotkey event */ 1203 /* hotkey event */
1197 case 0x0100: 1204 case 0x0100:
1198 case 0x0127: 1205 case 0x0127:
1199 ev_type = 1; 1206 ev_type = HOTKEY;
1200 real_ev = sony_nc_hotkeys_decode(event, handle); 1207 real_ev = sony_nc_hotkeys_decode(event, handle);
1201 1208
1202 if (real_ev > 0) 1209 if (real_ev > 0)
@@ -1216,7 +1223,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1216 * update the rfkill device status when the 1223 * update the rfkill device status when the
1217 * switch is moved. 1224 * switch is moved.
1218 */ 1225 */
1219 ev_type = 2; 1226 ev_type = KILLSWITCH;
1220 sony_call_snc_handle(handle, 0x0100, &result); 1227 sony_call_snc_handle(handle, 0x0100, &result);
1221 real_ev = result & 0x03; 1228 real_ev = result & 0x03;
1222 1229
@@ -1226,6 +1233,24 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1226 1233
1227 break; 1234 break;
1228 1235
1236 case 0x0128:
1237 case 0x0146:
1238 /* Hybrid GFX switching */
1239 sony_call_snc_handle(handle, 0x0000, &result);
1240 dprintk("GFX switch event received (reason: %s)\n",
1241 (result & 0x01) ?
1242 "switch change" : "unknown");
1243
1244 /* verify the switch state
1245 * 1: discrete GFX
1246 * 0: integrated GFX
1247 */
1248 sony_call_snc_handle(handle, 0x0100, &result);
1249
1250 ev_type = GFX_SWITCH;
1251 real_ev = result & 0xff;
1252 break;
1253
1229 default: 1254 default:
1230 dprintk("Unknown event 0x%x for handle 0x%x\n", 1255 dprintk("Unknown event 0x%x for handle 0x%x\n",
1231 event, handle); 1256 event, handle);
@@ -1238,7 +1263,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
1238 1263
1239 } else { 1264 } else {
1240 /* old style event */ 1265 /* old style event */
1241 ev_type = 1; 1266 ev_type = HOTKEY;
1242 sony_laptop_report_input_event(real_ev); 1267 sony_laptop_report_input_event(real_ev);
1243 } 1268 }
1244 1269
@@ -1893,32 +1918,33 @@ static ssize_t sony_nc_battery_care_limit_store(struct device *dev,
1893 * bits 4,5: store the limit into the EC 1918 * bits 4,5: store the limit into the EC
1894 * bits 6,7: store the limit into the battery 1919 * bits 6,7: store the limit into the battery
1895 */ 1920 */
1921 cmd = 0;
1896 1922
1897 /* 1923 if (value > 0) {
1898 * handle 0x0115 should allow storing on battery too; 1924 if (value <= 50)
1899 * handle 0x0136 same as 0x0115 + health status; 1925 cmd = 0x20;
1900 * handle 0x013f, same as 0x0136 but no storing on the battery
1901 *
1902 * Store only inside the EC for now, regardless the handle number
1903 */
1904 if (value == 0)
1905 /* disable limits */
1906 cmd = 0x0;
1907 1926
1908 else if (value <= 50) 1927 else if (value <= 80)
1909 cmd = 0x21; 1928 cmd = 0x10;
1910 1929
1911 else if (value <= 80) 1930 else if (value <= 100)
1912 cmd = 0x11; 1931 cmd = 0x30;
1913 1932
1914 else if (value <= 100) 1933 else
1915 cmd = 0x31; 1934 return -EINVAL;
1916 1935
1917 else 1936 /*
1918 return -EINVAL; 1937 * handle 0x0115 should allow storing on battery too;
1938 * handle 0x0136 same as 0x0115 + health status;
1939 * handle 0x013f, same as 0x0136 but no storing on the battery
1940 */
1941 if (bcare_ctl->handle != 0x013f)
1942 cmd = cmd | (cmd << 2);
1919 1943
1920 if (sony_call_snc_handle(bcare_ctl->handle, (cmd << 0x10) | 0x0100, 1944 cmd = (cmd | 0x1) << 0x10;
1921 &result)) 1945 }
1946
1947 if (sony_call_snc_handle(bcare_ctl->handle, cmd | 0x0100, &result))
1922 return -EIO; 1948 return -EIO;
1923 1949
1924 return count; 1950 return count;
@@ -2113,7 +2139,7 @@ static ssize_t sony_nc_thermal_mode_show(struct device *dev,
2113 struct device_attribute *attr, char *buffer) 2139 struct device_attribute *attr, char *buffer)
2114{ 2140{
2115 ssize_t count = 0; 2141 ssize_t count = 0;
2116 unsigned int mode = sony_nc_thermal_mode_get(); 2142 int mode = sony_nc_thermal_mode_get();
2117 2143
2118 if (mode < 0) 2144 if (mode < 0)
2119 return mode; 2145 return mode;
@@ -2472,6 +2498,7 @@ static void sony_nc_backlight_ng_read_limits(int handle,
2472{ 2498{
2473 u64 offset; 2499 u64 offset;
2474 int i; 2500 int i;
2501 int lvl_table_len = 0;
2475 u8 min = 0xff, max = 0x00; 2502 u8 min = 0xff, max = 0x00;
2476 unsigned char buffer[32] = { 0 }; 2503 unsigned char buffer[32] = { 0 };
2477 2504
@@ -2480,8 +2507,6 @@ static void sony_nc_backlight_ng_read_limits(int handle,
2480 props->maxlvl = 0xff; 2507 props->maxlvl = 0xff;
2481 2508
2482 offset = sony_find_snc_handle(handle); 2509 offset = sony_find_snc_handle(handle);
2483 if (offset < 0)
2484 return;
2485 2510
2486 /* try to read the boundaries from ACPI tables, if we fail the above 2511 /* try to read the boundaries from ACPI tables, if we fail the above
2487 * defaults should be reasonable 2512 * defaults should be reasonable
@@ -2491,11 +2516,21 @@ static void sony_nc_backlight_ng_read_limits(int handle,
2491 if (i < 0) 2516 if (i < 0)
2492 return; 2517 return;
2493 2518
2519 switch (handle) {
2520 case 0x012f:
2521 case 0x0137:
2522 lvl_table_len = 9;
2523 break;
2524 case 0x143:
2525 lvl_table_len = 16;
2526 break;
2527 }
2528
2494 /* the buffer lists brightness levels available, brightness levels are 2529 /* the buffer lists brightness levels available, brightness levels are
2495 * from position 0 to 8 in the array, other values are used by ALS 2530 * from position 0 to 8 in the array, other values are used by ALS
2496 * control. 2531 * control.
2497 */ 2532 */
2498 for (i = 0; i < 9 && i < ARRAY_SIZE(buffer); i++) { 2533 for (i = 0; i < lvl_table_len && i < ARRAY_SIZE(buffer); i++) {
2499 2534
2500 dprintk("Brightness level: %d\n", buffer[i]); 2535 dprintk("Brightness level: %d\n", buffer[i]);
2501 2536
@@ -2520,16 +2555,24 @@ static void sony_nc_backlight_setup(void)
2520 const struct backlight_ops *ops = NULL; 2555 const struct backlight_ops *ops = NULL;
2521 struct backlight_properties props; 2556 struct backlight_properties props;
2522 2557
2523 if (sony_find_snc_handle(0x12f) != -1) { 2558 if (sony_find_snc_handle(0x12f) >= 0) {
2524 ops = &sony_backlight_ng_ops; 2559 ops = &sony_backlight_ng_ops;
2560 sony_bl_props.cmd_base = 0x0100;
2525 sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); 2561 sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props);
2526 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 2562 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
2527 2563
2528 } else if (sony_find_snc_handle(0x137) != -1) { 2564 } else if (sony_find_snc_handle(0x137) >= 0) {
2529 ops = &sony_backlight_ng_ops; 2565 ops = &sony_backlight_ng_ops;
2566 sony_bl_props.cmd_base = 0x0100;
2530 sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); 2567 sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props);
2531 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; 2568 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
2532 2569
2570 } else if (sony_find_snc_handle(0x143) >= 0) {
2571 ops = &sony_backlight_ng_ops;
2572 sony_bl_props.cmd_base = 0x3000;
2573 sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props);
2574 max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset;
2575
2533 } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", 2576 } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
2534 &unused))) { 2577 &unused))) {
2535 ops = &sony_backlight_ops; 2578 ops = &sony_backlight_ops;
@@ -2597,6 +2640,12 @@ static int sony_nc_add(struct acpi_device *device)
2597 } 2640 }
2598 } 2641 }
2599 2642
2643 result = sony_laptop_setup_input(device);
2644 if (result) {
2645 pr_err("Unable to create input devices\n");
2646 goto outplatform;
2647 }
2648
2600 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", 2649 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
2601 &handle))) { 2650 &handle))) {
2602 int arg = 1; 2651 int arg = 1;
@@ -2614,12 +2663,6 @@ static int sony_nc_add(struct acpi_device *device)
2614 } 2663 }
2615 2664
2616 /* setup input devices and helper fifo */ 2665 /* setup input devices and helper fifo */
2617 result = sony_laptop_setup_input(device);
2618 if (result) {
2619 pr_err("Unable to create input devices\n");
2620 goto outsnc;
2621 }
2622
2623 if (acpi_video_backlight_support()) { 2666 if (acpi_video_backlight_support()) {
2624 pr_info("brightness ignored, must be controlled by ACPI video driver\n"); 2667 pr_info("brightness ignored, must be controlled by ACPI video driver\n");
2625 } else { 2668 } else {
@@ -2667,22 +2710,21 @@ static int sony_nc_add(struct acpi_device *device)
2667 2710
2668 return 0; 2711 return 0;
2669 2712
2670 out_sysfs: 2713out_sysfs:
2671 for (item = sony_nc_values; item->name; ++item) { 2714 for (item = sony_nc_values; item->name; ++item) {
2672 device_remove_file(&sony_pf_device->dev, &item->devattr); 2715 device_remove_file(&sony_pf_device->dev, &item->devattr);
2673 } 2716 }
2674 sony_nc_backlight_cleanup(); 2717 sony_nc_backlight_cleanup();
2675
2676 sony_laptop_remove_input();
2677
2678 outsnc:
2679 sony_nc_function_cleanup(sony_pf_device); 2718 sony_nc_function_cleanup(sony_pf_device);
2680 sony_nc_handles_cleanup(sony_pf_device); 2719 sony_nc_handles_cleanup(sony_pf_device);
2681 2720
2682 outpresent: 2721outplatform:
2722 sony_laptop_remove_input();
2723
2724outpresent:
2683 sony_pf_remove(); 2725 sony_pf_remove();
2684 2726
2685 outwalk: 2727outwalk:
2686 sony_nc_rfkill_cleanup(); 2728 sony_nc_rfkill_cleanup();
2687 return result; 2729 return result;
2688} 2730}