OSDN Git Service

Merge branch 'android-4.4@6fc0573' into branch 'msm-4.4'
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / tty / serial / msm_smd_tty.c
1 /* Copyright (C) 2007 Google, Inc.
2  * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
3  * Author: Brian Swetland <swetland@google.com>
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #include <linux/module.h>
16 #include <linux/fs.h>
17 #include <linux/cdev.h>
18 #include <linux/device.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/pm.h>
22 #include <linux/platform_device.h>
23 #include <linux/sched.h>
24 #include <linux/slab.h>
25 #include <linux/ipc_logging.h>
26 #include <linux/of.h>
27 #include <linux/suspend.h>
28
29 #include <linux/tty.h>
30 #include <linux/tty_driver.h>
31 #include <linux/tty_flip.h>
32
33 #include <soc/qcom/smd.h>
34 #include <soc/qcom/smsm.h>
35 #include <soc/qcom/subsystem_restart.h>
36
37 #define MODULE_NAME "msm_smdtty"
38 #define MAX_SMD_TTYS 37
39 #define MAX_TTY_BUF_SIZE 2048
40 #define TTY_PUSH_WS_DELAY 500
41 #define TTY_PUSH_WS_POST_SUSPEND_DELAY 100
42 #define MAX_RA_WAKE_LOCK_NAME_LEN 32
43 #define SMD_TTY_LOG_PAGES 2
44
45 #define SMD_TTY_INFO(buf...) \
46 do { \
47         if (smd_tty_log_ctx) { \
48                 ipc_log_string(smd_tty_log_ctx, buf); \
49         } \
50 } while (0)
51
52 #define SMD_TTY_ERR(buf...) \
53 do { \
54         if (smd_tty_log_ctx) \
55                 ipc_log_string(smd_tty_log_ctx, buf); \
56         pr_err(buf); \
57 } while (0)
58
59 static void *smd_tty_log_ctx;
60 static bool smd_tty_in_suspend;
61 static bool smd_tty_read_in_suspend;
62 static struct wakeup_source read_in_suspend_ws;
63
64 /**
65  * struct smd_tty_info - context for an individual SMD TTY device
66  *
67  * @ch:  SMD channel handle
68  * @port:  TTY port context structure
69  * @device_ptr:  TTY device pointer
70  * @pending_ws:  pending-data wakeup source
71  * @tty_tsklt:  read tasklet
72  * @buf_req_timer:  RX buffer retry timer
73  * @ch_allocated:  completion set when SMD channel is allocated
74  * @pil:  Peripheral Image Loader handle
75  * @edge:  SMD edge associated with port
76  * @ch_name:  SMD channel name associated with port
77  * @dev_name:  SMD platform device name associated with port
78  *
79  * @open_lock_lha1: open/close lock - used to serialize open/close operations
80  * @open_wait:  Timeout in seconds to wait for SMD port to be created / opened
81  *
82  * @reset_lock_lha2: lock for reset and open state
83  * @in_reset:  True if SMD channel is closed / in SSR
84  * @in_reset_updated:  reset state changed
85  * @is_open:  True if SMD port is open
86  * @ch_opened_wait_queue:  SMD port open/close wait queue
87  *
88  * @ra_lock_lha3:  Read-available lock - used to synchronize reads from SMD
89  * @ra_wakeup_source_name: Name of the read-available wakeup source
90  * @ra_wakeup_source:  Read-available wakeup source
91  */
92 struct smd_tty_info {
93         smd_channel_t *ch;
94         struct tty_port port;
95         struct device *device_ptr;
96         struct wakeup_source pending_ws;
97         struct tasklet_struct tty_tsklt;
98         struct timer_list buf_req_timer;
99         struct completion ch_allocated;
100         void *pil;
101         uint32_t edge;
102         char ch_name[SMD_MAX_CH_NAME_LEN];
103         char dev_name[SMD_MAX_CH_NAME_LEN];
104
105         struct mutex open_lock_lha1;
106         unsigned int open_wait;
107
108         spinlock_t reset_lock_lha2;
109         int in_reset;
110         int in_reset_updated;
111         int is_open;
112         wait_queue_head_t ch_opened_wait_queue;
113
114         spinlock_t ra_lock_lha3;
115         char ra_wakeup_source_name[MAX_RA_WAKE_LOCK_NAME_LEN];
116         struct wakeup_source ra_wakeup_source;
117 };
118
119 /**
120  * struct smd_tty_pfdriver - SMD tty channel platform driver structure
121  *
122  * @list:  Adds this structure into smd_tty_platform_driver_list::list.
123  * @ref_cnt:  reference count for this structure.
124  * @driver:  SMD channel platform driver context structure
125  */
126 struct smd_tty_pfdriver {
127         struct list_head list;
128         int ref_cnt;
129         struct platform_driver driver;
130 };
131
132 #define LOOPBACK_IDX 36
133
134 static struct delayed_work loopback_work;
135 static struct smd_tty_info smd_tty[MAX_SMD_TTYS];
136
137 static DEFINE_MUTEX(smd_tty_pfdriver_lock_lha1);
138 static LIST_HEAD(smd_tty_pfdriver_list);
139
140 static int is_in_reset(struct smd_tty_info *info)
141 {
142         return info->in_reset;
143 }
144
145 static void buf_req_retry(unsigned long param)
146 {
147         struct smd_tty_info *info = (struct smd_tty_info *)param;
148         unsigned long flags;
149
150         spin_lock_irqsave(&info->reset_lock_lha2, flags);
151         if (info->is_open) {
152                 spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
153                 tasklet_hi_schedule(&info->tty_tsklt);
154                 return;
155         }
156         spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
157 }
158
159 static ssize_t open_timeout_store(struct device *dev,
160                                 struct device_attribute *attr,
161                                 const char *buf, size_t n)
162 {
163         unsigned int num_dev;
164         unsigned long wait;
165         if (dev == NULL) {
166                 SMD_TTY_INFO("%s: Invalid Device passed", __func__);
167                 return -EINVAL;
168         }
169         for (num_dev = 0; num_dev < MAX_SMD_TTYS; num_dev++) {
170                 if (dev == smd_tty[num_dev].device_ptr)
171                         break;
172         }
173         if (num_dev >= MAX_SMD_TTYS) {
174                 SMD_TTY_ERR("[%s]: Device Not found", __func__);
175                 return -EINVAL;
176         }
177         if (!kstrtoul(buf, 10, &wait)) {
178                 mutex_lock(&smd_tty[num_dev].open_lock_lha1);
179                 smd_tty[num_dev].open_wait = wait;
180                 mutex_unlock(&smd_tty[num_dev].open_lock_lha1);
181                 return n;
182         } else {
183                 SMD_TTY_INFO("[%s]: Unable to convert %s to an int",
184                         __func__, buf);
185                 return -EINVAL;
186         }
187 }
188
189 static ssize_t open_timeout_show(struct device *dev,
190                         struct device_attribute *attr, char *buf)
191 {
192         unsigned int num_dev;
193         unsigned int open_wait;
194
195         if (dev == NULL) {
196                 SMD_TTY_INFO("%s: Invalid Device passed", __func__);
197                 return -EINVAL;
198         }
199         for (num_dev = 0; num_dev < MAX_SMD_TTYS; num_dev++) {
200                 if (dev == smd_tty[num_dev].device_ptr)
201                         break;
202         }
203         if (num_dev >= MAX_SMD_TTYS) {
204                 SMD_TTY_ERR("[%s]: Device Not Found", __func__);
205                 return -EINVAL;
206         }
207
208         mutex_lock(&smd_tty[num_dev].open_lock_lha1);
209         open_wait = smd_tty[num_dev].open_wait;
210         mutex_unlock(&smd_tty[num_dev].open_lock_lha1);
211
212         return snprintf(buf, PAGE_SIZE, "%d\n", open_wait);
213 }
214
215 static DEVICE_ATTR
216         (open_timeout, 0664, open_timeout_show, open_timeout_store);
217
218 static void smd_tty_read(unsigned long param)
219 {
220         unsigned char *ptr;
221         int avail;
222         struct smd_tty_info *info = (struct smd_tty_info *)param;
223         struct tty_struct *tty = tty_port_tty_get(&info->port);
224         unsigned long flags;
225
226         if (!tty)
227                 return;
228
229         for (;;) {
230                 if (is_in_reset(info)) {
231                         /* signal TTY clients using TTY_BREAK */
232                         tty_insert_flip_char(tty->port, 0x00, TTY_BREAK);
233                         tty_flip_buffer_push(tty->port);
234                         break;
235                 }
236
237                 if (test_bit(TTY_THROTTLED, &tty->flags))
238                         break;
239                 spin_lock_irqsave(&info->ra_lock_lha3, flags);
240                 avail = smd_read_avail(info->ch);
241                 if (avail == 0) {
242                         __pm_relax(&info->ra_wakeup_source);
243                         spin_unlock_irqrestore(&info->ra_lock_lha3, flags);
244                         break;
245                 }
246                 spin_unlock_irqrestore(&info->ra_lock_lha3, flags);
247
248                 if (avail > MAX_TTY_BUF_SIZE)
249                         avail = MAX_TTY_BUF_SIZE;
250
251                 avail = tty_prepare_flip_string(tty->port, &ptr, avail);
252                 if (avail <= 0) {
253                         mod_timer(&info->buf_req_timer,
254                                         jiffies + msecs_to_jiffies(30));
255                         tty_kref_put(tty);
256                         return;
257                 }
258
259                 if (smd_read(info->ch, ptr, avail) != avail) {
260                         /* shouldn't be possible since we're in interrupt
261                         ** context here and nobody else could 'steal' our
262                         ** characters.
263                         */
264                         SMD_TTY_ERR(
265                                 "%s - Possible smd_tty_buffer mismatch for %s",
266                                 __func__, info->ch_name);
267                 }
268
269                 /*
270                  * Keep system awake long enough to allow the TTY
271                  * framework to pass the flip buffer to any waiting
272                  * userspace clients.
273                  */
274                 __pm_wakeup_event(&info->pending_ws, TTY_PUSH_WS_DELAY);
275
276                 if (smd_tty_in_suspend)
277                         smd_tty_read_in_suspend = true;
278
279                 tty_flip_buffer_push(tty->port);
280         }
281
282         /* XXX only when writable and necessary */
283         tty_wakeup(tty);
284         tty_kref_put(tty);
285 }
286
287 static void smd_tty_notify(void *priv, unsigned event)
288 {
289         struct smd_tty_info *info = priv;
290         struct tty_struct *tty;
291         unsigned long flags;
292
293         switch (event) {
294         case SMD_EVENT_DATA:
295                 spin_lock_irqsave(&info->reset_lock_lha2, flags);
296                 if (!info->is_open) {
297                         spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
298                         break;
299                 }
300                 spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
301                 /* There may be clients (tty framework) that are blocked
302                  * waiting for space to write data, so if a possible read
303                  * interrupt came in wake anyone waiting and disable the
304                  * interrupts
305                  */
306                 if (smd_write_avail(info->ch)) {
307                         smd_disable_read_intr(info->ch);
308                         tty = tty_port_tty_get(&info->port);
309                         if (tty)
310                                 wake_up_interruptible(&tty->write_wait);
311                         tty_kref_put(tty);
312                 }
313                 spin_lock_irqsave(&info->ra_lock_lha3, flags);
314                 if (smd_read_avail(info->ch)) {
315                         __pm_stay_awake(&info->ra_wakeup_source);
316                         tasklet_hi_schedule(&info->tty_tsklt);
317                 }
318                 spin_unlock_irqrestore(&info->ra_lock_lha3, flags);
319                 break;
320
321         case SMD_EVENT_OPEN:
322                 tty = tty_port_tty_get(&info->port);
323                 spin_lock_irqsave(&info->reset_lock_lha2, flags);
324                 if (tty)
325                         clear_bit(TTY_OTHER_CLOSED, &tty->flags);
326                 info->in_reset = 0;
327                 info->in_reset_updated = 1;
328                 info->is_open = 1;
329                 wake_up_interruptible(&info->ch_opened_wait_queue);
330                 spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
331                 tty_kref_put(tty);
332                 break;
333
334         case SMD_EVENT_CLOSE:
335                 spin_lock_irqsave(&info->reset_lock_lha2, flags);
336                 info->in_reset = 1;
337                 info->in_reset_updated = 1;
338                 info->is_open = 0;
339                 wake_up_interruptible(&info->ch_opened_wait_queue);
340                 spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
341
342                 tty = tty_port_tty_get(&info->port);
343                 if (tty) {
344                         /* send TTY_BREAK through read tasklet */
345                         set_bit(TTY_OTHER_CLOSED, &tty->flags);
346                         tasklet_hi_schedule(&info->tty_tsklt);
347
348                         if (tty->index == LOOPBACK_IDX)
349                                 schedule_delayed_work(&loopback_work,
350                                                 msecs_to_jiffies(1000));
351                 }
352                 tty_kref_put(tty);
353                 break;
354         }
355 }
356
357 static uint32_t is_modem_smsm_inited(void)
358 {
359         uint32_t modem_state;
360         uint32_t ready_state = (SMSM_INIT | SMSM_SMDINIT);
361
362         modem_state = smsm_get_state(SMSM_MODEM_STATE);
363         return (modem_state & ready_state) == ready_state;
364 }
365
366 static int smd_tty_dummy_probe(struct platform_device *pdev)
367 {
368         int n;
369
370         for (n = 0; n < MAX_SMD_TTYS; ++n) {
371                 if (!smd_tty[n].dev_name)
372                         continue;
373
374                 if (pdev->id == smd_tty[n].edge &&
375                         !strcmp(pdev->name, smd_tty[n].dev_name)) {
376                         complete_all(&smd_tty[n].ch_allocated);
377                         return 0;
378                 }
379         }
380         SMD_TTY_ERR("[ERR]%s: unknown device '%s'\n", __func__, pdev->name);
381
382         return -ENODEV;
383 }
384
385 /**
386  * smd_tty_add_driver() - Add platform drivers for smd tty device
387  *
388  * @info: context for an individual SMD TTY device
389  *
390  * @returns: 0 for success, standard Linux error code otherwise
391  *
392  * This function is used to register platform driver once for all
393  * smd tty devices which have same names and increment the reference
394  * count for 2nd to nth devices.
395  */
396 static int smd_tty_add_driver(struct smd_tty_info *info)
397 {
398         int r = 0;
399         struct smd_tty_pfdriver *smd_tty_pfdriverp;
400         struct smd_tty_pfdriver *item;
401
402         if (!info) {
403                 pr_err("%s on a NULL device structure\n", __func__);
404                 return -EINVAL;
405         }
406
407         SMD_TTY_INFO("Begin %s on smd_tty[%s]\n", __func__,
408                                         info->ch_name);
409
410         mutex_lock(&smd_tty_pfdriver_lock_lha1);
411         list_for_each_entry(item, &smd_tty_pfdriver_list, list) {
412                 if (!strcmp(item->driver.driver.name, info->dev_name)) {
413                         SMD_TTY_INFO("%s:%s Driver Already reg. cnt:%d\n",
414                                 __func__, info->ch_name, item->ref_cnt);
415                         ++item->ref_cnt;
416                         goto exit;
417                 }
418         }
419
420         smd_tty_pfdriverp = kzalloc(sizeof(*smd_tty_pfdriverp), GFP_KERNEL);
421         if (IS_ERR_OR_NULL(smd_tty_pfdriverp)) {
422                 pr_err("%s: kzalloc() failed for smd_tty_pfdriver[%s]\n",
423                         __func__, info->ch_name);
424                 r = -ENOMEM;
425                 goto exit;
426         }
427
428         smd_tty_pfdriverp->driver.probe = smd_tty_dummy_probe;
429         smd_tty_pfdriverp->driver.driver.name = info->dev_name;
430         smd_tty_pfdriverp->driver.driver.owner = THIS_MODULE;
431         r = platform_driver_register(&smd_tty_pfdriverp->driver);
432         if (r) {
433                 pr_err("%s: %s Platform driver reg. failed\n",
434                         __func__, info->ch_name);
435                 kfree(smd_tty_pfdriverp);
436                 goto exit;
437         }
438         ++smd_tty_pfdriverp->ref_cnt;
439         list_add(&smd_tty_pfdriverp->list, &smd_tty_pfdriver_list);
440
441 exit:
442         SMD_TTY_INFO("End %s on smd_tty_ch[%s]\n", __func__, info->ch_name);
443         mutex_unlock(&smd_tty_pfdriver_lock_lha1);
444         return r;
445 }
446
447 /**
448  * smd_tty_remove_driver() - Remove the platform drivers for smd tty device
449  *
450  * @info: context for an individual SMD TTY device
451  *
452  * This function is used to decrement the reference count on
453  * platform drivers for smd pkt devices and removes the drivers
454  * when the reference count becomes zero.
455  */
456 static void smd_tty_remove_driver(struct smd_tty_info *info)
457 {
458         struct smd_tty_pfdriver *smd_tty_pfdriverp;
459         bool found_item = false;
460
461         if (!info) {
462                 pr_err("%s on a NULL device\n", __func__);
463                 return;
464         }
465
466         SMD_TTY_INFO("Begin %s on smd_tty_ch[%s]\n", __func__,
467                                         info->ch_name);
468         mutex_lock(&smd_tty_pfdriver_lock_lha1);
469         list_for_each_entry(smd_tty_pfdriverp, &smd_tty_pfdriver_list, list) {
470                 if (!strcmp(smd_tty_pfdriverp->driver.driver.name,
471                                         info->dev_name)) {
472                         found_item = true;
473                         SMD_TTY_INFO("%s:%s Platform driver cnt:%d\n",
474                                 __func__, info->ch_name,
475                                 smd_tty_pfdriverp->ref_cnt);
476                         if (smd_tty_pfdriverp->ref_cnt > 0)
477                                 --smd_tty_pfdriverp->ref_cnt;
478                         else
479                                 pr_warn("%s reference count <= 0\n", __func__);
480                         break;
481                 }
482         }
483         if (!found_item)
484                 SMD_TTY_ERR("%s:%s No item found in list.\n",
485                         __func__, info->ch_name);
486
487         if (found_item && smd_tty_pfdriverp->ref_cnt == 0) {
488                 platform_driver_unregister(&smd_tty_pfdriverp->driver);
489                 smd_tty_pfdriverp->driver.probe = NULL;
490                 list_del(&smd_tty_pfdriverp->list);
491                 kfree(smd_tty_pfdriverp);
492         }
493         mutex_unlock(&smd_tty_pfdriver_lock_lha1);
494         SMD_TTY_INFO("End %s on smd_tty_ch[%s]\n", __func__, info->ch_name);
495 }
496
497 static int smd_tty_port_activate(struct tty_port *tport,
498                                  struct tty_struct *tty)
499 {
500         int res = 0;
501         unsigned int n = tty->index;
502         struct smd_tty_info *info;
503         const char *peripheral = NULL;
504
505         if (n >= MAX_SMD_TTYS || !smd_tty[n].ch_name)
506                 return -ENODEV;
507
508         info = smd_tty + n;
509
510         mutex_lock(&info->open_lock_lha1);
511         tty->driver_data = info;
512
513         res = smd_tty_add_driver(info);
514         if (res) {
515                 SMD_TTY_ERR("%s:%d Idx smd_tty_driver register failed %d\n",
516                                                         __func__, n, res);
517                 goto out;
518         }
519
520         peripheral = smd_edge_to_pil_str(smd_tty[n].edge);
521         if (!IS_ERR_OR_NULL(peripheral)) {
522                 info->pil = subsystem_get(peripheral);
523                 if (IS_ERR(info->pil)) {
524                         SMD_TTY_INFO(
525                                 "%s failed on smd_tty device :%s subsystem_get failed for %s",
526                                 __func__, info->ch_name,
527                                 peripheral);
528
529                         /*
530                          * Sleep, inorder to reduce the frequency of
531                          * retry by user-space modules and to avoid
532                          * possible watchdog bite.
533                          */
534                         msleep((smd_tty[n].open_wait * 1000));
535                         res = PTR_ERR(info->pil);
536                         goto platform_unregister;
537                 }
538         }
539
540         /* Wait for the modem SMSM to be inited for the SMD
541          * Loopback channel to be allocated at the modem. Since
542          * the wait need to be done atmost once, using msleep
543          * doesn't degrade the performance.
544          */
545         if (n == LOOPBACK_IDX) {
546                 if (!is_modem_smsm_inited())
547                         msleep(5000);
548                 smsm_change_state(SMSM_APPS_STATE,
549                                   0, SMSM_SMD_LOOPBACK);
550                 msleep(100);
551         }
552
553         /*
554          * Wait for a channel to be allocated so we know
555          * the modem is ready enough.
556          */
557         if (smd_tty[n].open_wait) {
558                 res = wait_for_completion_interruptible_timeout(
559                                 &info->ch_allocated,
560                                 msecs_to_jiffies(smd_tty[n].open_wait *
561                                                                 1000));
562
563                 if (res == 0) {
564                         SMD_TTY_INFO(
565                                 "Timed out waiting for SMD channel %s",
566                                 info->ch_name);
567                         res = -ETIMEDOUT;
568                         goto release_pil;
569                 } else if (res < 0) {
570                         SMD_TTY_INFO(
571                                 "Error waiting for SMD channel %s : %d\n",
572                                 info->ch_name, res);
573                         goto release_pil;
574                 }
575         }
576
577         tasklet_init(&info->tty_tsklt, smd_tty_read, (unsigned long)info);
578         wakeup_source_init(&info->pending_ws, info->ch_name);
579         scnprintf(info->ra_wakeup_source_name, MAX_RA_WAKE_LOCK_NAME_LEN,
580                   "SMD_TTY_%s_RA", info->ch_name);
581         wakeup_source_init(&info->ra_wakeup_source,
582                         info->ra_wakeup_source_name);
583
584         res = smd_named_open_on_edge(info->ch_name,
585                                      smd_tty[n].edge, &info->ch, info,
586                                      smd_tty_notify);
587         if (res < 0) {
588                 SMD_TTY_INFO("%s: %s open failed %d\n",
589                               __func__, info->ch_name, res);
590                 goto release_wl_tl;
591         }
592
593         res = wait_event_interruptible_timeout(info->ch_opened_wait_queue,
594                                                info->is_open, (2 * HZ));
595         if (res == 0)
596                 res = -ETIMEDOUT;
597         if (res < 0) {
598                 SMD_TTY_INFO("%s: wait for %s smd_open failed %d\n",
599                               __func__, info->ch_name, res);
600                 goto close_ch;
601         }
602         SMD_TTY_INFO("%s with PID %u opened port %s",
603                       current->comm, current->pid, info->ch_name);
604         smd_disable_read_intr(info->ch);
605         mutex_unlock(&info->open_lock_lha1);
606         return 0;
607
608 close_ch:
609         smd_close(info->ch);
610         info->ch = NULL;
611
612 release_wl_tl:
613         tasklet_kill(&info->tty_tsklt);
614         wakeup_source_trash(&info->pending_ws);
615         wakeup_source_trash(&info->ra_wakeup_source);
616
617 release_pil:
618         subsystem_put(info->pil);
619
620 platform_unregister:
621         smd_tty_remove_driver(info);
622
623 out:
624         mutex_unlock(&info->open_lock_lha1);
625
626         return res;
627 }
628
629 static void smd_tty_port_shutdown(struct tty_port *tport)
630 {
631         struct smd_tty_info *info;
632         struct tty_struct *tty = tty_port_tty_get(tport);
633         unsigned long flags;
634
635         info = tty->driver_data;
636         if (info == 0) {
637                 tty_kref_put(tty);
638                 return;
639         }
640
641         mutex_lock(&info->open_lock_lha1);
642
643         spin_lock_irqsave(&info->reset_lock_lha2, flags);
644         info->is_open = 0;
645         spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
646
647         tasklet_kill(&info->tty_tsklt);
648         wakeup_source_trash(&info->pending_ws);
649         wakeup_source_trash(&info->ra_wakeup_source);
650
651         SMD_TTY_INFO("%s with PID %u closed port %s",
652                         current->comm, current->pid,
653                         info->ch_name);
654         tty->driver_data = NULL;
655         del_timer(&info->buf_req_timer);
656
657         smd_close(info->ch);
658         info->ch = NULL;
659         subsystem_put(info->pil);
660         smd_tty_remove_driver(info);
661
662         mutex_unlock(&info->open_lock_lha1);
663         tty_kref_put(tty);
664 }
665
666 static int smd_tty_open(struct tty_struct *tty, struct file *f)
667 {
668         struct smd_tty_info *info = smd_tty + tty->index;
669
670         return tty_port_open(&info->port, tty, f);
671 }
672
673 static void smd_tty_close(struct tty_struct *tty, struct file *f)
674 {
675         struct smd_tty_info *info = smd_tty + tty->index;
676
677         tty_port_close(&info->port, tty, f);
678 }
679
680 static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf,
681                                                                         int len)
682 {
683         struct smd_tty_info *info = tty->driver_data;
684         int avail;
685
686         /* if we're writing to a packet channel we will
687         ** never be able to write more data than there
688         ** is currently space for
689         */
690         if (is_in_reset(info))
691                 return -ENETRESET;
692
693         avail = smd_write_avail(info->ch);
694         /* if no space, we'll have to setup a notification later to wake up the
695          * tty framework when space becomes avaliable
696          */
697         if (!avail) {
698                 smd_enable_read_intr(info->ch);
699                 return 0;
700         }
701         if (len > avail)
702                 len = avail;
703         SMD_TTY_INFO("[WRITE]: PID %u -> port %s %x bytes",
704                         current->pid, info->ch_name, len);
705
706         return smd_write(info->ch, buf, len);
707 }
708
709 static int smd_tty_write_room(struct tty_struct *tty)
710 {
711         struct smd_tty_info *info = tty->driver_data;
712         return smd_write_avail(info->ch);
713 }
714
715 static int smd_tty_chars_in_buffer(struct tty_struct *tty)
716 {
717         struct smd_tty_info *info = tty->driver_data;
718         return smd_read_avail(info->ch);
719 }
720
721 static void smd_tty_unthrottle(struct tty_struct *tty)
722 {
723         struct smd_tty_info *info = tty->driver_data;
724         unsigned long flags;
725
726         spin_lock_irqsave(&info->reset_lock_lha2, flags);
727         if (info->is_open) {
728                 spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
729                 tasklet_hi_schedule(&info->tty_tsklt);
730                 return;
731         }
732         spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
733 }
734
735 /*
736  * Returns the current TIOCM status bits including:
737  *      SMD Signals (DTR/DSR, CTS/RTS, CD, RI)
738  *      TIOCM_OUT1 - reset state (1=in reset)
739  *      TIOCM_OUT2 - reset state updated (1=updated)
740  */
741 static int smd_tty_tiocmget(struct tty_struct *tty)
742 {
743         struct smd_tty_info *info = tty->driver_data;
744         unsigned long flags;
745         int tiocm;
746
747         tiocm = smd_tiocmget(info->ch);
748
749         spin_lock_irqsave(&info->reset_lock_lha2, flags);
750         tiocm |= (info->in_reset ? TIOCM_OUT1 : 0);
751         if (info->in_reset_updated) {
752                 tiocm |= TIOCM_OUT2;
753                 info->in_reset_updated = 0;
754         }
755         SMD_TTY_INFO("PID %u --> %s TIOCM is %x ",
756                         current->pid, __func__, tiocm);
757         spin_unlock_irqrestore(&info->reset_lock_lha2, flags);
758
759         return tiocm;
760 }
761
762 static int smd_tty_tiocmset(struct tty_struct *tty,
763                                 unsigned int set, unsigned int clear)
764 {
765         struct smd_tty_info *info = tty->driver_data;
766
767         if (info->in_reset)
768                 return -ENETRESET;
769
770         SMD_TTY_INFO("PID %u --> %s Set: %x Clear: %x",
771                         current->pid, __func__, set, clear);
772         return smd_tiocmset(info->ch, set, clear);
773 }
774
775 static void loopback_probe_worker(struct work_struct *work)
776 {
777         /* wait for modem to restart before requesting loopback server */
778         if (!is_modem_smsm_inited())
779                 schedule_delayed_work(&loopback_work, msecs_to_jiffies(1000));
780         else
781                 smsm_change_state(SMSM_APPS_STATE,
782                           0, SMSM_SMD_LOOPBACK);
783 }
784
785 static const struct tty_port_operations smd_tty_port_ops = {
786         .shutdown = smd_tty_port_shutdown,
787         .activate = smd_tty_port_activate,
788 };
789
790 static const struct tty_operations smd_tty_ops = {
791         .open = smd_tty_open,
792         .close = smd_tty_close,
793         .write = smd_tty_write,
794         .write_room = smd_tty_write_room,
795         .chars_in_buffer = smd_tty_chars_in_buffer,
796         .unthrottle = smd_tty_unthrottle,
797         .tiocmget = smd_tty_tiocmget,
798         .tiocmset = smd_tty_tiocmset,
799 };
800
801 static int smd_tty_pm_notifier(struct notifier_block *nb,
802                                 unsigned long event, void *unused)
803 {
804         switch (event) {
805         case PM_SUSPEND_PREPARE:
806                 smd_tty_read_in_suspend = false;
807                 smd_tty_in_suspend = true;
808                 break;
809
810         case PM_POST_SUSPEND:
811                 smd_tty_in_suspend = false;
812                 if (smd_tty_read_in_suspend) {
813                         smd_tty_read_in_suspend = false;
814                         __pm_wakeup_event(&read_in_suspend_ws,
815                                         TTY_PUSH_WS_POST_SUSPEND_DELAY);
816                 }
817                 break;
818         }
819         return NOTIFY_DONE;
820 }
821
822 static struct notifier_block smd_tty_pm_nb = {
823         .notifier_call = smd_tty_pm_notifier,
824         .priority = 0,
825 };
826
827 /**
828  * smd_tty_log_init()- Init function for IPC logging
829  *
830  * Initialize the buffer that is used to provide the log information
831  * pertaining to the smd_tty module.
832  */
833 static void smd_tty_log_init(void)
834 {
835         smd_tty_log_ctx = ipc_log_context_create(SMD_TTY_LOG_PAGES,
836                                                 "smd_tty", 0);
837         if (!smd_tty_log_ctx)
838                 pr_err("%s: Unable to create IPC log", __func__);
839 }
840
841 static struct tty_driver *smd_tty_driver;
842
843 static int smd_tty_register_driver(void)
844 {
845         int ret;
846
847         smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS);
848         if (smd_tty_driver == 0) {
849                 SMD_TTY_ERR("%s - Driver allocation failed", __func__);
850                 return -ENOMEM;
851         }
852
853         smd_tty_driver->owner = THIS_MODULE;
854         smd_tty_driver->driver_name = "smd_tty_driver";
855         smd_tty_driver->name = "smd";
856         smd_tty_driver->major = 0;
857         smd_tty_driver->minor_start = 0;
858         smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
859         smd_tty_driver->subtype = SERIAL_TYPE_NORMAL;
860         smd_tty_driver->init_termios = tty_std_termios;
861         smd_tty_driver->init_termios.c_iflag = 0;
862         smd_tty_driver->init_termios.c_oflag = 0;
863         smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
864         smd_tty_driver->init_termios.c_lflag = 0;
865         smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS |
866                 TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
867         tty_set_operations(smd_tty_driver, &smd_tty_ops);
868
869         ret = tty_register_driver(smd_tty_driver);
870         if (ret) {
871                 put_tty_driver(smd_tty_driver);
872                 SMD_TTY_ERR("%s: driver registration failed %d", __func__, ret);
873         }
874
875         return ret;
876 }
877
878 static void smd_tty_device_init(int idx)
879 {
880         struct tty_port *port;
881
882         port = &smd_tty[idx].port;
883         tty_port_init(port);
884         port->ops = &smd_tty_port_ops;
885         smd_tty[idx].device_ptr = tty_port_register_device(port, smd_tty_driver,
886                                                            idx, NULL);
887         if (IS_ERR_OR_NULL(smd_tty[idx].device_ptr)) {
888                 SMD_TTY_ERR("%s: Unable to register tty port %s reason %d\n",
889                                 __func__,
890                                 smd_tty[idx].ch_name,
891                                 PTR_ERR_OR_ZERO(smd_tty[idx].device_ptr));
892                 return;
893         }
894         init_completion(&smd_tty[idx].ch_allocated);
895         mutex_init(&smd_tty[idx].open_lock_lha1);
896         spin_lock_init(&smd_tty[idx].reset_lock_lha2);
897         spin_lock_init(&smd_tty[idx].ra_lock_lha3);
898         smd_tty[idx].is_open = 0;
899         setup_timer(&smd_tty[idx].buf_req_timer, buf_req_retry,
900                         (unsigned long)&smd_tty[idx]);
901         init_waitqueue_head(&smd_tty[idx].ch_opened_wait_queue);
902
903         if (device_create_file(smd_tty[idx].device_ptr, &dev_attr_open_timeout))
904                 SMD_TTY_ERR("%s: Unable to create device attributes for %s",
905                         __func__, smd_tty[idx].ch_name);
906 }
907
908 static int smd_tty_devicetree_init(struct platform_device *pdev)
909 {
910         int ret;
911         int idx;
912         int edge;
913         char *key = NULL;
914         const char *ch_name;
915         const char *dev_name;
916         const char *remote_ss;
917         struct device_node *node;
918
919         ret = smd_tty_register_driver();
920         if (ret) {
921                 SMD_TTY_ERR("%s: driver registration failed %d\n",
922                                                 __func__, ret);
923                 return ret;
924         }
925
926         for_each_child_of_node(pdev->dev.of_node, node) {
927
928                 ret = of_alias_get_id(node, "smd");
929                 SMD_TTY_INFO("%s:adding smd%d\n", __func__, ret);
930
931                 if (ret < 0 || ret >= MAX_SMD_TTYS)
932                         goto error;
933                 idx = ret;
934
935                 key = "qcom,smdtty-remote";
936                 remote_ss = of_get_property(node, key, NULL);
937                 if (!remote_ss)
938                         goto error;
939
940                 edge = smd_remote_ss_to_edge(remote_ss);
941                 if (edge < 0)
942                         goto error;
943                 smd_tty[idx].edge = edge;
944
945                 key = "qcom,smdtty-port-name";
946                 ch_name = of_get_property(node, key, NULL);
947                 if (!ch_name)
948                         goto error;
949                 strlcpy(smd_tty[idx].ch_name, ch_name,
950                                         SMD_MAX_CH_NAME_LEN);
951
952                 key = "qcom,smdtty-dev-name";
953                 dev_name = of_get_property(node, key, NULL);
954                 if (!dev_name) {
955                         strlcpy(smd_tty[idx].dev_name, smd_tty[idx].ch_name,
956                                                         SMD_MAX_CH_NAME_LEN);
957                 } else {
958                         strlcpy(smd_tty[idx].dev_name, dev_name,
959                                                 SMD_MAX_CH_NAME_LEN);
960                 }
961
962                 smd_tty_device_init(idx);
963         }
964         INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
965
966         ret = register_pm_notifier(&smd_tty_pm_nb);
967         if (ret)
968                 pr_err("%s: power state notif error %d\n", __func__, ret);
969
970         return 0;
971
972 error:
973         SMD_TTY_ERR("%s:Initialization error, key[%s]\n", __func__, key);
974         /* Unregister tty platform devices */
975         for_each_child_of_node(pdev->dev.of_node, node) {
976
977                 ret = of_alias_get_id(node, "smd");
978                 SMD_TTY_INFO("%s:Removing smd%d\n", __func__, ret);
979
980                 if (ret < 0 || ret >= MAX_SMD_TTYS)
981                         goto out;
982                 idx = ret;
983
984                 if (smd_tty[idx].device_ptr) {
985                         device_remove_file(smd_tty[idx].device_ptr,
986                                                 &dev_attr_open_timeout);
987                         tty_unregister_device(smd_tty_driver, idx);
988                 }
989         }
990 out:
991         tty_unregister_driver(smd_tty_driver);
992         put_tty_driver(smd_tty_driver);
993         return ret;
994 }
995
996 static int msm_smd_tty_probe(struct platform_device *pdev)
997 {
998         int ret;
999
1000         if (pdev) {
1001                 if (pdev->dev.of_node) {
1002                         ret = smd_tty_devicetree_init(pdev);
1003                         if (ret) {
1004                                 SMD_TTY_ERR("%s: device tree init failed\n",
1005                                                                 __func__);
1006                                 return ret;
1007                         }
1008                 }
1009         }
1010
1011         return 0;
1012 }
1013
1014 static struct of_device_id msm_smd_tty_match_table[] = {
1015         { .compatible = "qcom,smdtty" },
1016         {},
1017 };
1018
1019 static struct platform_driver msm_smd_tty_driver = {
1020         .probe = msm_smd_tty_probe,
1021         .driver = {
1022                 .name = MODULE_NAME,
1023                 .owner = THIS_MODULE,
1024                 .of_match_table = msm_smd_tty_match_table,
1025          },
1026 };
1027
1028
1029 static int __init smd_tty_init(void)
1030 {
1031         int rc;
1032
1033         smd_tty_log_init();
1034         rc = platform_driver_register(&msm_smd_tty_driver);
1035         if (rc) {
1036                 SMD_TTY_ERR("%s: msm_smd_tty_driver register failed %d\n",
1037                                                                 __func__, rc);
1038                 return rc;
1039         }
1040
1041         wakeup_source_init(&read_in_suspend_ws, "SMDTTY_READ_IN_SUSPEND");
1042         return 0;
1043 }
1044
1045 module_init(smd_tty_init);