cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

toshiba-wmi.c (3012B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * toshiba_wmi.c - Toshiba WMI Hotkey Driver
      4 *
      5 * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com>
      6 */
      7
      8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      9
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/init.h>
     13#include <linux/types.h>
     14#include <linux/acpi.h>
     15#include <linux/input.h>
     16#include <linux/input/sparse-keymap.h>
     17#include <linux/dmi.h>
     18
     19MODULE_AUTHOR("Azael Avalos");
     20MODULE_DESCRIPTION("Toshiba WMI Hotkey Driver");
     21MODULE_LICENSE("GPL");
     22
     23#define WMI_EVENT_GUID	"59142400-C6A3-40FA-BADB-8A2652834100"
     24
     25MODULE_ALIAS("wmi:"WMI_EVENT_GUID);
     26
     27static struct input_dev *toshiba_wmi_input_dev;
     28
     29static const struct key_entry toshiba_wmi_keymap[] __initconst = {
     30	/* TODO: Add keymap values once found... */
     31	/*{ KE_KEY, 0x00, { KEY_ } },*/
     32	{ KE_END, 0 }
     33};
     34
     35static void toshiba_wmi_notify(u32 value, void *context)
     36{
     37	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
     38	union acpi_object *obj;
     39	acpi_status status;
     40
     41	status = wmi_get_event_data(value, &response);
     42	if (ACPI_FAILURE(status)) {
     43		pr_err("Bad event status 0x%x\n", status);
     44		return;
     45	}
     46
     47	obj = (union acpi_object *)response.pointer;
     48	if (!obj)
     49		return;
     50
     51	/* TODO: Add proper checks once we have data */
     52	pr_debug("Unknown event received, obj type %x\n", obj->type);
     53
     54	kfree(response.pointer);
     55}
     56
     57static const struct dmi_system_id toshiba_wmi_dmi_table[] __initconst = {
     58	{
     59		.ident = "Toshiba laptop",
     60		.matches = {
     61			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
     62		},
     63	},
     64	{}
     65};
     66
     67static int __init toshiba_wmi_input_setup(void)
     68{
     69	acpi_status status;
     70	int err;
     71
     72	toshiba_wmi_input_dev = input_allocate_device();
     73	if (!toshiba_wmi_input_dev)
     74		return -ENOMEM;
     75
     76	toshiba_wmi_input_dev->name = "Toshiba WMI hotkeys";
     77	toshiba_wmi_input_dev->phys = "wmi/input0";
     78	toshiba_wmi_input_dev->id.bustype = BUS_HOST;
     79
     80	err = sparse_keymap_setup(toshiba_wmi_input_dev,
     81				  toshiba_wmi_keymap, NULL);
     82	if (err)
     83		goto err_free_dev;
     84
     85	status = wmi_install_notify_handler(WMI_EVENT_GUID,
     86					    toshiba_wmi_notify, NULL);
     87	if (ACPI_FAILURE(status)) {
     88		err = -EIO;
     89		goto err_free_dev;
     90	}
     91
     92	err = input_register_device(toshiba_wmi_input_dev);
     93	if (err)
     94		goto err_remove_notifier;
     95
     96	return 0;
     97
     98 err_remove_notifier:
     99	wmi_remove_notify_handler(WMI_EVENT_GUID);
    100 err_free_dev:
    101	input_free_device(toshiba_wmi_input_dev);
    102	return err;
    103}
    104
    105static void toshiba_wmi_input_destroy(void)
    106{
    107	wmi_remove_notify_handler(WMI_EVENT_GUID);
    108	input_unregister_device(toshiba_wmi_input_dev);
    109}
    110
    111static int __init toshiba_wmi_init(void)
    112{
    113	int ret;
    114
    115	if (!wmi_has_guid(WMI_EVENT_GUID) ||
    116	    !dmi_check_system(toshiba_wmi_dmi_table))
    117		return -ENODEV;
    118
    119	ret = toshiba_wmi_input_setup();
    120	if (ret) {
    121		pr_err("Failed to setup input device\n");
    122		return ret;
    123	}
    124
    125	pr_info("Toshiba WMI Hotkey Driver\n");
    126
    127	return 0;
    128}
    129
    130static void __exit toshiba_wmi_exit(void)
    131{
    132	if (wmi_has_guid(WMI_EVENT_GUID))
    133		toshiba_wmi_input_destroy();
    134}
    135
    136module_init(toshiba_wmi_init);
    137module_exit(toshiba_wmi_exit);