Reorder uniwill driver init and remove

This commit is contained in:
Christoffer Sandberg 2021-09-15 17:58:06 +02:00
parent b855a8ff6d
commit 9ec3dc927a
3 changed files with 80 additions and 42 deletions

View file

@ -28,15 +28,9 @@ MODULE_DESCRIPTION("TUXEDO Computers keyboard & keyboard backlight Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION("3.0.8"); MODULE_VERSION("3.0.8");
MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_0);
MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_1);
MODULE_ALIAS("wmi:" UNIWILL_WMI_EVENT_GUID_2);
static DEFINE_MUTEX(tuxedo_keyboard_init_driver_lock); static DEFINE_MUTEX(tuxedo_keyboard_init_driver_lock);
static struct tuxedo_keyboard_driver *driver_list[] = { // static struct tuxedo_keyboard_driver *driver_list[] = { };
&uniwill_keyboard_driver
};
static int tuxedo_input_init(const struct key_entry key_map[]) static int tuxedo_input_init(const struct key_entry key_map[])
{ {
@ -134,44 +128,48 @@ static void __exit tuxedo_input_exit(void)
} }
} }
static int __init tuxedo_keyboard_init(void) void tuxedo_keyboard_remove_driver(struct tuxedo_keyboard_driver *tk_driver)
{ {
int i; bool specified_driver_differ_from_used =
int num_drivers = sizeof(driver_list) / sizeof(*driver_list); tk_driver != NULL &&
TUXEDO_INFO("Model '%s' found\n", (
dmi_get_system_info(DMI_PRODUCT_NAME)); strcmp(
tk_driver->platform_driver->driver.name,
current_driver->platform_driver->driver.name
) != 0
);
// Attempt to load each available driver if (specified_driver_differ_from_used)
// Associated probe decides if it fits return;
// Driver from first successful probe is used
i = 0; TUXEDO_DEBUG("tuxedo_input_exit()\n");
while (IS_ERR_OR_NULL(tuxedo_platform_device) && i < num_drivers) { tuxedo_input_exit();
current_driver = driver_list[i]; TUXEDO_DEBUG("platform_device_unregister()\n");
tuxedo_keyboard_init_driver(current_driver); if (!IS_ERR_OR_NULL(tuxedo_platform_device)) {
++i; platform_device_unregister(tuxedo_platform_device);
tuxedo_platform_device = NULL;
} }
TUXEDO_DEBUG("platform_driver_unregister()\n");
if (IS_ERR_OR_NULL(tuxedo_platform_device)) { if (!IS_ERR_OR_NULL(current_driver)) {
TUXEDO_DEBUG("No matching hardware found on init\n"); platform_driver_unregister(current_driver->platform_driver);
current_driver = NULL; current_driver = NULL;
} }
}
EXPORT_SYMBOL(tuxedo_keyboard_remove_driver);
static int __init tuxedo_keyboard_init(void)
{
TUXEDO_INFO("module init\n");
return 0; return 0;
} }
static void __exit tuxedo_keyboard_exit(void) static void __exit tuxedo_keyboard_exit(void)
{ {
TUXEDO_DEBUG("tuxedo_input_exit()\n"); TUXEDO_INFO("module exit\n");
tuxedo_input_exit();
TUXEDO_DEBUG("platform_device_unregister()\n");
if (!IS_ERR_OR_NULL(tuxedo_platform_device))
platform_device_unregister(tuxedo_platform_device);
TUXEDO_DEBUG("platform_driver_unregister()\n");
if (!IS_ERR_OR_NULL(current_driver))
platform_driver_unregister(current_driver->platform_driver);
TUXEDO_DEBUG("exit\n"); if (tuxedo_platform_device != NULL)
tuxedo_keyboard_remove_driver(NULL);
} }
module_init(tuxedo_keyboard_init); module_init(tuxedo_keyboard_init);

View file

@ -56,6 +56,7 @@ static struct input_dev *tuxedo_input_device = NULL;
static struct tuxedo_keyboard_driver *current_driver = NULL; static struct tuxedo_keyboard_driver *current_driver = NULL;
struct platform_device *tuxedo_keyboard_init_driver(struct tuxedo_keyboard_driver *tk_driver); struct platform_device *tuxedo_keyboard_init_driver(struct tuxedo_keyboard_driver *tk_driver);
void tuxedo_keyboard_remove_driver(struct tuxedo_keyboard_driver *tk_driver);
/** /**
* Basically a copy of the existing report event but doesn't report unknown events * Basically a copy of the existing report event but doesn't report unknown events

View file

@ -133,6 +133,10 @@ u32 uniwill_add_interface(struct uniwill_interface_t *interface)
interface->event_callb = uniwill_event_callb; interface->event_callb = uniwill_event_callb;
mutex_unlock(&uniwill_interface_modification_lock); mutex_unlock(&uniwill_interface_modification_lock);
// Initialize driver if not already present
tuxedo_keyboard_init_driver(&uniwill_keyboard_driver);
return 0; return 0;
} }
EXPORT_SYMBOL(uniwill_add_interface); EXPORT_SYMBOL(uniwill_add_interface);
@ -141,14 +145,18 @@ u32 uniwill_remove_interface(struct uniwill_interface_t *interface)
{ {
mutex_lock(&uniwill_interface_modification_lock); mutex_lock(&uniwill_interface_modification_lock);
if (strcmp(interface->string_id, UNIWILL_INTERFACE_WMI_STRID)) if (strcmp(interface->string_id, UNIWILL_INTERFACE_WMI_STRID) == 0) {
// Remove driver if last interface is removed
tuxedo_keyboard_remove_driver(&uniwill_keyboard_driver);
uniwill_interfaces.wmi = NULL; uniwill_interfaces.wmi = NULL;
else { } else {
mutex_unlock(&uniwill_interface_modification_lock); mutex_unlock(&uniwill_interface_modification_lock);
return -EINVAL; return -EINVAL;
} }
mutex_unlock(&uniwill_interface_modification_lock); mutex_unlock(&uniwill_interface_modification_lock);
return 0; return 0;
} }
EXPORT_SYMBOL(uniwill_remove_interface); EXPORT_SYMBOL(uniwill_remove_interface);
@ -342,7 +350,7 @@ void uniwill_event_callb(u32 code)
} }
} }
static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr) /*static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr)
{ {
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj; union acpi_object *obj;
@ -367,9 +375,9 @@ static void uniwill_wmi_handle_event(u32 value, void *context, u32 guid_nr)
} }
kfree(obj); kfree(obj);
} }*/
static void uniwill_wmi_notify0(u32 value, void *context) /*static void uniwill_wmi_notify0(u32 value, void *context)
{ {
uniwill_wmi_handle_event(value, context, 0); uniwill_wmi_handle_event(value, context, 0);
} }
@ -382,7 +390,7 @@ static void uniwill_wmi_notify1(u32 value, void *context)
static void uniwill_wmi_notify2(u32 value, void *context) static void uniwill_wmi_notify2(u32 value, void *context)
{ {
uniwill_wmi_handle_event(value, context, 2); uniwill_wmi_handle_event(value, context, 2);
} }*/
static ssize_t uw_brightness_show(struct device *child, static ssize_t uw_brightness_show(struct device *child,
struct device_attribute *attr, char *buffer) struct device_attribute *attr, char *buffer)
@ -820,7 +828,7 @@ static int uw_lightbar_remove(struct platform_device *dev)
return 0; return 0;
} }
static int uniwill_keyboard_probe(struct platform_device *dev) /*static int uniwill_keyboard_probe(struct platform_device *dev)
{ {
int status; int status;
@ -872,6 +880,40 @@ err_remove_notifiers:
wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_2); wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_2);
return -ENODEV; return -ENODEV;
}*/
static int uniwill_keyboard_probe(struct platform_device *dev)
{
u32 i;
u8 data;
int status;
// FIXME Hard set balanced profile until we have implemented a way to
// switch it while tuxedo_io is loaded
// uw_ec_write_addr(0x51, 0x07, 0x00, 0x00, &reg_write_return);
uniwill_write_ec_ram(0x0751, 0x00);
// Set manual-mode fan-curve in 0x0743 - 0x0747
// Some kind of default fan-curve is stored in 0x0786 - 0x078a: Using it to initialize manual-mode fan-curve
for (i = 0; i < 5; ++i) {
uniwill_read_ec_ram(0x0786 + i, &data);
uniwill_write_ec_ram(0x0743 + i, data);
}
// Enable manual mode
uniwill_write_ec_ram(0x0741, 0x01);
// Zero second fan temp for detection
uniwill_write_ec_ram(0x044f, 0x00);
status = register_keyboard_notifier(&keyboard_notifier_block);
uw_kbd_bl_init(dev);
status = uw_lightbar_init(dev);
uw_lightbar_loaded = (status >= 0);
return 0;
} }
static int uniwill_keyboard_remove(struct platform_device *dev) static int uniwill_keyboard_remove(struct platform_device *dev)
@ -887,9 +929,6 @@ static int uniwill_keyboard_remove(struct platform_device *dev)
} }
unregister_keyboard_notifier(&keyboard_notifier_block); unregister_keyboard_notifier(&keyboard_notifier_block);
wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_0);
wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_1);
wmi_remove_notify_handler(UNIWILL_WMI_EVENT_GUID_2);
del_timer(&uw_kbd_bl_init_timer); del_timer(&uw_kbd_bl_init_timer);