diff options
-rw-r--r-- | drivers/input/keyboard/hil_kbd.c | 272 |
1 files changed, 140 insertions, 132 deletions
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index f732893a960e..fe57044e9e54 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
40 | #include <linux/semaphore.h> | 40 | #include <linux/completion.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/pci_ids.h> | 42 | #include <linux/pci_ids.h> |
43 | 43 | ||
@@ -81,135 +81,128 @@ struct hil_kbd { | |||
81 | char exd[HIL_KBD_MAX_LENGTH]; /* EXD record */ | 81 | char exd[HIL_KBD_MAX_LENGTH]; /* EXD record */ |
82 | char rnm[HIL_KBD_MAX_LENGTH + 1]; /* RNM record + NULL term. */ | 82 | char rnm[HIL_KBD_MAX_LENGTH + 1]; /* RNM record + NULL term. */ |
83 | 83 | ||
84 | /* Something to sleep around with. */ | 84 | struct completion cmd_done; |
85 | struct semaphore sem; | ||
86 | }; | 85 | }; |
87 | 86 | ||
88 | /* Process a complete packet after transfer from the HIL */ | 87 | static bool hil_kbd_is_command_response(hil_packet p) |
89 | static void hil_kbd_process_record(struct hil_kbd *kbd) | ||
90 | { | 88 | { |
91 | struct input_dev *dev = kbd->dev; | 89 | if ((p & ~HIL_CMDCT_POL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
92 | hil_packet *data = kbd->data; | 90 | return false; |
93 | hil_packet p; | ||
94 | int idx, i, cnt; | ||
95 | 91 | ||
96 | idx = kbd->idx4/4; | 92 | if ((p & ~HIL_CMDCT_RPL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) |
97 | p = data[idx - 1]; | 93 | return false; |
94 | |||
95 | return true; | ||
96 | } | ||
97 | |||
98 | static void hil_kbd_handle_command_response(struct hil_kbd *kbd) | ||
99 | { | ||
100 | hil_packet p; | ||
101 | char *buf; | ||
102 | int i, idx; | ||
98 | 103 | ||
99 | if ((p & ~HIL_CMDCT_POL) == | 104 | idx = kbd->idx4 / 4; |
100 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) | 105 | p = kbd->data[idx - 1]; |
101 | goto report; | ||
102 | if ((p & ~HIL_CMDCT_RPL) == | ||
103 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | ||
104 | goto report; | ||
105 | 106 | ||
106 | /* Not a poll response. See if we are loading config records. */ | ||
107 | switch (p & HIL_PKT_DATA_MASK) { | 107 | switch (p & HIL_PKT_DATA_MASK) { |
108 | case HIL_CMD_IDD: | 108 | case HIL_CMD_IDD: |
109 | for (i = 0; i < idx; i++) | 109 | buf = kbd->idd; |
110 | kbd->idd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
111 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
112 | kbd->idd[i] = 0; | ||
113 | break; | 110 | break; |
114 | 111 | ||
115 | case HIL_CMD_RSC: | 112 | case HIL_CMD_RSC: |
116 | for (i = 0; i < idx; i++) | 113 | buf = kbd->rsc; |
117 | kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
118 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
119 | kbd->rsc[i] = 0; | ||
120 | break; | 114 | break; |
121 | 115 | ||
122 | case HIL_CMD_EXD: | 116 | case HIL_CMD_EXD: |
123 | for (i = 0; i < idx; i++) | 117 | buf = kbd->exd; |
124 | kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | ||
125 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
126 | kbd->exd[i] = 0; | ||
127 | break; | 118 | break; |
128 | 119 | ||
129 | case HIL_CMD_RNM: | 120 | case HIL_CMD_RNM: |
130 | for (i = 0; i < idx; i++) | 121 | kbd->rnm[HIL_KBD_MAX_LENGTH] = 0; |
131 | kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; | 122 | buf = kbd->rnm; |
132 | for (; i < HIL_KBD_MAX_LENGTH + 1; i++) | ||
133 | kbd->rnm[i] = '\0'; | ||
134 | break; | 123 | break; |
135 | 124 | ||
136 | default: | 125 | default: |
137 | /* These occur when device isn't present */ | 126 | /* These occur when device isn't present */ |
138 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) | 127 | if (p != (HIL_ERR_INT | HIL_PKT_CMD)) { |
139 | break; | 128 | /* Anything else we'd like to know about. */ |
140 | /* Anything else we'd like to know about. */ | 129 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); |
141 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | 130 | } |
142 | break; | 131 | goto out; |
143 | } | 132 | } |
144 | goto out; | ||
145 | 133 | ||
146 | report: | 134 | for (i = 0; i < idx; i++) |
147 | cnt = 1; | 135 | buf[i] = kbd->data[i] & HIL_PKT_DATA_MASK; |
136 | for (; i < HIL_KBD_MAX_LENGTH; i++) | ||
137 | buf[i] = 0; | ||
138 | out: | ||
139 | complete(&kbd->cmd_done); | ||
140 | } | ||
141 | |||
142 | static void hil_kbd_handle_key_events(struct hil_kbd *kbd) | ||
143 | { | ||
144 | struct input_dev *dev = kbd->dev; | ||
145 | int idx = kbd->idx4 / 4; | ||
146 | int i; | ||
147 | |||
148 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { | 148 | switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { |
149 | case HIL_POL_CHARTYPE_NONE: | 149 | case HIL_POL_CHARTYPE_NONE: |
150 | break; | 150 | return; |
151 | 151 | ||
152 | case HIL_POL_CHARTYPE_ASCII: | 152 | case HIL_POL_CHARTYPE_ASCII: |
153 | while (cnt < idx - 1) | 153 | for (i = 1; i < idx - 1; i++) |
154 | input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); | 154 | input_report_key(dev, kbd->data[i] & 0x7f, 1); |
155 | break; | 155 | break; |
156 | 156 | ||
157 | case HIL_POL_CHARTYPE_RSVD1: | 157 | case HIL_POL_CHARTYPE_RSVD1: |
158 | case HIL_POL_CHARTYPE_RSVD2: | 158 | case HIL_POL_CHARTYPE_RSVD2: |
159 | case HIL_POL_CHARTYPE_BINARY: | 159 | case HIL_POL_CHARTYPE_BINARY: |
160 | while (cnt < idx - 1) | 160 | for (i = 1; i < idx - 1; i++) |
161 | input_report_key(dev, kbd->data[cnt++], 1); | 161 | input_report_key(dev, kbd->data[i], 1); |
162 | break; | 162 | break; |
163 | 163 | ||
164 | case HIL_POL_CHARTYPE_SET1: | 164 | case HIL_POL_CHARTYPE_SET1: |
165 | while (cnt < idx - 1) { | 165 | for (i = 1; i < idx - 1; i++) { |
166 | unsigned int key; | 166 | unsigned int key = kbd->data[i]; |
167 | int up; | 167 | int up = key & HIL_KBD_SET1_UPBIT; |
168 | key = kbd->data[cnt++]; | 168 | |
169 | up = key & HIL_KBD_SET1_UPBIT; | ||
170 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 169 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
171 | key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT]; | 170 | key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT]; |
172 | if (key != KEY_RESERVED) | 171 | input_report_key(dev, key, !up); |
173 | input_report_key(dev, key, !up); | ||
174 | } | 172 | } |
175 | break; | 173 | break; |
176 | 174 | ||
177 | case HIL_POL_CHARTYPE_SET2: | 175 | case HIL_POL_CHARTYPE_SET2: |
178 | while (cnt < idx - 1) { | 176 | for (i = 1; i < idx - 1; i++) { |
179 | unsigned int key; | 177 | unsigned int key = kbd->data[i]; |
180 | int up; | 178 | int up = key & HIL_KBD_SET2_UPBIT; |
181 | key = kbd->data[cnt++]; | 179 | |
182 | up = key & HIL_KBD_SET2_UPBIT; | ||
183 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 180 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
184 | key = key >> HIL_KBD_SET2_SHIFT; | 181 | key = key >> HIL_KBD_SET2_SHIFT; |
185 | if (key != KEY_RESERVED) | 182 | input_report_key(dev, key, !up); |
186 | input_report_key(dev, key, !up); | ||
187 | } | 183 | } |
188 | break; | 184 | break; |
189 | 185 | ||
190 | case HIL_POL_CHARTYPE_SET3: | 186 | case HIL_POL_CHARTYPE_SET3: |
191 | while (cnt < idx - 1) { | 187 | for (i = 1; i < idx - 1; i++) { |
192 | unsigned int key; | 188 | unsigned int key = kbd->data[i]; |
193 | int up; | 189 | int up = key & HIL_KBD_SET3_UPBIT; |
194 | key = kbd->data[cnt++]; | 190 | |
195 | up = key & HIL_KBD_SET3_UPBIT; | ||
196 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); | 191 | key &= (~HIL_KBD_SET1_UPBIT & 0xff); |
197 | key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT]; | 192 | key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT]; |
198 | if (key != KEY_RESERVED) | 193 | input_report_key(dev, key, !up); |
199 | input_report_key(dev, key, !up); | ||
200 | } | 194 | } |
201 | break; | 195 | break; |
202 | } | 196 | } |
203 | out: | 197 | |
204 | kbd->idx4 = 0; | 198 | input_sync(dev); |
205 | up(&kbd->sem); | ||
206 | } | 199 | } |
207 | 200 | ||
208 | static void hil_kbd_process_err(struct hil_kbd *kbd) | 201 | static void hil_kbd_process_err(struct hil_kbd *kbd) |
209 | { | 202 | { |
210 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | 203 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); |
211 | kbd->idx4 = 0; | 204 | kbd->idx4 = 0; |
212 | up(&kbd->sem); | 205 | complete(&kbd->cmd_done); /* just in case somebody is waiting */ |
213 | } | 206 | } |
214 | 207 | ||
215 | static irqreturn_t hil_kbd_interrupt(struct serio *serio, | 208 | static irqreturn_t hil_kbd_interrupt(struct serio *serio, |
@@ -222,11 +215,12 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio, | |||
222 | kbd = serio_get_drvdata(serio); | 215 | kbd = serio_get_drvdata(serio); |
223 | BUG_ON(kbd == NULL); | 216 | BUG_ON(kbd == NULL); |
224 | 217 | ||
225 | if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { | 218 | if (kbd->idx4 >= HIL_KBD_MAX_LENGTH * sizeof(hil_packet)) { |
226 | hil_kbd_process_err(kbd); | 219 | hil_kbd_process_err(kbd); |
227 | return IRQ_HANDLED; | 220 | goto out; |
228 | } | 221 | } |
229 | idx = kbd->idx4/4; | 222 | |
223 | idx = kbd->idx4 / 4; | ||
230 | if (!(kbd->idx4 % 4)) | 224 | if (!(kbd->idx4 % 4)) |
231 | kbd->data[idx] = 0; | 225 | kbd->data[idx] = 0; |
232 | packet = kbd->data[idx]; | 226 | packet = kbd->data[idx]; |
@@ -234,22 +228,25 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio, | |||
234 | kbd->data[idx] = packet; | 228 | kbd->data[idx] = packet; |
235 | 229 | ||
236 | /* Records of N 4-byte hil_packets must terminate with a command. */ | 230 | /* Records of N 4-byte hil_packets must terminate with a command. */ |
237 | if ((++(kbd->idx4)) % 4) | 231 | if ((++kbd->idx4 % 4) == 0) { |
238 | return IRQ_HANDLED; | 232 | if ((packet & 0xffff0000) != HIL_ERR_INT) { |
239 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | 233 | hil_kbd_process_err(kbd); |
240 | hil_kbd_process_err(kbd); | 234 | } else if (packet & HIL_PKT_CMD) { |
241 | return IRQ_HANDLED; | 235 | if (hil_kbd_is_command_response(packet)) |
236 | hil_kbd_handle_command_response(kbd); | ||
237 | else | ||
238 | hil_kbd_handle_key_events(kbd); | ||
239 | kbd->idx4 = 0; | ||
240 | } | ||
242 | } | 241 | } |
243 | if (packet & HIL_PKT_CMD) | 242 | out: |
244 | hil_kbd_process_record(kbd); | ||
245 | return IRQ_HANDLED; | 243 | return IRQ_HANDLED; |
246 | } | 244 | } |
247 | 245 | ||
248 | static void hil_kbd_disconnect(struct serio *serio) | 246 | static void hil_kbd_disconnect(struct serio *serio) |
249 | { | 247 | { |
250 | struct hil_kbd *kbd; | 248 | struct hil_kbd *kbd = serio_get_drvdata(serio); |
251 | 249 | ||
252 | kbd = serio_get_drvdata(serio); | ||
253 | BUG_ON(kbd == NULL); | 250 | BUG_ON(kbd == NULL); |
254 | 251 | ||
255 | serio_close(serio); | 252 | serio_close(serio); |
@@ -259,52 +256,64 @@ static void hil_kbd_disconnect(struct serio *serio) | |||
259 | 256 | ||
260 | static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | 257 | static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) |
261 | { | 258 | { |
262 | struct hil_kbd *kbd; | 259 | struct hil_kbd *kbd; |
263 | uint8_t did, *idd; | 260 | struct input_dev *input_dev; |
264 | int i; | 261 | uint8_t did, *idd; |
262 | int i; | ||
263 | int error; | ||
265 | 264 | ||
266 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); | 265 | kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); |
267 | if (!kbd) | 266 | input_dev = input_allocate_device(); |
268 | return -ENOMEM; | 267 | if (!kbd || !input_dev) { |
269 | 268 | error = -ENOMEM; | |
270 | kbd->dev = input_allocate_device(); | ||
271 | if (!kbd->dev) | ||
272 | goto bail0; | 269 | goto bail0; |
270 | } | ||
273 | 271 | ||
274 | if (serio_open(serio, drv)) | ||
275 | goto bail1; | ||
276 | |||
277 | serio_set_drvdata(serio, kbd); | ||
278 | kbd->serio = serio; | 272 | kbd->serio = serio; |
273 | kbd->dev = input_dev; | ||
274 | |||
275 | error = serio_open(serio, drv); | ||
276 | if (error) | ||
277 | goto bail0; | ||
279 | 278 | ||
280 | init_MUTEX_LOCKED(&kbd->sem); | 279 | serio_set_drvdata(serio, kbd); |
281 | 280 | ||
282 | /* Get device info. MLC driver supplies devid/status/etc. */ | 281 | /* Get device info. MLC driver supplies devid/status/etc. */ |
282 | init_completion(&kbd->cmd_done); | ||
283 | serio_write(serio, 0); | 283 | serio_write(serio, 0); |
284 | serio_write(serio, 0); | 284 | serio_write(serio, 0); |
285 | serio_write(serio, HIL_PKT_CMD >> 8); | 285 | serio_write(serio, HIL_PKT_CMD >> 8); |
286 | serio_write(serio, HIL_CMD_IDD); | 286 | serio_write(serio, HIL_CMD_IDD); |
287 | down(&kbd->sem); | 287 | error = wait_for_completion_killable(&kbd->cmd_done); |
288 | if (error) | ||
289 | goto bail1; | ||
288 | 290 | ||
291 | init_completion(&kbd->cmd_done); | ||
289 | serio_write(serio, 0); | 292 | serio_write(serio, 0); |
290 | serio_write(serio, 0); | 293 | serio_write(serio, 0); |
291 | serio_write(serio, HIL_PKT_CMD >> 8); | 294 | serio_write(serio, HIL_PKT_CMD >> 8); |
292 | serio_write(serio, HIL_CMD_RSC); | 295 | serio_write(serio, HIL_CMD_RSC); |
293 | down(&kbd->sem); | 296 | error = wait_for_completion_killable(&kbd->cmd_done); |
297 | if (error) | ||
298 | goto bail1; | ||
294 | 299 | ||
300 | init_completion(&kbd->cmd_done); | ||
295 | serio_write(serio, 0); | 301 | serio_write(serio, 0); |
296 | serio_write(serio, 0); | 302 | serio_write(serio, 0); |
297 | serio_write(serio, HIL_PKT_CMD >> 8); | 303 | serio_write(serio, HIL_PKT_CMD >> 8); |
298 | serio_write(serio, HIL_CMD_RNM); | 304 | serio_write(serio, HIL_CMD_RNM); |
299 | down(&kbd->sem); | 305 | error = wait_for_completion_killable(&kbd->cmd_done); |
306 | if (error) | ||
307 | goto bail1; | ||
300 | 308 | ||
309 | init_completion(&kbd->cmd_done); | ||
301 | serio_write(serio, 0); | 310 | serio_write(serio, 0); |
302 | serio_write(serio, 0); | 311 | serio_write(serio, 0); |
303 | serio_write(serio, HIL_PKT_CMD >> 8); | 312 | serio_write(serio, HIL_PKT_CMD >> 8); |
304 | serio_write(serio, HIL_CMD_EXD); | 313 | serio_write(serio, HIL_CMD_EXD); |
305 | down(&kbd->sem); | 314 | error = wait_for_completion_killable(&kbd->cmd_done); |
306 | 315 | if (error) | |
307 | up(&kbd->sem); | 316 | goto bail1; |
308 | 317 | ||
309 | did = kbd->idd[0]; | 318 | did = kbd->idd[0]; |
310 | idd = kbd->idd + 1; | 319 | idd = kbd->idd + 1; |
@@ -317,55 +326,54 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
317 | did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); | 326 | did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); |
318 | break; | 327 | break; |
319 | default: | 328 | default: |
320 | goto bail2; | 329 | goto bail1; |
321 | } | 330 | } |
322 | 331 | ||
323 | if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { | 332 | if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { |
324 | printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); | 333 | printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); |
325 | goto bail2; | 334 | goto bail1; |
326 | } | 335 | } |
327 | 336 | ||
328 | kbd->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 337 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
329 | kbd->dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | 338 | input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | |
330 | BIT_MASK(LED_SCROLLL); | 339 | BIT_MASK(LED_SCROLLL); |
331 | kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | 340 | input_dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; |
332 | kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]); | 341 | input_dev->keycodesize = sizeof(hil_kbd_set1[0]); |
333 | kbd->dev->keycode = hil_kbd_set1; | 342 | input_dev->keycode = hil_kbd_set1; |
334 | kbd->dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; | 343 | input_dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; |
335 | kbd->dev->phys = "hpkbd/input0"; /* XXX */ | 344 | input_dev->phys = "hpkbd/input0"; /* XXX */ |
336 | 345 | ||
337 | kbd->dev->id.bustype = BUS_HIL; | 346 | input_dev->id.bustype = BUS_HIL; |
338 | kbd->dev->id.vendor = PCI_VENDOR_ID_HP; | 347 | input_dev->id.vendor = PCI_VENDOR_ID_HP; |
339 | kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ | 348 | input_dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ |
340 | kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ | 349 | input_dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ |
341 | kbd->dev->dev.parent = &serio->dev; | 350 | input_dev->dev.parent = &serio->dev; |
342 | 351 | ||
343 | for (i = 0; i < 128; i++) { | 352 | for (i = 0; i < 128; i++) { |
344 | set_bit(hil_kbd_set1[i], kbd->dev->keybit); | 353 | __set_bit(hil_kbd_set1[i], input_dev->keybit); |
345 | set_bit(hil_kbd_set3[i], kbd->dev->keybit); | 354 | __set_bit(hil_kbd_set3[i], input_dev->keybit); |
346 | } | 355 | } |
347 | clear_bit(0, kbd->dev->keybit); | 356 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
348 | |||
349 | input_register_device(kbd->dev); | ||
350 | printk(KERN_INFO "input: %s, ID: %d\n", | ||
351 | kbd->dev->name, did); | ||
352 | 357 | ||
353 | serio_write(serio, 0); | 358 | serio_write(serio, 0); |
354 | serio_write(serio, 0); | 359 | serio_write(serio, 0); |
355 | serio_write(serio, HIL_PKT_CMD >> 8); | 360 | serio_write(serio, HIL_PKT_CMD >> 8); |
356 | serio_write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ | 361 | serio_write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ |
357 | down(&kbd->sem); | 362 | /* No need to wait for completion */ |
358 | up(&kbd->sem); | 363 | |
364 | error = input_register_device(kbd->dev); | ||
365 | if (error) | ||
366 | goto bail1; | ||
359 | 367 | ||
360 | return 0; | 368 | return 0; |
361 | bail2: | 369 | |
370 | bail1: | ||
362 | serio_close(serio); | 371 | serio_close(serio); |
363 | serio_set_drvdata(serio, NULL); | 372 | serio_set_drvdata(serio, NULL); |
364 | bail1: | ||
365 | input_free_device(kbd->dev); | ||
366 | bail0: | 373 | bail0: |
374 | input_free_device(input_dev); | ||
367 | kfree(kbd); | 375 | kfree(kbd); |
368 | return -EIO; | 376 | return error; |
369 | } | 377 | } |
370 | 378 | ||
371 | static struct serio_device_id hil_kbd_ids[] = { | 379 | static struct serio_device_id hil_kbd_ids[] = { |