1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
6 #include <linux/delay.h>
7 #include <linux/interrupt.h>
9 #include <linux/mailbox_controller.h>
11 #include <linux/of_device.h>
12 #include <linux/platform_device.h>
14 #include <linux/slab.h>
16 #include <dt-bindings/mailbox/tegra186-hsp.h>
20 #define HSP_INT_IE(x) (0x100 + ((x) * 4))
21 #define HSP_INT_IV 0x300
22 #define HSP_INT_IR 0x304
24 #define HSP_INT_EMPTY_SHIFT 0
25 #define HSP_INT_EMPTY_MASK 0xff
26 #define HSP_INT_FULL_SHIFT 8
27 #define HSP_INT_FULL_MASK 0xff
29 #define HSP_INT_DIMENSIONING 0x380
30 #define HSP_nSM_SHIFT 0
31 #define HSP_nSS_SHIFT 4
32 #define HSP_nAS_SHIFT 8
33 #define HSP_nDB_SHIFT 12
34 #define HSP_nSI_SHIFT 16
35 #define HSP_nINT_MASK 0xf
37 #define HSP_DB_TRIGGER 0x0
38 #define HSP_DB_ENABLE 0x4
39 #define HSP_DB_RAW 0x8
40 #define HSP_DB_PENDING 0xc
42 #define HSP_SM_SHRD_MBOX 0x0
43 #define HSP_SM_SHRD_MBOX_FULL BIT(31)
44 #define HSP_SM_SHRD_MBOX_FULL_INT_IE 0x04
45 #define HSP_SM_SHRD_MBOX_EMPTY_INT_IE 0x08
47 #define HSP_DB_CCPLEX 1
51 struct tegra_hsp_channel
;
54 struct tegra_hsp_channel
{
55 struct tegra_hsp
*hsp
;
56 struct mbox_chan
*chan
;
60 struct tegra_hsp_doorbell
{
61 struct tegra_hsp_channel channel
;
62 struct list_head list
;
68 struct tegra_hsp_mailbox
{
69 struct tegra_hsp_channel channel
;
74 struct tegra_hsp_db_map
{
80 struct tegra_hsp_soc
{
81 const struct tegra_hsp_db_map
*map
;
87 const struct tegra_hsp_soc
*soc
;
88 struct mbox_controller mbox_db
;
89 struct mbox_controller mbox_sm
;
91 unsigned int doorbell_irq
;
92 unsigned int *shared_irqs
;
93 unsigned int shared_irq
;
101 struct list_head doorbells
;
102 struct tegra_hsp_mailbox
*mailboxes
;
107 static inline u32
tegra_hsp_readl(struct tegra_hsp
*hsp
, unsigned int offset
)
109 return readl(hsp
->regs
+ offset
);
112 static inline void tegra_hsp_writel(struct tegra_hsp
*hsp
, u32 value
,
115 writel(value
, hsp
->regs
+ offset
);
118 static inline u32
tegra_hsp_channel_readl(struct tegra_hsp_channel
*channel
,
121 return readl(channel
->regs
+ offset
);
124 static inline void tegra_hsp_channel_writel(struct tegra_hsp_channel
*channel
,
125 u32 value
, unsigned int offset
)
127 writel(value
, channel
->regs
+ offset
);
130 static bool tegra_hsp_doorbell_can_ring(struct tegra_hsp_doorbell
*db
)
134 value
= tegra_hsp_channel_readl(&db
->channel
, HSP_DB_ENABLE
);
136 return (value
& BIT(TEGRA_HSP_DB_MASTER_CCPLEX
)) != 0;
139 static struct tegra_hsp_doorbell
*
140 __tegra_hsp_doorbell_get(struct tegra_hsp
*hsp
, unsigned int master
)
142 struct tegra_hsp_doorbell
*entry
;
144 list_for_each_entry(entry
, &hsp
->doorbells
, list
)
145 if (entry
->master
== master
)
151 static struct tegra_hsp_doorbell
*
152 tegra_hsp_doorbell_get(struct tegra_hsp
*hsp
, unsigned int master
)
154 struct tegra_hsp_doorbell
*db
;
157 spin_lock_irqsave(&hsp
->lock
, flags
);
158 db
= __tegra_hsp_doorbell_get(hsp
, master
);
159 spin_unlock_irqrestore(&hsp
->lock
, flags
);
164 static irqreturn_t
tegra_hsp_doorbell_irq(int irq
, void *data
)
166 struct tegra_hsp
*hsp
= data
;
167 struct tegra_hsp_doorbell
*db
;
168 unsigned long master
, value
;
170 db
= tegra_hsp_doorbell_get(hsp
, TEGRA_HSP_DB_MASTER_CCPLEX
);
174 value
= tegra_hsp_channel_readl(&db
->channel
, HSP_DB_PENDING
);
175 tegra_hsp_channel_writel(&db
->channel
, value
, HSP_DB_PENDING
);
177 spin_lock(&hsp
->lock
);
179 for_each_set_bit(master
, &value
, hsp
->mbox_db
.num_chans
) {
180 struct tegra_hsp_doorbell
*db
;
182 db
= __tegra_hsp_doorbell_get(hsp
, master
);
184 * Depending on the bootloader chain, the CCPLEX doorbell will
185 * have some doorbells enabled, which means that requesting an
186 * interrupt will immediately fire.
188 * In that case, db->channel.chan will still be NULL here and
189 * cause a crash if not properly guarded.
191 * It remains to be seen if ignoring the doorbell in that case
192 * is the correct solution.
194 if (db
&& db
->channel
.chan
)
195 mbox_chan_received_data(db
->channel
.chan
, NULL
);
198 spin_unlock(&hsp
->lock
);
203 static irqreturn_t
tegra_hsp_shared_irq(int irq
, void *data
)
205 struct tegra_hsp
*hsp
= data
;
206 unsigned long bit
, mask
;
210 status
= tegra_hsp_readl(hsp
, HSP_INT_IR
) & hsp
->mask
;
212 /* process EMPTY interrupts first */
213 mask
= (status
>> HSP_INT_EMPTY_SHIFT
) & HSP_INT_EMPTY_MASK
;
215 for_each_set_bit(bit
, &mask
, hsp
->num_sm
) {
216 struct tegra_hsp_mailbox
*mb
= &hsp
->mailboxes
[bit
];
220 * Disable EMPTY interrupts until data is sent with
221 * the next message. These interrupts are level-
222 * triggered, so if we kept them enabled they would
223 * constantly trigger until we next write data into
226 spin_lock(&hsp
->lock
);
228 hsp
->mask
&= ~BIT(HSP_INT_EMPTY_SHIFT
+ mb
->index
);
229 tegra_hsp_writel(hsp
, hsp
->mask
,
230 HSP_INT_IE(hsp
->shared_irq
));
232 spin_unlock(&hsp
->lock
);
234 mbox_chan_txdone(mb
->channel
.chan
, 0);
238 /* process FULL interrupts */
239 mask
= (status
>> HSP_INT_FULL_SHIFT
) & HSP_INT_FULL_MASK
;
241 for_each_set_bit(bit
, &mask
, hsp
->num_sm
) {
242 struct tegra_hsp_mailbox
*mb
= &hsp
->mailboxes
[bit
];
245 value
= tegra_hsp_channel_readl(&mb
->channel
,
247 value
&= ~HSP_SM_SHRD_MBOX_FULL
;
248 msg
= (void *)(unsigned long)value
;
249 mbox_chan_received_data(mb
->channel
.chan
, msg
);
252 * Need to clear all bits here since some producers,
253 * such as TCU, depend on fields in the register
254 * getting cleared by the consumer.
256 * The mailbox API doesn't give the consumers a way
257 * of doing that explicitly, so we have to make sure
258 * we cover all possible cases.
260 tegra_hsp_channel_writel(&mb
->channel
, 0x0,
268 static struct tegra_hsp_channel
*
269 tegra_hsp_doorbell_create(struct tegra_hsp
*hsp
, const char *name
,
270 unsigned int master
, unsigned int index
)
272 struct tegra_hsp_doorbell
*db
;
276 db
= devm_kzalloc(hsp
->dev
, sizeof(*db
), GFP_KERNEL
);
278 return ERR_PTR(-ENOMEM
);
280 offset
= (1 + (hsp
->num_sm
/ 2) + hsp
->num_ss
+ hsp
->num_as
) * SZ_64K
;
281 offset
+= index
* 0x100;
283 db
->channel
.regs
= hsp
->regs
+ offset
;
284 db
->channel
.hsp
= hsp
;
286 db
->name
= devm_kstrdup_const(hsp
->dev
, name
, GFP_KERNEL
);
290 spin_lock_irqsave(&hsp
->lock
, flags
);
291 list_add_tail(&db
->list
, &hsp
->doorbells
);
292 spin_unlock_irqrestore(&hsp
->lock
, flags
);
297 static int tegra_hsp_doorbell_send_data(struct mbox_chan
*chan
, void *data
)
299 struct tegra_hsp_doorbell
*db
= chan
->con_priv
;
301 tegra_hsp_channel_writel(&db
->channel
, 1, HSP_DB_TRIGGER
);
306 static int tegra_hsp_doorbell_startup(struct mbox_chan
*chan
)
308 struct tegra_hsp_doorbell
*db
= chan
->con_priv
;
309 struct tegra_hsp
*hsp
= db
->channel
.hsp
;
310 struct tegra_hsp_doorbell
*ccplex
;
314 if (db
->master
>= chan
->mbox
->num_chans
) {
315 dev_err(chan
->mbox
->dev
,
316 "invalid master ID %u for HSP channel\n",
321 ccplex
= tegra_hsp_doorbell_get(hsp
, TEGRA_HSP_DB_MASTER_CCPLEX
);
325 if (!tegra_hsp_doorbell_can_ring(db
))
328 spin_lock_irqsave(&hsp
->lock
, flags
);
330 value
= tegra_hsp_channel_readl(&ccplex
->channel
, HSP_DB_ENABLE
);
331 value
|= BIT(db
->master
);
332 tegra_hsp_channel_writel(&ccplex
->channel
, value
, HSP_DB_ENABLE
);
334 spin_unlock_irqrestore(&hsp
->lock
, flags
);
339 static void tegra_hsp_doorbell_shutdown(struct mbox_chan
*chan
)
341 struct tegra_hsp_doorbell
*db
= chan
->con_priv
;
342 struct tegra_hsp
*hsp
= db
->channel
.hsp
;
343 struct tegra_hsp_doorbell
*ccplex
;
347 ccplex
= tegra_hsp_doorbell_get(hsp
, TEGRA_HSP_DB_MASTER_CCPLEX
);
351 spin_lock_irqsave(&hsp
->lock
, flags
);
353 value
= tegra_hsp_channel_readl(&ccplex
->channel
, HSP_DB_ENABLE
);
354 value
&= ~BIT(db
->master
);
355 tegra_hsp_channel_writel(&ccplex
->channel
, value
, HSP_DB_ENABLE
);
357 spin_unlock_irqrestore(&hsp
->lock
, flags
);
360 static const struct mbox_chan_ops tegra_hsp_db_ops
= {
361 .send_data
= tegra_hsp_doorbell_send_data
,
362 .startup
= tegra_hsp_doorbell_startup
,
363 .shutdown
= tegra_hsp_doorbell_shutdown
,
366 static int tegra_hsp_mailbox_send_data(struct mbox_chan
*chan
, void *data
)
368 struct tegra_hsp_mailbox
*mb
= chan
->con_priv
;
369 struct tegra_hsp
*hsp
= mb
->channel
.hsp
;
373 if (WARN_ON(!mb
->producer
))
376 /* copy data and mark mailbox full */
377 value
= (u32
)(unsigned long)data
;
378 value
|= HSP_SM_SHRD_MBOX_FULL
;
380 tegra_hsp_channel_writel(&mb
->channel
, value
, HSP_SM_SHRD_MBOX
);
382 /* enable EMPTY interrupt for the shared mailbox */
383 spin_lock_irqsave(&hsp
->lock
, flags
);
385 hsp
->mask
|= BIT(HSP_INT_EMPTY_SHIFT
+ mb
->index
);
386 tegra_hsp_writel(hsp
, hsp
->mask
, HSP_INT_IE(hsp
->shared_irq
));
388 spin_unlock_irqrestore(&hsp
->lock
, flags
);
393 static int tegra_hsp_mailbox_flush(struct mbox_chan
*chan
,
394 unsigned long timeout
)
396 struct tegra_hsp_mailbox
*mb
= chan
->con_priv
;
397 struct tegra_hsp_channel
*ch
= &mb
->channel
;
400 timeout
= jiffies
+ msecs_to_jiffies(timeout
);
402 while (time_before(jiffies
, timeout
)) {
403 value
= tegra_hsp_channel_readl(ch
, HSP_SM_SHRD_MBOX
);
404 if ((value
& HSP_SM_SHRD_MBOX_FULL
) == 0) {
405 mbox_chan_txdone(chan
, 0);
415 static int tegra_hsp_mailbox_startup(struct mbox_chan
*chan
)
417 struct tegra_hsp_mailbox
*mb
= chan
->con_priv
;
418 struct tegra_hsp_channel
*ch
= &mb
->channel
;
419 struct tegra_hsp
*hsp
= mb
->channel
.hsp
;
422 chan
->txdone_method
= TXDONE_BY_IRQ
;
425 * Shared mailboxes start out as consumers by default. FULL and EMPTY
426 * interrupts are coalesced at the same shared interrupt.
428 * Keep EMPTY interrupts disabled at startup and only enable them when
429 * the mailbox is actually full. This is required because the FULL and
430 * EMPTY interrupts are level-triggered, so keeping EMPTY interrupts
431 * enabled all the time would cause an interrupt storm while mailboxes
435 spin_lock_irqsave(&hsp
->lock
, flags
);
438 hsp
->mask
&= ~BIT(HSP_INT_EMPTY_SHIFT
+ mb
->index
);
440 hsp
->mask
|= BIT(HSP_INT_FULL_SHIFT
+ mb
->index
);
442 tegra_hsp_writel(hsp
, hsp
->mask
, HSP_INT_IE(hsp
->shared_irq
));
444 spin_unlock_irqrestore(&hsp
->lock
, flags
);
446 if (hsp
->soc
->has_per_mb_ie
) {
448 tegra_hsp_channel_writel(ch
, 0x0,
449 HSP_SM_SHRD_MBOX_EMPTY_INT_IE
);
451 tegra_hsp_channel_writel(ch
, 0x1,
452 HSP_SM_SHRD_MBOX_FULL_INT_IE
);
458 static void tegra_hsp_mailbox_shutdown(struct mbox_chan
*chan
)
460 struct tegra_hsp_mailbox
*mb
= chan
->con_priv
;
461 struct tegra_hsp_channel
*ch
= &mb
->channel
;
462 struct tegra_hsp
*hsp
= mb
->channel
.hsp
;
465 if (hsp
->soc
->has_per_mb_ie
) {
467 tegra_hsp_channel_writel(ch
, 0x0,
468 HSP_SM_SHRD_MBOX_EMPTY_INT_IE
);
470 tegra_hsp_channel_writel(ch
, 0x0,
471 HSP_SM_SHRD_MBOX_FULL_INT_IE
);
474 spin_lock_irqsave(&hsp
->lock
, flags
);
477 hsp
->mask
&= ~BIT(HSP_INT_EMPTY_SHIFT
+ mb
->index
);
479 hsp
->mask
&= ~BIT(HSP_INT_FULL_SHIFT
+ mb
->index
);
481 tegra_hsp_writel(hsp
, hsp
->mask
, HSP_INT_IE(hsp
->shared_irq
));
483 spin_unlock_irqrestore(&hsp
->lock
, flags
);
486 static const struct mbox_chan_ops tegra_hsp_sm_ops
= {
487 .send_data
= tegra_hsp_mailbox_send_data
,
488 .flush
= tegra_hsp_mailbox_flush
,
489 .startup
= tegra_hsp_mailbox_startup
,
490 .shutdown
= tegra_hsp_mailbox_shutdown
,
493 static struct mbox_chan
*tegra_hsp_db_xlate(struct mbox_controller
*mbox
,
494 const struct of_phandle_args
*args
)
496 struct tegra_hsp
*hsp
= container_of(mbox
, struct tegra_hsp
, mbox_db
);
497 unsigned int type
= args
->args
[0], master
= args
->args
[1];
498 struct tegra_hsp_channel
*channel
= ERR_PTR(-ENODEV
);
499 struct tegra_hsp_doorbell
*db
;
500 struct mbox_chan
*chan
;
504 if (type
!= TEGRA_HSP_MBOX_TYPE_DB
|| !hsp
->doorbell_irq
)
505 return ERR_PTR(-ENODEV
);
507 db
= tegra_hsp_doorbell_get(hsp
, master
);
509 channel
= &db
->channel
;
512 return ERR_CAST(channel
);
514 spin_lock_irqsave(&hsp
->lock
, flags
);
516 for (i
= 0; i
< mbox
->num_chans
; i
++) {
517 chan
= &mbox
->chans
[i
];
518 if (!chan
->con_priv
) {
519 channel
->chan
= chan
;
527 spin_unlock_irqrestore(&hsp
->lock
, flags
);
529 return chan
?: ERR_PTR(-EBUSY
);
532 static struct mbox_chan
*tegra_hsp_sm_xlate(struct mbox_controller
*mbox
,
533 const struct of_phandle_args
*args
)
535 struct tegra_hsp
*hsp
= container_of(mbox
, struct tegra_hsp
, mbox_sm
);
536 unsigned int type
= args
->args
[0], index
;
537 struct tegra_hsp_mailbox
*mb
;
539 index
= args
->args
[1] & TEGRA_HSP_SM_MASK
;
541 if (type
!= TEGRA_HSP_MBOX_TYPE_SM
|| !hsp
->shared_irqs
||
542 index
>= hsp
->num_sm
)
543 return ERR_PTR(-ENODEV
);
545 mb
= &hsp
->mailboxes
[index
];
547 if ((args
->args
[1] & TEGRA_HSP_SM_FLAG_TX
) == 0)
548 mb
->producer
= false;
552 return mb
->channel
.chan
;
555 static int tegra_hsp_add_doorbells(struct tegra_hsp
*hsp
)
557 const struct tegra_hsp_db_map
*map
= hsp
->soc
->map
;
558 struct tegra_hsp_channel
*channel
;
561 channel
= tegra_hsp_doorbell_create(hsp
, map
->name
,
562 map
->master
, map
->index
);
564 return PTR_ERR(channel
);
572 static int tegra_hsp_add_mailboxes(struct tegra_hsp
*hsp
, struct device
*dev
)
576 hsp
->mailboxes
= devm_kcalloc(dev
, hsp
->num_sm
, sizeof(*hsp
->mailboxes
),
581 for (i
= 0; i
< hsp
->num_sm
; i
++) {
582 struct tegra_hsp_mailbox
*mb
= &hsp
->mailboxes
[i
];
586 mb
->channel
.hsp
= hsp
;
587 mb
->channel
.regs
= hsp
->regs
+ SZ_64K
+ i
* SZ_32K
;
588 mb
->channel
.chan
= &hsp
->mbox_sm
.chans
[i
];
589 mb
->channel
.chan
->con_priv
= mb
;
595 static int tegra_hsp_request_shared_irq(struct tegra_hsp
*hsp
)
597 unsigned int i
, irq
= 0;
600 for (i
= 0; i
< hsp
->num_si
; i
++) {
601 irq
= hsp
->shared_irqs
[i
];
605 err
= devm_request_irq(hsp
->dev
, irq
, tegra_hsp_shared_irq
, 0,
606 dev_name(hsp
->dev
), hsp
);
608 dev_err(hsp
->dev
, "failed to request interrupt: %d\n",
615 /* disable all interrupts */
616 tegra_hsp_writel(hsp
, 0, HSP_INT_IE(hsp
->shared_irq
));
618 dev_dbg(hsp
->dev
, "interrupt requested: %u\n", irq
);
623 if (i
== hsp
->num_si
) {
624 dev_err(hsp
->dev
, "failed to find available interrupt\n");
631 static int tegra_hsp_probe(struct platform_device
*pdev
)
633 struct tegra_hsp
*hsp
;
634 struct resource
*res
;
639 hsp
= devm_kzalloc(&pdev
->dev
, sizeof(*hsp
), GFP_KERNEL
);
643 hsp
->dev
= &pdev
->dev
;
644 hsp
->soc
= of_device_get_match_data(&pdev
->dev
);
645 INIT_LIST_HEAD(&hsp
->doorbells
);
646 spin_lock_init(&hsp
->lock
);
648 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
649 hsp
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
650 if (IS_ERR(hsp
->regs
))
651 return PTR_ERR(hsp
->regs
);
653 value
= tegra_hsp_readl(hsp
, HSP_INT_DIMENSIONING
);
654 hsp
->num_sm
= (value
>> HSP_nSM_SHIFT
) & HSP_nINT_MASK
;
655 hsp
->num_ss
= (value
>> HSP_nSS_SHIFT
) & HSP_nINT_MASK
;
656 hsp
->num_as
= (value
>> HSP_nAS_SHIFT
) & HSP_nINT_MASK
;
657 hsp
->num_db
= (value
>> HSP_nDB_SHIFT
) & HSP_nINT_MASK
;
658 hsp
->num_si
= (value
>> HSP_nSI_SHIFT
) & HSP_nINT_MASK
;
660 err
= platform_get_irq_byname(pdev
, "doorbell");
662 hsp
->doorbell_irq
= err
;
664 if (hsp
->num_si
> 0) {
665 unsigned int count
= 0;
667 hsp
->shared_irqs
= devm_kcalloc(&pdev
->dev
, hsp
->num_si
,
668 sizeof(*hsp
->shared_irqs
),
670 if (!hsp
->shared_irqs
)
673 for (i
= 0; i
< hsp
->num_si
; i
++) {
676 name
= kasprintf(GFP_KERNEL
, "shared%u", i
);
680 err
= platform_get_irq_byname(pdev
, name
);
682 hsp
->shared_irqs
[i
] = err
;
690 devm_kfree(&pdev
->dev
, hsp
->shared_irqs
);
691 hsp
->shared_irqs
= NULL
;
695 /* setup the doorbell controller */
696 hsp
->mbox_db
.of_xlate
= tegra_hsp_db_xlate
;
697 hsp
->mbox_db
.num_chans
= 32;
698 hsp
->mbox_db
.dev
= &pdev
->dev
;
699 hsp
->mbox_db
.ops
= &tegra_hsp_db_ops
;
701 hsp
->mbox_db
.chans
= devm_kcalloc(&pdev
->dev
, hsp
->mbox_db
.num_chans
,
702 sizeof(*hsp
->mbox_db
.chans
),
704 if (!hsp
->mbox_db
.chans
)
707 if (hsp
->doorbell_irq
) {
708 err
= tegra_hsp_add_doorbells(hsp
);
710 dev_err(&pdev
->dev
, "failed to add doorbells: %d\n",
716 err
= devm_mbox_controller_register(&pdev
->dev
, &hsp
->mbox_db
);
718 dev_err(&pdev
->dev
, "failed to register doorbell mailbox: %d\n",
723 /* setup the shared mailbox controller */
724 hsp
->mbox_sm
.of_xlate
= tegra_hsp_sm_xlate
;
725 hsp
->mbox_sm
.num_chans
= hsp
->num_sm
;
726 hsp
->mbox_sm
.dev
= &pdev
->dev
;
727 hsp
->mbox_sm
.ops
= &tegra_hsp_sm_ops
;
729 hsp
->mbox_sm
.chans
= devm_kcalloc(&pdev
->dev
, hsp
->mbox_sm
.num_chans
,
730 sizeof(*hsp
->mbox_sm
.chans
),
732 if (!hsp
->mbox_sm
.chans
)
735 if (hsp
->shared_irqs
) {
736 err
= tegra_hsp_add_mailboxes(hsp
, &pdev
->dev
);
738 dev_err(&pdev
->dev
, "failed to add mailboxes: %d\n",
744 err
= devm_mbox_controller_register(&pdev
->dev
, &hsp
->mbox_sm
);
746 dev_err(&pdev
->dev
, "failed to register shared mailbox: %d\n",
751 platform_set_drvdata(pdev
, hsp
);
753 if (hsp
->doorbell_irq
) {
754 err
= devm_request_irq(&pdev
->dev
, hsp
->doorbell_irq
,
755 tegra_hsp_doorbell_irq
, IRQF_NO_SUSPEND
,
756 dev_name(&pdev
->dev
), hsp
);
759 "failed to request doorbell IRQ#%u: %d\n",
760 hsp
->doorbell_irq
, err
);
765 if (hsp
->shared_irqs
) {
766 err
= tegra_hsp_request_shared_irq(hsp
);
774 static int __maybe_unused
tegra_hsp_resume(struct device
*dev
)
776 struct tegra_hsp
*hsp
= dev_get_drvdata(dev
);
778 struct tegra_hsp_doorbell
*db
;
780 list_for_each_entry(db
, &hsp
->doorbells
, list
) {
781 if (db
&& db
->channel
.chan
)
782 tegra_hsp_doorbell_startup(db
->channel
.chan
);
785 if (hsp
->mailboxes
) {
786 for (i
= 0; i
< hsp
->num_sm
; i
++) {
787 struct tegra_hsp_mailbox
*mb
= &hsp
->mailboxes
[i
];
789 if (mb
->channel
.chan
->cl
)
790 tegra_hsp_mailbox_startup(mb
->channel
.chan
);
797 static const struct dev_pm_ops tegra_hsp_pm_ops
= {
798 .resume_noirq
= tegra_hsp_resume
,
801 static const struct tegra_hsp_db_map tegra186_hsp_db_map
[] = {
802 { "ccplex", TEGRA_HSP_DB_MASTER_CCPLEX
, HSP_DB_CCPLEX
, },
803 { "bpmp", TEGRA_HSP_DB_MASTER_BPMP
, HSP_DB_BPMP
, },
807 static const struct tegra_hsp_soc tegra186_hsp_soc
= {
808 .map
= tegra186_hsp_db_map
,
809 .has_per_mb_ie
= false,
812 static const struct tegra_hsp_soc tegra194_hsp_soc
= {
813 .map
= tegra186_hsp_db_map
,
814 .has_per_mb_ie
= true,
817 static const struct of_device_id tegra_hsp_match
[] = {
818 { .compatible
= "nvidia,tegra186-hsp", .data
= &tegra186_hsp_soc
},
819 { .compatible
= "nvidia,tegra194-hsp", .data
= &tegra194_hsp_soc
},
823 static struct platform_driver tegra_hsp_driver
= {
826 .of_match_table
= tegra_hsp_match
,
827 .pm
= &tegra_hsp_pm_ops
,
829 .probe
= tegra_hsp_probe
,
832 static int __init
tegra_hsp_init(void)
834 return platform_driver_register(&tegra_hsp_driver
);
836 core_initcall(tegra_hsp_init
);