aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
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 /drivers/platform
parent003d6a38ce1a59e0053a02fd9e9a65b588bc8e33 (diff)
parentde4c8cc7bddd9c43dc1b85517ab445ffa8163058 (diff)
Merge branch 'thinkpad' into release
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c381
1 files changed, 309 insertions, 72 deletions
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