From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CC2E2C433B4 for ; Mon, 10 May 2021 05:50:25 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 242D2611F1 for ; Mon, 10 May 2021 05:50:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 242D2611F1 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=aj.id.au Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=xqSA+kbMy/Y4FUfPbeiIOsVLj75M/af5t2XaEG3FV3I=; b=NB1mldPeJm1M2tobEckiuzoji 3ExCX4c9gifxfPKWwSOBg89dyzvnho00KpH9LsOTbJkO/ulS0CHQhA3jBu0ue9/T7VB+G2FMwfAov n25H3aOy51N++lZIcZ6eJ9R/OeOgL5cainCgg5C0QJjIzk1lYhcmomLkxEYt7SfLv3SRcKLlQditE a7HwNzJdWb2pBRkGyLP+zLkfFjNC5dg4jTOaDX4Xg9vlwtrDPBx6ojSOoUG4jjkZSMiuVuOC6AlIZ k9XszZ7TAWAiLosa4l2UpXXqPMgttOWhuVkbHJPCKgl0+GGlppksMyRgxUs9JlBlXvM0+HFnOt4KH lGF+BTtvA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lfymV-00DFCo-2R; Mon, 10 May 2021 05:48:39 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lfyi8-00DEWN-Jz for linux-arm-kernel@desiato.infradead.org; Mon, 10 May 2021 05:44:18 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=E0UnERwk5jiqV0/qRRyEl8PacMyhOcRKLUTOtqwa6T0=; b=vo1MyYNg/JknJaSVvQ5TQl25Dd WlKyankZXAzcvhpbji0ElF0I1/oMKP2fnk0ut+tBs6qG9HwDHzdeRcGa3Ryz3JSTEAFRDx68Blfzx 8n2U0/tRQmkiLmAHT7b+4Y1xo3YC6pEJac+nU0iAl+ZTAtF+ZwuiGviX6A0mu+6GbtX4mhZ7cmjvB sVLUzrO0EfU15s2VpEY6q9BPztdbqz9oi5j/seEDxdAtiDV5vuFT7n0ZnfP9dpr0uPBtJmrCGtfK5 D3icMqKydwxWVnfh7h/8alRy9a/kI9xIZSVKA7MUOyP8dGEPzr6r0QAntNxQR8OWK44pD3u9w6cfa /DGYvlRg==; Received: from new1-smtp.messagingengine.com ([66.111.4.221]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lfyi5-008JHX-Az for linux-arm-kernel@lists.infradead.org; Mon, 10 May 2021 05:44:07 +0000 Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id B65BF5803EE; Mon, 10 May 2021 01:44:04 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Mon, 10 May 2021 01:44:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=from :to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=E0UnERwk5jiqV 0/qRRyEl8PacMyhOcRKLUTOtqwa6T0=; b=C+soS976MudPq2EjIz8LsG3y/he/y YLJAo2Rt2ufLZ7bfjiYR1tZQR0KAhYFj0edkzqfCYxITGegRNEBQBxIqFAcCFz28 OGXgJEyZPdIB2CeioSzF6ZtI4lnkg3NyNvYG23SFRmQWgdJkuxc78ds1F+jCNMmw NSlIgg79BCzlj0vL1pjasz9IdV8BpArt4TME15AFAmk11yQldR6rPgvgPOjbsbU3 oeUY7OZFIRs/2lMp3Ou2WVT3iKfQhBxQk3BScCa+lPRHCgbDW9yQaMvSbZVcGahu 7iPGtTcRtIuJnWpss5veqNNkvvbIaDd5yV+u/8ZOZN6bw0o0DIzpR4ayA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=E0UnERwk5jiqV0/qRRyEl8PacMyhOcRKLUTOtqwa6T0=; b=XlLbOuvx UXg59jWScC9JGvFrTMROD+VdqjVWjz7zmfwKlyZBH6udmPGtu/TBcMA5d4ZenZww bl719vb1YymyzvrFx2VPpsyZA2wMP6VhJxD9Cz5bdu3TpXP/qGZlMlJMGfG+g3sE 5DkcUgpf+iUguz+j6LS/9O85Un+ADSLJ+WzZ27BIDkGLz7RGFF6/4Fe05whSpvV2 RvgtvSpsiYc0tCJwqvZ1rWlcSeUi+uWKmLXupqi/Man11UOTMnTYtD3I3DXzamIe O0fwaDV5eI2xeKEbj120DTv0SMLLd0s/I2Xq+HxgGZMFSpPoXDm7LFEgf3MQVxiB wfZX4k7k2PsBmg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdegjedgleeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomheptehnughrvgifucflvghffhgvrhihuceorghnughrvgifsegr jhdrihgurdgruheqnecuggftrfgrthhtvghrnhepjefgvdevheetkeevgeegleelgfelte etjeffleffvdduudevieffgeetleevhfetnecukfhppedvtdefrdehjedrvdduhedrkeen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegrnhgurh gvfiesrghjrdhiugdrrghu X-ME-Proxy: Received: from localhost.localdomain (unknown [203.57.215.8]) by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 10 May 2021 01:43:58 -0400 (EDT) From: Andrew Jeffery To: openipmi-developer@lists.sourceforge.net, openbmc@lists.ozlabs.org, minyard@acm.org Cc: devicetree@vger.kernel.org, tmaimon77@gmail.com, linux-aspeed@lists.ozlabs.org, avifishman70@gmail.com, venture@google.com, linux-kernel@vger.kernel.org, tali.perry1@gmail.com, robh+dt@kernel.org, chiawei_wang@aspeedtech.com, linux-arm-kernel@lists.infradead.org, benjaminfair@google.com, arnd@arndb.de, zweiss@equinix.com Subject: [PATCH v3 09/16] ipmi: kcs_bmc: Allow clients to control KCS IRQ state Date: Mon, 10 May 2021 15:12:06 +0930 Message-Id: <20210510054213.1610760-10-andrew@aj.id.au> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210510054213.1610760-1-andrew@aj.id.au> References: <20210510054213.1610760-1-andrew@aj.id.au> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210509_224405_543178_7F1F2ED8 X-CRM114-Status: GOOD ( 19.93 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a mechanism for controlling whether the client associated with a KCS device will receive Input Buffer Full (IBF) and Output Buffer Empty (OBE) events. This enables an abstract implementation of poll() for KCS devices. A wart in the implementation is that the ASPEED KCS devices don't support an OBE interrupt for the BMC. Instead we pretend it has one by polling the status register waiting for the Output Buffer Full (OBF) bit to clear, and generating an event when OBE is observed. Signed-off-by: Andrew Jeffery --- drivers/char/ipmi/kcs_bmc.c | 6 ++ drivers/char/ipmi/kcs_bmc.h | 3 + drivers/char/ipmi/kcs_bmc_aspeed.c | 150 ++++++++++++++++++---------- drivers/char/ipmi/kcs_bmc_client.h | 2 + drivers/char/ipmi/kcs_bmc_device.h | 1 + drivers/char/ipmi/kcs_bmc_npcm7xx.c | 25 ++++- 6 files changed, 130 insertions(+), 57 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index 2ec8312ce766..7081541bb6ce 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -176,6 +176,12 @@ void kcs_bmc_unregister_driver(struct kcs_bmc_driver *drv) } EXPORT_SYMBOL(kcs_bmc_unregister_driver); +void kcs_bmc_update_event_mask(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 events) +{ + kcs_bmc->ops->irq_mask_update(kcs_bmc, mask, events); +} +EXPORT_SYMBOL(kcs_bmc_update_event_mask); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Haiyue Wang "); MODULE_AUTHOR("Andrew Jeffery "); diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h index 3f0cce315b4f..fa408b802c79 100644 --- a/drivers/char/ipmi/kcs_bmc.h +++ b/drivers/char/ipmi/kcs_bmc.h @@ -8,6 +8,9 @@ #include +#define KCS_BMC_EVENT_TYPE_OBE BIT(0) +#define KCS_BMC_EVENT_TYPE_IBF BIT(1) + #define KCS_BMC_STR_OBF BIT(0) #define KCS_BMC_STR_IBF BIT(1) #define KCS_BMC_STR_CMD_DAT BIT(3) diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index 8e00675d1019..8b223e58d900 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -60,10 +60,18 @@ #define LPC_ODR4 0x118 #define LPC_STR4 0x11C +#define OBE_POLL_PERIOD (HZ / 2) + struct aspeed_kcs_bmc { struct kcs_bmc_device kcs_bmc; struct regmap *map; + + struct { + spinlock_t lock; + bool remove; + struct timer_list timer; + } obe; }; struct aspeed_kcs_of_ops { @@ -159,68 +167,89 @@ static void aspeed_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enabl switch (kcs_bmc->channel) { case 1: - if (enable) { - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF1, LPC_HICR2_IBFIF1); - regmap_update_bits(priv->map, LPC_HICR0, - LPC_HICR0_LPC1E, LPC_HICR0_LPC1E); - } else { - regmap_update_bits(priv->map, LPC_HICR0, - LPC_HICR0_LPC1E, 0); - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF1, 0); - } - break; - + regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC1E, enable * LPC_HICR0_LPC1E); + return; case 2: - if (enable) { - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF2, LPC_HICR2_IBFIF2); - regmap_update_bits(priv->map, LPC_HICR0, - LPC_HICR0_LPC2E, LPC_HICR0_LPC2E); - } else { - regmap_update_bits(priv->map, LPC_HICR0, - LPC_HICR0_LPC2E, 0); - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF2, 0); - } - break; - + regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC2E, enable * LPC_HICR0_LPC2E); + return; case 3: - if (enable) { - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF3, LPC_HICR2_IBFIF3); - regmap_update_bits(priv->map, LPC_HICR0, - LPC_HICR0_LPC3E, LPC_HICR0_LPC3E); - regmap_update_bits(priv->map, LPC_HICR4, - LPC_HICR4_KCSENBL, LPC_HICR4_KCSENBL); - } else { - regmap_update_bits(priv->map, LPC_HICR0, - LPC_HICR0_LPC3E, 0); - regmap_update_bits(priv->map, LPC_HICR4, - LPC_HICR4_KCSENBL, 0); - regmap_update_bits(priv->map, LPC_HICR2, - LPC_HICR2_IBFIF3, 0); - } - break; - + regmap_update_bits(priv->map, LPC_HICR0, LPC_HICR0_LPC3E, enable * LPC_HICR0_LPC3E); + regmap_update_bits(priv->map, LPC_HICR4, + LPC_HICR4_KCSENBL, enable * LPC_HICR4_KCSENBL); + return; case 4: - if (enable) - regmap_update_bits(priv->map, LPC_HICRB, - LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E, - LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E); + regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_LPC4E, enable * LPC_HICRB_LPC4E); + return; + default: + pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel); + return; + } +} + +static void aspeed_kcs_check_obe(struct timer_list *timer) +{ + struct aspeed_kcs_bmc *priv = container_of(timer, struct aspeed_kcs_bmc, obe.timer); + unsigned long flags; + u8 str; + + spin_lock_irqsave(&priv->obe.lock, flags); + if (priv->obe.remove) { + spin_unlock_irqrestore(&priv->obe.lock, flags); + return; + } + + str = aspeed_kcs_inb(&priv->kcs_bmc, priv->kcs_bmc.ioreg.str); + if (str & KCS_BMC_STR_OBF) { + mod_timer(timer, jiffies + OBE_POLL_PERIOD); + spin_unlock_irqrestore(&priv->obe.lock, flags); + return; + } + spin_unlock_irqrestore(&priv->obe.lock, flags); + + kcs_bmc_handle_event(&priv->kcs_bmc); +} + +static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state) +{ + struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc); + + /* We don't have an OBE IRQ, emulate it */ + if (mask & KCS_BMC_EVENT_TYPE_OBE) { + if (KCS_BMC_EVENT_TYPE_OBE & state) + mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD); else - regmap_update_bits(priv->map, LPC_HICRB, - LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E, - 0); - break; + del_timer(&priv->obe.timer); + } - default: - break; + if (mask & KCS_BMC_EVENT_TYPE_IBF) { + const bool enable = !!(state & KCS_BMC_EVENT_TYPE_IBF); + + switch (kcs_bmc->channel) { + case 1: + regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIF1, + enable * LPC_HICR2_IBFIF1); + return; + case 2: + regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIF2, + enable * LPC_HICR2_IBFIF2); + return; + case 3: + regmap_update_bits(priv->map, LPC_HICR2, LPC_HICR2_IBFIF3, + enable * LPC_HICR2_IBFIF3); + return; + case 4: + regmap_update_bits(priv->map, LPC_HICRB, LPC_HICRB_IBFIF4, + enable * LPC_HICRB_IBFIF4); + return; + default: + pr_warn("%s: Unsupported channel: %d", __func__, kcs_bmc->channel); + return; + } } } static const struct kcs_bmc_device_ops aspeed_kcs_ops = { + .irq_mask_update = aspeed_kcs_irq_mask_update, .io_inputb = aspeed_kcs_inb, .io_outputb = aspeed_kcs_outb, .io_updateb = aspeed_kcs_updateb, @@ -373,6 +402,10 @@ static int aspeed_kcs_probe(struct platform_device *pdev) return -ENODEV; } + spin_lock_init(&priv->obe.lock); + priv->obe.remove = false; + timer_setup(&priv->obe.timer, aspeed_kcs_check_obe, 0); + aspeed_kcs_set_address(kcs_bmc, addr); rc = aspeed_kcs_config_irq(kcs_bmc, pdev); @@ -381,6 +414,8 @@ static int aspeed_kcs_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); + aspeed_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), + KCS_BMC_EVENT_TYPE_IBF); aspeed_kcs_enable_channel(kcs_bmc, true); kcs_bmc_add_device(&priv->kcs_bmc); @@ -397,6 +432,15 @@ static int aspeed_kcs_remove(struct platform_device *pdev) kcs_bmc_remove_device(kcs_bmc); + aspeed_kcs_enable_channel(kcs_bmc, false); + aspeed_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), 0); + + /* Make sure it's proper dead */ + spin_lock_irq(&priv->obe.lock); + priv->obe.remove = true; + spin_unlock_irq(&priv->obe.lock); + del_timer_sync(&priv->obe.timer); + return 0; } diff --git a/drivers/char/ipmi/kcs_bmc_client.h b/drivers/char/ipmi/kcs_bmc_client.h index cb38b56cda85..d14e8e0fa230 100644 --- a/drivers/char/ipmi/kcs_bmc_client.h +++ b/drivers/char/ipmi/kcs_bmc_client.h @@ -38,6 +38,8 @@ void kcs_bmc_unregister_driver(struct kcs_bmc_driver *drv); int kcs_bmc_enable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_client *client); void kcs_bmc_disable_device(struct kcs_bmc_device *kcs_bmc, struct kcs_bmc_client *client); +void kcs_bmc_update_event_mask(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 events); + u8 kcs_bmc_read_data(struct kcs_bmc_device *kcs_bmc); void kcs_bmc_write_data(struct kcs_bmc_device *kcs_bmc, u8 data); u8 kcs_bmc_read_status(struct kcs_bmc_device *kcs_bmc); diff --git a/drivers/char/ipmi/kcs_bmc_device.h b/drivers/char/ipmi/kcs_bmc_device.h index dd90f8c2ebd6..a1410eb16308 100644 --- a/drivers/char/ipmi/kcs_bmc_device.h +++ b/drivers/char/ipmi/kcs_bmc_device.h @@ -9,6 +9,7 @@ #include "kcs_bmc.h" struct kcs_bmc_device_ops { + void (*irq_mask_update)(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 enable); u8 (*io_inputb)(struct kcs_bmc_device *kcs_bmc, u32 reg); void (*io_outputb)(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 b); void (*io_updateb)(struct kcs_bmc_device *kcs_bmc, u32 reg, u8 mask, u8 b); diff --git a/drivers/char/ipmi/kcs_bmc_npcm7xx.c b/drivers/char/ipmi/kcs_bmc_npcm7xx.c index 9f0b168e487c..f8b7162fb830 100644 --- a/drivers/char/ipmi/kcs_bmc_npcm7xx.c +++ b/drivers/char/ipmi/kcs_bmc_npcm7xx.c @@ -38,6 +38,7 @@ #define KCS2CTL 0x2A #define KCS3CTL 0x3C #define KCS_CTL_IBFIE BIT(0) +#define KCS_CTL_OBEIE BIT(0) #define KCS1IE 0x1C #define KCS2IE 0x2E @@ -117,13 +118,23 @@ static void npcm7xx_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enab { struct npcm7xx_kcs_bmc *priv = to_npcm7xx_kcs_bmc(kcs_bmc); - regmap_update_bits(priv->map, priv->reg->ctl, KCS_CTL_IBFIE, - enable ? KCS_CTL_IBFIE : 0); - regmap_update_bits(priv->map, priv->reg->ie, KCS_IE_IRQE | KCS_IE_HIRQE, enable ? KCS_IE_IRQE | KCS_IE_HIRQE : 0); } +static void npcm7xx_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state) +{ + struct npcm7xx_kcs_bmc *priv = to_npcm7xx_kcs_bmc(kcs_bmc); + + if (KCS_BMC_EVENT_TYPE_OBE & mask) + regmap_update_bits(priv->map, priv->reg->ctl, KCS_CTL_OBEIE, + !!(KCS_BMC_EVENT_TYPE_OBE & state) * KCS_CTL_OBEIE); + + if (KCS_BMC_EVENT_TYPE_IBF & mask) + regmap_update_bits(priv->map, priv->reg->ctl, KCS_CTL_IBFIE, + !!(state & KCS_BMC_EVENT_TYPE_IBF) * KCS_CTL_IBFIE); +} + static irqreturn_t npcm7xx_kcs_irq(int irq, void *arg) { struct kcs_bmc_device *kcs_bmc = arg; @@ -146,6 +157,7 @@ static int npcm7xx_kcs_config_irq(struct kcs_bmc_device *kcs_bmc, } static const struct kcs_bmc_device_ops npcm7xx_kcs_ops = { + .irq_mask_update = npcm7xx_kcs_irq_mask_update, .io_inputb = npcm7xx_kcs_inb, .io_outputb = npcm7xx_kcs_outb, .io_updateb = npcm7xx_kcs_updateb, @@ -186,11 +198,13 @@ static int npcm7xx_kcs_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv); - npcm7xx_kcs_enable_channel(kcs_bmc, true); rc = npcm7xx_kcs_config_irq(kcs_bmc, pdev); if (rc) return rc; + npcm7xx_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), + KCS_BMC_EVENT_TYPE_IBF); + npcm7xx_kcs_enable_channel(kcs_bmc, true); pr_info("channel=%u idr=0x%x odr=0x%x str=0x%x\n", chan, @@ -208,6 +222,9 @@ static int npcm7xx_kcs_remove(struct platform_device *pdev) kcs_bmc_remove_device(kcs_bmc); + npcm7xx_kcs_enable_channel(kcs_bmc, false); + npcm7xx_kcs_irq_mask_update(kcs_bmc, (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE), 0); + return 0; } -- 2.27.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel