Lines Matching +full:mhu +full:- +full:doorbell

1 // SPDX-License-Identifier: GPL-2.0
10 * protocol modes: data-transfer and doorbell, to be used on those channel
19 * hardware - mainly the number of channel windows implemented by the platform,
45 #define LSB_MASK(n) ((1 << (n * __CHAR_BIT__)) - 1)
46 #define MHUV2_PROTOCOL_PROP "arm,mhuv2-protocols"
94 u8 pad1[0x0C - 0x04];
99 u8 pad2[0x20 - 0x1C];
114 u8 pad[0xFC8 - 0xFB0];
124 u8 reserved0[0x10 - 0x0C];
128 u8 pad[0x20 - 0x1C];
135 u8 reserved0[0xF90 - 0xF84];
141 u8 reserved2[0xFC8 - 0xFB0];
150 DOORBELL = 0, enumerator
160 * struct mhuv2 - MHUv2 mailbox controller data
162 * @mbox: Mailbox controller belonging to the MHU frame.
192 * struct mhuv2_protocol_ops - MHUv2 operations
206 int (*rx_startup)(struct mhuv2 *mhu, struct mbox_chan *chan);
207 void (*rx_shutdown)(struct mhuv2 *mhu, struct mbox_chan *chan);
208 void *(*read_data)(struct mhuv2 *mhu, struct mbox_chan *chan);
210 void (*tx_startup)(struct mhuv2 *mhu, struct mbox_chan *chan);
211 void (*tx_shutdown)(struct mhuv2 *mhu, struct mbox_chan *chan);
212 int (*last_tx_done)(struct mhuv2 *mhu, struct mbox_chan *chan);
213 int (*send_data)(struct mhuv2 *mhu, struct mbox_chan *chan, void *arg);
223 * @doorbell: Doorbell bit number within the ch_wn_idx window, only relevant
224 * in DOORBELL protocol.
225 * @pending: Flag indicating pending doorbell interrupt, only relevant in
226 * DOORBELL protocol.
234 u32 doorbell; member
258 /* =================== Doorbell transport protocol operations =============== */
260 static int mhuv2_doorbell_rx_startup(struct mhuv2 *mhu, struct mbox_chan *chan) in mhuv2_doorbell_rx_startup() argument
262 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_doorbell_rx_startup()
264 writel_relaxed(BIT(priv->doorbell), in mhuv2_doorbell_rx_startup()
265 &mhu->recv->ch_wn[priv->ch_wn_idx].mask_clear); in mhuv2_doorbell_rx_startup()
269 static void mhuv2_doorbell_rx_shutdown(struct mhuv2 *mhu, in mhuv2_doorbell_rx_shutdown() argument
272 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_doorbell_rx_shutdown()
274 writel_relaxed(BIT(priv->doorbell), in mhuv2_doorbell_rx_shutdown()
275 &mhu->recv->ch_wn[priv->ch_wn_idx].mask_set); in mhuv2_doorbell_rx_shutdown()
278 static void *mhuv2_doorbell_read_data(struct mhuv2 *mhu, struct mbox_chan *chan) in mhuv2_doorbell_read_data() argument
280 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_doorbell_read_data()
282 writel_relaxed(BIT(priv->doorbell), in mhuv2_doorbell_read_data()
283 &mhu->recv->ch_wn[priv->ch_wn_idx].stat_clear); in mhuv2_doorbell_read_data()
287 static int mhuv2_doorbell_last_tx_done(struct mhuv2 *mhu, in mhuv2_doorbell_last_tx_done() argument
290 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_doorbell_last_tx_done()
292 return !(readl_relaxed(&mhu->send->ch_wn[priv->ch_wn_idx].stat) & in mhuv2_doorbell_last_tx_done()
293 BIT(priv->doorbell)); in mhuv2_doorbell_last_tx_done()
296 static int mhuv2_doorbell_send_data(struct mhuv2 *mhu, struct mbox_chan *chan, in mhuv2_doorbell_send_data() argument
299 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_doorbell_send_data()
302 spin_lock_irqsave(&mhu->doorbell_pending_lock, flags); in mhuv2_doorbell_send_data()
304 priv->pending = 1; in mhuv2_doorbell_send_data()
305 writel_relaxed(BIT(priv->doorbell), in mhuv2_doorbell_send_data()
306 &mhu->send->ch_wn[priv->ch_wn_idx].stat_set); in mhuv2_doorbell_send_data()
308 spin_unlock_irqrestore(&mhu->doorbell_pending_lock, flags); in mhuv2_doorbell_send_data()
320 #define IS_PROTOCOL_DOORBELL(_priv) (_priv->ops == &mhuv2_doorbell_ops)
324 static int mhuv2_data_transfer_rx_startup(struct mhuv2 *mhu, in mhuv2_data_transfer_rx_startup() argument
327 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_rx_startup()
328 int i = priv->ch_wn_idx + priv->windows - 1; in mhuv2_data_transfer_rx_startup()
334 writel_relaxed(0xFFFFFFFF, &mhu->recv->ch_wn[i].mask_clear); in mhuv2_data_transfer_rx_startup()
338 static void mhuv2_data_transfer_rx_shutdown(struct mhuv2 *mhu, in mhuv2_data_transfer_rx_shutdown() argument
341 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_rx_shutdown()
342 int i = priv->ch_wn_idx + priv->windows - 1; in mhuv2_data_transfer_rx_shutdown()
344 writel_relaxed(0xFFFFFFFF, &mhu->recv->ch_wn[i].mask_set); in mhuv2_data_transfer_rx_shutdown()
347 static void *mhuv2_data_transfer_read_data(struct mhuv2 *mhu, in mhuv2_data_transfer_read_data() argument
350 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_read_data()
351 const int windows = priv->windows; in mhuv2_data_transfer_read_data()
358 return ERR_PTR(-ENOMEM); in mhuv2_data_transfer_read_data()
360 data = msg->data = msg + 1; in mhuv2_data_transfer_read_data()
361 msg->len = windows * MHUV2_STAT_BYTES; in mhuv2_data_transfer_read_data()
373 * data-transfer protocol, the interrupt is de-asserted. in mhuv2_data_transfer_read_data()
376 idx = priv->ch_wn_idx + i; in mhuv2_data_transfer_read_data()
377 data[windows - 1 - i] = readl_relaxed(&mhu->recv->ch_wn[idx].stat); in mhuv2_data_transfer_read_data()
378 writel_relaxed(0xFFFFFFFF, &mhu->recv->ch_wn[idx].stat_clear); in mhuv2_data_transfer_read_data()
384 static void mhuv2_data_transfer_tx_startup(struct mhuv2 *mhu, in mhuv2_data_transfer_tx_startup() argument
387 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_tx_startup()
388 int i = priv->ch_wn_idx + priv->windows - 1; in mhuv2_data_transfer_tx_startup()
391 if (mhu->minor) { in mhuv2_data_transfer_tx_startup()
392 writel_relaxed(0x1, &mhu->send->ch_wn[i].int_clr); in mhuv2_data_transfer_tx_startup()
393 writel_relaxed(0x1, &mhu->send->ch_wn[i].int_en); in mhuv2_data_transfer_tx_startup()
397 static void mhuv2_data_transfer_tx_shutdown(struct mhuv2 *mhu, in mhuv2_data_transfer_tx_shutdown() argument
400 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_tx_shutdown()
401 int i = priv->ch_wn_idx + priv->windows - 1; in mhuv2_data_transfer_tx_shutdown()
403 if (mhu->minor) in mhuv2_data_transfer_tx_shutdown()
404 writel_relaxed(0x0, &mhu->send->ch_wn[i].int_en); in mhuv2_data_transfer_tx_shutdown()
407 static int mhuv2_data_transfer_last_tx_done(struct mhuv2 *mhu, in mhuv2_data_transfer_last_tx_done() argument
410 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_last_tx_done()
411 int i = priv->ch_wn_idx + priv->windows - 1; in mhuv2_data_transfer_last_tx_done()
414 return !readl_relaxed(&mhu->send->ch_wn[i].stat); in mhuv2_data_transfer_last_tx_done()
421 * written. As an example, a 6-word message is to be written on a 4-channel MHU
430 * [ stat 3 ] <- [0x00000001] 4 <- triggers interrupt on receiver
431 * [ stat 2 ] <- [0x00000002] 3
432 * [ stat 1 ] <- [0x00000003] 2
433 * [ stat 0 ] <- [0x00000004] 1
439 * [ stat 3 ] <- [0x00000005] 2 <- triggers interrupt on receiver
440 * [ stat 2 ] <- [0x00000006] 1
441 * [ stat 1 ] <- [0x00000000]
442 * [ stat 0 ] <- [0x00000000]
444 static int mhuv2_data_transfer_send_data(struct mhuv2 *mhu, in mhuv2_data_transfer_send_data() argument
448 int bytes_left = msg->len, bytes_to_send, bytes_in_round, i; in mhuv2_data_transfer_send_data()
449 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_data_transfer_send_data()
450 int windows = priv->windows; in mhuv2_data_transfer_send_data()
451 u32 *data = msg->data, word; in mhuv2_data_transfer_send_data()
455 …dev_err(mhu->mbox.dev, "Data aligned at first window can't be zero to guarantee interrupt generati… in mhuv2_data_transfer_send_data()
456 return -EINVAL; in mhuv2_data_transfer_send_data()
459 while(!mhuv2_data_transfer_last_tx_done(mhu, chan)) in mhuv2_data_transfer_send_data()
464 for (i = windows - 1; i >= 0; i--) { in mhuv2_data_transfer_send_data()
470 bytes_to_send = bytes_in_round & (MHUV2_STAT_BYTES - 1); in mhuv2_data_transfer_send_data()
476 writel_relaxed(word, &mhu->send->ch_wn[priv->ch_wn_idx + windows - 1 - i].stat_set); in mhuv2_data_transfer_send_data()
477 bytes_left -= bytes_to_send; in mhuv2_data_transfer_send_data()
478 bytes_in_round -= bytes_to_send; in mhuv2_data_transfer_send_data()
499 static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg) in get_irq_chan_comb() argument
501 struct mbox_chan *chans = mhu->mbox.chans; in get_irq_chan_comb()
512 for (i = 0; i < mhu->length; i += 2) { in get_irq_chan_comb()
513 protocol = mhu->protocols[i]; in get_irq_chan_comb()
514 windows = mhu->protocols[i + 1]; in get_irq_chan_comb()
517 if (protocol == DOORBELL) in get_irq_chan_comb()
526 /* Return first chan of the window in doorbell mode */ in get_irq_chan_comb()
527 if (protocol == DOORBELL) in get_irq_chan_comb()
528 channel += MHUV2_STAT_BITS * (ch_wn - offset); in get_irq_chan_comb()
534 return ERR_PTR(-EIO); in get_irq_chan_comb()
539 struct mhuv2 *mhu = data; in mhuv2_sender_interrupt() local
540 struct device *dev = mhu->mbox.dev; in mhuv2_sender_interrupt()
547 chan = get_irq_chan_comb(mhu, mhu->send->chcomb_int_st); in mhuv2_sender_interrupt()
552 priv = chan->con_priv; in mhuv2_sender_interrupt()
555 writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + priv->windows - 1].int_clr); in mhuv2_sender_interrupt()
557 if (chan->cl) { in mhuv2_sender_interrupt()
563 priv->ch_wn_idx); in mhuv2_sender_interrupt()
567 /* Clear the interrupt first, so we don't miss any doorbell later */ in mhuv2_sender_interrupt()
568 writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx].int_clr); in mhuv2_sender_interrupt()
571 * In Doorbell mode, make sure no new transitions happen while the in mhuv2_sender_interrupt()
572 * interrupt handler is trying to find the finished doorbell tx in mhuv2_sender_interrupt()
576 spin_lock_irqsave(&mhu->doorbell_pending_lock, flags); in mhuv2_sender_interrupt()
579 * In case of doorbell mode, the first channel of the window is returned in mhuv2_sender_interrupt()
582 stat = readl_relaxed(&mhu->send->ch_wn[priv->ch_wn_idx].stat); in mhuv2_sender_interrupt()
588 if (priv->pending ^ ((stat >> i) & 0x1)) { in mhuv2_sender_interrupt()
589 BUG_ON(!priv->pending); in mhuv2_sender_interrupt()
591 if (!chan->cl) { in mhuv2_sender_interrupt()
592 …dev_warn(dev, "Tx interrupt received on doorbell (%u : %u) channel not currently attached to a mai… in mhuv2_sender_interrupt()
593 priv->ch_wn_idx, i); in mhuv2_sender_interrupt()
598 priv->pending = 0; in mhuv2_sender_interrupt()
603 spin_unlock_irqrestore(&mhu->doorbell_pending_lock, flags); in mhuv2_sender_interrupt()
607 * We may have already processed the doorbell in the previous in mhuv2_sender_interrupt()
611 dev_dbg(dev, "Couldn't find the doorbell (%u) for the Tx interrupt interrupt\n", in mhuv2_sender_interrupt()
612 priv->ch_wn_idx); in mhuv2_sender_interrupt()
619 static struct mbox_chan *get_irq_chan_comb_rx(struct mhuv2 *mhu) in get_irq_chan_comb_rx() argument
625 chan = get_irq_chan_comb(mhu, mhu->recv->chcomb_int_st); in get_irq_chan_comb_rx()
629 priv = chan->con_priv; in get_irq_chan_comb_rx()
634 * In case of doorbell mode, the first channel of the window is returned in get_irq_chan_comb_rx()
637 stat = readl_relaxed(&mhu->recv->ch_wn[priv->ch_wn_idx].stat_masked); in get_irq_chan_comb_rx()
643 static struct mbox_chan *get_irq_chan_stat_rx(struct mhuv2 *mhu) in get_irq_chan_stat_rx() argument
645 struct mbox_chan *chans = mhu->mbox.chans; in get_irq_chan_stat_rx()
650 while (i < mhu->mbox.num_chans) { in get_irq_chan_stat_rx()
652 stat = readl_relaxed(&mhu->recv->ch_wn[priv->ch_wn_idx].stat_masked); in get_irq_chan_stat_rx()
663 return ERR_PTR(-EIO); in get_irq_chan_stat_rx()
666 static struct mbox_chan *get_irq_chan_rx(struct mhuv2 *mhu) in get_irq_chan_rx() argument
668 if (!mhu->minor) in get_irq_chan_rx()
669 return get_irq_chan_stat_rx(mhu); in get_irq_chan_rx()
671 return get_irq_chan_comb_rx(mhu); in get_irq_chan_rx()
676 struct mhuv2 *mhu = arg; in mhuv2_receiver_interrupt() local
677 struct mbox_chan *chan = get_irq_chan_rx(mhu); in mhuv2_receiver_interrupt()
678 struct device *dev = mhu->mbox.dev; in mhuv2_receiver_interrupt()
687 priv = chan->con_priv; in mhuv2_receiver_interrupt()
690 data = priv->ops->read_data(mhu, chan); in mhuv2_receiver_interrupt()
692 if (!chan->cl) { in mhuv2_receiver_interrupt()
694 priv->ch_wn_idx); in mhuv2_receiver_interrupt()
711 struct mhuv2 *mhu = mhu_from_mbox(chan->mbox); in mhuv2_sender_last_tx_done() local
712 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_sender_last_tx_done()
714 return priv->ops->last_tx_done(mhu, chan); in mhuv2_sender_last_tx_done()
719 struct mhuv2 *mhu = mhu_from_mbox(chan->mbox); in mhuv2_sender_send_data() local
720 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_sender_send_data()
722 if (!priv->ops->last_tx_done(mhu, chan)) in mhuv2_sender_send_data()
723 return -EBUSY; in mhuv2_sender_send_data()
725 return priv->ops->send_data(mhu, chan, data); in mhuv2_sender_send_data()
730 struct mhuv2 *mhu = mhu_from_mbox(chan->mbox); in mhuv2_sender_startup() local
731 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_sender_startup()
733 if (priv->ops->tx_startup) in mhuv2_sender_startup()
734 priv->ops->tx_startup(mhu, chan); in mhuv2_sender_startup()
740 struct mhuv2 *mhu = mhu_from_mbox(chan->mbox); in mhuv2_sender_shutdown() local
741 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_sender_shutdown()
743 if (priv->ops->tx_shutdown) in mhuv2_sender_shutdown()
744 priv->ops->tx_shutdown(mhu, chan); in mhuv2_sender_shutdown()
756 struct mhuv2 *mhu = mhu_from_mbox(chan->mbox); in mhuv2_receiver_startup() local
757 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_receiver_startup()
759 return priv->ops->rx_startup(mhu, chan); in mhuv2_receiver_startup()
764 struct mhuv2 *mhu = mhu_from_mbox(chan->mbox); in mhuv2_receiver_shutdown() local
765 struct mhuv2_mbox_chan_priv *priv = chan->con_priv; in mhuv2_receiver_shutdown()
767 priv->ops->rx_shutdown(mhu, chan); in mhuv2_receiver_shutdown()
772 dev_err(chan->mbox->dev, in mhuv2_receiver_send_data()
773 "Trying to transmit on a receiver MHU frame\n"); in mhuv2_receiver_send_data()
774 return -EIO; in mhuv2_receiver_send_data()
779 dev_err(chan->mbox->dev, "Trying to Tx poll on a receiver MHU frame\n"); in mhuv2_receiver_last_tx_done()
793 struct mhuv2 *mhu = mhu_from_mbox(mbox); in mhuv2_mbox_of_xlate() local
794 struct mbox_chan *chans = mbox->chans; in mhuv2_mbox_of_xlate()
795 int channel = 0, i, offset, doorbell, protocol, windows; in mhuv2_mbox_of_xlate() local
797 if (pa->args_count != 2) in mhuv2_mbox_of_xlate()
798 return ERR_PTR(-EINVAL); in mhuv2_mbox_of_xlate()
800 offset = pa->args[0]; in mhuv2_mbox_of_xlate()
801 doorbell = pa->args[1]; in mhuv2_mbox_of_xlate()
802 if (doorbell >= MHUV2_STAT_BITS) in mhuv2_mbox_of_xlate()
805 for (i = 0; i < mhu->length; i += 2) { in mhuv2_mbox_of_xlate()
806 protocol = mhu->protocols[i]; in mhuv2_mbox_of_xlate()
807 windows = mhu->protocols[i + 1]; in mhuv2_mbox_of_xlate()
809 if (protocol == DOORBELL) { in mhuv2_mbox_of_xlate()
811 return &chans[channel + MHUV2_STAT_BITS * offset + doorbell]; in mhuv2_mbox_of_xlate()
814 offset -= windows; in mhuv2_mbox_of_xlate()
817 if (doorbell) in mhuv2_mbox_of_xlate()
824 offset--; in mhuv2_mbox_of_xlate()
829 dev_err(mbox->dev, "Couldn't xlate to a valid channel (%d: %d)\n", in mhuv2_mbox_of_xlate()
830 pa->args[0], doorbell); in mhuv2_mbox_of_xlate()
831 return ERR_PTR(-ENODEV); in mhuv2_mbox_of_xlate()
834 static int mhuv2_verify_protocol(struct mhuv2 *mhu) in mhuv2_verify_protocol() argument
836 struct device *dev = mhu->mbox.dev; in mhuv2_verify_protocol()
839 for (i = 0; i < mhu->length; i += 2) { in mhuv2_verify_protocol()
840 protocol = mhu->protocols[i]; in mhuv2_verify_protocol()
841 windows = mhu->protocols[i + 1]; in mhuv2_verify_protocol()
845 return -EINVAL; in mhuv2_verify_protocol()
849 if (protocol == DOORBELL) { in mhuv2_verify_protocol()
856 return -EINVAL; in mhuv2_verify_protocol()
860 if (total_windows > mhu->windows) { in mhuv2_verify_protocol()
862 total_windows, mhu->windows); in mhuv2_verify_protocol()
863 return -EINVAL; in mhuv2_verify_protocol()
866 mhu->mbox.num_chans = channels; in mhuv2_verify_protocol()
870 static int mhuv2_allocate_channels(struct mhuv2 *mhu) in mhuv2_allocate_channels() argument
872 struct mbox_controller *mbox = &mhu->mbox; in mhuv2_allocate_channels()
874 struct device *dev = mbox->dev; in mhuv2_allocate_channels()
878 chans = devm_kcalloc(dev, mbox->num_chans, sizeof(*chans), GFP_KERNEL); in mhuv2_allocate_channels()
880 return -ENOMEM; in mhuv2_allocate_channels()
882 mbox->chans = chans; in mhuv2_allocate_channels()
884 for (i = 0; i < mhu->length; i += 2) { in mhuv2_allocate_channels()
887 protocol = mhu->protocols[i]; in mhuv2_allocate_channels()
888 windows = mhu->protocols[i + 1]; in mhuv2_allocate_channels()
893 return -ENOMEM; in mhuv2_allocate_channels()
895 priv->ch_wn_idx = next_window; in mhuv2_allocate_channels()
896 priv->ops = &mhuv2_data_transfer_ops; in mhuv2_allocate_channels()
897 priv->windows = windows; in mhuv2_allocate_channels()
898 chans++->con_priv = priv; in mhuv2_allocate_channels()
906 return -ENOMEM; in mhuv2_allocate_channels()
908 priv->ch_wn_idx = next_window + j; in mhuv2_allocate_channels()
909 priv->ops = &mhuv2_doorbell_ops; in mhuv2_allocate_channels()
910 priv->doorbell = k; in mhuv2_allocate_channels()
911 chans++->con_priv = priv; in mhuv2_allocate_channels()
916 * control it per doorbell. in mhuv2_allocate_channels()
918 if (mhu->frame == SENDER_FRAME && mhu->minor) in mhuv2_allocate_channels()
919 writel_relaxed(0x1, &mhu->send->ch_wn[priv->ch_wn_idx].int_en); in mhuv2_allocate_channels()
924 BUG_ON(chans - mbox->chans != mbox->num_chans); in mhuv2_allocate_channels()
929 static int mhuv2_parse_channels(struct mhuv2 *mhu) in mhuv2_parse_channels() argument
931 struct device *dev = mhu->mbox.dev; in mhuv2_parse_channels()
932 const struct device_node *np = dev->of_node; in mhuv2_parse_channels()
940 return -EINVAL; in mhuv2_parse_channels()
945 return -ENOMEM; in mhuv2_parse_channels()
954 mhu->protocols = protocols; in mhuv2_parse_channels()
955 mhu->length = count; in mhuv2_parse_channels()
957 ret = mhuv2_verify_protocol(mhu); in mhuv2_parse_channels()
961 return mhuv2_allocate_channels(mhu); in mhuv2_parse_channels()
964 static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu, in mhuv2_tx_init() argument
967 struct device *dev = mhu->mbox.dev; in mhuv2_tx_init()
970 mhu->frame = SENDER_FRAME; in mhuv2_tx_init()
971 mhu->mbox.ops = &mhuv2_sender_ops; in mhuv2_tx_init()
972 mhu->send = reg; in mhuv2_tx_init()
974 mhu->windows = readl_relaxed_bitfield(&mhu->send->mhu_cfg, struct mhu_cfg_t, num_ch); in mhuv2_tx_init()
975 mhu->minor = readl_relaxed_bitfield(&mhu->send->aidr, struct aidr_t, arch_minor_rev); in mhuv2_tx_init()
977 spin_lock_init(&mhu->doorbell_pending_lock); in mhuv2_tx_init()
983 if (mhu->minor && adev->irq[0]) { in mhuv2_tx_init()
984 ret = devm_request_threaded_irq(dev, adev->irq[0], NULL, in mhuv2_tx_init()
986 IRQF_ONESHOT, "mhuv2-tx", mhu); in mhuv2_tx_init()
991 mhu->mbox.txdone_irq = true; in mhuv2_tx_init()
992 mhu->mbox.txdone_poll = false; in mhuv2_tx_init()
993 mhu->irq = adev->irq[0]; in mhuv2_tx_init()
995 writel_relaxed_bitfield(1, &mhu->send->int_en, struct int_en_t, chcomb); in mhuv2_tx_init()
998 for (i = 0; i < mhu->windows; i++) in mhuv2_tx_init()
999 writel_relaxed(0x0, &mhu->send->ch_wn[i].int_en); in mhuv2_tx_init()
1005 mhu->mbox.txdone_irq = false; in mhuv2_tx_init()
1006 mhu->mbox.txdone_poll = true; in mhuv2_tx_init()
1007 mhu->mbox.txpoll_period = 1; in mhuv2_tx_init()
1011 writel_relaxed(0x1, &mhu->send->access_request); in mhuv2_tx_init()
1012 while (!readl_relaxed(&mhu->send->access_ready)) in mhuv2_tx_init()
1018 static int mhuv2_rx_init(struct amba_device *adev, struct mhuv2 *mhu, in mhuv2_rx_init() argument
1021 struct device *dev = mhu->mbox.dev; in mhuv2_rx_init()
1024 mhu->frame = RECEIVER_FRAME; in mhuv2_rx_init()
1025 mhu->mbox.ops = &mhuv2_receiver_ops; in mhuv2_rx_init()
1026 mhu->recv = reg; in mhuv2_rx_init()
1028 mhu->windows = readl_relaxed_bitfield(&mhu->recv->mhu_cfg, struct mhu_cfg_t, num_ch); in mhuv2_rx_init()
1029 mhu->minor = readl_relaxed_bitfield(&mhu->recv->aidr, struct aidr_t, arch_minor_rev); in mhuv2_rx_init()
1031 mhu->irq = adev->irq[0]; in mhuv2_rx_init()
1032 if (!mhu->irq) { in mhuv2_rx_init()
1034 return -EINVAL; in mhuv2_rx_init()
1037 ret = devm_request_threaded_irq(dev, mhu->irq, NULL, in mhuv2_rx_init()
1039 "mhuv2-rx", mhu); in mhuv2_rx_init()
1046 for (i = 0; i < mhu->windows; i++) in mhuv2_rx_init()
1047 writel_relaxed(0xFFFFFFFF, &mhu->recv->ch_wn[i].mask_set); in mhuv2_rx_init()
1049 if (mhu->minor) in mhuv2_rx_init()
1050 writel_relaxed_bitfield(1, &mhu->recv->int_en, struct int_en_t, chcomb); in mhuv2_rx_init()
1057 struct device *dev = &adev->dev; in mhuv2_probe()
1058 const struct device_node *np = dev->of_node; in mhuv2_probe()
1059 struct mhuv2 *mhu; in mhuv2_probe() local
1061 int ret = -EINVAL; in mhuv2_probe()
1063 reg = devm_of_iomap(dev, dev->of_node, 0, NULL); in mhuv2_probe()
1065 return -ENOMEM; in mhuv2_probe()
1067 mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL); in mhuv2_probe()
1068 if (!mhu) in mhuv2_probe()
1069 return -ENOMEM; in mhuv2_probe()
1071 mhu->mbox.dev = dev; in mhuv2_probe()
1072 mhu->mbox.of_xlate = mhuv2_mbox_of_xlate; in mhuv2_probe()
1074 if (of_device_is_compatible(np, "arm,mhuv2-tx")) in mhuv2_probe()
1075 ret = mhuv2_tx_init(adev, mhu, reg); in mhuv2_probe()
1076 else if (of_device_is_compatible(np, "arm,mhuv2-rx")) in mhuv2_probe()
1077 ret = mhuv2_rx_init(adev, mhu, reg); in mhuv2_probe()
1085 BUG_ON(!mhu->windows); in mhuv2_probe()
1087 ret = mhuv2_parse_channels(mhu); in mhuv2_probe()
1091 amba_set_drvdata(adev, mhu); in mhuv2_probe()
1093 ret = devm_mbox_controller_register(dev, &mhu->mbox); in mhuv2_probe()
1102 struct mhuv2 *mhu = amba_get_drvdata(adev); in mhuv2_remove() local
1104 if (mhu->frame == SENDER_FRAME) in mhuv2_remove()
1105 writel_relaxed(0x0, &mhu->send->access_request); in mhuv2_remove()
1125 .name = "arm-mhuv2",