Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932223AbcKGN15 (ORCPT ); Mon, 7 Nov 2016 08:27:57 -0500 Received: from mout.kundenserver.de ([212.227.17.13]:53931 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752646AbcKGN1w (ORCPT ); Mon, 7 Nov 2016 08:27:52 -0500 From: Arnd Bergmann To: linux-arm-kernel@lists.infradead.org Cc: Anurup M , anurup.m@huawei.com, linux-kernel@vger.kernel.org, mark.rutland@arm.com, shyju.pv@huawei.com, gabriele.paoloni@huawei.com, john.garry@huawei.com, will.deacon@arm.com, linuxarm@huawei.com, xuwei5@hisilicon.com, zhangshaokun@hisilicon.com, sanil.kumar@hisilicon.com, tanxiaojun@huawei.com, shiju.jose@huawei.com Subject: Re: [PATCH v1 03/11] drivers: soc: hisi: Add support for Hisilicon Djtag driver Date: Mon, 07 Nov 2016 14:26:59 +0100 Message-ID: <2127881.qmAR1XgW9F@wuerfel> User-Agent: KMail/5.1.3 (Linux/4.4.0-34-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: <1478101374-18778-4-git-send-email-anurup.m@huawei.com> References: <1478101374-18778-1-git-send-email-anurup.m@huawei.com> <1478101374-18778-4-git-send-email-anurup.m@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Provags-ID: V03:K0:00vdDN20GRsjos0YDdQaBUSl4qTM6AMUlY47TqiqydymyXAGyq4 +p8BhBfdOTxsKo2z+O/FlcNo4mX10MbhFgO+ZISbx4XnbV9U9Dwi17pao+eHOYQAV9aMycz M7VrKrbcUEDWIS2CPUnw4BIi2TxCA/dmLTOPiv6/UTAPis3zNck+U6mI3ZCty6QdsNFGJBM EXwZzBVt3WVr1d9NWWndw== X-UI-Out-Filterresults: notjunk:1;V01:K0:3Gv1g/KOxgE=:VAm+gNN6IWU6MnXyHdGtHx Q6AIKMYv0u6hApucl6/Y7U4+10J5yHu6IWvg3/AUYZh77JTOEnn3r2Ks5h2/L4ZAVGoWZXjAG N06vePj5ZWwXF2/O32KmJWAbd+GJoeuSvE4l4r9dyCY8C1B4SbO7iUkyDR00v6LCyofFLCsXm G5kRdnQoMB4lAT8ojpBEQF9pAWv8Y6MEcQCvdWcbZeF087XBGGh8Bgiorx1ILZFGq4rKE1+HA A/VjPJb9U5FOpMR2xJJWNLJpMK9JEo/4eKCCusSnyK8jGptkgPRucUxqIQy+COBbZkjaXD1BF HOsfwRzqDm8bVlfrqUwMumpdIuqq0mFlVpPWpzRzd4FETnode4+zrFrZpkgTu9giZo96kZrEv EXsksZRcmLRRvf/skswtAhH2Z1T/puThMEASSms43BWu2txz58vof8AWVnIBJJnzn20yBlvUf /nKzoNlEfl2h2w0R4pRE0YMLIjeG0ye9tAleMw/DF71e61C1s9azRgaxDpjshKj7DDrQr4MRU avj27y7TkWmvWqUoll2dy84nlTPujt89edXALUe+AVcp5IVhEPZanUX0yM53XY0ENXakC9dfW Cf9foq7k+QSj2zP9tt1vX7es/omzeHmSJBPrPbpNfeeEvk+S0m943HONJrWt8KeHYZkiWdg9o a5HCEbX3Urs2/VnrV8p98sr3/pDf9zIl7bnNlqTVPdkIpUB/H9wNpl9wKvaMcpr/etxg752Oc 1hP5e6cBfSQspjko Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5234 Lines: 160 On Wednesday, November 2, 2016 11:42:46 AM CET Anurup M wrote: > From: Tan Xiaojun > > The Hisilicon Djtag is an independent component which connects > with some other components in the SoC by Debug Bus. This driver > can be configured to access the registers of connecting components > (like L3 cache) during real time debugging. The formatting of the text seems odd, please remove the leading spaces. > drivers/soc/Kconfig | 1 + > drivers/soc/Makefile | 1 + > drivers/soc/hisilicon/Kconfig | 12 + > drivers/soc/hisilicon/Makefile | 1 + > drivers/soc/hisilicon/djtag.c | 639 ++++++++++++++++++++++++++++++++++++ > include/linux/soc/hisilicon/djtag.h | 38 +++ Do you expect other drivers to be added that reference this interface? If not, or if you are unsure, just put all of it under drivers/perf so we don't introduce a global API that has only one user. > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include Never include files from asm-generic directly except from an architecture specific asm/*.h header file. > +DEFINE_IDR(djtag_hosts_idr); make this static > +static void djtag_read32_relaxed(void __iomem *regs_base, u32 off, u32 *value) > +{ > + void __iomem *reg_addr = regs_base + off; > + > + *value = readl_relaxed(reg_addr); > +} > + > +static void djtag_write32(void __iomem *regs_base, u32 off, u32 val) > +{ > + void __iomem *reg_addr = regs_base + off; > + > + writel(val, reg_addr); > +} This looks like an odd combination of interfaces. Why can the reads be "relaxed" when the writes can not? Generally speaking, I'd advise to always use non-relaxed accessors unless there is a strong performance reason, and in that case there should be a comment explaining the use at each of the callers of a relaxed accessor. > + /* ensure the djtag operation is done */ > + do { > + djtag_read32_relaxed(regs_base, SC_DJTAG_MSTR_START_EN_EX, &rd); > + > + if (!(rd & DJTAG_MSTR_START_EN_EX)) > + break; > + > + udelay(1); > + } while (timeout--); This one is obviously not performance critical at all, so use a non-relaxed accessor. Same for the other two in this function. Are these functions ever called from atomic context? If yes, please document from what context they can be called, otherwise please consider changing the udelay calls into sleeping waits. > +int hisi_djtag_writel(struct hisi_djtag_client *client, u32 offset, u32 mod_sel, > + u32 mod_mask, u32 val) > +{ > + void __iomem *reg_map = client->host->sysctl_reg_map; > + unsigned long flags; > + int ret = 0; > + > + spin_lock_irqsave(&client->host->lock, flags); > + ret = client->host->djtag_readwrite(reg_map, offset, mod_sel, mod_mask, > + true, val, 0, NULL); > + if (ret) > + pr_err("djtag_writel: error! ret=%d\n", ret); > + spin_unlock_irqrestore(&client->host->lock, flags); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(hisi_djtag_writel); That would of course imply changing the spinlock to a mutex here as well. > +static const struct of_device_id djtag_of_match[] = { > + /* for hip05(D02) cpu die */ > + { .compatible = "hisilicon,hip05-cpu-djtag-v1", > + .data = (void *)djtag_readwrite_v1 }, > + /* for hip05(D02) io die */ > + { .compatible = "hisilicon,hip05-io-djtag-v1", > + .data = (void *)djtag_readwrite_v1 }, > + /* for hip06(D03) cpu die */ > + { .compatible = "hisilicon,hip06-cpu-djtag-v1", > + .data = (void *)djtag_readwrite_v1 }, > + /* for hip06(D03) io die */ > + { .compatible = "hisilicon,hip06-io-djtag-v2", > + .data = (void *)djtag_readwrite_v2 }, > + /* for hip07(D05) cpu die */ > + { .compatible = "hisilicon,hip07-cpu-djtag-v2", > + .data = (void *)djtag_readwrite_v2 }, > + /* for hip07(D05) io die */ > + { .compatible = "hisilicon,hip07-io-djtag-v2", > + .data = (void *)djtag_readwrite_v2 }, > + {}, > +}; If these are backwards compatible, just mark them as compatible in DT, e.g. hip06 can use compatible = "hisilicon,hip06-cpu-djtag-v1", "hisilicon,hip05-cpu-djtag-v1"; so you can tell the difference if you need to, but the driver only has to list the oldest one here. What is the difference between the cpu and io djtag interfaces? I think you can also drop the '(void *)'. > +static void djtag_register_devices(struct hisi_djtag_host *host) > +{ > + struct device_node *node; > + struct hisi_djtag_client *client; > + > + if (!host->of_node) > + return; > + > + for_each_available_child_of_node(host->of_node, node) { > + if (of_node_test_and_set_flag(node, OF_POPULATED)) > + continue; > + client = hisi_djtag_of_register_device(host, node); > + list_add(&client->next, &host->client_list); > + } > +} Can you explain your thoughts behind creating a new bus type and adding the child devices manually rather than using platform_device structures with of_platform_populate()? Do you expect to see other implementations of this bus type with incompatible bus drivers? Arnd