Received: by 10.223.185.116 with SMTP id b49csp4007038wrg; Tue, 6 Mar 2018 08:22:57 -0800 (PST) X-Google-Smtp-Source: AG47ELsITPjoK0MidmAFZvtt64zYOBrD6CnFwAjSEPgC8Yga5xJ19zZEgkkOghxfJRpVfAcE98LP X-Received: by 2002:a17:902:424:: with SMTP id 33-v6mr17521584ple.433.1520353377262; Tue, 06 Mar 2018 08:22:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520353377; cv=none; d=google.com; s=arc-20160816; b=WPB0OsXaYWOdoKY1aIbUI5INZFu4moLbMKWncb9wM7swT1WKRVBB27ougYwN+a5kDA oTkVMePuWd8eX3vw6y6Wr+NRZQ7L4XhP9U/b+8AaxzmOGb6CVVerT7qcV4PMvrcEUAtG r2Yv3XCbxfyKnbFL6ntA05XspXKc5srX2etgto6VTFka5kThkVNvEllazPpnhdbE/q4k E0ipVUG/PoiFDE1XAxJjwx0YKFsjvnPkJLvRPQMvQBmLgjz59KJZAgnBxU5dcwKXEM/s plUUiFP5SilOT+2vLntBPgM++ZzHLJb7p+xYpMH5aIZ2Qw0rpXdwZbqU2TuyCuL/TRyU 712w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dmarc-filter:dkim-signature:dkim-signature :arc-authentication-results; bh=73i8t4C6canpsWe4wOK/4CH0VFl222FIxXGrzHA62VU=; b=x8zotWPkLuhnx/4L0B9v1+FhsdI8Eu9MDrRGV66nUs4q9/d3eNncmd+zzFY9W4yW/x dx7WGwynMVRHQtlFI1CUeRoCrw25FqZ3RHd57amfR/T4JVKKmiEAdV/KXcVmIBQZn3fF 86oPmLc/Kq2KNI1KNa7+X/ANNAB3O63sVchi4mZu9H7By1kl8q7JFZbBTprX7OgTuhrj Dp2s15sJZtIitSaz0TN9BAmzIMNc2vwYCb9BiPShEPWfCva5X1v37H9ArMIzKc6qmSFc V7zztwJsL6Mt79RKaM9O04H2i+F9O1efhvi9mJQeRdJdGCnPJr3SSrQKCeNqSEQkmiWF uHZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=n5gBPLgg; dkim=pass header.i=@codeaurora.org header.s=default header.b=Vh1jUbO5; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r59-v6si11412270plb.69.2018.03.06.08.22.42; Tue, 06 Mar 2018 08:22:57 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=n5gBPLgg; dkim=pass header.i=@codeaurora.org header.s=default header.b=Vh1jUbO5; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753857AbeCFQVo (ORCPT + 99 others); Tue, 6 Mar 2018 11:21:44 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:44896 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750797AbeCFQVm (ORCPT ); Tue, 6 Mar 2018 11:21:42 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 4130A60452; Tue, 6 Mar 2018 16:21:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1520353302; bh=xeEAuctgW2ZQv5XnHU0vnSLuDbjQj+GSZ5uIEoITTs4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=n5gBPLgglteI95vFJGIbGanegBT/geGfoEwEbfrUUxLaxuJUnZ1OkUMElzOinYER6 s6X3kTUYclPwgVxuBIwtFBuG/izm+dM/sBkrBCgWCcdzTEixXUpGDJK35kU4plW67M 0uMHCIdZBrsTK5Xwhl8zLt8sOCfGDP7tTQFFB+wg= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from localhost (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: ilina@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 53D4A600E6; Tue, 6 Mar 2018 16:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1520353301; bh=xeEAuctgW2ZQv5XnHU0vnSLuDbjQj+GSZ5uIEoITTs4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=Vh1jUbO5BLoO5GzXOLhtSOPzXMbF+rsLVqd0kNcYkQPGA76vZIJ99mCt4jgf4x/6l PBWdulCCRUsQ8QXide7UIxuivlZIa2pY7QhQsjLKQnbodYBidlR21XHd/rgBALU2LG Ku7jKUkKiY7fDJvx7TP2ZYtRPZWiS8XdBFNs3a9A= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 53D4A600E6 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=ilina@codeaurora.org Date: Tue, 6 Mar 2018 09:21:40 -0700 From: Lina Iyer To: Stephen Boyd Cc: andy.gross@linaro.org, david.brown@linaro.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, rnayak@codeaurora.org, bjorn.andersson@linaro.org, linux-kernel@vger.kernel.org, Mahesh Sivasubramanian Subject: Re: [PATCH v4 1/2] drivers: qcom: add command DB driver Message-ID: <20180306162140.GC4930@codeaurora.org> References: <20180226175802.20052-1-ilina@codeaurora.org> <20180226175802.20052-2-ilina@codeaurora.org> <152027534725.108663.13213325833387672227@swboyd.mtv.corp.google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <152027534725.108663.13213325833387672227@swboyd.mtv.corp.google.com> User-Agent: Mutt/1.9.3 (2018-01-21) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Mar 05 2018 at 11:42 -0700, Stephen Boyd wrote: >Quoting Lina Iyer (2018-02-26 09:58:01) >> diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c >> new file mode 100644 >> index 000000000000..0792a2a98fc9 >> --- /dev/null >> +++ b/drivers/soc/qcom/cmd-db.c >> @@ -0,0 +1,319 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#define NUM_PRIORITY 2 >> +#define MAX_SLV_ID 8 >> +#define CMD_DB_MAGIC 0x0C0330DBUL > >Make this an array so it's endian safe. > >> +#define SLAVE_ID_MASK 0x7 >> +#define SLAVE_ID_SHIFT 16 >> + >> +#define ENTRY_HEADER(hdr) ((void *)cmd_db_header + \ >> + sizeof(*cmd_db_header) + \ >> + hdr->header_offset) >> + >> +#define RSC_OFFSET(hdr, ent) ((void *)cmd_db_header + \ >> + sizeof(*cmd_db_header) + \ >> + hdr.data_offset + ent.offset) >> + >> +/** >> + * entry_header: header for each entry in cmddb > >struct entry_header - header for each... > Ok >> + * >> + * @id: resource's identifier >> + * @priority: unused >> + * @addr: the address of the resource >> + * @len: length of the data >> + * @offset: offset at which data starts > >offset from this entry header at which data starts? Or offset from >where? > Offset from @data_offset of the rsc_header. >> + */ >> +struct entry_header { >> + u64 id; >> + u32 priority[NUM_PRIORITY]; >> + u32 addr; >> + u16 len; >> + u16 offset; >> +}; >> + >> +/** >> + * rsc_hdr: resource header information > >ditto. > Will do. >> + * >> + * @slv_id: id for the resource >> + * @header_offset: Entry header offset from data >> + * @data_offset: Entry offset for data location > >Same question: offset from where? > Ok >> + * @cnt: number of entries for HW type >> + * @version: MSB is major, LSB is minor > >@reserved: reserved for future use > Ok. >> + */ >> +struct rsc_hdr { >> + u16 slv_id; >> + u16 header_offset; >> + u16 data_offset; >> + u16 cnt; >> + u16 version; >> + u16 reserved[3]; >> +}; >> + >> +/** >> + * cmd_db_header: The DB header information >> + * >> + * @version: The cmd db version >> + * @magic_number: constant expected in the database >> + * @header: array of resources >> + * @check_sum: check sum for the header. Unused. >> + * @reserved: reserved memory >> + * @data: driver specific data >> + */ >> +struct cmd_db_header { >> + u32 version; >> + u32 magic_num; >> + struct rsc_hdr header[MAX_SLV_ID]; >> + u32 check_sum; > >Drop underscore? 'checksum' is usually one word. > Sure. >> + u32 reserved; >> + u8 data[]; >> +}; >> + >> +/** >> + * DOC: Description of the Command DB database. >> + * >> + * At the start of the command DB memory is the cmd_db_header structure. >> + * The cmd_db_header holds the version, checksum, magic key as well as an >> + * array for header for each slave (depicted by the rsc_header). Each h/w >> + * based accelerator is a 'slave' (shared resource) and has slave id indicating >> + * the type of accelerator. The rsc_header is the header for such individual >> + * slaves of a given type. The entries for each of these slaves begin at the >> + * rsc_hdr.header_offset. In addition each slave could have auxiliary data >> + * that may be needed by the driver. The data for the slave starts at the >> + * entry_header.offset to the location pointed to by the rsc_hdr.data_offset. >> + * >> + * Drivers have a stringified key to a slave/resource. They can query the slave >> + * information and get the slave id and the auxiliary data and the length of the >> + * data. Using this information, they can format the request to be sent to the >> + * h/w accelerator and request a resource state. >> + */ >> + >> +static struct cmd_db_header *cmd_db_header; >> + >> +/** >> + * cmd_db_ready - Indicates if command DB is available >> + * >> + * Return: 0 on success, errno otherwise >> + */ >> +int cmd_db_ready(void) >> +{ >> + if (cmd_db_header == NULL) >> + return -EPROBE_DEFER; >> + else if (cmd_db_header->magic_num != CMD_DB_MAGIC) >> + return -EINVAL; >> + else >> + return 0; > >Drop else and just return 0. > Ok. >> +} >> +EXPORT_SYMBOL(cmd_db_ready); >> + >> +static u64 cmd_db_get_u64_id(const char *id) >> +{ >> + u64 rsc_id = 0; >> + u8 *ch = (u8 *)&rsc_id; >> + int i; >> + >> + for (i = 0; i < sizeof(rsc_id) && id[i]; i++) >> + ch[i] = id[i]; > >This could be a strncpy now? Didn't I already ask this? I'll have to >look back at the other emails it seems. Actually, it looks like a cast >of a string to an integer, Yes, you did ask. The cast helps do an integer comparison as opposed to string comparision on the database. >which is then reversed to look up the same >string. Not sure what the use is for this. > Where do you see that? >> + >> + return rsc_id; >> +} >> + >> +static int cmd_db_get_header(u64 query, struct entry_header *eh, >> + struct rsc_hdr *rh) >> +{ >> + struct rsc_hdr *rsc_hdr; >> + struct entry_header *ent; >> + int ret, i, j; >> + >> + ret = cmd_db_ready(); >> + if (ret) >> + return ret; >> + >> + if (!eh || !rh) >> + return -EINVAL; >> + >> + for (i = 0; i < MAX_SLV_ID; i++) { >> + rsc_hdr = &cmd_db_header->header[i]; >> + if (!rsc_hdr->slv_id) >> + break; >> + >> + ent = ENTRY_HEADER(rsc_hdr); >> + for (j = 0; j < rsc_hdr->cnt; j++, ent++) { >> + if (ent->id == query) >> + break; >> + } >> + >> + if (j < rsc_hdr->cnt) { >> + memcpy(eh, ent, sizeof(*ent)); >> + memcpy(rh, rsc_hdr, sizeof(*rh)); > >I suppose it's OK to punt on the endian issues for now if it's too hard. >Eventually we'll want to handle it though and it shouldn't make the code >any worse when endianness is the same. Can it be done now? > Why is the change in endian needed? We can always add that in later if we decide to change the default endian. I would prefer that we punt it for now. >> + return 0; >> + } >> + } >> + >> + return -ENODEV; >> +} >> + >> +static int cmd_db_get_header_by_rsc_id(const char *id, >> + struct entry_header *ent_hdr, >> + struct rsc_hdr *rsc_hdr) >> +{ >> + u64 rsc_id = cmd_db_get_u64_id(id); >> + >> + return cmd_db_get_header(rsc_id, ent_hdr, rsc_hdr); >> +} >> + >> +/** >> + * cmd_db_read_addr() - Query command db for resource id address. >> + * >> + * @id: resource id to query for address >> + * >> + * This is used to retrieve resource address based on resource >> + * id. >> + * Return: resource address on success, 0 on error > >Weird spaces here. Mix of tabs and spaces perhaps? > Hmm. Not sure, didn't see checkpatch complain. Will check. >> + */ >> +u32 cmd_db_read_addr(const char *id) >> +{ >> + int ret; >> + struct entry_header ent; >> + struct rsc_hdr rsc_hdr; >> + >> + ret = cmd_db_get_header_by_rsc_id(id, &ent, &rsc_hdr); >> + >> + return ret < 0 ? 0 : ent.addr; >> +} >> +EXPORT_SYMBOL(cmd_db_read_addr); >> + >> +/** >> + * cmd_db_read_aux_data() - Query command db for aux data. >> + * >> + * @id : Resource to retrieve AUX Data on. >> + * @data : Data buffer to copy returned aux data to. Returns size on NULL >> + * @len : Caller provides size of data buffer passed in. > >Attach the ':' to the variable please. > Ok >> + * >> + * Return: size of data on success, errno on error > >success, -EINVAL on error > Ok >> + */ >> +int cmd_db_read_aux_data(const char *id, u8 *data, int len) >> +{ >> + int ret; >> + struct entry_header ent; >> + struct rsc_hdr rsc_hdr; >> + >> + if (!data) >> + return -EINVAL; >> + >> + ret = cmd_db_get_header_by_rsc_id(id, &ent, &rsc_hdr); >> + if (ret) >> + return ret; >> + >> + if (len < ent.len) >> + return -EINVAL; >> + >> + len = min_t(u16, ent.len, len); >> + memcpy(data, RSC_OFFSET(rsc_hdr, ent), len); >> + >> + return len; >> +} >> +EXPORT_SYMBOL(cmd_db_read_aux_data); >> + >> +/** >> + * cmd_db_read_aux_data_len - Get the length of the auxllary data stored in DB. >> + * >> + * @id: Resource to retrieve AUX Data. >> + * >> + * Return: size on success, 0 on error >> + */ >> +size_t cmd_db_read_aux_data_len(const char *id) >> +{ >> + int ret; >> + struct entry_header ent; >> + struct rsc_hdr rsc_hdr; >> + >> + ret = cmd_db_get_header_by_rsc_id(id, &ent, &rsc_hdr); > >A bunch of code is calling this function. Why not change the user >interface to use an opaque 'resource' cookie that we can 'get' or 'find' >and then use that cookie in the rest of the API to pull out the data >that's desired? > Fair point. Let me find out. I suspect this was done to keep the API similar to other non-Linux interfaces. I am not sure why they all didn't use a handle instead of char *. >> + >> + return ret < 0 ? 0 : ent.len; >> +} >> +EXPORT_SYMBOL(cmd_db_read_aux_data_len); >> + >> +/** >> + * cmd_db_read_slave_id - Get the slave ID for a given resource address >> + * >> + * @id: Resource id to query the DB for version >> + * >> + * Return: cmd_db_hw_type enum on success, CMD_DB_HW_INVALID on error >> + */ >> +enum cmd_db_hw_type cmd_db_read_slave_id(const char *id) >> +{ >> + int ret; >> + struct entry_header ent; >> + struct rsc_hdr rsc_hdr; >> + >> + ret = cmd_db_get_header_by_rsc_id(id, &ent, &rsc_hdr); >> + >> + return ret < 0 ? CMD_DB_HW_INVALID : >> + (ent.addr >> SLAVE_ID_SHIFT) & SLAVE_ID_MASK; >> +} >> +EXPORT_SYMBOL(cmd_db_read_slave_id); >> + >> +static int cmd_db_dev_probe(struct platform_device *pdev) >> +{ >> + struct reserved_mem *rmem; >> + void *dict, *start_addr; >> + int ret = 0; >> + >> + rmem = of_reserved_mem_lookup(pdev->dev.of_node); >> + if (!rmem) { >> + dev_err(&pdev->dev, "failed to acquire memory region\n"); >> + return -EINVAL; >> + } >> + >> + dict = devm_memremap(&pdev->dev, rmem->base, rmem->size, MEMREMAP_WB); >> + if (IS_ERR(dict)) >> + return -ENOMEM; >> + >> + start_addr = memremap(readl_relaxed(dict), readl_relaxed(dict + 0x4), >> + MEMREMAP_WB); >> + if (IS_ERR_OR_NULL(start_addr)) { > >Should just be !start_addr? I don't see where memremap() returns an >error pointer. > Sure. >> + ret = PTR_ERR(start_addr); >> + goto done; >> + } >> + >> + cmd_db_header = start_addr; >> + if (cmd_db_header->magic_num != CMD_DB_MAGIC) { > >memcmp? > Why? It could be a simple comparison. >> + ret = -EINVAL; >> + dev_err(&pdev->dev, "Invalid Command DB Magic\n"); >> + goto done; >> + } >> + >> +done: >> + devm_memunmap(&pdev->dev, dict); > >I'm lost why we use devm_*() for this mapping. > Must have picked it up from an example. Curious, why not though? >> + return ret; >> +} >> + >> +static const struct of_device_id cmd_db_match_table[] = { >> + { .compatible = "qcom,cmd-db" }, >> + { }, >> +}; >> + >> +static struct platform_driver cmd_db_dev_driver = { >> + .probe = cmd_db_dev_probe, >> + .driver = { >> + .name = "cmd-db", >> + .of_match_table = cmd_db_match_table, > >Add suppress_bind_attrs here to make sure we can't remove this device >later? That also allows us to ignore unmapping the start_addr pointer >in any sort of 'remove' function. > Ok.. Thanks Stephen. -- Lina