aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-11 00:19:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-11 00:19:06 -0400
commitf007cad159e99fa2acd3b2e9364fbb32ad28b971 (patch)
tree3347b090b27c27082414070a9cbf08a7bb75cbc6 /drivers/base/firmware_class.c
parent64414e5f9896805c2e80583345e9b1745be73aa9 (diff)
Revert "firmware: add sanity check on shutdown/suspend"
This reverts commit 81f95076281fdd3bc382e004ba1bce8e82fccbce. It causes random failures of firmware loading at resume time (well, random for me, it seems to be more reliable for others) because the firmware disabling is not actually synchronous with any particular resume event, and at least the btusb driver that uses a workqueue to load the firmware at resume seems to occasionally hit the "firmware loading is disabled" logic because the firmware loader hasn't gotten the resume event yet. Some kind of sanity check for not trying to load firmware when it's not possible might be a good thing, but this commit was not it. Greg seems to have silently suffered the same issue, and pointed to the likely culprit, and Gabriel C verified the revert fixed it for him too. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Pointed-at-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Tested-by: Gabriel C <nix.or.die@gmail.com> Cc: Luis R. Rodriguez <mcgrof@kernel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c99
1 files changed, 0 insertions, 99 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index a5fb884a136d..4b57cf5bc81d 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -258,38 +258,6 @@ static int fw_cache_piggyback_on_request(const char *name);
258 * guarding for corner cases a global lock should be OK */ 258 * guarding for corner cases a global lock should be OK */
259static DEFINE_MUTEX(fw_lock); 259static DEFINE_MUTEX(fw_lock);
260 260
261static bool __enable_firmware = false;
262
263static void enable_firmware(void)
264{
265 mutex_lock(&fw_lock);
266 __enable_firmware = true;
267 mutex_unlock(&fw_lock);
268}
269
270static void disable_firmware(void)
271{
272 mutex_lock(&fw_lock);
273 __enable_firmware = false;
274 mutex_unlock(&fw_lock);
275}
276
277/*
278 * When disabled only the built-in firmware and the firmware cache will be
279 * used to look for firmware.
280 */
281static bool firmware_enabled(void)
282{
283 bool enabled = false;
284
285 mutex_lock(&fw_lock);
286 if (__enable_firmware)
287 enabled = true;
288 mutex_unlock(&fw_lock);
289
290 return enabled;
291}
292
293static struct firmware_cache fw_cache; 261static struct firmware_cache fw_cache;
294 262
295static struct firmware_buf *__allocate_fw_buf(const char *fw_name, 263static struct firmware_buf *__allocate_fw_buf(const char *fw_name,
@@ -1246,12 +1214,6 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
1246 if (ret <= 0) /* error or already assigned */ 1214 if (ret <= 0) /* error or already assigned */
1247 goto out; 1215 goto out;
1248 1216
1249 if (!firmware_enabled()) {
1250 WARN(1, "firmware request while host is not available\n");
1251 ret = -EHOSTDOWN;
1252 goto out;
1253 }
1254
1255 ret = fw_get_filesystem_firmware(device, fw->priv); 1217 ret = fw_get_filesystem_firmware(device, fw->priv);
1256 if (ret) { 1218 if (ret) {
1257 if (!(opt_flags & FW_OPT_NO_WARN)) 1219 if (!(opt_flags & FW_OPT_NO_WARN))
@@ -1762,62 +1724,6 @@ static void device_uncache_fw_images_delay(unsigned long delay)
1762 msecs_to_jiffies(delay)); 1724 msecs_to_jiffies(delay));
1763} 1725}
1764 1726
1765/**
1766 * fw_pm_notify - notifier for suspend/resume
1767 * @notify_block: unused
1768 * @mode: mode we are switching to
1769 * @unused: unused
1770 *
1771 * Used to modify the firmware_class state as we move in between states.
1772 * The firmware_class implements a firmware cache to enable device driver
1773 * to fetch firmware upon resume before the root filesystem is ready. We
1774 * disable API calls which do not use the built-in firmware or the firmware
1775 * cache when we know these calls will not work.
1776 *
1777 * The inner logic behind all this is a bit complex so it is worth summarizing
1778 * the kernel's own suspend/resume process with context and focus on how this
1779 * can impact the firmware API.
1780 *
1781 * First a review on how we go to suspend::
1782 *
1783 * pm_suspend() --> enter_state() -->
1784 * sys_sync()
1785 * suspend_prepare() -->
1786 * __pm_notifier_call_chain(PM_SUSPEND_PREPARE, ...);
1787 * suspend_freeze_processes() -->
1788 * freeze_processes() -->
1789 * __usermodehelper_set_disable_depth(UMH_DISABLED);
1790 * freeze all tasks ...
1791 * freeze_kernel_threads()
1792 * suspend_devices_and_enter() -->
1793 * dpm_suspend_start() -->
1794 * dpm_prepare()
1795 * dpm_suspend()
1796 * suspend_enter() -->
1797 * platform_suspend_prepare()
1798 * dpm_suspend_late()
1799 * freeze_enter()
1800 * syscore_suspend()
1801 *
1802 * When we resume we bail out of a loop from suspend_devices_and_enter() and
1803 * unwind back out to the caller enter_state() where we were before as follows::
1804 *
1805 * enter_state() -->
1806 * suspend_devices_and_enter() --> (bail from loop)
1807 * dpm_resume_end() -->
1808 * dpm_resume()
1809 * dpm_complete()
1810 * suspend_finish() -->
1811 * suspend_thaw_processes() -->
1812 * thaw_processes() -->
1813 * __usermodehelper_set_disable_depth(UMH_FREEZING);
1814 * thaw_workqueues();
1815 * thaw all processes ...
1816 * usermodehelper_enable();
1817 * pm_notifier_call_chain(PM_POST_SUSPEND);
1818 *
1819 * fw_pm_notify() works through pm_notifier_call_chain().
1820 */
1821static int fw_pm_notify(struct notifier_block *notify_block, 1727static int fw_pm_notify(struct notifier_block *notify_block,
1822 unsigned long mode, void *unused) 1728 unsigned long mode, void *unused)
1823{ 1729{
@@ -1831,7 +1737,6 @@ static int fw_pm_notify(struct notifier_block *notify_block,
1831 */ 1737 */
1832 kill_pending_fw_fallback_reqs(true); 1738 kill_pending_fw_fallback_reqs(true);
1833 device_cache_fw_images(); 1739 device_cache_fw_images();
1834 disable_firmware();
1835 break; 1740 break;
1836 1741
1837 case PM_POST_SUSPEND: 1742 case PM_POST_SUSPEND:
@@ -1844,7 +1749,6 @@ static int fw_pm_notify(struct notifier_block *notify_block,
1844 mutex_lock(&fw_lock); 1749 mutex_lock(&fw_lock);
1845 fw_cache.state = FW_LOADER_NO_CACHE; 1750 fw_cache.state = FW_LOADER_NO_CACHE;
1846 mutex_unlock(&fw_lock); 1751 mutex_unlock(&fw_lock);
1847 enable_firmware();
1848 1752
1849 device_uncache_fw_images_delay(10 * MSEC_PER_SEC); 1753 device_uncache_fw_images_delay(10 * MSEC_PER_SEC);
1850 break; 1754 break;
@@ -1893,7 +1797,6 @@ static void __init fw_cache_init(void)
1893static int fw_shutdown_notify(struct notifier_block *unused1, 1797static int fw_shutdown_notify(struct notifier_block *unused1,
1894 unsigned long unused2, void *unused3) 1798 unsigned long unused2, void *unused3)
1895{ 1799{
1896 disable_firmware();
1897 /* 1800 /*
1898 * Kill all pending fallback requests to avoid both stalling shutdown, 1801 * Kill all pending fallback requests to avoid both stalling shutdown,
1899 * and avoid a deadlock with the usermode_lock. 1802 * and avoid a deadlock with the usermode_lock.
@@ -1909,7 +1812,6 @@ static struct notifier_block fw_shutdown_nb = {
1909 1812
1910static int __init firmware_class_init(void) 1813static int __init firmware_class_init(void)
1911{ 1814{
1912 enable_firmware();
1913 fw_cache_init(); 1815 fw_cache_init();
1914 register_reboot_notifier(&fw_shutdown_nb); 1816 register_reboot_notifier(&fw_shutdown_nb);
1915#ifdef CONFIG_FW_LOADER_USER_HELPER 1817#ifdef CONFIG_FW_LOADER_USER_HELPER
@@ -1921,7 +1823,6 @@ static int __init firmware_class_init(void)
1921 1823
1922static void __exit firmware_class_exit(void) 1824static void __exit firmware_class_exit(void)
1923{ 1825{
1924 disable_firmware();
1925#ifdef CONFIG_PM_SLEEP 1826#ifdef CONFIG_PM_SLEEP
1926 unregister_syscore_ops(&fw_syscore_ops); 1827 unregister_syscore_ops(&fw_syscore_ops);
1927 unregister_pm_notifier(&fw_cache.pm_notify); 1828 unregister_pm_notifier(&fw_cache.pm_notify);