blob: 3f9f22969d784dfe00add9b3eec595ca2b303b4e [file] [log] [blame]
Banajit Goswamide8271c2017-01-18 00:28:59 -08001/* Copyright (c) 2016-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#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/mutex.h>
17#include <linux/errno.h>
18#include <linux/fs.h>
19#include <linux/uaccess.h>
20#include <linux/slab.h>
21#include <linux/list.h>
22#include <linux/cdev.h>
23#include <linux/platform_device.h>
24#include <soc/qcom/glink.h>
25#include "sound/wcd-dsp-glink.h"
26
27#define WDSP_GLINK_DRIVER_NAME "wcd-dsp-glink"
28#define WDSP_MAX_WRITE_SIZE (512 * 1024)
29#define WDSP_MAX_READ_SIZE (4 * 1024)
30
31#define MINOR_NUMBER_COUNT 1
32#define WDSP_EDGE "wdsp"
33#define RESP_QUEUE_SIZE 3
34#define QOS_PKT_SIZE 1024
35#define TIMEOUT_MS 1000
36
37struct wdsp_glink_dev {
38 struct class *cls;
39 struct device *dev;
40 struct cdev cdev;
41 dev_t dev_num;
42};
43
44struct wdsp_glink_rsp_que {
45 /* Size of valid data in buffer */
46 u32 buf_size;
47
48 /* Response buffer */
49 u8 buf[WDSP_MAX_READ_SIZE];
50};
51
52struct wdsp_glink_tx_buf {
53 struct work_struct tx_work;
54
55 /* Glink channel information */
56 struct wdsp_glink_ch *ch;
57
58 /* Tx buffer to send to glink */
59 u8 buf[0];
60};
61
62struct wdsp_glink_ch {
63 struct wdsp_glink_priv *wpriv;
64
65 /* Glink channel handle */
66 void *handle;
67
68 /* Channel states like connect, disconnect */
69 int channel_state;
70 struct mutex mutex;
71
72 /* To free up the channel memory */
73 bool free_mem;
74
75 /* Glink local channel open work */
76 struct work_struct lcl_ch_open_wrk;
77
78 /* Glink local channel close work */
79 struct work_struct lcl_ch_cls_wrk;
80
81 /* Wait for ch connect state before sending any command */
82 wait_queue_head_t ch_connect_wait;
83
84 /*
85 * Glink channel configuration. This has to be the last
86 * member of the strucuture as it has variable size
87 */
88 struct wdsp_glink_ch_cfg ch_cfg;
89};
90
91struct wdsp_glink_state {
92 /* Glink link state information */
93 enum glink_link_state link_state;
94 void *handle;
95};
96
97struct wdsp_glink_priv {
98 /* Respone buffer related */
99 u8 rsp_cnt;
100 struct wdsp_glink_rsp_que rsp[RESP_QUEUE_SIZE];
101 struct completion rsp_complete;
102 struct mutex rsp_mutex;
103
104 /* Glink channel related */
105 struct mutex glink_mutex;
106 struct wdsp_glink_state glink_state;
107 struct wdsp_glink_ch **ch;
108 u8 no_of_channels;
109 struct work_struct ch_open_cls_wrk;
110 struct workqueue_struct *work_queue;
111
112 wait_queue_head_t link_state_wait;
113
114 struct device *dev;
115};
116
117static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch);
118static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch);
119
120/*
121 * wdsp_glink_notify_rx - Glink notify rx callback for responses
122 * handle: Opaque Channel handle returned by GLink
123 * priv: Private pointer to the channel
124 * pkt_priv: Private pointer to the packet
125 * ptr: Pointer to the Rx data
126 * size: Size of the Rx data
127 */
128static void wdsp_glink_notify_rx(void *handle, const void *priv,
129 const void *pkt_priv, const void *ptr,
130 size_t size)
131{
132 u8 *rx_buf;
133 u8 rsp_cnt;
134 struct wdsp_glink_ch *ch;
135 struct wdsp_glink_priv *wpriv;
136
137 if (!ptr || !priv) {
138 pr_err("%s: Invalid parameters\n", __func__);
139 return;
140 }
141
142 ch = (struct wdsp_glink_ch *)priv;
143 wpriv = ch->wpriv;
144 rx_buf = (u8 *)ptr;
145 if (size > WDSP_MAX_READ_SIZE) {
146 dev_err(wpriv->dev, "%s: Size %zd is greater than allowed %d\n",
147 __func__, size, WDSP_MAX_READ_SIZE);
148 size = WDSP_MAX_READ_SIZE;
149 }
150
151 mutex_lock(&wpriv->rsp_mutex);
152 rsp_cnt = wpriv->rsp_cnt;
153 if (rsp_cnt >= RESP_QUEUE_SIZE) {
154 dev_err(wpriv->dev, "%s: Resp Queue is Full\n", __func__);
155 rsp_cnt = 0;
156 }
157 dev_dbg(wpriv->dev, "%s: copy into buffer %d\n", __func__, rsp_cnt);
158
159 memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, size);
160 wpriv->rsp[rsp_cnt].buf_size = size;
161 wpriv->rsp_cnt = ++rsp_cnt;
162 mutex_unlock(&wpriv->rsp_mutex);
163
164 glink_rx_done(handle, ptr, true);
165 complete(&wpriv->rsp_complete);
166}
167
168/*
169 * wdsp_glink_notify_tx_done - Glink notify tx done callback to
170 * free tx buffer
171 * handle: Opaque Channel handle returned by GLink
172 * priv: Private pointer to the channel
173 * pkt_priv: Private pointer to the packet
174 * ptr: Pointer to the Tx data
175 */
176static void wdsp_glink_notify_tx_done(void *handle, const void *priv,
177 const void *pkt_priv, const void *ptr)
178{
179 if (!pkt_priv) {
180 pr_err("%s: Invalid parameter\n", __func__);
181 return;
182 }
183 /* Free tx pkt */
184 kfree(pkt_priv);
185}
186
187/*
188 * wdsp_glink_notify_tx_abort - Glink notify tx abort callback to
189 * free tx buffer
190 * handle: Opaque Channel handle returned by GLink
191 * priv: Private pointer to the channel
192 * pkt_priv: Private pointer to the packet
193 */
194static void wdsp_glink_notify_tx_abort(void *handle, const void *priv,
195 const void *pkt_priv)
196{
197 if (!pkt_priv) {
198 pr_err("%s: Invalid parameter\n", __func__);
199 return;
200 }
201 /* Free tx pkt */
202 kfree(pkt_priv);
203}
204
205/*
206 * wdsp_glink_notify_rx_intent_req - Glink notify rx intent request callback
207 * to queue buffer to receive from remote client
208 * handle: Opaque channel handle returned by GLink
209 * priv: Private pointer to the channel
210 * req_size: Size of intent to be queued
211 */
212static bool wdsp_glink_notify_rx_intent_req(void *handle, const void *priv,
213 size_t req_size)
214{
215 struct wdsp_glink_priv *wpriv;
216 struct wdsp_glink_ch *ch;
217 int rc = 0;
218 bool ret = false;
219
220 if (!priv) {
221 pr_err("%s: Invalid priv\n", __func__);
222 goto done;
223 }
224 if (req_size > WDSP_MAX_READ_SIZE) {
225 pr_err("%s: Invalid req_size %zd\n", __func__, req_size);
226 goto done;
227 }
228
229 ch = (struct wdsp_glink_ch *)priv;
230 wpriv = ch->wpriv;
231
232 dev_dbg(wpriv->dev, "%s: intent size %zd requested for ch name %s",
233 __func__, req_size, ch->ch_cfg.name);
234
235 mutex_lock(&ch->mutex);
236 rc = glink_queue_rx_intent(ch->handle, ch, req_size);
237 if (IS_ERR_VALUE(rc)) {
238 dev_err(wpriv->dev, "%s: Failed to queue rx intent, rc = %d\n",
239 __func__, rc);
240 mutex_unlock(&ch->mutex);
241 goto done;
242 }
243 mutex_unlock(&ch->mutex);
244 ret = true;
245
246done:
247 return ret;
248}
249
250/*
251 * wdsp_glink_lcl_ch_open_wrk - Work function to open channel again
252 * when local disconnect event happens
253 * work: Work structure
254 */
255static void wdsp_glink_lcl_ch_open_wrk(struct work_struct *work)
256{
257 struct wdsp_glink_ch *ch;
258
259 ch = container_of(work, struct wdsp_glink_ch,
260 lcl_ch_open_wrk);
261
262 wdsp_glink_open_ch(ch);
263}
264
265/*
266 * wdsp_glink_lcl_ch_cls_wrk - Work function to close channel locally
267 * when remote disconnect event happens
268 * work: Work structure
269 */
270static void wdsp_glink_lcl_ch_cls_wrk(struct work_struct *work)
271{
272 struct wdsp_glink_ch *ch;
273
274 ch = container_of(work, struct wdsp_glink_ch,
275 lcl_ch_cls_wrk);
276
277 wdsp_glink_close_ch(ch);
278}
279
280/*
281 * wdsp_glink_notify_state - Glink channel state information event callback
282 * handle: Opaque Channel handle returned by GLink
283 * priv: Private pointer to the channel
284 * event: channel state event
285 */
286static void wdsp_glink_notify_state(void *handle, const void *priv,
287 unsigned int event)
288{
289 struct wdsp_glink_priv *wpriv;
290 struct wdsp_glink_ch *ch;
291 int i, ret = 0;
292
293 if (!priv) {
294 pr_err("%s: Invalid priv\n", __func__);
295 return;
296 }
297
298 ch = (struct wdsp_glink_ch *)priv;
299 wpriv = ch->wpriv;
300
301 mutex_lock(&ch->mutex);
302 ch->channel_state = event;
303 if (event == GLINK_CONNECTED) {
304 dev_dbg(wpriv->dev, "%s: glink channel: %s connected\n",
305 __func__, ch->ch_cfg.name);
306
307 for (i = 0; i < ch->ch_cfg.no_of_intents; i++) {
308 dev_dbg(wpriv->dev, "%s: intent_size = %d\n", __func__,
309 ch->ch_cfg.intents_size[i]);
310 ret = glink_queue_rx_intent(ch->handle, ch,
311 ch->ch_cfg.intents_size[i]);
312 if (IS_ERR_VALUE(ret))
313 dev_warn(wpriv->dev, "%s: Failed to queue intent %d of size %d\n",
314 __func__, i,
315 ch->ch_cfg.intents_size[i]);
316 }
317
318 ret = glink_qos_latency(ch->handle, ch->ch_cfg.latency_in_us,
319 QOS_PKT_SIZE);
320 if (IS_ERR_VALUE(ret))
321 dev_warn(wpriv->dev, "%s: Failed to request qos %d for ch %s\n",
322 __func__, ch->ch_cfg.latency_in_us,
323 ch->ch_cfg.name);
324
325 wake_up(&ch->ch_connect_wait);
326 mutex_unlock(&ch->mutex);
327 } else if (event == GLINK_LOCAL_DISCONNECTED) {
328 /*
329 * Don't use dev_dbg here as dev may not be valid if channel
330 * closed from driver close.
331 */
332 pr_debug("%s: channel: %s disconnected locally\n",
333 __func__, ch->ch_cfg.name);
334 mutex_unlock(&ch->mutex);
335
336 if (ch->free_mem) {
337 kfree(ch);
338 ch = NULL;
339 }
340 } else if (event == GLINK_REMOTE_DISCONNECTED) {
341 dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n",
342 __func__, ch->ch_cfg.name);
343 mutex_unlock(&ch->mutex);
344 /*
345 * If remote disconnect happens, local side also has
346 * to close the channel as per glink design in a
347 * separate work_queue.
348 */
349 queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk);
350 }
351}
352
353/*
354 * wdsp_glink_close_ch - Internal function to close glink channel
355 * ch: Glink Channel structure.
356 */
357static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch)
358{
359 struct wdsp_glink_priv *wpriv = ch->wpriv;
360 int ret = 0;
361
362 mutex_lock(&wpriv->glink_mutex);
363 if (ch->handle) {
364 ret = glink_close(ch->handle);
365 if (IS_ERR_VALUE(ret)) {
366 dev_err(wpriv->dev, "%s: glink_close is failed, ret = %d\n",
367 __func__, ret);
368 } else {
369 ch->handle = NULL;
370 dev_dbg(wpriv->dev, "%s: ch %s is closed\n", __func__,
371 ch->ch_cfg.name);
372 }
373 } else {
374 dev_dbg(wpriv->dev, "%s: ch %s is already closed\n", __func__,
375 ch->ch_cfg.name);
376 }
377 mutex_unlock(&wpriv->glink_mutex);
378
379
380 return ret;
381}
382
383/*
384 * wdsp_glink_open_ch - Internal function to open glink channel
385 * ch: Glink Channel structure.
386 */
387static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch)
388{
389 struct wdsp_glink_priv *wpriv = ch->wpriv;
390 struct glink_open_config open_cfg;
391 int ret = 0;
392
393 mutex_lock(&wpriv->glink_mutex);
394 if (!ch->handle) {
395 memset(&open_cfg, 0, sizeof(open_cfg));
396 open_cfg.options = GLINK_OPT_INITIAL_XPORT;
397 open_cfg.edge = WDSP_EDGE;
398 open_cfg.notify_rx = wdsp_glink_notify_rx;
399 open_cfg.notify_tx_done = wdsp_glink_notify_tx_done;
400 open_cfg.notify_tx_abort = wdsp_glink_notify_tx_abort;
401 open_cfg.notify_state = wdsp_glink_notify_state;
402 open_cfg.notify_rx_intent_req = wdsp_glink_notify_rx_intent_req;
403 open_cfg.priv = ch;
404 open_cfg.name = ch->ch_cfg.name;
405
406 dev_dbg(wpriv->dev, "%s: ch->ch_cfg.name = %s, latency_in_us = %d, intents = %d\n",
407 __func__, ch->ch_cfg.name, ch->ch_cfg.latency_in_us,
408 ch->ch_cfg.no_of_intents);
409
410 ch->handle = glink_open(&open_cfg);
411 if (IS_ERR_OR_NULL(ch->handle)) {
412 dev_err(wpriv->dev, "%s: glink_open failed for ch %s\n",
413 __func__, ch->ch_cfg.name);
414 ch->handle = NULL;
415 ret = -EINVAL;
416 }
417 } else {
418 dev_err(wpriv->dev, "%s: ch %s is already opened\n", __func__,
419 ch->ch_cfg.name);
420 }
421 mutex_unlock(&wpriv->glink_mutex);
422
423 return ret;
424}
425
426/*
427 * wdsp_glink_close_all_ch - Internal function to close all glink channels
428 * wpriv: Wdsp_glink private structure
429 */
430static void wdsp_glink_close_all_ch(struct wdsp_glink_priv *wpriv)
431{
432 int i;
433
434 for (i = 0; i < wpriv->no_of_channels; i++)
435 if (wpriv->ch && wpriv->ch[i])
436 wdsp_glink_close_ch(wpriv->ch[i]);
437}
438
439/*
440 * wdsp_glink_open_all_ch - Internal function to open all glink channels
441 * wpriv: Wdsp_glink private structure
442 */
443static int wdsp_glink_open_all_ch(struct wdsp_glink_priv *wpriv)
444{
445 int ret = 0, i, j;
446
447 for (i = 0; i < wpriv->no_of_channels; i++) {
448 if (wpriv->ch && wpriv->ch[i]) {
449 ret = wdsp_glink_open_ch(wpriv->ch[i]);
450 if (IS_ERR_VALUE(ret))
451 goto err_open;
452 }
453 }
454 goto done;
455
456err_open:
457 for (j = 0; j < i; j++)
458 if (wpriv->ch[i])
459 wdsp_glink_close_ch(wpriv->ch[j]);
460
461done:
462 return ret;
463}
464
465/*
466 * wdsp_glink_ch_open_wq - Work function to open glink channels
467 * work: Work structure
468 */
469static void wdsp_glink_ch_open_cls_wrk(struct work_struct *work)
470{
471 struct wdsp_glink_priv *wpriv;
472
473 wpriv = container_of(work, struct wdsp_glink_priv,
474 ch_open_cls_wrk);
475
476 if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) {
477 dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_DOWN\n",
478 __func__);
479
480 wdsp_glink_close_all_ch(wpriv);
481 } else if (wpriv->glink_state.link_state == GLINK_LINK_STATE_UP) {
482 dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_UP\n",
483 __func__);
484
485 wdsp_glink_open_all_ch(wpriv);
486 }
487}
488
489/*
490 * wdsp_glink_link_state_cb - Glink link state callback to inform
491 * about link states
492 * cb_info: Glink link state callback information structure
493 * priv: Private structure of link state passed while register
494 */
495static void wdsp_glink_link_state_cb(struct glink_link_state_cb_info *cb_info,
496 void *priv)
497{
498 struct wdsp_glink_priv *wpriv;
499
500 if (!cb_info || !priv) {
501 pr_err("%s: Invalid parameters\n", __func__);
502 return;
503 }
504
505 wpriv = (struct wdsp_glink_priv *)priv;
506
507 mutex_lock(&wpriv->glink_mutex);
508 wpriv->glink_state.link_state = cb_info->link_state;
509 wake_up(&wpriv->link_state_wait);
510 mutex_unlock(&wpriv->glink_mutex);
511
512 queue_work(wpriv->work_queue, &wpriv->ch_open_cls_wrk);
513}
514
515/*
516 * wdsp_glink_ch_info_init- Internal function to allocate channel memory
517 * and register with glink
518 * wpriv: Wdsp_glink private structure.
519 * pkt: Glink registration packet contains glink channel information.
520 */
521static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv,
522 struct wdsp_reg_pkt *pkt)
523{
524 int ret = 0, i, j;
525 struct glink_link_info link_info;
526 struct wdsp_glink_ch_cfg *ch_cfg;
527 struct wdsp_glink_ch **ch;
528 u8 no_of_channels;
529 u8 *payload;
530 u32 ch_size, ch_cfg_size;
531
532 payload = (u8 *)pkt->payload;
533 no_of_channels = pkt->no_of_channels;
534
535 ch = kcalloc(no_of_channels, sizeof(struct wdsp_glink_ch *),
536 GFP_KERNEL);
537 if (!ch) {
538 ret = -ENOMEM;
539 goto done;
540 }
541
542 for (i = 0; i < no_of_channels; i++) {
543 ch_cfg = (struct wdsp_glink_ch_cfg *)payload;
544 ch_cfg_size = sizeof(struct wdsp_glink_ch_cfg) +
545 (sizeof(u32) * ch_cfg->no_of_intents);
546 ch_size = sizeof(struct wdsp_glink_ch) +
547 (sizeof(u32) * ch_cfg->no_of_intents);
548
549 dev_dbg(wpriv->dev, "%s: channels = %d, ch_cfg_size %d",
550 __func__, no_of_channels, ch_cfg_size);
551
552 ch[i] = kzalloc(ch_size, GFP_KERNEL);
553 if (!ch[i]) {
554 ret = -ENOMEM;
555 goto err_ch_mem;
556 }
557 ch[i]->channel_state = GLINK_LOCAL_DISCONNECTED;
558 memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size);
559 payload += ch_cfg_size;
560
561 mutex_init(&ch[i]->mutex);
562 ch[i]->wpriv = wpriv;
563 INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk);
564 INIT_WORK(&ch[i]->lcl_ch_cls_wrk, wdsp_glink_lcl_ch_cls_wrk);
565 init_waitqueue_head(&ch[i]->ch_connect_wait);
566 }
567 wpriv->ch = ch;
568 wpriv->no_of_channels = no_of_channels;
569
570 INIT_WORK(&wpriv->ch_open_cls_wrk, wdsp_glink_ch_open_cls_wrk);
571
572 /* Register glink link_state notification */
573 link_info.glink_link_state_notif_cb = wdsp_glink_link_state_cb;
574 link_info.transport = NULL;
575 link_info.edge = WDSP_EDGE;
576
577 wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN;
578 wpriv->glink_state.handle = glink_register_link_state_cb(&link_info,
579 wpriv);
580 if (!wpriv->glink_state.handle) {
581 dev_err(wpriv->dev, "%s: Unable to register wdsp link state\n",
582 __func__);
583 ret = -EINVAL;
584 goto err_ch_mem;
585 }
586 goto done;
587
588err_ch_mem:
589 for (j = 0; j < i; j++) {
590 mutex_destroy(&ch[j]->mutex);
591 kfree(wpriv->ch[j]);
592 wpriv->ch[j] = NULL;
593 }
594 kfree(wpriv->ch);
595 wpriv->ch = NULL;
596 wpriv->no_of_channels = 0;
597
598done:
599 return ret;
600}
601
602/*
603 * wdsp_glink_tx_buf_work - Work queue function to send tx buffer to glink
604 * work: Work structure
605 */
606static void wdsp_glink_tx_buf_work(struct work_struct *work)
607{
608 struct wdsp_glink_priv *wpriv;
609 struct wdsp_glink_ch *ch;
610 struct wdsp_glink_tx_buf *tx_buf;
611 struct wdsp_write_pkt *wpkt;
612 struct wdsp_cmd_pkt *cpkt;
613 int ret = 0;
614
615 tx_buf = container_of(work, struct wdsp_glink_tx_buf,
616 tx_work);
617 ch = tx_buf->ch;
618 wpriv = ch->wpriv;
619 wpkt = (struct wdsp_write_pkt *)tx_buf->buf;
620 cpkt = (struct wdsp_cmd_pkt *)wpkt->payload;
621 dev_dbg(wpriv->dev, "%s: ch name = %s, payload size = %d\n",
622 __func__, cpkt->ch_name, cpkt->payload_size);
623
624 mutex_lock(&tx_buf->ch->mutex);
625 if (ch->channel_state == GLINK_CONNECTED) {
626 mutex_unlock(&tx_buf->ch->mutex);
627 ret = glink_tx(ch->handle, tx_buf,
628 cpkt->payload, cpkt->payload_size,
629 GLINK_TX_REQ_INTENT);
630 if (IS_ERR_VALUE(ret)) {
631 dev_err(wpriv->dev, "%s: glink tx failed, ret = %d\n",
632 __func__, ret);
633 /*
634 * If glink_tx() is failed then free tx_buf here as
635 * there won't be any tx_done notification to
636 * free the buffer.
637 */
638 kfree(tx_buf);
639 }
640 } else {
641 mutex_unlock(&tx_buf->ch->mutex);
642 dev_err(wpriv->dev, "%s: channel %s is not in connected state\n",
643 __func__, ch->ch_cfg.name);
644 /*
645 * Free tx_buf here as there won't be any tx_done
646 * notification in this case also.
647 */
648 kfree(tx_buf);
649 }
650}
651
652/*
653 * wdsp_glink_read - Read API to send the data to userspace
654 * file: Pointer to the file structure
655 * buf: Pointer to the userspace buffer
656 * count: Number bytes to read from the file
657 * ppos: Pointer to the position into the file
658 */
659static ssize_t wdsp_glink_read(struct file *file, char __user *buf,
660 size_t count, loff_t *ppos)
661{
662 int ret = 0, ret1 = 0;
663 struct wdsp_glink_rsp_que *rsp;
664 struct wdsp_glink_priv *wpriv;
665
666 wpriv = (struct wdsp_glink_priv *)file->private_data;
667 if (!wpriv) {
668 pr_err("%s: Invalid private data\n", __func__);
669 ret = -EINVAL;
670 goto done;
671 }
672
673 if (count > WDSP_MAX_READ_SIZE) {
674 dev_info(wpriv->dev, "%s: count = %zd is more than WDSP_MAX_READ_SIZE\n",
675 __func__, count);
676 count = WDSP_MAX_READ_SIZE;
677 }
678 /*
679 * Complete signal has given from glink rx notification callback
680 * or from flush API. Also use interruptible wait_for_completion API
681 * to allow the system to go in suspend.
682 */
683 ret = wait_for_completion_interruptible(&wpriv->rsp_complete);
684 if (ret)
685 goto done;
686
687 mutex_lock(&wpriv->rsp_mutex);
688 if (wpriv->rsp_cnt) {
689 wpriv->rsp_cnt--;
690 dev_dbg(wpriv->dev, "%s: read from buffer %d\n",
691 __func__, wpriv->rsp_cnt);
692
693 rsp = &wpriv->rsp[wpriv->rsp_cnt];
694 if (count < rsp->buf_size) {
695 ret1 = copy_to_user(buf, &rsp->buf, count);
696 /* Return the number of bytes copied */
697 ret = count;
698 } else {
699 ret1 = copy_to_user(buf, &rsp->buf, rsp->buf_size);
700 /* Return the number of bytes copied */
701 ret = rsp->buf_size;
702 }
703
704 if (ret1) {
705 mutex_unlock(&wpriv->rsp_mutex);
706 dev_err(wpriv->dev, "%s: copy_to_user failed %d\n",
707 __func__, ret);
708 ret = -EFAULT;
709 goto done;
710 }
711 } else {
712 /*
713 * This will execute only if flush API is called or
714 * something wrong with ref_cnt
715 */
716 dev_dbg(wpriv->dev, "%s: resp count = %d\n", __func__,
717 wpriv->rsp_cnt);
718 ret = -EINVAL;
719 }
720 mutex_unlock(&wpriv->rsp_mutex);
721
722done:
723 return ret;
724}
725
726/*
727 * wdsp_glink_write - Write API to receive the data from userspace
728 * file: Pointer to the file structure
729 * buf: Pointer to the userspace buffer
730 * count: Number bytes to read from the file
731 * ppos: Pointer to the position into the file
732 */
733static ssize_t wdsp_glink_write(struct file *file, const char __user *buf,
734 size_t count, loff_t *ppos)
735{
736 int ret = 0, i, tx_buf_size;
737 struct wdsp_write_pkt *wpkt;
738 struct wdsp_cmd_pkt *cpkt;
739 struct wdsp_glink_tx_buf *tx_buf;
740 struct wdsp_glink_priv *wpriv;
741
742 wpriv = (struct wdsp_glink_priv *)file->private_data;
743 if (!wpriv) {
744 pr_err("%s: Invalid private data\n", __func__);
745 ret = -EINVAL;
746 goto done;
747 }
748
749 dev_dbg(wpriv->dev, "%s: count = %zd\n", __func__, count);
750
751 if (count > WDSP_MAX_WRITE_SIZE) {
752 dev_info(wpriv->dev, "%s: count = %zd is more than WDSP_MAX_WRITE_SIZE\n",
753 __func__, count);
754 count = WDSP_MAX_WRITE_SIZE;
755 }
756
757 tx_buf_size = count + sizeof(struct wdsp_glink_tx_buf);
758 tx_buf = kzalloc(tx_buf_size, GFP_KERNEL);
759 if (!tx_buf) {
760 ret = -ENOMEM;
761 goto done;
762 }
763
764 ret = copy_from_user(tx_buf->buf, buf, count);
765 if (ret) {
766 dev_err(wpriv->dev, "%s: copy_from_user failed %d\n",
767 __func__, ret);
768 ret = -EFAULT;
769 goto free_buf;
770 }
771
772 wpkt = (struct wdsp_write_pkt *)tx_buf->buf;
773 switch (wpkt->pkt_type) {
774 case WDSP_REG_PKT:
775 ret = wdsp_glink_ch_info_init(wpriv,
776 (struct wdsp_reg_pkt *)wpkt->payload);
777 if (IS_ERR_VALUE(ret))
778 dev_err(wpriv->dev, "%s: glink register failed, ret = %d\n",
779 __func__, ret);
780 kfree(tx_buf);
781 break;
782 case WDSP_READY_PKT:
783 ret = wait_event_timeout(wpriv->link_state_wait,
784 (wpriv->glink_state.link_state ==
785 GLINK_LINK_STATE_UP),
786 msecs_to_jiffies(TIMEOUT_MS));
787 if (!ret) {
788 dev_err(wpriv->dev, "%s: Link state wait timeout\n",
789 __func__);
790 ret = -ETIMEDOUT;
791 goto free_buf;
792 }
793 ret = 0;
794 kfree(tx_buf);
795 break;
796 case WDSP_CMD_PKT:
797 mutex_lock(&wpriv->glink_mutex);
798 if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) {
799 mutex_unlock(&wpriv->glink_mutex);
800 dev_err(wpriv->dev, "%s: Link state is Down\n",
801 __func__);
802
803 ret = -ENETRESET;
804 goto free_buf;
805 }
806 mutex_unlock(&wpriv->glink_mutex);
807
808 cpkt = (struct wdsp_cmd_pkt *)wpkt->payload;
809 dev_dbg(wpriv->dev, "%s: requested ch_name: %s\n", __func__,
810 cpkt->ch_name);
811 for (i = 0; i < wpriv->no_of_channels; i++) {
812 if (wpriv->ch && wpriv->ch[i] &&
813 (!strcmp(cpkt->ch_name,
814 wpriv->ch[i]->ch_cfg.name))) {
815 tx_buf->ch = wpriv->ch[i];
816 break;
817 }
818 }
819 if (!tx_buf->ch) {
820 dev_err(wpriv->dev, "%s: Failed to get glink channel\n",
821 __func__);
822 ret = -EINVAL;
823 goto free_buf;
824 }
825
826 ret = wait_event_timeout(tx_buf->ch->ch_connect_wait,
827 (tx_buf->ch->channel_state ==
828 GLINK_CONNECTED),
829 msecs_to_jiffies(TIMEOUT_MS));
830 if (!ret) {
831 dev_err(wpriv->dev, "%s: glink channel %s is not in connected state %d\n",
832 __func__, tx_buf->ch->ch_cfg.name,
833 tx_buf->ch->channel_state);
834 ret = -ETIMEDOUT;
835 goto free_buf;
836 }
837 ret = 0;
838
839 INIT_WORK(&tx_buf->tx_work, wdsp_glink_tx_buf_work);
840 queue_work(wpriv->work_queue, &tx_buf->tx_work);
841 break;
842 default:
843 dev_err(wpriv->dev, "%s: Invalid packet type\n", __func__);
844 ret = -EINVAL;
845 kfree(tx_buf);
846 break;
847 }
848 goto done;
849
850free_buf:
851 kfree(tx_buf);
852
853done:
854 return ret;
855}
856
857/*
858 * wdsp_glink_open - Open API to initialize private data
859 * inode: Pointer to the inode structure
860 * file: Pointer to the file structure
861 */
862static int wdsp_glink_open(struct inode *inode, struct file *file)
863{
864 int ret = 0;
865 struct wdsp_glink_priv *wpriv;
866 struct wdsp_glink_dev *wdev;
867
868 if (!inode->i_cdev) {
869 pr_err("%s: cdev is NULL\n", __func__);
870 ret = -EINVAL;
871 goto done;
872 }
873 wdev = container_of(inode->i_cdev, struct wdsp_glink_dev, cdev);
874
875 wpriv = kzalloc(sizeof(struct wdsp_glink_priv), GFP_KERNEL);
876 if (!wpriv) {
877 ret = -ENOMEM;
878 goto done;
879 }
880 wpriv->dev = wdev->dev;
881 wpriv->work_queue = create_singlethread_workqueue("wdsp_glink_wq");
882 if (!wpriv->work_queue) {
883 dev_err(wpriv->dev, "%s: Error creating wdsp_glink_wq\n",
884 __func__);
885 ret = -EINVAL;
886 goto err_wq;
887 }
888
889 init_completion(&wpriv->rsp_complete);
890 init_waitqueue_head(&wpriv->link_state_wait);
891 mutex_init(&wpriv->rsp_mutex);
892 mutex_init(&wpriv->glink_mutex);
893 file->private_data = wpriv;
894
895 goto done;
896
897err_wq:
898 kfree(wpriv);
899
900done:
901 return ret;
902}
903
904/*
905 * wdsp_glink_flush - Flush API to unblock read.
906 * file: Pointer to the file structure
907 * id: Lock owner ID
908 */
909static int wdsp_glink_flush(struct file *file, fl_owner_t id)
910{
911 struct wdsp_glink_priv *wpriv;
912
913 wpriv = (struct wdsp_glink_priv *)file->private_data;
914 if (!wpriv) {
915 pr_err("%s: Invalid private data\n", __func__);
916 return -EINVAL;
917 }
918
919 complete(&wpriv->rsp_complete);
920
921 return 0;
922}
923
924/*
925 * wdsp_glink_release - Release API to clean up resources.
926 * Whenever a file structure is shared across multiple threads,
927 * release won't be invoked until all copies are closed
928 * (file->f_count.counter should be 0). If we need to flush pending
929 * data when any copy is closed, you should implement the flush method.
930 *
931 * inode: Pointer to the inode structure
932 * file: Pointer to the file structure
933 */
934static int wdsp_glink_release(struct inode *inode, struct file *file)
935{
936 int i, ret = 0;
937 struct wdsp_glink_priv *wpriv;
938
939 wpriv = (struct wdsp_glink_priv *)file->private_data;
940 if (!wpriv) {
941 pr_err("%s: Invalid private data\n", __func__);
942 ret = -EINVAL;
943 goto done;
944 }
945
946 if (wpriv->glink_state.handle)
947 glink_unregister_link_state_cb(wpriv->glink_state.handle);
948
949 flush_workqueue(wpriv->work_queue);
950 destroy_workqueue(wpriv->work_queue);
951
952 /*
953 * Clean up glink channel memory in channel state
954 * callback only if close channels are called from here.
955 */
956 if (wpriv->ch) {
957 for (i = 0; i < wpriv->no_of_channels; i++) {
958 if (wpriv->ch[i]) {
959 wpriv->ch[i]->free_mem = true;
960 /*
961 * Channel handle NULL means channel is already
962 * closed. Free the channel memory here itself.
963 */
964 if (!wpriv->ch[i]->handle) {
965 kfree(wpriv->ch[i]);
966 wpriv->ch[i] = NULL;
967 } else {
968 wdsp_glink_close_ch(wpriv->ch[i]);
969 }
970 }
971 }
972
973 kfree(wpriv->ch);
974 wpriv->ch = NULL;
975 }
976
977 mutex_destroy(&wpriv->glink_mutex);
978 mutex_destroy(&wpriv->rsp_mutex);
979 kfree(wpriv);
980 file->private_data = NULL;
981
982done:
983 return ret;
984}
985
986static const struct file_operations wdsp_glink_fops = {
987 .owner = THIS_MODULE,
988 .open = wdsp_glink_open,
989 .read = wdsp_glink_read,
990 .write = wdsp_glink_write,
991 .flush = wdsp_glink_flush,
992 .release = wdsp_glink_release,
993};
994
995/*
996 * wdsp_glink_probe - Driver probe to expose char device
997 * pdev: Pointer to device tree data.
998 */
999static int wdsp_glink_probe(struct platform_device *pdev)
1000{
1001 int ret;
1002 struct wdsp_glink_dev *wdev;
1003
1004 wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL);
1005 if (!wdev) {
1006 ret = -ENOMEM;
1007 goto done;
1008 }
1009
1010 ret = alloc_chrdev_region(&wdev->dev_num, 0, MINOR_NUMBER_COUNT,
1011 WDSP_GLINK_DRIVER_NAME);
1012 if (IS_ERR_VALUE(ret)) {
1013 dev_err(&pdev->dev, "%s: Failed to alloc char dev, err = %d\n",
1014 __func__, ret);
1015 goto err_chrdev;
1016 }
1017
1018 wdev->cls = class_create(THIS_MODULE, WDSP_GLINK_DRIVER_NAME);
1019 if (IS_ERR(wdev->cls)) {
1020 ret = PTR_ERR(wdev->cls);
1021 dev_err(&pdev->dev, "%s: Failed to create class, err = %d\n",
1022 __func__, ret);
1023 goto err_class;
1024 }
1025
1026 wdev->dev = device_create(wdev->cls, NULL, wdev->dev_num,
1027 NULL, WDSP_GLINK_DRIVER_NAME);
1028 if (IS_ERR(wdev->dev)) {
1029 ret = PTR_ERR(wdev->dev);
1030 dev_err(&pdev->dev, "%s: Failed to create device, err = %d\n",
1031 __func__, ret);
1032 goto err_dev_create;
1033 }
1034
1035 cdev_init(&wdev->cdev, &wdsp_glink_fops);
1036 ret = cdev_add(&wdev->cdev, wdev->dev_num, MINOR_NUMBER_COUNT);
1037 if (IS_ERR_VALUE(ret)) {
1038 dev_err(&pdev->dev, "%s: Failed to register char dev, err = %d\n",
1039 __func__, ret);
1040 goto err_cdev_add;
1041 }
1042 platform_set_drvdata(pdev, wdev);
1043 goto done;
1044
1045err_cdev_add:
1046 device_destroy(wdev->cls, wdev->dev_num);
1047
1048err_dev_create:
1049 class_destroy(wdev->cls);
1050
1051err_class:
1052 unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
1053
1054err_chrdev:
1055 devm_kfree(&pdev->dev, wdev);
1056
1057done:
1058 return ret;
1059}
1060
1061/*
1062 * wdsp_glink_remove - Driver remove to handle cleanup
1063 * pdev: Pointer to device tree data.
1064 */
1065static int wdsp_glink_remove(struct platform_device *pdev)
1066{
1067 struct wdsp_glink_dev *wdev = platform_get_drvdata(pdev);
1068
1069 if (wdev) {
1070 cdev_del(&wdev->cdev);
1071 device_destroy(wdev->cls, wdev->dev_num);
1072 class_destroy(wdev->cls);
1073 unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
1074 devm_kfree(&pdev->dev, wdev);
1075 } else {
1076 dev_err(&pdev->dev, "%s: Invalid device data\n", __func__);
1077 }
1078
1079 return 0;
1080}
1081
1082static const struct of_device_id wdsp_glink_of_match[] = {
1083 {.compatible = "qcom,wcd-dsp-glink"},
1084 { }
1085};
1086MODULE_DEVICE_TABLE(of, wdsp_glink_of_match);
1087
1088static struct platform_driver wdsp_glink_driver = {
1089 .probe = wdsp_glink_probe,
1090 .remove = wdsp_glink_remove,
1091 .driver = {
1092 .name = WDSP_GLINK_DRIVER_NAME,
1093 .owner = THIS_MODULE,
1094 .of_match_table = wdsp_glink_of_match,
1095 },
1096};
1097
1098module_platform_driver(wdsp_glink_driver);
1099
1100MODULE_DESCRIPTION("SoC WCD_DSP GLINK Driver");
1101MODULE_LICENSE("GPL v2");