diff options
Diffstat (limited to 'net/rfkill')
-rw-r--r-- | net/rfkill/core.c | 9 | ||||
-rw-r--r-- | net/rfkill/rfkill-gpio.c | 33 |
2 files changed, 30 insertions, 12 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index c3feb4f49d09..7d3e82e4c2fc 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -539,18 +539,14 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type) #endif bool rfkill_set_hw_state_reason(struct rfkill *rfkill, - bool blocked, unsigned long reason) + bool blocked, + enum rfkill_hard_block_reasons reason) { unsigned long flags; bool ret, prev; BUG_ON(!rfkill); - if (WARN(reason & - ~(RFKILL_HARD_BLOCK_SIGNAL | RFKILL_HARD_BLOCK_NOT_OWNER), - "hw_state reason not supported: 0x%lx", reason)) - return blocked; - spin_lock_irqsave(&rfkill->lock, flags); prev = !!(rfkill->hard_block_reasons & reason); if (blocked) { @@ -1398,7 +1394,6 @@ static const struct file_operations rfkill_fops = { .release = rfkill_fop_release, .unlocked_ioctl = rfkill_fop_ioctl, .compat_ioctl = compat_ptr_ioctl, - .llseek = no_llseek, }; #define RFKILL_NAME "rfkill" diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 4e32d659524e..41e657e97761 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c @@ -3,6 +3,7 @@ * Copyright (c) 2011, NVIDIA Corporation. */ +#include <linux/dmi.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> @@ -31,8 +32,12 @@ static int rfkill_gpio_set_power(void *data, bool blocked) { struct rfkill_gpio_data *rfkill = data; - if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) - clk_enable(rfkill->clk); + if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) { + int ret = clk_enable(rfkill->clk); + + if (ret) + return ret; + } gpiod_set_value_cansleep(rfkill->shutdown_gpio, !blocked); gpiod_set_value_cansleep(rfkill->reset_gpio, !blocked); @@ -72,6 +77,20 @@ static int rfkill_gpio_acpi_probe(struct device *dev, return devm_acpi_dev_add_driver_gpios(dev, acpi_rfkill_default_gpios); } +/* List of DMI matches for devices on which rfkill-gpio should not load, + * to avoid firmware bugs. + */ +static const struct dmi_system_id rfkill_gpio_deny_table[] = { + { + /* Lenovo Yoga Tab 3 Pro YT3-X90, bogus "BCM4752" device in DSDT */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), + }, + }, + { } +}; + static int rfkill_gpio_probe(struct platform_device *pdev) { struct rfkill_gpio_data *rfkill; @@ -81,6 +100,9 @@ static int rfkill_gpio_probe(struct platform_device *pdev) const char *type_name; int ret; + if (dmi_check_system(rfkill_gpio_deny_table)) + return -ENODEV; + rfkill = devm_kzalloc(&pdev->dev, sizeof(*rfkill), GFP_KERNEL); if (!rfkill) return -ENOMEM; @@ -140,6 +162,9 @@ static int rfkill_gpio_probe(struct platform_device *pdev) if (!rfkill->rfkill_dev) return -ENOMEM; + if (device_property_present(&pdev->dev, "default-blocked")) + rfkill_init_sw_state(rfkill->rfkill_dev, true); + ret = rfkill_register(rfkill->rfkill_dev); if (ret < 0) goto err_destroy; @@ -156,14 +181,12 @@ err_destroy: return ret; } -static int rfkill_gpio_remove(struct platform_device *pdev) +static void rfkill_gpio_remove(struct platform_device *pdev) { struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev); rfkill_unregister(rfkill->rfkill_dev); rfkill_destroy(rfkill->rfkill_dev); - - return 0; } #ifdef CONFIG_ACPI |