Commit c59183ae70459db207f8ea5437076e27c72c5867
Exists in
ti-linux-3.14.y
and in
2 other branches
Merge branch 'rproc-linux-3.14.y' of git://git.ti.com/rpmsg/remoteproc into rpmsg-ti-linux-3.14.y
Pull in the updated remoteproc feature branch that includes the updates to the OMAP mailbox driver required for AM33xx/AM43xx PM fixes. * 'rproc-linux-3.14.y' of git://git.ti.com/rpmsg/remoteproc: ARM: dts: AM4372: Add ti,mbox-send-noirq to wkup_m3 mailbox ARM: dts: AM33XX: Add ti,mbox-send-noirq to wkup_m3 mailbox mailbox/omap: Add ti,mbox-send-noirq quirk to fix AM33xx CPU Idle Signed-off-by: Suman Anna <s-anna@ti.com>
Showing 4 changed files Side-by-side Diff
Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
... | ... | @@ -75,6 +75,14 @@ |
75 | 75 | Cell #3 (usr_id) - mailbox user id for identifying the interrupt line |
76 | 76 | associated with generating a tx/rx fifo interrupt. |
77 | 77 | |
78 | +Optional Properties: | |
79 | +-------------------- | |
80 | +- ti,mbox-send-noirq: Quirk flag to allow the client user of this sub-mailbox | |
81 | + to send messages without triggering a Tx ready interrupt, | |
82 | + and to control the Tx ticker. Should be used only on | |
83 | + sub-mailboxes used to communicate with WkupM3 remote | |
84 | + processor on AM33xx/AM43xx SoCs. | |
85 | + | |
78 | 86 | Mailbox Users: |
79 | 87 | ============== |
80 | 88 | A device needing to communicate with a target processor device should specify |
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am4372.dtsi
drivers/mailbox/omap-mailbox.c
... | ... | @@ -67,6 +67,13 @@ |
67 | 67 | #define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32)) |
68 | 68 | #define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32)) |
69 | 69 | |
70 | +/* | |
71 | + * We need this for special case handling where controller indicates done | |
72 | + * state with IRQ but a specific channel needs to use manually ACK (used | |
73 | + * by wkup_m3 on AM33xx/AM43xx). | |
74 | + */ | |
75 | +#define MBOX_TXDONE_BY_ACK (1 << 2) | |
76 | + | |
70 | 77 | struct omap_mbox_fifo { |
71 | 78 | unsigned long msg; |
72 | 79 | unsigned long fifo_stat; |
... | ... | @@ -106,6 +113,7 @@ |
106 | 113 | int rx_irq; |
107 | 114 | |
108 | 115 | const char *name; |
116 | + bool send_no_irq; | |
109 | 117 | }; |
110 | 118 | |
111 | 119 | struct omap_mbox { |
... | ... | @@ -119,6 +127,7 @@ |
119 | 127 | u32 ctx[OMAP4_MBOX_NR_REGS]; |
120 | 128 | u32 intr_type; |
121 | 129 | struct mbox_chan *chan; |
130 | + bool send_no_irq; | |
122 | 131 | }; |
123 | 132 | |
124 | 133 | /* global variables for the mailbox devices */ |
... | ... | @@ -418,6 +427,9 @@ |
418 | 427 | goto fail_request_irq; |
419 | 428 | } |
420 | 429 | |
430 | + if (mbox->send_no_irq) | |
431 | + mbox->chan->txdone_method = MBOX_TXDONE_BY_ACK; | |
432 | + | |
421 | 433 | _omap_mbox_enable_irq(mbox, IRQ_RX); |
422 | 434 | |
423 | 435 | return 0; |
424 | 436 | |
425 | 437 | |
426 | 438 | |
... | ... | @@ -586,14 +598,28 @@ |
586 | 598 | mutex_unlock(&mdev->cfg_lock); |
587 | 599 | } |
588 | 600 | |
589 | -static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data) | |
601 | +static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, void *data) | |
590 | 602 | { |
591 | - struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan); | |
592 | 603 | int ret = -EBUSY; |
593 | 604 | |
594 | - if (!mbox) | |
595 | - return -EINVAL; | |
605 | + if (!mbox_fifo_full(mbox)) { | |
606 | + _omap_mbox_enable_irq(mbox, IRQ_RX); | |
607 | + mbox_fifo_write(mbox, (mbox_msg_t)data); | |
608 | + ret = 0; | |
609 | + _omap_mbox_disable_irq(mbox, IRQ_RX); | |
596 | 610 | |
611 | + /* we must read and ack the interrupt directly from here */ | |
612 | + mbox_fifo_read(mbox); | |
613 | + ack_mbox_irq(mbox, IRQ_RX); | |
614 | + } | |
615 | + | |
616 | + return ret; | |
617 | +} | |
618 | + | |
619 | +static int omap_mbox_chan_send(struct omap_mbox *mbox, void *data) | |
620 | +{ | |
621 | + int ret = -EBUSY; | |
622 | + | |
597 | 623 | if (!mbox_fifo_full(mbox)) { |
598 | 624 | mbox_fifo_write(mbox, (mbox_msg_t)data); |
599 | 625 | ret = 0; |
... | ... | @@ -604,6 +630,22 @@ |
604 | 630 | return ret; |
605 | 631 | } |
606 | 632 | |
633 | +static int omap_mbox_chan_send_data(struct mbox_chan *chan, void *data) | |
634 | +{ | |
635 | + struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan); | |
636 | + int ret; | |
637 | + | |
638 | + if (!mbox) | |
639 | + return -EINVAL; | |
640 | + | |
641 | + if (mbox->send_no_irq) | |
642 | + ret = omap_mbox_chan_send_noirq(mbox, data); | |
643 | + else | |
644 | + ret = omap_mbox_chan_send(mbox, data); | |
645 | + | |
646 | + return ret; | |
647 | +} | |
648 | + | |
607 | 649 | static struct mbox_chan_ops omap_mbox_chan_ops = { |
608 | 650 | .startup = omap_mbox_chan_startup, |
609 | 651 | .send_data = omap_mbox_chan_send_data, |
... | ... | @@ -732,6 +774,9 @@ |
732 | 774 | finfo->rx_usr = tmp[2]; |
733 | 775 | |
734 | 776 | finfo->name = child->name; |
777 | + | |
778 | + if (of_find_property(child, "ti,mbox-send-noirq", NULL)) | |
779 | + finfo->send_no_irq = true; | |
735 | 780 | } else { |
736 | 781 | finfo->tx_id = info->tx_id; |
737 | 782 | finfo->rx_id = info->rx_id; |
... | ... | @@ -791,6 +836,7 @@ |
791 | 836 | fifo->irqstatus = MAILBOX_IRQSTATUS(intr_type, finfo->rx_usr); |
792 | 837 | fifo->irqdisable = MAILBOX_IRQDISABLE(intr_type, finfo->rx_usr); |
793 | 838 | |
839 | + mbox->send_no_irq = finfo->send_no_irq; | |
794 | 840 | mbox->intr_type = intr_type; |
795 | 841 | |
796 | 842 | mbox->parent = mdev; |