Commit b3337a6c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'platform-drivers-x86-v4.16-6' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform driver fixes from Darren Hart:
 "Correct a module loading race condition between the DELL_SMBIOS
  backend modules and the first user by converting them to bool features
  of the DELL_SMBIOS driver. Fixup the resulting Kconfig dependency
  issue with DCDBAS"

* tag 'platform-drivers-x86-v4.16-6' of git://git.infradead.org/linux-platform-drivers-x86:
  platform/x86: dell-smbios: Resolve dependency error on DCDBAS
  platform/x86: Allow for SMBIOS backend defaults
  platform/x86: dell-smbios: Link all dell-smbios-* modules together
  platform/x86: dell-smbios: Rename dell-smbios source to dell-smbios-base
  platform/x86: dell-smbios: Correct some style warnings
parents cdb06e9d 32d7b19b
...@@ -105,31 +105,44 @@ config ASUS_LAPTOP ...@@ -105,31 +105,44 @@ config ASUS_LAPTOP
If you have an ACPI-compatible ASUS laptop, say Y or M here. If you have an ACPI-compatible ASUS laptop, say Y or M here.
#
# If the DELL_SMBIOS_SMM feature is enabled, the DELL_SMBIOS driver
# becomes dependent on the DCDBAS driver. The "depends" line prevents a
# configuration where DELL_SMBIOS=y while DCDBAS=m.
#
config DELL_SMBIOS config DELL_SMBIOS
tristate tristate "Dell SMBIOS driver"
depends on DCDBAS || DCDBAS=n
---help---
This provides support for the Dell SMBIOS calling interface.
If you have a Dell computer you should enable this option.
Be sure to select at least one backend for it to work properly.
config DELL_SMBIOS_WMI config DELL_SMBIOS_WMI
tristate "Dell SMBIOS calling interface (WMI implementation)" bool "Dell SMBIOS driver WMI backend"
default y
depends on ACPI_WMI depends on ACPI_WMI
select DELL_WMI_DESCRIPTOR select DELL_WMI_DESCRIPTOR
select DELL_SMBIOS depends on DELL_SMBIOS
---help--- ---help---
This provides an implementation for the Dell SMBIOS calling interface This provides an implementation for the Dell SMBIOS calling interface
communicated over ACPI-WMI. communicated over ACPI-WMI.
If you have a Dell computer from >2007 you should say Y or M here. If you have a Dell computer from >2007 you should say Y here.
If you aren't sure and this module doesn't work for your computer If you aren't sure and this module doesn't work for your computer
it just won't load. it just won't load.
config DELL_SMBIOS_SMM config DELL_SMBIOS_SMM
tristate "Dell SMBIOS calling interface (SMM implementation)" bool "Dell SMBIOS driver SMM backend"
default y
depends on DCDBAS depends on DCDBAS
select DELL_SMBIOS depends on DELL_SMBIOS
---help--- ---help---
This provides an implementation for the Dell SMBIOS calling interface This provides an implementation for the Dell SMBIOS calling interface
communicated over SMI/SMM. communicated over SMI/SMM.
If you have a Dell computer from <=2017 you should say Y or M here. If you have a Dell computer from <=2017 you should say Y here.
If you aren't sure and this module doesn't work for your computer If you aren't sure and this module doesn't work for your computer
it just won't load. it just won't load.
......
...@@ -13,8 +13,9 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o ...@@ -13,8 +13,9 @@ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
obj-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o dell-smbios-objs := dell-smbios-base.o
obj-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o
......
...@@ -36,7 +36,7 @@ static DEFINE_MUTEX(smbios_mutex); ...@@ -36,7 +36,7 @@ static DEFINE_MUTEX(smbios_mutex);
struct smbios_device { struct smbios_device {
struct list_head list; struct list_head list;
struct device *device; struct device *device;
int (*call_fn)(struct calling_interface_buffer *); int (*call_fn)(struct calling_interface_buffer *arg);
}; };
struct smbios_call { struct smbios_call {
...@@ -352,8 +352,10 @@ static void __init parse_da_table(const struct dmi_header *dm) ...@@ -352,8 +352,10 @@ static void __init parse_da_table(const struct dmi_header *dm)
struct calling_interface_structure *table = struct calling_interface_structure *table =
container_of(dm, struct calling_interface_structure, header); container_of(dm, struct calling_interface_structure, header);
/* 4 bytes of table header, plus 7 bytes of Dell header, plus at least /*
6 bytes of entry */ * 4 bytes of table header, plus 7 bytes of Dell header
* plus at least 6 bytes of entry
*/
if (dm->length < 17) if (dm->length < 17)
return; return;
...@@ -554,7 +556,7 @@ static void free_group(struct platform_device *pdev) ...@@ -554,7 +556,7 @@ static void free_group(struct platform_device *pdev)
static int __init dell_smbios_init(void) static int __init dell_smbios_init(void)
{ {
const struct dmi_device *valid; const struct dmi_device *valid;
int ret; int ret, wmi, smm;
valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL); valid = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL);
if (!valid) { if (!valid) {
...@@ -589,8 +591,24 @@ static int __init dell_smbios_init(void) ...@@ -589,8 +591,24 @@ static int __init dell_smbios_init(void)
if (ret) if (ret)
goto fail_create_group; goto fail_create_group;
/* register backends */
wmi = init_dell_smbios_wmi();
if (wmi)
pr_debug("Failed to initialize WMI backend: %d\n", wmi);
smm = init_dell_smbios_smm();
if (smm)
pr_debug("Failed to initialize SMM backend: %d\n", smm);
if (wmi && smm) {
pr_err("No SMBIOS backends available (wmi: %d, smm: %d)\n",
wmi, smm);
goto fail_sysfs;
}
return 0; return 0;
fail_sysfs:
free_group(platform_device);
fail_create_group: fail_create_group:
platform_device_del(platform_device); platform_device_del(platform_device);
...@@ -607,6 +625,8 @@ static int __init dell_smbios_init(void) ...@@ -607,6 +625,8 @@ static int __init dell_smbios_init(void)
static void __exit dell_smbios_exit(void) static void __exit dell_smbios_exit(void)
{ {
exit_dell_smbios_wmi();
exit_dell_smbios_smm();
mutex_lock(&smbios_mutex); mutex_lock(&smbios_mutex);
if (platform_device) { if (platform_device) {
free_group(platform_device); free_group(platform_device);
...@@ -623,5 +643,6 @@ module_exit(dell_smbios_exit); ...@@ -623,5 +643,6 @@ module_exit(dell_smbios_exit);
MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS"); MODULE_DESCRIPTION("Common functions for kernel modules using Dell SMBIOS");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -58,7 +58,7 @@ static const struct dmi_system_id dell_device_table[] __initconst = { ...@@ -58,7 +58,7 @@ static const struct dmi_system_id dell_device_table[] __initconst = {
}; };
MODULE_DEVICE_TABLE(dmi, dell_device_table); MODULE_DEVICE_TABLE(dmi, dell_device_table);
static void __init parse_da_table(const struct dmi_header *dm) static void parse_da_table(const struct dmi_header *dm)
{ {
struct calling_interface_structure *table = struct calling_interface_structure *table =
container_of(dm, struct calling_interface_structure, header); container_of(dm, struct calling_interface_structure, header);
...@@ -73,7 +73,7 @@ static void __init parse_da_table(const struct dmi_header *dm) ...@@ -73,7 +73,7 @@ static void __init parse_da_table(const struct dmi_header *dm)
da_command_code = table->cmdIOCode; da_command_code = table->cmdIOCode;
} }
static void __init find_cmd_address(const struct dmi_header *dm, void *dummy) static void find_cmd_address(const struct dmi_header *dm, void *dummy)
{ {
switch (dm->type) { switch (dm->type) {
case 0xda: /* Calling interface */ case 0xda: /* Calling interface */
...@@ -128,7 +128,7 @@ static bool test_wsmt_enabled(void) ...@@ -128,7 +128,7 @@ static bool test_wsmt_enabled(void)
return false; return false;
} }
static int __init dell_smbios_smm_init(void) int init_dell_smbios_smm(void)
{ {
int ret; int ret;
/* /*
...@@ -176,7 +176,7 @@ static int __init dell_smbios_smm_init(void) ...@@ -176,7 +176,7 @@ static int __init dell_smbios_smm_init(void)
return ret; return ret;
} }
static void __exit dell_smbios_smm_exit(void) void exit_dell_smbios_smm(void)
{ {
if (platform_device) { if (platform_device) {
dell_smbios_unregister_device(&platform_device->dev); dell_smbios_unregister_device(&platform_device->dev);
...@@ -184,13 +184,3 @@ static void __exit dell_smbios_smm_exit(void) ...@@ -184,13 +184,3 @@ static void __exit dell_smbios_smm_exit(void)
free_page((unsigned long)buffer); free_page((unsigned long)buffer);
} }
} }
subsys_initcall(dell_smbios_smm_init);
module_exit(dell_smbios_smm_exit);
MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>");
MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
MODULE_DESCRIPTION("Dell SMBIOS communications over SMI");
MODULE_LICENSE("GPL");
...@@ -228,7 +228,7 @@ static const struct wmi_device_id dell_smbios_wmi_id_table[] = { ...@@ -228,7 +228,7 @@ static const struct wmi_device_id dell_smbios_wmi_id_table[] = {
{ }, { },
}; };
static void __init parse_b1_table(const struct dmi_header *dm) static void parse_b1_table(const struct dmi_header *dm)
{ {
struct misc_bios_flags_structure *flags = struct misc_bios_flags_structure *flags =
container_of(dm, struct misc_bios_flags_structure, header); container_of(dm, struct misc_bios_flags_structure, header);
...@@ -242,7 +242,7 @@ static void __init parse_b1_table(const struct dmi_header *dm) ...@@ -242,7 +242,7 @@ static void __init parse_b1_table(const struct dmi_header *dm)
wmi_supported = 1; wmi_supported = 1;
} }
static void __init find_b1(const struct dmi_header *dm, void *dummy) static void find_b1(const struct dmi_header *dm, void *dummy)
{ {
switch (dm->type) { switch (dm->type) {
case 0xb1: /* misc bios flags */ case 0xb1: /* misc bios flags */
...@@ -261,7 +261,7 @@ static struct wmi_driver dell_smbios_wmi_driver = { ...@@ -261,7 +261,7 @@ static struct wmi_driver dell_smbios_wmi_driver = {
.filter_callback = dell_smbios_wmi_filter, .filter_callback = dell_smbios_wmi_filter,
}; };
static int __init init_dell_smbios_wmi(void) int init_dell_smbios_wmi(void)
{ {
dmi_walk(find_b1, NULL); dmi_walk(find_b1, NULL);
...@@ -271,15 +271,9 @@ static int __init init_dell_smbios_wmi(void) ...@@ -271,15 +271,9 @@ static int __init init_dell_smbios_wmi(void)
return wmi_driver_register(&dell_smbios_wmi_driver); return wmi_driver_register(&dell_smbios_wmi_driver);
} }
static void __exit exit_dell_smbios_wmi(void) void exit_dell_smbios_wmi(void)
{ {
wmi_driver_unregister(&dell_smbios_wmi_driver); wmi_driver_unregister(&dell_smbios_wmi_driver);
} }
module_init(init_dell_smbios_wmi);
module_exit(exit_dell_smbios_wmi);
MODULE_ALIAS("wmi:" DELL_WMI_SMBIOS_GUID); MODULE_ALIAS("wmi:" DELL_WMI_SMBIOS_GUID);
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
MODULE_DESCRIPTION("Dell SMBIOS communications over WMI");
MODULE_LICENSE("GPL");
...@@ -75,4 +75,29 @@ int dell_laptop_register_notifier(struct notifier_block *nb); ...@@ -75,4 +75,29 @@ int dell_laptop_register_notifier(struct notifier_block *nb);
int dell_laptop_unregister_notifier(struct notifier_block *nb); int dell_laptop_unregister_notifier(struct notifier_block *nb);
void dell_laptop_call_notifier(unsigned long action, void *data); void dell_laptop_call_notifier(unsigned long action, void *data);
#endif /* for the supported backends */
#ifdef CONFIG_DELL_SMBIOS_WMI
int init_dell_smbios_wmi(void);
void exit_dell_smbios_wmi(void);
#else /* CONFIG_DELL_SMBIOS_WMI */
static inline int init_dell_smbios_wmi(void)
{
return -ENODEV;
}
static inline void exit_dell_smbios_wmi(void)
{}
#endif /* CONFIG_DELL_SMBIOS_WMI */
#ifdef CONFIG_DELL_SMBIOS_SMM
int init_dell_smbios_smm(void);
void exit_dell_smbios_smm(void);
#else /* CONFIG_DELL_SMBIOS_SMM */
static inline int init_dell_smbios_smm(void)
{
return -ENODEV;
}
static inline void exit_dell_smbios_smm(void)
{}
#endif /* CONFIG_DELL_SMBIOS_SMM */
#endif /* _DELL_SMBIOS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment