summaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorMario Limonciello <mario.limonciello@dell.com>2017-11-09 12:49:10 -0500
committerDarren Hart (VMware) <dvhart@infradead.org>2017-11-16 20:45:26 -0500
commit868b8d33f91e431b1961a35baa6b5022639067f3 (patch)
treea49852abaa758657c61145842cfd73094f0bd3e9 /drivers/platform
parent8b9528a6d9a901b9f933231505fef5630e80ce5a (diff)
platform/x86: dell-*wmi*: Relay failed initial probe to dependent drivers
dell-wmi and dell-smbios-wmi are dependent upon dell-wmi-descriptor finishing probe successfully to probe themselves. Currently if dell-wmi-descriptor fails probing in a non-recoverable way (such as invalid header) dell-wmi and dell-smbios-wmi will continue to try to redo probing due to deferred probing. To solve this have the dependent drivers query the dell-wmi-descriptor driver whether the descriptor has been determined valid. The possible results are: -ENODEV: Descriptor GUID missing from WMI bus -EPROBE_DEFER: Descriptor not yet probed, dependent driver should wait and use deferred probing < 0: Descriptor probed, invalid. Dependent driver should return an error. 0: Successful descriptor probe, dependent driver can continue Successful descriptor probe still doesn't mean that the descriptor driver is necessarily bound at the time of initialization of dependent driver. Userspace can unbind the driver, so all methods used from driver should still be verified to return success values otherwise deferred probing be used. Signed-off-by: Mario Limonciello <mario.limonciello@dell.com> Reviewed-by: Pali Rohár <pali.rohar@gmail.com> Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/dell-smbios-wmi.c5
-rw-r--r--drivers/platform/x86/dell-wmi-descriptor.c16
-rw-r--r--drivers/platform/x86/dell-wmi-descriptor.h8
-rw-r--r--drivers/platform/x86/dell-wmi.c6
4 files changed, 30 insertions, 5 deletions
diff --git a/drivers/platform/x86/dell-smbios-wmi.c b/drivers/platform/x86/dell-smbios-wmi.c
index 5cf9b13ce6e6..0cab1f9c35af 100644
--- a/drivers/platform/x86/dell-smbios-wmi.c
+++ b/drivers/platform/x86/dell-smbios-wmi.c
@@ -151,8 +151,9 @@ static int dell_smbios_wmi_probe(struct wmi_device *wdev)
151 int count; 151 int count;
152 int ret; 152 int ret;
153 153
154 if (!wmi_has_guid(DELL_WMI_DESCRIPTOR_GUID)) 154 ret = dell_wmi_get_descriptor_valid();
155 return -ENODEV; 155 if (ret)
156 return ret;
156 157
157 priv = devm_kzalloc(&wdev->dev, sizeof(struct wmi_smbios_priv), 158 priv = devm_kzalloc(&wdev->dev, sizeof(struct wmi_smbios_priv),
158 GFP_KERNEL); 159 GFP_KERNEL);
diff --git a/drivers/platform/x86/dell-wmi-descriptor.c b/drivers/platform/x86/dell-wmi-descriptor.c
index 28ef5f37cfbf..4dfef1f53481 100644
--- a/drivers/platform/x86/dell-wmi-descriptor.c
+++ b/drivers/platform/x86/dell-wmi-descriptor.c
@@ -21,14 +21,26 @@
21#include <linux/wmi.h> 21#include <linux/wmi.h>
22#include "dell-wmi-descriptor.h" 22#include "dell-wmi-descriptor.h"
23 23
24#define DELL_WMI_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492"
25
24struct descriptor_priv { 26struct descriptor_priv {
25 struct list_head list; 27 struct list_head list;
26 u32 interface_version; 28 u32 interface_version;
27 u32 size; 29 u32 size;
28}; 30};
31static int descriptor_valid = -EPROBE_DEFER;
29static LIST_HEAD(wmi_list); 32static LIST_HEAD(wmi_list);
30static DEFINE_MUTEX(list_mutex); 33static DEFINE_MUTEX(list_mutex);
31 34
35int dell_wmi_get_descriptor_valid(void)
36{
37 if (!wmi_has_guid(DELL_WMI_DESCRIPTOR_GUID))
38 return -ENODEV;
39
40 return descriptor_valid;
41}
42EXPORT_SYMBOL_GPL(dell_wmi_get_descriptor_valid);
43
32bool dell_wmi_get_interface_version(u32 *version) 44bool dell_wmi_get_interface_version(u32 *version)
33{ 45{
34 struct descriptor_priv *priv; 46 struct descriptor_priv *priv;
@@ -91,6 +103,7 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
91 if (obj->type != ACPI_TYPE_BUFFER) { 103 if (obj->type != ACPI_TYPE_BUFFER) {
92 dev_err(&wdev->dev, "Dell descriptor has wrong type\n"); 104 dev_err(&wdev->dev, "Dell descriptor has wrong type\n");
93 ret = -EINVAL; 105 ret = -EINVAL;
106 descriptor_valid = ret;
94 goto out; 107 goto out;
95 } 108 }
96 109
@@ -102,6 +115,7 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
102 "Dell descriptor buffer has unexpected length (%d)\n", 115 "Dell descriptor buffer has unexpected length (%d)\n",
103 obj->buffer.length); 116 obj->buffer.length);
104 ret = -EINVAL; 117 ret = -EINVAL;
118 descriptor_valid = ret;
105 goto out; 119 goto out;
106 } 120 }
107 121
@@ -111,8 +125,10 @@ static int dell_wmi_descriptor_probe(struct wmi_device *wdev)
111 dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%8ph)\n", 125 dev_err(&wdev->dev, "Dell descriptor buffer has invalid signature (%8ph)\n",
112 buffer); 126 buffer);
113 ret = -EINVAL; 127 ret = -EINVAL;
128 descriptor_valid = ret;
114 goto out; 129 goto out;
115 } 130 }
131 descriptor_valid = 0;
116 132
117 if (buffer[2] != 0 && buffer[2] != 1) 133 if (buffer[2] != 0 && buffer[2] != 1)
118 dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%lu)\n", 134 dev_warn(&wdev->dev, "Dell descriptor buffer has unknown version (%lu)\n",
diff --git a/drivers/platform/x86/dell-wmi-descriptor.h b/drivers/platform/x86/dell-wmi-descriptor.h
index 5f7b69c2c83a..1e8cb96ffd78 100644
--- a/drivers/platform/x86/dell-wmi-descriptor.h
+++ b/drivers/platform/x86/dell-wmi-descriptor.h
@@ -13,7 +13,13 @@
13 13
14#include <linux/wmi.h> 14#include <linux/wmi.h>
15 15
16#define DELL_WMI_DESCRIPTOR_GUID "8D9DDCBC-A997-11DA-B012-B622A1EF5492" 16/* possible return values:
17 * -ENODEV: Descriptor GUID missing from WMI bus
18 * -EPROBE_DEFER: probing for dell-wmi-descriptor not yet run
19 * 0: valid descriptor, successfully probed
20 * < 0: invalid descriptor, don't probe dependent devices
21 */
22int dell_wmi_get_descriptor_valid(void);
17 23
18bool dell_wmi_get_interface_version(u32 *version); 24bool dell_wmi_get_interface_version(u32 *version);
19bool dell_wmi_get_size(u32 *size); 25bool dell_wmi_get_size(u32 *size);
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index 54321080a30d..39d2f4518483 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -655,9 +655,11 @@ static int dell_wmi_events_set_enabled(bool enable)
655static int dell_wmi_probe(struct wmi_device *wdev) 655static int dell_wmi_probe(struct wmi_device *wdev)
656{ 656{
657 struct dell_wmi_priv *priv; 657 struct dell_wmi_priv *priv;
658 int ret;
658 659
659 if (!wmi_has_guid(DELL_WMI_DESCRIPTOR_GUID)) 660 ret = dell_wmi_get_descriptor_valid();
660 return -ENODEV; 661 if (ret)
662 return ret;
661 663
662 priv = devm_kzalloc( 664 priv = devm_kzalloc(
663 &wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL); 665 &wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);