From patchwork Wed Nov 4 15:23:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Liao, Bard" X-Patchwork-Id: 317876 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=-11.2 required=3.0 tests=BAYES_00, DATE_IN_PAST_06_12, DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, 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 D1F9EC2D0A3 for ; Thu, 5 Nov 2020 03:18:34 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (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 A301420867 for ; Thu, 5 Nov 2020 03:18:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="pf86sRsN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A301420867 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C9DBC1664; Thu, 5 Nov 2020 04:17:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C9DBC1664 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1604546311; bh=pz9H0VNJCOJr8M1Zfj53UcWuQYfMfPQwLud0zd30pO4=; h=From:To:Subject:Date:Cc:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=pf86sRsNYkilaqAedeG+IihUvfA2z7xHV8fY0eA2yHanFmmFLRoUr7KLcmDUbiRqb wic17wac1EwbH3baecoqSNL/w529EHR8DVz/o60ud/L+yKxeUemUFiYc8M1OngvGgz N1R5ejI9WYShGJ9GqEfah6AMQK6l21ip1yhzHrKI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 31AF1F80162; Thu, 5 Nov 2020 04:17:41 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4140EF80171; Thu, 5 Nov 2020 04:17:39 +0100 (CET) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id DCD7CF80150 for ; Thu, 5 Nov 2020 04:17:31 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz DCD7CF80150 IronPort-SDR: yflllAmv1vEflS25vlol5wtjYDqewUxhbpVOS2DtZIfTDMUdCOUEQCcJEdPwDGGIKJ2HbkmAlG CBKcZF+4CkcQ== X-IronPort-AV: E=McAfee;i="6000,8403,9795"; a="149174759" X-IronPort-AV: E=Sophos;i="5.77,452,1596524400"; d="scan'208";a="149174759" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Nov 2020 19:17:29 -0800 IronPort-SDR: vs+tsekgqge/n4nblXHSEk8dv6N3b/3MFe5j3GzPiAJA3dhwwq4Mgu00J62mRCMqb1sv7iiBjx jIvzFCb1MlqA== X-IronPort-AV: E=Sophos;i="5.77,452,1596524400"; d="scan'208";a="539192540" Received: from bard-ubuntu.sh.intel.com ([10.239.13.33]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Nov 2020 19:17:26 -0800 From: Bard Liao To: alsa-devel@alsa-project.org, vkoul@kernel.org Subject: [PATCH] soundwire: SDCA: detect sdca_cascade interrupt Date: Wed, 4 Nov 2020 23:23:58 +0800 Message-Id: <20201104152358.9518-1-yung-chuan.liao@linux.intel.com> X-Mailer: git-send-email 2.17.1 Cc: vinod.koul@linaro.org, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, pierre-louis.bossart@linux.intel.com, hui.wang@canonical.com, srinivas.kandagatla@linaro.org, jank@cadence.com, mengdong.lin@intel.com, sanyog.r.kale@intel.com, bard.liao@intel.com X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Pierre-Louis Bossart The SoundWire 1.2 specification defines an "SDCA cascade" bit which handles a logical OR of all SDCA interrupt sources (up to 30 defined). Due to limitations of the addressing space, this bit is located in the SDW_DP0_INT register when DP0 is used, or alternatively in the DP0_SDCA_Support_INTSTAT register when DP0 is not used. To allow for both cases to be handled, this bit will be checked in the main device-level interrupt handling code. This will result in the register being read twice if DP0 is enabled, but it's not clear how to optimize this case. It's also more logical to deal with this interrupt at the device than the port level, this bit is really not DP0 specific and its location in the DP0_INTSTAT bit is only due to the lack of free space in SCP_INTSTAT_1. The SDCA_Cascade bit cannot be masked or cleared, so the interrupt handling only forwards the detection to the Slave driver, which will deal with reading the relevant SDCA status bits and clearing them. The bus driver only signals the detection. The communication with the Slave driver is based on the same interrupt callback, with only an extension to provide the status of the sdca_cascade bit. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Guennadi Liakhovetski Signed-off-by: Bard Liao --- drivers/soundwire/bus.c | 28 +++++++++++++++++++++++++++- include/linux/soundwire/sdw.h | 4 ++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 8eaf31e76677..ffe4600fd95b 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -1424,6 +1424,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) int port_num, stat, ret, count = 0; unsigned long port; bool slave_notify = false; + u8 sdca_cascade = 0; u8 buf, buf2[2], _buf, _buf2[2]; bool parity_check; bool parity_quirk; @@ -1453,6 +1454,16 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) goto io_err; } + if (slave->prop.is_sdca) { + ret = sdw_read(slave, SDW_DP0_INT); + if (ret < 0) { + dev_err(slave->bus->dev, + "SDW_DP0_INT read failed:%d\n", ret); + goto io_err; + } + sdca_cascade = ret & SDW_DP0_SDCA_CASCADE; + } + do { /* * Check parity, bus clash and Slave (impl defined) @@ -1489,6 +1500,10 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) clear |= SDW_SCP_INT1_IMPL_DEF; } + /* the SDCA interrupts are cleared in the codec driver .interrupt_callback() */ + if (sdca_cascade) + slave_notify = true; + /* Check port 0 - 3 interrupts */ port = buf & SDW_SCP_INT1_PORT0_3; @@ -1526,6 +1541,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) /* Update the Slave driver */ if (slave_notify && slave->ops && slave->ops->interrupt_callback) { + slave_intr.sdca_cascade = sdca_cascade; slave_intr.control_port = clear; memcpy(slave_intr.port, &port_status, sizeof(slave_intr.port)); @@ -1563,11 +1579,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave) goto io_err; } + if (slave->prop.is_sdca) { + ret = sdw_read(slave, SDW_DP0_INT); + if (ret < 0) { + dev_err(slave->bus->dev, + "SDW_DP0_INT read failed:%d\n", ret); + goto io_err; + } + sdca_cascade = ret & SDW_DP0_SDCA_CASCADE; + } + /* Make sure no interrupts are pending */ buf &= _buf; buf2[0] &= _buf2[0]; buf2[1] &= _buf2[1]; - stat = buf || buf2[0] || buf2[1]; + stat = buf || buf2[0] || buf2[1] || sdca_cascade; /* * Exit loop if Slave is continuously in ALERT state even diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 41cc1192f9aa..f0b01b728640 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -359,6 +359,7 @@ struct sdw_dpn_prop { * @sink_dpn_prop: Sink Data Port N properties * @scp_int1_mask: SCP_INT1_MASK desired settings * @quirks: bitmask identifying deltas from the MIPI specification + * @is_sdca: the Slave supports the SDCA specification */ struct sdw_slave_prop { u32 mipi_revision; @@ -382,6 +383,7 @@ struct sdw_slave_prop { struct sdw_dpn_prop *sink_dpn_prop; u8 scp_int1_mask; u32 quirks; + bool is_sdca; }; #define SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY BIT(0) @@ -479,10 +481,12 @@ struct sdw_slave_id { /** * struct sdw_slave_intr_status - Slave interrupt status + * @sdca_cascade: set if the Slave device reports an SDCA interrupt * @control_port: control port status * @port: data port status */ struct sdw_slave_intr_status { + bool sdca_cascade; u8 control_port; u8 port[15]; };