/* * This module provides an interface to trigger and test firmware loading. * * It is designed to be used for basic evaluation of the firmware loading * subsystem (for example when validating firmware verification). It lacks * any extra dependencies, and will not normally be loaded by the system * unless explicitly requested by name. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include #include #include #include #include #include #include #include static DEFINE_MUTEX(test_fw_mutex); static const struct firmware *test_firmware; static ssize_t test_fw_misc_read(struct file *f, char __user *buf, size_t size, loff_t *offset) { ssize_t rc = 0; mutex_lock(&test_fw_mutex); if (test_firmware) rc = simple_read_from_buffer(buf, size, offset, test_firmware->data, test_firmware->size); mutex_unlock(&test_fw_mutex); return rc; } static const struct file_operations test_fw_fops = { .owner = THIS_MODULE, .read = test_fw_misc_read, }; static struct miscdevice test_fw_misc_device = { .minor = MISC_DYNAMIC_MINOR, .name = "test_firmware", .fops = &test_fw_fops, }; static ssize_t trigger_request_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc; char *name; name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOSPC; pr_info("loading '%s'\n", name); mutex_lock(&test_fw_mutex); release_firmware(test_firmware); test_firmware = NULL; rc = request_firmware(&test_firmware, name, dev); if (rc) { pr_info("load of '%s' failed: %d\n", name, rc); goto out; } pr_info("loaded: %zu\n", test_firmware->size); rc = count; out: mutex_unlock(&test_fw_mutex); kfree(name); return rc; } static DEVICE_ATTR_WO(trigger_request); static DECLARE_COMPLETION(async_fw_done); static void trigger_async_request_cb(const struct firmware *fw, void *context) { test_firmware = fw; complete(&async_fw_done); } static ssize_t trigger_async_request_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc; char *name; name = kstrndup(buf, count, GFP_KERNEL); if (!name) return -ENOSPC; pr_info("loading '%s'\n", name); mutex_lock(&test_fw_mutex); release_firmware(test_firmware); test_firmware = NULL; rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL, NULL, trigger_async_request_cb); if (rc) { pr_info("async load of '%s' failed: %d\n", name, rc); kfree(name); goto out; } /* Free 'name' ASAP, to test for race conditions */ kfree(name); wait_for_completion(&async_fw_done); if (test_firmware) { pr_info("loaded: %zu\n", test_firmware->size); rc = count; } else { pr_err("failed to async load firmware\n"); rc = -ENODEV; } out: mutex_unlock(&test_fw_mutex); return rc; } static DEVICE_ATTR_WO(trigger_async_request); static int __init test_firmware_init(void) { int rc; rc = misc_register(&test_fw_misc_device); if (rc) { pr_err("could not register misc device: %d\n", rc); return rc; } rc = device_create_file(test_fw_misc_device.this_device, &dev_attr_trigger_request); if (rc) { pr_err("could not create sysfs interface: %d\n", rc); goto dereg; } rc = device_create_file(test_fw_misc_device.this_device, &dev_attr_trigger_async_request); if (rc) { pr_err("could not create async sysfs interface: %d\n", rc); goto remove_file; } pr_warn("interface ready\n"); return 0; remove_file: device_remove_file(test_fw_misc_device.this_device, &dev_attr_trigger_async_request); dereg: misc_deregister(&test_fw_misc_device); return rc; } module_init(test_firmware_init); static void __exit test_firmware_exit(void) { release_firmware(test_firmware); device_remove_file(test_fw_misc_device.this_device, &dev_attr_trigger_async_request); device_remove_file(test_fw_misc_device.this_device, &dev_attr_trigger_request); misc_deregister(&test_fw_misc_device); pr_warn("removed interface\n"); } module_exit(test_firmware_exit); MODULE_AUTHOR("Kees Cook "); MODULE_LICENSE("GPL"); ' onchange='this.form.submit();'>
authorJerome Brunet <jbrunet@baylibre.com>2017-01-20 08:20:24 -0800
committerArnd Bergmann <arnd@arndb.de>2017-01-27 16:46:42 +0100
commitfeb3cbea0946c67060e2d5bcb7499b0a6f6700fe (patch)
tree4789978854a7fd97de08f4b77f220bcd9278417b /sound/core/seq/seq_midi.c
parent7a308bb3016f57e5be11a677d15b821536419d36 (diff)
ARM64: dts: meson-gxbb-odroidc2: fix GbE tx link breakage
OdroidC2 GbE link breaks under heavy tx transfer. This happens even if the MAC does not enable Energy Efficient Ethernet (No Low Power state Idle on the Tx path). The problem seems to come from the phy Rx path, entering the LPI state. Disabling EEE advertisement on the phy prevent this feature to be negociated with the link partner and solve the issue. Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Signed-off-by: Kevin Hilman <khilman@baylibre.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'sound/core/seq/seq_midi.c')