From patchwork Mon Dec 11 23:43:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 121481 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp3431787qgn; Mon, 11 Dec 2017 15:46:51 -0800 (PST) X-Google-Smtp-Source: ACJfBouT1H008QNKbI/ldhjn0iN2M3fg2OxFtPe0l9m7Kx+AmG4HHvZ+Ih8KLnXtb83p/in/W8YC X-Received: by 10.28.194.11 with SMTP id s11mr13618wmf.143.1513036011184; Mon, 11 Dec 2017 15:46:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513036011; cv=none; d=google.com; s=arc-20160816; b=OhY6nk6vsyjMKBZMf0PsmULsPYtjf2NdBq4KeSjNjkvrZcMntJX6hZrnQlPB/K4cnj MOffGGNsKdtyeAGMqwjVH7m/QdM5qjdMsUG0ul4XrfqIqtIULOKvVLAPkh8rENbSLVb1 5VZwAdBUGfXPXZZkCFOulGmj1gALT0+9PELKIPGkdqiwljq3u7SjdIl/9Cwit8liv2Tr MhgXlNPerkpjKBO/OrMAZDoipANR86I/X5Xrr9Hq3bO/tw8iMDfIU/4cMj4/ZOU9Q4s9 g7YfxYV76WO0AIyDuSTxsmWYsbEmTLLdtAToLVKwrenF+Brp8i4sy5PWrlc2pp1wln6L PvOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to:arc-authentication-results; bh=qg64e9TY83hHIdhG7K3dQrILnGST2GfK6L9LuMFvd2E=; b=0u8/fU8DEOxZ8Y8rEWnHk31S4jL+dYGlH0szVWQeGWy+8Os97eUuUetIvEdhwB0Yq/ Ay9yIUTfoxocgO8GCpUqwCGIXx4UGIA0j3xpobsQ7Pb5S+6O2Ftuz9/uOoZQwXyjFu0P b66slj0bxACYbPiOLEV2gJNIWHnBkUfMawsdfYSEdCXerYoV7ndUnVRnwIfDwCKW3S25 /Tjg2H9Eg24gNzt1L30ux7IJEQmR79FwA052VUiUB37xIE8tiEr4eIh05AumV1DgUzeh z5s4txR/tYQNG7JcrSF8xp7Gq4MexGMzu8xscyNpe9iilGDoFKJe7s1BecM3hpUQvYHh tZ0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=V8O5SRJ6; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from alsa0.perex.cz (alsa0.perex.cz. [77.48.224.243]) by mx.google.com with ESMTP id 15si1149406wmu.274.2017.12.11.15.46.50; Mon, 11 Dec 2017 15:46:51 -0800 (PST) Received-SPF: pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) client-ip=77.48.224.243; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=V8O5SRJ6; spf=pass (google.com: domain of alsa-devel-bounces@alsa-project.org designates 77.48.224.243 as permitted sender) smtp.mailfrom=alsa-devel-bounces@alsa-project.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 3672B2676ED; Tue, 12 Dec 2017 00:45:29 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id DAF9D2676C9; Tue, 12 Dec 2017 00:45:25 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS autolearn=disabled version=3.4.0 Received: from mail-wm0-f47.google.com (mail-wm0-f47.google.com [74.125.82.47]) by alsa0.perex.cz (Postfix) with ESMTP id CD5582676C4 for ; Tue, 12 Dec 2017 00:45:22 +0100 (CET) Received: by mail-wm0-f47.google.com with SMTP id g130so15251143wme.0 for ; Mon, 11 Dec 2017 15:45:22 -0800 (PST) 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=knVHKosbS3nbpd+2B5jJKtW5Ojd9ov/PAXCe/VuYA0s=; b=V8O5SRJ6AmInC6XiPwMXNK42Xc6cf34TvaCalPl40eqzSuOkj2YiS3xam74T80I+E3 lmm4ukdOLc+aIIiblMY4vFnPv33NvUu50fboHOSlFhezlsCgrM0izvJtaQbxx0XK5DMf PgTcnu7iwzZSptf7E/0t6cjgBXwNbKoZdlV1E= 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=knVHKosbS3nbpd+2B5jJKtW5Ojd9ov/PAXCe/VuYA0s=; b=ZHbRQt/MI3tdvYEO6cAk+SyBTBPO6MQdWYz8iSd+yWICmGAuGTtakvtyXpGgAwfoeq gjWOoh3gaoxfM8RoSKs1PC82Kg7d5aLHU5bi6J+Xp8ZpdBMV01RDjxvucIGmwZWRsBDk EweciaST5bkKGm2U/WEsbdOmrc4j75bXCAeejDDuEacPZ8KJLhC8f0FEYHZcX2KyMcQs YBsGD4yb7EJafpZPVuG566hXfJd4ZGvY/lctV4GY8aIdnCuW+G/GHm5fCi9T7u4WP17j z6NeNWc3hAuc+pwTQj36HO6LCa+lgSLH8O3uFDmnEI8UK23RFP41V4kGYrS08IoIGRuk jGlA== X-Gm-Message-State: AKGB3mLYmdQ0c3I+pwdaWzNMLRO4yOBl1QFMad42BY4nUITiBdqKHdeA Zu202y0+gx/oKuuOZ9FYmC4Wog== X-Received: by 10.28.178.135 with SMTP id b129mr15242wmf.103.1513035921917; Mon, 11 Dec 2017 15:45:21 -0800 (PST) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id k69sm10673615wmg.8.2017.12.11.15.45.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 11 Dec 2017 15:45:21 -0800 (PST) From: srinivas.kandagatla@linaro.org To: Mark Brown , Greg Kroah-Hartman , alsa-devel@alsa-project.org Date: Mon, 11 Dec 2017 23:43:00 +0000 Message-Id: <20171211234307.14465-7-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171211234307.14465-1-srinivas.kandagatla@linaro.org> References: <20171211234307.14465-1-srinivas.kandagatla@linaro.org> Cc: Mark Rutland , devicetree@vger.kernel.org, Jonathan Corbet , linux-arm-msm@vger.kernel.org, linux-doc@vger.kernel.org, j.neuschaefer@gmx.net, linux-kernel@vger.kernel.org, Rob Herring , Srinivas Kandagatla , pombredanne@nexb.com, sdharia@codeaurora.org Subject: [alsa-devel] [PATCH v10 06/13] slimbus: Add messaging APIs to slimbus framework X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.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 do synchronous and asynchronous reads/writes. Signed-off-by: Srinivas Kandagatla --- drivers/slimbus/Makefile | 2 +- drivers/slimbus/messaging.c | 297 ++++++++++++++++++++++++++++++++++++++++++++ drivers/slimbus/slimbus.h | 67 ++++++++++ include/linux/slimbus.h | 40 ++++++ 4 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 drivers/slimbus/messaging.c -- 2.15.0 _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile index 506ff17d6346..568a14c7be78 100644 --- a/drivers/slimbus/Makefile +++ b/drivers/slimbus/Makefile @@ -3,4 +3,4 @@ # Makefile for kernel SLIMbus framework. # obj-$(CONFIG_SLIMBUS) += slimbus.o -slimbus-y := core.o +slimbus-y := core.o messaging.o diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c new file mode 100644 index 000000000000..031e67648d7c --- /dev/null +++ b/drivers/slimbus/messaging.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2011-2017, The Linux Foundation + */ + +#include +#include "slimbus.h" + +/** + * 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_msg_txn *txn; + struct slim_val_inf *msg; + unsigned long flags; + + spin_lock_irqsave(&ctrl->txn_lock, flags); + txn = idr_find(&ctrl->tid_idr, tid); + if (txn == NULL) { + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + return; + } + + msg = txn->msg; + if (msg == NULL || msg->rbuf == NULL) { + dev_err(ctrl->dev, "Got response to invalid TID:%d, len:%d\n", + tid, len); + return; + } + + idr_remove(&ctrl->tid_idr, tid); + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + + memcpy(msg->rbuf, reply, len); + if (txn->comp) + complete(txn->comp); +} +EXPORT_SYMBOL_GPL(slim_msg_response); + +/** + * slim_do_transfer() - 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 + * + * Return: -ETIMEDOUT: If transmission of this message timed out + * (e.g. due to bus lines not being clocked or driven by controller) + */ +int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn) +{ + DECLARE_COMPLETION_ONSTACK(done); + bool need_tid; + unsigned long flags; + int ret, tid, timeout; + + need_tid = slim_tid_txn(txn->mt, txn->mc); + + if (need_tid) { + spin_lock_irqsave(&ctrl->txn_lock, flags); + tid = idr_alloc(&ctrl->tid_idr, txn, 0, + SLIM_MAX_TIDS, GFP_KERNEL); + txn->tid = tid; + + if (!txn->msg->comp) + txn->comp = &done; + else + txn->comp = txn->comp; + + spin_unlock_irqrestore(&ctrl->txn_lock, flags); + + if (tid < 0) + return tid; + } + + ret = ctrl->xfer_msg(ctrl, txn); + + if (ret && need_tid && !txn->msg->comp) { + unsigned long ms = txn->rl + HZ; + + timeout = wait_for_completion_timeout(txn->comp, + msecs_to_jiffies(ms)); + if (!timeout) { + ret = -ETIMEDOUT; + spin_lock_irqsave(&ctrl->txn_lock, flags); + idr_remove(&ctrl->tid_idr, tid); + 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); + + return ret; +} +EXPORT_SYMBOL_GPL(slim_do_transfer); + +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; + } +reterr: + dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n", + msg->start_offset, mc); + return -EINVAL; +} + +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]; +} + +/** + * slim_xfer_msg() - Transfer a value info message on slim device + * + * @sbdev: slim device to which this msg has to be transfered + * @msg: value info message pointer + * @mc: message code of the message + * + * Called by drivers which want to transfer a vlaue or info elements. + * + * Return: -ETIMEDOUT: If transmission of this message timed out + */ +int slim_xfer_msg(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; + struct slim_controller *ctrl = sbdev->ctrl; + int ret; + u16 sl; + + if (!ctrl) + return -EINVAL; + + 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); + + 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_do_transfer(ctrl, txn); +} +EXPORT_SYMBOL_GPL(slim_xfer_msg); + +static void slim_fill_msg(struct slim_val_inf *msg, u32 addr, + size_t count, u8 *rbuf, u8 *wbuf) +{ + msg->start_offset = addr; + msg->num_bytes = count; + msg->rbuf = rbuf; + msg->wbuf = wbuf; +} + +/** + * slim_read() - Read SLIMbus value element + * + * @sdev: client handle. + * @addr: address of value element to read. + * @count: number of bytes to read. Maximum bytes allowed are 16. + * @val: will return what the value element value was + * + * Return: -EINVAL for Invalid parameters, -ETIMEDOUT If transmission of + * this message timed out (e.g. due to bus lines not being clocked + * or driven by controller) + */ +int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val) +{ + struct slim_val_inf msg; + + slim_fill_msg(&msg, addr, count, val, NULL); + + return slim_xfer_msg(sdev, &msg, SLIM_MSG_MC_REQUEST_VALUE); +} +EXPORT_SYMBOL_GPL(slim_read); + +/** + * slim_readb() - Read byte from SLIMbus value element + * + * @sdev: client handle. + * @addr: address in the value element to read. + * + * Return: byte value of value element. + */ +int slim_readb(struct slim_device *sdev, u32 addr) +{ + int ret; + u8 buf; + + ret = slim_read(sdev, addr, 1, &buf); + if (ret < 0) + return ret; + else + return buf; +} +EXPORT_SYMBOL_GPL(slim_readb); + +/** + * slim_write() - Write SLIMbus value element + * + * @sdev: client handle. + * @addr: address in the value element to write. + * @count: number of bytes to write. Maximum bytes allowed are 16. + * @val: value to write to value element + * + * Return: -EINVAL for Invalid parameters, -ETIMEDOUT If transmission of + * this message timed out (e.g. due to bus lines not being clocked + * or driven by controller) + */ +int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val) +{ + struct slim_val_inf msg; + + slim_fill_msg(&msg, addr, count, val, NULL); + + return slim_xfer_msg(sdev, &msg, SLIM_MSG_MC_CHANGE_VALUE); +} +EXPORT_SYMBOL_GPL(slim_write); + +/** + * slim_writeb() - Write byte to SLIMbus value element + * + * @sdev: client handle. + * @addr: address of value element to write. + * @value: value to write to value element + * + * Return: -EINVAL for Invalid parameters, -ETIMEDOUT If transmission of + * this message timed out (e.g. due to bus lines not being clocked + * or driven by controller) + * + */ +int slim_writeb(struct slim_device *sdev, u32 addr, u8 value) +{ + return slim_write(sdev, addr, 1, &value); +} +EXPORT_SYMBOL_GPL(slim_writeb); diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h index 66657722f50f..0d40c2578c28 100644 --- a/drivers/slimbus/slimbus.h +++ b/drivers/slimbus/slimbus.h @@ -8,8 +8,17 @@ #include #include #include +#include #include +/* SLIMbus message types. Related to interpretation of message code. */ +#define SLIM_MSG_MT_CORE 0x0 + +/* Destination type Values */ +#define SLIM_MSG_DEST_LOGICALADDR 0 +#define SLIM_MSG_DEST_ENUMADDR 1 +#define SLIM_MSG_DEST_BROADCAST 3 + /* Standard values per SLIMbus spec needed by controllers and devices */ #define SLIM_MAX_CLK_GEAR 10 #define SLIM_MIN_CLK_GEAR 1 @@ -17,6 +26,7 @@ /* Manager's logical address is set to 0xFF per spec */ #define SLIM_LA_MANAGER 0xFF +#define SLIM_MAX_TIDS 256 /** * struct slim_framer - Represents SLIMbus framer. * Every controller may have multiple framers. There is 1 active framer device @@ -37,6 +47,39 @@ struct slim_framer { #define to_slim_framer(d) container_of(d, struct slim_framer, dev) +/** + * 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. + * @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 + * @comp: completion if read/write is synchronous, used internally + * for tid based transactions. + */ +struct slim_msg_txn { + u8 rl; + u8 mt; + u8 mc; + u8 dt; + u16 ec; + u8 tid; + u8 la; + struct slim_val_inf *msg; + struct completion *comp; +}; + +/* 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, } /** * struct slim_controller - Controls every instance of SLIMbus * (similar to 'master' on SPI) @@ -52,6 +95,9 @@ struct slim_framer { * @devices: Slim device list * @tid_idr: tid id allocator * @txn_lock: Lock to protect table of 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. * @set_laddr: Setup logical address at laddr for the slave with elemental * address e_addr. Drivers implementing controller will be expected to * send unicast message to this device with its logical address. @@ -93,6 +139,8 @@ struct slim_controller { struct list_head devices; struct idr tid_idr; spinlock_t txn_lock; + int (*xfer_msg)(struct slim_controller *ctrl, + struct slim_msg_txn *tx); int (*set_laddr)(struct slim_controller *ctrl, struct slim_eaddr *ea, u8 laddr); int (*get_laddr)(struct slim_controller *ctrl, @@ -104,5 +152,24 @@ int slim_device_report_present(struct slim_controller *ctrl, void slim_report_absent(struct slim_device *sbdev); int slim_register_controller(struct slim_controller *ctrl); int slim_unregister_controller(struct slim_controller *ctrl); +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l); +int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn); + +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)); +} +static inline bool slim_ec_txn(u8 mt, u8 mc) +{ + return (mt == SLIM_MSG_MT_CORE && + ((mc >= SLIM_MSG_MC_REQUEST_INFORMATION && + mc <= SLIM_MSG_MC_REPORT_INFORMATION) || + (mc >= SLIM_MSG_MC_REQUEST_VALUE && + mc <= SLIM_MSG_MC_CHANGE_VALUE))); +} #endif /* _LINUX_SLIMBUS_H */ diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h index aeed98a683be..c36cf121d2cd 100644 --- a/include/linux/slimbus.h +++ b/include/linux/slimbus.h @@ -7,6 +7,7 @@ #define _LINUX_SLIMBUS_H #include #include +#include #include extern struct bus_type slimbus_bus; @@ -88,6 +89,25 @@ struct slim_driver { }; #define to_slim_driver(d) container_of(d, struct slim_driver, driver) +/** + * struct slim_val_inf - Slimbus value or information element + * @start_offset: Specifies starting offset in information/value element map + * @rbuf: buffer to read the values + * @wbuf: buffer to write + * @num_bytes: upto 16. This ensures that the message will fit the slicesize + * per SLIMbus spec + * @comp: completion for asynchronous operations, valid only if TID is + * required for transaction, like REQUEST operations. + * Rest of the transactions are synchronous anyway. + */ +struct slim_val_inf { + u16 start_offset; + u8 num_bytes; + u8 *rbuf; + const u8 *wbuf; + struct completion *comp; +}; + /* * use a macro to avoid include chaining to get THIS_MODULE */ @@ -121,4 +141,24 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data) struct slim_device *slim_get_device(struct slim_controller *ctrl, struct slim_eaddr *e_addr); int slim_get_logical_addr(struct slim_device *sbdev); + +/* 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 + +int slim_xfer_msg(struct slim_device *sbdev, struct slim_val_inf *msg, + u8 mc); +int slim_readb(struct slim_device *sdev, u32 addr); +int slim_writeb(struct slim_device *sdev, u32 addr, u8 value); +int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val); +int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val); #endif /* _LINUX_SLIMBUS_H */