linux/drivers/platform/x86/asus-wmi.c
<<
>>
Prefs
   1/*
   2 * Asus PC WMI hotkey driver
   3 *
   4 * Copyright(C) 2010 Intel Corporation.
   5 * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
   6 *
   7 * Portions based on wistron_btns.c:
   8 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
   9 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
  10 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
  11 *
  12 *  This program is free software; you can redistribute it and/or modify
  13 *  it under the terms of the GNU General Public License as published by
  14 *  the Free Software Foundation; either version 2 of the License, or
  15 *  (at your option) any later version.
  16 *
  17 *  This program is distributed in the hope that it will be useful,
  18 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 *  GNU General Public License for more details.
  21 *
  22 *  You should have received a copy of the GNU General Public License
  23 *  along with this program; if not, write to the Free Software
  24 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  25 */
  26
  27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  28
  29#include <linux/kernel.h>
  30#include <linux/module.h>
  31#include <linux/init.h>
  32#include <linux/types.h>
  33#include <linux/slab.h>
  34#include <linux/input.h>
  35#include <linux/input/sparse-keymap.h>
  36#include <linux/fb.h>
  37#include <linux/backlight.h>
  38#include <linux/leds.h>
  39#include <linux/rfkill.h>
  40#include <linux/pci.h>
  41#include <linux/pci_hotplug.h>
  42#include <linux/hwmon.h>
  43#include <linux/hwmon-sysfs.h>
  44#include <linux/debugfs.h>
  45#include <linux/seq_file.h>
  46#include <linux/platform_device.h>
  47#include <linux/thermal.h>
  48#include <linux/security.h>
  49#include <acpi/acpi_bus.h>
  50#include <acpi/acpi_drivers.h>
  51#include <acpi/video.h>
  52
  53#include "asus-wmi.h"
  54
  55MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>, "
  56              "Yong Wang <yong.y.wang@intel.com>");
  57MODULE_DESCRIPTION("Asus Generic WMI Driver");
  58MODULE_LICENSE("GPL");
  59
  60#define to_platform_driver(drv)                                 \
  61        (container_of((drv), struct platform_driver, driver))
  62
  63#define to_asus_wmi_driver(pdrv)                                        \
  64        (container_of((pdrv), struct asus_wmi_driver, platform_driver))
  65
  66#define ASUS_WMI_MGMT_GUID      "97845ED0-4E6D-11DE-8A39-0800200C9A66"
  67
  68#define NOTIFY_BRNUP_MIN                0x11
  69#define NOTIFY_BRNUP_MAX                0x1f
  70#define NOTIFY_BRNDOWN_MIN              0x20
  71#define NOTIFY_BRNDOWN_MAX              0x2e
  72#define NOTIFY_KBD_BRTUP                0xc4
  73#define NOTIFY_KBD_BRTDWN               0xc5
  74
  75/* WMI Methods */
  76#define ASUS_WMI_METHODID_SPEC          0x43455053 /* BIOS SPECification */
  77#define ASUS_WMI_METHODID_SFBD          0x44424653 /* Set First Boot Device */
  78#define ASUS_WMI_METHODID_GLCD          0x44434C47 /* Get LCD status */
  79#define ASUS_WMI_METHODID_GPID          0x44495047 /* Get Panel ID?? (Resol) */
  80#define ASUS_WMI_METHODID_QMOD          0x444F4D51 /* Quiet MODe */
  81#define ASUS_WMI_METHODID_SPLV          0x4C425053 /* Set Panel Light Value */
  82#define ASUS_WMI_METHODID_SFUN          0x4E554653 /* FUNCtionalities */
  83#define ASUS_WMI_METHODID_SDSP          0x50534453 /* Set DiSPlay output */
  84#define ASUS_WMI_METHODID_GDSP          0x50534447 /* Get DiSPlay output */
  85#define ASUS_WMI_METHODID_DEVP          0x50564544 /* DEVice Policy */
  86#define ASUS_WMI_METHODID_OSVR          0x5256534F /* OS VeRsion */
  87#define ASUS_WMI_METHODID_DSTS          0x53544344 /* Device STatuS */
  88#define ASUS_WMI_METHODID_DSTS2         0x53545344 /* Device STatuS #2*/
  89#define ASUS_WMI_METHODID_BSTS          0x53545342 /* Bios STatuS ? */
  90#define ASUS_WMI_METHODID_DEVS          0x53564544 /* DEVice Set */
  91#define ASUS_WMI_METHODID_CFVS          0x53564643 /* CPU Frequency Volt Set */
  92#define ASUS_WMI_METHODID_KBFT          0x5446424B /* KeyBoard FilTer */
  93#define ASUS_WMI_METHODID_INIT          0x54494E49 /* INITialize */
  94#define ASUS_WMI_METHODID_HKEY          0x59454B48 /* Hot KEY ?? */
  95
  96#define ASUS_WMI_UNSUPPORTED_METHOD     0xFFFFFFFE
  97
  98/* Wireless */
  99#define ASUS_WMI_DEVID_HW_SWITCH        0x00010001
 100#define ASUS_WMI_DEVID_WIRELESS_LED     0x00010002
 101#define ASUS_WMI_DEVID_CWAP             0x00010003
 102#define ASUS_WMI_DEVID_WLAN             0x00010011
 103#define ASUS_WMI_DEVID_WLAN_LED         0x00010012
 104#define ASUS_WMI_DEVID_BLUETOOTH        0x00010013
 105#define ASUS_WMI_DEVID_GPS              0x00010015
 106#define ASUS_WMI_DEVID_WIMAX            0x00010017
 107#define ASUS_WMI_DEVID_WWAN3G           0x00010019
 108#define ASUS_WMI_DEVID_UWB              0x00010021
 109
 110/* Leds */
 111/* 0x000200XX and 0x000400XX */
 112#define ASUS_WMI_DEVID_LED1             0x00020011
 113#define ASUS_WMI_DEVID_LED2             0x00020012
 114#define ASUS_WMI_DEVID_LED3             0x00020013
 115#define ASUS_WMI_DEVID_LED4             0x00020014
 116#define ASUS_WMI_DEVID_LED5             0x00020015
 117#define ASUS_WMI_DEVID_LED6             0x00020016
 118
 119/* Backlight and Brightness */
 120#define ASUS_WMI_DEVID_BACKLIGHT        0x00050011
 121#define ASUS_WMI_DEVID_BRIGHTNESS       0x00050012
 122#define ASUS_WMI_DEVID_KBD_BACKLIGHT    0x00050021
 123#define ASUS_WMI_DEVID_LIGHT_SENSOR     0x00050022 /* ?? */
 124
 125/* Misc */
 126#define ASUS_WMI_DEVID_CAMERA           0x00060013
 127
 128/* Storage */
 129#define ASUS_WMI_DEVID_CARDREADER       0x00080013
 130
 131/* Input */
 132#define ASUS_WMI_DEVID_TOUCHPAD         0x00100011
 133#define ASUS_WMI_DEVID_TOUCHPAD_LED     0x00100012
 134
 135/* Fan, Thermal */
 136#define ASUS_WMI_DEVID_THERMAL_CTRL     0x00110011
 137#define ASUS_WMI_DEVID_FAN_CTRL         0x00110012
 138
 139/* Power */
 140#define ASUS_WMI_DEVID_PROCESSOR_STATE  0x00120012
 141
 142/* Deep S3 / Resume on LID open */
 143#define ASUS_WMI_DEVID_LID_RESUME       0x00120031
 144
 145/* DSTS masks */
 146#define ASUS_WMI_DSTS_STATUS_BIT        0x00000001
 147#define ASUS_WMI_DSTS_UNKNOWN_BIT       0x00000002
 148#define ASUS_WMI_DSTS_PRESENCE_BIT      0x00010000
 149#define ASUS_WMI_DSTS_USER_BIT          0x00020000
 150#define ASUS_WMI_DSTS_BIOS_BIT          0x00040000
 151#define ASUS_WMI_DSTS_BRIGHTNESS_MASK   0x000000FF
 152#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK   0x0000FF00
 153
 154struct bios_args {
 155        u32 arg0;
 156        u32 arg1;
 157} __packed;
 158
 159/*
 160 * <platform>/    - debugfs root directory
 161 *   dev_id      - current dev_id
 162 *   ctrl_param  - current ctrl_param
 163 *   method_id   - current method_id
 164 *   devs        - call DEVS(dev_id, ctrl_param) and print result
 165 *   dsts        - call DSTS(dev_id)  and print result
 166 *   call        - call method_id(dev_id, ctrl_param) and print result
 167 */
 168struct asus_wmi_debug {
 169        struct dentry *root;
 170        u32 method_id;
 171        u32 dev_id;
 172        u32 ctrl_param;
 173};
 174
 175struct asus_rfkill {
 176        struct asus_wmi *asus;
 177        struct rfkill *rfkill;
 178        u32 dev_id;
 179};
 180
 181struct asus_wmi {
 182        int dsts_id;
 183        int spec;
 184        int sfun;
 185
 186        struct input_dev *inputdev;
 187        struct backlight_device *backlight_device;
 188        struct device *hwmon_device;
 189        struct platform_device *platform_device;
 190
 191        struct led_classdev wlan_led;
 192        int wlan_led_wk;
 193        struct led_classdev tpd_led;
 194        int tpd_led_wk;
 195        struct led_classdev kbd_led;
 196        int kbd_led_wk;
 197        struct workqueue_struct *led_workqueue;
 198        struct work_struct tpd_led_work;
 199        struct work_struct kbd_led_work;
 200        struct work_struct wlan_led_work;
 201
 202        struct asus_rfkill wlan;
 203        struct asus_rfkill bluetooth;
 204        struct asus_rfkill wimax;
 205        struct asus_rfkill wwan3g;
 206        struct asus_rfkill gps;
 207        struct asus_rfkill uwb;
 208
 209        struct hotplug_slot *hotplug_slot;
 210        struct mutex hotplug_lock;
 211        struct mutex wmi_lock;
 212        struct workqueue_struct *hotplug_workqueue;
 213        struct work_struct hotplug_work;
 214
 215        struct asus_wmi_debug debug;
 216
 217        struct asus_wmi_driver *driver;
 218};
 219
 220static int asus_wmi_input_init(struct asus_wmi *asus)
 221{
 222        int err;
 223
 224        asus->inputdev = input_allocate_device();
 225        if (!asus->inputdev)
 226                return -ENOMEM;
 227
 228        asus->inputdev->name = asus->driver->input_name;
 229        asus->inputdev->phys = asus->driver->input_phys;
 230        asus->inputdev->id.bustype = BUS_HOST;
 231        asus->inputdev->dev.parent = &asus->platform_device->dev;
 232        set_bit(EV_REP, asus->inputdev->evbit);
 233
 234        err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
 235        if (err)
 236                goto err_free_dev;
 237
 238        err = input_register_device(asus->inputdev);
 239        if (err)
 240                goto err_free_keymap;
 241
 242        return 0;
 243
 244err_free_keymap:
 245        sparse_keymap_free(asus->inputdev);
 246err_free_dev:
 247        input_free_device(asus->inputdev);
 248        return err;
 249}
 250
 251static void asus_wmi_input_exit(struct asus_wmi *asus)
 252{
 253        if (asus->inputdev) {
 254                sparse_keymap_free(asus->inputdev);
 255                input_unregister_device(asus->inputdev);
 256        }
 257
 258        asus->inputdev = NULL;
 259}
 260
 261static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
 262                                    u32 *retval)
 263{
 264        struct bios_args args = {
 265                .arg0 = arg0,
 266                .arg1 = arg1,
 267        };
 268        struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
 269        struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
 270        acpi_status status;
 271        union acpi_object *obj;
 272        u32 tmp;
 273
 274        status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
 275                                     &input, &output);
 276
 277        if (ACPI_FAILURE(status))
 278                goto exit;
 279
 280        obj = (union acpi_object *)output.pointer;
 281        if (obj && obj->type == ACPI_TYPE_INTEGER)
 282                tmp = (u32) obj->integer.value;
 283        else
 284                tmp = 0;
 285
 286        if (retval)
 287                *retval = tmp;
 288
 289        kfree(obj);
 290
 291exit:
 292        if (ACPI_FAILURE(status))
 293                return -EIO;
 294
 295        if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
 296                return -ENODEV;
 297
 298        return 0;
 299}
 300
 301static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
 302{
 303        return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
 304}
 305
 306static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
 307                                 u32 *retval)
 308{
 309        return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
 310                                        ctrl_param, retval);
 311}
 312
 313/* Helper for special devices with magic return codes */
 314static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
 315                                      u32 dev_id, u32 mask)
 316{
 317        u32 retval = 0;
 318        int err;
 319
 320        err = asus_wmi_get_devstate(asus, dev_id, &retval);
 321
 322        if (err < 0)
 323                return err;
 324
 325        if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
 326                return -ENODEV;
 327
 328        if (mask == ASUS_WMI_DSTS_STATUS_BIT) {
 329                if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT)
 330                        return -ENODEV;
 331        }
 332
 333        return retval & mask;
 334}
 335
 336static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
 337{
 338        return asus_wmi_get_devstate_bits(asus, dev_id,
 339                                          ASUS_WMI_DSTS_STATUS_BIT);
 340}
 341
 342/*
 343 * LEDs
 344 */
 345/*
 346 * These functions actually update the LED's, and are called from a
 347 * workqueue. By doing this as separate work rather than when the LED
 348 * subsystem asks, we avoid messing with the Asus ACPI stuff during a
 349 * potentially bad time, such as a timer interrupt.
 350 */
 351static void tpd_led_update(struct work_struct *work)
 352{
 353        int ctrl_param;
 354        struct asus_wmi *asus;
 355
 356        asus = container_of(work, struct asus_wmi, tpd_led_work);
 357
 358        ctrl_param = asus->tpd_led_wk;
 359        asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
 360}
 361
 362static void tpd_led_set(struct led_classdev *led_cdev,
 363                        enum led_brightness value)
 364{
 365        struct asus_wmi *asus;
 366
 367        asus = container_of(led_cdev, struct asus_wmi, tpd_led);
 368
 369        asus->tpd_led_wk = !!value;
 370        queue_work(asus->led_workqueue, &asus->tpd_led_work);
 371}
 372
 373static int read_tpd_led_state(struct asus_wmi *asus)
 374{
 375        return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED);
 376}
 377
 378static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
 379{
 380        struct asus_wmi *asus;
 381
 382        asus = container_of(led_cdev, struct asus_wmi, tpd_led);
 383
 384        return read_tpd_led_state(asus);
 385}
 386
 387static void kbd_led_update(struct work_struct *work)
 388{
 389        int ctrl_param = 0;
 390        struct asus_wmi *asus;
 391
 392        asus = container_of(work, struct asus_wmi, kbd_led_work);
 393
 394        /*
 395         * bits 0-2: level
 396         * bit 7: light on/off
 397         */
 398        if (asus->kbd_led_wk > 0)
 399                ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
 400
 401        asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
 402}
 403
 404static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
 405{
 406        int retval;
 407
 408        /*
 409         * bits 0-2: level
 410         * bit 7: light on/off
 411         * bit 8-10: environment (0: dark, 1: normal, 2: light)
 412         * bit 17: status unknown
 413         */
 414        retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT,
 415                                            0xFFFF);
 416
 417        /* Unknown status is considered as off */
 418        if (retval == 0x8000)
 419                retval = 0;
 420
 421        if (retval >= 0) {
 422                if (level)
 423                        *level = retval & 0x7F;
 424                if (env)
 425                        *env = (retval >> 8) & 0x7F;
 426                retval = 0;
 427        }
 428
 429        return retval;
 430}
 431
 432static void kbd_led_set(struct led_classdev *led_cdev,
 433                        enum led_brightness value)
 434{
 435        struct asus_wmi *asus;
 436
 437        asus = container_of(led_cdev, struct asus_wmi, kbd_led);
 438
 439        if (value > asus->kbd_led.max_brightness)
 440                value = asus->kbd_led.max_brightness;
 441        else if (value < 0)
 442                value = 0;
 443
 444        asus->kbd_led_wk = value;
 445        queue_work(asus->led_workqueue, &asus->kbd_led_work);
 446}
 447
 448static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
 449{
 450        struct asus_wmi *asus;
 451        int retval, value;
 452
 453        asus = container_of(led_cdev, struct asus_wmi, kbd_led);
 454
 455        retval = kbd_led_read(asus, &value, NULL);
 456
 457        if (retval < 0)
 458                return retval;
 459
 460        return value;
 461}
 462
 463static int wlan_led_unknown_state(struct asus_wmi *asus)
 464{
 465        u32 result;
 466
 467        asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
 468
 469        return result & ASUS_WMI_DSTS_UNKNOWN_BIT;
 470}
 471
 472static int wlan_led_presence(struct asus_wmi *asus)
 473{
 474        u32 result;
 475
 476        asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
 477
 478        return result & ASUS_WMI_DSTS_PRESENCE_BIT;
 479}
 480
 481static void wlan_led_update(struct work_struct *work)
 482{
 483        int ctrl_param;
 484        struct asus_wmi *asus;
 485
 486        asus = container_of(work, struct asus_wmi, wlan_led_work);
 487
 488        ctrl_param = asus->wlan_led_wk;
 489        asus_wmi_set_devstate(ASUS_WMI_DEVID_WIRELESS_LED, ctrl_param, NULL);
 490}
 491
 492static void wlan_led_set(struct led_classdev *led_cdev,
 493                         enum led_brightness value)
 494{
 495        struct asus_wmi *asus;
 496
 497        asus = container_of(led_cdev, struct asus_wmi, wlan_led);
 498
 499        asus->wlan_led_wk = !!value;
 500        queue_work(asus->led_workqueue, &asus->wlan_led_work);
 501}
 502
 503static enum led_brightness wlan_led_get(struct led_classdev *led_cdev)
 504{
 505        struct asus_wmi *asus;
 506        u32 result;
 507
 508        asus = container_of(led_cdev, struct asus_wmi, wlan_led);
 509        asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WIRELESS_LED, &result);
 510
 511        return result & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
 512}
 513
 514static void asus_wmi_led_exit(struct asus_wmi *asus)
 515{
 516        if (!IS_ERR_OR_NULL(asus->kbd_led.dev))
 517                led_classdev_unregister(&asus->kbd_led);
 518        if (!IS_ERR_OR_NULL(asus->tpd_led.dev))
 519                led_classdev_unregister(&asus->tpd_led);
 520        if (!IS_ERR_OR_NULL(asus->wlan_led.dev))
 521                led_classdev_unregister(&asus->wlan_led);
 522        if (asus->led_workqueue)
 523                destroy_workqueue(asus->led_workqueue);
 524}
 525
 526static int asus_wmi_led_init(struct asus_wmi *asus)
 527{
 528        int rv = 0;
 529
 530        asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
 531        if (!asus->led_workqueue)
 532                return -ENOMEM;
 533
 534        if (read_tpd_led_state(asus) >= 0) {
 535                INIT_WORK(&asus->tpd_led_work, tpd_led_update);
 536
 537                asus->tpd_led.name = "asus::touchpad";
 538                asus->tpd_led.brightness_set = tpd_led_set;
 539                asus->tpd_led.brightness_get = tpd_led_get;
 540                asus->tpd_led.max_brightness = 1;
 541
 542                rv = led_classdev_register(&asus->platform_device->dev,
 543                                           &asus->tpd_led);
 544                if (rv)
 545                        goto error;
 546        }
 547
 548        if (kbd_led_read(asus, NULL, NULL) >= 0) {
 549                INIT_WORK(&asus->kbd_led_work, kbd_led_update);
 550
 551                asus->kbd_led.name = "asus::kbd_backlight";
 552                asus->kbd_led.brightness_set = kbd_led_set;
 553                asus->kbd_led.brightness_get = kbd_led_get;
 554                asus->kbd_led.max_brightness = 3;
 555
 556                rv = led_classdev_register(&asus->platform_device->dev,
 557                                           &asus->kbd_led);
 558                if (rv)
 559                        goto error;
 560        }
 561
 562        if (wlan_led_presence(asus)) {
 563                INIT_WORK(&asus->wlan_led_work, wlan_led_update);
 564
 565                asus->wlan_led.name = "asus::wlan";
 566                asus->wlan_led.brightness_set = wlan_led_set;
 567                if (!wlan_led_unknown_state(asus))
 568                        asus->wlan_led.brightness_get = wlan_led_get;
 569                asus->wlan_led.flags = LED_CORE_SUSPENDRESUME;
 570                asus->wlan_led.max_brightness = 1;
 571                asus->wlan_led.default_trigger = "asus-wlan";
 572
 573                rv = led_classdev_register(&asus->platform_device->dev,
 574                                           &asus->wlan_led);
 575        }
 576
 577error:
 578        if (rv)
 579                asus_wmi_led_exit(asus);
 580
 581        return rv;
 582}
 583
 584
 585/*
 586 * PCI hotplug (for wlan rfkill)
 587 */
 588static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
 589{
 590        int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
 591
 592        if (result < 0)
 593                return false;
 594        return !result;
 595}
 596
 597static void asus_rfkill_hotplug(struct asus_wmi *asus)
 598{
 599        struct pci_dev *dev;
 600        struct pci_bus *bus;
 601        bool blocked;
 602        bool absent;
 603        u32 l;
 604
 605        mutex_lock(&asus->wmi_lock);
 606        blocked = asus_wlan_rfkill_blocked(asus);
 607        mutex_unlock(&asus->wmi_lock);
 608
 609        mutex_lock(&asus->hotplug_lock);
 610        pci_lock_rescan_remove();
 611
 612        if (asus->wlan.rfkill)
 613                rfkill_set_sw_state(asus->wlan.rfkill, blocked);
 614
 615        if (asus->hotplug_slot) {
 616                bus = pci_find_bus(0, 1);
 617                if (!bus) {
 618                        pr_warn("Unable to find PCI bus 1?\n");
 619                        goto out_unlock;
 620                }
 621
 622                if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
 623                        pr_err("Unable to read PCI config space?\n");
 624                        goto out_unlock;
 625                }
 626                absent = (l == 0xffffffff);
 627
 628                if (blocked != absent) {
 629                        pr_warn("BIOS says wireless lan is %s, "
 630                                "but the pci device is %s\n",
 631                                blocked ? "blocked" : "unblocked",
 632                                absent ? "absent" : "present");
 633                        pr_warn("skipped wireless hotplug as probably "
 634                                "inappropriate for this model\n");
 635                        goto out_unlock;
 636                }
 637
 638                if (!blocked) {
 639                        dev = pci_get_slot(bus, 0);
 640                        if (dev) {
 641                                /* Device already present */
 642                                pci_dev_put(dev);
 643                                goto out_unlock;
 644                        }
 645                        dev = pci_scan_single_device(bus, 0);
 646                        if (dev) {
 647                                pci_bus_assign_resources(bus);
 648                                pci_bus_add_device(dev);
 649                        }
 650                } else {
 651                        dev = pci_get_slot(bus, 0);
 652                        if (dev) {
 653                                pci_stop_and_remove_bus_device(dev);
 654                                pci_dev_put(dev);
 655                        }
 656                }
 657        }
 658
 659out_unlock:
 660        pci_unlock_rescan_remove();
 661        mutex_unlock(&asus->hotplug_lock);
 662}
 663
 664static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
 665{
 666        struct asus_wmi *asus = data;
 667
 668        if (event != ACPI_NOTIFY_BUS_CHECK)
 669                return;
 670
 671        /*
 672         * We can't call directly asus_rfkill_hotplug because most
 673         * of the time WMBC is still being executed and not reetrant.
 674         * There is currently no way to tell ACPICA that  we want this
 675         * method to be serialized, we schedule a asus_rfkill_hotplug
 676         * call later, in a safer context.
 677         */
 678        queue_work(asus->hotplug_workqueue, &asus->hotplug_work);
 679}
 680
 681static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
 682{
 683        acpi_status status;
 684        acpi_handle handle;
 685
 686        status = acpi_get_handle(NULL, node, &handle);
 687
 688        if (ACPI_SUCCESS(status)) {
 689                status = acpi_install_notify_handler(handle,
 690                                                     ACPI_SYSTEM_NOTIFY,
 691                                                     asus_rfkill_notify, asus);
 692                if (ACPI_FAILURE(status))
 693                        pr_warn("Failed to register notify on %s\n", node);
 694        } else
 695                return -ENODEV;
 696
 697        return 0;
 698}
 699
 700static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
 701{
 702        acpi_status status = AE_OK;
 703        acpi_handle handle;
 704
 705        status = acpi_get_handle(NULL, node, &handle);
 706
 707        if (ACPI_SUCCESS(status)) {
 708                status = acpi_remove_notify_handler(handle,
 709                                                    ACPI_SYSTEM_NOTIFY,
 710                                                    asus_rfkill_notify);
 711                if (ACPI_FAILURE(status))
 712                        pr_err("Error removing rfkill notify handler %s\n",
 713                               node);
 714        }
 715}
 716
 717static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
 718                                   u8 *value)
 719{
 720        struct asus_wmi *asus = hotplug_slot->private;
 721        int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
 722
 723        if (result < 0)
 724                return result;
 725
 726        *value = !!result;
 727        return 0;
 728}
 729
 730static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
 731{
 732        kfree(hotplug_slot->info);
 733        kfree(hotplug_slot);
 734}
 735
 736static struct hotplug_slot_ops asus_hotplug_slot_ops = {
 737        .owner = THIS_MODULE,
 738        .get_adapter_status = asus_get_adapter_status,
 739        .get_power_status = asus_get_adapter_status,
 740};
 741
 742static void asus_hotplug_work(struct work_struct *work)
 743{
 744        struct asus_wmi *asus;
 745
 746        asus = container_of(work, struct asus_wmi, hotplug_work);
 747        asus_rfkill_hotplug(asus);
 748}
 749
 750static int asus_setup_pci_hotplug(struct asus_wmi *asus)
 751{
 752        int ret = -ENOMEM;
 753        struct pci_bus *bus = pci_find_bus(0, 1);
 754
 755        if (!bus) {
 756                pr_err("Unable to find wifi PCI bus\n");
 757                return -ENODEV;
 758        }
 759
 760        asus->hotplug_workqueue =
 761            create_singlethread_workqueue("hotplug_workqueue");
 762        if (!asus->hotplug_workqueue)
 763                goto error_workqueue;
 764
 765        INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
 766
 767        asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
 768        if (!asus->hotplug_slot)
 769                goto error_slot;
 770
 771        asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
 772                                           GFP_KERNEL);
 773        if (!asus->hotplug_slot->info)
 774                goto error_info;
 775
 776        asus->hotplug_slot->private = asus;
 777        asus->hotplug_slot->release = &asus_cleanup_pci_hotplug;
 778        asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
 779        asus_get_adapter_status(asus->hotplug_slot,
 780                                &asus->hotplug_slot->info->adapter_status);
 781
 782        ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
 783        if (ret) {
 784                pr_err("Unable to register hotplug slot - %d\n", ret);
 785                goto error_register;
 786        }
 787
 788        return 0;
 789
 790error_register:
 791        kfree(asus->hotplug_slot->info);
 792error_info:
 793        kfree(asus->hotplug_slot);
 794        asus->hotplug_slot = NULL;
 795error_slot:
 796        destroy_workqueue(asus->hotplug_workqueue);
 797error_workqueue:
 798        return ret;
 799}
 800
 801/*
 802 * Rfkill devices
 803 */
 804static int asus_rfkill_set(void *data, bool blocked)
 805{
 806        struct asus_rfkill *priv = data;
 807        u32 ctrl_param = !blocked;
 808        u32 dev_id = priv->dev_id;
 809
 810        /*
 811         * If the user bit is set, BIOS can't set and record the wlan status,
 812         * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED
 813         * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN).
 814         * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED
 815         * while setting the wlan status through WMI.
 816         * This is also the behavior that windows app will do.
 817         */
 818        if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
 819             priv->asus->driver->wlan_ctrl_by_user)
 820                dev_id = ASUS_WMI_DEVID_WLAN_LED;
 821
 822        return asus_wmi_set_devstate(dev_id, ctrl_param, NULL);
 823}
 824
 825static void asus_rfkill_query(struct rfkill *rfkill, void *data)
 826{
 827        struct asus_rfkill *priv = data;
 828        int result;
 829
 830        result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id);
 831
 832        if (result < 0)
 833                return;
 834
 835        rfkill_set_sw_state(priv->rfkill, !result);
 836}
 837
 838static int asus_rfkill_wlan_set(void *data, bool blocked)
 839{
 840        struct asus_rfkill *priv = data;
 841        struct asus_wmi *asus = priv->asus;
 842        int ret;
 843
 844        /*
 845         * This handler is enabled only if hotplug is enabled.
 846         * In this case, the asus_wmi_set_devstate() will
 847         * trigger a wmi notification and we need to wait
 848         * this call to finish before being able to call
 849         * any wmi method
 850         */
 851        mutex_lock(&asus->wmi_lock);
 852        ret = asus_rfkill_set(data, blocked);
 853        mutex_unlock(&asus->wmi_lock);
 854        return ret;
 855}
 856
 857static const struct rfkill_ops asus_rfkill_wlan_ops = {
 858        .set_block = asus_rfkill_wlan_set,
 859        .query = asus_rfkill_query,
 860};
 861
 862static const struct rfkill_ops asus_rfkill_ops = {
 863        .set_block = asus_rfkill_set,
 864        .query = asus_rfkill_query,
 865};
 866
 867static int asus_new_rfkill(struct asus_wmi *asus,
 868                           struct asus_rfkill *arfkill,
 869                           const char *name, enum rfkill_type type, int dev_id)
 870{
 871        int result = asus_wmi_get_devstate_simple(asus, dev_id);
 872        struct rfkill **rfkill = &arfkill->rfkill;
 873
 874        if (result < 0)
 875                return result;
 876
 877        arfkill->dev_id = dev_id;
 878        arfkill->asus = asus;
 879
 880        if (dev_id == ASUS_WMI_DEVID_WLAN &&
 881            asus->driver->quirks->hotplug_wireless)
 882                *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
 883                                       &asus_rfkill_wlan_ops, arfkill);
 884        else
 885                *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
 886                                       &asus_rfkill_ops, arfkill);
 887
 888        if (!*rfkill)
 889                return -EINVAL;
 890
 891        if (dev_id == ASUS_WMI_DEVID_WLAN)
 892                rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
 893
 894        rfkill_init_sw_state(*rfkill, !result);
 895        result = rfkill_register(*rfkill);
 896        if (result) {
 897                rfkill_destroy(*rfkill);
 898                *rfkill = NULL;
 899                return result;
 900        }
 901        return 0;
 902}
 903
 904static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
 905{
 906        asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
 907        asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
 908        asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
 909        if (asus->wlan.rfkill) {
 910                rfkill_unregister(asus->wlan.rfkill);
 911                rfkill_destroy(asus->wlan.rfkill);
 912                asus->wlan.rfkill = NULL;
 913        }
 914        /*
 915         * Refresh pci hotplug in case the rfkill state was changed after
 916         * asus_unregister_rfkill_notifier()
 917         */
 918        asus_rfkill_hotplug(asus);
 919        if (asus->hotplug_slot)
 920                pci_hp_deregister(asus->hotplug_slot);
 921        if (asus->hotplug_workqueue)
 922                destroy_workqueue(asus->hotplug_workqueue);
 923
 924        if (asus->bluetooth.rfkill) {
 925                rfkill_unregister(asus->bluetooth.rfkill);
 926                rfkill_destroy(asus->bluetooth.rfkill);
 927                asus->bluetooth.rfkill = NULL;
 928        }
 929        if (asus->wimax.rfkill) {
 930                rfkill_unregister(asus->wimax.rfkill);
 931                rfkill_destroy(asus->wimax.rfkill);
 932                asus->wimax.rfkill = NULL;
 933        }
 934        if (asus->wwan3g.rfkill) {
 935                rfkill_unregister(asus->wwan3g.rfkill);
 936                rfkill_destroy(asus->wwan3g.rfkill);
 937                asus->wwan3g.rfkill = NULL;
 938        }
 939        if (asus->gps.rfkill) {
 940                rfkill_unregister(asus->gps.rfkill);
 941                rfkill_destroy(asus->gps.rfkill);
 942                asus->gps.rfkill = NULL;
 943        }
 944        if (asus->uwb.rfkill) {
 945                rfkill_unregister(asus->uwb.rfkill);
 946                rfkill_destroy(asus->uwb.rfkill);
 947                asus->uwb.rfkill = NULL;
 948        }
 949}
 950
 951static int asus_wmi_rfkill_init(struct asus_wmi *asus)
 952{
 953        int result = 0;
 954
 955        mutex_init(&asus->hotplug_lock);
 956        mutex_init(&asus->wmi_lock);
 957
 958        result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan",
 959                                 RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN);
 960
 961        if (result && result != -ENODEV)
 962                goto exit;
 963
 964        result = asus_new_rfkill(asus, &asus->bluetooth,
 965                                 "asus-bluetooth", RFKILL_TYPE_BLUETOOTH,
 966                                 ASUS_WMI_DEVID_BLUETOOTH);
 967
 968        if (result && result != -ENODEV)
 969                goto exit;
 970
 971        result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax",
 972                                 RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX);
 973
 974        if (result && result != -ENODEV)
 975                goto exit;
 976
 977        result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g",
 978                                 RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G);
 979
 980        if (result && result != -ENODEV)
 981                goto exit;
 982
 983        result = asus_new_rfkill(asus, &asus->gps, "asus-gps",
 984                                 RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS);
 985
 986        if (result && result != -ENODEV)
 987                goto exit;
 988
 989        result = asus_new_rfkill(asus, &asus->uwb, "asus-uwb",
 990                                 RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB);
 991
 992        if (result && result != -ENODEV)
 993                goto exit;
 994
 995        if (!asus->driver->quirks->hotplug_wireless)
 996                goto exit;
 997
 998        result = asus_setup_pci_hotplug(asus);
 999        /*
1000         * If we get -EBUSY then something else is handling the PCI hotplug -
1001         * don't fail in this case
1002         */
1003        if (result == -EBUSY)
1004                result = 0;
1005
1006        asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
1007        asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
1008        asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
1009        /*
1010         * Refresh pci hotplug in case the rfkill state was changed during
1011         * setup.
1012         */
1013        asus_rfkill_hotplug(asus);
1014
1015exit:
1016        if (result && result != -ENODEV)
1017                asus_wmi_rfkill_exit(asus);
1018
1019        if (result == -ENODEV)
1020                result = 0;
1021
1022        return result;
1023}
1024
1025/*
1026 * Hwmon device
1027 */
1028static ssize_t asus_hwmon_pwm1(struct device *dev,
1029                               struct device_attribute *attr,
1030                               char *buf)
1031{
1032        struct asus_wmi *asus = dev_get_drvdata(dev);
1033        u32 value;
1034        int err;
1035
1036        err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
1037
1038        if (err < 0)
1039                return err;
1040
1041        value &= 0xFF;
1042
1043        if (value == 1) /* Low Speed */
1044                value = 85;
1045        else if (value == 2)
1046                value = 170;
1047        else if (value == 3)
1048                value = 255;
1049        else if (value != 0) {
1050                pr_err("Unknown fan speed %#x", value);
1051                value = -1;
1052        }
1053
1054        return sprintf(buf, "%d\n", value);
1055}
1056
1057static ssize_t asus_hwmon_temp1(struct device *dev,
1058                                struct device_attribute *attr,
1059                                char *buf)
1060{
1061        struct asus_wmi *asus = dev_get_drvdata(dev);
1062        u32 value;
1063        int err;
1064
1065        err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value);
1066
1067        if (err < 0)
1068                return err;
1069
1070        value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000;
1071
1072        return sprintf(buf, "%d\n", value);
1073}
1074
1075static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0);
1076static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL, 0);
1077
1078static ssize_t
1079show_name(struct device *dev, struct device_attribute *attr, char *buf)
1080{
1081        return sprintf(buf, "asus\n");
1082}
1083static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
1084
1085static struct attribute *hwmon_attributes[] = {
1086        &sensor_dev_attr_pwm1.dev_attr.attr,
1087        &sensor_dev_attr_temp1_input.dev_attr.attr,
1088        &sensor_dev_attr_name.dev_attr.attr,
1089        NULL
1090};
1091
1092static umode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
1093                                          struct attribute *attr, int idx)
1094{
1095        struct device *dev = container_of(kobj, struct device, kobj);
1096        struct platform_device *pdev = to_platform_device(dev->parent);
1097        struct asus_wmi *asus = platform_get_drvdata(pdev);
1098        bool ok = true;
1099        int dev_id = -1;
1100        u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
1101
1102        if (attr == &sensor_dev_attr_pwm1.dev_attr.attr)
1103                dev_id = ASUS_WMI_DEVID_FAN_CTRL;
1104        else if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr)
1105                dev_id = ASUS_WMI_DEVID_THERMAL_CTRL;
1106
1107        if (dev_id != -1) {
1108                int err = asus_wmi_get_devstate(asus, dev_id, &value);
1109
1110                if (err < 0)
1111                        return 0; /* can't return negative here */
1112        }
1113
1114        if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
1115                /*
1116                 * We need to find a better way, probably using sfun,
1117                 * bits or spec ...
1118                 * Currently we disable it if:
1119                 * - ASUS_WMI_UNSUPPORTED_METHOD is returned
1120                 * - reverved bits are non-zero
1121                 * - sfun and presence bit are not set
1122                 */
1123                if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
1124                    || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
1125                        ok = false;
1126        } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) {
1127                /* If value is zero, something is clearly wrong */
1128                if (value == 0)
1129                        ok = false;
1130        }
1131
1132        return ok ? attr->mode : 0;
1133}
1134
1135static struct attribute_group hwmon_attribute_group = {
1136        .is_visible = asus_hwmon_sysfs_is_visible,
1137        .attrs = hwmon_attributes
1138};
1139
1140static void asus_wmi_hwmon_exit(struct asus_wmi *asus)
1141{
1142        struct device *hwmon;
1143
1144        hwmon = asus->hwmon_device;
1145        if (!hwmon)
1146                return;
1147        sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group);
1148        hwmon_device_unregister(hwmon);
1149        asus->hwmon_device = NULL;
1150}
1151
1152static int asus_wmi_hwmon_init(struct asus_wmi *asus)
1153{
1154        struct device *hwmon;
1155        int result;
1156
1157        hwmon = hwmon_device_register(&asus->platform_device->dev);
1158        if (IS_ERR(hwmon)) {
1159                pr_err("Could not register asus hwmon device\n");
1160                return PTR_ERR(hwmon);
1161        }
1162        dev_set_drvdata(hwmon, asus);
1163        asus->hwmon_device = hwmon;
1164        result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group);
1165        if (result)
1166                asus_wmi_hwmon_exit(asus);
1167        return result;
1168}
1169
1170/*
1171 * Backlight
1172 */
1173static int read_backlight_power(struct asus_wmi *asus)
1174{
1175        int ret;
1176        if (asus->driver->quirks->store_backlight_power)
1177                ret = !asus->driver->panel_power;
1178        else
1179                ret = asus_wmi_get_devstate_simple(asus,
1180                                                   ASUS_WMI_DEVID_BACKLIGHT);
1181
1182        if (ret < 0)
1183                return ret;
1184
1185        return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
1186}
1187
1188static int read_brightness_max(struct asus_wmi *asus)
1189{
1190        u32 retval;
1191        int err;
1192
1193        err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
1194
1195        if (err < 0)
1196                return err;
1197
1198        retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK;
1199        retval >>= 8;
1200
1201        if (!retval)
1202                return -ENODEV;
1203
1204        return retval;
1205}
1206
1207static int read_brightness(struct backlight_device *bd)
1208{
1209        struct asus_wmi *asus = bl_get_data(bd);
1210        u32 retval;
1211        int err;
1212
1213        err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
1214
1215        if (err < 0)
1216                return err;
1217
1218        return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
1219}
1220
1221static u32 get_scalar_command(struct backlight_device *bd)
1222{
1223        struct asus_wmi *asus = bl_get_data(bd);
1224        u32 ctrl_param = 0;
1225
1226        if ((asus->driver->brightness < bd->props.brightness) ||
1227            bd->props.brightness == bd->props.max_brightness)
1228                ctrl_param = 0x00008001;
1229        else if ((asus->driver->brightness > bd->props.brightness) ||
1230                 bd->props.brightness == 0)
1231                ctrl_param = 0x00008000;
1232
1233        asus->driver->brightness = bd->props.brightness;
1234
1235        return ctrl_param;
1236}
1237
1238static int update_bl_status(struct backlight_device *bd)
1239{
1240        struct asus_wmi *asus = bl_get_data(bd);
1241        u32 ctrl_param;
1242        int power, err = 0;
1243
1244        power = read_backlight_power(asus);
1245        if (power != -ENODEV && bd->props.power != power) {
1246                ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
1247                err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
1248                                            ctrl_param, NULL);
1249                if (asus->driver->quirks->store_backlight_power)
1250                        asus->driver->panel_power = bd->props.power;
1251
1252                /* When using scalar brightness, updating the brightness
1253                 * will mess with the backlight power */
1254                if (asus->driver->quirks->scalar_panel_brightness)
1255                        return err;
1256        }
1257
1258        if (asus->driver->quirks->scalar_panel_brightness)
1259                ctrl_param = get_scalar_command(bd);
1260        else
1261                ctrl_param = bd->props.brightness;
1262
1263        err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
1264                                    ctrl_param, NULL);
1265
1266        return err;
1267}
1268
1269static const struct backlight_ops asus_wmi_bl_ops = {
1270        .get_brightness = read_brightness,
1271        .update_status = update_bl_status,
1272};
1273
1274static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
1275{
1276        struct backlight_device *bd = asus->backlight_device;
1277        int old = bd->props.brightness;
1278        int new = old;
1279
1280        if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
1281                new = code - NOTIFY_BRNUP_MIN + 1;
1282        else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
1283                new = code - NOTIFY_BRNDOWN_MIN;
1284
1285        bd->props.brightness = new;
1286        backlight_update_status(bd);
1287        backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
1288
1289        return old;
1290}
1291
1292static int asus_wmi_backlight_init(struct asus_wmi *asus)
1293{
1294        struct backlight_device *bd;
1295        struct backlight_properties props;
1296        int max;
1297        int power;
1298
1299        max = read_brightness_max(asus);
1300
1301        if (max == -ENODEV)
1302                max = 0;
1303        else if (max < 0)
1304                return max;
1305
1306        power = read_backlight_power(asus);
1307
1308        if (power == -ENODEV)
1309                power = FB_BLANK_UNBLANK;
1310        else if (power < 0)
1311                return power;
1312
1313        memset(&props, 0, sizeof(struct backlight_properties));
1314        props.type = BACKLIGHT_PLATFORM;
1315        props.max_brightness = max;
1316        bd = backlight_device_register(asus->driver->name,
1317                                       &asus->platform_device->dev, asus,
1318                                       &asus_wmi_bl_ops, &props);
1319        if (IS_ERR(bd)) {
1320                pr_err("Could not register backlight device\n");
1321                return PTR_ERR(bd);
1322        }
1323
1324        asus->backlight_device = bd;
1325
1326        if (asus->driver->quirks->store_backlight_power)
1327                asus->driver->panel_power = power;
1328
1329        bd->props.brightness = read_brightness(bd);
1330        bd->props.power = power;
1331        backlight_update_status(bd);
1332
1333        asus->driver->brightness = bd->props.brightness;
1334
1335        return 0;
1336}
1337
1338static void asus_wmi_backlight_exit(struct asus_wmi *asus)
1339{
1340        if (asus->backlight_device)
1341                backlight_device_unregister(asus->backlight_device);
1342
1343        asus->backlight_device = NULL;
1344}
1345
1346static int is_display_toggle(int code)
1347{
1348        /* display toggle keys */
1349        if ((code >= 0x61 && code <= 0x67) ||
1350            (code >= 0x8c && code <= 0x93) ||
1351            (code >= 0xa0 && code <= 0xa7) ||
1352            (code >= 0xd0 && code <= 0xd5))
1353                return 1;
1354
1355        return 0;
1356}
1357
1358static void asus_wmi_notify(u32 value, void *context)
1359{
1360        struct asus_wmi *asus = context;
1361        struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
1362        union acpi_object *obj;
1363        acpi_status status;
1364        int code;
1365        int orig_code;
1366        unsigned int key_value = 1;
1367        bool autorelease = 1;
1368
1369        status = wmi_get_event_data(value, &response);
1370        if (status != AE_OK) {
1371                pr_err("bad event status 0x%x\n", status);
1372                return;
1373        }
1374
1375        obj = (union acpi_object *)response.pointer;
1376
1377        if (!obj || obj->type != ACPI_TYPE_INTEGER)
1378                goto exit;
1379
1380        code = obj->integer.value;
1381        orig_code = code;
1382
1383        if (asus->driver->key_filter) {
1384                asus->driver->key_filter(asus->driver, &code, &key_value,
1385                                         &autorelease);
1386                if (code == ASUS_WMI_KEY_IGNORE)
1387                        goto exit;
1388        }
1389
1390        if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
1391                code = ASUS_WMI_BRN_UP;
1392        else if (code >= NOTIFY_BRNDOWN_MIN &&
1393                 code <= NOTIFY_BRNDOWN_MAX)
1394                code = ASUS_WMI_BRN_DOWN;
1395
1396        if (code == ASUS_WMI_BRN_DOWN || code == ASUS_WMI_BRN_UP) {
1397                if (!acpi_video_backlight_support()) {
1398                        asus_wmi_backlight_notify(asus, orig_code);
1399                        goto exit;
1400                }
1401        }
1402
1403        if (is_display_toggle(code) &&
1404            asus->driver->quirks->no_display_toggle)
1405                goto exit;
1406
1407        if (!sparse_keymap_report_event(asus->inputdev, code,
1408                                        key_value, autorelease))
1409                pr_info("Unknown key %x pressed\n", code);
1410
1411exit:
1412        kfree(obj);
1413}
1414
1415/*
1416 * Sys helpers
1417 */
1418static int parse_arg(const char *buf, unsigned long count, int *val)
1419{
1420        if (!count)
1421                return 0;
1422        if (sscanf(buf, "%i", val) != 1)
1423                return -EINVAL;
1424        return count;
1425}
1426
1427static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
1428                             const char *buf, size_t count)
1429{
1430        u32 retval;
1431        int rv, err, value;
1432
1433        value = asus_wmi_get_devstate_simple(asus, devid);
1434        if (value == -ENODEV)   /* Check device presence */
1435                return value;
1436
1437        rv = parse_arg(buf, count, &value);
1438        err = asus_wmi_set_devstate(devid, value, &retval);
1439
1440        if (err < 0)
1441                return err;
1442
1443        return rv;
1444}
1445
1446static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
1447{
1448        int value = asus_wmi_get_devstate_simple(asus, devid);
1449
1450        if (value < 0)
1451                return value;
1452
1453        return sprintf(buf, "%d\n", value);
1454}
1455
1456#define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm)                  \
1457        static ssize_t show_##_name(struct device *dev,                 \
1458                                    struct device_attribute *attr,      \
1459                                    char *buf)                          \
1460        {                                                               \
1461                struct asus_wmi *asus = dev_get_drvdata(dev);           \
1462                                                                        \
1463                return show_sys_wmi(asus, _cm, buf);                    \
1464        }                                                               \
1465        static ssize_t store_##_name(struct device *dev,                \
1466                                     struct device_attribute *attr,     \
1467                                     const char *buf, size_t count)     \
1468        {                                                               \
1469                struct asus_wmi *asus = dev_get_drvdata(dev);           \
1470                                                                        \
1471                return store_sys_wmi(asus, _cm, buf, count);            \
1472        }                                                               \
1473        static struct device_attribute dev_attr_##_name = {             \
1474                .attr = {                                               \
1475                        .name = __stringify(_name),                     \
1476                        .mode = _mode },                                \
1477                .show   = show_##_name,                                 \
1478                .store  = store_##_name,                                \
1479        }
1480
1481ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
1482ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
1483ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
1484ASUS_WMI_CREATE_DEVICE_ATTR(lid_resume, 0644, ASUS_WMI_DEVID_LID_RESUME);
1485
1486static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
1487                           const char *buf, size_t count)
1488{
1489        int value, rv;
1490
1491        if (!count || sscanf(buf, "%i", &value) != 1)
1492                return -EINVAL;
1493        if (value < 0 || value > 2)
1494                return -EINVAL;
1495
1496        rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL);
1497        if (rv < 0)
1498                return rv;
1499
1500        return count;
1501}
1502
1503static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
1504
1505static struct attribute *platform_attributes[] = {
1506        &dev_attr_cpufv.attr,
1507        &dev_attr_camera.attr,
1508        &dev_attr_cardr.attr,
1509        &dev_attr_touchpad.attr,
1510        &dev_attr_lid_resume.attr,
1511        NULL
1512};
1513
1514static umode_t asus_sysfs_is_visible(struct kobject *kobj,
1515                                    struct attribute *attr, int idx)
1516{
1517        struct device *dev = container_of(kobj, struct device, kobj);
1518        struct platform_device *pdev = to_platform_device(dev);
1519        struct asus_wmi *asus = platform_get_drvdata(pdev);
1520        bool ok = true;
1521        int devid = -1;
1522
1523        if (attr == &dev_attr_camera.attr)
1524                devid = ASUS_WMI_DEVID_CAMERA;
1525        else if (attr == &dev_attr_cardr.attr)
1526                devid = ASUS_WMI_DEVID_CARDREADER;
1527        else if (attr == &dev_attr_touchpad.attr)
1528                devid = ASUS_WMI_DEVID_TOUCHPAD;
1529        else if (attr == &dev_attr_lid_resume.attr)
1530                devid = ASUS_WMI_DEVID_LID_RESUME;
1531
1532        if (devid != -1)
1533                ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
1534
1535        return ok ? attr->mode : 0;
1536}
1537
1538static struct attribute_group platform_attribute_group = {
1539        .is_visible = asus_sysfs_is_visible,
1540        .attrs = platform_attributes
1541};
1542
1543static void asus_wmi_sysfs_exit(struct platform_device *device)
1544{
1545        sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
1546}
1547
1548static int asus_wmi_sysfs_init(struct platform_device *device)
1549{
1550        return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
1551}
1552
1553/*
1554 * Platform device
1555 */
1556static int asus_wmi_platform_init(struct asus_wmi *asus)
1557{
1558        int rv;
1559
1560        /* INIT enable hotkeys on some models */
1561        if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
1562                pr_info("Initialization: %#x", rv);
1563
1564        /* We don't know yet what to do with this version... */
1565        if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
1566                pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF);
1567                asus->spec = rv;
1568        }
1569
1570        /*
1571         * The SFUN method probably allows the original driver to get the list
1572         * of features supported by a given model. For now, 0x0100 or 0x0800
1573         * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
1574         * The significance of others is yet to be found.
1575         */
1576        if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
1577                pr_info("SFUN value: %#x", rv);
1578                asus->sfun = rv;
1579        }
1580
1581        /*
1582         * Eee PC and Notebooks seems to have different method_id for DSTS,
1583         * but it may also be related to the BIOS's SPEC.
1584         * Note, on most Eeepc, there is no way to check if a method exist
1585         * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
1586         * but once again, SPEC may probably be used for that kind of things.
1587         */
1588        if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL))
1589                asus->dsts_id = ASUS_WMI_METHODID_DSTS;
1590        else
1591                asus->dsts_id = ASUS_WMI_METHODID_DSTS2;
1592
1593        /* CWAP allow to define the behavior of the Fn+F2 key,
1594         * this method doesn't seems to be present on Eee PCs */
1595        if (asus->driver->quirks->wapf >= 0)
1596                asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP,
1597                                      asus->driver->quirks->wapf, NULL);
1598
1599        return asus_wmi_sysfs_init(asus->platform_device);
1600}
1601
1602static void asus_wmi_platform_exit(struct asus_wmi *asus)
1603{
1604        asus_wmi_sysfs_exit(asus->platform_device);
1605}
1606
1607/*
1608 * debugfs
1609 */
1610struct asus_wmi_debugfs_node {
1611        struct asus_wmi *asus;
1612        char *name;
1613        int (*show) (struct seq_file *m, void *data);
1614};
1615
1616static int show_dsts(struct seq_file *m, void *data)
1617{
1618        struct asus_wmi *asus = m->private;
1619        int err;
1620        u32 retval = -1;
1621
1622        if (get_securelevel() > 0)
1623                return -EPERM;
1624
1625        err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
1626
1627        if (err < 0)
1628                return err;
1629
1630        seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval);
1631
1632        return 0;
1633}
1634
1635static int show_devs(struct seq_file *m, void *data)
1636{
1637        struct asus_wmi *asus = m->private;
1638        int err;
1639        u32 retval = -1;
1640
1641        if (get_securelevel() > 0)
1642                return -EPERM;
1643
1644        err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
1645                                    &retval);
1646
1647        if (err < 0)
1648                return err;
1649
1650        seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id,
1651                   asus->debug.ctrl_param, retval);
1652
1653        return 0;
1654}
1655
1656static int show_call(struct seq_file *m, void *data)
1657{
1658        struct asus_wmi *asus = m->private;
1659        struct bios_args args = {
1660                .arg0 = asus->debug.dev_id,
1661                .arg1 = asus->debug.ctrl_param,
1662        };
1663        struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
1664        struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
1665        union acpi_object *obj;
1666        acpi_status status;
1667
1668        if (get_securelevel() > 0)
1669                return -EPERM;
1670
1671        status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1672                                     1, asus->debug.method_id,
1673                                     &input, &output);
1674
1675        if (ACPI_FAILURE(status))
1676                return -EIO;
1677
1678        obj = (union acpi_object *)output.pointer;
1679        if (obj && obj->type == ACPI_TYPE_INTEGER)
1680                seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
1681                           asus->debug.dev_id, asus->debug.ctrl_param,
1682                           (u32) obj->integer.value);
1683        else
1684                seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id,
1685                           asus->debug.dev_id, asus->debug.ctrl_param,
1686                           obj ? obj->type : -1);
1687
1688        kfree(obj);
1689
1690        return 0;
1691}
1692
1693static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
1694        {NULL, "devs", show_devs},
1695        {NULL, "dsts", show_dsts},
1696        {NULL, "call", show_call},
1697};
1698
1699static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
1700{
1701        struct asus_wmi_debugfs_node *node = inode->i_private;
1702
1703        return single_open(file, node->show, node->asus);
1704}
1705
1706static const struct file_operations asus_wmi_debugfs_io_ops = {
1707        .owner = THIS_MODULE,
1708        .open = asus_wmi_debugfs_open,
1709        .read = seq_read,
1710        .llseek = seq_lseek,
1711        .release = single_release,
1712};
1713
1714static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
1715{
1716        debugfs_remove_recursive(asus->debug.root);
1717}
1718
1719static int asus_wmi_debugfs_init(struct asus_wmi *asus)
1720{
1721        struct dentry *dent;
1722        int i;
1723
1724        asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
1725        if (!asus->debug.root) {
1726                pr_err("failed to create debugfs directory");
1727                goto error_debugfs;
1728        }
1729
1730        dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR,
1731                                  asus->debug.root, &asus->debug.method_id);
1732        if (!dent)
1733                goto error_debugfs;
1734
1735        dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
1736                                  asus->debug.root, &asus->debug.dev_id);
1737        if (!dent)
1738                goto error_debugfs;
1739
1740        dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
1741                                  asus->debug.root, &asus->debug.ctrl_param);
1742        if (!dent)
1743                goto error_debugfs;
1744
1745        for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
1746                struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
1747
1748                node->asus = asus;
1749                dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
1750                                           asus->debug.root, node,
1751                                           &asus_wmi_debugfs_io_ops);
1752                if (!dent) {
1753                        pr_err("failed to create debug file: %s\n", node->name);
1754                        goto error_debugfs;
1755                }
1756        }
1757
1758        return 0;
1759
1760error_debugfs:
1761        asus_wmi_debugfs_exit(asus);
1762        return -ENOMEM;
1763}
1764
1765/*
1766 * WMI Driver
1767 */
1768static int asus_wmi_add(struct platform_device *pdev)
1769{
1770        struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1771        struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1772        struct asus_wmi *asus;
1773        acpi_status status;
1774        int err;
1775        u32 result;
1776
1777        asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
1778        if (!asus)
1779                return -ENOMEM;
1780
1781        asus->driver = wdrv;
1782        asus->platform_device = pdev;
1783        wdrv->platform_device = pdev;
1784        platform_set_drvdata(asus->platform_device, asus);
1785
1786        if (wdrv->detect_quirks)
1787                wdrv->detect_quirks(asus->driver);
1788
1789        err = asus_wmi_platform_init(asus);
1790        if (err)
1791                goto fail_platform;
1792
1793        err = asus_wmi_input_init(asus);
1794        if (err)
1795                goto fail_input;
1796
1797        err = asus_wmi_hwmon_init(asus);
1798        if (err)
1799                goto fail_hwmon;
1800
1801        err = asus_wmi_led_init(asus);
1802        if (err)
1803                goto fail_leds;
1804
1805        err = asus_wmi_rfkill_init(asus);
1806        if (err)
1807                goto fail_rfkill;
1808
1809        if (asus->driver->quirks->wmi_backlight_power)
1810                acpi_video_dmi_promote_vendor();
1811        if (!acpi_video_backlight_support()) {
1812                pr_info("Disabling ACPI video driver\n");
1813                acpi_video_unregister();
1814                err = asus_wmi_backlight_init(asus);
1815                if (err && err != -ENODEV)
1816                        goto fail_backlight;
1817        } else
1818                pr_info("Backlight controlled by ACPI video driver\n");
1819
1820        status = wmi_install_notify_handler(asus->driver->event_guid,
1821                                            asus_wmi_notify, asus);
1822        if (ACPI_FAILURE(status)) {
1823                pr_err("Unable to register notify handler - %d\n", status);
1824                err = -ENODEV;
1825                goto fail_wmi_handler;
1826        }
1827
1828        err = asus_wmi_debugfs_init(asus);
1829        if (err)
1830                goto fail_debugfs;
1831
1832        asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result);
1833        if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
1834                asus->driver->wlan_ctrl_by_user = 1;
1835
1836        return 0;
1837
1838fail_debugfs:
1839        wmi_remove_notify_handler(asus->driver->event_guid);
1840fail_wmi_handler:
1841        asus_wmi_backlight_exit(asus);
1842fail_backlight:
1843        asus_wmi_rfkill_exit(asus);
1844fail_rfkill:
1845        asus_wmi_led_exit(asus);
1846fail_leds:
1847        asus_wmi_hwmon_exit(asus);
1848fail_hwmon:
1849        asus_wmi_input_exit(asus);
1850fail_input:
1851        asus_wmi_platform_exit(asus);
1852fail_platform:
1853        kfree(asus);
1854        return err;
1855}
1856
1857static int asus_wmi_remove(struct platform_device *device)
1858{
1859        struct asus_wmi *asus;
1860
1861        asus = platform_get_drvdata(device);
1862        wmi_remove_notify_handler(asus->driver->event_guid);
1863        asus_wmi_backlight_exit(asus);
1864        asus_wmi_input_exit(asus);
1865        asus_wmi_hwmon_exit(asus);
1866        asus_wmi_led_exit(asus);
1867        asus_wmi_rfkill_exit(asus);
1868        asus_wmi_debugfs_exit(asus);
1869        asus_wmi_platform_exit(asus);
1870
1871        kfree(asus);
1872        return 0;
1873}
1874
1875/*
1876 * Platform driver - hibernate/resume callbacks
1877 */
1878static int asus_hotk_thaw(struct device *device)
1879{
1880        struct asus_wmi *asus = dev_get_drvdata(device);
1881
1882        if (asus->wlan.rfkill) {
1883                bool wlan;
1884
1885                /*
1886                 * Work around bios bug - acpi _PTS turns off the wireless led
1887                 * during suspend.  Normally it restores it on resume, but
1888                 * we should kick it ourselves in case hibernation is aborted.
1889                 */
1890                wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
1891                asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL);
1892        }
1893
1894        return 0;
1895}
1896
1897static int asus_hotk_restore(struct device *device)
1898{
1899        struct asus_wmi *asus = dev_get_drvdata(device);
1900        int bl;
1901
1902        /* Refresh both wlan rfkill state and pci hotplug */
1903        if (asus->wlan.rfkill)
1904                asus_rfkill_hotplug(asus);
1905
1906        if (asus->bluetooth.rfkill) {
1907                bl = !asus_wmi_get_devstate_simple(asus,
1908                                                   ASUS_WMI_DEVID_BLUETOOTH);
1909                rfkill_set_sw_state(asus->bluetooth.rfkill, bl);
1910        }
1911        if (asus->wimax.rfkill) {
1912                bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX);
1913                rfkill_set_sw_state(asus->wimax.rfkill, bl);
1914        }
1915        if (asus->wwan3g.rfkill) {
1916                bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G);
1917                rfkill_set_sw_state(asus->wwan3g.rfkill, bl);
1918        }
1919        if (asus->gps.rfkill) {
1920                bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS);
1921                rfkill_set_sw_state(asus->gps.rfkill, bl);
1922        }
1923        if (asus->uwb.rfkill) {
1924                bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB);
1925                rfkill_set_sw_state(asus->uwb.rfkill, bl);
1926        }
1927
1928        return 0;
1929}
1930
1931static const struct dev_pm_ops asus_pm_ops = {
1932        .thaw = asus_hotk_thaw,
1933        .restore = asus_hotk_restore,
1934};
1935
1936static int asus_wmi_probe(struct platform_device *pdev)
1937{
1938        struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
1939        struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
1940        int ret;
1941
1942        if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1943                pr_warn("Management GUID not found\n");
1944                return -ENODEV;
1945        }
1946
1947        if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
1948                pr_warn("Event GUID not found\n");
1949                return -ENODEV;
1950        }
1951
1952        if (wdrv->probe) {
1953                ret = wdrv->probe(pdev);
1954                if (ret)
1955                        return ret;
1956        }
1957
1958        return asus_wmi_add(pdev);
1959}
1960
1961static bool used;
1962
1963int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver)
1964{
1965        struct platform_driver *platform_driver;
1966        struct platform_device *platform_device;
1967
1968        if (used)
1969                return -EBUSY;
1970
1971        platform_driver = &driver->platform_driver;
1972        platform_driver->remove = asus_wmi_remove;
1973        platform_driver->driver.owner = driver->owner;
1974        platform_driver->driver.name = driver->name;
1975        platform_driver->driver.pm = &asus_pm_ops;
1976
1977        platform_device = platform_create_bundle(platform_driver,
1978                                                 asus_wmi_probe,
1979                                                 NULL, 0, NULL, 0);
1980        if (IS_ERR(platform_device))
1981                return PTR_ERR(platform_device);
1982
1983        used = true;
1984        return 0;
1985}
1986EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
1987
1988void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
1989{
1990        platform_device_unregister(driver->platform_device);
1991        platform_driver_unregister(&driver->platform_driver);
1992        used = false;
1993}
1994EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
1995
1996static int __init asus_wmi_init(void)
1997{
1998        if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
1999                pr_info("Asus Management GUID not found");
2000                return -ENODEV;
2001        }
2002
2003        pr_info("ASUS WMI generic driver loaded");
2004        return 0;
2005}
2006
2007static void __exit asus_wmi_exit(void)
2008{
2009        pr_info("ASUS WMI generic driver unloaded");
2010}
2011
2012module_init(asus_wmi_init);
2013module_exit(asus_wmi_exit);
2014