aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-09-19 01:06:16 -0400
committerLen Brown <len.brown@intel.com>2009-09-19 01:06:16 -0400
commit596fb7ae462f5c82a1d663fe04f8c98464c963c9 (patch)
tree0853612306257f388a4cecdbd3043162a5d42251
parent003d6a38ce1a59e0053a02fd9e9a65b588bc8e33 (diff)
parentde4c8cc7bddd9c43dc1b85517ab445ffa8163058 (diff)
Merge branch 'thinkpad' into release
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt8
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c381
2 files changed, 315 insertions, 74 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index e2ddcdeb61b6..6d03487ef1c7 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -219,7 +219,7 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file:
219 echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys 219 echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
220 echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys 220 echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
221 ... any other 8-hex-digit mask ... 221 ... any other 8-hex-digit mask ...
222 echo reset > /proc/acpi/ibm/hotkey -- restore the original mask 222 echo reset > /proc/acpi/ibm/hotkey -- restore the recommended mask
223 223
224The following commands have been deprecated and will cause the kernel 224The following commands have been deprecated and will cause the kernel
225to log a warning: 225to log a warning:
@@ -240,9 +240,13 @@ sysfs notes:
240 Returns 0. 240 Returns 0.
241 241
242 hotkey_bios_mask: 242 hotkey_bios_mask:
243 DEPRECATED, DON'T USE, WILL BE REMOVED IN THE FUTURE.
244
243 Returns the hot keys mask when thinkpad-acpi was loaded. 245 Returns the hot keys mask when thinkpad-acpi was loaded.
244 Upon module unload, the hot keys mask will be restored 246 Upon module unload, the hot keys mask will be restored
245 to this value. 247 to this value. This is always 0x80c, because those are
248 the hotkeys that were supported by ancient firmware
249 without mask support.
246 250
247 hotkey_enable: 251 hotkey_enable:
248 DEPRECATED, WILL BE REMOVED SOON. 252 DEPRECATED, WILL BE REMOVED SOON.
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index e85600852502..955adf67e8f0 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -1601,6 +1601,196 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
1601#endif 1601#endif
1602} 1602}
1603 1603
1604/*************************************************************************
1605 * Firmware Data
1606 */
1607
1608/*
1609 * Table of recommended minimum BIOS versions
1610 *
1611 * Reasons for listing:
1612 * 1. Stable BIOS, listed because the unknown ammount of
1613 * bugs and bad ACPI behaviour on older versions
1614 *
1615 * 2. BIOS or EC fw with known bugs that trigger on Linux
1616 *
1617 * 3. BIOS with known reduced functionality in older versions
1618 *
1619 * We recommend the latest BIOS and EC version.
1620 * We only support the latest BIOS and EC fw version as a rule.
1621 *
1622 * Sources: IBM ThinkPad Public Web Documents (update changelogs),
1623 * Information from users in ThinkWiki
1624 *
1625 * WARNING: we use this table also to detect that the machine is
1626 * a ThinkPad in some cases, so don't remove entries lightly.
1627 */
1628
1629#define TPV_Q(__v, __id1, __id2, __bv1, __bv2) \
1630 { .vendor = (__v), \
1631 .bios = TPID(__id1, __id2), \
1632 .ec = TPACPI_MATCH_ANY, \
1633 .quirks = TPACPI_MATCH_ANY << 16 \
1634 | (__bv1) << 8 | (__bv2) }
1635
1636#define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \
1637 __eid1, __eid2, __ev1, __ev2) \
1638 { .vendor = (__v), \
1639 .bios = TPID(__bid1, __bid2), \
1640 .ec = TPID(__eid1, __eid2), \
1641 .quirks = (__ev1) << 24 | (__ev2) << 16 \
1642 | (__bv1) << 8 | (__bv2) }
1643
1644#define TPV_QI0(__id1, __id2, __bv1, __bv2) \
1645 TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)
1646
1647#define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
1648 TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \
1649 __bv1, __bv2, __id1, __id2, __ev1, __ev2)
1650
1651#define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \
1652 __eid1, __eid2, __ev1, __ev2) \
1653 TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \
1654 __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
1655
1656#define TPV_QL0(__id1, __id2, __bv1, __bv2) \
1657 TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2)
1658
1659#define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
1660 TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \
1661 __bv1, __bv2, __id1, __id2, __ev1, __ev2)
1662
1663#define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \
1664 __eid1, __eid2, __ev1, __ev2) \
1665 TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \
1666 __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
1667
1668static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
1669 /* Numeric models ------------------ */
1670 /* FW MODEL BIOS VERS */
1671 TPV_QI0('I', 'M', '6', '5'), /* 570 */
1672 TPV_QI0('I', 'U', '2', '6'), /* 570E */
1673 TPV_QI0('I', 'B', '5', '4'), /* 600 */
1674 TPV_QI0('I', 'H', '4', '7'), /* 600E */
1675 TPV_QI0('I', 'N', '3', '6'), /* 600E */
1676 TPV_QI0('I', 'T', '5', '5'), /* 600X */
1677 TPV_QI0('I', 'D', '4', '8'), /* 770, 770E, 770ED */
1678 TPV_QI0('I', 'I', '4', '2'), /* 770X */
1679 TPV_QI0('I', 'O', '2', '3'), /* 770Z */
1680
1681 /* A-series ------------------------- */
1682 /* FW MODEL BIOS VERS EC VERS */
1683 TPV_QI0('I', 'W', '5', '9'), /* A20m */
1684 TPV_QI0('I', 'V', '6', '9'), /* A20p */
1685 TPV_QI0('1', '0', '2', '6'), /* A21e, A22e */
1686 TPV_QI0('K', 'U', '3', '6'), /* A21e */
1687 TPV_QI0('K', 'X', '3', '6'), /* A21m, A22m */
1688 TPV_QI0('K', 'Y', '3', '8'), /* A21p, A22p */
1689 TPV_QI0('1', 'B', '1', '7'), /* A22e */
1690 TPV_QI0('1', '3', '2', '0'), /* A22m */
1691 TPV_QI0('1', 'E', '7', '3'), /* A30/p (0) */
1692 TPV_QI1('1', 'G', '4', '1', '1', '7'), /* A31/p (0) */
1693 TPV_QI1('1', 'N', '1', '6', '0', '7'), /* A31/p (0) */
1694
1695 /* G-series ------------------------- */
1696 /* FW MODEL BIOS VERS */
1697 TPV_QI0('1', 'T', 'A', '6'), /* G40 */
1698 TPV_QI0('1', 'X', '5', '7'), /* G41 */
1699
1700 /* R-series, T-series --------------- */
1701 /* FW MODEL BIOS VERS EC VERS */
1702 TPV_QI0('1', 'C', 'F', '0'), /* R30 */
1703 TPV_QI0('1', 'F', 'F', '1'), /* R31 */
1704 TPV_QI0('1', 'M', '9', '7'), /* R32 */
1705 TPV_QI0('1', 'O', '6', '1'), /* R40 */
1706 TPV_QI0('1', 'P', '6', '5'), /* R40 */
1707 TPV_QI0('1', 'S', '7', '0'), /* R40e */
1708 TPV_QI1('1', 'R', 'D', 'R', '7', '1'), /* R50/p, R51,
1709 T40/p, T41/p, T42/p (1) */
1710 TPV_QI1('1', 'V', '7', '1', '2', '8'), /* R50e, R51 (1) */
1711 TPV_QI1('7', '8', '7', '1', '0', '6'), /* R51e (1) */
1712 TPV_QI1('7', '6', '6', '9', '1', '6'), /* R52 (1) */
1713 TPV_QI1('7', '0', '6', '9', '2', '8'), /* R52, T43 (1) */
1714
1715 TPV_QI0('I', 'Y', '6', '1'), /* T20 */
1716 TPV_QI0('K', 'Z', '3', '4'), /* T21 */
1717 TPV_QI0('1', '6', '3', '2'), /* T22 */
1718 TPV_QI1('1', 'A', '6', '4', '2', '3'), /* T23 (0) */
1719 TPV_QI1('1', 'I', '7', '1', '2', '0'), /* T30 (0) */
1720 TPV_QI1('1', 'Y', '6', '5', '2', '9'), /* T43/p (1) */
1721
1722 TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */
1723 TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */
1724 TPV_QL0('7', 'E', 'D', '0'), /* R60e, R60i */
1725
1726 /* BIOS FW BIOS VERS EC FW EC VERS */
1727 TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */
1728 TPV_QL2('7', 'I', '3', '4', '7', '9', '5', '0'), /* T60/p wide */
1729
1730 /* X-series ------------------------- */
1731 /* FW MODEL BIOS VERS EC VERS */
1732 TPV_QI0('I', 'Z', '9', 'D'), /* X20, X21 */
1733 TPV_QI0('1', 'D', '7', '0'), /* X22, X23, X24 */
1734 TPV_QI1('1', 'K', '4', '8', '1', '8'), /* X30 (0) */
1735 TPV_QI1('1', 'Q', '9', '7', '2', '3'), /* X31, X32 (0) */
1736 TPV_QI1('1', 'U', 'D', '3', 'B', '2'), /* X40 (0) */
1737 TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */
1738 TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */
1739
1740 TPV_QL0('7', 'B', 'D', '7'), /* X60/s */
1741 TPV_QL0('7', 'J', '3', '0'), /* X60t */
1742
1743 /* (0) - older versions lack DMI EC fw string and functionality */
1744 /* (1) - older versions known to lack functionality */
1745};
1746
1747#undef TPV_QL1
1748#undef TPV_QL0
1749#undef TPV_QI2
1750#undef TPV_QI1
1751#undef TPV_QI0
1752#undef TPV_Q_X
1753#undef TPV_Q
1754
1755static void __init tpacpi_check_outdated_fw(void)
1756{
1757 unsigned long fwvers;
1758 u16 ec_version, bios_version;
1759
1760 fwvers = tpacpi_check_quirks(tpacpi_bios_version_qtable,
1761 ARRAY_SIZE(tpacpi_bios_version_qtable));
1762
1763 if (!fwvers)
1764 return;
1765
1766 bios_version = fwvers & 0xffffU;
1767 ec_version = (fwvers >> 16) & 0xffffU;
1768
1769 /* note that unknown versions are set to 0x0000 and we use that */
1770 if ((bios_version > thinkpad_id.bios_release) ||
1771 (ec_version > thinkpad_id.ec_release &&
1772 ec_version != TPACPI_MATCH_ANY)) {
1773 /*
1774 * The changelogs would let us track down the exact
1775 * reason, but it is just too much of a pain to track
1776 * it. We only list BIOSes that are either really
1777 * broken, or really stable to begin with, so it is
1778 * best if the user upgrades the firmware anyway.
1779 */
1780 printk(TPACPI_WARN
1781 "WARNING: Outdated ThinkPad BIOS/EC firmware\n");
1782 printk(TPACPI_WARN
1783 "WARNING: This firmware may be missing critical bug "
1784 "fixes and/or important features\n");
1785 }
1786}
1787
1788static bool __init tpacpi_is_fw_known(void)
1789{
1790 return tpacpi_check_quirks(tpacpi_bios_version_qtable,
1791 ARRAY_SIZE(tpacpi_bios_version_qtable)) != 0;
1792}
1793
1604/**************************************************************************** 1794/****************************************************************************
1605 **************************************************************************** 1795 ****************************************************************************
1606 * 1796 *
@@ -1634,6 +1824,7 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
1634 (thinkpad_id.nummodel_str) ? 1824 (thinkpad_id.nummodel_str) ?
1635 thinkpad_id.nummodel_str : "unknown"); 1825 thinkpad_id.nummodel_str : "unknown");
1636 1826
1827 tpacpi_check_outdated_fw();
1637 return 0; 1828 return 0;
1638} 1829}
1639 1830
@@ -1731,16 +1922,42 @@ struct tp_nvram_state {
1731 u8 volume_level; 1922 u8 volume_level;
1732}; 1923};
1733 1924
1925/* kthread for the hotkey poller */
1734static struct task_struct *tpacpi_hotkey_task; 1926static struct task_struct *tpacpi_hotkey_task;
1735static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ 1927
1736static int hotkey_poll_freq = 10; /* Hz */ 1928/* Acquired while the poller kthread is running, use to sync start/stop */
1737static struct mutex hotkey_thread_mutex; 1929static struct mutex hotkey_thread_mutex;
1930
1931/*
1932 * Acquire mutex to write poller control variables.
1933 * Increment hotkey_config_change when changing them.
1934 *
1935 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
1936 */
1738static struct mutex hotkey_thread_data_mutex; 1937static struct mutex hotkey_thread_data_mutex;
1739static unsigned int hotkey_config_change; 1938static unsigned int hotkey_config_change;
1740 1939
1940/*
1941 * hotkey poller control variables
1942 *
1943 * Must be atomic or readers will also need to acquire mutex
1944 */
1945static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */
1946static unsigned int hotkey_poll_freq = 10; /* Hz */
1947
1948#define HOTKEY_CONFIG_CRITICAL_START \
1949 do { \
1950 mutex_lock(&hotkey_thread_data_mutex); \
1951 hotkey_config_change++; \
1952 } while (0);
1953#define HOTKEY_CONFIG_CRITICAL_END \
1954 mutex_unlock(&hotkey_thread_data_mutex);
1955
1741#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1956#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1742 1957
1743#define hotkey_source_mask 0U 1958#define hotkey_source_mask 0U
1959#define HOTKEY_CONFIG_CRITICAL_START
1960#define HOTKEY_CONFIG_CRITICAL_END
1744 1961
1745#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 1962#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1746 1963
@@ -1765,19 +1982,6 @@ static u16 *hotkey_keycode_map;
1765 1982
1766static struct attribute_set *hotkey_dev_attributes; 1983static struct attribute_set *hotkey_dev_attributes;
1767 1984
1768#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
1769#define HOTKEY_CONFIG_CRITICAL_START \
1770 do { \
1771 mutex_lock(&hotkey_thread_data_mutex); \
1772 hotkey_config_change++; \
1773 } while (0);
1774#define HOTKEY_CONFIG_CRITICAL_END \
1775 mutex_unlock(&hotkey_thread_data_mutex);
1776#else
1777#define HOTKEY_CONFIG_CRITICAL_START
1778#define HOTKEY_CONFIG_CRITICAL_END
1779#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
1780
1781/* HKEY.MHKG() return bits */ 1985/* HKEY.MHKG() return bits */
1782#define TP_HOTKEY_TABLET_MASK (1 << 3) 1986#define TP_HOTKEY_TABLET_MASK (1 << 3)
1783 1987
@@ -1822,7 +2026,9 @@ static int hotkey_mask_get(void)
1822 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) 2026 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
1823 return -EIO; 2027 return -EIO;
1824 } 2028 }
2029 HOTKEY_CONFIG_CRITICAL_START
1825 hotkey_mask = m | (hotkey_source_mask & hotkey_mask); 2030 hotkey_mask = m | (hotkey_source_mask & hotkey_mask);
2031 HOTKEY_CONFIG_CRITICAL_END
1826 2032
1827 return 0; 2033 return 0;
1828} 2034}
@@ -2075,6 +2281,7 @@ static int hotkey_kthread(void *data)
2075 unsigned int si, so; 2281 unsigned int si, so;
2076 unsigned long t; 2282 unsigned long t;
2077 unsigned int change_detector, must_reset; 2283 unsigned int change_detector, must_reset;
2284 unsigned int poll_freq;
2078 2285
2079 mutex_lock(&hotkey_thread_mutex); 2286 mutex_lock(&hotkey_thread_mutex);
2080 2287
@@ -2091,12 +2298,17 @@ static int hotkey_kthread(void *data)
2091 mutex_lock(&hotkey_thread_data_mutex); 2298 mutex_lock(&hotkey_thread_data_mutex);
2092 change_detector = hotkey_config_change; 2299 change_detector = hotkey_config_change;
2093 mask = hotkey_source_mask & hotkey_mask; 2300 mask = hotkey_source_mask & hotkey_mask;
2301 poll_freq = hotkey_poll_freq;
2094 mutex_unlock(&hotkey_thread_data_mutex); 2302 mutex_unlock(&hotkey_thread_data_mutex);
2095 hotkey_read_nvram(&s[so], mask); 2303 hotkey_read_nvram(&s[so], mask);
2096 2304
2097 while (!kthread_should_stop() && hotkey_poll_freq) { 2305 while (!kthread_should_stop()) {
2098 if (t == 0) 2306 if (t == 0) {
2099 t = 1000/hotkey_poll_freq; 2307 if (likely(poll_freq))
2308 t = 1000/poll_freq;
2309 else
2310 t = 100; /* should never happen... */
2311 }
2100 t = msleep_interruptible(t); 2312 t = msleep_interruptible(t);
2101 if (unlikely(kthread_should_stop())) 2313 if (unlikely(kthread_should_stop()))
2102 break; 2314 break;
@@ -2112,6 +2324,7 @@ static int hotkey_kthread(void *data)
2112 change_detector = hotkey_config_change; 2324 change_detector = hotkey_config_change;
2113 } 2325 }
2114 mask = hotkey_source_mask & hotkey_mask; 2326 mask = hotkey_source_mask & hotkey_mask;
2327 poll_freq = hotkey_poll_freq;
2115 mutex_unlock(&hotkey_thread_data_mutex); 2328 mutex_unlock(&hotkey_thread_data_mutex);
2116 2329
2117 if (likely(mask)) { 2330 if (likely(mask)) {
@@ -2131,6 +2344,7 @@ exit:
2131 return 0; 2344 return 0;
2132} 2345}
2133 2346
2347/* call with hotkey_mutex held */
2134static void hotkey_poll_stop_sync(void) 2348static void hotkey_poll_stop_sync(void)
2135{ 2349{
2136 if (tpacpi_hotkey_task) { 2350 if (tpacpi_hotkey_task) {
@@ -2147,10 +2361,11 @@ static void hotkey_poll_stop_sync(void)
2147} 2361}
2148 2362
2149/* call with hotkey_mutex held */ 2363/* call with hotkey_mutex held */
2150static void hotkey_poll_setup(int may_warn) 2364static void hotkey_poll_setup(bool may_warn)
2151{ 2365{
2152 if ((hotkey_source_mask & hotkey_mask) != 0 && 2366 u32 hotkeys_to_poll = hotkey_source_mask & hotkey_mask;
2153 hotkey_poll_freq > 0 && 2367
2368 if (hotkeys_to_poll != 0 && hotkey_poll_freq > 0 &&
2154 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 2369 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) {
2155 if (!tpacpi_hotkey_task) { 2370 if (!tpacpi_hotkey_task) {
2156 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 2371 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
@@ -2164,26 +2379,37 @@ static void hotkey_poll_setup(int may_warn)
2164 } 2379 }
2165 } else { 2380 } else {
2166 hotkey_poll_stop_sync(); 2381 hotkey_poll_stop_sync();
2167 if (may_warn && 2382 if (may_warn && hotkeys_to_poll != 0 &&
2168 hotkey_source_mask != 0 && hotkey_poll_freq == 0) { 2383 hotkey_poll_freq == 0) {
2169 printk(TPACPI_NOTICE 2384 printk(TPACPI_NOTICE
2170 "hot keys 0x%08x require polling, " 2385 "hot keys 0x%08x require polling, "
2171 "which is currently disabled\n", 2386 "which is currently disabled\n",
2172 hotkey_source_mask); 2387 hotkeys_to_poll);
2173 } 2388 }
2174 } 2389 }
2175} 2390}
2176 2391
2177static void hotkey_poll_setup_safe(int may_warn) 2392static void hotkey_poll_setup_safe(bool may_warn)
2178{ 2393{
2179 mutex_lock(&hotkey_mutex); 2394 mutex_lock(&hotkey_mutex);
2180 hotkey_poll_setup(may_warn); 2395 hotkey_poll_setup(may_warn);
2181 mutex_unlock(&hotkey_mutex); 2396 mutex_unlock(&hotkey_mutex);
2182} 2397}
2183 2398
2399/* call with hotkey_mutex held */
2400static void hotkey_poll_set_freq(unsigned int freq)
2401{
2402 if (!freq)
2403 hotkey_poll_stop_sync();
2404
2405 HOTKEY_CONFIG_CRITICAL_START
2406 hotkey_poll_freq = freq;
2407 HOTKEY_CONFIG_CRITICAL_END
2408}
2409
2184#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2410#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
2185 2411
2186static void hotkey_poll_setup_safe(int __unused) 2412static void hotkey_poll_setup_safe(bool __unused)
2187{ 2413{
2188} 2414}
2189 2415
@@ -2201,7 +2427,7 @@ static int hotkey_inputdev_open(struct input_dev *dev)
2201 case TPACPI_LIFE_EXITING: 2427 case TPACPI_LIFE_EXITING:
2202 return -EBUSY; 2428 return -EBUSY;
2203 case TPACPI_LIFE_RUNNING: 2429 case TPACPI_LIFE_RUNNING:
2204 hotkey_poll_setup_safe(0); 2430 hotkey_poll_setup_safe(false);
2205 return 0; 2431 return 0;
2206 } 2432 }
2207 2433
@@ -2214,7 +2440,7 @@ static void hotkey_inputdev_close(struct input_dev *dev)
2214{ 2440{
2215 /* disable hotkey polling when possible */ 2441 /* disable hotkey polling when possible */
2216 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) 2442 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING)
2217 hotkey_poll_setup_safe(0); 2443 hotkey_poll_setup_safe(false);
2218} 2444}
2219 2445
2220/* sysfs hotkey enable ------------------------------------------------- */ 2446/* sysfs hotkey enable ------------------------------------------------- */
@@ -2288,7 +2514,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
2288 res = hotkey_mask_set(t); 2514 res = hotkey_mask_set(t);
2289 2515
2290#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2516#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2291 hotkey_poll_setup(1); 2517 hotkey_poll_setup(true);
2292#endif 2518#endif
2293 2519
2294 mutex_unlock(&hotkey_mutex); 2520 mutex_unlock(&hotkey_mutex);
@@ -2318,6 +2544,8 @@ static ssize_t hotkey_bios_mask_show(struct device *dev,
2318 struct device_attribute *attr, 2544 struct device_attribute *attr,
2319 char *buf) 2545 char *buf)
2320{ 2546{
2547 printk_deprecated_attribute("hotkey_bios_mask",
2548 "This attribute is useless.");
2321 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); 2549 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
2322} 2550}
2323 2551
@@ -2377,7 +2605,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2377 hotkey_source_mask = t; 2605 hotkey_source_mask = t;
2378 HOTKEY_CONFIG_CRITICAL_END 2606 HOTKEY_CONFIG_CRITICAL_END
2379 2607
2380 hotkey_poll_setup(1); 2608 hotkey_poll_setup(true);
2609 hotkey_mask_set(hotkey_mask);
2381 2610
2382 mutex_unlock(&hotkey_mutex); 2611 mutex_unlock(&hotkey_mutex);
2383 2612
@@ -2410,9 +2639,9 @@ static ssize_t hotkey_poll_freq_store(struct device *dev,
2410 if (mutex_lock_killable(&hotkey_mutex)) 2639 if (mutex_lock_killable(&hotkey_mutex))
2411 return -ERESTARTSYS; 2640 return -ERESTARTSYS;
2412 2641
2413 hotkey_poll_freq = t; 2642 hotkey_poll_set_freq(t);
2643 hotkey_poll_setup(true);
2414 2644
2415 hotkey_poll_setup(1);
2416 mutex_unlock(&hotkey_mutex); 2645 mutex_unlock(&hotkey_mutex);
2417 2646
2418 tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t); 2647 tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
@@ -2603,7 +2832,9 @@ static void tpacpi_send_radiosw_update(void)
2603static void hotkey_exit(void) 2832static void hotkey_exit(void)
2604{ 2833{
2605#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2834#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2835 mutex_lock(&hotkey_mutex);
2606 hotkey_poll_stop_sync(); 2836 hotkey_poll_stop_sync();
2837 mutex_unlock(&hotkey_mutex);
2607#endif 2838#endif
2608 2839
2609 if (hotkey_dev_attributes) 2840 if (hotkey_dev_attributes)
@@ -2623,6 +2854,15 @@ static void hotkey_exit(void)
2623 } 2854 }
2624} 2855}
2625 2856
2857static void __init hotkey_unmap(const unsigned int scancode)
2858{
2859 if (hotkey_keycode_map[scancode] != KEY_RESERVED) {
2860 clear_bit(hotkey_keycode_map[scancode],
2861 tpacpi_inputdev->keybit);
2862 hotkey_keycode_map[scancode] = KEY_RESERVED;
2863 }
2864}
2865
2626static int __init hotkey_init(struct ibm_init_struct *iibm) 2866static int __init hotkey_init(struct ibm_init_struct *iibm)
2627{ 2867{
2628 /* Requirements for changing the default keymaps: 2868 /* Requirements for changing the default keymaps:
@@ -2701,11 +2941,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2701 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 2941 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
2702 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 2942 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
2703 2943
2704 /* These either have to go through ACPI video, or 2944 /* These should be enabled --only-- when ACPI video
2705 * act like in the IBM ThinkPads, so don't ever 2945 * is disabled (i.e. in "vendor" mode), and are handled
2706 * enable them by default */ 2946 * in a special way by the init code */
2707 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 2947 KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */
2708 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 2948 KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */
2709 2949
2710 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ 2950 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
2711 2951
@@ -2831,19 +3071,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2831 goto err_exit; 3071 goto err_exit;
2832 } 3072 }
2833 3073
2834#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2835 if (tp_features.hotkey_mask) {
2836 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
2837 & ~hotkey_all_mask;
2838 } else {
2839 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
2840 }
2841
2842 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2843 "hotkey source mask 0x%08x, polling freq %d\n",
2844 hotkey_source_mask, hotkey_poll_freq);
2845#endif
2846
2847#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3074#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
2848 if (dbg_wlswemul) { 3075 if (dbg_wlswemul) {
2849 tp_features.hotkey_wlsw = 1; 3076 tp_features.hotkey_wlsw = 1;
@@ -2944,17 +3171,31 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2944 "Disabling thinkpad-acpi brightness events " 3171 "Disabling thinkpad-acpi brightness events "
2945 "by default...\n"); 3172 "by default...\n");
2946 3173
2947 /* The hotkey_reserved_mask change below is not 3174 /* Disable brightness up/down on Lenovo thinkpads when
2948 * necessary while the keys are at KEY_RESERVED in the 3175 * ACPI is handling them, otherwise it is plain impossible
2949 * default map, but better safe than sorry, leave it 3176 * for userspace to do something even remotely sane */
2950 * here as a marker of what we have to do, especially
2951 * when we finally become able to set this at runtime
2952 * on response to X.org requests */
2953 hotkey_reserved_mask |= 3177 hotkey_reserved_mask |=
2954 (1 << TP_ACPI_HOTKEYSCAN_FNHOME) 3178 (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
2955 | (1 << TP_ACPI_HOTKEYSCAN_FNEND); 3179 | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
3180 hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNHOME);
3181 hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNEND);
2956 } 3182 }
2957 3183
3184#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3185 if (tp_features.hotkey_mask) {
3186 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3187 & ~hotkey_all_mask
3188 & ~hotkey_reserved_mask;
3189 } else {
3190 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3191 & ~hotkey_reserved_mask;
3192 }
3193
3194 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3195 "hotkey source mask 0x%08x, polling freq %u\n",
3196 hotkey_source_mask, hotkey_poll_freq);
3197#endif
3198
2958 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3199 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2959 "enabling firmware HKEY event interface...\n"); 3200 "enabling firmware HKEY event interface...\n");
2960 res = hotkey_status_set(true); 3201 res = hotkey_status_set(true);
@@ -2978,7 +3219,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2978 tpacpi_inputdev->open = &hotkey_inputdev_open; 3219 tpacpi_inputdev->open = &hotkey_inputdev_open;
2979 tpacpi_inputdev->close = &hotkey_inputdev_close; 3220 tpacpi_inputdev->close = &hotkey_inputdev_close;
2980 3221
2981 hotkey_poll_setup_safe(1); 3222 hotkey_poll_setup_safe(true);
2982 tpacpi_send_radiosw_update(); 3223 tpacpi_send_radiosw_update();
2983 tpacpi_input_send_tabletsw(); 3224 tpacpi_input_send_tabletsw();
2984 3225
@@ -3266,7 +3507,7 @@ static void hotkey_resume(void)
3266 hotkey_tablet_mode_notify_change(); 3507 hotkey_tablet_mode_notify_change();
3267 hotkey_wakeup_reason_notify_change(); 3508 hotkey_wakeup_reason_notify_change();
3268 hotkey_wakeup_hotunplug_complete_notify_change(); 3509 hotkey_wakeup_hotunplug_complete_notify_change();
3269 hotkey_poll_setup_safe(0); 3510 hotkey_poll_setup_safe(false);
3270} 3511}
3271 3512
3272/* procfs -------------------------------------------------------------- */ 3513/* procfs -------------------------------------------------------------- */
@@ -3338,7 +3579,8 @@ static int hotkey_write(char *buf)
3338 hotkey_enabledisable_warn(0); 3579 hotkey_enabledisable_warn(0);
3339 res = -EPERM; 3580 res = -EPERM;
3340 } else if (strlencmp(cmd, "reset") == 0) { 3581 } else if (strlencmp(cmd, "reset") == 0) {
3341 mask = hotkey_orig_mask; 3582 mask = (hotkey_all_mask | hotkey_source_mask)
3583 & ~hotkey_reserved_mask;
3342 } else if (sscanf(cmd, "0x%x", &mask) == 1) { 3584 } else if (sscanf(cmd, "0x%x", &mask) == 1) {
3343 /* mask set */ 3585 /* mask set */
3344 } else if (sscanf(cmd, "%x", &mask) == 1) { 3586 } else if (sscanf(cmd, "%x", &mask) == 1) {
@@ -5655,16 +5897,16 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
5655 /* Models with ATI GPUs known to require ECNVRAM mode */ 5897 /* Models with ATI GPUs known to require ECNVRAM mode */
5656 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ 5898 TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */
5657 5899
5658 /* Models with ATI GPUs (waiting confirmation) */ 5900 /* Models with ATI GPUs that can use ECNVRAM */
5659 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5901 TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC),
5660 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5902 TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5661 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5903 TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5662 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), 5904 TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
5663 5905
5664 /* Models with Intel Extreme Graphics 2 (waiting confirmation) */ 5906 /* Models with Intel Extreme Graphics 2 */
5907 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC),
5665 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 5908 TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
5666 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), 5909 TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
5667 TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC),
5668 5910
5669 /* Models with Intel GMA900 */ 5911 /* Models with Intel GMA900 */
5670 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ 5912 TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */
@@ -7524,9 +7766,11 @@ static int __init probe_for_thinkpad(void)
7524 7766
7525 /* 7767 /*
7526 * Non-ancient models have better DMI tagging, but very old models 7768 * Non-ancient models have better DMI tagging, but very old models
7527 * don't. 7769 * don't. tpacpi_is_fw_known() is a cheat to help in that case.
7528 */ 7770 */
7529 is_thinkpad = (thinkpad_id.model_str != NULL); 7771 is_thinkpad = (thinkpad_id.model_str != NULL) ||
7772 (thinkpad_id.ec_model != 0) ||
7773 tpacpi_is_fw_known();
7530 7774
7531 /* ec is required because many other handles are relative to it */ 7775 /* ec is required because many other handles are relative to it */
7532 TPACPI_ACPIHANDLE_INIT(ec); 7776 TPACPI_ACPIHANDLE_INIT(ec);
@@ -7537,13 +7781,6 @@ static int __init probe_for_thinkpad(void)
7537 return -ENODEV; 7781 return -ENODEV;
7538 } 7782 }
7539 7783
7540 /*
7541 * Risks a regression on very old machines, but reduces potential
7542 * false positives a damn great deal
7543 */
7544 if (!is_thinkpad)
7545 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
7546
7547 if (!is_thinkpad && !force_load) 7784 if (!is_thinkpad && !force_load)
7548 return -ENODEV; 7785 return -ENODEV;
7549 7786