blob: ff77cb29caeb9fc739063bb34bcb941d78081a99 [file] [log] [blame]
Arun Kumar Neelakantamd680a242017-11-02 21:14:53 +05301/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13/*
14 * SMD Packet Driver -- Provides a binary SMD non-muxed packet port
15 * interface.
16 */
17
18#include <linux/slab.h>
19#include <linux/cdev.h>
20#include <linux/module.h>
21#include <linux/fs.h>
22#include <linux/device.h>
23#include <linux/sched.h>
24#include <linux/spinlock.h>
25#include <linux/mutex.h>
26#include <linux/delay.h>
27#include <linux/uaccess.h>
28#include <linux/workqueue.h>
29#include <linux/platform_device.h>
30#include <linux/completion.h>
31#include <linux/msm_smd_pkt.h>
32#include <linux/poll.h>
33#include <soc/qcom/smd.h>
34#include <soc/qcom/smsm.h>
35#include <soc/qcom/subsystem_restart.h>
36#include <asm/ioctls.h>
37#include <linux/pm.h>
38#include <linux/of.h>
39#include <linux/ipc_logging.h>
40
41#define MODULE_NAME "msm_smdpkt"
42#define DEVICE_NAME "smdpkt"
43#define WAKEUPSOURCE_TIMEOUT (2000) /* two seconds */
44
45struct smd_pkt_dev {
46 struct list_head dev_list;
47 char dev_name[SMD_MAX_CH_NAME_LEN];
48 char ch_name[SMD_MAX_CH_NAME_LEN];
49 uint32_t edge;
50
51 struct cdev cdev;
52 struct device *devicep;
53 void *pil;
54
55 struct smd_channel *ch;
56 struct mutex ch_lock;
57 struct mutex rx_lock;
58 struct mutex tx_lock;
59 wait_queue_head_t ch_read_wait_queue;
60 wait_queue_head_t ch_write_wait_queue;
61 wait_queue_head_t ch_opened_wait_queue;
62
63 int i;
64 int ref_cnt;
65
66 int blocking_write;
67 int is_open;
68 int poll_mode;
69 unsigned int ch_size;
70 uint open_modem_wait;
71
72 int has_reset;
73 int do_reset_notification;
74 struct completion ch_allocated;
75 struct wakeup_source pa_ws; /* Packet Arrival Wakeup Source */
76 struct work_struct packet_arrival_work;
77 spinlock_t pa_spinlock;
78 int ws_locked;
79};
80
81
82struct smd_pkt_driver {
83 struct list_head list;
84 int ref_cnt;
85 char pdriver_name[SMD_MAX_CH_NAME_LEN];
86 struct platform_driver driver;
87};
88
89static DEFINE_MUTEX(smd_pkt_driver_lock_lha1);
90static LIST_HEAD(smd_pkt_driver_list);
91
92struct class *smd_pkt_classp;
93static dev_t smd_pkt_number;
94static struct delayed_work loopback_work;
95static void check_and_wakeup_reader(struct smd_pkt_dev *smd_pkt_devp);
96static void check_and_wakeup_writer(struct smd_pkt_dev *smd_pkt_devp);
97static uint32_t is_modem_smsm_inited(void);
98
99static DEFINE_MUTEX(smd_pkt_dev_lock_lha1);
100static LIST_HEAD(smd_pkt_dev_list);
101static int num_smd_pkt_ports;
102
103#define SMD_PKT_IPC_LOG_PAGE_CNT 2
104static void *smd_pkt_ilctxt;
105
106static int msm_smd_pkt_debug_mask;
107module_param_named(debug_mask, msm_smd_pkt_debug_mask, int, 0664);
108
109enum {
110 SMD_PKT_STATUS = 1U << 0,
111 SMD_PKT_READ = 1U << 1,
112 SMD_PKT_WRITE = 1U << 2,
113 SMD_PKT_POLL = 1U << 5,
114};
115
116#define DEBUG
117
118#ifdef DEBUG
119
120#define SMD_PKT_LOG_STRING(x...) \
121do { \
122 if (smd_pkt_ilctxt) \
123 ipc_log_string(smd_pkt_ilctxt, "<SMD_PKT>: "x); \
124} while (0)
125
126#define D_STATUS(x...) \
127do { \
128 if (msm_smd_pkt_debug_mask & SMD_PKT_STATUS) \
129 pr_info("Status: "x); \
130 SMD_PKT_LOG_STRING(x); \
131} while (0)
132
133#define D_READ(x...) \
134do { \
135 if (msm_smd_pkt_debug_mask & SMD_PKT_READ) \
136 pr_info("Read: "x); \
137 SMD_PKT_LOG_STRING(x); \
138} while (0)
139
140#define D_WRITE(x...) \
141do { \
142 if (msm_smd_pkt_debug_mask & SMD_PKT_WRITE) \
143 pr_info("Write: "x); \
144 SMD_PKT_LOG_STRING(x); \
145} while (0)
146
147#define D_POLL(x...) \
148do { \
149 if (msm_smd_pkt_debug_mask & SMD_PKT_POLL) \
150 pr_info("Poll: "x); \
151 SMD_PKT_LOG_STRING(x); \
152} while (0)
153
154#define E_SMD_PKT_SSR(x) \
155do { \
156 if (x->do_reset_notification) \
157 pr_err("%s notifying reset for smd_pkt_dev id:%d\n", \
158 __func__, x->i); \
159} while (0)
160#else
161#define D_STATUS(x...) do {} while (0)
162#define D_READ(x...) do {} while (0)
163#define D_WRITE(x...) do {} while (0)
164#define D_POLL(x...) do {} while (0)
165#define E_SMD_PKT_SSR(x) do {} while (0)
166#endif
167
168static ssize_t open_timeout_store(struct device *d,
169 struct device_attribute *attr,
170 const char *buf,
171 size_t n)
172{
173 struct smd_pkt_dev *smd_pkt_devp;
174 unsigned long tmp;
175
176 mutex_lock(&smd_pkt_dev_lock_lha1);
177 list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) {
178 if (smd_pkt_devp->devicep == d) {
179 if (!kstrtoul(buf, 10, &tmp)) {
180 smd_pkt_devp->open_modem_wait = tmp;
181 mutex_unlock(&smd_pkt_dev_lock_lha1);
182 return n;
183 }
184 mutex_unlock(&smd_pkt_dev_lock_lha1);
185 pr_err("%s: unable to convert: %s to an int\n",
186 __func__, buf);
187 return -EINVAL;
188 }
189 }
190 mutex_unlock(&smd_pkt_dev_lock_lha1);
191
192 pr_err("%s: unable to match device to valid smd_pkt port\n", __func__);
193 return -EINVAL;
194}
195
196static ssize_t open_timeout_show(struct device *d,
197 struct device_attribute *attr,
198 char *buf)
199{
200 struct smd_pkt_dev *smd_pkt_devp;
201
202 mutex_lock(&smd_pkt_dev_lock_lha1);
203 list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) {
204 if (smd_pkt_devp->devicep == d) {
205 mutex_unlock(&smd_pkt_dev_lock_lha1);
206 return snprintf(buf, PAGE_SIZE, "%d\n",
207 smd_pkt_devp->open_modem_wait);
208 }
209 }
210 mutex_unlock(&smd_pkt_dev_lock_lha1);
211 pr_err("%s: unable to match device to valid smd_pkt port\n", __func__);
212 return -EINVAL;
213
214}
215
216static DEVICE_ATTR(open_timeout, 0664, open_timeout_show, open_timeout_store);
217
218/**
219 * loopback_edge_store() - Set the edge type for loopback device
220 * @d: Linux device structure
221 * @attr: Device attribute structure
222 * @buf: Input string
223 * @n: Length of the input string
224 *
225 * This function is used to set the loopback device edge runtime
226 * by writing to the loopback_edge node.
227 */
228static ssize_t loopback_edge_store(struct device *d,
229 struct device_attribute *attr,
230 const char *buf,
231 size_t n)
232{
233 struct smd_pkt_dev *smd_pkt_devp;
234 unsigned long tmp;
235
236 mutex_lock(&smd_pkt_dev_lock_lha1);
237 list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) {
238 if (smd_pkt_devp->devicep == d) {
239 if (!kstrtoul(buf, 10, &tmp)) {
240 smd_pkt_devp->edge = tmp;
241 mutex_unlock(&smd_pkt_dev_lock_lha1);
242 return n;
243 }
244 mutex_unlock(&smd_pkt_dev_lock_lha1);
245 pr_err("%s: unable to convert: %s to an int\n",
246 __func__, buf);
247 return -EINVAL;
248 }
249 }
250 mutex_unlock(&smd_pkt_dev_lock_lha1);
251 pr_err("%s: unable to match device to valid smd_pkt port\n", __func__);
252 return -EINVAL;
253}
254
255/**
256 * loopback_edge_show() - Get the edge type for loopback device
257 * @d: Linux device structure
258 * @attr: Device attribute structure
259 * @buf: Output buffer
260 *
261 * This function is used to get the loopback device edge runtime
262 * by reading the loopback_edge node.
263 */
264static ssize_t loopback_edge_show(struct device *d,
265 struct device_attribute *attr,
266 char *buf)
267{
268 struct smd_pkt_dev *smd_pkt_devp;
269
270 mutex_lock(&smd_pkt_dev_lock_lha1);
271 list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) {
272 if (smd_pkt_devp->devicep == d) {
273 mutex_unlock(&smd_pkt_dev_lock_lha1);
274 return snprintf(buf, PAGE_SIZE, "%d\n",
275 smd_pkt_devp->edge);
276 }
277 }
278 mutex_unlock(&smd_pkt_dev_lock_lha1);
279 pr_err("%s: unable to match device to valid smd_pkt port\n", __func__);
280 return -EINVAL;
281
282}
283
284static DEVICE_ATTR(loopback_edge, 0664, loopback_edge_show,
285 loopback_edge_store);
286
287static int notify_reset(struct smd_pkt_dev *smd_pkt_devp)
288{
289 smd_pkt_devp->do_reset_notification = 0;
290
291 return -ENETRESET;
292}
293
294static void clean_and_signal(struct smd_pkt_dev *smd_pkt_devp)
295{
296 smd_pkt_devp->do_reset_notification = 1;
297 smd_pkt_devp->has_reset = 1;
298
299 smd_pkt_devp->is_open = 0;
300
301 wake_up(&smd_pkt_devp->ch_read_wait_queue);
302 wake_up(&smd_pkt_devp->ch_write_wait_queue);
303 wake_up_interruptible(&smd_pkt_devp->ch_opened_wait_queue);
304 D_STATUS("%s smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i);
305}
306
307static void loopback_probe_worker(struct work_struct *work)
308{
309
310 /* Wait for the modem SMSM to be inited for the SMD
311 ** Loopback channel to be allocated at the modem. Since
312 ** the wait need to be done atmost once, using msleep
313 ** doesn't degrade the performance.
314 */
315 if (!is_modem_smsm_inited())
316 schedule_delayed_work(&loopback_work, msecs_to_jiffies(1000));
317 else
318 smsm_change_state(SMSM_APPS_STATE,
319 0, SMSM_SMD_LOOPBACK);
320
321}
322
323static void packet_arrival_worker(struct work_struct *work)
324{
325 struct smd_pkt_dev *smd_pkt_devp;
326 unsigned long flags;
327
328 smd_pkt_devp = container_of(work, struct smd_pkt_dev,
329 packet_arrival_work);
330 mutex_lock(&smd_pkt_devp->ch_lock);
331 spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags);
332 if (smd_pkt_devp->ch && smd_pkt_devp->ws_locked) {
333 D_READ("%s locking smd_pkt_dev id:%d wakeup source\n",
334 __func__, smd_pkt_devp->i);
335 /*
336 * Keep system awake long enough to allow userspace client
337 * to process the packet.
338 */
339 __pm_wakeup_event(&smd_pkt_devp->pa_ws, WAKEUPSOURCE_TIMEOUT);
340 }
341 spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
342 mutex_unlock(&smd_pkt_devp->ch_lock);
343}
344
345static long smd_pkt_ioctl(struct file *file, unsigned int cmd,
346 unsigned long arg)
347{
348 int ret;
349 struct smd_pkt_dev *smd_pkt_devp;
350 uint32_t val;
351
352 smd_pkt_devp = file->private_data;
353 if (!smd_pkt_devp)
354 return -EINVAL;
355
356 mutex_lock(&smd_pkt_devp->ch_lock);
357 switch (cmd) {
358 case TIOCMGET:
359 D_STATUS("%s TIOCMGET command on smd_pkt_dev id:%d\n",
360 __func__, smd_pkt_devp->i);
361 ret = smd_tiocmget(smd_pkt_devp->ch);
362 break;
363 case TIOCMSET:
364 ret = get_user(val, (uint32_t *)arg);
365 if (ret) {
366 pr_err("Error getting TIOCMSET value\n");
367 mutex_unlock(&smd_pkt_devp->ch_lock);
368 return ret;
369 }
370 D_STATUS("%s TIOCSET command on smd_pkt_dev id:%d arg[0x%x]\n",
371 __func__, smd_pkt_devp->i, val);
372 ret = smd_tiocmset(smd_pkt_devp->ch, val, ~val);
373 break;
374 case SMD_PKT_IOCTL_BLOCKING_WRITE:
375 ret = get_user(smd_pkt_devp->blocking_write, (int *)arg);
376 break;
377 default:
378 pr_err_ratelimited("%s: Unrecognized ioctl command %d\n",
379 __func__, cmd);
380 ret = -ENOIOCTLCMD;
381 }
382 mutex_unlock(&smd_pkt_devp->ch_lock);
383
384 return ret;
385}
386
387ssize_t smd_pkt_read(struct file *file,
388 char __user *_buf,
389 size_t count,
390 loff_t *ppos)
391{
392 int r;
393 int bytes_read;
394 int pkt_size;
395 struct smd_pkt_dev *smd_pkt_devp;
396 unsigned long flags;
397 void *buf;
398
399 smd_pkt_devp = file->private_data;
400
401 if (!smd_pkt_devp) {
402 pr_err_ratelimited("%s on NULL smd_pkt_dev\n", __func__);
403 return -EINVAL;
404 }
405
406 if (!smd_pkt_devp->ch) {
407 pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n",
408 __func__, smd_pkt_devp->i);
409 return -EINVAL;
410 }
411
412 if (smd_pkt_devp->do_reset_notification) {
413 /* notify client that a reset occurred */
414 E_SMD_PKT_SSR(smd_pkt_devp);
415 return notify_reset(smd_pkt_devp);
416 }
417 D_READ("Begin %s on smd_pkt_dev id:%d buffer_size %zu\n",
418 __func__, smd_pkt_devp->i, count);
419
420 buf = kmalloc(count, GFP_KERNEL);
421 if (!buf)
422 return -ENOMEM;
423
424wait_for_packet:
425 r = wait_event_interruptible(smd_pkt_devp->ch_read_wait_queue,
426 !smd_pkt_devp->ch ||
427 (smd_cur_packet_size(smd_pkt_devp->ch) > 0
428 && smd_read_avail(smd_pkt_devp->ch)) ||
429 smd_pkt_devp->has_reset);
430
431 mutex_lock(&smd_pkt_devp->rx_lock);
432 if (smd_pkt_devp->has_reset) {
433 mutex_unlock(&smd_pkt_devp->rx_lock);
434 E_SMD_PKT_SSR(smd_pkt_devp);
435 kfree(buf);
436 return notify_reset(smd_pkt_devp);
437 }
438
439 if (!smd_pkt_devp->ch) {
440 mutex_unlock(&smd_pkt_devp->rx_lock);
441 pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n",
442 __func__, smd_pkt_devp->i);
443 kfree(buf);
444 return -EINVAL;
445 }
446
447 if (r < 0) {
448 mutex_unlock(&smd_pkt_devp->rx_lock);
449 /* qualify error message */
450 if (r != -ERESTARTSYS) {
451 /* we get this anytime a signal comes in */
452 pr_err_ratelimited("%s: wait_event_interruptible on smd_pkt_dev id:%d ret %i\n",
453 __func__, smd_pkt_devp->i, r);
454 }
455 kfree(buf);
456 return r;
457 }
458
459 /* Here we have a whole packet waiting for us */
460 pkt_size = smd_cur_packet_size(smd_pkt_devp->ch);
461
462 if (!pkt_size) {
463 pr_err_ratelimited("%s: No data on smd_pkt_dev id:%d, False wakeup\n",
464 __func__, smd_pkt_devp->i);
465 mutex_unlock(&smd_pkt_devp->rx_lock);
466 goto wait_for_packet;
467 }
468
469 if (pkt_size < 0) {
470 pr_err_ratelimited("%s: Error %d obtaining packet size for Channel %s",
471 __func__, pkt_size, smd_pkt_devp->ch_name);
472 kfree(buf);
473 return pkt_size;
474 }
475
476 if ((uint32_t)pkt_size > count) {
477 pr_err_ratelimited("%s: failure on smd_pkt_dev id: %d - packet size %d > buffer size %zu,",
478 __func__, smd_pkt_devp->i,
479 pkt_size, count);
480 mutex_unlock(&smd_pkt_devp->rx_lock);
481 kfree(buf);
482 return -ETOOSMALL;
483 }
484
485 bytes_read = 0;
486 do {
487 r = smd_read(smd_pkt_devp->ch,
488 (buf + bytes_read),
489 (pkt_size - bytes_read));
490 if (r < 0) {
491 mutex_unlock(&smd_pkt_devp->rx_lock);
492 if (smd_pkt_devp->has_reset) {
493 E_SMD_PKT_SSR(smd_pkt_devp);
494 return notify_reset(smd_pkt_devp);
495 }
496 pr_err_ratelimited("%s Error while reading %d\n",
497 __func__, r);
498 kfree(buf);
499 return r;
500 }
501 bytes_read += r;
502 if (pkt_size != bytes_read)
503 wait_event(smd_pkt_devp->ch_read_wait_queue,
504 smd_read_avail(smd_pkt_devp->ch) ||
505 smd_pkt_devp->has_reset);
506 if (smd_pkt_devp->has_reset) {
507 mutex_unlock(&smd_pkt_devp->rx_lock);
508 E_SMD_PKT_SSR(smd_pkt_devp);
509 kfree(buf);
510 return notify_reset(smd_pkt_devp);
511 }
512 } while (pkt_size != bytes_read);
513 mutex_unlock(&smd_pkt_devp->rx_lock);
514
515 mutex_lock(&smd_pkt_devp->ch_lock);
516 spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags);
517 if (smd_pkt_devp->poll_mode &&
518 !smd_cur_packet_size(smd_pkt_devp->ch)) {
519 __pm_relax(&smd_pkt_devp->pa_ws);
520 smd_pkt_devp->ws_locked = 0;
521 smd_pkt_devp->poll_mode = 0;
522 D_READ("%s unlocked smd_pkt_dev id:%d wakeup_source\n",
523 __func__, smd_pkt_devp->i);
524 }
525 spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
526 mutex_unlock(&smd_pkt_devp->ch_lock);
527
528 r = copy_to_user(_buf, buf, bytes_read);
529 if (r) {
530 kfree(buf);
531 return -EFAULT;
532 }
533 D_READ("Finished %s on smd_pkt_dev id:%d %d bytes\n",
534 __func__, smd_pkt_devp->i, bytes_read);
535 kfree(buf);
536
537 /* check and wakeup read threads waiting on this device */
538 check_and_wakeup_reader(smd_pkt_devp);
539
540 return bytes_read;
541}
542
543ssize_t smd_pkt_write(struct file *file,
544 const char __user *_buf,
545 size_t count,
546 loff_t *ppos)
547{
548 int r = 0, bytes_written;
549 struct smd_pkt_dev *smd_pkt_devp;
550 DEFINE_WAIT(write_wait);
551 void *buf;
552
553 smd_pkt_devp = file->private_data;
554
555 if (!smd_pkt_devp) {
556 pr_err_ratelimited("%s on NULL smd_pkt_dev\n", __func__);
557 return -EINVAL;
558 }
559
560 if (!smd_pkt_devp->ch) {
561 pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n",
562 __func__, smd_pkt_devp->i);
563 return -EINVAL;
564 }
565
566 if (smd_pkt_devp->do_reset_notification || smd_pkt_devp->has_reset) {
567 E_SMD_PKT_SSR(smd_pkt_devp);
568 /* notify client that a reset occurred */
569 return notify_reset(smd_pkt_devp);
570 }
571 D_WRITE("Begin %s on smd_pkt_dev id:%d data_size %zu\n",
572 __func__, smd_pkt_devp->i, count);
573
574 buf = kmalloc(count, GFP_KERNEL);
575 if (!buf)
576 return -ENOMEM;
577
578 r = copy_from_user(buf, _buf, count);
579 if (r) {
580 kfree(buf);
581 return -EFAULT;
582 }
583
584 mutex_lock(&smd_pkt_devp->tx_lock);
585 if (!smd_pkt_devp->blocking_write) {
586 if (smd_write_avail(smd_pkt_devp->ch) < count) {
587 pr_err_ratelimited("%s: Not enough space in smd_pkt_dev id:%d\n",
588 __func__, smd_pkt_devp->i);
589 mutex_unlock(&smd_pkt_devp->tx_lock);
590 kfree(buf);
591 return -ENOMEM;
592 }
593 }
594
595 r = smd_write_start(smd_pkt_devp->ch, count);
596 if (r < 0) {
597 mutex_unlock(&smd_pkt_devp->tx_lock);
598 pr_err_ratelimited("%s: Error:%d in smd_pkt_dev id:%d @ smd_write_start\n",
599 __func__, r, smd_pkt_devp->i);
600 kfree(buf);
601 return r;
602 }
603
604 bytes_written = 0;
605 do {
606 prepare_to_wait(&smd_pkt_devp->ch_write_wait_queue,
607 &write_wait, TASK_UNINTERRUPTIBLE);
608 if (!smd_write_segment_avail(smd_pkt_devp->ch) &&
609 !smd_pkt_devp->has_reset) {
610 smd_enable_read_intr(smd_pkt_devp->ch);
611 schedule();
612 }
613 finish_wait(&smd_pkt_devp->ch_write_wait_queue, &write_wait);
614 smd_disable_read_intr(smd_pkt_devp->ch);
615
616 if (smd_pkt_devp->has_reset) {
617 mutex_unlock(&smd_pkt_devp->tx_lock);
618 E_SMD_PKT_SSR(smd_pkt_devp);
619 kfree(buf);
620 return notify_reset(smd_pkt_devp);
621 }
622 r = smd_write_segment(smd_pkt_devp->ch,
623 (void *)(buf + bytes_written),
624 (count - bytes_written));
625 if (r < 0) {
626 mutex_unlock(&smd_pkt_devp->tx_lock);
627 if (smd_pkt_devp->has_reset) {
628 E_SMD_PKT_SSR(smd_pkt_devp);
629 return notify_reset(smd_pkt_devp);
630 }
631 pr_err_ratelimited("%s on smd_pkt_dev id:%d failed r:%d\n",
632 __func__, smd_pkt_devp->i, r);
633 kfree(buf);
634 return r;
635 }
636 bytes_written += r;
637 } while (bytes_written != count);
638 smd_write_end(smd_pkt_devp->ch);
639 mutex_unlock(&smd_pkt_devp->tx_lock);
640 D_WRITE("Finished %s on smd_pkt_dev id:%d %zu bytes\n",
641 __func__, smd_pkt_devp->i, count);
642
643 kfree(buf);
644 return count;
645}
646
647static unsigned int smd_pkt_poll(struct file *file, poll_table *wait)
648{
649 struct smd_pkt_dev *smd_pkt_devp;
650 unsigned int mask = 0;
651
652 smd_pkt_devp = file->private_data;
653 if (!smd_pkt_devp) {
654 pr_err_ratelimited("%s on a NULL device\n", __func__);
655 return POLLERR;
656 }
657
658 smd_pkt_devp->poll_mode = 1;
659 poll_wait(file, &smd_pkt_devp->ch_read_wait_queue, wait);
660 mutex_lock(&smd_pkt_devp->ch_lock);
661 if (smd_pkt_devp->has_reset || !smd_pkt_devp->ch) {
662 mutex_unlock(&smd_pkt_devp->ch_lock);
663 return POLLERR;
664 }
665
666 if (smd_read_avail(smd_pkt_devp->ch)) {
667 mask |= POLLIN | POLLRDNORM;
668 D_POLL("%s sets POLLIN for smd_pkt_dev id: %d\n",
669 __func__, smd_pkt_devp->i);
670 }
671 mutex_unlock(&smd_pkt_devp->ch_lock);
672
673 return mask;
674}
675
676static void check_and_wakeup_reader(struct smd_pkt_dev *smd_pkt_devp)
677{
678 int sz;
679 unsigned long flags;
680
681 if (!smd_pkt_devp) {
682 pr_err("%s on a NULL device\n", __func__);
683 return;
684 }
685
686 if (!smd_pkt_devp->ch) {
687 pr_err("%s on a closed smd_pkt_dev id:%d\n",
688 __func__, smd_pkt_devp->i);
689 return;
690 }
691
692 sz = smd_cur_packet_size(smd_pkt_devp->ch);
693 if (sz == 0) {
694 D_READ("%s: No packet in smd_pkt_dev id:%d\n",
695 __func__, smd_pkt_devp->i);
696 return;
697 }
698 if (!smd_read_avail(smd_pkt_devp->ch)) {
699 D_READ(
700 "%s: packet size is %d in smd_pkt_dev id:%d - but the data isn't here\n",
701 __func__, sz, smd_pkt_devp->i);
702 return;
703 }
704
705 /* here we have a packet of size sz ready */
706 spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags);
707 __pm_stay_awake(&smd_pkt_devp->pa_ws);
708 smd_pkt_devp->ws_locked = 1;
709 spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
710 wake_up(&smd_pkt_devp->ch_read_wait_queue);
711 schedule_work(&smd_pkt_devp->packet_arrival_work);
712 D_READ("%s: wake_up smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i);
713}
714
715static void check_and_wakeup_writer(struct smd_pkt_dev *smd_pkt_devp)
716{
717 int sz;
718
719 if (!smd_pkt_devp) {
720 pr_err("%s on a NULL device\n", __func__);
721 return;
722 }
723
724 if (!smd_pkt_devp->ch) {
725 pr_err("%s on a closed smd_pkt_dev id:%d\n",
726 __func__, smd_pkt_devp->i);
727 return;
728 }
729
730 sz = smd_write_segment_avail(smd_pkt_devp->ch);
731 if (sz) {
732 D_WRITE("%s: %d bytes write space in smd_pkt_dev id:%d\n",
733 __func__, sz, smd_pkt_devp->i);
734 smd_disable_read_intr(smd_pkt_devp->ch);
735 wake_up(&smd_pkt_devp->ch_write_wait_queue);
736 }
737}
738
739static void ch_notify(void *priv, unsigned int event)
740{
741 struct smd_pkt_dev *smd_pkt_devp = priv;
742
743 if (smd_pkt_devp->ch == 0) {
744 if (event != SMD_EVENT_CLOSE)
745 pr_err("%s on a closed smd_pkt_dev id:%d\n",
746 __func__, smd_pkt_devp->i);
747 return;
748 }
749
750 switch (event) {
751 case SMD_EVENT_DATA: {
752 D_STATUS("%s: DATA event in smd_pkt_dev id:%d\n",
753 __func__, smd_pkt_devp->i);
754 check_and_wakeup_reader(smd_pkt_devp);
755 if (smd_pkt_devp->blocking_write)
756 check_and_wakeup_writer(smd_pkt_devp);
757 break;
758 }
759 case SMD_EVENT_OPEN:
760 D_STATUS("%s: OPEN event in smd_pkt_dev id:%d\n",
761 __func__, smd_pkt_devp->i);
762 smd_pkt_devp->has_reset = 0;
763 smd_pkt_devp->is_open = 1;
764 wake_up_interruptible(&smd_pkt_devp->ch_opened_wait_queue);
765 break;
766 case SMD_EVENT_CLOSE:
767 D_STATUS("%s: CLOSE event in smd_pkt_dev id:%d\n",
768 __func__, smd_pkt_devp->i);
769 smd_pkt_devp->is_open = 0;
770 /* put port into reset state */
771 clean_and_signal(smd_pkt_devp);
772 if (!strcmp(smd_pkt_devp->ch_name, "LOOPBACK"))
773 schedule_delayed_work(&loopback_work,
774 msecs_to_jiffies(1000));
775 break;
776 }
777}
778
779static int smd_pkt_dummy_probe(struct platform_device *pdev)
780{
781 struct smd_pkt_dev *smd_pkt_devp;
782
783 mutex_lock(&smd_pkt_dev_lock_lha1);
784 list_for_each_entry(smd_pkt_devp, &smd_pkt_dev_list, dev_list) {
785 if (smd_pkt_devp->edge == pdev->id
786 && !strcmp(pdev->name, smd_pkt_devp->ch_name)) {
787 complete_all(&smd_pkt_devp->ch_allocated);
788 D_STATUS("%s allocated SMD ch for smd_pkt_dev id:%d\n",
789 __func__, smd_pkt_devp->i);
790 break;
791 }
792 }
793 mutex_unlock(&smd_pkt_dev_lock_lha1);
794 return 0;
795}
796
797static uint32_t is_modem_smsm_inited(void)
798{
799 uint32_t modem_state;
800 uint32_t ready_state = (SMSM_INIT | SMSM_SMDINIT);
801
802 modem_state = smsm_get_state(SMSM_MODEM_STATE);
803 return (modem_state & ready_state) == ready_state;
804}
805
806/**
807 * smd_pkt_add_driver() - Add platform drivers for smd pkt device
808 *
809 * @smd_pkt_devp: pointer to the smd pkt device structure
810 *
811 * @returns: 0 for success, standard Linux error code otherwise
812 *
813 * This function is used to register platform driver once for all
814 * smd pkt devices which have same names and increment the reference
815 * count for 2nd to nth devices.
816 */
817static int smd_pkt_add_driver(struct smd_pkt_dev *smd_pkt_devp)
818{
819 int r = 0;
820 struct smd_pkt_driver *smd_pkt_driverp;
821 struct smd_pkt_driver *item;
822
823 if (!smd_pkt_devp) {
824 pr_err("%s on a NULL device\n", __func__);
825 return -EINVAL;
826 }
827 D_STATUS("Begin %s on smd_pkt_ch[%s]\n", __func__,
828 smd_pkt_devp->ch_name);
829
830 mutex_lock(&smd_pkt_driver_lock_lha1);
831 list_for_each_entry(item, &smd_pkt_driver_list, list) {
832 if (!strcmp(item->pdriver_name, smd_pkt_devp->ch_name)) {
833 D_STATUS("%s:%s Already Platform driver reg. cnt:%d\n",
834 __func__, smd_pkt_devp->ch_name, item->ref_cnt);
835 ++item->ref_cnt;
836 goto exit;
837 }
838 }
839
840 smd_pkt_driverp = kzalloc(sizeof(*smd_pkt_driverp), GFP_KERNEL);
841 if (IS_ERR_OR_NULL(smd_pkt_driverp)) {
842 pr_err("%s: kzalloc() failed for smd_pkt_driver[%s]\n",
843 __func__, smd_pkt_devp->ch_name);
844 r = -ENOMEM;
845 goto exit;
846 }
847
848 smd_pkt_driverp->driver.probe = smd_pkt_dummy_probe;
849 scnprintf(smd_pkt_driverp->pdriver_name, SMD_MAX_CH_NAME_LEN,
850 "%s", smd_pkt_devp->ch_name);
851 smd_pkt_driverp->driver.driver.name = smd_pkt_driverp->pdriver_name;
852 smd_pkt_driverp->driver.driver.owner = THIS_MODULE;
853 r = platform_driver_register(&smd_pkt_driverp->driver);
854 if (r) {
855 pr_err("%s: %s Platform driver reg. failed\n",
856 __func__, smd_pkt_devp->ch_name);
857 kfree(smd_pkt_driverp);
858 goto exit;
859 }
860 ++smd_pkt_driverp->ref_cnt;
861 list_add(&smd_pkt_driverp->list, &smd_pkt_driver_list);
862
863exit:
864 D_STATUS("End %s on smd_pkt_ch[%s]\n", __func__, smd_pkt_devp->ch_name);
865 mutex_unlock(&smd_pkt_driver_lock_lha1);
866 return r;
867}
868
869/**
870 * smd_pkt_remove_driver() - Remove the platform drivers for smd pkt device
871 *
872 * @smd_pkt_devp: pointer to the smd pkt device structure
873 *
874 * This function is used to decrement the reference count on
875 * platform drivers for smd pkt devices and removes the drivers
876 * when the reference count becomes zero.
877 */
878static void smd_pkt_remove_driver(struct smd_pkt_dev *smd_pkt_devp)
879{
880 struct smd_pkt_driver *smd_pkt_driverp;
881 bool found_item = false;
882
883 if (!smd_pkt_devp) {
884 pr_err("%s on a NULL device\n", __func__);
885 return;
886 }
887
888 D_STATUS("Begin %s on smd_pkt_ch[%s]\n", __func__,
889 smd_pkt_devp->ch_name);
890 mutex_lock(&smd_pkt_driver_lock_lha1);
891 list_for_each_entry(smd_pkt_driverp, &smd_pkt_driver_list, list) {
892 if (!strcmp(smd_pkt_driverp->pdriver_name,
893 smd_pkt_devp->ch_name)) {
894 found_item = true;
895 D_STATUS("%s:%s Platform driver cnt:%d\n",
896 __func__, smd_pkt_devp->ch_name,
897 smd_pkt_driverp->ref_cnt);
898 if (smd_pkt_driverp->ref_cnt > 0)
899 --smd_pkt_driverp->ref_cnt;
900 else
901 pr_warn("%s reference count <= 0\n", __func__);
902 break;
903 }
904 }
905 if (!found_item)
906 pr_err("%s:%s No item found in list.\n",
907 __func__, smd_pkt_devp->ch_name);
908
909 if (found_item && smd_pkt_driverp->ref_cnt == 0) {
910 platform_driver_unregister(&smd_pkt_driverp->driver);
911 smd_pkt_driverp->driver.probe = NULL;
912 list_del(&smd_pkt_driverp->list);
913 kfree(smd_pkt_driverp);
914 }
915 mutex_unlock(&smd_pkt_driver_lock_lha1);
916 D_STATUS("End %s on smd_pkt_ch[%s]\n", __func__, smd_pkt_devp->ch_name);
917}
918
919int smd_pkt_open(struct inode *inode, struct file *file)
920{
921 int r = 0;
922 struct smd_pkt_dev *smd_pkt_devp;
923 const char *peripheral = NULL;
924
925 smd_pkt_devp = container_of(inode->i_cdev, struct smd_pkt_dev, cdev);
926
927 if (!smd_pkt_devp) {
928 pr_err_ratelimited("%s on a NULL device\n", __func__);
929 return -EINVAL;
930 }
931 D_STATUS("Begin %s on smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i);
932
933 file->private_data = smd_pkt_devp;
934
935 mutex_lock(&smd_pkt_devp->ch_lock);
936 if (smd_pkt_devp->ch == 0) {
937 unsigned int open_wait_rem;
938
939 open_wait_rem = smd_pkt_devp->open_modem_wait * 1000;
940 reinit_completion(&smd_pkt_devp->ch_allocated);
941
942 r = smd_pkt_add_driver(smd_pkt_devp);
943 if (r) {
944 pr_err_ratelimited("%s: %s Platform driver reg. failed\n",
945 __func__, smd_pkt_devp->ch_name);
946 goto out;
947 }
948
949 peripheral = smd_edge_to_pil_str(smd_pkt_devp->edge);
950 if (!IS_ERR_OR_NULL(peripheral)) {
951 smd_pkt_devp->pil = subsystem_get(peripheral);
952 if (IS_ERR(smd_pkt_devp->pil)) {
953 r = PTR_ERR(smd_pkt_devp->pil);
954 pr_err_ratelimited("%s failed on smd_pkt_dev id:%d - subsystem_get failed for %s\n",
955 __func__, smd_pkt_devp->i, peripheral);
956 /*
957 * Sleep inorder to reduce the frequency of
958 * retry by user-space modules and to avoid
959 * possible watchdog bite.
960 */
961 msleep(open_wait_rem);
962 goto release_pd;
963 }
964 }
965
966 /* Wait for the modem SMSM to be inited for the SMD
967 ** Loopback channel to be allocated at the modem. Since
968 ** the wait need to be done atmost once, using msleep
969 ** doesn't degrade the performance.
970 */
971 if (!strcmp(smd_pkt_devp->ch_name, "LOOPBACK")) {
972 if (!is_modem_smsm_inited())
973 msleep(5000);
974 smsm_change_state(SMSM_APPS_STATE,
975 0, SMSM_SMD_LOOPBACK);
976 msleep(100);
977 }
978
979 /*
980 * Wait for a packet channel to be allocated so we know
981 * the modem is ready enough.
982 */
983 if (open_wait_rem) {
984 r = wait_for_completion_interruptible_timeout(
985 &smd_pkt_devp->ch_allocated,
986 msecs_to_jiffies(open_wait_rem));
987 if (r >= 0)
988 open_wait_rem = jiffies_to_msecs(r);
989 if (r == 0)
990 r = -ETIMEDOUT;
991 if (r == -ERESTARTSYS) {
992 pr_info_ratelimited("%s: wait on smd_pkt_dev id:%d allocation interrupted\n",
993 __func__, smd_pkt_devp->i);
994 goto release_pil;
995 }
996 if (r < 0) {
997 pr_err_ratelimited("%s: wait on smd_pkt_dev id:%d allocation failed rc:%d\n",
998 __func__, smd_pkt_devp->i, r);
999 goto release_pil;
1000 }
1001 }
1002
1003 r = smd_named_open_on_edge(smd_pkt_devp->ch_name,
1004 smd_pkt_devp->edge,
1005 &smd_pkt_devp->ch,
1006 smd_pkt_devp,
1007 ch_notify);
1008 if (r < 0) {
1009 pr_err_ratelimited("%s: %s open failed %d\n", __func__,
1010 smd_pkt_devp->ch_name, r);
1011 goto release_pil;
1012 }
1013
1014 open_wait_rem = max_t(unsigned int, 2000, open_wait_rem);
1015 r = wait_event_interruptible_timeout(
1016 smd_pkt_devp->ch_opened_wait_queue,
1017 smd_pkt_devp->is_open,
1018 msecs_to_jiffies(open_wait_rem));
1019 if (r == 0)
1020 r = -ETIMEDOUT;
1021
1022 if (r < 0) {
1023 /* close the ch to sync smd's state with smd_pkt */
1024 smd_close(smd_pkt_devp->ch);
1025 smd_pkt_devp->ch = NULL;
1026 }
1027
1028 if (r == -ERESTARTSYS) {
1029 pr_info_ratelimited("%s: wait on smd_pkt_dev id:%d OPEN interrupted\n",
1030 __func__, smd_pkt_devp->i);
1031 } else if (r < 0) {
1032 pr_err_ratelimited("%s: wait on smd_pkt_dev id:%d OPEN event failed rc:%d\n",
1033 __func__, smd_pkt_devp->i, r);
1034 } else if (!smd_pkt_devp->is_open) {
1035 pr_err_ratelimited("%s: Invalid OPEN event on smd_pkt_dev id:%d\n",
1036 __func__, smd_pkt_devp->i);
1037 r = -ENODEV;
1038 } else {
1039 smd_disable_read_intr(smd_pkt_devp->ch);
1040 smd_pkt_devp->ch_size =
1041 smd_write_avail(smd_pkt_devp->ch);
1042 r = 0;
1043 smd_pkt_devp->ref_cnt++;
1044 D_STATUS("Finished %s on smd_pkt_dev id:%d\n",
1045 __func__, smd_pkt_devp->i);
1046 }
1047 } else {
1048 smd_pkt_devp->ref_cnt++;
1049 }
1050release_pil:
1051 if (peripheral && (r < 0)) {
1052 subsystem_put(smd_pkt_devp->pil);
1053 smd_pkt_devp->pil = NULL;
1054 }
1055
1056release_pd:
1057 if (r < 0)
1058 smd_pkt_remove_driver(smd_pkt_devp);
1059out:
1060 mutex_unlock(&smd_pkt_devp->ch_lock);
1061
1062
1063 return r;
1064}
1065
1066int smd_pkt_release(struct inode *inode, struct file *file)
1067{
1068 int r = 0;
1069 struct smd_pkt_dev *smd_pkt_devp = file->private_data;
1070 unsigned long flags;
1071
1072 if (!smd_pkt_devp) {
1073 pr_err_ratelimited("%s on a NULL device\n", __func__);
1074 return -EINVAL;
1075 }
1076 D_STATUS("Begin %s on smd_pkt_dev id:%d\n",
1077 __func__, smd_pkt_devp->i);
1078
1079 mutex_lock(&smd_pkt_devp->ch_lock);
1080 mutex_lock(&smd_pkt_devp->rx_lock);
1081 mutex_lock(&smd_pkt_devp->tx_lock);
1082 if (smd_pkt_devp->ref_cnt > 0)
1083 smd_pkt_devp->ref_cnt--;
1084
1085 if (smd_pkt_devp->ch != 0 && smd_pkt_devp->ref_cnt == 0) {
1086 clean_and_signal(smd_pkt_devp);
1087 r = smd_close(smd_pkt_devp->ch);
1088 smd_pkt_devp->ch = 0;
1089 smd_pkt_devp->blocking_write = 0;
1090 smd_pkt_devp->poll_mode = 0;
1091 smd_pkt_remove_driver(smd_pkt_devp);
1092 if (smd_pkt_devp->pil)
1093 subsystem_put(smd_pkt_devp->pil);
1094 smd_pkt_devp->has_reset = 0;
1095 smd_pkt_devp->do_reset_notification = 0;
1096 spin_lock_irqsave(&smd_pkt_devp->pa_spinlock, flags);
1097 if (smd_pkt_devp->ws_locked) {
1098 __pm_relax(&smd_pkt_devp->pa_ws);
1099 smd_pkt_devp->ws_locked = 0;
1100 }
1101 spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags);
1102 }
1103 mutex_unlock(&smd_pkt_devp->tx_lock);
1104 mutex_unlock(&smd_pkt_devp->rx_lock);
1105 mutex_unlock(&smd_pkt_devp->ch_lock);
1106
1107 if (flush_work(&smd_pkt_devp->packet_arrival_work))
1108 D_STATUS("%s: Flushed work for smd_pkt_dev id:%d\n", __func__,
1109 smd_pkt_devp->i);
1110
1111 D_STATUS("Finished %s on smd_pkt_dev id:%d\n",
1112 __func__, smd_pkt_devp->i);
1113
1114 return r;
1115}
1116
1117static const struct file_operations smd_pkt_fops = {
1118 .owner = THIS_MODULE,
1119 .open = smd_pkt_open,
1120 .release = smd_pkt_release,
1121 .read = smd_pkt_read,
1122 .write = smd_pkt_write,
1123 .poll = smd_pkt_poll,
1124 .unlocked_ioctl = smd_pkt_ioctl,
1125 .compat_ioctl = smd_pkt_ioctl,
1126};
1127
1128static int smd_pkt_init_add_device(struct smd_pkt_dev *smd_pkt_devp, int i)
1129{
1130 int r = 0;
1131
1132 smd_pkt_devp->i = i;
1133
1134 init_waitqueue_head(&smd_pkt_devp->ch_read_wait_queue);
1135 init_waitqueue_head(&smd_pkt_devp->ch_write_wait_queue);
1136 smd_pkt_devp->is_open = 0;
1137 smd_pkt_devp->poll_mode = 0;
1138 smd_pkt_devp->ws_locked = 0;
1139 init_waitqueue_head(&smd_pkt_devp->ch_opened_wait_queue);
1140
1141 spin_lock_init(&smd_pkt_devp->pa_spinlock);
1142 mutex_init(&smd_pkt_devp->ch_lock);
1143 mutex_init(&smd_pkt_devp->rx_lock);
1144 mutex_init(&smd_pkt_devp->tx_lock);
1145 wakeup_source_init(&smd_pkt_devp->pa_ws, smd_pkt_devp->dev_name);
1146 INIT_WORK(&smd_pkt_devp->packet_arrival_work, packet_arrival_worker);
1147 init_completion(&smd_pkt_devp->ch_allocated);
1148
1149 cdev_init(&smd_pkt_devp->cdev, &smd_pkt_fops);
1150 smd_pkt_devp->cdev.owner = THIS_MODULE;
1151
1152 r = cdev_add(&smd_pkt_devp->cdev, (smd_pkt_number + i), 1);
1153 if (r) {
1154 pr_err("%s: cdev_add() failed for smd_pkt_dev id:%d ret:%i\n",
1155 __func__, i, r);
1156 return r;
1157 }
1158
1159 smd_pkt_devp->devicep =
1160 device_create(smd_pkt_classp,
1161 NULL,
1162 (smd_pkt_number + i),
1163 NULL,
1164 smd_pkt_devp->dev_name);
1165
1166 if (IS_ERR_OR_NULL(smd_pkt_devp->devicep)) {
1167 pr_err("%s: device_create() failed for smd_pkt_dev id:%d\n",
1168 __func__, i);
1169 r = -ENOMEM;
1170 cdev_del(&smd_pkt_devp->cdev);
1171 wakeup_source_trash(&smd_pkt_devp->pa_ws);
1172 return r;
1173 }
1174 if (device_create_file(smd_pkt_devp->devicep,
1175 &dev_attr_open_timeout))
1176 pr_err("%s: unable to create device attr for smd_pkt_dev id:%d\n",
1177 __func__, i);
1178
1179 if (!strcmp(smd_pkt_devp->ch_name, "LOOPBACK")) {
1180 if (device_create_file(smd_pkt_devp->devicep,
1181 &dev_attr_loopback_edge))
1182 pr_err("%s: unable to create device attr for smd_pkt_dev id:%d\n",
1183 __func__, i);
1184 }
1185 mutex_lock(&smd_pkt_dev_lock_lha1);
1186 list_add(&smd_pkt_devp->dev_list, &smd_pkt_dev_list);
1187 mutex_unlock(&smd_pkt_dev_lock_lha1);
1188
1189 return r;
1190}
1191
1192static void smd_pkt_core_deinit(void)
1193{
1194 struct smd_pkt_dev *smd_pkt_devp;
1195 struct smd_pkt_dev *index;
1196
1197 mutex_lock(&smd_pkt_dev_lock_lha1);
1198 list_for_each_entry_safe(smd_pkt_devp, index, &smd_pkt_dev_list,
1199 dev_list) {
1200 cdev_del(&smd_pkt_devp->cdev);
1201 list_del(&smd_pkt_devp->dev_list);
1202 device_destroy(smd_pkt_classp,
1203 MKDEV(MAJOR(smd_pkt_number), smd_pkt_devp->i));
1204 kfree(smd_pkt_devp);
1205 }
1206 mutex_unlock(&smd_pkt_dev_lock_lha1);
1207
1208 if (!IS_ERR_OR_NULL(smd_pkt_classp))
1209 class_destroy(smd_pkt_classp);
1210
1211 unregister_chrdev_region(MAJOR(smd_pkt_number), num_smd_pkt_ports);
1212}
1213
1214static int smd_pkt_alloc_chrdev_region(void)
1215{
1216 int r = alloc_chrdev_region(&smd_pkt_number,
1217 0,
1218 num_smd_pkt_ports,
1219 DEVICE_NAME);
1220
1221 if (r) {
1222 pr_err("%s: alloc_chrdev_region() failed ret:%i\n",
1223 __func__, r);
1224 return r;
1225 }
1226
1227 smd_pkt_classp = class_create(THIS_MODULE, DEVICE_NAME);
1228 if (IS_ERR(smd_pkt_classp)) {
1229 pr_err("%s: class_create() failed ENOMEM\n", __func__);
1230 r = -ENOMEM;
1231 unregister_chrdev_region(MAJOR(smd_pkt_number),
1232 num_smd_pkt_ports);
1233 return r;
1234 }
1235
1236 return 0;
1237}
1238
1239static int parse_smdpkt_devicetree(struct device_node *node,
1240 struct smd_pkt_dev *smd_pkt_devp)
1241{
1242 int edge;
1243 char *key;
1244 const char *ch_name;
1245 const char *dev_name;
1246 const char *remote_ss;
1247
1248 key = "qcom,smdpkt-remote";
1249 remote_ss = of_get_property(node, key, NULL);
1250 if (!remote_ss)
1251 goto error;
1252
1253 edge = smd_remote_ss_to_edge(remote_ss);
1254 if (edge < 0)
1255 goto error;
1256
1257 smd_pkt_devp->edge = edge;
1258 D_STATUS("%s: %s = %d", __func__, key, edge);
1259
1260 key = "qcom,smdpkt-port-name";
1261 ch_name = of_get_property(node, key, NULL);
1262 if (!ch_name)
1263 goto error;
1264
1265 strlcpy(smd_pkt_devp->ch_name, ch_name, SMD_MAX_CH_NAME_LEN);
1266 D_STATUS("%s ch_name = %s\n", __func__, ch_name);
1267
1268 key = "qcom,smdpkt-dev-name";
1269 dev_name = of_get_property(node, key, NULL);
1270 if (!dev_name)
1271 goto error;
1272
1273 strlcpy(smd_pkt_devp->dev_name, dev_name, SMD_MAX_CH_NAME_LEN);
1274 D_STATUS("%s dev_name = %s\n", __func__, dev_name);
1275
1276 return 0;
1277
1278error:
1279 pr_err("%s: missing key: %s\n", __func__, key);
1280 return -ENODEV;
1281
1282}
1283
1284static int smd_pkt_devicetree_init(struct platform_device *pdev)
1285{
1286 int ret;
1287 int i = 0;
1288 struct device_node *node;
1289 struct smd_pkt_dev *smd_pkt_devp;
1290 int subnode_num = 0;
1291
1292 for_each_child_of_node(pdev->dev.of_node, node)
1293 ++subnode_num;
1294
1295 num_smd_pkt_ports = subnode_num;
1296
1297 ret = smd_pkt_alloc_chrdev_region();
1298 if (ret) {
1299 pr_err("%s: smd_pkt_alloc_chrdev_region() failed ret:%i\n",
1300 __func__, ret);
1301 return ret;
1302 }
1303
1304 for_each_child_of_node(pdev->dev.of_node, node) {
1305 smd_pkt_devp = kzalloc(sizeof(struct smd_pkt_dev), GFP_KERNEL);
1306 if (IS_ERR_OR_NULL(smd_pkt_devp)) {
1307 pr_err("%s: kzalloc() failed for smd_pkt_dev id:%d\n",
1308 __func__, i);
1309 ret = -ENOMEM;
1310 goto error_destroy;
1311 }
1312
1313 ret = parse_smdpkt_devicetree(node, smd_pkt_devp);
1314 if (ret) {
1315 pr_err(" failed to parse_smdpkt_devicetree %d\n", i);
1316 kfree(smd_pkt_devp);
1317 goto error_destroy;
1318 }
1319
1320 ret = smd_pkt_init_add_device(smd_pkt_devp, i);
1321 if (ret < 0) {
1322 pr_err("add device failed for idx:%d ret=%d\n", i, ret);
1323 kfree(smd_pkt_devp);
1324 goto error_destroy;
1325 }
1326 i++;
1327 }
1328
1329 INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
1330
1331 D_STATUS("SMD Packet Port Driver Initialized.\n");
1332 return 0;
1333
1334error_destroy:
1335 smd_pkt_core_deinit();
1336 return ret;
1337}
1338
1339static int msm_smd_pkt_probe(struct platform_device *pdev)
1340{
1341 int ret;
1342
1343 if (pdev) {
1344 if (pdev->dev.of_node) {
1345 D_STATUS("%s device tree implementation\n", __func__);
1346 ret = smd_pkt_devicetree_init(pdev);
1347 if (ret)
1348 pr_err("%s: device tree init failed\n",
1349 __func__);
1350 }
1351 }
1352
1353 return 0;
1354}
1355
1356static const struct of_device_id msm_smd_pkt_match_table[] = {
1357 { .compatible = "qcom,smdpkt" },
1358 {},
1359};
1360
1361static struct platform_driver msm_smd_pkt_driver = {
1362 .probe = msm_smd_pkt_probe,
1363 .driver = {
1364 .name = MODULE_NAME,
1365 .owner = THIS_MODULE,
1366 .of_match_table = msm_smd_pkt_match_table,
1367 },
1368};
1369
1370static int __init smd_pkt_init(void)
1371{
1372 int rc;
1373
1374 INIT_LIST_HEAD(&smd_pkt_dev_list);
1375 INIT_LIST_HEAD(&smd_pkt_driver_list);
1376 rc = platform_driver_register(&msm_smd_pkt_driver);
1377 if (rc) {
1378 pr_err("%s: msm_smd_driver register failed %d\n",
1379 __func__, rc);
1380 return rc;
1381 }
1382
1383 smd_pkt_ilctxt = ipc_log_context_create(SMD_PKT_IPC_LOG_PAGE_CNT,
1384 "smd_pkt", 0);
1385 return 0;
1386}
1387
1388static void __exit smd_pkt_cleanup(void)
1389{
1390 smd_pkt_core_deinit();
1391}
1392
1393module_init(smd_pkt_init);
1394module_exit(smd_pkt_cleanup);
1395
1396MODULE_DESCRIPTION("MSM Shared Memory Packet Port");
1397MODULE_LICENSE("GPL v2");