diff options
-rw-r--r-- | drivers/platform/x86/intel_mid_powerbtn.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 213e79ba68d5..f1ae5078b7ec 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c | |||
@@ -23,58 +23,48 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
26 | |||
26 | #include <asm/intel_scu_ipc.h> | 27 | #include <asm/intel_scu_ipc.h> |
27 | 28 | ||
28 | #define DRIVER_NAME "msic_power_btn" | 29 | #define DRIVER_NAME "msic_power_btn" |
29 | 30 | ||
30 | #define MSIC_IRQ_STAT 0x02 | ||
31 | #define MSIC_IRQ_PB (1 << 0) | ||
32 | #define MSIC_PB_CONFIG 0x3e | ||
33 | #define MSIC_PB_STATUS 0x3f | 31 | #define MSIC_PB_STATUS 0x3f |
34 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ | 32 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ |
35 | |||
36 | struct mfld_pb_priv { | ||
37 | struct input_dev *input; | ||
38 | unsigned int irq; | ||
39 | }; | ||
40 | 33 | ||
41 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) | 34 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) |
42 | { | 35 | { |
43 | struct mfld_pb_priv *priv = dev_id; | 36 | struct input_dev *input = dev_id; |
44 | int ret; | 37 | int ret; |
45 | u8 pbstat; | 38 | u8 pbstat; |
46 | 39 | ||
47 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); | 40 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); |
48 | if (ret < 0) | 41 | if (ret < 0) { |
49 | return IRQ_HANDLED; | 42 | dev_err(input->dev.parent, "Read error %d while reading" |
50 | 43 | " MSIC_PB_STATUS\n", ret); | |
51 | input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL)); | 44 | } else { |
52 | input_sync(priv->input); | 45 | input_event(input, EV_KEY, KEY_POWER, |
46 | !(pbstat & MSIC_PB_LEVEL)); | ||
47 | input_sync(input); | ||
48 | } | ||
53 | 49 | ||
54 | return IRQ_HANDLED; | 50 | return IRQ_HANDLED; |
55 | } | 51 | } |
56 | 52 | ||
57 | static int __devinit mfld_pb_probe(struct platform_device *pdev) | 53 | static int __devinit mfld_pb_probe(struct platform_device *pdev) |
58 | { | 54 | { |
59 | struct mfld_pb_priv *priv; | ||
60 | struct input_dev *input; | 55 | struct input_dev *input; |
61 | int irq; | 56 | int irq = platform_get_irq(pdev, 0); |
62 | int error; | 57 | int error; |
63 | 58 | ||
64 | irq = platform_get_irq(pdev, 0); | ||
65 | if (irq < 0) | 59 | if (irq < 0) |
66 | return -EINVAL; | 60 | return -EINVAL; |
67 | 61 | ||
68 | priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL); | ||
69 | input = input_allocate_device(); | 62 | input = input_allocate_device(); |
70 | if (!priv || !input) { | 63 | if (!input) { |
71 | error = -ENOMEM; | 64 | dev_err(&pdev->dev, "Input device allocation error\n"); |
72 | goto err_free_mem; | 65 | return -ENOMEM; |
73 | } | 66 | } |
74 | 67 | ||
75 | priv->input = input; | ||
76 | priv->irq = irq; | ||
77 | |||
78 | input->name = pdev->name; | 68 | input->name = pdev->name; |
79 | input->phys = "power-button/input0"; | 69 | input->phys = "power-button/input0"; |
80 | input->id.bustype = BUS_HOST; | 70 | input->id.bustype = BUS_HOST; |
@@ -82,42 +72,40 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) | |||
82 | 72 | ||
83 | input_set_capability(input, EV_KEY, KEY_POWER); | 73 | input_set_capability(input, EV_KEY, KEY_POWER); |
84 | 74 | ||
85 | error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr, | 75 | error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, |
86 | 0, DRIVER_NAME, priv); | 76 | DRIVER_NAME, input); |
87 | if (error) { | 77 | if (error) { |
88 | dev_err(&pdev->dev, | 78 | dev_err(&pdev->dev, "Unable to request irq %d for mfld power" |
89 | "unable to request irq %d for mfld power button\n", | 79 | "button\n", irq); |
90 | irq); | 80 | goto err_free_input; |
91 | goto err_free_mem; | ||
92 | } | 81 | } |
93 | 82 | ||
94 | error = input_register_device(input); | 83 | error = input_register_device(input); |
95 | if (error) { | 84 | if (error) { |
96 | dev_err(&pdev->dev, | 85 | dev_err(&pdev->dev, "Unable to register input dev, error " |
97 | "unable to register input dev, error %d\n", error); | 86 | "%d\n", error); |
98 | goto err_free_irq; | 87 | goto err_free_irq; |
99 | } | 88 | } |
100 | 89 | ||
101 | platform_set_drvdata(pdev, priv); | 90 | platform_set_drvdata(pdev, input); |
102 | return 0; | 91 | return 0; |
103 | 92 | ||
104 | err_free_irq: | 93 | err_free_irq: |
105 | free_irq(priv->irq, priv); | 94 | free_irq(irq, input); |
106 | err_free_mem: | 95 | err_free_input: |
107 | input_free_device(input); | 96 | input_free_device(input); |
108 | kfree(priv); | ||
109 | return error; | 97 | return error; |
110 | } | 98 | } |
111 | 99 | ||
112 | static int __devexit mfld_pb_remove(struct platform_device *pdev) | 100 | static int __devexit mfld_pb_remove(struct platform_device *pdev) |
113 | { | 101 | { |
114 | struct mfld_pb_priv *priv = platform_get_drvdata(pdev); | 102 | struct input_dev *input = platform_get_drvdata(pdev); |
115 | 103 | int irq = platform_get_irq(pdev, 0); | |
116 | free_irq(priv->irq, priv); | ||
117 | input_unregister_device(priv->input); | ||
118 | kfree(priv); | ||
119 | 104 | ||
105 | free_irq(irq, input); | ||
106 | input_unregister_device(input); | ||
120 | platform_set_drvdata(pdev, NULL); | 107 | platform_set_drvdata(pdev, NULL); |
108 | |||
121 | return 0; | 109 | return 0; |
122 | } | 110 | } |
123 | 111 | ||