summaryrefslogtreecommitdiff
path: root/drivers/platform/surface
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/surface')
-rw-r--r--drivers/platform/surface/surface_hotplug.c2
-rw-r--r--drivers/platform/surface/surfacepro3_button.c71
2 files changed, 41 insertions, 32 deletions
diff --git a/drivers/platform/surface/surface_hotplug.c b/drivers/platform/surface/surface_hotplug.c
index c0d83ed5a208..33a8a9d41900 100644
--- a/drivers/platform/surface/surface_hotplug.c
+++ b/drivers/platform/surface/surface_hotplug.c
@@ -14,7 +14,7 @@
*/
#include <linux/acpi.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/drivers/platform/surface/surfacepro3_button.c b/drivers/platform/surface/surfacepro3_button.c
index 9bd39f09c7db..0293bc517b54 100644
--- a/drivers/platform/surface/surfacepro3_button.c
+++ b/drivers/platform/surface/surfacepro3_button.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/input.h>
#include <linux/acpi.h>
+#include <linux/platform_device.h>
#include <acpi/button.h>
#define SURFACE_PRO3_BUTTON_HID "MSHW0028"
@@ -72,9 +73,10 @@ struct surface_button {
bool suspended;
};
-static void surface_button_notify(struct acpi_device *device, u32 event)
+static void surface_button_notify(acpi_handle handle, u32 event, void *data)
{
- struct surface_button *button = acpi_driver_data(device);
+ struct device *dev = data;
+ struct surface_button *button = dev_get_drvdata(dev);
struct input_dev *input;
int key_code = KEY_RESERVED;
bool pressed = false;
@@ -109,18 +111,17 @@ static void surface_button_notify(struct acpi_device *device, u32 event)
key_code = KEY_VOLUMEDOWN;
break;
case SURFACE_BUTTON_NOTIFY_TABLET_MODE:
- dev_warn_once(&device->dev, "Tablet mode is not supported\n");
+ dev_warn_once(dev, "Tablet mode is not supported\n");
break;
default:
- dev_info_ratelimited(&device->dev,
- "Unsupported event [0x%x]\n", event);
+ dev_info_ratelimited(dev, "Unsupported event [0x%x]\n", event);
break;
}
input = button->input;
if (key_code == KEY_RESERVED)
return;
if (pressed)
- pm_wakeup_dev_event(&device->dev, 0, button->suspended);
+ pm_wakeup_dev_event(dev, 0, button->suspended);
if (button->suspended)
return;
input_report_key(input, key_code, pressed?1:0);
@@ -130,8 +131,7 @@ static void surface_button_notify(struct acpi_device *device, u32 event)
#ifdef CONFIG_PM_SLEEP
static int surface_button_suspend(struct device *dev)
{
- struct acpi_device *device = to_acpi_device(dev);
- struct surface_button *button = acpi_driver_data(device);
+ struct surface_button *button = dev_get_drvdata(dev);
button->suspended = true;
return 0;
@@ -139,8 +139,7 @@ static int surface_button_suspend(struct device *dev)
static int surface_button_resume(struct device *dev)
{
- struct acpi_device *device = to_acpi_device(dev);
- struct surface_button *button = acpi_driver_data(device);
+ struct surface_button *button = dev_get_drvdata(dev);
button->suspended = false;
return 0;
@@ -155,9 +154,8 @@ static int surface_button_resume(struct device *dev)
* Returns true if the driver should bind to this device, i.e. the device is
* either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
*/
-static bool surface_button_check_MSHW0040(struct acpi_device *dev)
+static bool surface_button_check_MSHW0040(struct device *dev, acpi_handle handle)
{
- acpi_handle handle = dev->handle;
union acpi_object *result;
u64 oem_platform_rev = 0; // valid revisions are nonzero
@@ -179,14 +177,15 @@ static bool surface_button_check_MSHW0040(struct acpi_device *dev)
ACPI_FREE(result);
}
- dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
+ dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
return oem_platform_rev == 0;
}
-static int surface_button_add(struct acpi_device *device)
+static int surface_button_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct surface_button *button;
struct input_dev *input;
const char *hid = acpi_device_hid(device);
@@ -196,14 +195,14 @@ static int surface_button_add(struct acpi_device *device)
strlen(SURFACE_BUTTON_OBJ_NAME)))
return -ENODEV;
- if (!surface_button_check_MSHW0040(device))
+ if (!surface_button_check_MSHW0040(&pdev->dev, device->handle))
return -ENODEV;
button = kzalloc_obj(struct surface_button);
if (!button)
return -ENOMEM;
- device->driver_data = button;
+ platform_set_drvdata(pdev, button);
button->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
@@ -216,7 +215,7 @@ static int surface_button_add(struct acpi_device *device)
input->name = acpi_device_name(device);
input->phys = button->phys;
input->id.bustype = BUS_HOST;
- input->dev.parent = &device->dev;
+ input->dev.parent = &pdev->dev;
input_set_capability(input, EV_KEY, KEY_POWER);
input_set_capability(input, EV_KEY, KEY_LEFTMETA);
input_set_capability(input, EV_KEY, KEY_VOLUMEUP);
@@ -226,8 +225,17 @@ static int surface_button_add(struct acpi_device *device)
if (error)
goto err_free_input;
- device_init_wakeup(&device->dev, true);
- dev_info(&device->dev, "%s [%s]\n", acpi_device_name(device),
+ device_init_wakeup(&pdev->dev, true);
+
+ error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ surface_button_notify, &pdev->dev);
+ if (error) {
+ device_init_wakeup(&pdev->dev, false);
+ input_unregister_device(input);
+ goto err_free_button;
+ }
+
+ dev_info(&pdev->dev, "%s [%s]\n", acpi_device_name(device),
acpi_device_bid(device));
return 0;
@@ -238,10 +246,13 @@ static int surface_button_add(struct acpi_device *device)
return error;
}
-static void surface_button_remove(struct acpi_device *device)
+static void surface_button_remove(struct platform_device *pdev)
{
- struct surface_button *button = acpi_driver_data(device);
+ struct surface_button *button = platform_get_drvdata(pdev);
+ acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+ ACPI_DEVICE_NOTIFY, surface_button_notify);
+ device_init_wakeup(&pdev->dev, false);
input_unregister_device(button->input);
kfree(button);
}
@@ -249,16 +260,14 @@ static void surface_button_remove(struct acpi_device *device)
static SIMPLE_DEV_PM_OPS(surface_button_pm,
surface_button_suspend, surface_button_resume);
-static struct acpi_driver surface_button_driver = {
- .name = "surface_pro3_button",
- .class = "SurfacePro3",
- .ids = surface_button_device_ids,
- .ops = {
- .add = surface_button_add,
- .remove = surface_button_remove,
- .notify = surface_button_notify,
+static struct platform_driver surface_button_driver = {
+ .probe = surface_button_probe,
+ .remove = surface_button_remove,
+ .driver = {
+ .name = "surface_pro3_button",
+ .acpi_match_table = surface_button_device_ids,
+ .pm = &surface_button_pm,
},
- .drv.pm = &surface_button_pm,
};
-module_acpi_driver(surface_button_driver);
+module_platform_driver(surface_button_driver);