From patchwork Fri Oct 6 15:51:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 115075 Delivered-To: patch@linaro.org Received: by 10.80.163.170 with SMTP id s39csp1519568edb; Fri, 6 Oct 2017 08:52:03 -0700 (PDT) X-Received: by 10.84.216.19 with SMTP id m19mr2382429pli.143.1507305123505; Fri, 06 Oct 2017 08:52:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507305123; cv=none; d=google.com; s=arc-20160816; b=bOaxQuRBIUHjuLs3CK0c6VnbmXjdON+tUvGwNQdNeGBteXJxDUaDngcdSiassSbT2Q yx/uwAfAqEeTvD8REID82hc7QXPyXGRe11xpB/XoAZlrFgHa+WsL1lSaVpjdok1tuWs/ wSUHEnH68CYMBvNDFTp2R+KXmFI/CPTAO/XQKddGH4gYAkVCSl8qD2zk2/53ZsxVr777 pVezW4kzgd9ed/rjfCn1fKVhvtz3yt4ADyL1OcL+wOAdibjIUkllqVee9MyrA8jv1upP 6Mf7kHaSrShzuiDvcUtHpGSpG8yC91DBSvmbw9w+1HR2H1P3y4SDunnDRNYmtdo7QQwM p5lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=PFGEIhPz3E8/7EmbNRiulK5UWBtM+0xVkiOXwMyzOtQ=; b=z7ZyKVsboJLqMtKu1AoEia9HkUWQOYOWGslLr8zJ7IkvKwDXzfJ1lYbISWTvyj/G+V iF5voLl6PWUW0u4l2K+SbOj22Z6+2btSnvqgxVOz2s07dPlRgvf+Wlgsk/BzWDFp+F1m w0bRNgtSRK6xikrDaKhRSkeHmAH9gLgPURl5Ujl1kehQFdcQsI/JbS72c+ormowTcSHA Bq5CgzSLY5FOl6umFmAkPnRdsv+b9iu1lkwbD2Vdt7+G3hNPnyvFxPkcFa+yClkBU/b7 iYzttAo0IiNLQeGLyDwxJ3gHF5gJNn77ava/l6pgQKFjbsx8BH81OaMYjoLwdeWpXoTD nmIA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EWb4xAst; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i186si1462881pfg.401.2017.10.06.08.52.03; Fri, 06 Oct 2017 08:52:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EWb4xAst; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752879AbdJFPwA (ORCPT + 6 others); Fri, 6 Oct 2017 11:52:00 -0400 Received: from mail-wm0-f45.google.com ([74.125.82.45]:49039 "EHLO mail-wm0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752651AbdJFPv5 (ORCPT ); Fri, 6 Oct 2017 11:51:57 -0400 Received: by mail-wm0-f45.google.com with SMTP id i124so8357638wmf.3 for ; Fri, 06 Oct 2017 08:51:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=a/N8VYiRep0NEX/Ui4/W+J/e3VbbWQGLY9aZC0IcarM=; b=EWb4xAst0TnCTc4HcJK1YuW2JuvNPBAWZn1uRH4sDzo6h+UyW7pwZR/uQHEkIxje8z Kjsuyd04Gz2Or1mwXOMXIdidNSIBVzgHp3pNM8Gu/ORm2vkQcXgsjOgO7z68eG0SGgbm noSlyxdFfSSwnZG4xasUqher0FO4ffZfFfrU0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=a/N8VYiRep0NEX/Ui4/W+J/e3VbbWQGLY9aZC0IcarM=; b=oj2Hs70sO9bkmhZdTmc7iC9+S+gM7HzRPJJQSq7SCFxlhJwp48JAYWY7EWzomLQ73J GoHXtADqeZQ4cO2t0a9nquMQsc2riEQ1O3W5aWG8wbIQPAY1g/1+aAQNpFWvZQaR8Yyc rcI0gT/7D9lZr//WfMKI62eBjNQ/QBn5KY33Vv1a40r+wqzN82pQ3NFkQRn8QFC8J60H qnR8a5WIL2dwKeQ8+wKCwdyOqAa76Rifow01CnZMsb1lirNpujoHP+52/vEmQlfU0axa joMBet7D8IChxRFT+/MS0Mf/5LCNUpS7B7BGTPv2YybHSv/3Me06TNjMqnAmk2vII8hj rMFg== X-Gm-Message-State: AMCzsaUcgZz3TTcD9Vf2WUJD+txZ4I1nle5hgULSnM0B7K+ySEx0Y7i4 O6z8pmhcUk0G9udh1oKlOIMHug== X-Google-Smtp-Source: AOwi7QBCAKKiJxnlsuCUFY2MyMYv377izeuMrDhwgkXEtRdwGg8gJcf2HxXD9jw7O4hAZDap0PeW2Q== X-Received: by 10.28.138.202 with SMTP id m193mr2372485wmd.63.1507305115178; Fri, 06 Oct 2017 08:51:55 -0700 (PDT) Received: from localhost.localdomain (static.8.26.4.46.clients.your-server.de. [46.4.26.8]) by smtp.gmail.com with ESMTPSA id r21sm1510327wmd.26.2017.10.06.08.51.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Oct 2017 08:51:54 -0700 (PDT) From: srinivas.kandagatla@linaro.org To: gregkh@linuxfoundation.org, broonie@kernel.org, alsa-devel@alsa-project.org Cc: sdharia@codeaurora.org, bp@suse.de, poeschel@lemonage.de, treding@nvidia.com, gong.chen@linux.intel.com, andreas.noever@gmail.com, alan@linux.intel.com, mathieu.poirier@linaro.org, daniel@ffwll.ch, jkosina@suse.cz, sharon.dvir1@mail.huji.ac.il, joe@perches.com, davem@davemloft.net, james.hogan@imgtec.com, michael.opdenacker@free-electrons.com, robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kheitke@audience.com, linux-arm-msm@vger.kernel.org, arnd@arndb.de, Srinivas Kandagatla Subject: [Patch v6 2/7] slimbus: Add messaging APIs to slimbus framework Date: Fri, 6 Oct 2017 17:51:31 +0200 Message-Id: <20171006155136.4682-3-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> References: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Sagar Dharia Slimbus devices use value-element, and information elements to control device parameters (e.g. value element is used to represent gain for codec, information element is used to represent interrupt status for codec when codec interrupt fires). Messaging APIs are used to set/get these value and information elements. Slimbus specification uses 8-bit "transaction IDs" for messages where a read-value is anticipated. Framework uses a table of pointers to store those TIDs and responds back to the caller in O(1). Caller can opt to do synchronous, or asynchronous reads/writes. For asynchronous operations, the callback will be called from atomic context. TX and RX circular rings are used to allow queuing of multiple transfers per controller. Controller can choose size of these rings based of controller HW implementation. The buffers are coerently mapped so that controller can utilize DMA operations for the transactions without remapping every transaction buffer. Statically allocated rings help to improve performance by avoiding overhead of dynamically allocating transactions on need basis. Signed-off-by: Sagar Dharia Tested-by: Naveen Kaje Signed-off-by: Srinivas Kandagatla --- drivers/slimbus/Makefile | 2 +- drivers/slimbus/slim-core.c | 15 ++ drivers/slimbus/slim-messaging.c | 471 +++++++++++++++++++++++++++++++++++++++ include/linux/slimbus.h | 161 +++++++++++++ 4 files changed, 648 insertions(+), 1 deletion(-) create mode 100644 drivers/slimbus/slim-messaging.c -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile index f580704..bd1d35e 100644 --- a/drivers/slimbus/Makefile +++ b/drivers/slimbus/Makefile @@ -2,4 +2,4 @@ # Makefile for kernel slimbus framework. # obj-$(CONFIG_SLIMBUS) += slimbus.o -slimbus-y := slim-core.o +slimbus-y := slim-core.o slim-messaging.o diff --git a/drivers/slimbus/slim-core.c b/drivers/slimbus/slim-core.c index de3ef79..5b1da28 100644 --- a/drivers/slimbus/slim-core.c +++ b/drivers/slimbus/slim-core.c @@ -362,6 +362,19 @@ int slim_register_controller(struct slim_controller *ctrl) ctrl->max_cg = SLIM_MAX_CLK_GEAR; mutex_init(&ctrl->m_ctrl); + spin_lock_init(&ctrl->tx.lock); + spin_lock_init(&ctrl->rx.lock); + + ctrl->pending_wr = kcalloc((ctrl->tx.n - 1), + sizeof(struct slim_pending), + GFP_KERNEL); + if (!ctrl->pending_wr) { + ret = -ENOMEM; + goto wr_alloc_failed; + } + + sema_init(&ctrl->tx_sem, (ctrl->tx.n - 1)); + ret = device_register(&ctrl->dev); if (ret) goto dev_reg_failed; @@ -380,6 +393,8 @@ int slim_register_controller(struct slim_controller *ctrl) err_workq_failed: device_unregister(&ctrl->dev); dev_reg_failed: + kfree(ctrl->pending_wr); +wr_alloc_failed: mutex_lock(&slim_lock); idr_remove(&ctrl_idr, ctrl->nr); mutex_unlock(&slim_lock); diff --git a/drivers/slimbus/slim-messaging.c b/drivers/slimbus/slim-messaging.c new file mode 100644 index 0000000..adcba67 --- /dev/null +++ b/drivers/slimbus/slim-messaging.c @@ -0,0 +1,471 @@ +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include + +/** + * slim_msg_response: Deliver Message response received from a device to the + * framework. + * @ctrl: Controller handle + * @reply: Reply received from the device + * @len: Length of the reply + * @tid: Transaction ID received with which framework can associate reply. + * Called by controller to inform framework about the response received. + * This helps in making the API asynchronous, and controller-driver doesn't need + * to manage 1 more table other than the one managed by framework mapping TID + * with buffers + */ +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len) +{ + struct slim_val_inf *msg; + unsigned long flags; + + spin_lock_irqsave(&ctrl->txn_lock, flags); + msg = ctrl->tid_tbl[tid]; + if (msg == NULL || msg->rbuf == NULL) { + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + dev_err(&ctrl->dev, "Got response to invalid TID:%d, len:%d\n", + tid, len); + return; + } + ctrl->tid_tbl[tid] = NULL; + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + + memcpy(msg->rbuf, reply, len); + if (msg->comp_cb) + msg->comp_cb(msg->ctx, 0); +} +EXPORT_SYMBOL_GPL(slim_msg_response); + +struct slim_cb_data { + struct completion *comp; + int ret; +}; + +static void slim_sync_default_cb(void *ctx, int err) +{ + struct slim_cb_data *cbd = ctx; + + cbd->ret = err; + complete(cbd->comp); +} + +/** + * slim_processtxn: Process a slimbus-messaging transaction + * @ctrl: Controller handle + * @txn: Transaction to be sent over SLIMbus + * Called by controller to transmit messaging transactions not dealing with + * Interface/Value elements. (e.g. transmittting a message to assign logical + * address to a slave device + * Returns: + * -ETIMEDOUT: If transmission of this message timed out (e.g. due to bus lines + * not being clocked or driven by controller) + * -ENOTCONN: If the transmitted message was not ACKed by destination device. + */ +int slim_processtxn(struct slim_controller *ctrl, + struct slim_msg_txn *txn) +{ + int ret, i = 0; + unsigned long flags; + u8 *buf; + bool async = false; + struct slim_cb_data cbd; + DECLARE_COMPLETION_ONSTACK(done); + bool need_tid = slim_tid_txn(txn->mt, txn->mc); + + if (!txn->msg->comp_cb) { + txn->msg->comp_cb = slim_sync_default_cb; + cbd.comp = &done; + txn->msg->ctx = &cbd; + } else { + async = true; + } + + buf = slim_get_tx(ctrl, txn, need_tid); + if (!buf) + return -ENOMEM; + + if (need_tid) { + spin_lock_irqsave(&ctrl->txn_lock, flags); + for (i = 0; i < ctrl->last_tid; i++) { + if (ctrl->tid_tbl[i] == NULL) + break; + } + if (i >= ctrl->last_tid) { + if (ctrl->last_tid == (SLIM_MAX_TIDS - 1)) { + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + slim_return_tx(ctrl, -ENOMEM); + return -ENOMEM; + } + ctrl->last_tid++; + } + ctrl->tid_tbl[i] = txn->msg; + txn->tid = i; + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + } + + ret = ctrl->xfer_msg(ctrl, txn, buf); + + if (!ret && !async) { /* sync transaction */ + /* Fine-tune calculation after bandwidth management */ + unsigned long ms = txn->rl + 100; + + ret = wait_for_completion_timeout(&done, + msecs_to_jiffies(ms)); + if (!ret) + slim_return_tx(ctrl, -ETIMEDOUT); + + ret = cbd.ret; + } + + if (ret && need_tid) { + spin_lock_irqsave(&ctrl->txn_lock, flags); + /* Invalidate the transaction */ + ctrl->tid_tbl[txn->tid] = NULL; + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + } + if (ret) + dev_err(&ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n", + txn->mt, txn->mc, txn->la, ret); + if (!async) { + txn->msg->comp_cb = NULL; + txn->msg->ctx = NULL; + } + return ret; +} +EXPORT_SYMBOL_GPL(slim_processtxn); + +static int slim_val_inf_sanity(struct slim_controller *ctrl, + struct slim_val_inf *msg, u8 mc) +{ + if (!msg || msg->num_bytes > 16 || + (msg->start_offset + msg->num_bytes) > 0xC00) + goto reterr; + switch (mc) { + case SLIM_MSG_MC_REQUEST_VALUE: + case SLIM_MSG_MC_REQUEST_INFORMATION: + if (msg->rbuf != NULL) + return 0; + break; + case SLIM_MSG_MC_CHANGE_VALUE: + case SLIM_MSG_MC_CLEAR_INFORMATION: + if (msg->wbuf != NULL) + return 0; + break; + case SLIM_MSG_MC_REQUEST_CHANGE_VALUE: + case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION: + if (msg->rbuf != NULL && msg->wbuf != NULL) + return 0; + break; + default: + break; + } +reterr: + dev_err(&ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n", + msg->start_offset, mc); + return -EINVAL; +} + +static u16 slim_slicecodefromsize(u16 req) +{ + static const u8 codetosize[8] = {1, 2, 3, 4, 6, 8, 12, 16}; + + if (req >= ARRAY_SIZE(codetosize)) + return 0; + else + return codetosize[req]; +} + +static u16 slim_slicesize(int code) +{ + static const u8 sizetocode[16] = { + 0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7 + }; + + clamp(code, 1, (int)ARRAY_SIZE(sizetocode)); + return sizetocode[code - 1]; +} + +int slim_xfer_msg(struct slim_controller *ctrl, + struct slim_device *sbdev, struct slim_val_inf *msg, + u8 mc) +{ + DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg); + struct slim_msg_txn *txn = &txn_stack; + int ret; + u16 sl, cur; + + ret = slim_val_inf_sanity(ctrl, msg, mc); + if (ret) + return ret; + + sl = slim_slicesize(msg->num_bytes); + + dev_dbg(&ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n", + msg->start_offset, msg->num_bytes, mc, sl); + + cur = slim_slicecodefromsize(sl); + txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4)); + + switch (mc) { + case SLIM_MSG_MC_REQUEST_CHANGE_VALUE: + case SLIM_MSG_MC_CHANGE_VALUE: + case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION: + case SLIM_MSG_MC_CLEAR_INFORMATION: + txn->rl += msg->num_bytes; + default: + break; + } + + if (slim_tid_txn(txn->mt, txn->mc)) + txn->rl++; + + return slim_processtxn(ctrl, txn); +} +EXPORT_SYMBOL_GPL(slim_xfer_msg); + +/* Message APIs Unicast message APIs used by slimbus slave drivers */ + +/* + * slim_request_val_element: request value element + * @sb: client handle requesting elemental message reads, writes. + * @msg: Input structure for start-offset, number of bytes to read. + * context: can sleep + * Returns: + * -EINVAL: Invalid parameters + * -ETIMEDOUT: If transmission of this message timed out (e.g. due to bus lines + * not being clocked or driven by controller) + * -ENOTCONN: If the transmitted message was not ACKed by destination device. + */ +int slim_request_val_element(struct slim_device *sb, + struct slim_val_inf *msg) +{ + struct slim_controller *ctrl = sb->ctrl; + + if (!ctrl) + return -EINVAL; + + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_VALUE); +} +EXPORT_SYMBOL_GPL(slim_request_val_element); + +/** + * slim_request_inf_element: Request a info element + * @sb: client handle requesting elemental message reads. + * @msg: Input structure for start-offset, number of bytes to read + * wbuf will contain information element(s) bit masks to be cleared. + * rbuf will return what the information element value was + */ +int slim_request_inf_element(struct slim_device *sb, + struct slim_val_inf *msg) +{ + struct slim_controller *ctrl = sb->ctrl; + + if (!ctrl) + return -EINVAL; + + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_INFORMATION); +} +EXPORT_SYMBOL_GPL(slim_request_inf_element); + + +/* + * slim_change_val_element: change a given value element + * @sb: client handle requesting elemental message reads, writes. + * @msg: Input structure for start-offset, number of bytes to write. + * context: can sleep + * Returns: + * -EINVAL: Invalid parameters + * -ETIMEDOUT: If transmission of this message timed out (e.g. due to bus lines + * not being clocked or driven by controller) + * -ENOTCONN: If the transmitted message was not ACKed by destination device. + */ +int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg) +{ + struct slim_controller *ctrl = sb->ctrl; + + if (!ctrl) + return -EINVAL; + + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CHANGE_VALUE); +} +EXPORT_SYMBOL_GPL(slim_change_val_element); + +/** + * slim_clear_inf_element: Clear info element + * @sb: client handle requesting elemental message reads, writes. + * @msg: Input structure for start-offset, number of bytes to read + * wbuf will contain information element(s) bit masks to be cleared. + * rbuf will return what the information element value was + */ +int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg) +{ + struct slim_controller *ctrl = sb->ctrl; + + if (!ctrl) + return -EINVAL; + + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CLEAR_INFORMATION); +} +EXPORT_SYMBOL_GPL(slim_clear_inf_element); + +/* + * slim_request_val_element: change and request a given value element + * @sb: client handle requesting elemental message reads, writes. + * @msg: Input structure for start-offset, number of bytes to write. + * context: can sleep + * Returns: + * -EINVAL: Invalid parameters + * -ETIMEDOUT: If transmission of this message timed out (e.g. due to bus lines + * not being clocked or driven by controller) + * -ENOTCONN: If the transmitted message was not ACKed by destination device. + */ +int slim_request_change_val_element(struct slim_device *sb, + struct slim_val_inf *msg) +{ + struct slim_controller *ctrl = sb->ctrl; + + if (!ctrl) + return -EINVAL; + + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE); +} +EXPORT_SYMBOL_GPL(slim_request_change_val_element); + +/** + * slim_request_clear_inf_element: Clear and request info element + * @sb: client handle requesting elemental message reads, writes. + * @msg: Input structure for start-offset, number of bytes to read + * wbuf will contain information element(s) bit masks to be cleared. + * rbuf will return what the information element value was + */ +int slim_request_clear_inf_element(struct slim_device *sb, + struct slim_val_inf *msg) +{ + struct slim_controller *ctrl = sb->ctrl; + + if (!ctrl) + return -EINVAL; + + return slim_xfer_msg(ctrl, sb, msg, + SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION); +} +EXPORT_SYMBOL_GPL(slim_request_clear_inf_element); + +/* Functions to get/return TX, RX buffers for messaging. */ + +/** + * slim_get_rx: To get RX buffers for messaging. + * @ctrl: Controller handle + * These functions are called by controller to process the RX buffers. + * RX buffer is requested by controller when data is received from HW, but is + * not processed (e.g. 'report-present message was sent by HW in ISR and SW + * needs more time to process the buffer to assign Logical Address) + * RX buffer is returned back to the pool when associated RX action + * is taken (e.g. Received message is decoded and client's + * response buffer is filled in.) + */ +void *slim_get_rx(struct slim_controller *ctrl) +{ + unsigned long flags; + int idx; + + spin_lock_irqsave(&ctrl->rx.lock, flags); + if ((ctrl->rx.tail + 1) % ctrl->rx.n == ctrl->rx.head) { + spin_unlock_irqrestore(&ctrl->rx.lock, flags); + dev_err(&ctrl->dev, "RX QUEUE full!"); + return NULL; + } + idx = ctrl->rx.tail; + ctrl->rx.tail = (ctrl->rx.tail + 1) % ctrl->rx.n; + spin_unlock_irqrestore(&ctrl->rx.lock, flags); + + return ctrl->rx.base + (idx * ctrl->rx.sl_sz); +} +EXPORT_SYMBOL_GPL(slim_get_rx); + +int slim_return_rx(struct slim_controller *ctrl, void *buf) +{ + unsigned long flags; + + spin_lock_irqsave(&ctrl->rx.lock, flags); + if (ctrl->rx.tail == ctrl->rx.head) { + spin_unlock_irqrestore(&ctrl->rx.lock, flags); + return -ENODATA; + } + memcpy(buf, ctrl->rx.base + (ctrl->rx.head * ctrl->rx.sl_sz), + ctrl->rx.sl_sz); + ctrl->rx.head = (ctrl->rx.head + 1) % ctrl->rx.n; + spin_unlock_irqrestore(&ctrl->rx.lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(slim_return_rx); + +void slim_return_tx(struct slim_controller *ctrl, int err) +{ + unsigned long flags; + int idx; + struct slim_pending cur; + + spin_lock_irqsave(&ctrl->tx.lock, flags); + idx = ctrl->tx.head; + ctrl->tx.head = (ctrl->tx.head + 1) % ctrl->tx.n; + cur = ctrl->pending_wr[idx]; + spin_unlock_irqrestore(&ctrl->tx.lock, flags); + + if (!cur.cb) + dev_err(&ctrl->dev, "NULL Transaction or completion"); + else + cur.cb(cur.ctx, err); + + up(&ctrl->tx_sem); +} +EXPORT_SYMBOL_GPL(slim_return_tx); + +/** + * slim_get_tx: To get TX buffers for messaging. + * @ctrl: Controller handle + * These functions are called by controller to process the TX buffers. + * TX buffer is requested by controller when it's filled-in and sent to the + * HW. When HW has finished processing this buffer, controller should return it + * back to the pool. + */ +void *slim_get_tx(struct slim_controller *ctrl, struct slim_msg_txn *txn, + bool need_tid) +{ + unsigned long flags; + int ret, idx; + + ret = down_interruptible(&ctrl->tx_sem); + if (ret < 0) { + dev_err(&ctrl->dev, "TX semaphore down returned:%d", ret); + return NULL; + } + spin_lock_irqsave(&ctrl->tx.lock, flags); + + if (((ctrl->tx.head + 1) % ctrl->tx.n) == ctrl->tx.tail) { + spin_unlock_irqrestore(&ctrl->tx.lock, flags); + dev_err(&ctrl->dev, "controller TX buf unavailable"); + up(&ctrl->tx_sem); + return NULL; + } + idx = ctrl->tx.tail; + ctrl->tx.tail = (ctrl->tx.tail + 1) % ctrl->tx.n; + ctrl->pending_wr[idx].cb = txn->msg->comp_cb; + ctrl->pending_wr[idx].ctx = txn->msg->ctx; + ctrl->pending_wr[idx].need_tid = need_tid; + spin_unlock_irqrestore(&ctrl->tx.lock, flags); + + return ctrl->tx.base + (idx * ctrl->tx.sl_sz); +} +EXPORT_SYMBOL_GPL(slim_get_tx); diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h index b5064b6..080d86a 100644 --- a/include/linux/slimbus.h +++ b/include/linux/slimbus.h @@ -15,6 +15,7 @@ #include #include #include +#include #include /** @@ -34,6 +35,9 @@ extern struct bus_type slimbus_type; #define SLIM_FRM_SLOTS_PER_SUPERFRAME 16 #define SLIM_GDE_SLOTS_PER_SUPERFRAME 2 +/* MAX in-flight transactions neededing transaction ID (8-bit, per spec) */ +#define SLIM_MAX_TIDS 256 + struct slim_controller; struct slim_device; @@ -100,12 +104,115 @@ struct slim_addrt { #define SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS 0x2 #define SLIM_MSG_MC_REPORT_ABSENT 0xF +/* Information Element management messages */ +#define SLIM_MSG_MC_REQUEST_INFORMATION 0x20 +#define SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION 0x21 +#define SLIM_MSG_MC_REPLY_INFORMATION 0x24 +#define SLIM_MSG_MC_CLEAR_INFORMATION 0x28 +#define SLIM_MSG_MC_REPORT_INFORMATION 0x29 + +/* Value Element management messages */ +#define SLIM_MSG_MC_REQUEST_VALUE 0x60 +#define SLIM_MSG_MC_REQUEST_CHANGE_VALUE 0x61 +#define SLIM_MSG_MC_REPLY_VALUE 0x64 +#define SLIM_MSG_MC_CHANGE_VALUE 0x68 + /* Destination type Values */ #define SLIM_MSG_DEST_LOGICALADDR 0 #define SLIM_MSG_DEST_ENUMADDR 1 #define SLIM_MSG_DEST_BROADCAST 3 /** + * struct slim_val_inf: Slimbus value or information element + * @start_offset: Specifies starting offset in information/value element map + * @num_bytes: upto 16. This ensures that the message will fit the slicesize + * per slimbus spec + * @comp_cb: Callback if this read/write is asynchronous + * @ctx: Argument for comp_cb + */ +struct slim_val_inf { + u16 start_offset; + u8 num_bytes; + u8 *rbuf; + const u8 *wbuf; + void (*comp_cb)(void *ctx, int err); + void *ctx; +}; + +/** + * struct slim_msg_txn: Message to be sent by the controller. + * This structure has packet header, payload and buffer to be filled (if any) + * @rl: Header field. remaining length. + * @mt: Header field. Message type. + * @mc: Header field. LSB is message code for type mt. + * @dt: Header field. Destination type. + * @ec: Element code. Used for elemental access APIs. + * @len: Length of payload. (excludes ec) + * @tid: Transaction ID. Used for messages expecting response. + * (relevant for message-codes involving read operation) + * @la: Logical address of the device this message is going to. + * (Not used when destination type is broadcast.) + * @msg: Elemental access message to be read/written + */ +struct slim_msg_txn { + u8 rl; + u8 mt; + u8 mc; + u8 dt; + u16 ec; + u8 tid; + u8 la; + struct slim_val_inf *msg; +}; + +/* Frequently used message transaction structures */ +#define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \ + struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\ + 0, la, msg, } + +#define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \ + struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\ + 0, la, msg, } + +#define DEFINE_SLIM_EDEST_TXN(name, mc, rl, la, msg) \ + struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_ENUMADDR, 0,\ + 0, la, msg, } + +/** + * struct slim_ctrl_buf: circular buffer used by contoller for TX, RX + * @base: virtual base address for this buffer + * @phy: physical address for this buffer (this is useful if controller can + * DMA the buffers for TX and RX to/from controller hardware + * @lock: lock protecting head and tail + * @head: index where buffer is returned back + * @tail: index from where buffer is consumed + * @sl_sz: byte-size of each slot in this buffer + * @n: number of elements in this circular ring, note that this needs to be + * 1 more than actual buffers to allow for one open slot + */ +struct slim_ctrl_buf { + void *base; + phys_addr_t phy; + spinlock_t lock; + int head; + int tail; + int sl_sz; + int n; +}; + +/** + * struct slim_pending: context of pending transfers + * @cb: callback for this transfer + * @ctx: contex for the callback function + * @need_tid: True if this transfer need Transaction ID + */ +struct slim_pending { + void (*cb)(void *ctx, int err); + void *ctx; + bool need_tid; +}; + +/** * struct slim_controller: Controls every instance of SLIMbus * (similar to 'master' on SPI) * 'Manager device' is responsible for device management, bandwidth @@ -139,6 +246,16 @@ struct slim_addrt { * @addrt: Logical address table * @num_dev: Number of active slimbus slaves on this bus * @wq: Workqueue per controller used to notify devices when they report present + * @tid_tbl: Table of transactions having transaction ID + * @txn_lock: Lock to protect table of transactions + * @rx: RX buffers used by controller to receive messages. Ctrl may receive more + * than 1 message (e.g. multiple report-present messages or messages from + * multiple slaves). + * @tx: TX buffers used by controller to transmit messages. Ctrl may have + * ability to send/queue multiple messages to HW at once. + * @pending_wr: Pending write transactions to be acknowledged by controller + * @tx_sem: Semaphore for available TX buffers for this controller + * @last_tid: Last used entry for TID transactions * @xfer_msg: Transfer a message on this controller (this can be a broadcast * control/status message like data channel setup, or a unicast message * like value element read/write. @@ -161,6 +278,15 @@ struct slim_controller { struct slim_addrt *addrt; u8 num_dev; struct workqueue_struct *wq; + struct slim_val_inf *tid_tbl[SLIM_MAX_TIDS]; + u8 last_tid; + spinlock_t txn_lock; + struct slim_ctrl_buf tx; + struct slim_ctrl_buf rx; + struct slim_pending *pending_wr; + struct semaphore tx_sem; + int (*xfer_msg)(struct slim_controller *ctrl, + struct slim_msg_txn *tx, void *buf); int (*set_laddr)(struct slim_controller *ctrl, struct slim_eaddr *ea, u8 laddr); int (*get_laddr)(struct slim_controller *ctrl, @@ -295,5 +421,40 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data) { dev_set_drvdata(&dev->dev, data); } +int slim_request_val_element(struct slim_device *sb, + struct slim_val_inf *msg); +int slim_change_val_element(struct slim_device *sb, + struct slim_val_inf *msg); +int slim_request_change_val_element(struct slim_device *sb, + struct slim_val_inf *msg); + + + +int slim_request_inf_element(struct slim_device *sb, + struct slim_val_inf *msg); +int slim_clear_inf_element(struct slim_device *sb, + struct slim_val_inf *msg); +int slim_request_clear_inf_element(struct slim_device *sb, + struct slim_val_inf *msg); +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, + u8 len); + +int slim_processtxn(struct slim_controller *ctrl, struct slim_msg_txn *txn); + +void *slim_get_rx(struct slim_controller *ctrl); +int slim_return_rx(struct slim_controller *ctrl, void *buf); +void *slim_get_tx(struct slim_controller *ctrl, struct slim_msg_txn *txn, + bool need_tid); +void slim_return_tx(struct slim_controller *ctrl, int err); + +static inline bool slim_tid_txn(u8 mt, u8 mc) +{ + return (mt == SLIM_MSG_MT_CORE && + (mc == SLIM_MSG_MC_REQUEST_INFORMATION || + mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION || + mc == SLIM_MSG_MC_REQUEST_VALUE || + mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION)); +} +/* end of message apis */ #endif /* _LINUX_SLIMBUS_H */ From patchwork Fri Oct 6 15:51:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 115076 Delivered-To: patch@linaro.org Received: by 10.80.163.170 with SMTP id s39csp1519635edb; Fri, 6 Oct 2017 08:52:06 -0700 (PDT) X-Received: by 10.84.129.77 with SMTP id 71mr2405712plb.151.1507305126812; Fri, 06 Oct 2017 08:52:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507305126; cv=none; d=google.com; s=arc-20160816; b=tcE96m/saTJyNDd3hlwjl+foAGwnfOC5Y2vbX62/jZJ/sHCzqYBREs/LqcrjVLI0AO x8Tx0dNwODwSzr9G4y4pMMaXQRPpNebGcZBA9tPxMfRoIOvBGb8g3eZnykM/k57UkcOC x2zGTPfYNm6eE3VhZ/UuSvJlQBf1RZqaxdMjNFyTE5m2yHj91MTaQyWMsqakwBCLzLD/ DJTJasM9XtEDwP7LsNxwUL1rDxPasRdOYY9kzOw7tYvJ3JtsV+xxNKaVcOV60ATEFqG7 7fuZbG1scT6Yr27Yhyn6AfSSxdA75mhBGsmzAjVbzQXo+7sYOSzJZlCU5wvEF6z1XB4D nE1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=iAWyGkN1gBFXLBOIxyrlW1ppV4ZQMmib3K7cYHUrrOc=; b=V871A6qh+sA0I971mC+9SQlSOf1UQSwBYZyXGGqUWIA0OQHpn+n6UREyzv6KaBhfIl yUt7gKcdPZPmx+9O2OEuoXR+OC+r7lGkiTVhywRCpabqcIzRxAJBYEy+VtXKeUnmK8Wi DthC3lKqlYJOdkdUE3dfkzPd51GlEt00ou89/b+Y4pKXQX//il/M9D4TqQNoS4p20vXK ExQ34ckCWcRWDpfbJoJJqLSReDuHbJpW4y4FgKzxLGFRkCr3eHT7K2+YlmOxdNvPwzCv DgaTR3F5iuz7bcgrBuX36kkD3YyMIKaCkfegJJyYzSo8LqB1OsFiq4nhflYBlvLecM9+ i/Bw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=BWDwUO/h; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i186si1462881pfg.401.2017.10.06.08.52.06; Fri, 06 Oct 2017 08:52:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=BWDwUO/h; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752739AbdJFPwE (ORCPT + 6 others); Fri, 6 Oct 2017 11:52:04 -0400 Received: from mail-wm0-f51.google.com ([74.125.82.51]:46897 "EHLO mail-wm0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752626AbdJFPv6 (ORCPT ); Fri, 6 Oct 2017 11:51:58 -0400 Received: by mail-wm0-f51.google.com with SMTP id m72so8428837wmc.1 for ; Fri, 06 Oct 2017 08:51:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=P83enxAMQMNdgpW2R5ixgvtdA/oqXsP7SF8XSTc2P1o=; b=BWDwUO/htMPjUO2e9FUQu9nw7hrAOpqhmdDO/olDFAbb7Id9Odf7UEIY9b3lH63JX7 QDzYvTqiwWf6IUSJpMDnhz+8X4jAzSFzCUXD4IfoY1vBv4IMsJvdRCySt8YLwFoUTgAw h+1SYMSt9/bz/YxfqgDK5IYHELSncjrQqUxWE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=P83enxAMQMNdgpW2R5ixgvtdA/oqXsP7SF8XSTc2P1o=; b=CDttbGZl0xI7F2y8AOLU7H8V4Ggv5FGaOLwt+CQZIJccUdcaXMcPeWYyqRX0ELL3Ej PM4l84xQ0Kj+uMIxoFCvSY8IwY4kteflt0VCSbn75Bt1gko/FCmMrPDP6NwP4nFCKaCT 6fPiWXE5uNk0OQpJprHUGHGUq7gnKV4dwL0bUJRlgmb04nLNOoxBbJcaSII5/xPK0Kb/ FPQeMI80ZxUFeclteTEktrg/EIXRZ6UNoEjhNGP300AFeRS15bw42VDLPFabsM1Hs4Js 0z5uAFWfXYHoenF3jZgwXm81fhdFq+AFnFAQIydbrriCSJx7sIFHo3qysf8nLzkCtu+y AlFg== X-Gm-Message-State: AMCzsaWuKCJemVQreFIzQJp6l26/SzPlQKLCBn8rl6g1MKei/RH4QKWX mD7JeSuxQ9Jh9dg1XeFCj84c8g== X-Google-Smtp-Source: AOwi7QCGvgXjV3FHcImaICOh63RmJsRPGnNDmGvePQIU03PeCTafisniX/ELOUHKhD5X6zOmK94TwA== X-Received: by 10.28.54.89 with SMTP id d86mr2091376wma.101.1507305116931; Fri, 06 Oct 2017 08:51:56 -0700 (PDT) Received: from localhost.localdomain (static.8.26.4.46.clients.your-server.de. [46.4.26.8]) by smtp.gmail.com with ESMTPSA id r21sm1510327wmd.26.2017.10.06.08.51.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Oct 2017 08:51:55 -0700 (PDT) From: srinivas.kandagatla@linaro.org To: gregkh@linuxfoundation.org, broonie@kernel.org, alsa-devel@alsa-project.org Cc: sdharia@codeaurora.org, bp@suse.de, poeschel@lemonage.de, treding@nvidia.com, gong.chen@linux.intel.com, andreas.noever@gmail.com, alan@linux.intel.com, mathieu.poirier@linaro.org, daniel@ffwll.ch, jkosina@suse.cz, sharon.dvir1@mail.huji.ac.il, joe@perches.com, davem@davemloft.net, james.hogan@imgtec.com, michael.opdenacker@free-electrons.com, robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kheitke@audience.com, linux-arm-msm@vger.kernel.org, arnd@arndb.de, Srinivas Kandagatla Subject: [Patch v6 3/7] slimbus: qcom: Add Qualcomm Slimbus controller driver Date: Fri, 6 Oct 2017 17:51:32 +0200 Message-Id: <20171006155136.4682-4-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> References: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Sagar Dharia This controller driver programs manager, interface, and framer devices for Qualcomm's slimbus HW block. Manager component currently implements logical address setting, and messaging interface. Interface device reports bus synchronization information, and framer device clocks the bus from the time it's woken up, until clock-pause is executed by the manager device. Signed-off-by: Sagar Dharia Signed-off-by: Srinivas Kandagatla --- .../devicetree/bindings/slimbus/slim-qcom-ctrl.txt | 43 ++ drivers/slimbus/Kconfig | 9 + drivers/slimbus/Makefile | 3 + drivers/slimbus/slim-qcom-ctrl.c | 594 +++++++++++++++++++++ drivers/slimbus/slim-qcom.h | 63 +++ 5 files changed, 712 insertions(+) create mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt create mode 100644 drivers/slimbus/slim-qcom-ctrl.c create mode 100644 drivers/slimbus/slim-qcom.h -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt new file mode 100644 index 0000000..081110d --- /dev/null +++ b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt @@ -0,0 +1,43 @@ +Qualcomm SLIMBUS controller +This controller is used if applications processor driver controls slimbus +master component. + +Required properties: + + - #address-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt + - #size-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt + + - reg : Offset and length of the register region(s) for the device + - reg-names : Register region name(s) referenced in reg above + Required register resource entries are: + "ctrl": Physical adderess of controller register blocks + - compatible : should be "qcom,-slim" for SOC specific compatible or + "qcom,slim" if using generic qcom SLIM IP. + - interrupts : Interrupt number used by this controller + - clocks : Interface and core clocks used by this slimbus controller + - clock-names : Required clock-name entries are: + "iface_clk" : Interface clock for this controller + "core_clk" : Interrupt for controller core's BAM + + +Optional property: + - reg entry for slew rate : If slew rate control register is provided, this + entry should be used. + - reg-name for slew rate: "slew" + +Example: + slim@28080000 { + compatible = "qcom,slim"; + #address-cells = <4>; + #size-cells = <0>; + reg = <0x28080000 0x2000>, <0x80207C 4>; + reg-names = "ctrl", "slew"; + interrupts = <0 33 0>; + clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>; + clock-names = "iface_clk", "core_clk"; + + codec: wcd9310@1{ + compatible = "slim217,60"; + reg = <1 0>; + }; + }; diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig index f0b118a..438773e 100644 --- a/drivers/slimbus/Kconfig +++ b/drivers/slimbus/Kconfig @@ -9,3 +9,12 @@ menuconfig SLIMBUS If unsure, choose N. +if SLIMBUS +config SLIM_QCOM_CTRL + tristate "Qualcomm Slimbus Manager Component" + depends on SLIMBUS + help + Select driver if Qualcomm's Slimbus Manager Component is + programmed using Linux kernel. + +endif diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile index bd1d35e..ed8521a 100644 --- a/drivers/slimbus/Makefile +++ b/drivers/slimbus/Makefile @@ -3,3 +3,6 @@ # obj-$(CONFIG_SLIMBUS) += slimbus.o slimbus-y := slim-core.o slim-messaging.o + +#Controllers +obj-$(CONFIG_SLIM_QCOM_CTRL) += slim-qcom-ctrl.o diff --git a/drivers/slimbus/slim-qcom-ctrl.c b/drivers/slimbus/slim-qcom-ctrl.c new file mode 100644 index 0000000..d0574e1 --- /dev/null +++ b/drivers/slimbus/slim-qcom-ctrl.c @@ -0,0 +1,594 @@ +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "slim-qcom.h" + +#define MSM_SLIM_NAME "msm_slim_ctrl" + +/* Manager registers */ +#define MGR_CFG 0x200 +#define MGR_STATUS 0x204 +#define MGR_INT_EN 0x210 +#define MGR_INT_STAT 0x214 +#define MGR_INT_CLR 0x218 +#define MGR_TX_MSG 0x230 +#define MGR_RX_MSG 0x270 +#define MGR_IE_STAT 0x2F0 +#define MGR_VE_STAT 0x300 +#define MGR_CFG_ENABLE 1 + +/* Framer registers */ +#define FRM_CFG 0x400 +#define FRM_STAT 0x404 +#define FRM_INT_EN 0x410 +#define FRM_INT_STAT 0x414 +#define FRM_INT_CLR 0x418 +#define FRM_WAKEUP 0x41C +#define FRM_CLKCTL_DONE 0x420 +#define FRM_IE_STAT 0x430 +#define FRM_VE_STAT 0x440 + +/* Interface registers */ +#define INTF_CFG 0x600 +#define INTF_STAT 0x604 +#define INTF_INT_EN 0x610 +#define INTF_INT_STAT 0x614 +#define INTF_INT_CLR 0x618 +#define INTF_IE_STAT 0x630 +#define INTF_VE_STAT 0x640 + +/* Interrupt status bits */ +#define MGR_INT_TX_NACKED_2 BIT(25) +#define MGR_INT_MSG_BUF_CONTE BIT(26) +#define MGR_INT_RX_MSG_RCVD BIT(30) +#define MGR_INT_TX_MSG_SENT BIT(31) + +/* Framer config register settings */ +#define FRM_ACTIVE 1 +#define CLK_GEAR 7 +#define ROOT_FREQ 11 +#define REF_CLK_GEAR 15 +#define INTR_WAKE 19 + +static int msm_slim_queue_tx(struct msm_slim_ctrl *dev, u32 *buf, u8 len, + u32 tx_reg) +{ + int i; + + for (i = 0; i < (len + 3) >> 2; i++) { + dev_dbg(dev->dev, "AHB TX data:0x%x\n", buf[i]); + writel_relaxed(buf[i], dev->base + tx_reg + (i * 4)); + } + /* Guarantee that message is sent before returning */ + mb(); + return 0; +} + +static irqreturn_t msm_slim_interrupt(int irq, void *d) +{ + struct msm_slim_ctrl *dev = d; + u32 stat = readl_relaxed(dev->base + MGR_INT_STAT); + int err = 0, ret = IRQ_NONE; + + if (stat & MGR_INT_TX_MSG_SENT || stat & MGR_INT_TX_NACKED_2) { + if (stat & MGR_INT_TX_MSG_SENT) + writel_relaxed(MGR_INT_TX_MSG_SENT, + dev->base + MGR_INT_CLR); + if (stat & MGR_INT_TX_NACKED_2) { + u32 mgr_stat = readl_relaxed(dev->base + MGR_STATUS); + u32 mgr_ie_stat = readl_relaxed(dev->base + + MGR_IE_STAT); + u32 frm_stat = readl_relaxed(dev->base + FRM_STAT); + u32 frm_cfg = readl_relaxed(dev->base + FRM_CFG); + u32 frm_intr_stat = readl_relaxed(dev->base + + FRM_INT_STAT); + u32 frm_ie_stat = readl_relaxed(dev->base + + FRM_IE_STAT); + u32 intf_stat = readl_relaxed(dev->base + INTF_STAT); + u32 intf_intr_stat = readl_relaxed(dev->base + + INTF_INT_STAT); + u32 intf_ie_stat = readl_relaxed(dev->base + + INTF_IE_STAT); + + writel_relaxed(MGR_INT_TX_NACKED_2, dev->base + + MGR_INT_CLR); + dev_err(dev->dev, "TX Nack MGR:int:0x%x, stat:0x%x\n", + stat, mgr_stat); + dev_err(dev->dev, "TX Nack MGR:ie:0x%x\n", mgr_ie_stat); + dev_err(dev->dev, "TX Nack FRM:int:0x%x, stat:0x%x\n", + frm_intr_stat, frm_stat); + dev_err(dev->dev, "TX Nack FRM:cfg:0x%x, ie:0x%x\n", + frm_cfg, frm_ie_stat); + dev_err(dev->dev, "TX Nack INTF:intr:0x%x, stat:0x%x\n", + intf_intr_stat, intf_stat); + dev_err(dev->dev, "TX Nack INTF:ie:0x%x\n", + intf_ie_stat); + err = -ENOTCONN; + } + /** + * Guarantee that interrupt clear bit write goes through before + * signalling completion/exiting ISR + */ + mb(); + slim_return_tx(&dev->ctrl, err); + ret = IRQ_HANDLED; + } + if (stat & MGR_INT_RX_MSG_RCVD) { + u8 mc, mt; + u8 len, i; + u32 *rx_buf, pkt[10]; + bool q_rx = false; + + pkt[0] = readl_relaxed(dev->base + MGR_RX_MSG); + mt = (pkt[0] >> 5) & 0x7; + mc = (pkt[0] >> 8) & 0xff; + len = pkt[0] & 0x1F; + dev_dbg(dev->dev, "RX-IRQ: MC: %x, MT: %x\n", mc, mt); + + /** + * this message cannot be handled by ISR, so + * let work-queue handle it + */ + if (mt == SLIM_MSG_MT_CORE && + mc == SLIM_MSG_MC_REPORT_PRESENT) + rx_buf = (u32 *)slim_get_rx(&dev->ctrl); + else + rx_buf = pkt; + + if (rx_buf == NULL) { + dev_err(dev->dev, "dropping RX:0x%x due to RX full\n", + pkt[0]); + goto rx_ret_irq; + } + + rx_buf[0] = pkt[0]; + for (i = 1; i < ((len + 3) >> 2); i++) { + rx_buf[i] = readl_relaxed(dev->base + MGR_RX_MSG + + (4 * i)); + dev_dbg(dev->dev, "reading data: %x\n", rx_buf[i]); + } + + switch (mc) { + u8 *buf, la; + u16 ele; + + case SLIM_MSG_MC_REPORT_PRESENT: + q_rx = true; + break; + case SLIM_MSG_MC_REPLY_INFORMATION: + case SLIM_MSG_MC_REPLY_VALUE: + slim_msg_response(&dev->ctrl, (u8 *)(rx_buf + 1), + (u8)(*rx_buf >> 24), (len - 4)); + break; + case SLIM_MSG_MC_REPORT_INFORMATION: + buf = (u8 *)rx_buf; + la = buf[2]; + ele = (u16)buf[4] << 4; + + ele |= ((buf[3] & 0xf0) >> 4); + /** + * report information is most likely loss of + * sync or collision detected in data slots + */ + dev_err(dev->dev, "LA:%d report inf ele:0x%x\n", + la, ele); + for (i = 0; i < len - 5; i++) + dev_err(dev->dev, "bit-mask:%x\n", + buf[i+5]); + break; + default: + dev_err(dev->dev, "unsupported MC,%x MT:%x\n", + mc, mt); + break; + } +rx_ret_irq: + writel_relaxed(MGR_INT_RX_MSG_RCVD, dev->base + + MGR_INT_CLR); + /** + * Guarantee that CLR bit write goes through + * before exiting + */ + mb(); + if (q_rx) + queue_work(dev->rxwq, &dev->wd); + + ret = IRQ_HANDLED; + } + return ret; +} + +static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn, + void *pbuf) +{ + struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); + u32 *head = (u32 *)pbuf; + u8 *puc = (u8 *)pbuf; + u8 la = txn->la; + + /* HW expects length field to be excluded */ + txn->rl--; + + if (txn->dt == SLIM_MSG_DEST_LOGICALADDR) + *head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0, + la); + else + *head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1, + la); + + if (txn->dt == SLIM_MSG_DEST_LOGICALADDR) + puc += 3; + else + puc += 2; + + if (txn->mt == SLIM_MSG_MT_CORE && slim_tid_txn(txn->mt, txn->mc)) + *(puc++) = txn->tid; + + if ((txn->mt == SLIM_MSG_MT_CORE) && + ((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION && + txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) || + (txn->mc >= SLIM_MSG_MC_REQUEST_VALUE && + txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) { + *(puc++) = (txn->ec & 0xFF); + *(puc++) = (txn->ec >> 8) & 0xFF; + } + + if (txn->msg && txn->msg->wbuf) + memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes); + + return msm_slim_queue_tx(dev, head, txn->rl, MGR_TX_MSG); +} + +static int msm_set_laddr(struct slim_controller *ctrl, + struct slim_eaddr *ead, u8 laddr) +{ + struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); + u8 buf[7]; + int ret; + struct slim_val_inf msg = {0}; + + DEFINE_SLIM_EDEST_TXN(txn, SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS, + 10, laddr, &msg); + + /* Enumeration address */ + buf[0] = (u8)(ead->manf_id >> 8); + buf[1] = (u8)(ead->manf_id & 0xFF); + buf[2] = (u8) (ead->prod_code >> 8); + buf[3] = (u8) (ead->prod_code & 0xFF); + buf[4] = ead->dev_index; + buf[5] = ead->instance; + + /* Logical address for this EA */ + buf[6] = laddr; + + /** + * Retries are needed since bus may lose sync when multiple devices + * are coming up and reporting present + */ + msg.wbuf = buf; + msg.num_bytes = 7; + + ret = slim_processtxn(&dev->ctrl, &txn); + + if (ret) + dev_err(dev->dev, "set LA:0x%x failed:ret:%d\n", + laddr, ret); + return ret; +} + +static void msm_slim_rxwq(struct work_struct *work) +{ + u8 buf[40]; + u8 mc, mt, len; + int i, ret; + struct msm_slim_ctrl *dev = container_of(work, struct msm_slim_ctrl, + wd); + + while ((slim_return_rx(&dev->ctrl, buf)) != -ENODATA) { + len = buf[0] & 0x1F; + mt = (buf[0] >> 5) & 0x7; + mc = buf[1]; + if (mt == SLIM_MSG_MT_CORE && + mc == SLIM_MSG_MC_REPORT_PRESENT) { + u8 laddr; + struct slim_eaddr ea; + u8 e_addr[6]; + + for (i = 0; i < 6; i++) + e_addr[i] = buf[7-i]; + + ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4]; + ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2]; + ea.dev_index = e_addr[1]; + ea.instance = e_addr[0]; + ret = slim_assign_laddr(&dev->ctrl, &ea, &laddr, false); + if (ret) + dev_err(dev->dev, "assign laddr failed:%d\n", + ret); + } else { + dev_err(dev->dev, "unexpected message:mc:%x, mt:%x\n", + mc, mt); + + } + + } +} + +static void msm_slim_prg_slew(struct platform_device *pdev, + struct msm_slim_ctrl *dev) +{ + void __iomem *slew_reg; + + /* SLEW RATE register for this slimbus */ + dev->slew_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "slew"); + if (!dev->slew_mem) { + dev_warn(&pdev->dev, "no slimbus slew resource\n"); + return; + } + + slew_reg = devm_ioremap(&pdev->dev, dev->slew_mem->start, + resource_size(dev->slew_mem)); + if (!slew_reg) { + dev_err(dev->dev, "slew register mapping failed"); + release_mem_region(dev->slew_mem->start, + resource_size(dev->slew_mem)); + dev->slew_mem = NULL; + return; + } + writel_relaxed(1, slew_reg); + /* Make sure slimbus-slew rate enabling goes through */ + wmb(); +} + +static int msm_slim_probe(struct platform_device *pdev) +{ + struct msm_slim_ctrl *dev; + struct slim_controller *ctrl; + struct resource *slim_mem; + struct resource *irq; + struct clk *hclk, *rclk; + int ret; + + hclk = devm_clk_get(&pdev->dev, "iface_clk"); + if (IS_ERR(hclk)) + return PTR_ERR(hclk); + + rclk = devm_clk_get(&pdev->dev, "core_clk"); + if (IS_ERR(rclk)) { + /* unlikely that this is probe-defer */ + dev_err(&pdev->dev, "rclk get failed:%ld\n", PTR_ERR(rclk)); + return PTR_ERR(rclk); + } + + ret = clk_set_rate(rclk, SLIM_ROOT_FREQ); + if (ret) { + dev_err(&pdev->dev, "ref-clock set-rate failed:%d\n", ret); + return ret; + } + + slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); + if (!slim_mem) { + dev_err(&pdev->dev, "no slimbus physical memory resource\n"); + return -ENODEV; + } + + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { + dev_err(&pdev->dev, "no slimbus IRQ resource\n"); + return -ENODEV; + } + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->hclk = hclk; + dev->rclk = rclk; + ctrl = &dev->ctrl; + dev->dev = &pdev->dev; + platform_set_drvdata(pdev, dev); + slim_set_ctrldata(&dev->ctrl, dev); + dev->base = devm_ioremap(dev->dev, slim_mem->start, + resource_size(slim_mem)); + if (!dev->base) { + dev_err(&pdev->dev, "IOremap failed\n"); + return -ENOMEM; + } + + dev->ctrl.set_laddr = msm_set_laddr; + dev->ctrl.xfer_msg = msm_xfer_msg; + dev->ctrl.tx.n = MSM_TX_MSGS; + dev->ctrl.rx.n = MSM_RX_MSGS; + dev->ctrl.tx.sl_sz = SLIM_MSGQ_BUF_LEN; + dev->ctrl.rx.sl_sz = SLIM_MSGQ_BUF_LEN; + + dev->irq = irq->start; + + INIT_WORK(&dev->wd, msm_slim_rxwq); + dev->rxwq = create_singlethread_workqueue("msm_slim_rx"); + if (!dev->rxwq) { + dev_err(dev->dev, "Failed to start Rx WQ\n"); + return -ENOMEM; + } + + dev->framer.rootfreq = SLIM_ROOT_FREQ >> 3; + dev->framer.superfreq = + dev->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8; + dev->ctrl.a_framer = &dev->framer; + dev->ctrl.clkgear = SLIM_MAX_CLK_GEAR; + dev->ctrl.dev.parent = &pdev->dev; + dev->ctrl.dev.of_node = pdev->dev.of_node; + + msm_slim_prg_slew(pdev, dev); + + ret = devm_request_irq(&pdev->dev, dev->irq, msm_slim_interrupt, + IRQF_TRIGGER_HIGH, "msm_slim_irq", dev); + if (ret) { + dev_err(&pdev->dev, "request IRQ failed\n"); + goto err_request_irq_failed; + } + + ret = clk_prepare_enable(hclk); + if (ret) + goto err_hclk_enable_failed; + + ret = clk_prepare_enable(rclk); + if (ret) + goto err_rclk_enable_failed; + + + ctrl->tx.base = dma_alloc_coherent(&pdev->dev, + (ctrl->tx.sl_sz * ctrl->tx.n), + &ctrl->tx.phy, GFP_KERNEL); + if (!ctrl->tx.base) { + ret = -ENOMEM; + goto tx_alloc_failed; + } + + ctrl->rx.base = dma_alloc_coherent(&pdev->dev, + (ctrl->rx.sl_sz * ctrl->rx.n), + &ctrl->rx.phy, GFP_KERNEL); + if (!ctrl->rx.base) { + ret = -ENOMEM; + goto rx_alloc_failed; + } + + + /* Register with framework before enabling frame, clock */ + ret = slim_register_controller(&dev->ctrl); + if (ret) { + dev_err(dev->dev, "error adding controller\n"); + goto err_ctrl_failed; + } + + dev->ver = readl_relaxed(dev->base); + /* Version info in 16 MSbits */ + dev->ver >>= 16; + /* Component register initialization */ + writel_relaxed(1, dev->base + CFG_PORT(COMP_CFG, dev->ver)); + writel_relaxed((EE_MGR_RSC_GRP | EE_NGD_2 | EE_NGD_1), + dev->base + CFG_PORT(COMP_TRUST_CFG, dev->ver)); + + writel_relaxed((MGR_INT_TX_NACKED_2 | + MGR_INT_MSG_BUF_CONTE | MGR_INT_RX_MSG_RCVD | + MGR_INT_TX_MSG_SENT), dev->base + MGR_INT_EN); + writel_relaxed(1, dev->base + MGR_CFG); + /* + * Framer registers are beyond 1K memory region after Manager and/or + * component registers. Make sure those writes are ordered + * before framer register writes + */ + wmb(); + + /* Framer register initialization */ + writel_relaxed((1 << INTR_WAKE) | (0xA << REF_CLK_GEAR) | + (0xA << CLK_GEAR) | (1 << ROOT_FREQ) | (1 << FRM_ACTIVE) | 1, + dev->base + FRM_CFG); + /* + * Make sure that framer wake-up and enabling writes go through + * before any other component is enabled. Framer is responsible for + * clocking the bus and enabling framer first will ensure that other + * devices can report presence when they are enabled + */ + mb(); + + writel_relaxed(MGR_CFG_ENABLE, dev->base + MGR_CFG); + /* + * Make sure that manager-enable is written through before interface + * device is enabled + */ + mb(); + writel_relaxed(1, dev->base + INTF_CFG); + /* + * Make sure that interface-enable is written through before enabling + * ported generic device inside MSM manager + */ + mb(); + + writel_relaxed(1, dev->base + CFG_PORT(COMP_CFG, dev->ver)); + /* + * Make sure that all writes have gone through before exiting this + * function + */ + mb(); + + dev_dbg(dev->dev, "MSM SB controller is up:ver:0x%x!\n", dev->ver); + return 0; + +err_ctrl_failed: + dma_free_coherent(&pdev->dev, (ctrl->rx.sl_sz * ctrl->rx.n), + ctrl->rx.base, ctrl->rx.phy); +rx_alloc_failed: + dma_free_coherent(ctrl->dev.parent, (ctrl->tx.sl_sz * ctrl->tx.n), + ctrl->tx.base, ctrl->tx.phy); +tx_alloc_failed: + clk_disable_unprepare(dev->rclk); +err_rclk_enable_failed: + clk_disable_unprepare(dev->hclk); + +err_hclk_enable_failed: +err_request_irq_failed: + destroy_workqueue(dev->rxwq); + return ret; +} + +static int msm_slim_remove(struct platform_device *pdev) +{ + struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); + struct slim_controller *ctrl = to_slim_controller(&pdev->dev); + + dma_free_coherent(&pdev->dev, (ctrl->rx.sl_sz * ctrl->rx.n), + ctrl->rx.base, ctrl->rx.phy); + dma_free_coherent(&pdev->dev, (ctrl->tx.sl_sz * ctrl->tx.n), + ctrl->tx.base, ctrl->tx.phy); + + disable_irq(dev->irq); + clk_disable_unprepare(dev->rclk); + clk_disable_unprepare(dev->hclk); + slim_del_controller(&dev->ctrl); + destroy_workqueue(dev->rxwq); + return 0; +} + +static const struct of_device_id msm_slim_dt_match[] = { + { + .compatible = "qcom,slim", + }, + {} +}; + +static struct platform_driver msm_slim_driver = { + .probe = msm_slim_probe, + .remove = msm_slim_remove, + .driver = { + .name = MSM_SLIM_NAME, + .owner = THIS_MODULE, + .of_match_table = msm_slim_dt_match, + }, +}; +module_platform_driver(msm_slim_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0.1"); +MODULE_DESCRIPTION("Qualcomm Slimbus controller"); +MODULE_ALIAS("platform:qcom-slim"); diff --git a/drivers/slimbus/slim-qcom.h b/drivers/slimbus/slim-qcom.h new file mode 100644 index 0000000..0ad59c3 --- /dev/null +++ b/drivers/slimbus/slim-qcom.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SLIM_QCOM_H +#define _SLIM_QCOM_H + +#include +#include + +#define QC_MFGID_LSB 0x2 +#define QC_MFGID_MSB 0x17 + +#define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \ + ((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16)) + +#define SLIM_ROOT_FREQ 24576000 + +/* MAX message size over control channel */ +#define SLIM_MSGQ_BUF_LEN 40 +#define MSM_TX_MSGS 2 +#define MSM_RX_MSGS 8 + +#define CFG_PORT(r, v) ((v) ? CFG_PORT_V2(r) : CFG_PORT_V1(r)) + +/* V2 Component registers */ +#define CFG_PORT_V2(r) ((r ## _V2)) +#define COMP_CFG_V2 4 +#define COMP_TRUST_CFG_V2 0x3000 + +/* V1 Component registers */ +#define CFG_PORT_V1(r) ((r ## _V1)) +#define COMP_CFG_V1 0 +#define COMP_TRUST_CFG_V1 0x14 + +/* Resource group info for manager, and non-ported generic device-components */ +#define EE_MGR_RSC_GRP (1 << 10) +#define EE_NGD_2 (2 << 6) +#define EE_NGD_1 0 + +struct msm_slim_ctrl { + struct slim_controller ctrl; + struct slim_framer framer; + struct device *dev; + void __iomem *base; + struct resource *slew_mem; + int irq; + struct workqueue_struct *rxwq; + struct work_struct wd; + struct clk *rclk; + struct clk *hclk; + u32 ver; +}; + +#endif From patchwork Fri Oct 6 15:51:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 115077 Delivered-To: patch@linaro.org Received: by 10.80.163.170 with SMTP id s39csp1519673edb; Fri, 6 Oct 2017 08:52:09 -0700 (PDT) X-Received: by 10.84.210.165 with SMTP id a34mr297812pli.298.1507305129115; Fri, 06 Oct 2017 08:52:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507305129; cv=none; d=google.com; s=arc-20160816; b=t0al7FkipBBLJ67Fgx86pWbhoq+5KRbmRFz8WtcuIUPxJkqDaw9zN4wdCgmEcRhYfj kzCD3WFix8euS+MFHzgHXazdw8iK6gdeKKqoybr9KtkmX0+BTwXfhE1jdxDP/1JQjtur MAs4Ptzroj9Kgzhl7zCso7JJoaa9X1MQYvYE8ECGuXXBuE7/86qQuEQqCUoTc4Fo3mph w8WGNo/ikz5SVdsGodPHWNGQnjKLKufeFVn0S2iNKTAIzSBRt/H79n/UXlp/dusN4gBE 6b31Qcf2CKAuwveZp4JdU4xpov0uhUh990vU9kJUfX7GFnV3PtzxWYlBXAgfrpreE5/k sZAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=1t9KeSG1JYPEQDvI11M+q/AFCKVRw1axLwBKp1thtaA=; b=weY9L93pp9DAbM6hKtp43UUp+nsiNxPvurUPUsc1qaxGsIKno2OLcHNydDFujAyQxH 0VFEGEsvx6KhYt7Wer8+H6mhqYYXwObz3QohmiRidaI5se8U9TDctT2qks1c0sZG0pix QHmNa1mlQHHI2h/bIcG6ezb6Q8C9eqt5sqD5qpXpX8k+eEhuzL/aq5kVRcmN8BTSBGM6 8OFoOPGYFeCUvoctS72Wi/rQ3sOoTEp9WwIwTaqEfl6Uo2rBtp75fYX18xAB3B+2Hx0b Uv2Ckf3m//1qqJmJOAhjhIEF6E8A7Eexn3OLSuZ/axN/dJQdJJCeSTVNGZNo/yQ5LE3m hA/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Fm1DVGcY; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i186si1462881pfg.401.2017.10.06.08.52.08; Fri, 06 Oct 2017 08:52:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=Fm1DVGcY; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752629AbdJFPwG (ORCPT + 6 others); Fri, 6 Oct 2017 11:52:06 -0400 Received: from mail-wr0-f181.google.com ([209.85.128.181]:45170 "EHLO mail-wr0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752878AbdJFPwA (ORCPT ); Fri, 6 Oct 2017 11:52:00 -0400 Received: by mail-wr0-f181.google.com with SMTP id k7so2330187wre.2 for ; Fri, 06 Oct 2017 08:52:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CtoHELCpuxSzEDoabBLrSTtJtOeKz8uCXeFp/N7vi3w=; b=Fm1DVGcYYa8/YDA0BK/edAorjRpnYquBsWFbdMK1iKMMX0bO4h/8iTt5RdUzvQ/ifd Gm6uFkR0qfOMAz5zAdky5N37YlmcQGvK/FVl2YjBcw3sc5ZP60E+RVEV/uxBLL3iS7Z2 0nj4B960VIP/mZuAMMIsdGAOrFWDQ/tUphyaw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CtoHELCpuxSzEDoabBLrSTtJtOeKz8uCXeFp/N7vi3w=; b=h7j7zu6AzHdbQxJhYiCXvPSaYcNN0nzo5Ys+IBjuajzgbCj/B4xOXyvv8s2GQlawp3 OiGmbTdKsHIgXZSC+GQOgJSyEwsksIzP5sF7RK4atEoUPg4i9YLaUZmRJF1vN9KNwDnV qw5TwZ+tvrEoZJGW/kzTjKvO1M+jpbgQSb32jH7R6blb6qmSnBR989EBcxfRwPLsAq23 66sjs0+Vx3yLJdtbVawjwzNKEPO2ofwrCP4m6pbJ/8kJYEmOOwgbUs92HmiHEuM5BWcw wzPU8VAAnJuxUws/GSiqelKcq77qlgUqGusLAIJ1f0nGFeV7/W0wPnYXCsaNav6WwPoY Jb5g== X-Gm-Message-State: AMCzsaWhhy7GERMfATLf8sqdaFU3w3eS+498huc6BI07ImNrfJI4LPMA UqOg83gPBPkPM12Xy0Cp6XW1mQ== X-Google-Smtp-Source: AOwi7QCfp6yAR4TrJWh5SChztkQntLVx1l7QZwEysI9/3pBm4UCIwnte5ehkazeF6WcHUuyPJHHnOQ== X-Received: by 10.223.134.212 with SMTP id 20mr2327382wry.81.1507305119520; Fri, 06 Oct 2017 08:51:59 -0700 (PDT) Received: from localhost.localdomain (static.8.26.4.46.clients.your-server.de. [46.4.26.8]) by smtp.gmail.com with ESMTPSA id r21sm1510327wmd.26.2017.10.06.08.51.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Oct 2017 08:51:59 -0700 (PDT) From: srinivas.kandagatla@linaro.org To: gregkh@linuxfoundation.org, broonie@kernel.org, alsa-devel@alsa-project.org Cc: sdharia@codeaurora.org, bp@suse.de, poeschel@lemonage.de, treding@nvidia.com, gong.chen@linux.intel.com, andreas.noever@gmail.com, alan@linux.intel.com, mathieu.poirier@linaro.org, daniel@ffwll.ch, jkosina@suse.cz, sharon.dvir1@mail.huji.ac.il, joe@perches.com, davem@davemloft.net, james.hogan@imgtec.com, michael.opdenacker@free-electrons.com, robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kheitke@audience.com, linux-arm-msm@vger.kernel.org, arnd@arndb.de, Srinivas Kandagatla Subject: [Patch v6 5/7] slimbus: qcom: Add runtime-pm support using clock-pause feature Date: Fri, 6 Oct 2017 17:51:34 +0200 Message-Id: <20171006155136.4682-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> References: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Sagar Dharia Slimbus HW mandates that clock-pause sequence has to be executed before disabling relevant interface and core clocks. Runtime-PM's autosuspend feature is used here to enter/exit low power mode for Qualcomm's Slimbus controller. Autosuspend feature enables driver to avoid changing power-modes too frequently since entering clock-pause is an expensive sequence Signed-off-by: Sagar Dharia Signed-off-by: Srinivas Kandagatla --- drivers/slimbus/slim-qcom-ctrl.c | 128 +++++++++++++++++++++++++++++++++++++-- drivers/slimbus/slim-qcom.h | 1 + 2 files changed, 125 insertions(+), 4 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/slimbus/slim-qcom-ctrl.c b/drivers/slimbus/slim-qcom-ctrl.c index d0574e1..05ba44f 100644 --- a/drivers/slimbus/slim-qcom-ctrl.c +++ b/drivers/slimbus/slim-qcom-ctrl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "slim-qcom.h" #define MSM_SLIM_NAME "msm_slim_ctrl" @@ -217,6 +218,30 @@ static irqreturn_t msm_slim_interrupt(int irq, void *d) return ret; } +static int msm_clk_pause_wakeup(struct slim_controller *ctrl) +{ + struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); + + clk_prepare_enable(dev->hclk); + clk_prepare_enable(dev->rclk); + enable_irq(dev->irq); + + writel_relaxed(1, dev->base + FRM_WAKEUP); + /* Make sure framer wakeup write goes through before ISR fires */ + mb(); + /** + * HW Workaround: Currently, slave is reporting lost-sync messages + * after slimbus comes out of clock pause. + * Transaction with slave fail before slave reports that message + * Give some time for that report to come + * Slimbus wakes up in clock gear 10 at 24.576MHz. With each superframe + * being 250 usecs, we wait for 5-10 superframes here to ensure + * we get the message + */ + usleep_range(1250, 2500); + return 0; +} + static int msm_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn, void *pbuf) { @@ -286,7 +311,6 @@ static int msm_set_laddr(struct slim_controller *ctrl, */ msg.wbuf = buf; msg.num_bytes = 7; - ret = slim_processtxn(&dev->ctrl, &txn); if (ret) @@ -417,6 +441,8 @@ static int msm_slim_probe(struct platform_device *pdev) dev->ctrl.set_laddr = msm_set_laddr; dev->ctrl.xfer_msg = msm_xfer_msg; + dev->ctrl.wakeup = msm_clk_pause_wakeup; + dev->ctrl.tx.n = MSM_TX_MSGS; dev->ctrl.rx.n = MSM_RX_MSGS; dev->ctrl.tx.sl_sz = SLIM_MSGQ_BUF_LEN; @@ -532,6 +558,12 @@ static int msm_slim_probe(struct platform_device *pdev) */ mb(); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_SLIM_AUTOSUSPEND); + pm_runtime_set_active(&pdev->dev); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_enable(&pdev->dev); + dev_dbg(dev->dev, "MSM SB controller is up:ver:0x%x!\n", dev->ver); return 0; @@ -562,14 +594,101 @@ static int msm_slim_remove(struct platform_device *pdev) dma_free_coherent(&pdev->dev, (ctrl->tx.sl_sz * ctrl->tx.n), ctrl->tx.base, ctrl->tx.phy); - disable_irq(dev->irq); - clk_disable_unprepare(dev->rclk); - clk_disable_unprepare(dev->hclk); + pm_runtime_disable(&pdev->dev); slim_del_controller(&dev->ctrl); destroy_workqueue(dev->rxwq); return 0; } +/** + * If PM_RUNTIME is not defined, these 2 functions become helper + * functions to be called from system suspend/resume. + */ +#ifdef CONFIG_PM +static int msm_slim_runtime_suspend(struct device *device) +{ + struct platform_device *pdev = to_platform_device(device); + struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); + int ret; + + dev_dbg(device, "pm_runtime: suspending...\n"); + ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED); + if (ret) { + dev_err(device, "clk pause not entered:%d", ret); + } else { + disable_irq(dev->irq); + clk_disable_unprepare(dev->hclk); + clk_disable_unprepare(dev->rclk); + } + return ret; +} + +static int msm_slim_runtime_resume(struct device *device) +{ + struct platform_device *pdev = to_platform_device(device); + struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); + int ret = 0; + + dev_dbg(device, "pm_runtime: resuming...\n"); + ret = slim_ctrl_clk_pause(&dev->ctrl, true, 0); + if (ret) + dev_err(device, "clk pause not exited:%d", ret); + return ret; +} +#endif + +#ifdef CONFIG_PM_SLEEP +static int msm_slim_suspend(struct device *dev) +{ + int ret = 0; + + if (!pm_runtime_enabled(dev) || + (!pm_runtime_suspended(dev))) { + dev_dbg(dev, "system suspend"); + ret = msm_slim_runtime_suspend(dev); + } + if (ret == -EISCONN) { + /** + * If the clock pause failed due to active channels, there is + * a possibility that some audio stream is active during suspend. + * (e.g. modem usecase during suspend) + * We dont want to return suspend failure in that case so that + * display and relevant components can still go to suspend. + * If there is some other error, then it should prevent + * system level suspend + */ + ret = 0; + } + return ret; +} + +static int msm_slim_resume(struct device *dev) +{ + if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) { + int ret; + + dev_dbg(dev, "system resume"); + ret = msm_slim_runtime_resume(dev); + if (!ret) { + pm_runtime_mark_last_busy(dev); + pm_request_autosuspend(dev); + } + return ret; + + } + return 0; +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops msm_slim_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(msm_slim_suspend, msm_slim_resume) + SET_RUNTIME_PM_OPS( + msm_slim_runtime_suspend, + msm_slim_runtime_resume, + NULL + ) +}; + static const struct of_device_id msm_slim_dt_match[] = { { .compatible = "qcom,slim", @@ -584,6 +703,7 @@ static struct platform_driver msm_slim_driver = { .name = MSM_SLIM_NAME, .owner = THIS_MODULE, .of_match_table = msm_slim_dt_match, + .pm = &msm_slim_dev_pm_ops, }, }; module_platform_driver(msm_slim_driver); diff --git a/drivers/slimbus/slim-qcom.h b/drivers/slimbus/slim-qcom.h index 0ad59c3..8b1d649 100644 --- a/drivers/slimbus/slim-qcom.h +++ b/drivers/slimbus/slim-qcom.h @@ -23,6 +23,7 @@ ((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16)) #define SLIM_ROOT_FREQ 24576000 +#define MSM_SLIM_AUTOSUSPEND 1000 /* MAX message size over control channel */ #define SLIM_MSGQ_BUF_LEN 40 From patchwork Fri Oct 6 15:51:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 115079 Delivered-To: patch@linaro.org Received: by 10.80.163.170 with SMTP id s39csp1520476edb; Fri, 6 Oct 2017 08:52:59 -0700 (PDT) X-Received: by 10.98.186.6 with SMTP id k6mr2662003pff.166.1507305179414; Fri, 06 Oct 2017 08:52:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507305179; cv=none; d=google.com; s=arc-20160816; b=GXhC2QPQXmR4l2AeXPABmkz46P3YatYtIkmtBUX5fJjFXoloIEgFS21VdMzpUCFVmj Nlwv+eA7wPnkh2Wi8LD6qDaIByTcopoG9Fo9yft2SW8wJTy8IFdw1y7TU+zLzKtUSTDs Emfbkz/iT3U+aExoQub197G2ejAHdVudWMHxFaija0isFRa73NgmLQ3nf+Q6p0nqQU7V O7ECb3Xh2+xAu5kmvuYqm6AJBTO9yTJQhMf/XTIK4doQRyFHbV0kGGklkHeJoNjGzJsf A3j8J3ux9YQxi+k62XsoAIPZnKCw0fuHk2cbKd5SmsoDtU8iOjK+VfGOXtqO+uazU/Jd mT+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=grTeCAF+2CR1Ew1LAcB4gJ9Pg2pksozSGQKisFu8q44=; b=BI/jLCZxdClFean0CCwlvgTutoowbNpi9G9KqiyjdPP3mgiLQTxzOsgmIhgdVEaaXC GXxVjnsLnMtTGBZkkh3UmrOJus21tR0Jpz+q1EiXnJwNtkPg9i7igRJ1IHgP4bCd0Zr9 K6eFRQKkJ24RKXiy48lq3GAGEYwfwEmVGEhWr1flSp3cWKL3NAAu3eCWODVbRRwLz0il RJdJ3F3hSAhxcgEoFdnc978V7Qws6NH82hLvYtczEbcTAhCBYwV38KloEfB1jijzxZ/q Rp5j5b7cIS5x/5R0few8cKO55oml9XNDQCY1ov5i/VXbJgxiCy9yPZzJDQE4x+nPYevS Qleg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ZuIecZ04; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q72si1446746pfi.307.2017.10.06.08.52.59; Fri, 06 Oct 2017 08:52:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ZuIecZ04; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753015AbdJFPw4 (ORCPT + 6 others); Fri, 6 Oct 2017 11:52:56 -0400 Received: from mail-wr0-f171.google.com ([209.85.128.171]:56865 "EHLO mail-wr0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752669AbdJFPwD (ORCPT ); Fri, 6 Oct 2017 11:52:03 -0400 Received: by mail-wr0-f171.google.com with SMTP id r79so7976431wrb.13 for ; Fri, 06 Oct 2017 08:52:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OPi2/M+Azj9HPzMDnTt1+itVuJemS67fkZ3lA2riMMQ=; b=ZuIecZ04n2XvjYbkYJdD3tbLyMsLeu64sF86qqmaljdAr3sQhmgXB+BzT7kzNeNPDA uaislbTxYbrs7uvSfz9ETHmjlE5ZXWMkQe5aqd+xaX6/MHDo1r7Fb/G97DnZ+JFVDLht LLxg5Xli8zjVjvJi8mNQEh1NoCCd16YkPbqec= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OPi2/M+Azj9HPzMDnTt1+itVuJemS67fkZ3lA2riMMQ=; b=G7Zdj6ykelYsuhAZTpS+IYjn/YwTIuJAOQRkyoVCckXI6ulV1ttsYruYk880flLWH/ WSgRJdKZNQ6AkZTrcHw7XJmQW24ZR1edLWde8XTcOTIuCVFNxI1DYmi7nvm/DJ70yxjD Jl8odqK5VXaBcRkFwUIlPqOTE4Wy+o+IW80wv4kwTliQydoivI1qB4ICjMO6mNgXkOfu 51XfHxwiKSiz8GwHgbxH+HRKNM18s1GEkcSpt1Wt4ZG4hs++9TQj7G2SuyTfwE2YZ/vp XrLmIbfNP58dKRfOFJ3uqIItTes8fmyFaPHElQtEnTu8y/fRrbCa7kcLnQt782Cn3u28 vYdQ== X-Gm-Message-State: AMCzsaVKPM/C6bpJ69VtYFabIEVMxFW2PxjCnT5KywLZeO1ev5HkaiBM f5NchhJF6WdXWZM10P2YkPFT6w== X-Google-Smtp-Source: AOwi7QAAdjE0cj34OpHRQ5ZFOatNn3ybWsV/vAJpsvBF+b25uht+wy3VfbTlTE7sUywvYDO7wXf1Jg== X-Received: by 10.223.181.131 with SMTP id c3mr2416175wre.129.1507305121938; Fri, 06 Oct 2017 08:52:01 -0700 (PDT) Received: from localhost.localdomain (static.8.26.4.46.clients.your-server.de. [46.4.26.8]) by smtp.gmail.com with ESMTPSA id r21sm1510327wmd.26.2017.10.06.08.52.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Oct 2017 08:52:01 -0700 (PDT) From: srinivas.kandagatla@linaro.org To: gregkh@linuxfoundation.org, broonie@kernel.org, alsa-devel@alsa-project.org Cc: sdharia@codeaurora.org, bp@suse.de, poeschel@lemonage.de, treding@nvidia.com, gong.chen@linux.intel.com, andreas.noever@gmail.com, alan@linux.intel.com, mathieu.poirier@linaro.org, daniel@ffwll.ch, jkosina@suse.cz, sharon.dvir1@mail.huji.ac.il, joe@perches.com, davem@davemloft.net, james.hogan@imgtec.com, michael.opdenacker@free-electrons.com, robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kheitke@audience.com, linux-arm-msm@vger.kernel.org, arnd@arndb.de, Srinivas Kandagatla Subject: [Patch v6 7/7] MAINTAINERS: Add SLIMbus maintainer Date: Fri, 6 Oct 2017 17:51:36 +0200 Message-Id: <20171006155136.4682-8-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> References: <20171006155136.4682-1-srinivas.kandagatla@linaro.org> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Srinivas Kandagatla Add myself as maintainer for slimbus. Signed-off-by: Srinivas Kandagatla --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/MAINTAINERS b/MAINTAINERS index 2281af4..014f74b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12320,6 +12320,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git F: include/linux/srcu.h F: kernel/rcu/srcu.c +SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus) +M: Srinivas Kandagatla +L: alsa-devel@alsa-project.org (moderated for non-subscribers) +S: Maintained +F: drivers/slimbus/ +F: Documentation/devicetree/bindings/slimbus/ +F: include/linux/slimbus.h + SMACK SECURITY MODULE M: Casey Schaufler L: linux-security-module@vger.kernel.org