diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-platform-asus-wmi | 7 | ||||
-rw-r--r-- | drivers/acpi/video_detect.c | 60 | ||||
-rw-r--r-- | drivers/platform/x86/acer-wmi.c | 153 | ||||
-rw-r--r-- | drivers/platform/x86/apple-gmux.c | 6 | ||||
-rw-r--r-- | drivers/platform/x86/asus-nb-wmi.c | 108 | ||||
-rw-r--r-- | drivers/platform/x86/asus-wmi.c | 23 | ||||
-rw-r--r-- | drivers/platform/x86/asus-wmi.h | 1 | ||||
-rw-r--r-- | drivers/platform/x86/classmate-laptop.c | 405 | ||||
-rw-r--r-- | drivers/platform/x86/dell-laptop.c | 54 | ||||
-rw-r--r-- | drivers/platform/x86/eeepc-wmi.c | 25 | ||||
-rw-r--r-- | drivers/platform/x86/samsung-laptop.c | 41 | ||||
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 5 | ||||
-rw-r--r-- | include/linux/acpi.h | 10 |
13 files changed, 864 insertions, 34 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi index 2e7df91620de..019e1e29370e 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi | |||
@@ -29,3 +29,10 @@ KernelVersion: 2.6.39 | |||
29 | Contact: "Corentin Chary" <corentincj@iksaif.net> | 29 | Contact: "Corentin Chary" <corentincj@iksaif.net> |
30 | Description: | 30 | Description: |
31 | Control the card touchpad. 1 means on, 0 means off. | 31 | Control the card touchpad. 1 means on, 0 means off. |
32 | |||
33 | What: /sys/devices/platform/<platform>/lid_resume | ||
34 | Date: May 2012 | ||
35 | KernelVersion: 3.5 | ||
36 | Contact: "AceLan Kao" <acelan.kao@canonical.com> | ||
37 | Description: | ||
38 | Resume on lid open. 1 means on, 0 means off. | ||
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 45d8097ef4cf..b728880ef10e 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -132,6 +132,33 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
132 | return AE_OK; | 132 | return AE_OK; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* Force to use vendor driver when the ACPI device is known to be | ||
136 | * buggy */ | ||
137 | static int video_detect_force_vendor(const struct dmi_system_id *d) | ||
138 | { | ||
139 | acpi_video_support |= ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static struct dmi_system_id video_detect_dmi_table[] = { | ||
144 | /* On Samsung X360, the BIOS will set a flag (VDRV) if generic | ||
145 | * ACPI backlight device is used. This flag will definitively break | ||
146 | * the backlight interface (even the vendor interface) untill next | ||
147 | * reboot. It's why we should prevent video.ko from being used here | ||
148 | * and we can't rely on a later call to acpi_video_unregister(). | ||
149 | */ | ||
150 | { | ||
151 | .callback = video_detect_force_vendor, | ||
152 | .ident = "X360", | ||
153 | .matches = { | ||
154 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
155 | DMI_MATCH(DMI_PRODUCT_NAME, "X360"), | ||
156 | DMI_MATCH(DMI_BOARD_NAME, "X360"), | ||
157 | }, | ||
158 | }, | ||
159 | { }, | ||
160 | }; | ||
161 | |||
135 | /* | 162 | /* |
136 | * Returns the video capabilities of a specific ACPI graphics device | 163 | * Returns the video capabilities of a specific ACPI graphics device |
137 | * | 164 | * |
@@ -164,6 +191,8 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle) | |||
164 | * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | 191 | * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; |
165 | *} | 192 | *} |
166 | */ | 193 | */ |
194 | |||
195 | dmi_check_system(video_detect_dmi_table); | ||
167 | } else { | 196 | } else { |
168 | status = acpi_bus_get_device(graphics_handle, &tmp_dev); | 197 | status = acpi_bus_get_device(graphics_handle, &tmp_dev); |
169 | if (ACPI_FAILURE(status)) { | 198 | if (ACPI_FAILURE(status)) { |
@@ -182,8 +211,7 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle) | |||
182 | } | 211 | } |
183 | EXPORT_SYMBOL(acpi_video_get_capabilities); | 212 | EXPORT_SYMBOL(acpi_video_get_capabilities); |
184 | 213 | ||
185 | /* Returns true if video.ko can do backlight switching */ | 214 | static void acpi_video_caps_check(void) |
186 | int acpi_video_backlight_support(void) | ||
187 | { | 215 | { |
188 | /* | 216 | /* |
189 | * We must check whether the ACPI graphics device is physically plugged | 217 | * We must check whether the ACPI graphics device is physically plugged |
@@ -191,6 +219,34 @@ int acpi_video_backlight_support(void) | |||
191 | */ | 219 | */ |
192 | if (!acpi_video_caps_checked) | 220 | if (!acpi_video_caps_checked) |
193 | acpi_video_get_capabilities(NULL); | 221 | acpi_video_get_capabilities(NULL); |
222 | } | ||
223 | |||
224 | /* Promote the vendor interface instead of the generic video module. | ||
225 | * This function allow DMI blacklists to be implemented by externals | ||
226 | * platform drivers instead of putting a big blacklist in video_detect.c | ||
227 | * After calling this function you will probably want to call | ||
228 | * acpi_video_unregister() to make sure the video module is not loaded | ||
229 | */ | ||
230 | void acpi_video_dmi_promote_vendor(void) | ||
231 | { | ||
232 | acpi_video_caps_check(); | ||
233 | acpi_video_support |= ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | ||
234 | } | ||
235 | EXPORT_SYMBOL(acpi_video_dmi_promote_vendor); | ||
236 | |||
237 | /* To be called when a driver who previously promoted the vendor | ||
238 | * interface */ | ||
239 | void acpi_video_dmi_demote_vendor(void) | ||
240 | { | ||
241 | acpi_video_caps_check(); | ||
242 | acpi_video_support &= ~ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | ||
243 | } | ||
244 | EXPORT_SYMBOL(acpi_video_dmi_demote_vendor); | ||
245 | |||
246 | /* Returns true if video.ko can do backlight switching */ | ||
247 | int acpi_video_backlight_support(void) | ||
248 | { | ||
249 | acpi_video_caps_check(); | ||
194 | 250 | ||
195 | /* First check for boot param -> highest prio */ | 251 | /* First check for boot param -> highest prio */ |
196 | if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR) | 252 | if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR) |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c8f40c9c0428..3782e1cd3697 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -95,6 +95,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); | |||
95 | 95 | ||
96 | enum acer_wmi_event_ids { | 96 | enum acer_wmi_event_ids { |
97 | WMID_HOTKEY_EVENT = 0x1, | 97 | WMID_HOTKEY_EVENT = 0x1, |
98 | WMID_ACCEL_EVENT = 0x5, | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | static const struct key_entry acer_wmi_keymap[] = { | 101 | static const struct key_entry acer_wmi_keymap[] = { |
@@ -130,6 +131,7 @@ static const struct key_entry acer_wmi_keymap[] = { | |||
130 | }; | 131 | }; |
131 | 132 | ||
132 | static struct input_dev *acer_wmi_input_dev; | 133 | static struct input_dev *acer_wmi_input_dev; |
134 | static struct input_dev *acer_wmi_accel_dev; | ||
133 | 135 | ||
134 | struct event_return_value { | 136 | struct event_return_value { |
135 | u8 function; | 137 | u8 function; |
@@ -200,6 +202,7 @@ struct hotkey_function_type_aa { | |||
200 | #define ACER_CAP_BLUETOOTH (1<<2) | 202 | #define ACER_CAP_BLUETOOTH (1<<2) |
201 | #define ACER_CAP_BRIGHTNESS (1<<3) | 203 | #define ACER_CAP_BRIGHTNESS (1<<3) |
202 | #define ACER_CAP_THREEG (1<<4) | 204 | #define ACER_CAP_THREEG (1<<4) |
205 | #define ACER_CAP_ACCEL (1<<5) | ||
203 | #define ACER_CAP_ANY (0xFFFFFFFF) | 206 | #define ACER_CAP_ANY (0xFFFFFFFF) |
204 | 207 | ||
205 | /* | 208 | /* |
@@ -1399,6 +1402,60 @@ static void acer_backlight_exit(void) | |||
1399 | } | 1402 | } |
1400 | 1403 | ||
1401 | /* | 1404 | /* |
1405 | * Accelerometer device | ||
1406 | */ | ||
1407 | static acpi_handle gsensor_handle; | ||
1408 | |||
1409 | static int acer_gsensor_init(void) | ||
1410 | { | ||
1411 | acpi_status status; | ||
1412 | struct acpi_buffer output; | ||
1413 | union acpi_object out_obj; | ||
1414 | |||
1415 | output.length = sizeof(out_obj); | ||
1416 | output.pointer = &out_obj; | ||
1417 | status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output); | ||
1418 | if (ACPI_FAILURE(status)) | ||
1419 | return -1; | ||
1420 | |||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | static int acer_gsensor_open(struct input_dev *input) | ||
1425 | { | ||
1426 | return acer_gsensor_init(); | ||
1427 | } | ||
1428 | |||
1429 | static int acer_gsensor_event(void) | ||
1430 | { | ||
1431 | acpi_status status; | ||
1432 | struct acpi_buffer output; | ||
1433 | union acpi_object out_obj[5]; | ||
1434 | |||
1435 | if (!has_cap(ACER_CAP_ACCEL)) | ||
1436 | return -1; | ||
1437 | |||
1438 | output.length = sizeof(out_obj); | ||
1439 | output.pointer = out_obj; | ||
1440 | |||
1441 | status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output); | ||
1442 | if (ACPI_FAILURE(status)) | ||
1443 | return -1; | ||
1444 | |||
1445 | if (out_obj->package.count != 4) | ||
1446 | return -1; | ||
1447 | |||
1448 | input_report_abs(acer_wmi_accel_dev, ABS_X, | ||
1449 | (s16)out_obj->package.elements[0].integer.value); | ||
1450 | input_report_abs(acer_wmi_accel_dev, ABS_Y, | ||
1451 | (s16)out_obj->package.elements[1].integer.value); | ||
1452 | input_report_abs(acer_wmi_accel_dev, ABS_Z, | ||
1453 | (s16)out_obj->package.elements[2].integer.value); | ||
1454 | input_sync(acer_wmi_accel_dev); | ||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | /* | ||
1402 | * Rfkill devices | 1459 | * Rfkill devices |
1403 | */ | 1460 | */ |
1404 | static void acer_rfkill_update(struct work_struct *ignored); | 1461 | static void acer_rfkill_update(struct work_struct *ignored); |
@@ -1673,6 +1730,9 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1673 | 1, true); | 1730 | 1, true); |
1674 | } | 1731 | } |
1675 | break; | 1732 | break; |
1733 | case WMID_ACCEL_EVENT: | ||
1734 | acer_gsensor_event(); | ||
1735 | break; | ||
1676 | default: | 1736 | default: |
1677 | pr_warn("Unknown function number - %d - %d\n", | 1737 | pr_warn("Unknown function number - %d - %d\n", |
1678 | return_value.function, return_value.key_num); | 1738 | return_value.function, return_value.key_num); |
@@ -1758,6 +1818,73 @@ static int acer_wmi_enable_lm(void) | |||
1758 | return status; | 1818 | return status; |
1759 | } | 1819 | } |
1760 | 1820 | ||
1821 | static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level, | ||
1822 | void *ctx, void **retval) | ||
1823 | { | ||
1824 | *(acpi_handle *)retval = ah; | ||
1825 | return AE_OK; | ||
1826 | } | ||
1827 | |||
1828 | static int __init acer_wmi_get_handle(const char *name, const char *prop, | ||
1829 | acpi_handle *ah) | ||
1830 | { | ||
1831 | acpi_status status; | ||
1832 | acpi_handle handle; | ||
1833 | |||
1834 | BUG_ON(!name || !ah); | ||
1835 | |||
1836 | handle = NULL; | ||
1837 | status = acpi_get_devices(prop, acer_wmi_get_handle_cb, | ||
1838 | (void *)name, &handle); | ||
1839 | |||
1840 | if (ACPI_SUCCESS(status)) { | ||
1841 | *ah = handle; | ||
1842 | return 0; | ||
1843 | } else { | ||
1844 | return -ENODEV; | ||
1845 | } | ||
1846 | } | ||
1847 | |||
1848 | static int __init acer_wmi_accel_setup(void) | ||
1849 | { | ||
1850 | int err; | ||
1851 | |||
1852 | err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle); | ||
1853 | if (err) | ||
1854 | return err; | ||
1855 | |||
1856 | interface->capability |= ACER_CAP_ACCEL; | ||
1857 | |||
1858 | acer_wmi_accel_dev = input_allocate_device(); | ||
1859 | if (!acer_wmi_accel_dev) | ||
1860 | return -ENOMEM; | ||
1861 | |||
1862 | acer_wmi_accel_dev->open = acer_gsensor_open; | ||
1863 | |||
1864 | acer_wmi_accel_dev->name = "Acer BMA150 accelerometer"; | ||
1865 | acer_wmi_accel_dev->phys = "wmi/input1"; | ||
1866 | acer_wmi_accel_dev->id.bustype = BUS_HOST; | ||
1867 | acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS); | ||
1868 | input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0); | ||
1869 | input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0); | ||
1870 | input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0); | ||
1871 | |||
1872 | err = input_register_device(acer_wmi_accel_dev); | ||
1873 | if (err) | ||
1874 | goto err_free_dev; | ||
1875 | |||
1876 | return 0; | ||
1877 | |||
1878 | err_free_dev: | ||
1879 | input_free_device(acer_wmi_accel_dev); | ||
1880 | return err; | ||
1881 | } | ||
1882 | |||
1883 | static void acer_wmi_accel_destroy(void) | ||
1884 | { | ||
1885 | input_unregister_device(acer_wmi_accel_dev); | ||
1886 | } | ||
1887 | |||
1761 | static int __init acer_wmi_input_setup(void) | 1888 | static int __init acer_wmi_input_setup(void) |
1762 | { | 1889 | { |
1763 | acpi_status status; | 1890 | acpi_status status; |
@@ -1912,6 +2039,9 @@ static int acer_resume(struct device *dev) | |||
1912 | if (has_cap(ACER_CAP_BRIGHTNESS)) | 2039 | if (has_cap(ACER_CAP_BRIGHTNESS)) |
1913 | set_u32(data->brightness, ACER_CAP_BRIGHTNESS); | 2040 | set_u32(data->brightness, ACER_CAP_BRIGHTNESS); |
1914 | 2041 | ||
2042 | if (has_cap(ACER_CAP_ACCEL)) | ||
2043 | acer_gsensor_init(); | ||
2044 | |||
1915 | return 0; | 2045 | return 0; |
1916 | } | 2046 | } |
1917 | 2047 | ||
@@ -2060,14 +2190,16 @@ static int __init acer_wmi_init(void) | |||
2060 | 2190 | ||
2061 | set_quirks(); | 2191 | set_quirks(); |
2062 | 2192 | ||
2193 | if (dmi_check_system(video_vendor_dmi_table)) | ||
2194 | acpi_video_dmi_promote_vendor(); | ||
2063 | if (acpi_video_backlight_support()) { | 2195 | if (acpi_video_backlight_support()) { |
2064 | if (dmi_check_system(video_vendor_dmi_table)) { | 2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; |
2065 | acpi_video_unregister(); | 2197 | pr_info("Brightness must be controlled by acpi video driver\n"); |
2066 | } else { | 2198 | } else { |
2067 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | 2199 | #ifdef CONFIG_ACPI_VIDEO |
2068 | pr_info("Brightness must be controlled by " | 2200 | pr_info("Disabling ACPI video driver\n"); |
2069 | "acpi video driver\n"); | 2201 | acpi_video_unregister(); |
2070 | } | 2202 | #endif |
2071 | } | 2203 | } |
2072 | 2204 | ||
2073 | if (wmi_has_guid(WMID_GUID3)) { | 2205 | if (wmi_has_guid(WMID_GUID3)) { |
@@ -2090,6 +2222,8 @@ static int __init acer_wmi_init(void) | |||
2090 | return err; | 2222 | return err; |
2091 | } | 2223 | } |
2092 | 2224 | ||
2225 | acer_wmi_accel_setup(); | ||
2226 | |||
2093 | err = platform_driver_register(&acer_platform_driver); | 2227 | err = platform_driver_register(&acer_platform_driver); |
2094 | if (err) { | 2228 | if (err) { |
2095 | pr_err("Unable to register platform driver\n"); | 2229 | pr_err("Unable to register platform driver\n"); |
@@ -2133,6 +2267,8 @@ error_device_alloc: | |||
2133 | error_platform_register: | 2267 | error_platform_register: |
2134 | if (wmi_has_guid(ACERWMID_EVENT_GUID)) | 2268 | if (wmi_has_guid(ACERWMID_EVENT_GUID)) |
2135 | acer_wmi_input_destroy(); | 2269 | acer_wmi_input_destroy(); |
2270 | if (has_cap(ACER_CAP_ACCEL)) | ||
2271 | acer_wmi_accel_destroy(); | ||
2136 | 2272 | ||
2137 | return err; | 2273 | return err; |
2138 | } | 2274 | } |
@@ -2142,6 +2278,9 @@ static void __exit acer_wmi_exit(void) | |||
2142 | if (wmi_has_guid(ACERWMID_EVENT_GUID)) | 2278 | if (wmi_has_guid(ACERWMID_EVENT_GUID)) |
2143 | acer_wmi_input_destroy(); | 2279 | acer_wmi_input_destroy(); |
2144 | 2280 | ||
2281 | if (has_cap(ACER_CAP_ACCEL)) | ||
2282 | acer_wmi_accel_destroy(); | ||
2283 | |||
2145 | remove_sysfs(acer_platform_device); | 2284 | remove_sysfs(acer_platform_device); |
2146 | remove_debugfs(); | 2285 | remove_debugfs(); |
2147 | platform_device_unregister(acer_platform_device); | 2286 | platform_device_unregister(acer_platform_device); |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 694a15a56230..905fa01ac8df 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -193,7 +193,10 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
193 | * backlight control and supports more levels than other options. | 193 | * backlight control and supports more levels than other options. |
194 | * Disable the other backlight choices. | 194 | * Disable the other backlight choices. |
195 | */ | 195 | */ |
196 | acpi_video_dmi_promote_vendor(); | ||
197 | #ifdef CONFIG_ACPI_VIDEO | ||
196 | acpi_video_unregister(); | 198 | acpi_video_unregister(); |
199 | #endif | ||
197 | apple_bl_unregister(); | 200 | apple_bl_unregister(); |
198 | 201 | ||
199 | return 0; | 202 | return 0; |
@@ -213,7 +216,10 @@ static void __devexit gmux_remove(struct pnp_dev *pnp) | |||
213 | release_region(gmux_data->iostart, gmux_data->iolen); | 216 | release_region(gmux_data->iostart, gmux_data->iolen); |
214 | kfree(gmux_data); | 217 | kfree(gmux_data); |
215 | 218 | ||
219 | acpi_video_dmi_demote_vendor(); | ||
220 | #ifdef CONFIG_ACPI_VIDEO | ||
216 | acpi_video_register(); | 221 | acpi_video_register(); |
222 | #endif | ||
217 | apple_bl_register(); | 223 | apple_bl_register(); |
218 | } | 224 | } |
219 | 225 | ||
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 99a30b513137..6b0ebdeae916 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/input/sparse-keymap.h> | 27 | #include <linux/input/sparse-keymap.h> |
28 | #include <linux/fb.h> | 28 | #include <linux/fb.h> |
29 | #include <linux/dmi.h> | ||
29 | 30 | ||
30 | #include "asus-wmi.h" | 31 | #include "asus-wmi.h" |
31 | 32 | ||
@@ -48,18 +49,115 @@ MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); | |||
48 | * 1 | Hardware | Software | 49 | * 1 | Hardware | Software |
49 | * 4 | Software | Software | 50 | * 4 | Software | Software |
50 | */ | 51 | */ |
51 | static uint wapf; | 52 | static int wapf = -1; |
52 | module_param(wapf, uint, 0444); | 53 | module_param(wapf, uint, 0444); |
53 | MODULE_PARM_DESC(wapf, "WAPF value"); | 54 | MODULE_PARM_DESC(wapf, "WAPF value"); |
54 | 55 | ||
56 | static struct quirk_entry *quirks; | ||
57 | |||
55 | static struct quirk_entry quirk_asus_unknown = { | 58 | static struct quirk_entry quirk_asus_unknown = { |
59 | .wapf = 0, | ||
60 | }; | ||
61 | |||
62 | static struct quirk_entry quirk_asus_x401u = { | ||
63 | .wapf = 4, | ||
64 | }; | ||
65 | |||
66 | static int dmi_matched(const struct dmi_system_id *dmi) | ||
67 | { | ||
68 | quirks = dmi->driver_data; | ||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | static struct dmi_system_id asus_quirks[] = { | ||
73 | { | ||
74 | .callback = dmi_matched, | ||
75 | .ident = "ASUSTeK COMPUTER INC. X401U", | ||
76 | .matches = { | ||
77 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
78 | DMI_MATCH(DMI_PRODUCT_NAME, "X401U"), | ||
79 | }, | ||
80 | .driver_data = &quirk_asus_x401u, | ||
81 | }, | ||
82 | { | ||
83 | .callback = dmi_matched, | ||
84 | .ident = "ASUSTeK COMPUTER INC. X401A1", | ||
85 | .matches = { | ||
86 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
87 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), | ||
88 | }, | ||
89 | .driver_data = &quirk_asus_x401u, | ||
90 | }, | ||
91 | { | ||
92 | .callback = dmi_matched, | ||
93 | .ident = "ASUSTeK COMPUTER INC. X501U", | ||
94 | .matches = { | ||
95 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
96 | DMI_MATCH(DMI_PRODUCT_NAME, "X501U"), | ||
97 | }, | ||
98 | .driver_data = &quirk_asus_x401u, | ||
99 | }, | ||
100 | { | ||
101 | .callback = dmi_matched, | ||
102 | .ident = "ASUSTeK COMPUTER INC. X501A1", | ||
103 | .matches = { | ||
104 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
105 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), | ||
106 | }, | ||
107 | .driver_data = &quirk_asus_x401u, | ||
108 | }, | ||
109 | { | ||
110 | .callback = dmi_matched, | ||
111 | .ident = "ASUSTeK COMPUTER INC. X55A", | ||
112 | .matches = { | ||
113 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
114 | DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), | ||
115 | }, | ||
116 | .driver_data = &quirk_asus_x401u, | ||
117 | }, | ||
118 | { | ||
119 | .callback = dmi_matched, | ||
120 | .ident = "ASUSTeK COMPUTER INC. X55C", | ||
121 | .matches = { | ||
122 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
123 | DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), | ||
124 | }, | ||
125 | .driver_data = &quirk_asus_x401u, | ||
126 | }, | ||
127 | { | ||
128 | .callback = dmi_matched, | ||
129 | .ident = "ASUSTeK COMPUTER INC. X55U", | ||
130 | .matches = { | ||
131 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
132 | DMI_MATCH(DMI_PRODUCT_NAME, "X55U"), | ||
133 | }, | ||
134 | .driver_data = &quirk_asus_x401u, | ||
135 | }, | ||
136 | { | ||
137 | .callback = dmi_matched, | ||
138 | .ident = "ASUSTeK COMPUTER INC. X55VD", | ||
139 | .matches = { | ||
140 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
141 | DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), | ||
142 | }, | ||
143 | .driver_data = &quirk_asus_x401u, | ||
144 | }, | ||
145 | {}, | ||
56 | }; | 146 | }; |
57 | 147 | ||
58 | static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) | 148 | static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) |
59 | { | 149 | { |
60 | driver->quirks = &quirk_asus_unknown; | 150 | quirks = &quirk_asus_unknown; |
61 | driver->quirks->wapf = wapf; | 151 | dmi_check_system(asus_quirks); |
152 | |||
153 | driver->quirks = quirks; | ||
62 | driver->panel_power = FB_BLANK_UNBLANK; | 154 | driver->panel_power = FB_BLANK_UNBLANK; |
155 | |||
156 | /* overwrite the wapf setting if the wapf paramater is specified */ | ||
157 | if (wapf != -1) | ||
158 | quirks->wapf = wapf; | ||
159 | else | ||
160 | wapf = quirks->wapf; | ||
63 | } | 161 | } |
64 | 162 | ||
65 | static const struct key_entry asus_nb_wmi_keymap[] = { | 163 | static const struct key_entry asus_nb_wmi_keymap[] = { |
@@ -94,6 +192,10 @@ static const struct key_entry asus_nb_wmi_keymap[] = { | |||
94 | { KE_KEY, 0x8A, { KEY_PROG1 } }, | 192 | { KE_KEY, 0x8A, { KEY_PROG1 } }, |
95 | { KE_KEY, 0x95, { KEY_MEDIA } }, | 193 | { KE_KEY, 0x95, { KEY_MEDIA } }, |
96 | { KE_KEY, 0x99, { KEY_PHONE } }, | 194 | { KE_KEY, 0x99, { KEY_PHONE } }, |
195 | { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ | ||
196 | { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ | ||
197 | { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ | ||
198 | { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ | ||
97 | { KE_KEY, 0xb5, { KEY_CALC } }, | 199 | { KE_KEY, 0xb5, { KEY_CALC } }, |
98 | { KE_KEY, 0xc4, { KEY_KBDILLUMUP } }, | 200 | { KE_KEY, 0xc4, { KEY_KBDILLUMUP } }, |
99 | { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } }, | 201 | { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } }, |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 77aadde5281c..c7a36f6b0580 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -47,6 +47,9 @@ | |||
47 | #include <linux/thermal.h> | 47 | #include <linux/thermal.h> |
48 | #include <acpi/acpi_bus.h> | 48 | #include <acpi/acpi_bus.h> |
49 | #include <acpi/acpi_drivers.h> | 49 | #include <acpi/acpi_drivers.h> |
50 | #ifdef CONFIG_ACPI_VIDEO | ||
51 | #include <acpi/video.h> | ||
52 | #endif | ||
50 | 53 | ||
51 | #include "asus-wmi.h" | 54 | #include "asus-wmi.h" |
52 | 55 | ||
@@ -136,6 +139,9 @@ MODULE_LICENSE("GPL"); | |||
136 | /* Power */ | 139 | /* Power */ |
137 | #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 | 140 | #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 |
138 | 141 | ||
142 | /* Deep S3 / Resume on LID open */ | ||
143 | #define ASUS_WMI_DEVID_LID_RESUME 0x00120031 | ||
144 | |||
139 | /* DSTS masks */ | 145 | /* DSTS masks */ |
140 | #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001 | 146 | #define ASUS_WMI_DSTS_STATUS_BIT 0x00000001 |
141 | #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002 | 147 | #define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002 |
@@ -1365,6 +1371,7 @@ static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf) | |||
1365 | ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD); | 1371 | ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD); |
1366 | ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA); | 1372 | ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA); |
1367 | ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); | 1373 | ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); |
1374 | ASUS_WMI_CREATE_DEVICE_ATTR(lid_resume, 0644, ASUS_WMI_DEVID_LID_RESUME); | ||
1368 | 1375 | ||
1369 | static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, | 1376 | static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, |
1370 | const char *buf, size_t count) | 1377 | const char *buf, size_t count) |
@@ -1390,6 +1397,7 @@ static struct attribute *platform_attributes[] = { | |||
1390 | &dev_attr_camera.attr, | 1397 | &dev_attr_camera.attr, |
1391 | &dev_attr_cardr.attr, | 1398 | &dev_attr_cardr.attr, |
1392 | &dev_attr_touchpad.attr, | 1399 | &dev_attr_touchpad.attr, |
1400 | &dev_attr_lid_resume.attr, | ||
1393 | NULL | 1401 | NULL |
1394 | }; | 1402 | }; |
1395 | 1403 | ||
@@ -1408,6 +1416,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, | |||
1408 | devid = ASUS_WMI_DEVID_CARDREADER; | 1416 | devid = ASUS_WMI_DEVID_CARDREADER; |
1409 | else if (attr == &dev_attr_touchpad.attr) | 1417 | else if (attr == &dev_attr_touchpad.attr) |
1410 | devid = ASUS_WMI_DEVID_TOUCHPAD; | 1418 | devid = ASUS_WMI_DEVID_TOUCHPAD; |
1419 | else if (attr == &dev_attr_lid_resume.attr) | ||
1420 | devid = ASUS_WMI_DEVID_LID_RESUME; | ||
1411 | 1421 | ||
1412 | if (devid != -1) | 1422 | if (devid != -1) |
1413 | ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); | 1423 | ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0); |
@@ -1467,14 +1477,9 @@ static int asus_wmi_platform_init(struct asus_wmi *asus) | |||
1467 | */ | 1477 | */ |
1468 | if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL)) | 1478 | if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL)) |
1469 | asus->dsts_id = ASUS_WMI_METHODID_DSTS; | 1479 | asus->dsts_id = ASUS_WMI_METHODID_DSTS; |
1470 | else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL)) | 1480 | else |
1471 | asus->dsts_id = ASUS_WMI_METHODID_DSTS2; | 1481 | asus->dsts_id = ASUS_WMI_METHODID_DSTS2; |
1472 | 1482 | ||
1473 | if (!asus->dsts_id) { | ||
1474 | pr_err("Can't find DSTS"); | ||
1475 | return -ENODEV; | ||
1476 | } | ||
1477 | |||
1478 | /* CWAP allow to define the behavior of the Fn+F2 key, | 1483 | /* CWAP allow to define the behavior of the Fn+F2 key, |
1479 | * this method doesn't seems to be present on Eee PCs */ | 1484 | * this method doesn't seems to be present on Eee PCs */ |
1480 | if (asus->driver->quirks->wapf >= 0) | 1485 | if (asus->driver->quirks->wapf >= 0) |
@@ -1681,7 +1686,13 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1681 | if (err) | 1686 | if (err) |
1682 | goto fail_rfkill; | 1687 | goto fail_rfkill; |
1683 | 1688 | ||
1689 | if (asus->driver->quirks->wmi_backlight_power) | ||
1690 | acpi_video_dmi_promote_vendor(); | ||
1684 | if (!acpi_video_backlight_support()) { | 1691 | if (!acpi_video_backlight_support()) { |
1692 | #ifdef CONFIG_ACPI_VIDEO | ||
1693 | pr_info("Disabling ACPI video driver\n"); | ||
1694 | acpi_video_unregister(); | ||
1695 | #endif | ||
1685 | err = asus_wmi_backlight_init(asus); | 1696 | err = asus_wmi_backlight_init(asus); |
1686 | if (err && err != -ENODEV) | 1697 | if (err && err != -ENODEV) |
1687 | goto fail_backlight; | 1698 | goto fail_backlight; |
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index d43b66742004..9c1da8b81bea 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h | |||
@@ -39,6 +39,7 @@ struct quirk_entry { | |||
39 | bool hotplug_wireless; | 39 | bool hotplug_wireless; |
40 | bool scalar_panel_brightness; | 40 | bool scalar_panel_brightness; |
41 | bool store_backlight_power; | 41 | bool store_backlight_power; |
42 | bool wmi_backlight_power; | ||
42 | int wapf; | 43 | int wapf; |
43 | }; | 44 | }; |
44 | 45 | ||
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index e2230a2b2f8e..2ca7dd1ab3e4 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -31,15 +31,21 @@ MODULE_LICENSE("GPL"); | |||
31 | 31 | ||
32 | struct cmpc_accel { | 32 | struct cmpc_accel { |
33 | int sensitivity; | 33 | int sensitivity; |
34 | int g_select; | ||
35 | int inputdev_state; | ||
34 | }; | 36 | }; |
35 | 37 | ||
36 | #define CMPC_ACCEL_SENSITIVITY_DEFAULT 5 | 38 | #define CMPC_ACCEL_DEV_STATE_CLOSED 0 |
39 | #define CMPC_ACCEL_DEV_STATE_OPEN 1 | ||
37 | 40 | ||
41 | #define CMPC_ACCEL_SENSITIVITY_DEFAULT 5 | ||
42 | #define CMPC_ACCEL_G_SELECT_DEFAULT 0 | ||
38 | 43 | ||
39 | #define CMPC_ACCEL_HID "ACCE0000" | 44 | #define CMPC_ACCEL_HID "ACCE0000" |
45 | #define CMPC_ACCEL_HID_V4 "ACCE0001" | ||
40 | #define CMPC_TABLET_HID "TBLT0000" | 46 | #define CMPC_TABLET_HID "TBLT0000" |
41 | #define CMPC_IPML_HID "IPML200" | 47 | #define CMPC_IPML_HID "IPML200" |
42 | #define CMPC_KEYS_HID "FnBT0000" | 48 | #define CMPC_KEYS_HID "FNBT0000" |
43 | 49 | ||
44 | /* | 50 | /* |
45 | * Generic input device code. | 51 | * Generic input device code. |
@@ -76,7 +82,391 @@ static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi) | |||
76 | } | 82 | } |
77 | 83 | ||
78 | /* | 84 | /* |
79 | * Accelerometer code. | 85 | * Accelerometer code for Classmate V4 |
86 | */ | ||
87 | static acpi_status cmpc_start_accel_v4(acpi_handle handle) | ||
88 | { | ||
89 | union acpi_object param[4]; | ||
90 | struct acpi_object_list input; | ||
91 | acpi_status status; | ||
92 | |||
93 | param[0].type = ACPI_TYPE_INTEGER; | ||
94 | param[0].integer.value = 0x3; | ||
95 | param[1].type = ACPI_TYPE_INTEGER; | ||
96 | param[1].integer.value = 0; | ||
97 | param[2].type = ACPI_TYPE_INTEGER; | ||
98 | param[2].integer.value = 0; | ||
99 | param[3].type = ACPI_TYPE_INTEGER; | ||
100 | param[3].integer.value = 0; | ||
101 | input.count = 4; | ||
102 | input.pointer = param; | ||
103 | status = acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
104 | return status; | ||
105 | } | ||
106 | |||
107 | static acpi_status cmpc_stop_accel_v4(acpi_handle handle) | ||
108 | { | ||
109 | union acpi_object param[4]; | ||
110 | struct acpi_object_list input; | ||
111 | acpi_status status; | ||
112 | |||
113 | param[0].type = ACPI_TYPE_INTEGER; | ||
114 | param[0].integer.value = 0x4; | ||
115 | param[1].type = ACPI_TYPE_INTEGER; | ||
116 | param[1].integer.value = 0; | ||
117 | param[2].type = ACPI_TYPE_INTEGER; | ||
118 | param[2].integer.value = 0; | ||
119 | param[3].type = ACPI_TYPE_INTEGER; | ||
120 | param[3].integer.value = 0; | ||
121 | input.count = 4; | ||
122 | input.pointer = param; | ||
123 | status = acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
124 | return status; | ||
125 | } | ||
126 | |||
127 | static acpi_status cmpc_accel_set_sensitivity_v4(acpi_handle handle, int val) | ||
128 | { | ||
129 | union acpi_object param[4]; | ||
130 | struct acpi_object_list input; | ||
131 | |||
132 | param[0].type = ACPI_TYPE_INTEGER; | ||
133 | param[0].integer.value = 0x02; | ||
134 | param[1].type = ACPI_TYPE_INTEGER; | ||
135 | param[1].integer.value = val; | ||
136 | param[2].type = ACPI_TYPE_INTEGER; | ||
137 | param[2].integer.value = 0; | ||
138 | param[3].type = ACPI_TYPE_INTEGER; | ||
139 | param[3].integer.value = 0; | ||
140 | input.count = 4; | ||
141 | input.pointer = param; | ||
142 | return acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
143 | } | ||
144 | |||
145 | static acpi_status cmpc_accel_set_g_select_v4(acpi_handle handle, int val) | ||
146 | { | ||
147 | union acpi_object param[4]; | ||
148 | struct acpi_object_list input; | ||
149 | |||
150 | param[0].type = ACPI_TYPE_INTEGER; | ||
151 | param[0].integer.value = 0x05; | ||
152 | param[1].type = ACPI_TYPE_INTEGER; | ||
153 | param[1].integer.value = val; | ||
154 | param[2].type = ACPI_TYPE_INTEGER; | ||
155 | param[2].integer.value = 0; | ||
156 | param[3].type = ACPI_TYPE_INTEGER; | ||
157 | param[3].integer.value = 0; | ||
158 | input.count = 4; | ||
159 | input.pointer = param; | ||
160 | return acpi_evaluate_object(handle, "ACMD", &input, NULL); | ||
161 | } | ||
162 | |||
163 | static acpi_status cmpc_get_accel_v4(acpi_handle handle, | ||
164 | int16_t *x, | ||
165 | int16_t *y, | ||
166 | int16_t *z) | ||
167 | { | ||
168 | union acpi_object param[4]; | ||
169 | struct acpi_object_list input; | ||
170 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
171 | int16_t *locs; | ||
172 | acpi_status status; | ||
173 | |||
174 | param[0].type = ACPI_TYPE_INTEGER; | ||
175 | param[0].integer.value = 0x01; | ||
176 | param[1].type = ACPI_TYPE_INTEGER; | ||
177 | param[1].integer.value = 0; | ||
178 | param[2].type = ACPI_TYPE_INTEGER; | ||
179 | param[2].integer.value = 0; | ||
180 | param[3].type = ACPI_TYPE_INTEGER; | ||
181 | param[3].integer.value = 0; | ||
182 | input.count = 4; | ||
183 | input.pointer = param; | ||
184 | status = acpi_evaluate_object(handle, "ACMD", &input, &output); | ||
185 | if (ACPI_SUCCESS(status)) { | ||
186 | union acpi_object *obj; | ||
187 | obj = output.pointer; | ||
188 | locs = (int16_t *) obj->buffer.pointer; | ||
189 | *x = locs[0]; | ||
190 | *y = locs[1]; | ||
191 | *z = locs[2]; | ||
192 | kfree(output.pointer); | ||
193 | } | ||
194 | return status; | ||
195 | } | ||
196 | |||
197 | static void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event) | ||
198 | { | ||
199 | if (event == 0x81) { | ||
200 | int16_t x, y, z; | ||
201 | acpi_status status; | ||
202 | |||
203 | status = cmpc_get_accel_v4(dev->handle, &x, &y, &z); | ||
204 | if (ACPI_SUCCESS(status)) { | ||
205 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); | ||
206 | |||
207 | input_report_abs(inputdev, ABS_X, x); | ||
208 | input_report_abs(inputdev, ABS_Y, y); | ||
209 | input_report_abs(inputdev, ABS_Z, z); | ||
210 | input_sync(inputdev); | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev, | ||
216 | struct device_attribute *attr, | ||
217 | char *buf) | ||
218 | { | ||
219 | struct acpi_device *acpi; | ||
220 | struct input_dev *inputdev; | ||
221 | struct cmpc_accel *accel; | ||
222 | |||
223 | acpi = to_acpi_device(dev); | ||
224 | inputdev = dev_get_drvdata(&acpi->dev); | ||
225 | accel = dev_get_drvdata(&inputdev->dev); | ||
226 | |||
227 | return sprintf(buf, "%d\n", accel->sensitivity); | ||
228 | } | ||
229 | |||
230 | static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev, | ||
231 | struct device_attribute *attr, | ||
232 | const char *buf, size_t count) | ||
233 | { | ||
234 | struct acpi_device *acpi; | ||
235 | struct input_dev *inputdev; | ||
236 | struct cmpc_accel *accel; | ||
237 | unsigned long sensitivity; | ||
238 | int r; | ||
239 | |||
240 | acpi = to_acpi_device(dev); | ||
241 | inputdev = dev_get_drvdata(&acpi->dev); | ||
242 | accel = dev_get_drvdata(&inputdev->dev); | ||
243 | |||
244 | r = kstrtoul(buf, 0, &sensitivity); | ||
245 | if (r) | ||
246 | return r; | ||
247 | |||
248 | /* sensitivity must be between 1 and 127 */ | ||
249 | if (sensitivity < 1 || sensitivity > 127) | ||
250 | return -EINVAL; | ||
251 | |||
252 | accel->sensitivity = sensitivity; | ||
253 | cmpc_accel_set_sensitivity_v4(acpi->handle, sensitivity); | ||
254 | |||
255 | return strnlen(buf, count); | ||
256 | } | ||
257 | |||
258 | static struct device_attribute cmpc_accel_sensitivity_attr_v4 = { | ||
259 | .attr = { .name = "sensitivity", .mode = 0660 }, | ||
260 | .show = cmpc_accel_sensitivity_show_v4, | ||
261 | .store = cmpc_accel_sensitivity_store_v4 | ||
262 | }; | ||
263 | |||
264 | static ssize_t cmpc_accel_g_select_show_v4(struct device *dev, | ||
265 | struct device_attribute *attr, | ||
266 | char *buf) | ||
267 | { | ||
268 | struct acpi_device *acpi; | ||
269 | struct input_dev *inputdev; | ||
270 | struct cmpc_accel *accel; | ||
271 | |||
272 | acpi = to_acpi_device(dev); | ||
273 | inputdev = dev_get_drvdata(&acpi->dev); | ||
274 | accel = dev_get_drvdata(&inputdev->dev); | ||
275 | |||
276 | return sprintf(buf, "%d\n", accel->g_select); | ||
277 | } | ||
278 | |||
279 | static ssize_t cmpc_accel_g_select_store_v4(struct device *dev, | ||
280 | struct device_attribute *attr, | ||
281 | const char *buf, size_t count) | ||
282 | { | ||
283 | struct acpi_device *acpi; | ||
284 | struct input_dev *inputdev; | ||
285 | struct cmpc_accel *accel; | ||
286 | unsigned long g_select; | ||
287 | int r; | ||
288 | |||
289 | acpi = to_acpi_device(dev); | ||
290 | inputdev = dev_get_drvdata(&acpi->dev); | ||
291 | accel = dev_get_drvdata(&inputdev->dev); | ||
292 | |||
293 | r = kstrtoul(buf, 0, &g_select); | ||
294 | if (r) | ||
295 | return r; | ||
296 | |||
297 | /* 0 means 1.5g, 1 means 6g, everything else is wrong */ | ||
298 | if (g_select != 0 && g_select != 1) | ||
299 | return -EINVAL; | ||
300 | |||
301 | accel->g_select = g_select; | ||
302 | cmpc_accel_set_g_select_v4(acpi->handle, g_select); | ||
303 | |||
304 | return strnlen(buf, count); | ||
305 | } | ||
306 | |||
307 | static struct device_attribute cmpc_accel_g_select_attr_v4 = { | ||
308 | .attr = { .name = "g_select", .mode = 0660 }, | ||
309 | .show = cmpc_accel_g_select_show_v4, | ||
310 | .store = cmpc_accel_g_select_store_v4 | ||
311 | }; | ||
312 | |||
313 | static int cmpc_accel_open_v4(struct input_dev *input) | ||
314 | { | ||
315 | struct acpi_device *acpi; | ||
316 | struct cmpc_accel *accel; | ||
317 | |||
318 | acpi = to_acpi_device(input->dev.parent); | ||
319 | accel = dev_get_drvdata(&input->dev); | ||
320 | |||
321 | cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity); | ||
322 | cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select); | ||
323 | |||
324 | if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) { | ||
325 | accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN; | ||
326 | return 0; | ||
327 | } | ||
328 | return -EIO; | ||
329 | } | ||
330 | |||
331 | static void cmpc_accel_close_v4(struct input_dev *input) | ||
332 | { | ||
333 | struct acpi_device *acpi; | ||
334 | struct cmpc_accel *accel; | ||
335 | |||
336 | acpi = to_acpi_device(input->dev.parent); | ||
337 | accel = dev_get_drvdata(&input->dev); | ||
338 | |||
339 | cmpc_stop_accel_v4(acpi->handle); | ||
340 | accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED; | ||
341 | } | ||
342 | |||
343 | static void cmpc_accel_idev_init_v4(struct input_dev *inputdev) | ||
344 | { | ||
345 | set_bit(EV_ABS, inputdev->evbit); | ||
346 | input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0); | ||
347 | input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0); | ||
348 | input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0); | ||
349 | inputdev->open = cmpc_accel_open_v4; | ||
350 | inputdev->close = cmpc_accel_close_v4; | ||
351 | } | ||
352 | |||
353 | static int cmpc_accel_suspend_v4(struct device *dev) | ||
354 | { | ||
355 | struct input_dev *inputdev; | ||
356 | struct cmpc_accel *accel; | ||
357 | |||
358 | inputdev = dev_get_drvdata(dev); | ||
359 | accel = dev_get_drvdata(&inputdev->dev); | ||
360 | |||
361 | if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) | ||
362 | return cmpc_stop_accel_v4(to_acpi_device(dev)->handle); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int cmpc_accel_resume_v4(struct device *dev) | ||
368 | { | ||
369 | struct input_dev *inputdev; | ||
370 | struct cmpc_accel *accel; | ||
371 | |||
372 | inputdev = dev_get_drvdata(dev); | ||
373 | accel = dev_get_drvdata(&inputdev->dev); | ||
374 | |||
375 | if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) { | ||
376 | cmpc_accel_set_sensitivity_v4(to_acpi_device(dev)->handle, | ||
377 | accel->sensitivity); | ||
378 | cmpc_accel_set_g_select_v4(to_acpi_device(dev)->handle, | ||
379 | accel->g_select); | ||
380 | |||
381 | if (ACPI_FAILURE(cmpc_start_accel_v4(to_acpi_device(dev)->handle))) | ||
382 | return -EIO; | ||
383 | } | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int cmpc_accel_add_v4(struct acpi_device *acpi) | ||
389 | { | ||
390 | int error; | ||
391 | struct input_dev *inputdev; | ||
392 | struct cmpc_accel *accel; | ||
393 | |||
394 | accel = kmalloc(sizeof(*accel), GFP_KERNEL); | ||
395 | if (!accel) | ||
396 | return -ENOMEM; | ||
397 | |||
398 | accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED; | ||
399 | |||
400 | accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT; | ||
401 | cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity); | ||
402 | |||
403 | error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4); | ||
404 | if (error) | ||
405 | goto failed_sensitivity; | ||
406 | |||
407 | accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT; | ||
408 | cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select); | ||
409 | |||
410 | error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v4); | ||
411 | if (error) | ||
412 | goto failed_g_select; | ||
413 | |||
414 | error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4", | ||
415 | cmpc_accel_idev_init_v4); | ||
416 | if (error) | ||
417 | goto failed_input; | ||
418 | |||
419 | inputdev = dev_get_drvdata(&acpi->dev); | ||
420 | dev_set_drvdata(&inputdev->dev, accel); | ||
421 | |||
422 | return 0; | ||
423 | |||
424 | failed_input: | ||
425 | device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4); | ||
426 | failed_g_select: | ||
427 | device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4); | ||
428 | failed_sensitivity: | ||
429 | kfree(accel); | ||
430 | return error; | ||
431 | } | ||
432 | |||
433 | static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type) | ||
434 | { | ||
435 | struct input_dev *inputdev; | ||
436 | struct cmpc_accel *accel; | ||
437 | |||
438 | inputdev = dev_get_drvdata(&acpi->dev); | ||
439 | accel = dev_get_drvdata(&inputdev->dev); | ||
440 | |||
441 | device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4); | ||
442 | device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4); | ||
443 | return cmpc_remove_acpi_notify_device(acpi); | ||
444 | } | ||
445 | |||
446 | static SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4, | ||
447 | cmpc_accel_resume_v4); | ||
448 | |||
449 | static const struct acpi_device_id cmpc_accel_device_ids_v4[] = { | ||
450 | {CMPC_ACCEL_HID_V4, 0}, | ||
451 | {"", 0} | ||
452 | }; | ||
453 | |||
454 | static struct acpi_driver cmpc_accel_acpi_driver_v4 = { | ||
455 | .owner = THIS_MODULE, | ||
456 | .name = "cmpc_accel_v4", | ||
457 | .class = "cmpc_accel_v4", | ||
458 | .ids = cmpc_accel_device_ids_v4, | ||
459 | .ops = { | ||
460 | .add = cmpc_accel_add_v4, | ||
461 | .remove = cmpc_accel_remove_v4, | ||
462 | .notify = cmpc_accel_handler_v4, | ||
463 | }, | ||
464 | .drv.pm = &cmpc_accel_pm, | ||
465 | }; | ||
466 | |||
467 | |||
468 | /* | ||
469 | * Accelerometer code for Classmate versions prior to V4 | ||
80 | */ | 470 | */ |
81 | static acpi_status cmpc_start_accel(acpi_handle handle) | 471 | static acpi_status cmpc_start_accel(acpi_handle handle) |
82 | { | 472 | { |
@@ -726,8 +1116,15 @@ static int cmpc_init(void) | |||
726 | if (r) | 1116 | if (r) |
727 | goto failed_accel; | 1117 | goto failed_accel; |
728 | 1118 | ||
1119 | r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4); | ||
1120 | if (r) | ||
1121 | goto failed_accel_v4; | ||
1122 | |||
729 | return r; | 1123 | return r; |
730 | 1124 | ||
1125 | failed_accel_v4: | ||
1126 | acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); | ||
1127 | |||
731 | failed_accel: | 1128 | failed_accel: |
732 | acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); | 1129 | acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); |
733 | 1130 | ||
@@ -743,6 +1140,7 @@ failed_keys: | |||
743 | 1140 | ||
744 | static void cmpc_exit(void) | 1141 | static void cmpc_exit(void) |
745 | { | 1142 | { |
1143 | acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4); | ||
746 | acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); | 1144 | acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); |
747 | acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); | 1145 | acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); |
748 | acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver); | 1146 | acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver); |
@@ -754,6 +1152,7 @@ module_exit(cmpc_exit); | |||
754 | 1152 | ||
755 | static const struct acpi_device_id cmpc_device_ids[] = { | 1153 | static const struct acpi_device_id cmpc_device_ids[] = { |
756 | {CMPC_ACCEL_HID, 0}, | 1154 | {CMPC_ACCEL_HID, 0}, |
1155 | {CMPC_ACCEL_HID_V4, 0}, | ||
757 | {CMPC_TABLET_HID, 0}, | 1156 | {CMPC_TABLET_HID, 0}, |
758 | {CMPC_IPML_HID, 0}, | 1157 | {CMPC_IPML_HID, 0}, |
759 | {CMPC_KEYS_HID, 0}, | 1158 | {CMPC_KEYS_HID, 0}, |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 5f78aac9b163..4e96e8c0b60f 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -206,6 +206,60 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
206 | }, | 206 | }, |
207 | .driver_data = &quirk_dell_vostro_v130, | 207 | .driver_data = &quirk_dell_vostro_v130, |
208 | }, | 208 | }, |
209 | { | ||
210 | .callback = dmi_matched, | ||
211 | .ident = "Dell Inspiron 5420", | ||
212 | .matches = { | ||
213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
214 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5420"), | ||
215 | }, | ||
216 | .driver_data = &quirk_dell_vostro_v130, | ||
217 | }, | ||
218 | { | ||
219 | .callback = dmi_matched, | ||
220 | .ident = "Dell Inspiron 5520", | ||
221 | .matches = { | ||
222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
223 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5520"), | ||
224 | }, | ||
225 | .driver_data = &quirk_dell_vostro_v130, | ||
226 | }, | ||
227 | { | ||
228 | .callback = dmi_matched, | ||
229 | .ident = "Dell Inspiron 5720", | ||
230 | .matches = { | ||
231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
232 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5720"), | ||
233 | }, | ||
234 | .driver_data = &quirk_dell_vostro_v130, | ||
235 | }, | ||
236 | { | ||
237 | .callback = dmi_matched, | ||
238 | .ident = "Dell Inspiron 7420", | ||
239 | .matches = { | ||
240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
241 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7420"), | ||
242 | }, | ||
243 | .driver_data = &quirk_dell_vostro_v130, | ||
244 | }, | ||
245 | { | ||
246 | .callback = dmi_matched, | ||
247 | .ident = "Dell Inspiron 7520", | ||
248 | .matches = { | ||
249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
250 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7520"), | ||
251 | }, | ||
252 | .driver_data = &quirk_dell_vostro_v130, | ||
253 | }, | ||
254 | { | ||
255 | .callback = dmi_matched, | ||
256 | .ident = "Dell Inspiron 7720", | ||
257 | .matches = { | ||
258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
259 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7720"), | ||
260 | }, | ||
261 | .driver_data = &quirk_dell_vostro_v130, | ||
262 | }, | ||
209 | { } | 263 | { } |
210 | }; | 264 | }; |
211 | 265 | ||
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 656761380342..5838332ea5bd 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -79,7 +79,7 @@ static const struct key_entry eeepc_wmi_keymap[] = { | |||
79 | { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ | 79 | { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ |
80 | { KE_KEY, HOME_PRESS, { KEY_CONFIG } }, /* Home/Express gate key */ | 80 | { KE_KEY, HOME_PRESS, { KEY_CONFIG } }, /* Home/Express gate key */ |
81 | { KE_KEY, 0xe8, { KEY_SCREENLOCK } }, | 81 | { KE_KEY, 0xe8, { KEY_SCREENLOCK } }, |
82 | { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, | 82 | { KE_KEY, 0xe9, { KEY_DISPLAYTOGGLE } }, |
83 | { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, | 83 | { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, |
84 | { KE_KEY, 0xec, { KEY_CAMERA_UP } }, | 84 | { KE_KEY, 0xec, { KEY_CAMERA_UP } }, |
85 | { KE_KEY, 0xed, { KEY_CAMERA_DOWN } }, | 85 | { KE_KEY, 0xed, { KEY_CAMERA_DOWN } }, |
@@ -107,6 +107,11 @@ static struct quirk_entry quirk_asus_et2012_type3 = { | |||
107 | .store_backlight_power = true, | 107 | .store_backlight_power = true, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static struct quirk_entry quirk_asus_x101ch = { | ||
111 | /* We need this when ACPI function doesn't do this well */ | ||
112 | .wmi_backlight_power = true, | ||
113 | }; | ||
114 | |||
110 | static struct quirk_entry *quirks; | 115 | static struct quirk_entry *quirks; |
111 | 116 | ||
112 | static void et2012_quirks(void) | 117 | static void et2012_quirks(void) |
@@ -157,6 +162,24 @@ static struct dmi_system_id asus_quirks[] = { | |||
157 | }, | 162 | }, |
158 | .driver_data = &quirk_asus_unknown, | 163 | .driver_data = &quirk_asus_unknown, |
159 | }, | 164 | }, |
165 | { | ||
166 | .callback = dmi_matched, | ||
167 | .ident = "ASUSTeK Computer INC. X101CH", | ||
168 | .matches = { | ||
169 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
170 | DMI_MATCH(DMI_PRODUCT_NAME, "X101CH"), | ||
171 | }, | ||
172 | .driver_data = &quirk_asus_x101ch, | ||
173 | }, | ||
174 | { | ||
175 | .callback = dmi_matched, | ||
176 | .ident = "ASUSTeK Computer INC. 1015CX", | ||
177 | .matches = { | ||
178 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
179 | DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"), | ||
180 | }, | ||
181 | .driver_data = &quirk_asus_x101ch, | ||
182 | }, | ||
160 | {}, | 183 | {}, |
161 | }; | 184 | }; |
162 | 185 | ||
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index e2a34b42ddc1..c1ca7bcebb66 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) | 29 | #ifdef CONFIG_ACPI_VIDEO |
30 | #include <acpi/video.h> | 30 | #include <acpi/video.h> |
31 | #endif | 31 | #endif |
32 | 32 | ||
@@ -1465,6 +1465,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
1465 | DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ | 1465 | DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ |
1466 | }, | 1466 | }, |
1467 | }, | 1467 | }, |
1468 | /* DMI ids for laptops with bad Chassis Type */ | ||
1469 | { | ||
1470 | .ident = "R40/R41", | ||
1471 | .matches = { | ||
1472 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
1473 | DMI_MATCH(DMI_PRODUCT_NAME, "R40/R41"), | ||
1474 | DMI_MATCH(DMI_BOARD_NAME, "R40/R41"), | ||
1475 | }, | ||
1476 | }, | ||
1468 | /* Specific DMI ids for laptop with quirks */ | 1477 | /* Specific DMI ids for laptop with quirks */ |
1469 | { | 1478 | { |
1470 | .callback = samsung_dmi_matched, | 1479 | .callback = samsung_dmi_matched, |
@@ -1506,6 +1515,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
1506 | }, | 1515 | }, |
1507 | .driver_data = &samsung_broken_acpi_video, | 1516 | .driver_data = &samsung_broken_acpi_video, |
1508 | }, | 1517 | }, |
1518 | { | ||
1519 | .callback = samsung_dmi_matched, | ||
1520 | .ident = "X360", | ||
1521 | .matches = { | ||
1522 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
1523 | DMI_MATCH(DMI_PRODUCT_NAME, "X360"), | ||
1524 | DMI_MATCH(DMI_BOARD_NAME, "X360"), | ||
1525 | }, | ||
1526 | .driver_data = &samsung_broken_acpi_video, | ||
1527 | }, | ||
1509 | { }, | 1528 | { }, |
1510 | }; | 1529 | }; |
1511 | MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); | 1530 | MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); |
@@ -1530,15 +1549,18 @@ static int __init samsung_init(void) | |||
1530 | samsung->quirks = quirks; | 1549 | samsung->quirks = quirks; |
1531 | 1550 | ||
1532 | 1551 | ||
1533 | #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) | 1552 | #ifdef CONFIG_ACPI |
1553 | if (samsung->quirks->broken_acpi_video) | ||
1554 | acpi_video_dmi_promote_vendor(); | ||
1555 | |||
1534 | /* Don't handle backlight here if the acpi video already handle it */ | 1556 | /* Don't handle backlight here if the acpi video already handle it */ |
1535 | if (acpi_video_backlight_support()) { | 1557 | if (acpi_video_backlight_support()) { |
1536 | if (samsung->quirks->broken_acpi_video) { | 1558 | samsung->handle_backlight = false; |
1537 | pr_info("Disabling ACPI video driver\n"); | 1559 | } else if (samsung->quirks->broken_acpi_video) { |
1538 | acpi_video_unregister(); | 1560 | pr_info("Disabling ACPI video driver\n"); |
1539 | } else { | 1561 | #ifdef CONFIG_ACPI_VIDEO |
1540 | samsung->handle_backlight = false; | 1562 | acpi_video_unregister(); |
1541 | } | 1563 | #endif |
1542 | } | 1564 | } |
1543 | #endif | 1565 | #endif |
1544 | 1566 | ||
@@ -1552,8 +1574,7 @@ static int __init samsung_init(void) | |||
1552 | 1574 | ||
1553 | #ifdef CONFIG_ACPI | 1575 | #ifdef CONFIG_ACPI |
1554 | /* Only log that if we are really on a sabi platform */ | 1576 | /* Only log that if we are really on a sabi platform */ |
1555 | if (acpi_video_backlight_support() && | 1577 | if (acpi_video_backlight_support()) |
1556 | !samsung->quirks->broken_acpi_video) | ||
1557 | pr_info("Backlight controlled by ACPI video driver\n"); | 1578 | pr_info("Backlight controlled by ACPI video driver\n"); |
1558 | #endif | 1579 | #endif |
1559 | 1580 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d5fd4a1193f8..e7f73287636c 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -3015,8 +3015,6 @@ static void hotkey_exit(void) | |||
3015 | if (hotkey_dev_attributes) | 3015 | if (hotkey_dev_attributes) |
3016 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | 3016 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); |
3017 | 3017 | ||
3018 | kfree(hotkey_keycode_map); | ||
3019 | |||
3020 | dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, | 3018 | dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, |
3021 | "restoring original HKEY status and mask\n"); | 3019 | "restoring original HKEY status and mask\n"); |
3022 | /* yes, there is a bitwise or below, we want the | 3020 | /* yes, there is a bitwise or below, we want the |
@@ -5217,6 +5215,7 @@ static void led_exit(void) | |||
5217 | led_classdev_unregister(&tpacpi_leds[i].led_classdev); | 5215 | led_classdev_unregister(&tpacpi_leds[i].led_classdev); |
5218 | } | 5216 | } |
5219 | 5217 | ||
5218 | flush_workqueue(tpacpi_wq); | ||
5220 | kfree(tpacpi_leds); | 5219 | kfree(tpacpi_leds); |
5221 | } | 5220 | } |
5222 | 5221 | ||
@@ -8936,6 +8935,7 @@ static void thinkpad_acpi_module_exit(void) | |||
8936 | input_unregister_device(tpacpi_inputdev); | 8935 | input_unregister_device(tpacpi_inputdev); |
8937 | else | 8936 | else |
8938 | input_free_device(tpacpi_inputdev); | 8937 | input_free_device(tpacpi_inputdev); |
8938 | kfree(hotkey_keycode_map); | ||
8939 | } | 8939 | } |
8940 | 8940 | ||
8941 | if (tpacpi_hwmon) | 8941 | if (tpacpi_hwmon) |
@@ -8969,6 +8969,7 @@ static void thinkpad_acpi_module_exit(void) | |||
8969 | kfree(thinkpad_id.bios_version_str); | 8969 | kfree(thinkpad_id.bios_version_str); |
8970 | kfree(thinkpad_id.ec_version_str); | 8970 | kfree(thinkpad_id.ec_version_str); |
8971 | kfree(thinkpad_id.model_str); | 8971 | kfree(thinkpad_id.model_str); |
8972 | kfree(thinkpad_id.nummodel_str); | ||
8972 | } | 8973 | } |
8973 | 8974 | ||
8974 | 8975 | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b2b4d2ad7103..3ad510b25283 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -190,6 +190,8 @@ extern bool wmi_has_guid(const char *guid); | |||
190 | 190 | ||
191 | extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle); | 191 | extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle); |
192 | extern long acpi_is_video_device(struct acpi_device *device); | 192 | extern long acpi_is_video_device(struct acpi_device *device); |
193 | extern void acpi_video_dmi_promote_vendor(void); | ||
194 | extern void acpi_video_dmi_demote_vendor(void); | ||
193 | extern int acpi_video_backlight_support(void); | 195 | extern int acpi_video_backlight_support(void); |
194 | extern int acpi_video_display_switch_support(void); | 196 | extern int acpi_video_display_switch_support(void); |
195 | 197 | ||
@@ -205,6 +207,14 @@ static inline long acpi_is_video_device(struct acpi_device *device) | |||
205 | return 0; | 207 | return 0; |
206 | } | 208 | } |
207 | 209 | ||
210 | static inline void acpi_video_dmi_promote_vendor(void) | ||
211 | { | ||
212 | } | ||
213 | |||
214 | static inline void acpi_video_dmi_demote_vendor(void) | ||
215 | { | ||
216 | } | ||
217 | |||
208 | static inline int acpi_video_backlight_support(void) | 218 | static inline int acpi_video_backlight_support(void) |
209 | { | 219 | { |
210 | return 0; | 220 | return 0; |