From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932385AbcIUHKh (ORCPT ); Wed, 21 Sep 2016 03:10:37 -0400 Received: from mail-sn1nam02on0054.outbound.protection.outlook.com ([104.47.36.54]:48393 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755144AbcIUHKY (ORCPT ); Wed, 21 Sep 2016 03:10:24 -0400 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com;nxp.com; dkim=none (message not signed) header.d=none; From: Yangbo Lu To: , , Scott Wood , Arnd Bergmann CC: , , , , , , , , Mark Rutland , Rob Herring , Russell King , Jochen Friedrich , Joerg Roedel , Claudiu Manoil , "Bhupesh Sharma" , Qiang Zhao , "Kumar Gala" , Santosh Shilimkar , Leo Li , Xiaobo Xie , Minghuan Lian , Yangbo Lu Subject: [v12, 7/8] base: soc: introduce soc_device_match() interface Date: Wed, 21 Sep 2016 14:57:19 +0800 Message-ID: <1474441040-11946-8-git-send-email-yangbo.lu@nxp.com> X-Mailer: git-send-email 2.1.0.27.g96db324 In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu@nxp.com> References: <1474441040-11946-1-git-send-email-yangbo.lu@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131189154211643545;(91ab9b29-cfa4-454e-5278-08d120cd25b8);() X-Forefront-Antispam-Report: CIP:192.88.168.50;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(7916002)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(11100500001)(5003940100001)(106466001)(4326007)(86362001)(50986999)(76176999)(356003)(104016004)(105606002)(92566002)(77096005)(5660300001)(626004)(36756003)(586003)(7846002)(68736007)(33646002)(8666005)(50226002)(2906002)(7416002)(5001770100001)(97736004)(189998001)(305945005)(81166006)(19580405001)(19580395003)(81156014)(48376002)(229853001)(87936001)(8676002)(50466002)(85426001)(2950100001)(47776003)(8936002)(7059030);DIR:OUT;SFP:1101;SCL:1;SRVR:DM2PR0301MB0718;H:tx30smr01.am.freescale.net;FPR:;SPF:Fail;PTR:InfoDomainNonexistent;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BN1AFFO11FD025;1:jX7NdDjwtcqv8r9D7Ne5X6fjM13meDF3j1P50GxyJnh9+M6YbZC/Ni9yD5PGj1Au7Eu+F5yKETCMXTwg0bU2UCzEobjOwcugBoYfwnIAC79dyhHEXa3aaHqL2NhXBbeCnkDKjWwqe8I7ByJLANGReyd12vvoLE7qixkMBwq800HiS89Gg1iFQLYpCvhbekINXiLM7yYy5aEgO3/eizXlnG1831VM8oOgWZ1yum4+Cjx+OWUawTlGpCHZbFIZq5R9+AJJSWIVXJOO+1WZ3C1Oxrd86X+tMxH2HMoYajiB9D0W1YTu2hXeWY6FjJ27MYDao0+nfVz53Gjb5jz4vFmDlOcfd/WTfqJ4GKDNPUz+4alRtDaX/VsDpyOWsoRHhg8LdN68jircL64TwBdM9khFJXrXpYUtjGdKCELxqgjlLtt7OILc9g516NvNTF7uhvWtLnxahejDU5oX3D1ZX/9jfwiLGyG9OGwjO6Ro0zzlMMczEXdX5Xz9FMTvp35T/HxsSxxPjVvpGgrpqiKy5++2iU9Uxwskq73uxusiwHSlcgbSgbutnHTnyhzMznhy+0lGDO3BJk2lusC9MKc5sJlRUPIPlCNkYhc3HEHt/1k+MgnN9lgvaoF1nEM3c70nHxMAfoaVzUCfy1ofQ+odqh4yn/XGW/uPHqc9ojeKsTgrp16G7/bdnpEUKvbL6coXUsq3qsyh9uHMsYmRgtn+orx24O4sN0gB19po/h3eh4dC4IPmAlxppRBOvaRBC5SGdf1M MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: b4c3ec3e-db9e-4ede-df38-08d3e1ee599f X-Microsoft-Exchange-Diagnostics: 1;DM2PR0301MB0718;2:ojZcEIK1pJavDbKu21wqzk8FbzizR5dFHp1PEJYk1zIX4BAgI3dPb0Wncl/p3qW8ejSMyL1ENnIJkpU8gjUxeP3m1BVpHHA23Bi+A4MsnkSnhnuyKFxy78ykrCAUTYUijVN7Ig5WINZNEZhMRY5ezZXAIIweRBRALHREGWb29qLngwCBXQDMvj7pNnZKNDaZ;3:1aE6EEqKAhwjpMwT4a4ViXYpKK5aR/wRmzWvuj+27BmbzD97DgRhnF1iLovMrghrVVmpW3Pd0RZmz200omLjPks8luX769IpMa4E+lPD0vcAHdFWTCEQIy5qi8dnrqiXDjo13RDm0EutRESF93tGK3TpxSjLqfvP5P5sHKyJIhdyBTDr23gTlgfEcD5VIUm3bfkuJcDwPHB96oU7gqzwWvne8uv34Kjpr6AFStH4mEw= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM2PR0301MB0718; X-Microsoft-Exchange-Diagnostics: 1;DM2PR0301MB0718;25:4kvdx0otjJvruXJC5O6rr9P+cWv6S8ad2vugcVdJ6ic9AuynJzhQInJ51KJjLRfNFB4viCYd3Xn5gd+xYkMq0KJQqoElkgTjAr7I3SFf0fgokX2sWe6c8uIvGq/ZW1yuI2S/BYsdlDNnxQIGIvXPN9quy83gmvI/3K5BqADwydNsktcpkACrKCdxDxy6M4U0s3vyhBL/V1v+aa3+E3qsqHOGYM28P7GPYbst2dz5CANYaoFPhk1RQiBoYQ38gVXqlZJaE9qd+7O9WA8l39dz1RHuvA1uszgF42OXJnWpc0cwtPVsAKF0OR9o6Nvzl2fWAyBGtgSBnbk7A20uIcxsSlxADD2MFkk4gHDkFCsmcanl4uCIjtUmZAH0YEGFAmvD1X6FApp05319QIp6hyWbU3r0ko0KROCff56ey3v9Oe/mR4aJjE4if6asPqktuoVdaES6slS/Sei6rMnBQfVtrHMVWACqMe5AZPNeshQFLWaBkJosQKoZ/D90l2CuXx1y6YLD6x3kgHM7Z0BmJc6BDCfDZkLBw7rE0HJNoKpmaQztNrsWF/2uELgncZ1FK+2pz76C8FW5AJ4aph+ZXmFP6leISmyjl+i9uo6rCQpJuMFlB+VTfBzmT2UurKISgCfAZgOpKIuML1phCfylx/NK8clxNM6MA8qRbilJ/hurn8z2Xr791bk++1hRJyoZu55KBrgbzvMcZJaKM6vJR5QkBhunscfSTSFGPc6iGGP1KH0trONiR6ua73+MCGFT7qrb X-Microsoft-Exchange-Diagnostics: 1;DM2PR0301MB0718;31:v6qd0gfeUG45gRTBPPSVH25w+xR+kYfCWq9Cy4gJjeCWlmkD2X82W8I/oLHsQb8qjI8/3YdJEVVhkf+k/Ukdfyl2fjyi92LIXS2gCedL3W1yh+Q6KdJmaUhSCpXIsu8doyQI5FkIMxlk23PXl0AWlPR0vol7hIU9x52NgR2DJ2zckOJYW4ErSw4Pod+S/bdVg8jNbaU+u3bWr/pYwx901TkFSgt1TI7R8VDk4LXKYX4=;4:AOheck4TjIxgcrQF/u/nUsF4b/fYPhVNcuwv8TWeqdx7FPdXssUzkhD7sBXOs/pmLjsyJYFW/kcDZt1ujHJx2tfNQVzVxStTa7pH74s8GbuuaDM7tQl6CyGHoKgwtlGPK3omhKi/W/1L9fQAe4fa+qMV/wfnMxYq1HCFK6HHXqkIUXn8q22BEtOF0kDe/C2Zf8pdB+MtFlMsczqx2+F7SbEDms1F5wIxfWAyVYSS4Fz4JiMAhz/H3kIV+vgcbFMO73n9Vonxy5IIVR3OKUpBNa/cFVb/RAumvF0yVveQkfnri3OnSzq10nbgnOhTaxSlLwQ6+BvPVIdfPq0i2mIYc0eq/R45qrK2JCEXyZhQ0RNLN88YnIongOcE/br9KST5WMbYXgIfoPynpir7XMj9wbQ7h3bqW7u0uKbkl1eyVV5c5e6o/0mdytpmuUATQteL5M9VWiyAkapbwiIG8u5P3MSwvzIQ9SJjeCo/fcjACAoet/4Eq+KerDUyKBHkOJ634/BywNpY6egNXJwtt+QaDLq85CMgBG59nheFjVVcN9U= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(13015025)(13017025)(13023025)(13024025)(13018025)(8121501046)(5005006)(10201501046)(3002001)(6055026);SRVR:DM2PR0301MB0718;BCL:0;PCL:0;RULEID:(400006);SRVR:DM2PR0301MB0718; X-Forefront-PRVS: 007271867D X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM2PR0301MB0718;23:xxQ5j/j8t2WFqOQNiElOnCBgNezcsFpe+SvebXU?= =?us-ascii?Q?J945cU/wLTD9HD7B1c9q1WnynsoGNekDuVLpaVUF2pZwXuv0W6YSfNqkieem?= =?us-ascii?Q?V3ZMFbKBirxihao45vQzizn/FfPu7rsMHas2Q7h6Pf226jSbc71LVNCT8xCU?= =?us-ascii?Q?e7nn288GPF+ZyL2entIymNqB6gSWpDxJKScrWzUtq86tED0aold+63iiVrFn?= =?us-ascii?Q?/foxx5wP3Lp5BRRKm18xzd8RGMy+2aPBbrXmFlqESBYlkyRQ7yRXhfdBBhXV?= =?us-ascii?Q?dJ6ww6HtC/56dvN51gjXYBjc4a4gg/MKr8jSS3MTooKjWuyHJJfHU2ou2B1O?= =?us-ascii?Q?FoIzUKQTN1Dkmp9fzEzJqzu+g4fSd4NrrktXImxZ2yWl19snlOB9jQdWWzXx?= =?us-ascii?Q?B+Mc6swXRB9J9nyZLxk4QCtvtDhPSJM3peYiIZybXnD0yB0JhGlW/r2hAhE5?= =?us-ascii?Q?U7Sl+374mnKpCCa16CYzrcAZ/9ot9GZR1EerXOUEmBF9xOopccwR+vQHQY1x?= =?us-ascii?Q?/WXQIdb7DD9/5i44ehUO1N3gglV72idWQxK6NS/AK6AvYZv+Tv5M4ayZo26c?= =?us-ascii?Q?tWRAuGheDK1qm1orwtv81udABMAHvc4ysY0mAxkK4K6BB5BeY8wPRPx2oHbo?= =?us-ascii?Q?XdgZmKpU+pkQtU+slX7tyWxSNnCy3QdGCIpQT2KIzjva7RJadHsCuk0w03t3?= =?us-ascii?Q?Xb6rCRoEYjHynDI8Ax+PabspyynKbe2vkdR74J+SjHs8HiAHRThVwisohpWq?= =?us-ascii?Q?JRAKbV4eHPasYM/gP7NZjNZzMHkyKg7rKdfTHBgh/219Cb2NH1dmV5LDIYF+?= =?us-ascii?Q?aVg0ZHELaXU1+YcXOQIuEqQUB+BUYng2P0XBUe09u/YqPNWlUKc+oSG2UC8o?= =?us-ascii?Q?/7noHdIHuL81EWYgEeaz4FRuWpRm97d2L0hDd3+gNsIXlkqkH6jgiH9c8tgA?= =?us-ascii?Q?viKDCOIp6uOXc1D5VrnXUPWKhUUKt7z6vCGoD4/hbUuvgzBdVvbsm/2v7o5T?= =?us-ascii?Q?MuszMta+D72gw85GK/FtlWslRcRwYT1inbi/ugm2711nd0maXDWEh0wyE/gh?= =?us-ascii?Q?bfB3w6lQlVzV1/9yOqXhLnBF7lkus7Cz5wjrZhisM9AA4pfoZAqXil6tThH4?= =?us-ascii?Q?WCmaZ05wWsFbz8aT4ZzBe3XjJHCLCIZw4wr1Nt5FlzBQwFuZwifKJw/bWUdL?= =?us-ascii?Q?UwpCEySKNklcAcSU=3D?= X-Microsoft-Exchange-Diagnostics: 1;DM2PR0301MB0718;6:0Jk8myuQmg5WKw66eWcgpUrnyGLs0dsa6Km2el2k7qtrhiJGIDoROvs0pmydAt8GC2I+EoIFu/9dTzIyK1nfNQMHaqkjpVmu62qewCseSv2im6E/7nwg+lHPcgtGAWo5Xi8EexIRkHrAI4J8LKWQcPAKIwqmxI7DeCP2p6UmL2J1Dogu7WDuCaS4qVGHizWPS8NnMgkGPc7TcnN4mOQ6AnzFXzTmQ3cawQTMJ8fi5qwlky0shGRrIfT/E1ecfqJedorH6UPivjvmuk/bSq6+flZcp2MjA9yJ8oPdomaIxOk=;5:Wf7v7llfZtUOH+LmItsygm5FHi1dkwPIPKhQ5FamLHXOTbHtbNngtokzGvzrWGSx3nmTQh1ht8yNOGlgEKB4mugK7lSIVcH5WJSJQKPkMwcX3PySzDfhkd0nqsShMnXdWu1OUBAwuNlBJDKn+l69Poja5fPIEe8G1twW7E81F8c=;24:VzPOtShzIOFOYcl8KimOoH2H6pNWdnPxwtzKn2+HMLHZg/PFjchoFIujHtjymcvAD3jK0/QpQ8i9ujYJJiiVYfqN8LI1WFPa4TM730MciZI=;7:7kwxmeXhuM3hHRMvO1GO/kw/4DZUwf45DCQG55uF2HhGbrCzBBIXKCND9TqfkSlSFqO0S4sFaYvaPCmBuU1Yg0+ybg3Rlc+euC0GJUDXkPj+8TyOGpTL0uYerqGaSW2QlQAgosakoIaKeVp/arKdwWJ1f4AHat02Nyz4bYjfYZVb0r1rLyPHsXyc8LLD2fHlsBbhjnuaGkeUy1wiUA47Wn7N7TOtxImyshIOGBYnY0EylDjl7TM2eWEYf1HEaQewqPkgEsGcHUN2+S83QxjiGq4Wbs7TaIKyIp6Z7gBoD9gKR+mgl3D7ruZMgw80SwxD SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2016 07:10:20.9147 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e;Ip=[192.88.168.50];Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR0301MB0718 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop --- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 98504ec..f1591ad2 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -225,6 +225,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 75b98aa..d2fd1ad 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -168,3 +169,68 @@ static void __exit soc_bus_unregister(void) bus_unregister(&soc_bus_type); } module_exit(soc_bus_unregister); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -13,6 +13,7 @@ struct soc_device_attribute { const char *family; const char *revision; const char *soc_id; + const void *data; }; /** @@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev); */ struct device *soc_device_to_device(struct soc_device *soc); +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches); #endif /* __SOC_BUS_H */ -- 2.1.0.27.g96db324 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yangbo Lu Subject: [v12, 7/8] base: soc: introduce soc_device_match() interface Date: Wed, 21 Sep 2016 14:57:19 +0800 Message-ID: <1474441040-11946-8-git-send-email-yangbo.lu@nxp.com> References: <1474441040-11946-1-git-send-email-yangbo.lu@nxp.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: Mark Rutland , Xiaobo Xie , Minghuan Lian , linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Qiang Zhao , Russell King , Bhupesh Sharma , Jochen Friedrich , Claudiu Manoil , devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Kumar Gala , Rob Herring , Santosh Shilimkar , linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Leo Li , iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, Yangbo Lu , linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org To: , , Scott Wood , Arnd Bergmann Return-path: In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org Errors-To: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org List-Id: netdev.vger.kernel.org From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop --- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 98504ec..f1591ad2 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -225,6 +225,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 75b98aa..d2fd1ad 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -168,3 +169,68 @@ static void __exit soc_bus_unregister(void) bus_unregister(&soc_bus_type); } module_exit(soc_bus_unregister); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -13,6 +13,7 @@ struct soc_device_attribute { const char *family; const char *revision; const char *soc_id; + const void *data; }; /** @@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev); */ struct device *soc_device_to_device(struct soc_device *soc); +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches); #endif /* __SOC_BUS_H */ -- 2.1.0.27.g96db324 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yangbo Lu Subject: [v12, 7/8] base: soc: introduce soc_device_match() interface Date: Wed, 21 Sep 2016 14:57:19 +0800 Message-ID: <1474441040-11946-8-git-send-email-yangbo.lu@nxp.com> References: <1474441040-11946-1-git-send-email-yangbo.lu@nxp.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org Errors-To: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org To: linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org, Scott Wood , Arnd Bergmann Cc: Mark Rutland , Xiaobo Xie , Minghuan Lian , linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Qiang Zhao , Russell King , Bhupesh Sharma , Jochen Friedrich , Claudiu Manoil , devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Kumar Gala , Rob Herring , Santosh Shilimkar , linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org, netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Leo Li , iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, Yangbo Lu , linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org List-Id: devicetree@vger.kernel.org From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop --- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 98504ec..f1591ad2 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -225,6 +225,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 75b98aa..d2fd1ad 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -168,3 +169,68 @@ static void __exit soc_bus_unregister(void) bus_unregister(&soc_bus_type); } module_exit(soc_bus_unregister); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -13,6 +13,7 @@ struct soc_device_attribute { const char *family; const char *revision; const char *soc_id; + const void *data; }; /** @@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev); */ struct device *soc_device_to_device(struct soc_device *soc); +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches); #endif /* __SOC_BUS_H */ -- 2.1.0.27.g96db324 From mboxrd@z Thu Jan 1 00:00:00 1970 From: yangbo.lu@nxp.com (Yangbo Lu) Date: Wed, 21 Sep 2016 14:57:19 +0800 Subject: [v12, 7/8] base: soc: introduce soc_device_match() interface In-Reply-To: <1474441040-11946-1-git-send-email-yangbo.lu@nxp.com> References: <1474441040-11946-1-git-send-email-yangbo.lu@nxp.com> Message-ID: <1474441040-11946-8-git-send-email-yangbo.lu@nxp.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop --- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 98504ec..f1591ad2 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -225,6 +225,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 75b98aa..d2fd1ad 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -168,3 +169,68 @@ static void __exit soc_bus_unregister(void) bus_unregister(&soc_bus_type); } module_exit(soc_bus_unregister); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h @@ -13,6 +13,7 @@ struct soc_device_attribute { const char *family; const char *revision; const char *soc_id; + const void *data; }; /** @@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev); */ struct device *soc_device_to_device(struct soc_device *soc); +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches); #endif /* __SOC_BUS_H */ -- 2.1.0.27.g96db324