64717c56ab45a4803c08baf6ded3183f2aa17038
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / staging / nanohub / main.c
1 /*
2 * Copyright (C) 2016 Google, Inc.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/slab.h>
19 #include <linux/iio/iio.h>
20 #include <linux/firmware.h>
21 #include <linux/fs.h>
22 #include <linux/cdev.h>
23 #include <linux/uaccess.h>
24 #include <linux/delay.h>
25 #include <linux/of_gpio.h>
26 #include <linux/of_irq.h>
27 #include <linux/interrupt.h>
28 #include <linux/poll.h>
29 #include <linux/list.h>
30 #include <linux/vmalloc.h>
31 #include <linux/spinlock.h>
32 #include <linux/semaphore.h>
33 #include <linux/sched.h>
34 #include <linux/sched/rt.h>
35 #include <linux/sched/prio.h>
36 #include <linux/sched/signal.h>
37 #include <linux/time.h>
38 #include <linux/platform_data/nanohub.h>
39 #include <uapi/linux/sched/types.h>
40
41 #include "main.h"
42 #include "comms.h"
43 #include "bl.h"
44
45 #if defined(CONFIG_NANOHUB_MAILBOX)
46 #include "chub.h"
47 #include "chub_dbg.h"
48 #elif defined(CONFIG_SPI_MAILBOX)
49 #include "spi.h"
50 #endif
51
52 #define READ_QUEUE_DEPTH 10
53 #define APP_FROM_HOST_EVENTID 0x000000F8
54 #define FIRST_SENSOR_EVENTID 0x00000200
55 #define LAST_SENSOR_EVENTID 0x000002FF
56 #define APP_TO_HOST_EVENTID 0x00000401
57 #define OS_LOG_EVENTID 0x3B474F4C
58 #define WAKEUP_INTERRUPT 1
59 #define WAKEUP_TIMEOUT_MS 1000
60 #define SUSPEND_TIMEOUT_MS 100
61 #define KTHREAD_ERR_TIME_NS (60LL * NSEC_PER_SEC)
62 #define KTHREAD_ERR_CNT 70
63 #define KTHREAD_WARN_CNT 10
64 #define WAKEUP_ERR_TIME_NS (60LL * NSEC_PER_SEC)
65 #define WAKEUP_ERR_CNT 4
66
67 #ifdef CONFIG_EXT_CHUB
68 /**
69 * struct gpio_config - this is a binding between platform data and driver data
70 * @label: for diagnostics
71 * @flags: to pass to gpio_request_one()
72 * @options: one or more of GPIO_OPT_* flags, below
73 * @pdata_off: offset of u32 field in platform data with gpio #
74 * @data_off: offset of int field in driver data with irq # (optional)
75 */
76 struct gpio_config {
77 const char *label;
78 u16 flags;
79 u16 options;
80 u16 pdata_off;
81 u16 data_off;
82 };
83
84 #define GPIO_OPT_HAS_IRQ 0x0001
85 #define GPIO_OPT_OPTIONAL 0x8000
86
87 #define PLAT_GPIO_DEF(name, _flags) \
88 .pdata_off = offsetof(struct nanohub_platform_data, name ## _gpio), \
89 .label = "nanohub_" #name, \
90 .flags = _flags \
91
92 #define PLAT_GPIO_DEF_IRQ(name, _flags, _opts) \
93 PLAT_GPIO_DEF(name, _flags), \
94 .data_off = offsetof(struct nanohub_data, name), \
95 .options = GPIO_OPT_HAS_IRQ | (_opts) \
96
97 #endif
98
99 static int nanohub_open(struct inode *, struct file *);
100 static ssize_t nanohub_read(struct file *, char *, size_t, loff_t *);
101 static ssize_t nanohub_write(struct file *, const char *, size_t, loff_t *);
102 static unsigned int nanohub_poll(struct file *, poll_table *);
103 static int nanohub_release(struct inode *, struct file *);
104 static int nanohub_hw_reset(struct nanohub_data *data);
105
106 static int chub_dev_open(struct inode *, struct file *);
107 static ssize_t chub_dev_read(struct file *, char *, size_t, loff_t *);
108 static ssize_t chub_dev_write(struct file *, const char *, size_t, loff_t *);
109
110 static struct class *sensor_class;
111 static int major, chub_dev_major;
112
113 extern const char *os_image[SENSOR_VARIATION];
114
115 #ifdef CONFIG_EXT_CHUB
116 static const struct gpio_config gconf[] = {
117 { PLAT_GPIO_DEF(nreset, GPIOF_OUT_INIT_HIGH) },
118 { PLAT_GPIO_DEF(wakeup, GPIOF_OUT_INIT_HIGH) },
119 { PLAT_GPIO_DEF(boot0, GPIOF_OUT_INIT_LOW) },
120 { PLAT_GPIO_DEF_IRQ(irq1, GPIOF_DIR_IN, 0) },
121 { PLAT_GPIO_DEF_IRQ(irq2, GPIOF_DIR_IN, GPIO_OPT_OPTIONAL) },
122 };
123 #endif
124
125 static const struct iio_info nanohub_iio_info = {
126 .driver_module = THIS_MODULE,
127 };
128
129 static const struct file_operations nanohub_fileops = {
130 .owner = THIS_MODULE,
131 .open = nanohub_open,
132 .read = nanohub_read,
133 .write = nanohub_write,
134 .poll = nanohub_poll,
135 .release = nanohub_release,
136 };
137
138 static const struct file_operations chub_dev_fileops = {
139 .owner = THIS_MODULE,
140 .open = chub_dev_open,
141 .read = chub_dev_read,
142 .write = chub_dev_write,
143 };
144
145 enum {
146 ST_IDLE,
147 ST_ERROR,
148 ST_RUNNING
149 };
150
151 #ifdef CONFIG_EXT_CHUB
152 static inline bool gpio_is_optional(const struct gpio_config *_cfg)
153 {
154 return _cfg->options & GPIO_OPT_OPTIONAL;
155 }
156
157 static inline bool gpio_has_irq(const struct gpio_config *_cfg)
158 {
159 return _cfg->options & GPIO_OPT_HAS_IRQ;
160 }
161 #endif
162
163 static inline bool nanohub_has_priority_lock_locked(struct nanohub_data *data)
164 {
165 return atomic_read(&data->wakeup_lock_cnt) >
166 atomic_read(&data->wakeup_cnt);
167 }
168
169 static inline void nanohub_notify_thread(struct nanohub_data *data)
170 {
171 atomic_set(&data->kthread_run, 1);
172 /* wake_up implementation works as memory barrier */
173 wake_up_interruptible_sync(&data->kthread_wait);
174 }
175
176 static inline void nanohub_io_init(struct nanohub_io *io,
177 struct nanohub_data *data,
178 struct device *dev)
179 {
180 init_waitqueue_head(&io->buf_wait);
181 INIT_LIST_HEAD(&io->buf_list);
182 io->data = data;
183 io->dev = dev;
184 }
185
186 static inline bool nanohub_io_has_buf(struct nanohub_io *io)
187 {
188 return !list_empty(&io->buf_list);
189 }
190
191 #ifdef CONFIG_NANOHUB_MAILBOX
192 #define EVT_DEBUG_DUMP 0x00007F02 /* defined on sensorhal */
193
194 int nanohub_is_reset_notify_io(struct nanohub_buf *buf)
195 {
196 if (buf) {
197 uint32_t *buffer = (uint32_t *)buf->buffer;
198 if (*buffer == EVT_DEBUG_DUMP)
199 return true;
200 }
201 return false;
202 }
203 #endif
204
205 static struct nanohub_buf *nanohub_io_get_buf(struct nanohub_io *io,
206 bool wait)
207 {
208 struct nanohub_buf *buf = NULL;
209 int ret;
210
211 spin_lock(&io->buf_wait.lock);
212 if (wait) {
213 ret = wait_event_interruptible_locked(io->buf_wait,
214 nanohub_io_has_buf(io));
215 if (ret < 0) {
216 spin_unlock(&io->buf_wait.lock);
217 return ERR_PTR(ret);
218 }
219 }
220
221 if (nanohub_io_has_buf(io)) {
222 buf = list_first_entry(&io->buf_list, struct nanohub_buf, list);
223 list_del(&buf->list);
224 }
225 spin_unlock(&io->buf_wait.lock);
226
227 return buf;
228 }
229
230 static void nanohub_io_put_buf(struct nanohub_io *io,
231 struct nanohub_buf *buf)
232 {
233 bool was_empty;
234
235 spin_lock(&io->buf_wait.lock);
236 was_empty = !nanohub_io_has_buf(io);
237 list_add_tail(&buf->list, &io->buf_list);
238 spin_unlock(&io->buf_wait.lock);
239
240 if (was_empty) {
241 if (&io->data->free_pool == io)
242 nanohub_notify_thread(io->data);
243 else
244 wake_up_interruptible(&io->buf_wait);
245 }
246 }
247
248 #ifdef CONFIG_EXT_CHUB
249 static inline int plat_gpio_get(struct nanohub_data *data,
250 const struct gpio_config *_cfg)
251 {
252 const struct nanohub_platform_data *pdata = data->pdata;
253
254 return *(u32 *)(((char *)pdata) + (_cfg)->pdata_off);
255 }
256
257 static inline void nanohub_set_irq_data(struct nanohub_data *data,
258 const struct gpio_config *_cfg, int val)
259 {
260 int *data_addr = ((int *)(((char *)data) + _cfg->data_off));
261
262 if ((void *)data_addr > (void *)data &&
263 (void *)data_addr < (void *)(data + 1))
264 *data_addr = val;
265 else
266 WARN(1, "No data binding defined for %s", _cfg->label);
267 }
268 #endif
269
270 static inline void mcu_wakeup_gpio_set_value(struct nanohub_data *data,
271 int val)
272 {
273 #ifdef CONFIG_EXT_CHUB
274 const struct nanohub_platform_data *pdata = data->pdata;
275
276 gpio_set_value(pdata->wakeup_gpio, val);
277 #else
278 if (val)
279 contexthub_ipc_write_event(data->pdata->mailbox_client, MAILBOX_EVT_WAKEUP_CLR);
280 else
281 contexthub_ipc_write_event(data->pdata->mailbox_client, MAILBOX_EVT_WAKEUP);
282 #endif
283 }
284
285 static inline void mcu_wakeup_gpio_get_locked(struct nanohub_data *data,
286 int priority_lock)
287 {
288 atomic_inc(&data->wakeup_lock_cnt);
289 if (!priority_lock && atomic_inc_return(&data->wakeup_cnt) == 1 &&
290 !nanohub_has_priority_lock_locked(data))
291 mcu_wakeup_gpio_set_value(data, 0);
292 }
293
294 static inline bool mcu_wakeup_gpio_put_locked(struct nanohub_data *data,
295 int priority_lock)
296 {
297 bool gpio_done = priority_lock ?
298 atomic_read(&data->wakeup_cnt) == 0 :
299 atomic_dec_and_test(&data->wakeup_cnt);
300 bool done = atomic_dec_and_test(&data->wakeup_lock_cnt);
301
302 if (!nanohub_has_priority_lock_locked(data))
303 mcu_wakeup_gpio_set_value(data, gpio_done ? 1 : 0);
304
305 return done;
306 }
307
308 static inline bool mcu_wakeup_gpio_is_locked(struct nanohub_data *data)
309 {
310 return atomic_read(&data->wakeup_lock_cnt) != 0;
311 }
312
313 inline void nanohub_handle_irq1(struct nanohub_data *data)
314 {
315 bool locked;
316
317 spin_lock(&data->wakeup_wait.lock);
318 locked = mcu_wakeup_gpio_is_locked(data);
319 spin_unlock(&data->wakeup_wait.lock);
320 if (!locked)
321 nanohub_notify_thread(data);
322 else
323 wake_up_interruptible_sync(&data->wakeup_wait);
324 }
325
326 static inline void nanohub_handle_irq2(struct nanohub_data *data)
327 {
328 nanohub_notify_thread(data);
329 }
330
331 static inline bool mcu_wakeup_try_lock(struct nanohub_data *data, int key)
332 {
333 /* implementation contains memory barrier */
334 return atomic_cmpxchg(&data->wakeup_acquired, 0, key) == 0;
335 }
336
337 static inline void mcu_wakeup_unlock(struct nanohub_data *data, int key)
338 {
339 WARN(atomic_cmpxchg(&data->wakeup_acquired, key, 0) != key,
340 "%s: failed to unlock with key %d; current state: %d",
341 __func__, key, atomic_read(&data->wakeup_acquired));
342 }
343
344 static inline void nanohub_set_state(struct nanohub_data *data, int state)
345 {
346 atomic_set(&data->thread_state, state);
347 smp_mb__after_atomic(); /* updated thread state is now visible */
348 }
349
350 static inline int nanohub_get_state(struct nanohub_data *data)
351 {
352 smp_mb__before_atomic(); /* wait for all updates to finish */
353 return atomic_read(&data->thread_state);
354 }
355
356 static inline void nanohub_clear_err_cnt(struct nanohub_data *data)
357 {
358 data->kthread_err_cnt = data->wakeup_err_cnt = 0;
359 }
360
361 int request_wakeup_ex(struct nanohub_data *data, long timeout_ms,
362 int key, int lock_mode)
363 {
364 long timeout;
365 bool priority_lock = lock_mode > LOCK_MODE_NORMAL;
366 struct device *sensor_dev = data->io[ID_NANOHUB_SENSOR].dev;
367 int ret;
368 ktime_t ktime_delta;
369 ktime_t wakeup_ktime;
370 #ifdef CONFIG_NANOHUB_MAILBOX
371 unsigned long flag;
372
373 spin_lock_irqsave(&data->wakeup_wait.lock, flag);
374 #else
375 spin_lock(&data->wakeup_wait.lock);
376 #endif
377 mcu_wakeup_gpio_get_locked(data, priority_lock);
378 timeout = (timeout_ms != MAX_SCHEDULE_TIMEOUT) ?
379 msecs_to_jiffies(timeout_ms) :
380 MAX_SCHEDULE_TIMEOUT;
381
382 if (!priority_lock && !data->wakeup_err_cnt)
383 wakeup_ktime = ktime_get_boottime();
384 timeout = wait_event_interruptible_timeout_locked(
385 data->wakeup_wait,
386 ((priority_lock || nanohub_irq1_fired(data)) &&
387 mcu_wakeup_try_lock(data, key)),
388 timeout
389 );
390
391 if (timeout <= 0) {
392 if (!timeout && !priority_lock) {
393 if (!data->wakeup_err_cnt)
394 data->wakeup_err_ktime = wakeup_ktime;
395 ktime_delta = ktime_sub(ktime_get_boottime(),
396 data->wakeup_err_ktime);
397 data->wakeup_err_cnt++;
398 if (ktime_to_ns(ktime_delta) > WAKEUP_ERR_TIME_NS
399 && data->wakeup_err_cnt > WAKEUP_ERR_CNT) {
400 mcu_wakeup_gpio_put_locked(data, priority_lock);
401 #ifdef CONFIG_NANOHUB_MAILBOX
402 spin_unlock_irqrestore(&data->wakeup_wait.lock, flag);
403 #else
404 spin_unlock(&data->wakeup_wait.lock);
405 #endif
406 dev_info(sensor_dev,
407 "wakeup: hard reset due to consistent error\n");
408 ret = nanohub_hw_reset(data);
409 if (ret) {
410 dev_info(sensor_dev,
411 "%s: failed to reset nanohub: ret=%d\n",
412 __func__, ret);
413 }
414 return -ETIME;
415 }
416 }
417 mcu_wakeup_gpio_put_locked(data, priority_lock);
418
419 if (timeout == 0)
420 timeout = -ETIME;
421 } else {
422 data->wakeup_err_cnt = 0;
423 timeout = 0;
424 }
425
426 #ifdef CONFIG_NANOHUB_MAILBOX
427 spin_unlock_irqrestore(&data->wakeup_wait.lock, flag);
428 #else
429 spin_unlock(&data->wakeup_wait.lock);
430 #endif
431
432 return timeout;
433 }
434
435 void release_wakeup_ex(struct nanohub_data *data, int key, int lock_mode)
436 {
437 bool done;
438 bool priority_lock = lock_mode > LOCK_MODE_NORMAL;
439 #ifdef CONFIG_NANOHUB_MAILBOX
440 unsigned long flag;
441
442 spin_lock_irqsave(&data->wakeup_wait.lock, flag);
443 #else
444 spin_lock(&data->wakeup_wait.lock);
445 #endif
446
447 done = mcu_wakeup_gpio_put_locked(data, priority_lock);
448 mcu_wakeup_unlock(data, key);
449
450 #ifdef CONFIG_NANOHUB_MAILBOX
451 spin_unlock_irqrestore(&data->wakeup_wait.lock, flag);
452 #else
453 spin_unlock(&data->wakeup_wait.lock);
454 #endif
455
456 if (!done)
457 wake_up_interruptible_sync(&data->wakeup_wait);
458 else if (nanohub_irq1_fired(data) || nanohub_irq2_fired(data))
459 nanohub_notify_thread(data);
460 }
461
462 int nanohub_wait_for_interrupt(struct nanohub_data *data)
463 {
464 int ret = -EFAULT;
465
466 /* release the wakeup line, and wait for nanohub to send
467 * us an interrupt indicating the transaction completed.
468 */
469
470 #ifdef CONFIG_NANOHUB_MAILBOX
471 unsigned long flag;
472 spin_lock_irqsave(&data->wakeup_wait.lock, flag);
473 #else
474 spin_lock(&data->wakeup_wait.lock);
475 #endif
476
477 if (mcu_wakeup_gpio_is_locked(data)) {
478 mcu_wakeup_gpio_set_value(data, 1);
479 ret = wait_event_interruptible_locked(data->wakeup_wait,
480 nanohub_irq1_fired(data));
481 mcu_wakeup_gpio_set_value(data, 0);
482 }
483 #ifdef CONFIG_NANOHUB_MAILBOX
484 spin_unlock_irqrestore(&data->wakeup_wait.lock, flag);
485 #else
486 spin_unlock(&data->wakeup_wait.lock);
487 #endif
488
489 return ret;
490 }
491
492 int nanohub_wakeup_eom(struct nanohub_data *data, bool repeat)
493 {
494 int ret = -EFAULT;
495 #ifdef LOWLEVEL_DEBUG
496 int wakeup_flag = 0;
497 #endif
498
499 #ifdef CONFIG_NANOHUB_MAILBOX
500 unsigned long flag;
501 spin_lock_irqsave(&data->wakeup_wait.lock, flag);
502 #else
503 spin_lock(&data->wakeup_wait.lock);
504 #endif
505
506 if (mcu_wakeup_gpio_is_locked(data)) {
507 mcu_wakeup_gpio_set_value(data, 1);
508 if (repeat)
509 mcu_wakeup_gpio_set_value(data, 0);
510 ret = 0;
511 #ifdef LOWLEVEL_DEBUG
512 wakeup_flag = 1;
513 #endif
514 }
515
516 #ifdef CONFIG_NANOHUB_MAILBOX
517 spin_unlock_irqrestore(&data->wakeup_wait.lock, flag);
518 #else
519 spin_unlock(&data->wakeup_wait.lock);
520 #endif
521
522 return ret;
523 }
524
525 #ifdef CONFIG_EXT_CHUB
526 static void __nanohub_interrupt_cfg(struct nanohub_data *data,
527 u8 interrupt, bool mask)
528 {
529 int ret;
530 uint8_t mask_ret;
531 int cnt = 10;
532 struct device *dev = data->io[ID_NANOHUB_SENSOR].dev;
533 int cmd = mask ? CMD_COMMS_MASK_INTR : CMD_COMMS_UNMASK_INTR;
534
535 do {
536 ret = request_wakeup_timeout(data, WAKEUP_TIMEOUT_MS);
537 if (ret) {
538 dev_err(dev,
539 "%s: interrupt %d %smask failed: ret=%d\n",
540 __func__, interrupt, mask ? "" : "un", ret);
541 return;
542 }
543
544 ret =
545 nanohub_comms_tx_rx_retrans(data, cmd,
546 &interrupt, sizeof(interrupt),
547 &mask_ret, sizeof(mask_ret),
548 false, 10, 0);
549 release_wakeup(data);
550 dev_dbg(dev,
551 "%smasking interrupt %d, ret=%d, mask_ret=%d\n",
552 mask ? "" : "un",
553 interrupt, ret, mask_ret);
554 } while ((ret != 1 || mask_ret != 1) && --cnt > 0);
555 }
556 #endif
557 static inline void nanohub_mask_interrupt(struct nanohub_data *data,
558 u8 interrupt)
559 {
560 #ifdef CONFIG_EXT_CHUB
561 __nanohub_interrupt_cfg(data, interrupt, true);
562 #endif
563 }
564
565 static inline void nanohub_unmask_interrupt(struct nanohub_data *data,
566 u8 interrupt)
567 {
568 #ifdef CONFIG_EXT_CHUB
569 __nanohub_interrupt_cfg(data, interrupt, false);
570 #endif
571 }
572
573 static ssize_t nanohub_wakeup_query(struct device *dev,
574 struct device_attribute *attr, char *buf)
575 {
576 struct nanohub_data *data = dev_get_nanohub_data(dev);
577 const struct nanohub_platform_data *pdata = data->pdata;
578 #ifdef CONFIG_NANOHUB_MAILBOX
579 struct contexthub_ipc_info *ipc;
580 #endif
581
582 nanohub_clear_err_cnt(data);
583 if (nanohub_irq1_fired(data) || nanohub_irq2_fired(data))
584 wake_up_interruptible(&data->wakeup_wait);
585
586 #ifdef CONFIG_NANOHUB_MAILBOX
587 ipc = pdata->mailbox_client;
588 return scnprintf(buf, PAGE_SIZE, "WAKEUP: %d INT1: %d INT2: %d\n",
589 atomic_read(&ipc->wakeup_chub),
590 atomic_read(&ipc->irq1_apInt), -1);
591 #else
592 return scnprintf(buf, PAGE_SIZE, "WAKEUP: %d INT1: %d INT2: %d\n",
593 gpio_get_value(pdata->wakeup_gpio),
594 gpio_get_value(pdata->irq1_gpio),
595 data->irq2 ? gpio_get_value(pdata->irq2_gpio) : -1);
596 #endif
597 }
598
599 static ssize_t nanohub_app_info(struct device *dev,
600 struct device_attribute *attr, char *buf)
601 {
602 struct nanohub_data *data = dev_get_nanohub_data(dev);
603 struct {
604 uint64_t appId;
605 uint32_t appVer;
606 uint32_t appSize;
607 } __packed buffer;
608 uint32_t i = 0;
609 int ret;
610 ssize_t len = 0;
611
612 do {
613 if (request_wakeup(data))
614 return -ERESTARTSYS;
615
616 if (nanohub_comms_tx_rx_retrans
617 (data, CMD_COMMS_QUERY_APP_INFO, (uint8_t *)&i,
618 sizeof(i), (u8 *)&buffer, sizeof(buffer),
619 false, 10, 10) == sizeof(buffer)) {
620 ret =
621 scnprintf(buf + len, PAGE_SIZE - len,
622 "app: %d id: %016llx ver: %08x size: %08x\n",
623 i, buffer.appId, buffer.appVer,
624 buffer.appSize);
625 if (ret > 0) {
626 len += ret;
627 i++;
628 }
629 } else {
630 ret = -1;
631 }
632
633 release_wakeup(data);
634 } while (ret > 0);
635
636 return len;
637 }
638
639 static ssize_t nanohub_firmware_query(struct device *dev,
640 struct device_attribute *attr, char *buf)
641 {
642 struct nanohub_data *data = dev_get_nanohub_data(dev);
643 uint16_t buffer[6];
644
645 if (request_wakeup(data))
646 return -ERESTARTSYS;
647
648 if (nanohub_comms_tx_rx_retrans
649 (data, CMD_COMMS_GET_OS_HW_VERSIONS, NULL, 0, (uint8_t *)&buffer,
650 sizeof(buffer), false, 10, 10) == sizeof(buffer)) {
651 release_wakeup(data);
652 return scnprintf(buf, PAGE_SIZE,
653 "hw type: %04x hw ver: %04x bl ver: %04x os ver: %04x variant ver: %08x\n",
654 buffer[0], buffer[1], buffer[2], buffer[3],
655 buffer[5] << 16 | buffer[4]);
656 } else {
657 release_wakeup(data);
658 return 0;
659 }
660 }
661
662 static inline int nanohub_wakeup_lock(struct nanohub_data *data, int mode)
663 {
664 int ret;
665
666 if (data->irq2)
667 disable_irq(data->irq2);
668 else
669 nanohub_mask_interrupt(data, 2);
670
671 ret = request_wakeup_ex(data,
672 mode == LOCK_MODE_SUSPEND_RESUME ?
673 SUSPEND_TIMEOUT_MS : WAKEUP_TIMEOUT_MS,
674 KEY_WAKEUP_LOCK, mode);
675 if (ret < 0) {
676 #ifdef CONFIG_EXT_CHUB
677 if (data->irq2)
678 enable_irq(data->irq2);
679 else
680 nanohub_unmask_interrupt(data, 2);
681 #endif
682 return ret;
683 }
684
685 #ifdef CONFIG_EXT_CHUB
686 if (mode == LOCK_MODE_IO || mode == LOCK_MODE_IO_BL)
687 ret = nanohub_bl_open(data);
688 if (ret < 0) {
689 release_wakeup_ex(data, KEY_WAKEUP_LOCK, mode);
690 return ret;
691 }
692 if (mode != LOCK_MODE_SUSPEND_RESUME)
693 disable_irq(data->irq1);
694 #else
695 if (mode != LOCK_MODE_SUSPEND_RESUME)
696 contexthub_ipc_write_event(data->pdata->mailbox_client, (u32)MAILBOX_EVT_DISABLE_IRQ);
697 #endif
698
699 atomic_set(&data->lock_mode, mode);
700 mcu_wakeup_gpio_set_value(data, mode != LOCK_MODE_IO_BL);
701
702 return 0;
703 }
704
705 /* returns lock mode used to perform this lock */
706 static inline int nanohub_wakeup_unlock(struct nanohub_data *data)
707 {
708 int mode = atomic_read(&data->lock_mode);
709
710 atomic_set(&data->lock_mode, LOCK_MODE_NONE);
711 #ifdef CONFIG_EXT_CHUB
712 if (mode != LOCK_MODE_SUSPEND_RESUME)
713 enable_irq(data->irq1);
714 if (mode == LOCK_MODE_IO || mode == LOCK_MODE_IO_BL)
715 nanohub_bl_close(data);
716 if (data->irq2)
717 enable_irq(data->irq2);
718
719 release_wakeup_ex(data, KEY_WAKEUP_LOCK, mode);
720 if (!data->irq2)
721 nanohub_unmask_interrupt(data, 2);
722 #else
723 if (mode != LOCK_MODE_SUSPEND_RESUME)
724 contexthub_ipc_write_event(data->pdata->mailbox_client, (u32)MAILBOX_EVT_ENABLE_IRQ);
725 release_wakeup_ex(data, KEY_WAKEUP_LOCK, mode);
726 #endif
727
728 nanohub_notify_thread(data);
729
730 return mode;
731 }
732
733 static void __nanohub_hw_reset(struct nanohub_data *data, int boot0)
734 {
735 const struct nanohub_platform_data *pdata = data->pdata;
736
737 #if defined(CONFIG_EXT_CHUB)
738 gpio_set_value(pdata->nreset_gpio, 0);
739 gpio_set_value(pdata->boot0_gpio, boot0 > 0);
740 usleep_range(30, 40);
741 gpio_set_value(pdata->nreset_gpio, 1);
742 if (boot0 > 0)
743 usleep_range(70000, 75000);
744 else if (!boot0)
745 usleep_range(750000, 800000);
746 #elif defined(CONFIG_NANOHUB_MAILBOX)
747 int ret;
748
749 if (boot0)
750 ret = contexthub_ipc_write_event(pdata->mailbox_client, MAILBOX_EVT_SHUTDOWN);
751 else
752 ret = contexthub_ipc_write_event(pdata->mailbox_client, MAILBOX_EVT_RESET);
753
754 if (ret)
755 dev_warn(data->io[ID_NANOHUB_SENSOR].dev,
756 "%s: fail to reset on boot0 %d\n", __func__, boot0);
757 #endif
758 }
759
760 static int nanohub_hw_reset(struct nanohub_data *data)
761 {
762 int ret;
763 #if defined(CONFIG_EXT_CHUB)
764 ret = nanohub_wakeup_lock(data, LOCK_MODE_RESET);
765
766 if (!ret) {
767 data->err_cnt = 0;
768 __nanohub_hw_reset(data, 0);
769 nanohub_wakeup_unlock(data);
770 }
771 #elif defined(CONFIG_NANOHUB_MAILBOX)
772 #ifdef CHUB_RESET_ENABLE
773 ret = contexthub_reset(data->pdata->mailbox_client, 1, CHUB_ERR_COMMS);
774 #else
775 ret = -EINVAL;
776 #endif
777 #endif
778 return ret;
779 }
780
781 static ssize_t nanohub_try_hw_reset(struct device *dev,
782 struct device_attribute *attr,
783 const char *buf, size_t count)
784 {
785 struct nanohub_data *data = dev_get_nanohub_data(dev);
786 int ret;
787
788 ret = nanohub_hw_reset(data);
789
790 return ret < 0 ? ret : count;
791 }
792
793 static ssize_t nanohub_erase_shared(struct device *dev,
794 struct device_attribute *attr,
795 const char *buf, size_t count)
796 {
797 struct nanohub_data *data = dev_get_nanohub_data(dev);
798
799 #if defined(CONFIG_EXT_CHUB)
800 uint8_t status = CMD_ACK;
801 int ret;
802
803 ret = nanohub_wakeup_lock(data, LOCK_MODE_IO);
804 if (ret < 0)
805 return ret;
806
807 data->err_cnt = 0;
808 __nanohub_hw_reset(data, 1);
809
810 status = nanohub_bl_erase_shared(data);
811 dev_info(dev, "nanohub_bl_erase_shared: status=%02x\n",
812 status);
813
814 __nanohub_hw_reset(data, 0);
815 nanohub_wakeup_unlock(data);
816
817 return ret < 0 ? ret : count;
818 #elif defined(CONFIG_NANOHUB_MAILBOX)
819 __nanohub_hw_reset(data, 1);
820
821 contexthub_ipc_write_event(data->pdata->mailbox_client, MAILBOX_EVT_ERASE_SHARED);
822
823 __nanohub_hw_reset(data, 0);
824 return count;
825 #endif
826
827 }
828
829 #ifdef CONFIG_EXT_CHUB
830 static ssize_t nanohub_erase_shared_bl(struct device *dev,
831 struct device_attribute *attr,
832 const char *buf, size_t count)
833 {
834 struct nanohub_data *data = dev_get_nanohub_data(dev);
835 uint8_t status = CMD_ACK;
836 int ret;
837
838 ret = nanohub_wakeup_lock(data, LOCK_MODE_IO_BL);
839 if (ret < 0)
840 return ret;
841
842 __nanohub_hw_reset(data, -1);
843
844 status = nanohub_bl_erase_shared_bl(data);
845 dev_info(dev, "%s: status=%02x\n", __func__, status);
846
847 __nanohub_hw_reset(data, 0);
848 nanohub_wakeup_unlock(data);
849
850 return ret < 0 ? ret : count;
851 }
852 #endif
853 static ssize_t nanohub_download_bl(struct device *dev,
854 struct device_attribute *attr,
855 const char *buf, size_t count)
856 {
857 struct nanohub_data *data = dev_get_nanohub_data(dev);
858 int ret;
859 #ifdef CONFIG_EXT_CHUB
860 const struct nanohub_platform_data *pdata = data->pdata;
861 const struct firmware *fw_entry;
862
863 uint8_t status = CMD_ACK;
864 uint32_t *buf;
865
866 ret = nanohub_wakeup_lock(data, LOCK_MODE_IO);
867 if (ret < 0)
868 return ret;
869
870 data->err_cnt = 0;
871 __nanohub_hw_reset(data, 1);
872
873 ret = request_firmware(&fw_entry, "nanohub.full.bin", dev);
874 if (ret) {
875 dev_err(dev, "%s: err=%d\n", __func__, ret);
876 } else {
877 status = nanohub_bl_download(data, pdata->bl_addr,
878 fw_entry->data, fw_entry->size);
879 dev_info(dev, "%s: status=%02x\n", __func__, status);
880 release_firmware(fw_entry);
881 }
882
883 __nanohub_hw_reset(data, 0);
884 nanohub_wakeup_unlock(data);
885
886 return ret < 0 ? ret : count;
887 #elif defined(CONFIG_NANOHUB_MAILBOX)
888 ret = contexthub_reset(data->pdata->mailbox_client, 1, CHUB_ERR_NONE);
889
890 return ret < 0 ? ret : count;
891 #endif
892 }
893
894 static ssize_t nanohub_download_kernel(struct device *dev,
895 struct device_attribute *attr,
896 const char *buf, size_t count)
897 {
898 struct nanohub_data *data = dev_get_nanohub_data(dev);
899
900 #ifdef CONFIG_NANOHUB_MAILBOX
901 int ret = contexthub_download_image(data->pdata->mailbox_client, IPC_REG_OS);
902
903 return ret < 0 ? ret : count;
904 #else
905 const struct firmware *fw_entry;
906 int ret;
907
908 ret = request_firmware(&fw_entry, "nanohub.update.bin", dev);
909 if (ret) {
910 dev_err(dev, "nanohub_download_kernel: err=%d\n", ret);
911 return -EIO;
912 } else {
913 ret =
914 nanohub_comms_kernel_download(data, fw_entry->data,
915 fw_entry->size);
916
917 release_firmware(fw_entry);
918
919 return count;
920 }
921 #endif
922 }
923
924 #ifdef CONFIG_EXT_CHUB
925 static ssize_t nanohub_download_kernel_bl(struct device *dev,
926 struct device_attribute *attr,
927 const char *buf, size_t count)
928 {
929 struct nanohub_data *data = dev_get_nanohub_data(dev);
930 const struct firmware *fw_entry;
931 int ret;
932 uint8_t status = CMD_ACK;
933
934 ret = request_firmware(&fw_entry, "nanohub.kernel.signed", dev);
935 if (ret) {
936 dev_err(dev, "%s: err=%d\n", __func__, ret);
937 } else {
938 ret = nanohub_wakeup_lock(data, LOCK_MODE_IO_BL);
939 if (ret < 0)
940 return ret;
941
942 __nanohub_hw_reset(data, -1);
943
944 status = nanohub_bl_erase_shared_bl(data);
945 dev_info(dev, "%s: (erase) status=%02x\n", __func__, status);
946 if (status == CMD_ACK) {
947 status = nanohub_bl_write_memory(data, 0x50000000,
948 fw_entry->size,
949 fw_entry->data);
950 mcu_wakeup_gpio_set_value(data, 1);
951 dev_info(dev, "%s: (write) status=%02x\n", __func__, status);
952 if (status == CMD_ACK) {
953 status = nanohub_bl_update_finished(data);
954 dev_info(dev, "%s: (finish) status=%02x\n", __func__, status);
955 }
956 } else {
957 mcu_wakeup_gpio_set_value(data, 1);
958 }
959
960 __nanohub_hw_reset(data, 0);
961 nanohub_wakeup_unlock(data);
962
963 release_firmware(fw_entry);
964 }
965
966 return ret < 0 ? ret : count;
967 }
968 #endif
969
970 static ssize_t nanohub_download_app(struct device *dev,
971 struct device_attribute *attr,
972 const char *buf, size_t count)
973 {
974 struct nanohub_data *data = dev_get_nanohub_data(dev);
975 const struct firmware *fw_entry;
976 char buffer[70];
977 int i, ret, ret1, ret2, file_len = 0, appid_len = 0, ver_len = 0;
978 const char *appid = NULL, *ver = NULL;
979 unsigned long version;
980 uint64_t id;
981 uint32_t cur_version;
982 bool update = true;
983
984 for (i = 0; i < count; i++) {
985 if (buf[i] == ' ') {
986 if (i + 1 == count) {
987 break;
988 } else {
989 if (appid == NULL)
990 appid = buf + i + 1;
991 else if (ver == NULL)
992 ver = buf + i + 1;
993 else
994 break;
995 }
996 } else if (buf[i] == '\n' || buf[i] == '\r') {
997 break;
998 } else {
999 if (ver)
1000 ver_len++;
1001 else if (appid)
1002 appid_len++;
1003 else
1004 file_len++;
1005 }
1006 }
1007
1008 if (file_len > 64 || appid_len > 16 || ver_len > 8 || file_len < 1)
1009 return -EIO;
1010
1011 memcpy(buffer, buf, file_len);
1012 memcpy(buffer + file_len, ".napp", 5);
1013 buffer[file_len + 5] = '\0';
1014
1015 ret = request_firmware(&fw_entry, buffer, dev);
1016 if (ret) {
1017 dev_err(dev, "nanohub_download_app(%s): err=%d\n",
1018 buffer, ret);
1019 return -EIO;
1020 }
1021 if (appid_len > 0 && ver_len > 0) {
1022 memcpy(buffer, appid, appid_len);
1023 buffer[appid_len] = '\0';
1024
1025 ret1 = kstrtoull(buffer, 16, &id);
1026
1027 memcpy(buffer, ver, ver_len);
1028 buffer[ver_len] = '\0';
1029
1030 ret2 = kstrtoul(buffer, 16, &version);
1031
1032 if (ret1 == 0 && ret2 == 0) {
1033 if (request_wakeup(data))
1034 return -ERESTARTSYS;
1035 if (nanohub_comms_tx_rx_retrans
1036 (data, CMD_COMMS_GET_APP_VERSIONS,
1037 (uint8_t *)&id, sizeof(id),
1038 (uint8_t *)&cur_version,
1039 sizeof(cur_version), false, 10,
1040 10) == sizeof(cur_version)) {
1041 if (cur_version == version)
1042 update = false;
1043 }
1044 release_wakeup(data);
1045 }
1046 }
1047
1048 if (update)
1049 ret =
1050 nanohub_comms_app_download(data, fw_entry->data,
1051 fw_entry->size);
1052
1053 release_firmware(fw_entry);
1054
1055 return count;
1056 }
1057 #ifdef CONFIG_EXT_CHUB
1058 static ssize_t nanohub_lock_bl(struct device *dev,
1059 struct device_attribute *attr,
1060 const char *buf, size_t count)
1061 {
1062 struct nanohub_data *data = dev_get_nanohub_data(dev);
1063 int ret;
1064 uint8_t status = CMD_ACK;
1065
1066 ret = nanohub_wakeup_lock(data, LOCK_MODE_IO);
1067 if (ret < 0)
1068 return ret;
1069
1070 __nanohub_hw_reset(data, 1);
1071
1072 gpio_set_value(data->pdata->boot0_gpio, 0);
1073 /* this command reboots itself */
1074 status = nanohub_bl_lock(data);
1075 dev_info(dev, "%s: status=%02x\n", __func__, status);
1076 msleep(350);
1077
1078 nanohub_wakeup_unlock(data);
1079
1080 return ret < 0 ? ret : count;
1081 }
1082
1083 static ssize_t nanohub_unlock_bl(struct device *dev,
1084 struct device_attribute *attr,
1085 const char *buf, size_t count)
1086 {
1087 struct nanohub_data *data = dev_get_nanohub_data(dev);
1088 int ret;
1089 uint8_t status = CMD_ACK;
1090
1091 ret = nanohub_wakeup_lock(data, LOCK_MODE_IO);
1092 if (ret < 0)
1093 return ret;
1094
1095 __nanohub_hw_reset(data, 1);
1096
1097 gpio_set_value(data->pdata->boot0_gpio, 0);
1098 /* this command reboots itself (erasing the flash) */
1099 status = nanohub_bl_unlock(data);
1100 dev_info(dev, "%s: status=%02x\n", __func__, status);
1101 msleep(20);
1102
1103 nanohub_wakeup_unlock(data);
1104
1105 return ret < 0 ? ret : count;
1106 }
1107 #endif
1108
1109 #ifdef CONFIG_NANOHUB_MAILBOX
1110 static int chub_get_chipid(struct contexthub_ipc_info *ipc)
1111
1112 {
1113 int trycnt = 0;
1114 u32 id = 0;
1115
1116 ipc_write_debug_val(IPC_DATA_C2A, 0); /* clear */
1117 contexthub_ipc_write_event(ipc, (u32)IPC_DEBUG_UTC_SENSOR_CHIPID);
1118
1119 do {
1120 msleep(WAIT_CHUB_MS);
1121 id = ipc_read_debug_val(IPC_DATA_C2A);
1122 if (++trycnt > WAIT_TRY_CNT) {
1123 pr_warn("%s: can't get result\n", __func__);
1124 break;
1125 }
1126 } while (!id);
1127
1128 return id;
1129 }
1130
1131 static ssize_t chub_chipid_show(struct device *dev,
1132 struct device_attribute *attr, char *buf)
1133 {
1134 struct nanohub_data *data = dev_get_nanohub_data(dev);
1135 u32 id = chub_get_chipid(data->pdata->mailbox_client);
1136
1137 dev_info(dev, "%s: %d\n", __func__, id);
1138 if (id)
1139 return sprintf(buf, "0x%x\n", id);
1140 else
1141 return 0;
1142 }
1143
1144 static ssize_t chub_chipid_store(struct device *dev,
1145 struct device_attribute *attr,
1146 const char *buf, size_t count)
1147 {
1148 long id;
1149 int err = kstrtol(&buf[0], 10, &id);
1150
1151 dev_info(dev, "%s: id: %d\n", __func__, id);
1152 if (!err) {
1153 ipc_write_debug_val(IPC_DATA_A2C, (u32)id);
1154 return count;
1155 } else {
1156 return 0;
1157 }
1158 }
1159
1160 static ssize_t chub_sensortype_store(struct device *dev,
1161 struct device_attribute *attr,
1162 const char *buf, size_t count)
1163 {
1164 return 0;
1165 }
1166
1167 static ssize_t chub_sensortype_show(struct device *dev,
1168 struct device_attribute *attr, char *buf)
1169 {
1170 struct nanohub_data *data = dev_get_nanohub_data(dev);
1171
1172 return contexthub_get_sensortype(data->pdata->mailbox_client, buf);
1173 }
1174
1175 void nanohub_add_dump_request(struct nanohub_data *data)
1176 {
1177 struct nanohub_io *io = &data->io[ID_NANOHUB_SENSOR];
1178 struct nanohub_buf *buf = nanohub_io_get_buf(&data->free_pool, false);
1179 uint32_t *buffer;
1180
1181 if (buf) {
1182 buffer = (uint32_t *)buf->buffer;
1183 *buffer = EVT_DEBUG_DUMP;
1184 nanohub_io_put_buf(io, buf);
1185 wake_lock_timeout(&data->wakelock_read, msecs_to_jiffies(250));
1186 } else {
1187 pr_err("%s: cann't get io buf\n", __func__);
1188 }
1189 }
1190
1191 static ssize_t chub_dumpio_show(struct device *dev,
1192 struct device_attribute *attr, char *buf)
1193 {
1194 struct nanohub_data *data = dev_get_nanohub_data(dev);
1195 struct nanohub_io *io;
1196 struct nanohub_buf *desc = NULL;
1197 int buf_io_cnt[ID_NANOHUB_MAX] = {0, 0};
1198 int free_io_cnt = 0;
1199 int i;
1200 int io_num;
1201
1202 for (i = 0; i < ID_NANOHUB_MAX; i++) {
1203 io_num = i;
1204 io = &data->io[i];
1205 list_for_each_entry(desc, &io->buf_list, list)
1206 buf_io_cnt[i]++;
1207 }
1208 list_for_each_entry(desc, &data->free_pool.buf_list, list)
1209 free_io_cnt++;
1210
1211 return sprintf(buf, "%s: sensor:%d, comms:%d, free:%d \n", __func__,
1212 buf_io_cnt[ID_NANOHUB_SENSOR], buf_io_cnt[ID_NANOHUB_COMMS], free_io_cnt);
1213 }
1214 #endif
1215
1216 static struct device_attribute attributes[] = {
1217 __ATTR(wakeup, 0440, nanohub_wakeup_query, NULL),
1218 __ATTR(app_info, 0440, nanohub_app_info, NULL),
1219 __ATTR(firmware_version, 0440, nanohub_firmware_query, NULL),
1220 __ATTR(download_bl, 0220, NULL, nanohub_download_bl),
1221 __ATTR(download_kernel, 0220, NULL, nanohub_download_kernel),
1222 #ifdef CONFIG_EXT_CHUB
1223 __ATTR(download_kernel_bl, 0220, NULL, nanohub_download_kernel_bl),
1224 #endif
1225 __ATTR(download_app, 0220, NULL, nanohub_download_app),
1226 __ATTR(erase_shared, 0220, NULL, nanohub_erase_shared),
1227 #ifdef CONFIG_EXT_CHUB
1228 __ATTR(erase_shared_bl, 0220, NULL, nanohub_erase_shared_bl),
1229 #endif
1230 __ATTR(reset, 0220, NULL, nanohub_try_hw_reset),
1231 #ifdef CONFIG_EXT_CHUB
1232 __ATTR(lock, 0220, NULL, nanohub_lock_bl),
1233 __ATTR(unlock, 0220, NULL, nanohub_unlock_bl),
1234 #endif
1235 #ifdef CONFIG_NANOHUB_MAILBOX
1236 __ATTR(chipid, 0664, chub_chipid_show, chub_chipid_store),
1237 __ATTR(sensortype, 0775, chub_sensortype_show, chub_sensortype_store),
1238 __ATTR(dumpio, 0440, chub_dumpio_show, NULL),
1239 #endif
1240 };
1241
1242 static inline int nanohub_create_sensor(struct nanohub_data *data)
1243 {
1244 int i, ret;
1245 struct device *sensor_dev = data->io[ID_NANOHUB_SENSOR].dev;
1246
1247 for (i = 0, ret = 0; i < ARRAY_SIZE(attributes); i++) {
1248 ret = device_create_file(sensor_dev, &attributes[i]);
1249 if (ret) {
1250 dev_err(sensor_dev,
1251 "create sysfs attr %d [%s] failed; err=%d\n",
1252 i, attributes[i].attr.name, ret);
1253 goto fail_attr;
1254 }
1255 }
1256
1257 ret = sysfs_create_link(&sensor_dev->kobj,
1258 &data->iio_dev->dev.kobj, "iio");
1259 if (ret) {
1260 dev_err(sensor_dev,
1261 "sysfs_create_link failed; err=%d\n", ret);
1262 goto fail_attr;
1263 }
1264 goto done;
1265
1266 fail_attr:
1267 for (i--; i >= 0; i--)
1268 device_remove_file(sensor_dev, &attributes[i]);
1269 done:
1270 return ret;
1271 }
1272
1273 static int nanohub_create_devices(struct nanohub_data *data)
1274 {
1275 int i, ret;
1276 struct device *chub_dev;
1277 static const char *names[ID_NANOHUB_MAX] = {
1278 "nanohub", "nanohub_comms"
1279 };
1280
1281 for (i = 0; i < ID_NANOHUB_MAX; ++i) {
1282 struct nanohub_io *io = &data->io[i];
1283
1284 nanohub_io_init(io, data, device_create(sensor_class, NULL,
1285 MKDEV(major, i),
1286 io, names[i]));
1287 if (IS_ERR(io->dev)) {
1288 ret = PTR_ERR(io->dev);
1289 pr_err("nanohub: device_create failed for %s; err=%d\n",
1290 names[i], ret);
1291 goto fail_dev;
1292 }
1293 }
1294 chub_dev = device_create(sensor_class, NULL, MKDEV(chub_dev_major, 0), NULL, "chub_dev");
1295 if(chub_dev == NULL)
1296 pr_info("nanohub: device_create failed for chub_dev!\n");
1297 ret = nanohub_create_sensor(data);
1298 if (!ret)
1299 goto done;
1300
1301 fail_dev:
1302 for (--i; i >= 0; --i)
1303 device_destroy(sensor_class, MKDEV(major, i));
1304 device_destroy(sensor_class, MKDEV(chub_dev_major, 0));
1305 done:
1306 return ret;
1307 }
1308
1309 static int nanohub_match_devt(struct device *dev, const void *data)
1310 {
1311 const dev_t *devt = data;
1312
1313 return dev->devt == *devt;
1314 }
1315
1316 int nanohub_reset(struct nanohub_data *data)
1317 {
1318 #ifdef CONFIG_NANOHUB_MAILBOX
1319 return contexthub_poweron(data->pdata->mailbox_client);
1320 #else
1321 const struct nanohub_platform_data *pdata = data->pdata;
1322
1323 gpio_set_value(pdata->nreset_gpio, 1);
1324 usleep_range(650000, 700000);
1325
1326 #ifdef CONFIG_EXT_CHUB
1327 enable_irq(data->irq1);
1328 if (data->irq2)
1329 enable_irq(data->irq2);
1330 else
1331 nanohub_unmask_interrupt(data, 2);
1332 #else
1333 contexthub_ipc_write_event(data->pdata->mailbox_client, (u32)MAILBOX_EVT_ENABLE_IRQ);
1334 #endif
1335
1336 return 0;
1337 #endif
1338 }
1339
1340 static int nanohub_kthread(void *arga);
1341 static int nanohub_open(struct inode *inode, struct file *file)
1342 {
1343 dev_t devt = inode->i_rdev;
1344 struct device *dev;
1345 #ifdef CONFIG_NANOHUB_MAILBOX
1346 struct nanohub_io *io;
1347 #endif
1348 dev = class_find_device(sensor_class, NULL, &devt, nanohub_match_devt);
1349 if (dev) {
1350 file->private_data = dev_get_drvdata(dev);
1351 nonseekable_open(inode, file);
1352 #ifdef CONFIG_NANOHUB_MAILBOX
1353 io = file->private_data;
1354 nanohub_reset(io->data);
1355 io->data->thread = kthread_run(nanohub_kthread, io->data, "nanohub");
1356 udelay(30);
1357 #endif
1358 return 0;
1359 }
1360
1361 return -ENODEV;
1362 }
1363
1364 static ssize_t nanohub_read(struct file *file, char *buffer, size_t length,
1365 loff_t *offset)
1366 {
1367 struct nanohub_io *io = file->private_data;
1368 struct nanohub_data *data = io->data;
1369 struct nanohub_buf *buf;
1370 int ret;
1371
1372 if (!nanohub_io_has_buf(io) && (file->f_flags & O_NONBLOCK))
1373 return -EAGAIN;
1374
1375 buf = nanohub_io_get_buf(io, true);
1376 if (IS_ERR_OR_NULL(buf))
1377 return PTR_ERR(buf);
1378
1379 ret = copy_to_user(buffer, buf->buffer, buf->length);
1380 if (ret != 0)
1381 ret = -EFAULT;
1382 else
1383 ret = buf->length;
1384
1385 #ifdef CONFIG_NANOHUB_MAILBOX
1386 if (nanohub_is_reset_notify_io(buf)) {
1387 io = &io->data->free_pool;
1388 spin_lock(&io->buf_wait.lock);
1389 list_add_tail(&buf->list, &io->buf_list);
1390 spin_unlock(&io->buf_wait.lock);
1391 } else
1392 nanohub_io_put_buf(&data->free_pool, buf);
1393 #else
1394 nanohub_io_put_buf(&data->free_pool, buf);
1395 #endif
1396
1397 return ret;
1398 }
1399
1400 static ssize_t nanohub_write(struct file *file, const char *buffer,
1401 size_t length, loff_t *offset)
1402 {
1403 struct nanohub_io *io = file->private_data;
1404 struct nanohub_data *data = io->data;
1405 int ret;
1406 #ifdef CONFIG_NANOHUB_MAILBOX
1407 struct contexthub_ipc_info *ipc = data->pdata->mailbox_client;
1408
1409 if (atomic_read(&ipc->chub_status) != CHUB_ST_RUN) {
1410 dev_warn(data->io[ID_NANOHUB_SENSOR].dev,
1411 "%s fails. nanohub isn't running\n", __func__);
1412 return -EINVAL;
1413 }
1414
1415 /* wakeup timeout should be bigger than timeout_write (544) to support both usecase */
1416 ret = request_wakeup_timeout(data, 644);
1417 #else
1418
1419 ret = request_wakeup_timeout(data, 500);
1420 #endif
1421
1422 if (ret)
1423 return ret;
1424
1425 ret = nanohub_comms_write(data, buffer, length);
1426
1427 release_wakeup(data);
1428
1429 return ret;
1430 }
1431
1432 static unsigned int nanohub_poll(struct file *file, poll_table *wait)
1433 {
1434 struct nanohub_io *io = file->private_data;
1435 unsigned int mask = POLLOUT | POLLWRNORM;
1436
1437 poll_wait(file, &io->buf_wait, wait);
1438
1439 if (nanohub_io_has_buf(io))
1440 mask |= POLLIN | POLLRDNORM;
1441
1442 return mask;
1443 }
1444
1445 static int nanohub_release(struct inode *inode, struct file *file)
1446 {
1447 file->private_data = NULL;
1448
1449 return 0;
1450 }
1451
1452 static int chub_dev_open(struct inode *inode, struct file *file)
1453 {
1454 pr_info("%s\n", __func__);
1455 return 0;
1456 }
1457
1458 static ssize_t chub_dev_read(struct file *file, char *buffer,
1459 size_t length, loff_t *offset)
1460 {
1461 return 0;
1462 }
1463
1464 static int nanohub_match_name(struct device *dev, const void *data)
1465 {
1466 const char *name = data;
1467
1468 if(dev->kobj.name == NULL) {
1469 pr_info("nanohub device name invalid\n");
1470 return 0;
1471 }
1472
1473 pr_info("nanohub device name = %s\n", dev->kobj.name);
1474 return !strcmp(dev->kobj.name, name);
1475 }
1476
1477 static ssize_t chub_dev_write(struct file *file, const char *buffer,
1478 size_t length, loff_t *offset)
1479 {
1480 struct device *dev_nanohub;
1481 struct nanohub_data *data;
1482 struct contexthub_ipc_info *ipc;
1483 int8_t num_os;
1484 int ret;
1485
1486 dev_nanohub = class_find_device(sensor_class, NULL, "nanohub", nanohub_match_name);
1487 if(dev_nanohub == NULL) {
1488 pr_err("%s: dev_nanohub not available\n", __func__);
1489 return -EINVAL;
1490 }
1491
1492 data = dev_get_nanohub_data(dev_nanohub);
1493 if(data == NULL) {
1494 pr_err("%s nanohub_data not available\n", __func__);
1495 return -EINVAL;
1496 }
1497
1498 ipc = data->pdata->mailbox_client;
1499 if(ipc == NULL) {
1500 pr_err("%s ipc not available\n", __func__);
1501 return -EINVAL;
1502 }
1503
1504 //read int8_t num_os
1505 ret = copy_from_user(&num_os, buffer, sizeof(num_os));
1506
1507 if(num_os > 0 && num_os < SENSOR_VARIATION) {
1508 ipc->sel_os = true;
1509 pr_info("%s saved os name: %s\n", __func__, os_image[num_os]);
1510 strncpy(ipc->os_name, os_image[num_os], sizeof(ipc->os_name));
1511 } else
1512 pr_warn("%s num_os is invalid %d\n", __func__, num_os);
1513
1514 return 0;
1515 }
1516
1517 static void nanohub_destroy_devices(struct nanohub_data *data)
1518 {
1519 int i;
1520 struct device *sensor_dev = data->io[ID_NANOHUB_SENSOR].dev;
1521
1522 sysfs_remove_link(&sensor_dev->kobj, "iio");
1523 for (i = 0; i < ARRAY_SIZE(attributes); i++)
1524 device_remove_file(sensor_dev, &attributes[i]);
1525 for (i = 0; i < ID_NANOHUB_MAX; ++i)
1526 device_destroy(sensor_class, MKDEV(major, i));
1527 device_destroy(sensor_class, MKDEV(chub_dev_major, 0));
1528 }
1529
1530 #ifdef CONFIG_EXT_CHUB
1531 static irqreturn_t nanohub_irq1(int irq, void *dev_id)
1532 {
1533 struct nanohub_data *data = (struct nanohub_data *)dev_id;
1534
1535 nanohub_handle_irq1(data);
1536
1537 return IRQ_HANDLED;
1538 }
1539
1540 static irqreturn_t nanohub_irq2(int irq, void *dev_id)
1541 {
1542 struct nanohub_data *data = (struct nanohub_data *)dev_id;
1543
1544 nanohub_handle_irq2(data);
1545
1546 return IRQ_HANDLED;
1547 }
1548 #endif
1549
1550 static bool nanohub_os_log(char *buffer, int len)
1551 {
1552 if (le32_to_cpu((((uint32_t *)buffer)[0]) & 0x7FFFFFFF) ==
1553 OS_LOG_EVENTID) {
1554 char *mtype, *mdata = &buffer[5];
1555
1556 buffer[len] = 0x00;
1557
1558 switch (buffer[4]) {
1559 case 'E':
1560 mtype = KERN_ERR;
1561 break;
1562 case 'W':
1563 mtype = KERN_WARNING;
1564 break;
1565 case 'I':
1566 mtype = KERN_INFO;
1567 break;
1568 case 'D':
1569 mtype = KERN_DEBUG;
1570 break;
1571 default:
1572 mtype = KERN_DEFAULT;
1573 mdata--;
1574 break;
1575 }
1576 printk("%snanohub: %s", mtype, mdata);
1577 return true;
1578 } else {
1579 return false;
1580 }
1581 }
1582
1583 static void nanohub_process_buffer(struct nanohub_data *data,
1584 struct nanohub_buf **buf,
1585 int ret)
1586 {
1587 uint32_t event_id;
1588 uint8_t interrupt;
1589 bool wakeup = false;
1590 struct nanohub_io *io = &data->io[ID_NANOHUB_SENSOR];
1591
1592 data->kthread_err_cnt = 0;
1593 if (ret < 4 || nanohub_os_log((*buf)->buffer, ret)) {
1594 release_wakeup(data);
1595 return;
1596 }
1597
1598 (*buf)->length = ret;
1599
1600 event_id = le32_to_cpu((((uint32_t *)(*buf)->buffer)[0]) & 0x7FFFFFFF);
1601 if (ret >= sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint32_t) &&
1602 event_id > FIRST_SENSOR_EVENTID &&
1603 event_id <= LAST_SENSOR_EVENTID) {
1604 interrupt = (*buf)->buffer[sizeof(uint32_t) +
1605 sizeof(uint64_t) + 3];
1606 if (interrupt == WAKEUP_INTERRUPT)
1607 wakeup = true;
1608 }
1609 if (event_id == APP_TO_HOST_EVENTID) {
1610 wakeup = true;
1611 /* chub doesn't enable nanohal. use sensorhal io */
1612 io = &data->io[ID_NANOHUB_COMMS];
1613 }
1614
1615 nanohub_io_put_buf(io, *buf);
1616
1617 *buf = NULL;
1618 /* (for wakeup interrupts): hold a wake lock for 250ms so the sensor hal
1619 * has time to grab its own wake lock */
1620 if (wakeup)
1621 wake_lock_timeout(&data->wakelock_read, msecs_to_jiffies(250));
1622 release_wakeup(data);
1623 }
1624
1625 static int nanohub_kthread(void *arg)
1626 {
1627 struct nanohub_data *data = (struct nanohub_data *)arg;
1628 struct nanohub_buf *buf = NULL;
1629 int ret;
1630 ktime_t ktime_delta;
1631 uint32_t clear_interrupts[8] = { 0x00000006 };
1632 struct device *sensor_dev = data->io[ID_NANOHUB_SENSOR].dev;
1633 static const struct sched_param param = {
1634 .sched_priority = (MAX_USER_RT_PRIO/2)-1,
1635 };
1636
1637 data->kthread_err_cnt = 0;
1638 sched_setscheduler(current, SCHED_FIFO, &param);
1639 nanohub_set_state(data, ST_IDLE);
1640
1641 while (!kthread_should_stop()) {
1642 switch (nanohub_get_state(data)) {
1643 case ST_IDLE:
1644 wait_event_interruptible(data->kthread_wait,
1645 atomic_read(&data->kthread_run)
1646 );
1647 nanohub_set_state(data, ST_RUNNING);
1648 break;
1649 case ST_ERROR:
1650 ktime_delta = ktime_sub(ktime_get_boottime(),
1651 data->kthread_err_ktime);
1652 if (ktime_to_ns(ktime_delta) > KTHREAD_ERR_TIME_NS
1653 && data->kthread_err_cnt > KTHREAD_ERR_CNT) {
1654 dev_info(sensor_dev,
1655 "kthread: hard reset due to consistent error\n");
1656 ret = nanohub_hw_reset(data);
1657 if (ret) {
1658 dev_info(sensor_dev,
1659 "%s: failed to reset nanohub: ret=%d\n",
1660 __func__, ret);
1661 }
1662 }
1663 msleep_interruptible(WAKEUP_TIMEOUT_MS);
1664 nanohub_set_state(data, ST_RUNNING);
1665 #ifdef CONFIG_NANOHUB_MAILBOX
1666 #ifndef CHUB_RESET_ENABLE
1667 if (ret) {
1668 dev_warn(data->io[ID_NANOHUB_SENSOR].dev,
1669 "%s fails. nanohub isn't running\n", __func__);
1670 return 0;
1671 }
1672 #endif
1673 #endif
1674 break;
1675 case ST_RUNNING:
1676 break;
1677 }
1678 atomic_set(&data->kthread_run, 0);
1679 if (!buf)
1680 buf = nanohub_io_get_buf(&data->free_pool,
1681 false);
1682 if (buf) {
1683 ret = request_wakeup_timeout(data, 600);
1684 if (ret) {
1685 dev_info(sensor_dev,
1686 "%s: request_wakeup_timeout: ret=%d, err_cnt:%d\n",
1687 __func__, ret, data->kthread_err_cnt);
1688 continue;
1689 }
1690
1691 ret = nanohub_comms_rx_retrans_boottime(
1692 data, CMD_COMMS_READ, buf->buffer,
1693 sizeof(buf->buffer), 10, 0);
1694
1695 if (ret > 0) {
1696 nanohub_process_buffer(data, &buf, ret);
1697 if (!nanohub_irq1_fired(data) &&
1698 !nanohub_irq2_fired(data)) {
1699 nanohub_set_state(data, ST_IDLE);
1700 continue;
1701 }
1702 } else if (ret == 0) {
1703 /* queue empty, go to sleep */
1704 data->kthread_err_cnt = 0;
1705 data->interrupts[0] &= ~0x00000006;
1706 release_wakeup(data);
1707 nanohub_set_state(data, ST_IDLE);
1708 continue;
1709 } else {
1710 release_wakeup(data);
1711 if (data->kthread_err_cnt == 0)
1712 data->kthread_err_ktime =
1713 ktime_get_boottime();
1714
1715 data->kthread_err_cnt++;
1716 if (data->kthread_err_cnt >= KTHREAD_WARN_CNT) {
1717 dev_err(sensor_dev,
1718 "%s: kthread_err_cnt=%d\n",
1719 __func__,
1720 data->kthread_err_cnt);
1721 nanohub_set_state(data, ST_ERROR);
1722 continue;
1723 }
1724 }
1725 } else {
1726 if (!nanohub_irq1_fired(data) &&
1727 !nanohub_irq2_fired(data)) {
1728 nanohub_set_state(data, ST_IDLE);
1729 continue;
1730 }
1731 /* pending interrupt, but no room to read data -
1732 * clear interrupts */
1733 if (request_wakeup(data))
1734 continue;
1735 nanohub_comms_tx_rx_retrans(data,
1736 CMD_COMMS_CLR_GET_INTR,
1737 (uint8_t *)
1738 clear_interrupts,
1739 sizeof(clear_interrupts),
1740 (uint8_t *) data->
1741 interrupts,
1742 sizeof(data->interrupts),
1743 false, 10, 0);
1744 release_wakeup(data);
1745 nanohub_set_state(data, ST_IDLE);
1746 }
1747 }
1748
1749 return 0;
1750 }
1751
1752 #ifndef CONFIG_NANOHUB_MAILBOX
1753 #ifdef CONFIG_OF
1754 static struct nanohub_platform_data *nanohub_parse_dt(struct device *dev)
1755 {
1756 struct nanohub_platform_data *pdata;
1757 struct device_node *dt = dev->of_node;
1758 const uint32_t *tmp;
1759 struct property *prop;
1760 uint32_t u, i;
1761 int ret;
1762
1763 if (!dt)
1764 return ERR_PTR(-ENODEV);
1765
1766 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1767 if (!pdata)
1768 return ERR_PTR(-ENOMEM);
1769
1770 ret = pdata->irq1_gpio =
1771 of_get_named_gpio(dt, "sensorhub,irq1-gpio", 0);
1772 if (ret < 0) {
1773 pr_err("nanohub: missing sensorhub,irq1-gpio in device tree\n");
1774 goto free_pdata;
1775 }
1776
1777 /* optional (strongly recommended) */
1778 pdata->irq2_gpio = of_get_named_gpio(dt, "sensorhub,irq2-gpio", 0);
1779
1780 ret = pdata->wakeup_gpio =
1781 of_get_named_gpio(dt, "sensorhub,wakeup-gpio", 0);
1782 if (ret < 0) {
1783 pr_err
1784 ("nanohub: missing sensorhub,wakeup-gpio in device tree\n");
1785 goto free_pdata;
1786 }
1787
1788 ret = pdata->nreset_gpio =
1789 of_get_named_gpio(dt, "sensorhub,nreset-gpio", 0);
1790 if (ret < 0) {
1791 pr_err
1792 ("nanohub: missing sensorhub,nreset-gpio in device tree\n");
1793 goto free_pdata;
1794 }
1795
1796 /* optional (stm32f bootloader) */
1797 pdata->boot0_gpio = of_get_named_gpio(dt, "sensorhub,boot0-gpio", 0);
1798
1799 /* optional (spi) */
1800 pdata->spi_cs_gpio = of_get_named_gpio(dt, "sensorhub,spi-cs-gpio", 0);
1801
1802 /* optional (stm32f bootloader) */
1803 of_property_read_u32(dt, "sensorhub,bl-addr", &pdata->bl_addr);
1804
1805 /* optional (stm32f bootloader) */
1806 tmp = of_get_property(dt, "sensorhub,num-flash-banks", NULL);
1807 if (tmp) {
1808 pdata->num_flash_banks = be32_to_cpup(tmp);
1809 pdata->flash_banks =
1810 devm_kzalloc(dev,
1811 sizeof(struct nanohub_flash_bank) *
1812 pdata->num_flash_banks, GFP_KERNEL);
1813 if (!pdata->flash_banks)
1814 goto no_mem;
1815
1816 /* TODO: investigate replacing with of_property_read_u32_array
1817 */
1818 i = 0;
1819 of_property_for_each_u32(dt, "sensorhub,flash-banks", prop, tmp,
1820 u) {
1821 if (i / 3 >= pdata->num_flash_banks)
1822 break;
1823 switch (i % 3) {
1824 case 0:
1825 pdata->flash_banks[i / 3].bank = u;
1826 break;
1827 case 1:
1828 pdata->flash_banks[i / 3].address = u;
1829 break;
1830 case 2:
1831 pdata->flash_banks[i / 3].length = u;
1832 break;
1833 }
1834 i++;
1835 }
1836 }
1837
1838 /* optional (stm32f bootloader) */
1839 tmp = of_get_property(dt, "sensorhub,num-shared-flash-banks", NULL);
1840 if (tmp) {
1841 pdata->num_shared_flash_banks = be32_to_cpup(tmp);
1842 pdata->shared_flash_banks =
1843 devm_kzalloc(dev,
1844 sizeof(struct nanohub_flash_bank) *
1845 pdata->num_shared_flash_banks, GFP_KERNEL);
1846 if (!pdata->shared_flash_banks)
1847 goto no_mem_shared;
1848
1849 /* TODO: investigate replacing with of_property_read_u32_array
1850 */
1851 i = 0;
1852 of_property_for_each_u32(dt, "sensorhub,shared-flash-banks",
1853 prop, tmp, u) {
1854 if (i / 3 >= pdata->num_shared_flash_banks)
1855 break;
1856 switch (i % 3) {
1857 case 0:
1858 pdata->shared_flash_banks[i / 3].bank = u;
1859 break;
1860 case 1:
1861 pdata->shared_flash_banks[i / 3].address = u;
1862 break;
1863 case 2:
1864 pdata->shared_flash_banks[i / 3].length = u;
1865 break;
1866 }
1867 i++;
1868 }
1869 }
1870
1871 return pdata;
1872
1873 no_mem_shared:
1874 devm_kfree(dev, pdata->flash_banks);
1875 no_mem:
1876 ret = -ENOMEM;
1877 free_pdata:
1878 devm_kfree(dev, pdata);
1879 return ERR_PTR(ret);
1880 }
1881 #else
1882 static struct nanohub_platform_data *nanohub_parse_dt(struct device *dev)
1883 {
1884 struct nanohub_platform_data *pdata;
1885
1886 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1887 if (!pdata)
1888 return ERR_PTR(-ENOMEM);
1889
1890 return pdata;
1891 }
1892 #endif
1893
1894 static int nanohub_request_irqs(struct nanohub_data *data)
1895 {
1896 int ret;
1897
1898 ret = request_threaded_irq(data->irq1, NULL, nanohub_irq1,
1899 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1900 "nanohub-irq1", data);
1901 if (ret < 0)
1902 data->irq1 = 0;
1903 else
1904 disable_irq(data->irq1);
1905 if (data->irq2 <= 0 || ret < 0) {
1906 data->irq2 = 0;
1907 return ret;
1908 }
1909
1910 ret = request_threaded_irq(data->irq2, NULL, nanohub_irq2,
1911 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1912 "nanohub-irq2", data);
1913 if (ret < 0) {
1914 data->irq2 = 0;
1915 WARN(1, "failed to request optional IRQ %d; err=%d",
1916 data->irq2, ret);
1917 } else {
1918 disable_irq(data->irq2);
1919 }
1920
1921 /* if 2d request fails, hide this; it is optional IRQ,
1922 * and failure should not interrupt driver init sequence.
1923 */
1924 return 0;
1925 }
1926
1927 static int nanohub_request_gpios(struct nanohub_data *data)
1928 {
1929 int i, ret = 0;
1930
1931 for (i = 0; i < ARRAY_SIZE(gconf); ++i) {
1932 const struct gpio_config *cfg = &gconf[i];
1933 unsigned int gpio = plat_gpio_get(data, cfg);
1934 const char *label;
1935 bool optional = gpio_is_optional(cfg);
1936
1937 ret = 0; /* clear errors on optional pins, if any */
1938
1939 if (!gpio_is_valid(gpio) && optional)
1940 continue;
1941
1942 label = cfg->label;
1943 ret = gpio_request_one(gpio, cfg->flags, label);
1944 if (ret && !optional) {
1945 pr_err("nanohub: gpio %d[%s] request failed;err=%d\n",
1946 gpio, label, ret);
1947 break;
1948 }
1949 if (gpio_has_irq(cfg)) {
1950 int irq = gpio_to_irq(gpio);
1951 if (irq > 0) {
1952 nanohub_set_irq_data(data, cfg, irq);
1953 } else if (!optional) {
1954 ret = -EINVAL;
1955 pr_err("nanohub: no irq; gpio %d[%s];err=%d\n",
1956 gpio, label, irq);
1957 break;
1958 }
1959 }
1960 }
1961 if (i < ARRAY_SIZE(gconf)) {
1962 for (--i; i >= 0; --i)
1963 gpio_free(plat_gpio_get(data, &gconf[i]));
1964 }
1965
1966 return ret;
1967 }
1968
1969 static void nanohub_release_gpios_irqs(struct nanohub_data *data)
1970 {
1971 const struct nanohub_platform_data *pdata = data->pdata;
1972
1973 if (data->irq2)
1974 free_irq(data->irq2, data);
1975 if (data->irq1)
1976 free_irq(data->irq1, data);
1977 if (gpio_is_valid(pdata->irq2_gpio))
1978 gpio_free(pdata->irq2_gpio);
1979 gpio_free(pdata->irq1_gpio);
1980 gpio_set_value(pdata->nreset_gpio, 0);
1981 gpio_free(pdata->nreset_gpio);
1982 mcu_wakeup_gpio_set_value(data, 1);
1983 gpio_free(pdata->wakeup_gpio);
1984 gpio_set_value(pdata->boot0_gpio, 0);
1985 gpio_free(pdata->boot0_gpio);
1986 }
1987 #endif
1988
1989 struct iio_dev *nanohub_probe(struct device *dev, struct iio_dev *iio_dev)
1990 {
1991 int ret, i;
1992 #ifdef CONFIG_NANOHUB_MAILBOX
1993 struct nanohub_platform_data *pdata;
1994 #else
1995 const struct nanohub_platform_data *pdata;
1996 #endif
1997 struct nanohub_data *data;
1998 struct nanohub_buf *buf;
1999 bool own_iio_dev = !iio_dev;
2000 pdata = dev_get_platdata(dev);
2001 if (!pdata) {
2002 #ifdef CONFIG_NANOHUB_MAILBOX
2003 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
2004 #else
2005 pdata = nanohub_parse_dt(dev);
2006 #endif
2007 if (IS_ERR(pdata))
2008 return ERR_PTR(PTR_ERR(pdata));
2009 }
2010
2011 if (own_iio_dev) {
2012 iio_dev = iio_device_alloc(sizeof(struct nanohub_data));
2013 if (!iio_dev)
2014 return ERR_PTR(-ENOMEM);
2015 }
2016
2017 iio_dev->name = "nanohub";
2018 iio_dev->dev.parent = dev;
2019 iio_dev->info = &nanohub_iio_info;
2020 iio_dev->channels = NULL;
2021 iio_dev->num_channels = 0;
2022
2023 data = iio_priv(iio_dev);
2024 data->iio_dev = iio_dev;
2025 data->pdata = pdata;
2026
2027 init_waitqueue_head(&data->kthread_wait);
2028
2029 nanohub_io_init(&data->free_pool, data, dev);
2030
2031 buf = vmalloc(sizeof(*buf) * READ_QUEUE_DEPTH);
2032 data->vbuf = buf;
2033 if (!buf) {
2034 ret = -ENOMEM;
2035 goto fail_vma;
2036 }
2037
2038 for (i = 0; i < READ_QUEUE_DEPTH; i++)
2039 nanohub_io_put_buf(&data->free_pool, &buf[i]);
2040 atomic_set(&data->kthread_run, 0);
2041 wake_lock_init(&data->wakelock_read, WAKE_LOCK_SUSPEND,
2042 "nanohub_wakelock_read");
2043
2044 atomic_set(&data->lock_mode, LOCK_MODE_NONE);
2045 atomic_set(&data->wakeup_cnt, 0);
2046 atomic_set(&data->wakeup_lock_cnt, 0);
2047 atomic_set(&data->wakeup_acquired, 0);
2048 init_waitqueue_head(&data->wakeup_wait);
2049
2050 #ifdef CONFIG_EXT_CHUB
2051 ret = nanohub_request_gpios(data);
2052 if (ret)
2053 goto fail_gpio;
2054
2055 ret = nanohub_request_irqs(data);
2056 if (ret)
2057 goto fail_irq;
2058 #endif
2059
2060 ret = iio_device_register(iio_dev);
2061 if (ret) {
2062 pr_err("nanohub: iio_device_register failed\n");
2063 goto fail_irq;
2064 }
2065
2066 ret = nanohub_create_devices(data);
2067 if (ret)
2068 goto fail_dev;
2069
2070 #ifdef CONFIG_EXT_CHUB
2071 data->thread = kthread_run(nanohub_kthread, data, "nanohub");
2072 #endif
2073 udelay(30);
2074
2075 return iio_dev;
2076
2077 fail_dev:
2078 iio_device_unregister(iio_dev);
2079 fail_irq:
2080 #ifdef CONFIG_EXT_CHUB
2081 nanohub_release_gpios_irqs(data);
2082 fail_gpio:
2083 free_irq(data->irq, data);
2084 #endif
2085 wake_lock_destroy(&data->wakelock_read);
2086 vfree(buf);
2087 fail_vma:
2088 if (own_iio_dev)
2089 iio_device_free(iio_dev);
2090
2091 return ERR_PTR(ret);
2092 }
2093
2094 int nanohub_remove(struct iio_dev *iio_dev)
2095 {
2096 struct nanohub_data *data = iio_priv(iio_dev);
2097
2098 nanohub_notify_thread(data);
2099 kthread_stop(data->thread);
2100
2101 nanohub_destroy_devices(data);
2102 iio_device_unregister(iio_dev);
2103 #ifdef CONFIG_EXT_CHUB
2104 nanohub_release_gpios_irqs(data);
2105 #endif
2106 wake_lock_destroy(&data->wakelock_read);
2107 vfree(data->vbuf);
2108 iio_device_free(iio_dev);
2109
2110 return 0;
2111 }
2112
2113 int nanohub_suspend(struct iio_dev *iio_dev)
2114 {
2115 #if defined(CONFIG_EXT_CHUB)
2116 struct nanohub_data *data = iio_priv(iio_dev);
2117 int ret;
2118
2119 ret = nanohub_wakeup_lock(data, LOCK_MODE_SUSPEND_RESUME);
2120 if (!ret) {
2121 int cnt;
2122 const int max_cnt = 10;
2123
2124 for (cnt = 0; cnt < max_cnt; ++cnt) {
2125 if (!nanohub_irq1_fired(data))
2126 break;
2127 usleep_range(10, 15);
2128 }
2129 if (cnt < max_cnt) {
2130 dev_dbg(&iio_dev->dev, "%s: cnt=%d\n", __func__, cnt);
2131 enable_irq_wake(data->irq1);
2132 return 0;
2133 }
2134 ret = -EBUSY;
2135 dev_info(&iio_dev->dev,
2136 "%s: failed to suspend: IRQ1=%d, state=%d\n",
2137 __func__, nanohub_irq1_fired(data),
2138 nanohub_get_state(data));
2139 nanohub_wakeup_unlock(data);
2140 } else {
2141 dev_info(&iio_dev->dev, "%s: could not take wakeup lock\n",
2142 __func__);
2143 }
2144
2145 return ret;
2146 #elif defined(CONFIG_NANOHUB_MAILBOX)
2147 (void)iio_dev;
2148
2149 return 0;
2150 #endif
2151 }
2152
2153 int nanohub_resume(struct iio_dev *iio_dev)
2154 {
2155 struct nanohub_data *data = iio_priv(iio_dev);
2156
2157 #if defined(CONFIG_EXT_CHUB)
2158 disable_irq_wake(data->irq1);
2159 nanohub_wakeup_unlock(data);
2160 #elif defined(CONFIG_NANOHUB_MAILBOX)
2161 nanohub_notify_thread(data);
2162 #endif
2163 return 0;
2164 }
2165
2166 static int __init nanohub_init(void)
2167 {
2168 int ret = 0;
2169
2170 sensor_class = class_create(THIS_MODULE, "nanohub");
2171 if (IS_ERR(sensor_class)) {
2172 ret = PTR_ERR(sensor_class);
2173 pr_err("nanohub: class_create failed; err=%d\n", ret);
2174 }
2175
2176 if (!ret)
2177 major = __register_chrdev(0, 0, ID_NANOHUB_MAX, "nanohub",
2178 &nanohub_fileops);
2179
2180 chub_dev_major = __register_chrdev(0, 0, 1, "chub_dev", &chub_dev_fileops);
2181 if(chub_dev_major < 0) {
2182 pr_info("nanohub : can't register chub_dev; err = %d\n", chub_dev_major);
2183 chub_dev_major = 0;
2184 } else {
2185 pr_info("nanohub : registered chub_dev; %d\n", chub_dev_major);
2186 }
2187
2188 if (major < 0) {
2189 ret = major;
2190 major = 0;
2191 pr_err("nanohub: can't register; err=%d\n", ret);
2192 } else
2193 pr_info("nanohub : registered major; %d\n", major);
2194
2195 #ifdef CONFIG_NANOHUB_I2C
2196 if (ret == 0)
2197 ret = nanohub_i2c_init();
2198 #endif
2199 #ifdef CONFIG_NANOHUB_SPI
2200 if (ret == 0)
2201 ret = nanohub_spi_init();
2202 #endif
2203 pr_info("nanohub: loaded; ret=%d\n", ret);
2204 return ret;
2205 }
2206
2207 static void __exit nanohub_cleanup(void)
2208 {
2209 #ifdef CONFIG_NANOHUB_I2C
2210 nanohub_i2c_cleanup();
2211 #endif
2212 #ifdef CONFIG_NANOHUB_SPI
2213 nanohub_spi_cleanup();
2214 #endif
2215 __unregister_chrdev(major, 0, ID_NANOHUB_MAX, "nanohub");
2216 __unregister_chrdev(chub_dev_major, 0, 1, "chub_dev");
2217 class_destroy(sensor_class);
2218 major = 0;
2219 sensor_class = 0;
2220 }
2221
2222 module_init(nanohub_init);
2223 module_exit(nanohub_cleanup);
2224
2225 MODULE_AUTHOR("Ben Fennema");
2226 MODULE_LICENSE("GPL");