From patchwork Tue Aug 6 21:40:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suman Anna X-Patchwork-Id: 2839667 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 772469F479 for ; Tue, 6 Aug 2013 21:47:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8D90B201FB for ; Tue, 6 Aug 2013 21:47:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7D1FF201F8 for ; Tue, 6 Aug 2013 21:47:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756818Ab3HFVr0 (ORCPT ); Tue, 6 Aug 2013 17:47:26 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:39769 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756731Ab3HFVrX (ORCPT ); Tue, 6 Aug 2013 17:47:23 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id r76LkuB5005459; Tue, 6 Aug 2013 16:46:56 -0500 Received: from DLEE70.ent.ti.com (dlee70.ent.ti.com [157.170.170.113]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r76LkuNU017252; Tue, 6 Aug 2013 16:46:56 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.2.342.3; Tue, 6 Aug 2013 16:46:56 -0500 Received: from localhost (irmo.am.dhcp.ti.com [128.247.74.241]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r76LkuMk024251; Tue, 6 Aug 2013 16:46:56 -0500 From: Suman Anna To: Tony Lindgren , Benoit Cousson CC: Paul Walmsley , Ohad Ben-Cohen , Jassi Brar , , , , Suman Anna Subject: [PATCHv3 7/8] mailbox/omap: add code to support the wkupm3 operations Date: Tue, 6 Aug 2013 16:40:38 -0500 Message-ID: <1375825238-18299-1-git-send-email-s-anna@ti.com> X-Mailer: git-send-email 1.8.3.3 MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The WkupM3 mailbox used for triggering PM operations such as suspend and resume on AM33x/AM43x is special in that the M3 processor cannot access the mailbox registers. However, an interrupt is needed to be sent to request the M3 to perform a desired PM operation. This patch adds the support for this special mailbox through separate ops for this mailbox. These ops are designed to have the WkupM3's Rx interrupt programmed within the driver, during transmission of a message. The message is immediately read back and the internal mailbox interrupt acknowledged as well to avoid triggering any spurious interrupts to the M3. Signed-off-by: Suman Anna --- drivers/mailbox/mailbox-omap2.c | 87 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c index fef18f4..00ac2a2 100644 --- a/drivers/mailbox/mailbox-omap2.c +++ b/drivers/mailbox/mailbox-omap2.c @@ -36,6 +36,8 @@ #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) +#define AM33X_MBOX_WKUPM3_USR 3 + #define MBOX_REG_SIZE 0x120 #define OMAP4_MBOX_REG_SIZE 0x130 @@ -179,6 +181,57 @@ static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) return (int)(enable & status & bit); } +static void wkupm3_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) +{ + struct omap_mbox2_priv *p = mbox->priv; + u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; + unsigned long irqenable = ((irq == IRQ_RX) ? + OMAP4_MAILBOX_IRQENABLE(AM33X_MBOX_WKUPM3_USR) : p->irqenable); + + l = mbox_read_reg(mbox->parent, irqenable); + l |= bit; + mbox_write_reg(mbox->parent, l, irqenable); +} + +static void wkupm3_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) +{ + struct omap_mbox2_priv *p = mbox->priv; + u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; + unsigned long irqdisable = ((irq == IRQ_RX) ? + OMAP4_MAILBOX_IRQENABLE_CLR(AM33X_MBOX_WKUPM3_USR) : p->irqdisable); + + mbox_write_reg(mbox->parent, bit, irqdisable); +} + +static void wkupm3_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) +{ + struct omap_mbox2_priv *p = mbox->priv; + u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; + unsigned long irqstatus = ((irq == IRQ_RX) ? + OMAP4_MAILBOX_IRQSTATUS(AM33X_MBOX_WKUPM3_USR) : p->irqstatus); + + mbox_write_reg(mbox->parent, bit, irqstatus); + + /* Flush posted write for irq status to avoid spurious interrupts */ + mbox_read_reg(mbox->parent, irqstatus); +} + +static int wkupm3_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) +{ + struct omap_mbox2_priv *p = mbox->priv; + u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; + u32 enable, status; + + /* WkupM3 mailbox does not use a receive queue */ + if (irq == IRQ_RX) + return 0; + + enable = mbox_read_reg(mbox->parent, p->irqenable); + status = mbox_read_reg(mbox->parent, p->irqstatus); + + return (int)(enable & status & bit); +} + static void omap2_mbox_save_ctx(struct omap_mbox *mbox) { int i; @@ -215,6 +268,20 @@ static void omap2_mbox_restore_ctx(struct omap_mbox *mbox) } } +static void wkupm3_mbox_send_data(struct omap_mbox *mbox, mbox_msg_t msg) +{ + mbox_msg_t rmsg; + + /* enable the mbox Rx interrupt for WkupM3 only briefly */ + wkupm3_mbox_enable_irq(mbox, IRQ_RX); + omap2_mbox_fifo_write(mbox, msg); + wkupm3_mbox_disable_irq(mbox, IRQ_RX); + + /* read back the message and ack the interrupt on behalf of WkupM3 */ + rmsg = omap2_mbox_fifo_read(mbox); + wkupm3_mbox_ack_irq(mbox, IRQ_RX); +} + static struct omap_mbox_ops omap2_mbox_ops = { .startup = omap2_mbox_startup, .shutdown = omap2_mbox_shutdown, @@ -230,6 +297,21 @@ static struct omap_mbox_ops omap2_mbox_ops = { .restore_ctx = omap2_mbox_restore_ctx, }; +static struct omap_mbox_ops wkupm3_mbox_ops = { + .startup = omap2_mbox_startup, + .shutdown = omap2_mbox_shutdown, + .fifo_read = omap2_mbox_fifo_read, + .fifo_write = wkupm3_mbox_send_data, + .fifo_empty = omap2_mbox_fifo_empty, + .poll_for_space = omap2_mbox_poll_for_space, + .enable_irq = wkupm3_mbox_enable_irq, + .disable_irq = wkupm3_mbox_disable_irq, + .ack_irq = wkupm3_mbox_ack_irq, + .is_irq = wkupm3_mbox_is_irq, + .save_ctx = omap2_mbox_save_ctx, + .restore_ctx = omap2_mbox_restore_ctx, +}; + static const struct of_device_id omap_mailbox_of_match[] = { { .compatible = "ti,omap2-mailbox", @@ -387,7 +469,10 @@ static int omap2_mbox_probe(struct platform_device *pdev) mbox->priv = priv; mbox->parent = mdev; mbox->name = info->name; - mbox->ops = &omap2_mbox_ops; + if (!strcmp(mbox->name, "wkup_m3")) + mbox->ops = &wkupm3_mbox_ops; + else + mbox->ops = &omap2_mbox_ops; mbox->irq = platform_get_irq(pdev, info->irq_id); if (mbox->irq < 0) { ret = mbox->irq;