blob: 34be2301be20add3b9345261a1905721a2f416cc [file] [log] [blame]
Shrey Vijayec24ad82018-04-10 15:05:31 +05301/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002 *
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 */
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -060012#include <asm/dma-iommu.h>
Sagar Dhariabe37c9c2016-11-28 23:06:58 -070013#include <linux/irq.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/io.h>
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -060018#include <linux/iommu.h>
Sagar Dhariabe37c9c2016-11-28 23:06:58 -070019#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/dma-mapping.h>
22#include <linux/slimbus/slimbus.h>
23#include <linux/delay.h>
24#include <linux/kthread.h>
25#include <linux/clk.h>
26#include <linux/pm_runtime.h>
27#include <linux/of.h>
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -060028#include <linux/of_platform.h>
Sagar Dhariabe37c9c2016-11-28 23:06:58 -070029#include <linux/of_slimbus.h>
30#include <linux/timer.h>
31#include <linux/msm-sps.h>
32#include <soc/qcom/service-locator.h>
33#include <soc/qcom/service-notifier.h>
34#include <soc/qcom/subsystem_notif.h>
35#include "slim-msm.h"
36
37#define NGD_SLIM_NAME "ngd_msm_ctrl"
38#define SLIM_LA_MGR 0xFF
39#define SLIM_ROOT_FREQ 24576000
40#define LADDR_RETRY 5
41
42#define NGD_BASE_V1(r) (((r) % 2) ? 0x800 : 0xA00)
43#define NGD_BASE_V2(r) (((r) % 2) ? 0x1000 : 0x2000)
44#define NGD_BASE(r, v) ((v) ? NGD_BASE_V2(r) : NGD_BASE_V1(r))
45/* NGD (Non-ported Generic Device) registers */
46enum ngd_reg {
47 NGD_CFG = 0x0,
48 NGD_STATUS = 0x4,
49 NGD_RX_MSGQ_CFG = 0x8,
50 NGD_INT_EN = 0x10,
51 NGD_INT_STAT = 0x14,
52 NGD_INT_CLR = 0x18,
53 NGD_TX_MSG = 0x30,
54 NGD_RX_MSG = 0x70,
55 NGD_IE_STAT = 0xF0,
56 NGD_VE_STAT = 0x100,
57};
58
59enum ngd_msg_cfg {
60 NGD_CFG_ENABLE = 1,
61 NGD_CFG_RX_MSGQ_EN = 1 << 1,
62 NGD_CFG_TX_MSGQ_EN = 1 << 2,
63};
64
65enum ngd_intr {
66 NGD_INT_RECFG_DONE = 1 << 24,
67 NGD_INT_TX_NACKED_2 = 1 << 25,
68 NGD_INT_MSG_BUF_CONTE = 1 << 26,
69 NGD_INT_MSG_TX_INVAL = 1 << 27,
70 NGD_INT_IE_VE_CHG = 1 << 28,
71 NGD_INT_DEV_ERR = 1 << 29,
72 NGD_INT_RX_MSG_RCVD = 1 << 30,
73 NGD_INT_TX_MSG_SENT = 1 << 31,
74};
75
76enum ngd_offsets {
77 NGD_NACKED_MC = 0x7F00000,
78 NGD_ACKED_MC = 0xFE000,
79 NGD_ERROR = 0x1800,
80 NGD_MSGQ_SUPPORT = 0x400,
81 NGD_RX_MSGQ_TIME_OUT = 0x16,
82 NGD_ENUMERATED = 0x1,
83 NGD_TX_BUSY = 0x0,
84};
85
86enum ngd_status {
87 NGD_LADDR = 1 << 1,
88};
89
90static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf);
91static int ngd_slim_runtime_resume(struct device *device);
92static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);
93static void ngd_dom_down(struct msm_slim_ctrl *dev);
94static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
95 void *_cmd);
96
97static irqreturn_t ngd_slim_interrupt(int irq, void *d)
98{
99 struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)d;
100 void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
101 u32 stat = readl_relaxed(ngd + NGD_INT_STAT);
102 u32 pstat;
103
104 if ((stat & NGD_INT_MSG_BUF_CONTE) ||
105 (stat & NGD_INT_MSG_TX_INVAL) || (stat & NGD_INT_DEV_ERR) ||
106 (stat & NGD_INT_TX_NACKED_2)) {
107 writel_relaxed(stat, ngd + NGD_INT_CLR);
108 if (stat & NGD_INT_MSG_TX_INVAL)
109 dev->err = -EINVAL;
110 else
111 dev->err = -EIO;
112
113 SLIM_WARN(dev, "NGD interrupt error:0x%x, err:%d\n", stat,
114 dev->err);
115 /* Guarantee that error interrupts are cleared */
116 mb();
117 msm_slim_manage_tx_msgq(dev, false, NULL, dev->err);
118
119 } else if (stat & NGD_INT_TX_MSG_SENT) {
120 writel_relaxed(NGD_INT_TX_MSG_SENT, ngd + NGD_INT_CLR);
121 /* Make sure interrupt is cleared */
122 mb();
123 msm_slim_manage_tx_msgq(dev, false, NULL, 0);
124 }
125 if (stat & NGD_INT_RX_MSG_RCVD) {
126 u32 rx_buf[10];
127 u8 len, i;
128
129 rx_buf[0] = readl_relaxed(ngd + NGD_RX_MSG);
130 len = rx_buf[0] & 0x1F;
131 for (i = 1; i < ((len + 3) >> 2); i++) {
132 rx_buf[i] = readl_relaxed(ngd + NGD_RX_MSG +
133 (4 * i));
134 SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]);
135 }
136 writel_relaxed(NGD_INT_RX_MSG_RCVD,
137 ngd + NGD_INT_CLR);
138 /*
139 * Guarantee that CLR bit write goes through before
140 * queuing work
141 */
142 mb();
143 ngd_slim_rx(dev, (u8 *)rx_buf);
144 }
145 if (stat & NGD_INT_RECFG_DONE) {
146 writel_relaxed(NGD_INT_RECFG_DONE, ngd + NGD_INT_CLR);
147 /* Guarantee RECONFIG DONE interrupt is cleared */
148 mb();
149 /* In satellite mode, just log the reconfig done IRQ */
150 SLIM_DBG(dev, "reconfig done IRQ for NGD\n");
151 }
152 if (stat & NGD_INT_IE_VE_CHG) {
153 writel_relaxed(NGD_INT_IE_VE_CHG, ngd + NGD_INT_CLR);
154 /* Guarantee IE VE change interrupt is cleared */
155 mb();
156 SLIM_DBG(dev, "NGD IE VE change\n");
157 }
158
159 pstat = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_ST_EEn, dev->ver));
160 if (pstat != 0)
161 return msm_slim_port_irq_handler(dev, pstat);
162 return IRQ_HANDLED;
163}
164
165static int ngd_qmi_available(struct notifier_block *n, unsigned long code,
166 void *_cmd)
167{
168 struct msm_slim_qmi *qmi = container_of(n, struct msm_slim_qmi, nb);
169 struct msm_slim_ctrl *dev =
170 container_of(qmi, struct msm_slim_ctrl, qmi);
171 SLIM_INFO(dev, "Slimbus QMI NGD CB received event:%ld\n", code);
172 switch (code) {
173 case QMI_SERVER_ARRIVE:
174 atomic_set(&dev->ssr_in_progress, 0);
175 schedule_work(&dev->dsp.dom_up);
176 break;
177 default:
178 break;
179 }
180 return 0;
181}
182
183static void ngd_reg_ssr(struct msm_slim_ctrl *dev)
184{
185 int ret;
186 const char *subsys_name = NULL;
187
188 dev->dsp.dom_t = MSM_SLIM_DOM_NONE;
189 ret = of_property_read_string(dev->dev->of_node,
190 "qcom,subsys-name", &subsys_name);
191 if (ret)
192 subsys_name = "adsp";
193
194 dev->dsp.nb.notifier_call = dsp_domr_notify_cb;
195 dev->dsp.domr = subsys_notif_register_notifier(subsys_name,
196 &dev->dsp.nb);
197 if (IS_ERR_OR_NULL(dev->dsp.domr)) {
198 dev_err(dev->dev,
199 "subsys_notif_register_notifier failed %ld",
200 PTR_ERR(dev->dsp.domr));
201 return;
202 }
203 dev->dsp.dom_t = MSM_SLIM_DOM_SS;
204 SLIM_INFO(dev, "reg-SSR with:%s, PDR not available\n",
205 subsys_name);
206}
207
208static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
209 void *_cmd)
210{
211 int cur = -1;
212 struct msm_slim_ss *dsp = container_of(n, struct msm_slim_ss, nb);
213 struct msm_slim_ctrl *dev = container_of(dsp, struct msm_slim_ctrl,
214 dsp);
215 struct pd_qmi_client_data *reg;
216
Shrey Vijayab142792018-06-18 17:30:18 +0530217 /* Resetting the log level */
218 SLIM_RST_LOGLVL(dev);
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700219 SLIM_INFO(dev, "SLIM DSP SSR/PDR notify cb:0x%lx, type:%d\n",
220 code, dsp->dom_t);
221 switch (code) {
222 case SUBSYS_BEFORE_SHUTDOWN:
223 case SERVREG_NOTIF_SERVICE_STATE_DOWN_V01:
224 SLIM_INFO(dev, "SLIM DSP SSR notify cb:%lu\n", code);
225 atomic_set(&dev->ssr_in_progress, 1);
226 /* wait for current transaction */
227 mutex_lock(&dev->tx_lock);
228 /* make sure autosuspend is not called until ADSP comes up*/
229 pm_runtime_get_noresume(dev->dev);
230 dev->state = MSM_CTRL_DOWN;
Sagar Dhariaa4bfae12016-08-25 22:35:24 -0600231 dev->qmi.deferred_resp = false;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700232 msm_slim_sps_exit(dev, false);
233 ngd_dom_down(dev);
234 mutex_unlock(&dev->tx_lock);
235 break;
236 case LOCATOR_UP:
237 reg = _cmd;
238 if (!reg || reg->total_domains != 1) {
239 SLIM_WARN(dev, "error locating audio-PD\n");
240 if (reg)
241 SLIM_WARN(dev, "audio-PDs matched:%d\n",
242 reg->total_domains);
243
244 /* Fall back to SSR */
245 ngd_reg_ssr(dev);
246 return NOTIFY_DONE;
247 }
248 dev->dsp.domr = service_notif_register_notifier(
249 reg->domain_list->name,
250 reg->domain_list->instance_id,
251 &dev->dsp.nb,
252 &cur);
253 SLIM_INFO(dev, "reg-PD client:%s with service:%s\n",
254 reg->client_name, reg->service_name);
255 SLIM_INFO(dev, "reg-PD dom:%s instance:%d, cur:%d\n",
256 reg->domain_list->name,
257 reg->domain_list->instance_id, cur);
258 if (IS_ERR_OR_NULL(dev->dsp.domr))
259 ngd_reg_ssr(dev);
260 else
261 dev->dsp.dom_t = MSM_SLIM_DOM_PD;
262 break;
263 case LOCATOR_DOWN:
264 ngd_reg_ssr(dev);
265 default:
266 break;
267 }
268 return NOTIFY_DONE;
269}
270
271static void ngd_dom_init(struct msm_slim_ctrl *dev)
272{
273 struct pd_qmi_client_data reg;
274 int ret;
275
276 memset(&reg, 0, sizeof(struct pd_qmi_client_data));
277 dev->dsp.nb.priority = 4;
278 dev->dsp.nb.notifier_call = dsp_domr_notify_cb;
279 scnprintf(reg.client_name, QMI_SERVREG_LOC_NAME_LENGTH_V01, "appsngd%d",
280 dev->ctrl.nr);
281 scnprintf(reg.service_name, QMI_SERVREG_LOC_NAME_LENGTH_V01,
282 "avs/audio");
283 ret = get_service_location(reg.client_name, reg.service_name,
284 &dev->dsp.nb);
285 if (ret)
286 ngd_reg_ssr(dev);
287}
288
289static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code,
290 void *_cmd)
291{
292 void __iomem *ngd;
293 struct msm_slim_ss *ext_mdm = container_of(n, struct msm_slim_ss, nb);
294 struct msm_slim_ctrl *dev = container_of(ext_mdm, struct msm_slim_ctrl,
295 ext_mdm);
296 struct slim_controller *ctrl = &dev->ctrl;
297 u32 laddr;
298 struct slim_device *sbdev;
299
300 switch (code) {
301 case SUBSYS_BEFORE_SHUTDOWN:
302 SLIM_INFO(dev, "SLIM %lu external_modem SSR notify cb\n", code);
303 /* vote for runtime-pm so that ADSP doesn't go down */
304 msm_slim_get_ctrl(dev);
305 /*
306 * checking framer here will wake-up ADSP and may avoid framer
307 * handover later
308 */
309 msm_slim_qmi_check_framer_request(dev);
310 dev->ext_mdm.state = MSM_CTRL_DOWN;
311 msm_slim_put_ctrl(dev);
312 break;
313 case SUBSYS_AFTER_POWERUP:
314 if (dev->ext_mdm.state != MSM_CTRL_DOWN)
315 return NOTIFY_DONE;
316 SLIM_INFO(dev,
317 "SLIM %lu external_modem SSR notify cb\n", code);
318 /* vote for runtime-pm so that ADSP doesn't go down */
319 msm_slim_get_ctrl(dev);
320 msm_slim_qmi_check_framer_request(dev);
321 /* If NGD enumeration is lost, we will need to power us up */
322 ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
323 laddr = readl_relaxed(ngd + NGD_STATUS);
324 if (!(laddr & NGD_LADDR)) {
325 mutex_lock(&dev->tx_lock);
326 /* runtime-pm state should be consistent with HW */
327 pm_runtime_disable(dev->dev);
328 pm_runtime_set_suspended(dev->dev);
329 dev->state = MSM_CTRL_DOWN;
330 mutex_unlock(&dev->tx_lock);
331 SLIM_INFO(dev,
332 "SLIM MDM SSR (active framer on MDM) dev-down\n");
333 list_for_each_entry(sbdev, &ctrl->devs, dev_list)
334 slim_report_absent(sbdev);
335 ngd_slim_runtime_resume(dev->dev);
336 pm_runtime_set_active(dev->dev);
337 pm_runtime_enable(dev->dev);
338 }
339 dev->ext_mdm.state = MSM_CTRL_AWAKE;
340 msm_slim_put_ctrl(dev);
341 break;
342 default:
343 break;
344 }
345 return NOTIFY_DONE;
346}
347
348static int ngd_get_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn,
349 u8 *tid, struct completion *done)
350{
351 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
352 unsigned long flags;
353
354 spin_lock_irqsave(&ctrl->txn_lock, flags);
355 if (ctrl->last_tid <= 255) {
356 dev->msg_cnt = ctrl->last_tid;
357 ctrl->last_tid++;
358 } else {
359 int i;
360
361 for (i = 0; i < 256; i++) {
362 dev->msg_cnt = ((dev->msg_cnt + 1) & 0xFF);
363 if (ctrl->txnt[dev->msg_cnt] == NULL)
364 break;
365 }
366 if (i >= 256) {
367 dev_err(&ctrl->dev, "out of TID");
368 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
369 return -ENOMEM;
370 }
371 }
372 ctrl->txnt[dev->msg_cnt] = txn;
373 txn->tid = dev->msg_cnt;
374 txn->comp = done;
375 *tid = dev->msg_cnt;
376 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
377 return 0;
378}
379
380static void slim_reinit_tx_msgq(struct msm_slim_ctrl *dev)
381{
382 /*
383 * disconnect/recoonect pipe so that subsequent
384 * transactions don't timeout due to unavailable
385 * descriptors
386 */
387 if (dev->state != MSM_CTRL_DOWN) {
388 msm_slim_disconnect_endp(dev, &dev->tx_msgq,
389 &dev->use_tx_msgqs);
390 msm_slim_connect_endp(dev, &dev->tx_msgq);
391 }
392}
393
394static int ngd_check_hw_status(struct msm_slim_ctrl *dev)
395{
396 void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
397 u32 laddr = readl_relaxed(ngd + NGD_STATUS);
398 int ret = 0;
399
400 /* Lost logical addr due to noise */
401 if (!(laddr & NGD_LADDR)) {
402 SLIM_WARN(dev, "NGD lost LADDR: status:0x%x\n", laddr);
403 ret = ngd_slim_power_up(dev, false);
404
405 if (ret) {
406 SLIM_WARN(dev, "slim resume ret:%d, state:%d\n",
407 ret, dev->state);
408 ret = -EREMOTEIO;
409 }
410 }
411 return ret;
412}
413
414static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn)
415{
416 DECLARE_COMPLETION_ONSTACK(done);
417 DECLARE_COMPLETION_ONSTACK(tx_sent);
418
419 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
420 u32 *pbuf;
421 u8 *puc;
422 int ret = 0;
423 u8 la = txn->la;
424 u8 txn_mt;
425 u16 txn_mc = txn->mc;
426 u8 wbuf[SLIM_MSGQ_BUF_LEN];
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600427 const u8 *old_wbuf = NULL;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700428 bool report_sat = false;
429 bool sync_wr = true;
Shrey Vijayec24ad82018-04-10 15:05:31 +0530430 bool txn_async = txn->async;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700431
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600432 memset(wbuf, 0, sizeof(wbuf));
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700433 if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
434 return -EPROTONOSUPPORT;
435
436 if (txn->mt == SLIM_MSG_MT_CORE &&
437 (txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
438 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
439 return 0;
440
441 if (txn->mc == SLIM_USR_MC_REPORT_SATELLITE &&
442 txn->mt == SLIM_MSG_MT_SRC_REFERRED_USER)
443 report_sat = true;
444 else
445 mutex_lock(&dev->tx_lock);
446
447 if (!report_sat && !pm_runtime_enabled(dev->dev) &&
448 dev->state == MSM_CTRL_ASLEEP) {
449 /*
450 * Counter-part of system-suspend when runtime-pm is not enabled
451 * This way, resume can be left empty and device will be put in
452 * active mode only if client requests anything on the bus
453 * If the state was DOWN, SSR UP notification will take
454 * care of putting the device in active state.
455 */
456 mutex_unlock(&dev->tx_lock);
457 ret = ngd_slim_runtime_resume(dev->dev);
458
459 if (ret) {
460 SLIM_ERR(dev, "slim resume failed ret:%d, state:%d",
461 ret, dev->state);
462 return -EREMOTEIO;
463 }
464 mutex_lock(&dev->tx_lock);
465 }
466
467 /* If txn is tried when controller is down, wait for ADSP to boot */
468 if (!report_sat) {
469 if (dev->state == MSM_CTRL_DOWN) {
470 u8 mc = (u8)txn->mc;
471 int timeout;
472
473 mutex_unlock(&dev->tx_lock);
474 SLIM_INFO(dev, "ADSP slimbus not up yet\n");
475 /*
476 * Messages related to data channel management can't
477 * wait since they are holding reconfiguration lock.
478 * clk_pause in resume (which can change state back to
479 * MSM_CTRL_AWAKE), will need that lock.
480 * Port disconnection, channel removal calls should pass
481 * through since there is no activity on the bus and
482 * those calls are triggered by clients due to
483 * device_down callback in that situation.
484 * Returning 0 on the disconnections and
485 * removals will ensure consistent state of channels,
486 * ports with the HW
487 * Remote requests to remove channel/port will be
488 * returned from the path where they wait on
489 * acknowledgment from ADSP
490 */
491 if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
492 ((mc == SLIM_USR_MC_CHAN_CTRL ||
493 mc == SLIM_USR_MC_DISCONNECT_PORT ||
494 mc == SLIM_USR_MC_RECONFIG_NOW)))
495 return -EREMOTEIO;
496 if ((txn->mt == SLIM_MSG_MT_CORE) &&
497 ((mc == SLIM_MSG_MC_DISCONNECT_PORT ||
498 mc == SLIM_MSG_MC_NEXT_REMOVE_CHANNEL ||
499 mc == SLIM_USR_MC_RECONFIG_NOW)))
500 return 0;
501 if ((txn->mt == SLIM_MSG_MT_CORE) &&
502 ((mc >= SLIM_MSG_MC_CONNECT_SOURCE &&
503 mc <= SLIM_MSG_MC_CHANGE_CONTENT) ||
504 (mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
505 mc <= SLIM_MSG_MC_RECONFIGURE_NOW)))
506 return -EREMOTEIO;
507 if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
508 ((mc >= SLIM_USR_MC_DEFINE_CHAN &&
509 mc < SLIM_USR_MC_DISCONNECT_PORT)))
510 return -EREMOTEIO;
511 timeout = wait_for_completion_timeout(&dev->ctrl_up,
512 HZ);
513 if (!timeout)
514 return -ETIMEDOUT;
515 mutex_lock(&dev->tx_lock);
516 }
517
518 mutex_unlock(&dev->tx_lock);
519 ret = msm_slim_get_ctrl(dev);
520 mutex_lock(&dev->tx_lock);
521 /*
522 * Runtime-pm's callbacks are not called until runtime-pm's
523 * error status is cleared
524 * Setting runtime status to suspended clears the error
525 * It also makes HW status cosistent with what SW has it here
526 */
527 if ((pm_runtime_enabled(dev->dev) && ret < 0) ||
528 dev->state >= MSM_CTRL_ASLEEP) {
529 SLIM_ERR(dev, "slim ctrl vote failed ret:%d, state:%d",
530 ret, dev->state);
531 pm_runtime_set_suspended(dev->dev);
532 mutex_unlock(&dev->tx_lock);
533 msm_slim_put_ctrl(dev);
534 return -EREMOTEIO;
535 }
536 ret = ngd_check_hw_status(dev);
537 if (ret) {
538 mutex_unlock(&dev->tx_lock);
539 msm_slim_put_ctrl(dev);
540 return ret;
541 }
542 }
543
544 if (txn->mt == SLIM_MSG_MT_CORE &&
545 (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE ||
546 txn->mc == SLIM_MSG_MC_CONNECT_SINK ||
547 txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)) {
548 int i = 0;
549
550 if (txn->mc != SLIM_MSG_MC_DISCONNECT_PORT)
551 SLIM_INFO(dev,
552 "Connect port: laddr 0x%x port_num %d chan_num %d\n",
553 txn->la, txn->wbuf[0], txn->wbuf[1]);
554 else
555 SLIM_INFO(dev,
556 "Disconnect port: laddr 0x%x port_num %d\n",
557 txn->la, txn->wbuf[0]);
558 txn->mt = SLIM_MSG_MT_DEST_REFERRED_USER;
559 if (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE)
560 txn->mc = SLIM_USR_MC_CONNECT_SRC;
561 else if (txn->mc == SLIM_MSG_MC_CONNECT_SINK)
562 txn->mc = SLIM_USR_MC_CONNECT_SINK;
563 else if (txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)
564 txn->mc = SLIM_USR_MC_DISCONNECT_PORT;
565 if (txn->la == SLIM_LA_MGR) {
566 if (dev->pgdla == SLIM_LA_MGR) {
567 u8 ea[] = {0, QC_DEVID_PGD, 0, 0, QC_MFGID_MSB,
568 QC_MFGID_LSB};
569 ea[2] = (u8)(dev->pdata.eapc & 0xFF);
570 ea[3] = (u8)((dev->pdata.eapc & 0xFF00) >> 8);
571 mutex_unlock(&dev->tx_lock);
572 ret = dev->ctrl.get_laddr(&dev->ctrl, ea, 6,
573 &dev->pgdla);
574 SLIM_DBG(dev, "SLIM PGD LA:0x%x, ret:%d\n",
575 dev->pgdla, ret);
576 if (ret) {
577 SLIM_ERR(dev,
578 "Incorrect SLIM-PGD EAPC:0x%x\n",
579 dev->pdata.eapc);
580 return ret;
581 }
582 mutex_lock(&dev->tx_lock);
583 }
584 txn->la = dev->pgdla;
585 }
586 wbuf[i++] = txn->la;
587 la = SLIM_LA_MGR;
588 wbuf[i++] = txn->wbuf[0];
589 if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT)
590 wbuf[i++] = txn->wbuf[1];
591 ret = ngd_get_tid(ctrl, txn, &wbuf[i++], &done);
592 if (ret) {
593 SLIM_ERR(dev, "TID for connect/disconnect fail:%d\n",
594 ret);
595 goto ngd_xfer_err;
596 }
597 txn->len = i;
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600598 old_wbuf = txn->wbuf;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700599 txn->wbuf = wbuf;
600 txn->rl = txn->len + 4;
601 }
602 txn->rl--;
603
604 if (txn->len > SLIM_MSGQ_BUF_LEN || txn->rl > SLIM_MSGQ_BUF_LEN) {
605 SLIM_WARN(dev, "msg exeeds HW lim:%d, rl:%d, mc:0x%x, mt:0x%x",
606 txn->len, txn->rl, txn->mc, txn->mt);
607 ret = -EDQUOT;
608 goto ngd_xfer_err;
609 }
610
611 if (txn->mt == SLIM_MSG_MT_CORE && txn->comp &&
612 dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
613 (txn_mc != SLIM_MSG_MC_REQUEST_INFORMATION &&
614 txn_mc != SLIM_MSG_MC_REQUEST_VALUE &&
615 txn_mc != SLIM_MSG_MC_REQUEST_CHANGE_VALUE &&
616 txn_mc != SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION)) {
617 sync_wr = false;
618 pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
619 } else if (txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
620 dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
621 txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
622 txn->comp) {
623 sync_wr = false;
624 pbuf = msm_get_msg_buf(dev, txn->rl, txn->comp);
625 } else {
626 pbuf = msm_get_msg_buf(dev, txn->rl, &tx_sent);
627 }
628
629 if (!pbuf) {
630 SLIM_ERR(dev, "Message buffer unavailable\n");
631 ret = -ENOMEM;
632 goto ngd_xfer_err;
633 }
634 dev->err = 0;
635
636 if (txn->dt == SLIM_MSG_DEST_ENUMADDR) {
637 ret = -EPROTONOSUPPORT;
638 goto ngd_xfer_err;
639 }
640 if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
641 *pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
642 la);
643 else
644 *pbuf = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
645 la);
646 if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
647 puc = ((u8 *)pbuf) + 3;
648 else
649 puc = ((u8 *)pbuf) + 2;
650 if (txn->rbuf)
651 *(puc++) = txn->tid;
652 if (((txn->mt == SLIM_MSG_MT_CORE) &&
653 ((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
654 txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
655 (txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
656 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) ||
657 (txn->mc == SLIM_USR_MC_REPEAT_CHANGE_VALUE &&
658 txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER)) {
659 *(puc++) = (txn->ec & 0xFF);
660 *(puc++) = (txn->ec >> 8)&0xFF;
661 }
662 if (txn->wbuf)
663 memcpy(puc, txn->wbuf, txn->len);
664 if (txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
665 (txn->mc == SLIM_USR_MC_CONNECT_SRC ||
666 txn->mc == SLIM_USR_MC_CONNECT_SINK ||
667 txn->mc == SLIM_USR_MC_DISCONNECT_PORT) && txn->wbuf &&
668 wbuf[0] == dev->pgdla) {
669 if (txn->mc != SLIM_USR_MC_DISCONNECT_PORT)
670 dev->err = msm_slim_connect_pipe_port(dev, wbuf[1]);
671 else
672 writel_relaxed(0, PGD_PORT(PGD_PORT_CFGn,
673 (dev->pipes[wbuf[1]].port_b),
674 dev->ver));
675 if (dev->err) {
676 SLIM_ERR(dev, "pipe-port connect err:%d\n", dev->err);
677 goto ngd_xfer_err;
678 }
679 /* Add port-base to port number if this is manager side port */
680 puc[1] = (u8)dev->pipes[wbuf[1]].port_b;
681 }
682 dev->err = 0;
683 /*
684 * If it's a read txn, it may be freed if a response is received by
685 * received thread before reaching end of this function.
686 * mc, mt may have changed to convert standard slimbus code/type to
687 * satellite user-defined message. Reinitialize again
688 */
689 txn_mc = txn->mc;
690 txn_mt = txn->mt;
691 ret = msm_send_msg_buf(dev, pbuf, txn->rl,
692 NGD_BASE(dev->ctrl.nr, dev->ver) + NGD_TX_MSG);
693 if (!ret && sync_wr) {
694 int i;
695 int timeout = wait_for_completion_timeout(&tx_sent, HZ);
696
697 if (!timeout && dev->use_tx_msgqs == MSM_MSGQ_ENABLED) {
698 struct msm_slim_endp *endpoint = &dev->tx_msgq;
699 struct sps_mem_buffer *mem = &endpoint->buf;
700 u32 idx = (u32) (((u8 *)pbuf - (u8 *)mem->base) /
701 SLIM_MSGQ_BUF_LEN);
702 phys_addr_t addr = mem->phys_base +
703 (idx * SLIM_MSGQ_BUF_LEN);
704 ret = -ETIMEDOUT;
705 SLIM_WARN(dev, "timeout, BAM desc_idx:%d, phys:%llx",
706 idx, (u64)addr);
707 for (i = 0; i < (SLIM_MSGQ_BUF_LEN >> 2) ; i++)
708 SLIM_WARN(dev, "timeout:bam-desc[%d]:0x%x",
709 i, *(pbuf + i));
710 if (idx < MSM_TX_BUFS)
711 dev->wr_comp[idx] = NULL;
712 slim_reinit_tx_msgq(dev);
713 } else if (!timeout) {
714 ret = -ETIMEDOUT;
715 SLIM_WARN(dev, "timeout non-BAM TX,len:%d", txn->rl);
716 for (i = 0; i < (SLIM_MSGQ_BUF_LEN >> 2) ; i++)
717 SLIM_WARN(dev, "timeout:txbuf[%d]:0x%x", i,
718 dev->tx_buf[i]);
719 } else {
720 ret = dev->err;
721 }
722 }
723 if (ret) {
724 u32 conf, stat, rx_msgq, int_stat, int_en, int_clr;
725 void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr,
726 dev->ver);
727 SLIM_WARN(dev, "TX failed :MC:0x%x,mt:0x%x, ret:%d, ver:%d\n",
728 txn_mc, txn_mt, ret, dev->ver);
729 conf = readl_relaxed(ngd);
730 stat = readl_relaxed(ngd + NGD_STATUS);
731 rx_msgq = readl_relaxed(ngd + NGD_RX_MSGQ_CFG);
732 int_stat = readl_relaxed(ngd + NGD_INT_STAT);
733 int_en = readl_relaxed(ngd + NGD_INT_EN);
734 int_clr = readl_relaxed(ngd + NGD_INT_CLR);
735
736 SLIM_WARN(dev, "conf:0x%x,stat:0x%x,rxmsgq:0x%x\n",
737 conf, stat, rx_msgq);
738 SLIM_ERR(dev, "int_stat:0x%x,int_en:0x%x,int_cll:0x%x\n",
739 int_stat, int_en, int_clr);
740 }
741
742 if (txn_mt == SLIM_MSG_MT_DEST_REFERRED_USER &&
743 (txn_mc == SLIM_USR_MC_CONNECT_SRC ||
744 txn_mc == SLIM_USR_MC_CONNECT_SINK ||
745 txn_mc == SLIM_USR_MC_DISCONNECT_PORT)) {
746 int timeout;
747 unsigned long flags;
748
749 mutex_unlock(&dev->tx_lock);
750 msm_slim_put_ctrl(dev);
751 if (!ret) {
752 timeout = wait_for_completion_timeout(txn->comp, HZ);
753 /* remote side did not acknowledge */
754 if (!timeout)
755 ret = -EREMOTEIO;
756 else
757 ret = txn->ec;
758 }
759 if (ret) {
760 SLIM_ERR(dev,
761 "connect/disconnect:0x%x,tid:%d err:%d\n",
762 txn->mc, txn->tid, ret);
763 spin_lock_irqsave(&ctrl->txn_lock, flags);
764 ctrl->txnt[txn->tid] = NULL;
765 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
766 }
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600767 goto ngd_xfer_ret;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700768 }
769ngd_xfer_err:
770 if (!report_sat) {
771 mutex_unlock(&dev->tx_lock);
772 msm_slim_put_ctrl(dev);
773 }
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600774ngd_xfer_ret:
Shrey Vijayec24ad82018-04-10 15:05:31 +0530775 if (!txn_async && txn->wbuf == wbuf)
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600776 txn->wbuf = old_wbuf;
Shrey Vijayec24ad82018-04-10 15:05:31 +0530777 if (!txn_async && txn->comp == &done)
Karthikeyan Ramasubramanian8c1c5f52017-10-04 10:57:18 -0600778 txn->comp = NULL;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -0700779 return ret ? ret : dev->err;
780}
781
782static int ngd_get_ec(u16 start_offset, u8 len, u16 *ec)
783{
784 if (len > SLIM_MAX_VE_SLC_BYTES ||
785 start_offset > MSM_SLIM_VE_MAX_MAP_ADDR)
786 return -EINVAL;
787 if (len <= 4) {
788 *ec = len - 1;
789 } else if (len <= 8) {
790 if (len & 0x1)
791 return -EINVAL;
792 *ec = ((len >> 1) + 1);
793 } else {
794 if (len & 0x3)
795 return -EINVAL;
796 *ec = ((len >> 2) + 3);
797 }
798 *ec |= (0x8 | ((start_offset & 0xF) << 4));
799 *ec |= ((start_offset & 0xFF0) << 4);
800 return 0;
801}
802
803static int ngd_user_msg(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc,
804 struct slim_ele_access *msg, u8 *buf, u8 len)
805{
806 int ret;
807 struct slim_msg_txn txn;
808
809 if (mt != SLIM_MSG_MT_DEST_REFERRED_USER ||
810 mc != SLIM_USR_MC_REPEAT_CHANGE_VALUE) {
811 return -EPROTONOSUPPORT;
812 }
813
814 ret = ngd_get_ec(msg->start_offset, len, &txn.ec);
815 if (ret)
816 return ret;
817 txn.la = la;
818 txn.mt = mt;
819 txn.mc = mc;
820 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
821 txn.len = len;
822 txn.rl = len + 6;
823 txn.wbuf = buf;
824 txn.rbuf = NULL;
825 txn.comp = msg->comp;
826 return ngd_xfer_msg(ctrl, &txn);
827}
828
829static int ngd_bulk_cb(void *ctx, int err)
830{
831 if (ctx)
832 complete(ctx);
833 return err;
834}
835
836static int ngd_bulk_wr(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc,
837 struct slim_val_inf msgs[], int n,
838 int (*comp_cb)(void *ctx, int err), void *ctx)
839{
840 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
841 int i, ret;
842 struct msm_slim_endp *endpoint = &dev->tx_msgq;
843 u32 *header;
844 DECLARE_COMPLETION_ONSTACK(done);
845
846 ret = msm_slim_get_ctrl(dev);
847 mutex_lock(&dev->tx_lock);
848
849 if ((pm_runtime_enabled(dev->dev) && ret < 0) ||
850 dev->state >= MSM_CTRL_ASLEEP) {
851 SLIM_WARN(dev, "vote failed/SSR in-progress ret:%d, state:%d",
852 ret, dev->state);
853 pm_runtime_set_suspended(dev->dev);
854 mutex_unlock(&dev->tx_lock);
855 msm_slim_put_ctrl(dev);
856 return -EREMOTEIO;
857 }
858 if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP) {
859 mutex_unlock(&dev->tx_lock);
860 ret = ngd_slim_runtime_resume(dev->dev);
861
862 if (ret) {
863 SLIM_ERR(dev, "slim resume failed ret:%d, state:%d",
864 ret, dev->state);
865 return -EREMOTEIO;
866 }
867 mutex_lock(&dev->tx_lock);
868 }
869
870 ret = ngd_check_hw_status(dev);
871 if (ret) {
872 mutex_unlock(&dev->tx_lock);
873 msm_slim_put_ctrl(dev);
874 return ret;
875 }
876
877 if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
878 SLIM_WARN(dev, "bulk wr not supported");
879 ret = -EPROTONOSUPPORT;
880 goto retpath;
881 }
882 if (dev->bulk.in_progress) {
883 SLIM_WARN(dev, "bulk wr in progress:");
884 ret = -EAGAIN;
885 goto retpath;
886 }
887 dev->bulk.in_progress = true;
888 /* every txn has 5 bytes of overhead: la, mc, mt, ec, len */
889 dev->bulk.size = n * 5;
890 for (i = 0; i < n; i++) {
891 dev->bulk.size += msgs[i].num_bytes;
892 dev->bulk.size += (4 - ((msgs[i].num_bytes + 1) & 0x3));
893 }
894
895 if (dev->bulk.size > 0xffff) {
896 SLIM_WARN(dev, "len exceeds limit, split bulk and retry");
897 ret = -EDQUOT;
898 goto retpath;
899 }
900 if (dev->bulk.size > dev->bulk.buf_sz) {
901 void *temp = krealloc(dev->bulk.base, dev->bulk.size,
902 GFP_KERNEL | GFP_DMA);
903 if (!temp) {
904 ret = -ENOMEM;
905 goto retpath;
906 }
907 dev->bulk.base = temp;
908 dev->bulk.buf_sz = dev->bulk.size;
909 }
910
911 header = dev->bulk.base;
912 for (i = 0; i < n; i++) {
913 u8 *buf = (u8 *)header;
914 int rl = msgs[i].num_bytes + 5;
915 u16 ec;
916
917 *header = SLIM_MSG_ASM_FIRST_WORD(rl, mt, mc, 0, la);
918 buf += 3;
919 ret = ngd_get_ec(msgs[i].start_offset, msgs[i].num_bytes, &ec);
920 if (ret)
921 goto retpath;
922 *(buf++) = (ec & 0xFF);
923 *(buf++) = (ec >> 8) & 0xFF;
924 memcpy(buf, msgs[i].wbuf, msgs[i].num_bytes);
925 buf += msgs[i].num_bytes;
926 header += (rl >> 2);
927 if (rl & 3) {
928 header++;
929 memset(buf, 0, ((u8 *)header - buf));
930 }
931 }
932 header = dev->bulk.base;
933 if (comp_cb) {
934 dev->bulk.cb = comp_cb;
935 dev->bulk.ctx = ctx;
936 } else {
937 dev->bulk.cb = ngd_bulk_cb;
938 dev->bulk.ctx = &done;
939 }
940 dev->bulk.wr_dma = dma_map_single(dev->dev, dev->bulk.base,
941 dev->bulk.size, DMA_TO_DEVICE);
942 if (dma_mapping_error(dev->dev, dev->bulk.wr_dma)) {
943 ret = -ENOMEM;
944 goto retpath;
945 }
946
947 ret = sps_transfer_one(endpoint->sps, dev->bulk.wr_dma, dev->bulk.size,
948 NULL, SPS_IOVEC_FLAG_EOT);
949 if (ret) {
950 SLIM_WARN(dev, "sps transfer one returned error:%d", ret);
951 goto retpath;
952 }
953 if (dev->bulk.cb == ngd_bulk_cb) {
954 int timeout = wait_for_completion_timeout(&done, HZ);
955
956 if (!timeout) {
957 SLIM_WARN(dev, "timeout for bulk wr");
958 dma_unmap_single(dev->dev, dev->bulk.wr_dma,
959 dev->bulk.size, DMA_TO_DEVICE);
960 ret = -ETIMEDOUT;
961 }
962 }
963retpath:
964 if (ret) {
965 dev->bulk.in_progress = false;
966 dev->bulk.ctx = NULL;
967 dev->bulk.wr_dma = 0;
968 slim_reinit_tx_msgq(dev);
969 }
970 mutex_unlock(&dev->tx_lock);
971 msm_slim_put_ctrl(dev);
972 return ret;
973}
974
975static int ngd_xferandwait_ack(struct slim_controller *ctrl,
976 struct slim_msg_txn *txn)
977{
978 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
979 unsigned long flags;
980 int ret;
981
982 if (dev->state == MSM_CTRL_DOWN) {
983 /*
984 * no need to send anything to the bus due to SSR
985 * transactions related to channel removal marked as success
986 * since HW is down
987 */
988 if ((txn->mt == SLIM_MSG_MT_DEST_REFERRED_USER) &&
989 ((txn->mc >= SLIM_USR_MC_CHAN_CTRL &&
990 txn->mc <= SLIM_USR_MC_REQ_BW) ||
991 txn->mc == SLIM_USR_MC_DISCONNECT_PORT)) {
992 spin_lock_irqsave(&ctrl->txn_lock, flags);
993 ctrl->txnt[txn->tid] = NULL;
994 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
995 return 0;
996 }
997 }
998
999 ret = ngd_xfer_msg(ctrl, txn);
1000 if (!ret) {
1001 int timeout;
1002
1003 timeout = wait_for_completion_timeout(txn->comp, HZ);
1004 if (!timeout)
1005 ret = -ETIMEDOUT;
1006 else
1007 ret = txn->ec;
1008 }
1009
1010 if (ret) {
1011 if (ret != -EREMOTEIO || txn->mc != SLIM_USR_MC_CHAN_CTRL)
1012 SLIM_ERR(dev, "master msg:0x%x,tid:%d ret:%d\n",
1013 txn->mc, txn->tid, ret);
1014 spin_lock_irqsave(&ctrl->txn_lock, flags);
1015 ctrl->txnt[txn->tid] = NULL;
1016 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
1017 }
1018
1019 return ret;
1020}
1021
1022static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear)
1023{
1024 int ret = 0, num_chan = 0;
1025 struct slim_pending_ch *pch;
1026 struct slim_msg_txn txn;
1027 struct slim_controller *ctrl = sb->ctrl;
1028 DECLARE_COMPLETION_ONSTACK(done);
1029 u8 wbuf[SLIM_MSGQ_BUF_LEN];
1030 struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
1031
1032 *clkgear = ctrl->clkgear;
1033 *subfrmc = 0;
1034 txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
1035 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1036 txn.la = SLIM_LA_MGR;
1037 txn.len = 0;
1038 txn.ec = 0;
1039 txn.wbuf = wbuf;
1040 txn.rbuf = NULL;
1041
1042 if (ctrl->sched.msgsl != ctrl->sched.pending_msgsl) {
1043 SLIM_DBG(dev, "slim reserve BW for messaging: req: %d\n",
1044 ctrl->sched.pending_msgsl);
1045 txn.mc = SLIM_USR_MC_REQ_BW;
1046 wbuf[txn.len++] = ((sb->laddr & 0x1f) |
1047 ((u8)(ctrl->sched.pending_msgsl & 0x7) << 5));
1048 wbuf[txn.len++] = (u8)(ctrl->sched.pending_msgsl >> 3);
1049 ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
1050 if (ret)
1051 return ret;
1052 txn.rl = txn.len + 4;
1053 ret = ngd_xferandwait_ack(ctrl, &txn);
1054 if (ret)
1055 return ret;
1056
1057 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
1058 txn.len = 2;
1059 wbuf[1] = sb->laddr;
1060 txn.rl = txn.len + 4;
1061 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1062 if (ret)
1063 return ret;
1064 ret = ngd_xferandwait_ack(ctrl, &txn);
1065 if (ret)
1066 return ret;
1067
1068 txn.len = 0;
1069 }
1070 list_for_each_entry(pch, &sb->mark_define, pending) {
1071 struct slim_ich *slc;
1072
1073 slc = &ctrl->chans[pch->chan];
1074 if (!slc) {
1075 SLIM_WARN(dev, "no channel in define?\n");
1076 return -ENXIO;
1077 }
1078 if (txn.len == 0) {
1079 /* Per protocol, only last 5 bits for client no. */
1080 wbuf[txn.len++] = (u8) (slc->prop.dataf << 5) |
1081 (sb->laddr & 0x1f);
1082 wbuf[txn.len] = slc->prop.sampleszbits >> 2;
1083 if (slc->srch && slc->prop.prot == SLIM_PUSH)
1084 slc->prop.prot = SLIM_PULL;
1085 if (slc->coeff == SLIM_COEFF_3)
1086 wbuf[txn.len] |= 1 << 5;
1087 wbuf[txn.len++] |= slc->prop.auxf << 6;
1088 wbuf[txn.len++] = slc->rootexp << 4 | slc->prop.prot;
1089 wbuf[txn.len++] = slc->prrate;
1090 ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
1091 if (ret) {
1092 SLIM_WARN(dev, "no tid for channel define?\n");
1093 return -ENXIO;
1094 }
1095 }
1096 num_chan++;
1097 wbuf[txn.len++] = slc->chan;
1098 SLIM_INFO(dev, "slim activate chan:%d, laddr: 0x%x\n",
1099 slc->chan, sb->laddr);
1100 }
1101 if (txn.len) {
1102 txn.mc = SLIM_USR_MC_DEF_ACT_CHAN;
1103 txn.rl = txn.len + 4;
1104 ret = ngd_xferandwait_ack(ctrl, &txn);
1105 if (ret)
1106 return ret;
1107
1108 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
1109 txn.len = 2;
1110 wbuf[1] = sb->laddr;
1111 txn.rl = txn.len + 4;
1112 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1113 if (ret)
1114 return ret;
1115 ret = ngd_xferandwait_ack(ctrl, &txn);
1116 if (ret)
1117 return ret;
1118 }
1119 txn.len = 0;
1120 list_for_each_entry(pch, &sb->mark_removal, pending) {
1121 struct slim_ich *slc;
1122
1123 slc = &ctrl->chans[pch->chan];
1124 if (!slc) {
1125 SLIM_WARN(dev, "no channel in removal?\n");
1126 return -ENXIO;
1127 }
1128 if (txn.len == 0) {
1129 /* Per protocol, only last 5 bits for client no. */
1130 wbuf[txn.len++] = (u8) (SLIM_CH_REMOVE << 6) |
1131 (sb->laddr & 0x1f);
1132 ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done);
1133 if (ret) {
1134 SLIM_WARN(dev, "no tid for channel define?\n");
1135 return -ENXIO;
1136 }
1137 }
1138 wbuf[txn.len++] = slc->chan;
1139 SLIM_INFO(dev, "slim remove chan:%d, laddr: 0x%x\n",
1140 slc->chan, sb->laddr);
1141 }
1142 if (txn.len) {
1143 txn.mc = SLIM_USR_MC_CHAN_CTRL;
1144 txn.rl = txn.len + 4;
1145 ret = ngd_xferandwait_ack(ctrl, &txn);
1146 /* HW restarting, channel removal should succeed */
1147 if (ret == -EREMOTEIO)
1148 return 0;
1149 else if (ret)
1150 return ret;
1151
1152 txn.mc = SLIM_USR_MC_RECONFIG_NOW;
1153 txn.len = 2;
1154 wbuf[1] = sb->laddr;
1155 txn.rl = txn.len + 4;
1156 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1157 if (ret)
1158 return ret;
1159 ret = ngd_xferandwait_ack(ctrl, &txn);
1160 if (ret)
1161 return ret;
1162 txn.len = 0;
1163 }
1164 return 0;
1165}
1166
1167static int ngd_set_laddr(struct slim_controller *ctrl, const u8 *ea,
1168 u8 elen, u8 laddr)
1169{
1170 return 0;
1171}
1172
1173static int ngd_get_laddr(struct slim_controller *ctrl, const u8 *ea,
1174 u8 elen, u8 *laddr)
1175{
1176 int ret;
1177 u8 wbuf[10];
1178 struct slim_msg_txn txn;
1179 DECLARE_COMPLETION_ONSTACK(done);
1180
1181 txn.mt = SLIM_MSG_MT_DEST_REFERRED_USER;
1182 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1183 txn.la = SLIM_LA_MGR;
1184 txn.ec = 0;
1185 ret = ngd_get_tid(ctrl, &txn, &wbuf[0], &done);
1186 if (ret)
1187 return ret;
1188 memcpy(&wbuf[1], ea, elen);
1189 txn.mc = SLIM_USR_MC_ADDR_QUERY;
1190 txn.rl = 11;
1191 txn.len = 7;
1192 txn.wbuf = wbuf;
1193 txn.rbuf = NULL;
1194 ret = ngd_xferandwait_ack(ctrl, &txn);
1195 if (!ret && txn.la == 0xFF)
1196 ret = -ENXIO;
1197 else if (!ret)
1198 *laddr = txn.la;
1199 return ret;
1200}
1201
1202static void ngd_slim_setup(struct msm_slim_ctrl *dev)
1203{
1204 u32 new_cfg = NGD_CFG_ENABLE;
1205 u32 cfg = readl_relaxed(dev->base +
1206 NGD_BASE(dev->ctrl.nr, dev->ver));
1207 if (dev->state == MSM_CTRL_DOWN) {
1208 /* if called after SSR, cleanup and re-assign */
1209 if (dev->use_tx_msgqs != MSM_MSGQ_RESET)
1210 msm_slim_deinit_ep(dev, &dev->tx_msgq,
1211 &dev->use_tx_msgqs);
1212
1213 if (dev->use_rx_msgqs != MSM_MSGQ_RESET)
1214 msm_slim_deinit_ep(dev, &dev->rx_msgq,
1215 &dev->use_rx_msgqs);
1216
1217 msm_slim_sps_init(dev, dev->bam_mem,
1218 NGD_BASE(dev->ctrl.nr,
1219 dev->ver) + NGD_STATUS, true);
1220 } else {
1221 if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
1222 goto setup_tx_msg_path;
1223
1224 if ((dev->use_rx_msgqs == MSM_MSGQ_ENABLED) &&
1225 (cfg & NGD_CFG_RX_MSGQ_EN))
1226 goto setup_tx_msg_path;
1227
1228 if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
1229 msm_slim_disconnect_endp(dev, &dev->rx_msgq,
1230 &dev->use_rx_msgqs);
1231 msm_slim_connect_endp(dev, &dev->rx_msgq);
1232
1233setup_tx_msg_path:
1234 if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED)
1235 goto ngd_enable;
1236 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED &&
1237 cfg & NGD_CFG_TX_MSGQ_EN)
1238 goto ngd_enable;
1239
1240 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
1241 msm_slim_disconnect_endp(dev, &dev->tx_msgq,
1242 &dev->use_tx_msgqs);
1243 msm_slim_connect_endp(dev, &dev->tx_msgq);
1244 }
1245ngd_enable:
1246
1247 if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
1248 new_cfg |= NGD_CFG_RX_MSGQ_EN;
1249 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
1250 new_cfg |= NGD_CFG_TX_MSGQ_EN;
1251
1252 /* Enable NGD, and program MSGQs if not already */
1253 if (cfg == new_cfg)
1254 return;
1255
1256 writel_relaxed(new_cfg, dev->base + NGD_BASE(dev->ctrl.nr, dev->ver));
1257 /* make sure NGD MSG-Q config goes through */
1258 mb();
1259}
1260
1261static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf)
1262{
1263 unsigned long flags;
1264 u8 mc, mt, len;
1265
1266 len = buf[0] & 0x1F;
1267 mt = (buf[0] >> 5) & 0x7;
1268 mc = buf[1];
1269 if (mc == SLIM_USR_MC_MASTER_CAPABILITY &&
1270 mt == SLIM_MSG_MT_SRC_REFERRED_USER)
1271 complete(&dev->rx_msgq_notify);
1272
1273 if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
1274 mc == SLIM_MSG_MC_REPLY_VALUE) {
1275 u8 tid = buf[3];
1276
1277 dev_dbg(dev->dev, "tid:%d, len:%d\n", tid, len);
1278 slim_msg_response(&dev->ctrl, &buf[4], tid,
1279 len - 4);
1280 pm_runtime_mark_last_busy(dev->dev);
1281 }
1282 if (mc == SLIM_USR_MC_ADDR_REPLY &&
1283 mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
1284 struct slim_msg_txn *txn;
1285 u8 failed_ea[6] = {0, 0, 0, 0, 0, 0};
1286
1287 spin_lock_irqsave(&dev->ctrl.txn_lock, flags);
1288 txn = dev->ctrl.txnt[buf[3]];
1289 if (!txn) {
1290 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1291 SLIM_WARN(dev,
1292 "LADDR response after timeout, tid:0x%x\n",
1293 buf[3]);
1294 return;
1295 }
1296 if (memcmp(&buf[4], failed_ea, 6))
1297 txn->la = buf[10];
1298 dev->ctrl.txnt[buf[3]] = NULL;
1299 complete(txn->comp);
1300 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1301 }
1302 if (mc == SLIM_USR_MC_GENERIC_ACK &&
1303 mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
1304 struct slim_msg_txn *txn;
1305
1306 spin_lock_irqsave(&dev->ctrl.txn_lock, flags);
1307 txn = dev->ctrl.txnt[buf[3]];
1308 if (!txn) {
1309 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1310 SLIM_WARN(dev, "ACK received after timeout, tid:0x%x\n",
1311 buf[3]);
1312 return;
1313 }
1314 dev_dbg(dev->dev, "got response:tid:%d, response:0x%x",
1315 (int)buf[3], buf[4]);
1316 if (!(buf[4] & MSM_SAT_SUCCSS)) {
1317 SLIM_WARN(dev, "TID:%d, NACK code:0x%x\n", (int)buf[3],
1318 buf[4]);
1319 txn->ec = -EIO;
1320 }
1321 dev->ctrl.txnt[buf[3]] = NULL;
1322 complete(txn->comp);
1323 spin_unlock_irqrestore(&dev->ctrl.txn_lock, flags);
1324 }
1325}
1326
1327static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart)
1328{
1329 void __iomem *ngd;
1330 int timeout, retries = 0, ret = 0;
1331 enum msm_ctrl_state cur_state = dev->state;
1332 u32 laddr;
1333 u32 rx_msgq;
1334 u32 ngd_int = (NGD_INT_TX_NACKED_2 |
1335 NGD_INT_MSG_BUF_CONTE | NGD_INT_MSG_TX_INVAL |
1336 NGD_INT_IE_VE_CHG | NGD_INT_DEV_ERR |
1337 NGD_INT_TX_MSG_SENT);
1338
1339 if (!mdm_restart && cur_state == MSM_CTRL_DOWN) {
1340 int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp,
1341 HZ);
1342 if (!timeout) {
1343 SLIM_ERR(dev, "slimbus QMI init timed out\n");
1344 return -EREMOTEIO;
1345 }
1346 }
1347
1348hw_init_retry:
1349 /* No need to vote if contorller is not in low power mode */
1350 if (!mdm_restart &&
1351 (cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP)) {
1352 ret = msm_slim_qmi_power_request(dev, true);
1353 if (ret) {
1354 SLIM_WARN(dev, "SLIM power req failed:%d, retry:%d\n",
1355 ret, retries);
1356 if (!atomic_read(&dev->ssr_in_progress))
1357 msm_slim_qmi_power_request(dev, false);
1358 if (retries < INIT_MX_RETRIES &&
1359 !atomic_read(&dev->ssr_in_progress)) {
1360 retries++;
1361 goto hw_init_retry;
1362 }
1363 return ret;
1364 }
1365 }
1366 retries = 0;
1367
1368 if (!dev->ver) {
1369 dev->ver = readl_relaxed(dev->base);
1370 /* Version info in 16 MSbits */
1371 dev->ver >>= 16;
1372 }
1373 ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver);
1374 laddr = readl_relaxed(ngd + NGD_STATUS);
1375 if (laddr & NGD_LADDR) {
1376 u32 int_en = readl_relaxed(ngd + NGD_INT_EN);
1377
1378 /*
1379 * external MDM restart case where ADSP itself was active framer
1380 * For example, modem restarted when playback was active
1381 */
1382 if (cur_state == MSM_CTRL_AWAKE) {
1383 SLIM_INFO(dev, "Subsys restart: ADSP active framer\n");
1384 return 0;
1385 }
1386 /*
1387 * ADSP power collapse case, where HW wasn't reset.
1388 */
1389 if (int_en != 0)
1390 return 0;
1391
1392 /* Retention */
1393 if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
1394 msm_slim_disconnect_endp(dev, &dev->rx_msgq,
1395 &dev->use_rx_msgqs);
1396 if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
1397 msm_slim_disconnect_endp(dev, &dev->tx_msgq,
1398 &dev->use_tx_msgqs);
1399
1400 writel_relaxed(ngd_int, (dev->base + NGD_INT_EN +
1401 NGD_BASE(dev->ctrl.nr, dev->ver)));
1402
1403 rx_msgq = readl_relaxed(ngd + NGD_RX_MSGQ_CFG);
1404 /**
1405 * Program with minimum value so that signal get
1406 * triggered immediately after receiving the message
1407 */
1408 writel_relaxed((rx_msgq | SLIM_RX_MSGQ_TIMEOUT_VAL),
1409 (ngd + NGD_RX_MSGQ_CFG));
1410 /* reconnect BAM pipes if needed and enable NGD */
1411 ngd_slim_setup(dev);
1412 return 0;
1413 }
1414
1415 if (mdm_restart) {
1416 /*
1417 * external MDM SSR when MDM is active framer
1418 * ADSP will reset slimbus HW. disconnect BAM pipes so that
1419 * they can be connected after capability message is received.
1420 * Set device state to ASLEEP to be synchronous with the HW
1421 */
1422 /* make current state as DOWN */
1423 cur_state = MSM_CTRL_DOWN;
1424 SLIM_INFO(dev,
1425 "SLIM MDM restart: MDM active framer: reinit HW\n");
1426 /* disconnect BAM pipes */
1427 msm_slim_sps_exit(dev, false);
1428 dev->state = MSM_CTRL_DOWN;
1429 }
1430
1431capability_retry:
1432 /*
1433 * ADSP power collapse case (OR SSR), where HW was reset
1434 * BAM programming will happen when capability message is received
1435 */
1436 writel_relaxed(ngd_int, dev->base + NGD_INT_EN +
1437 NGD_BASE(dev->ctrl.nr, dev->ver));
1438
1439 rx_msgq = readl_relaxed(ngd + NGD_RX_MSGQ_CFG);
1440 /*
1441 * Program with minimum value so that signal get
1442 * triggered immediately after receiving the message
1443 */
1444 writel_relaxed(rx_msgq|SLIM_RX_MSGQ_TIMEOUT_VAL,
1445 ngd + NGD_RX_MSGQ_CFG);
1446 /* make sure register got updated */
1447 mb();
1448
1449 /* reconnect BAM pipes if needed and enable NGD */
1450 ngd_slim_setup(dev);
1451
1452 timeout = wait_for_completion_timeout(&dev->reconf, HZ);
1453 if (!timeout) {
1454 u32 cfg = readl_relaxed(dev->base +
1455 NGD_BASE(dev->ctrl.nr, dev->ver));
1456 laddr = readl_relaxed(ngd + NGD_STATUS);
1457 SLIM_WARN(dev,
1458 "slim capability time-out:%d, stat:0x%x,cfg:0x%x\n",
1459 retries, laddr, cfg);
1460 if ((retries < INIT_MX_RETRIES) &&
1461 !atomic_read(&dev->ssr_in_progress)) {
1462 retries++;
1463 goto capability_retry;
1464 }
1465 return -ETIMEDOUT;
1466 }
1467 /* mutliple transactions waiting on slimbus to power up? */
1468 if (cur_state == MSM_CTRL_DOWN)
1469 complete_all(&dev->ctrl_up);
1470 /* Resetting the log level */
1471 SLIM_RST_LOGLVL(dev);
1472 return 0;
1473}
1474
1475static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable)
1476{
1477 int ret = 0;
1478
1479 if (enable) {
1480 ret = msm_slim_qmi_init(dev, false);
1481 /* controller state should be in sync with framework state */
1482 if (!ret) {
1483 complete(&dev->qmi.qmi_comp);
1484 if (!pm_runtime_enabled(dev->dev) ||
1485 !pm_runtime_suspended(dev->dev))
1486 ngd_slim_runtime_resume(dev->dev);
1487 else
1488 pm_runtime_resume(dev->dev);
1489 pm_runtime_mark_last_busy(dev->dev);
1490 pm_runtime_put(dev->dev);
1491 } else
1492 SLIM_ERR(dev, "qmi init fail, ret:%d, state:%d\n",
1493 ret, dev->state);
1494 } else {
1495 msm_slim_qmi_exit(dev);
1496 }
1497
1498 return ret;
1499}
1500
1501#ifdef CONFIG_PM
1502static int ngd_slim_power_down(struct msm_slim_ctrl *dev)
1503{
1504 unsigned long flags;
1505 int i;
1506 struct slim_controller *ctrl = &dev->ctrl;
1507
1508 spin_lock_irqsave(&ctrl->txn_lock, flags);
1509 /* Pending response for a message */
1510 for (i = 0; i < ctrl->last_tid; i++) {
1511 if (ctrl->txnt[i]) {
1512 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
1513 SLIM_INFO(dev, "NGD down:txn-rsp for %d pending", i);
1514 return -EBUSY;
1515 }
1516 }
1517 spin_unlock_irqrestore(&ctrl->txn_lock, flags);
1518 return msm_slim_qmi_power_request(dev, false);
1519}
1520#endif
1521
1522static int ngd_slim_rx_msgq_thread(void *data)
1523{
1524 struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data;
1525 struct completion *notify = &dev->rx_msgq_notify;
1526 int ret = 0;
1527
1528 while (!kthread_should_stop()) {
1529 struct slim_msg_txn txn;
1530 int retries = 0;
1531 u8 wbuf[8];
1532
1533 wait_for_completion_interruptible(notify);
1534
1535 txn.dt = SLIM_MSG_DEST_LOGICALADDR;
1536 txn.ec = 0;
1537 txn.rbuf = NULL;
1538 txn.mc = SLIM_USR_MC_REPORT_SATELLITE;
1539 txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
1540 txn.la = SLIM_LA_MGR;
1541 wbuf[0] = SAT_MAGIC_LSB;
1542 wbuf[1] = SAT_MAGIC_MSB;
1543 wbuf[2] = SAT_MSG_VER;
1544 wbuf[3] = SAT_MSG_PROT;
1545 txn.wbuf = wbuf;
1546 txn.len = 4;
1547 SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n");
1548capability_retry:
1549 txn.rl = 8;
1550 ret = ngd_xfer_msg(&dev->ctrl, &txn);
1551 if (!ret) {
1552 enum msm_ctrl_state prev_state = dev->state;
1553
1554 SLIM_INFO(dev,
1555 "SLIM SAT: capability exchange successful\n");
1556 if (prev_state < MSM_CTRL_ASLEEP)
1557 SLIM_WARN(dev,
1558 "capability due to noise, state:%d\n",
1559 prev_state);
1560 complete(&dev->reconf);
1561 /* ADSP SSR, send device_up notifications */
1562 if (prev_state == MSM_CTRL_DOWN)
1563 complete(&dev->qmi.slave_notify);
1564 } else if (ret == -EIO) {
1565 SLIM_WARN(dev, "capability message NACKed, retrying\n");
1566 if (retries < INIT_MX_RETRIES) {
1567 msleep(DEF_RETRY_MS);
1568 retries++;
1569 goto capability_retry;
1570 }
1571 } else {
1572 SLIM_WARN(dev, "SLIM: capability TX failed:%d\n", ret);
1573 }
1574 }
1575 return 0;
1576}
1577
1578static int ngd_notify_slaves(void *data)
1579{
1580 struct msm_slim_ctrl *dev = (struct msm_slim_ctrl *)data;
1581 struct slim_controller *ctrl = &dev->ctrl;
1582 struct slim_device *sbdev;
1583 struct list_head *pos, *next;
1584 int ret, i = 0;
1585
1586 ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
1587 SLIMBUS_QMI_SVC_V1,
1588 SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
1589 if (ret) {
1590 pr_err("Slimbus QMI service registration failed:%d", ret);
1591 return ret;
1592 }
1593
1594 while (!kthread_should_stop()) {
1595 wait_for_completion_interruptible(&dev->qmi.slave_notify);
1596 /* Probe devices for first notification */
1597 if (!i) {
1598 i++;
1599 dev->err = 0;
1600 if (dev->dev->of_node)
1601 of_register_slim_devices(&dev->ctrl);
1602
1603 /*
1604 * Add devices registered with board-info now that
1605 * controller is up
1606 */
1607 slim_ctrl_add_boarddevs(&dev->ctrl);
1608 ngd_dom_init(dev);
1609 } else {
1610 slim_framer_booted(ctrl);
1611 }
1612 mutex_lock(&ctrl->m_ctrl);
1613 list_for_each_safe(pos, next, &ctrl->devs) {
1614 int j;
1615
1616 sbdev = list_entry(pos, struct slim_device, dev_list);
1617 mutex_unlock(&ctrl->m_ctrl);
1618 for (j = 0; j < LADDR_RETRY; j++) {
1619 ret = slim_get_logical_addr(sbdev,
1620 sbdev->e_addr,
1621 6, &sbdev->laddr);
1622 if (!ret)
1623 break;
1624 /* time for ADSP to assign LA */
1625 msleep(20);
1626 }
1627 mutex_lock(&ctrl->m_ctrl);
1628 }
1629 mutex_unlock(&ctrl->m_ctrl);
1630 }
1631 return 0;
1632}
1633
1634static void ngd_dom_down(struct msm_slim_ctrl *dev)
1635{
1636 struct slim_controller *ctrl = &dev->ctrl;
1637 struct slim_device *sbdev;
1638
1639 mutex_lock(&dev->ssr_lock);
1640 ngd_slim_enable(dev, false);
1641 /* device up should be called again after SSR */
1642 list_for_each_entry(sbdev, &ctrl->devs, dev_list)
1643 slim_report_absent(sbdev);
1644 SLIM_INFO(dev, "SLIM ADSP SSR (DOWN) done\n");
1645 mutex_unlock(&dev->ssr_lock);
1646}
1647
1648static void ngd_dom_up(struct work_struct *work)
1649{
1650 struct msm_slim_ss *dsp =
1651 container_of(work, struct msm_slim_ss, dom_up);
1652 struct msm_slim_ctrl *dev =
1653 container_of(dsp, struct msm_slim_ctrl, dsp);
1654 mutex_lock(&dev->ssr_lock);
1655 ngd_slim_enable(dev, true);
1656 mutex_unlock(&dev->ssr_lock);
1657}
1658
1659static ssize_t show_mask(struct device *device, struct device_attribute *attr,
1660 char *buf)
1661{
1662 struct platform_device *pdev = to_platform_device(device);
1663 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1664
1665 return snprintf(buf, sizeof(int), "%u\n", dev->ipc_log_mask);
1666}
1667
1668static ssize_t set_mask(struct device *device, struct device_attribute *attr,
1669 const char *buf, size_t count)
1670{
1671 struct platform_device *pdev = to_platform_device(device);
1672 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1673
1674 dev->ipc_log_mask = buf[0] - '0';
1675 if (dev->ipc_log_mask > DBG_LEV)
1676 dev->ipc_log_mask = DBG_LEV;
1677 return count;
1678}
1679
1680static DEVICE_ATTR(debug_mask, 0644, show_mask, set_mask);
1681
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -06001682static const struct of_device_id ngd_slim_dt_match[] = {
1683 {
1684 .compatible = "qcom,slim-ngd",
1685 },
1686 {
1687 .compatible = "qcom,iommu-slim-ctrl-cb",
1688 },
1689 {}
1690};
1691
1692static int ngd_slim_iommu_probe(struct device *dev)
1693{
1694 struct platform_device *pdev;
1695 struct msm_slim_ctrl *ctrl_dev;
1696
1697 if (unlikely(!dev->parent)) {
1698 dev_err(dev, "%s no parent for this device\n", __func__);
1699 return -EINVAL;
1700 }
1701
1702 pdev = to_platform_device(dev->parent);
1703 if (!pdev) {
1704 dev_err(dev, "%s Parent platform device not found\n", __func__);
1705 return -EINVAL;
1706 }
1707
1708 ctrl_dev = platform_get_drvdata(pdev);
1709 if (!ctrl_dev) {
1710 dev_err(dev, "%s NULL controller device\n", __func__);
1711 return -EINVAL;
1712
1713 }
1714 ctrl_dev->iommu_desc.cb_dev = dev;
1715 SLIM_INFO(ctrl_dev, "NGD IOMMU initialization complete\n");
1716 return 0;
1717}
1718
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001719static int ngd_slim_probe(struct platform_device *pdev)
1720{
1721 struct msm_slim_ctrl *dev;
1722 int ret;
1723 struct resource *bam_mem;
1724 struct resource *slim_mem;
1725 struct resource *irq, *bam_irq;
1726 bool rxreg_access = false;
1727 bool slim_mdm = false;
1728 const char *ext_modem_id = NULL;
1729
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -06001730 if (of_device_is_compatible(pdev->dev.of_node,
1731 "qcom,iommu-slim-ctrl-cb"))
1732 return ngd_slim_iommu_probe(&pdev->dev);
1733
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001734 slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1735 "slimbus_physical");
1736 if (!slim_mem) {
1737 dev_err(&pdev->dev, "no slimbus physical memory resource\n");
1738 return -ENODEV;
1739 }
1740 bam_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1741 "slimbus_bam_physical");
1742 if (!bam_mem) {
1743 dev_err(&pdev->dev, "no slimbus BAM memory resource\n");
1744 return -ENODEV;
1745 }
1746 irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1747 "slimbus_irq");
1748 if (!irq) {
1749 dev_err(&pdev->dev, "no slimbus IRQ resource\n");
1750 return -ENODEV;
1751 }
1752 bam_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1753 "slimbus_bam_irq");
1754 if (!bam_irq) {
1755 dev_err(&pdev->dev, "no slimbus BAM IRQ resource\n");
1756 return -ENODEV;
1757 }
1758
1759 dev = kzalloc(sizeof(struct msm_slim_ctrl), GFP_KERNEL);
1760 if (IS_ERR_OR_NULL(dev)) {
1761 dev_err(&pdev->dev, "no memory for MSM slimbus controller\n");
1762 return PTR_ERR(dev);
1763 }
1764 dev->wr_comp = kzalloc(sizeof(struct completion *) * MSM_TX_BUFS,
1765 GFP_KERNEL);
Karthikeyan Ramasubramanian26182ce2017-01-17 10:15:00 -07001766 if (!dev->wr_comp) {
1767 ret = -ENOMEM;
1768 goto err_nobulk;
1769 }
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001770
1771 /* typical txn numbers and size used in bulk operation */
1772 dev->bulk.buf_sz = SLIM_MAX_TXNS * 8;
1773 dev->bulk.base = kzalloc(dev->bulk.buf_sz, GFP_KERNEL | GFP_DMA);
1774 if (!dev->bulk.base) {
1775 ret = -ENOMEM;
1776 goto err_nobulk;
1777 }
1778
1779 dev->dev = &pdev->dev;
1780 platform_set_drvdata(pdev, dev);
1781 slim_set_ctrldata(&dev->ctrl, dev);
1782
1783 /* Create IPC log context */
1784 dev->ipc_slimbus_log = ipc_log_context_create(IPC_SLIMBUS_LOG_PAGES,
1785 dev_name(dev->dev), 0);
1786 if (!dev->ipc_slimbus_log)
1787 dev_err(&pdev->dev, "error creating ipc_logging context\n");
1788 else {
1789 /* Initialize the log mask */
1790 dev->ipc_log_mask = INFO_LEV;
1791 dev->default_ipc_log_mask = INFO_LEV;
1792 SLIM_INFO(dev, "start logging for slim dev %s\n",
1793 dev_name(dev->dev));
1794 }
1795 ret = sysfs_create_file(&dev->dev->kobj, &dev_attr_debug_mask.attr);
1796 if (ret) {
1797 dev_err(&pdev->dev, "Failed to create dev. attr\n");
1798 dev->sysfs_created = false;
1799 } else
1800 dev->sysfs_created = true;
1801
1802 dev->base = ioremap(slim_mem->start, resource_size(slim_mem));
1803 if (!dev->base) {
1804 dev_err(&pdev->dev, "IOremap failed\n");
1805 ret = -ENOMEM;
1806 goto err_ioremap_failed;
1807 }
1808 dev->bam.base = ioremap(bam_mem->start, resource_size(bam_mem));
1809 if (!dev->bam.base) {
1810 dev_err(&pdev->dev, "BAM IOremap failed\n");
1811 ret = -ENOMEM;
1812 goto err_ioremap_bam_failed;
1813 }
1814 if (pdev->dev.of_node) {
1815
1816 ret = of_property_read_u32(pdev->dev.of_node, "cell-index",
1817 &dev->ctrl.nr);
1818 if (ret) {
1819 dev_err(&pdev->dev, "Cell index not specified:%d", ret);
1820 goto err_ctrl_failed;
1821 }
1822 rxreg_access = of_property_read_bool(pdev->dev.of_node,
1823 "qcom,rxreg-access");
1824 of_property_read_u32(pdev->dev.of_node, "qcom,apps-ch-pipes",
1825 &dev->pdata.apps_pipes);
1826 of_property_read_u32(pdev->dev.of_node, "qcom,ea-pc",
1827 &dev->pdata.eapc);
1828 ret = of_property_read_string(pdev->dev.of_node,
1829 "qcom,slim-mdm", &ext_modem_id);
1830 if (!ret)
1831 slim_mdm = true;
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -06001832
1833 dev->iommu_desc.s1_bypass = of_property_read_bool(
1834 pdev->dev.of_node,
1835 "qcom,iommu-s1-bypass");
1836 ret = of_platform_populate(pdev->dev.of_node, ngd_slim_dt_match,
1837 NULL, &pdev->dev);
1838 if (ret) {
1839 dev_err(dev->dev, "%s: Failed to of_platform_populate %d\n",
1840 __func__, ret);
1841 goto err_ctrl_failed;
1842 }
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001843 } else {
1844 dev->ctrl.nr = pdev->id;
1845 }
1846 /*
1847 * Keep PGD's logical address as manager's. Query it when first data
1848 * channel request comes in
1849 */
1850 dev->pgdla = SLIM_LA_MGR;
1851 dev->ctrl.nchans = MSM_SLIM_NCHANS;
1852 dev->ctrl.nports = MSM_SLIM_NPORTS;
1853 dev->framer.rootfreq = SLIM_ROOT_FREQ >> 3;
1854 dev->framer.superfreq =
1855 dev->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8;
1856 dev->ctrl.a_framer = &dev->framer;
1857 dev->ctrl.clkgear = SLIM_MAX_CLK_GEAR;
1858 dev->ctrl.set_laddr = ngd_set_laddr;
1859 dev->ctrl.get_laddr = ngd_get_laddr;
1860 dev->ctrl.allocbw = ngd_allocbw;
1861 dev->ctrl.xfer_msg = ngd_xfer_msg;
1862 dev->ctrl.xfer_user_msg = ngd_user_msg;
1863 dev->ctrl.xfer_bulk_wr = ngd_bulk_wr;
1864 dev->ctrl.wakeup = NULL;
1865 dev->ctrl.alloc_port = msm_alloc_port;
1866 dev->ctrl.dealloc_port = msm_dealloc_port;
1867 dev->ctrl.port_xfer = msm_slim_port_xfer;
1868 dev->ctrl.port_xfer_status = msm_slim_port_xfer_status;
1869 dev->bam_mem = bam_mem;
1870 dev->rx_slim = ngd_slim_rx;
1871
1872 init_completion(&dev->reconf);
1873 init_completion(&dev->ctrl_up);
1874 mutex_init(&dev->tx_lock);
1875 mutex_init(&dev->ssr_lock);
1876 spin_lock_init(&dev->tx_buf_lock);
1877 spin_lock_init(&dev->rx_lock);
1878 dev->ee = 1;
1879 dev->irq = irq->start;
1880 dev->bam.irq = bam_irq->start;
1881 atomic_set(&dev->ssr_in_progress, 0);
1882
1883 if (rxreg_access)
1884 dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
1885 else
1886 dev->use_rx_msgqs = MSM_MSGQ_RESET;
1887
1888 /* Enable TX message queues by default as recommended by HW */
1889 dev->use_tx_msgqs = MSM_MSGQ_RESET;
1890
1891 init_completion(&dev->rx_msgq_notify);
1892 init_completion(&dev->qmi.slave_notify);
1893
1894 /* Register with framework */
1895 ret = slim_add_numbered_controller(&dev->ctrl);
1896 if (ret) {
1897 dev_err(dev->dev, "error adding controller\n");
1898 goto err_ctrl_failed;
1899 }
1900
1901 dev->ctrl.dev.parent = &pdev->dev;
1902 dev->ctrl.dev.of_node = pdev->dev.of_node;
1903 dev->state = MSM_CTRL_DOWN;
1904
1905 /*
1906 * As this does not perform expensive
1907 * operations, it can execute in an
1908 * interrupt context. This avoids
1909 * context switches, provides
1910 * extensive benifits and performance
1911 * improvements.
1912 */
1913 ret = request_irq(dev->irq,
1914 ngd_slim_interrupt,
1915 IRQF_TRIGGER_HIGH,
1916 "ngd_slim_irq", dev);
1917
1918 if (ret) {
1919 dev_err(&pdev->dev, "request IRQ failed\n");
1920 goto err_request_irq_failed;
1921 }
1922
1923 init_completion(&dev->qmi.qmi_comp);
1924 dev->err = -EPROBE_DEFER;
1925 pm_runtime_use_autosuspend(dev->dev);
1926 pm_runtime_set_autosuspend_delay(dev->dev, MSM_SLIM_AUTOSUSPEND);
1927 pm_runtime_set_suspended(dev->dev);
1928 pm_runtime_enable(dev->dev);
1929
1930 if (slim_mdm) {
1931 dev->ext_mdm.nb.notifier_call = mdm_ssr_notify_cb;
1932 dev->ext_mdm.domr = subsys_notif_register_notifier(ext_modem_id,
1933 &dev->ext_mdm.nb);
1934 if (IS_ERR_OR_NULL(dev->ext_mdm.domr))
1935 dev_err(dev->dev,
1936 "subsys_notif_register_notifier failed %p",
1937 dev->ext_mdm.domr);
1938 }
1939
1940 INIT_WORK(&dev->dsp.dom_up, ngd_dom_up);
1941 dev->qmi.nb.notifier_call = ngd_qmi_available;
1942 pm_runtime_get_noresume(dev->dev);
1943
1944 /* Fire up the Rx message queue thread */
1945 dev->rx_msgq_thread = kthread_run(ngd_slim_rx_msgq_thread, dev,
1946 "ngd_rx_thread%d", dev->ctrl.nr);
1947 if (IS_ERR(dev->rx_msgq_thread)) {
1948 ret = PTR_ERR(dev->rx_msgq_thread);
1949 dev_err(dev->dev, "Failed to start Rx thread:%d\n", ret);
1950 goto err_rx_thread_create_failed;
1951 }
1952
1953 /* Start thread to probe, and notify slaves */
1954 dev->qmi.slave_thread = kthread_run(ngd_notify_slaves, dev,
1955 "ngd_notify_sl%d", dev->ctrl.nr);
1956 if (IS_ERR(dev->qmi.slave_thread)) {
1957 ret = PTR_ERR(dev->qmi.slave_thread);
1958 dev_err(dev->dev, "Failed to start notifier thread:%d\n", ret);
1959 goto err_notify_thread_create_failed;
1960 }
1961 SLIM_INFO(dev, "NGD SB controller is up!\n");
1962 return 0;
1963
1964err_notify_thread_create_failed:
1965 kthread_stop(dev->rx_msgq_thread);
1966err_rx_thread_create_failed:
1967 free_irq(dev->irq, dev);
1968err_request_irq_failed:
1969err_ctrl_failed:
1970 iounmap(dev->bam.base);
1971err_ioremap_bam_failed:
1972 iounmap(dev->base);
1973err_ioremap_failed:
1974 if (dev->sysfs_created)
1975 sysfs_remove_file(&dev->dev->kobj,
1976 &dev_attr_debug_mask.attr);
1977 kfree(dev->bulk.base);
1978err_nobulk:
1979 kfree(dev->wr_comp);
1980 kfree(dev);
1981 return ret;
1982}
1983
1984static int ngd_slim_remove(struct platform_device *pdev)
1985{
1986 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
1987
1988 ngd_slim_enable(dev, false);
Karthikeyan Ramasubramanian9cd18ff2017-05-09 17:11:26 -06001989 if (!IS_ERR_OR_NULL(dev->iommu_desc.iommu_map)) {
1990 arm_iommu_detach_device(dev->iommu_desc.cb_dev);
1991 arm_iommu_release_mapping(dev->iommu_desc.iommu_map);
1992 }
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07001993 if (dev->sysfs_created)
1994 sysfs_remove_file(&dev->dev->kobj,
1995 &dev_attr_debug_mask.attr);
1996 qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
1997 SLIMBUS_QMI_SVC_V1,
1998 SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
1999 pm_runtime_disable(&pdev->dev);
2000 if (dev->dsp.dom_t == MSM_SLIM_DOM_SS)
2001 subsys_notif_unregister_notifier(dev->dsp.domr,
2002 &dev->dsp.nb);
2003 if (dev->dsp.dom_t == MSM_SLIM_DOM_PD)
2004 service_notif_unregister_notifier(dev->dsp.domr,
2005 &dev->dsp.nb);
2006 if (!IS_ERR_OR_NULL(dev->ext_mdm.domr))
2007 subsys_notif_unregister_notifier(dev->ext_mdm.domr,
2008 &dev->ext_mdm.nb);
2009 kfree(dev->bulk.base);
2010 free_irq(dev->irq, dev);
2011 slim_del_controller(&dev->ctrl);
2012 kthread_stop(dev->rx_msgq_thread);
2013 iounmap(dev->bam.base);
2014 iounmap(dev->base);
2015 kfree(dev->wr_comp);
2016 kfree(dev);
2017 return 0;
2018}
2019
2020#ifdef CONFIG_PM
2021static int ngd_slim_runtime_idle(struct device *device)
2022{
2023 struct platform_device *pdev = to_platform_device(device);
2024 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
2025
2026 mutex_lock(&dev->tx_lock);
2027 if (dev->state == MSM_CTRL_AWAKE)
2028 dev->state = MSM_CTRL_IDLE;
2029 mutex_unlock(&dev->tx_lock);
2030 dev_dbg(device, "pm_runtime: idle...\n");
2031 pm_request_autosuspend(device);
2032 return -EAGAIN;
2033}
2034#endif
2035
2036/*
2037 * If PM_RUNTIME is not defined, these 2 functions become helper
2038 * functions to be called from system suspend/resume. So they are not
2039 * inside ifdef CONFIG_PM_RUNTIME
2040 */
2041static int ngd_slim_runtime_resume(struct device *device)
2042{
2043 struct platform_device *pdev = to_platform_device(device);
2044 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
2045 int ret = 0;
2046
2047 mutex_lock(&dev->tx_lock);
2048 if (dev->state >= MSM_CTRL_ASLEEP)
2049 ret = ngd_slim_power_up(dev, false);
2050 if (ret) {
2051 /* Did SSR cause this power up failure */
2052 if (dev->state != MSM_CTRL_DOWN)
2053 dev->state = MSM_CTRL_ASLEEP;
2054 else
2055 SLIM_WARN(dev, "HW wakeup attempt during SSR\n");
2056 } else {
2057 dev->state = MSM_CTRL_AWAKE;
2058 }
2059 mutex_unlock(&dev->tx_lock);
2060 SLIM_INFO(dev, "Slim runtime resume: ret %d\n", ret);
2061 return ret;
2062}
2063
2064#ifdef CONFIG_PM
2065static int ngd_slim_runtime_suspend(struct device *device)
2066{
2067 struct platform_device *pdev = to_platform_device(device);
2068 struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
2069 int ret = 0;
2070
2071 mutex_lock(&dev->tx_lock);
2072 ret = ngd_slim_power_down(dev);
2073 if (ret && ret != -EBUSY)
2074 SLIM_INFO(dev, "slim resource not idle:%d\n", ret);
2075 if (!ret || ret == -ETIMEDOUT)
2076 dev->state = MSM_CTRL_ASLEEP;
2077 mutex_unlock(&dev->tx_lock);
2078 SLIM_INFO(dev, "Slim runtime suspend: ret %d\n", ret);
2079 return ret;
2080}
2081#endif
2082
2083#ifdef CONFIG_PM_SLEEP
2084static int ngd_slim_suspend(struct device *dev)
2085{
2086 int ret = -EBUSY;
2087 struct platform_device *pdev = to_platform_device(dev);
Sagar Dharia7d0f2b22017-07-01 18:26:15 -06002088 struct msm_slim_ctrl *cdev;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002089
Sagar Dharia7d0f2b22017-07-01 18:26:15 -06002090 if (of_device_is_compatible(pdev->dev.of_node,
2091 "qcom,iommu-slim-ctrl-cb"))
2092 return 0;
2093
2094 cdev = platform_get_drvdata(pdev);
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002095 if (!pm_runtime_enabled(dev) ||
2096 (!pm_runtime_suspended(dev) &&
2097 cdev->state == MSM_CTRL_IDLE)) {
Sagar Dhariaa4bfae12016-08-25 22:35:24 -06002098 cdev->qmi.deferred_resp = true;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002099 ret = ngd_slim_runtime_suspend(dev);
2100 /*
2101 * If runtime-PM still thinks it's active, then make sure its
2102 * status is in sync with HW status.
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002103 */
2104 if (!ret) {
2105 pm_runtime_disable(dev);
2106 pm_runtime_set_suspended(dev);
2107 pm_runtime_enable(dev);
Sagar Dhariaa4bfae12016-08-25 22:35:24 -06002108 } else {
2109 cdev->qmi.deferred_resp = false;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002110 }
2111 }
2112 if (ret == -EBUSY) {
2113 /*
2114 * There is a possibility that some audio stream is active
2115 * during suspend. We dont want to return suspend failure in
2116 * that case so that display and relevant components can still
2117 * go to suspend.
2118 * If there is some other error, then it should be passed-on
2119 * to system level suspend
2120 */
2121 ret = 0;
2122 }
2123 SLIM_INFO(cdev, "system suspend\n");
2124 return ret;
2125}
2126
2127static int ngd_slim_resume(struct device *dev)
2128{
2129 struct platform_device *pdev = to_platform_device(dev);
Sagar Dharia7d0f2b22017-07-01 18:26:15 -06002130 struct msm_slim_ctrl *cdev;
Sagar Dhariaa4bfae12016-08-25 22:35:24 -06002131 int ret = 0;
2132
Sagar Dharia7d0f2b22017-07-01 18:26:15 -06002133 if (of_device_is_compatible(pdev->dev.of_node,
2134 "qcom,iommu-slim-ctrl-cb"))
2135 return 0;
2136
2137 cdev = platform_get_drvdata(pdev);
Sagar Dhariaa4bfae12016-08-25 22:35:24 -06002138 /*
2139 * If deferred response was requested for power-off and it failed,
2140 * mark runtime-pm status as active to be consistent
2141 * with HW status
2142 */
2143 if (cdev->qmi.deferred_resp) {
2144 ret = msm_slim_qmi_deferred_status_req(cdev);
2145 if (ret) {
2146 pm_runtime_disable(dev);
2147 pm_runtime_set_active(dev);
2148 pm_runtime_enable(dev);
2149 }
2150 cdev->qmi.deferred_resp = false;
2151 }
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002152 /*
2153 * Rely on runtime-PM to call resume in case it is enabled.
2154 * Even if it's not enabled, rely on 1st client transaction to do
2155 * clock/power on
2156 */
2157 SLIM_INFO(cdev, "system resume\n");
Sagar Dhariaa4bfae12016-08-25 22:35:24 -06002158 return ret;
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002159}
2160#endif /* CONFIG_PM_SLEEP */
2161
2162static const struct dev_pm_ops ngd_slim_dev_pm_ops = {
2163 SET_SYSTEM_SLEEP_PM_OPS(
2164 ngd_slim_suspend,
2165 ngd_slim_resume
2166 )
2167 SET_RUNTIME_PM_OPS(
2168 ngd_slim_runtime_suspend,
2169 ngd_slim_runtime_resume,
2170 ngd_slim_runtime_idle
2171 )
2172};
2173
Sagar Dhariabe37c9c2016-11-28 23:06:58 -07002174static struct platform_driver ngd_slim_driver = {
2175 .probe = ngd_slim_probe,
2176 .remove = ngd_slim_remove,
2177 .driver = {
2178 .name = NGD_SLIM_NAME,
2179 .owner = THIS_MODULE,
2180 .pm = &ngd_slim_dev_pm_ops,
2181 .of_match_table = ngd_slim_dt_match,
2182 },
2183};
2184
2185static int ngd_slim_init(void)
2186{
2187 return platform_driver_register(&ngd_slim_driver);
2188}
2189late_initcall(ngd_slim_init);
2190
2191static void ngd_slim_exit(void)
2192{
2193 platform_driver_unregister(&ngd_slim_driver);
2194}
2195module_exit(ngd_slim_exit);
2196
2197MODULE_LICENSE("GPL v2");
2198MODULE_DESCRIPTION("MSM Slimbus controller");
2199MODULE_ALIAS("platform:msm-slim-ngd");