From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932428AbcHZDoB (ORCPT ); Thu, 25 Aug 2016 23:44:01 -0400 Received: from mail-db5eur01on0123.outbound.protection.outlook.com ([104.47.2.123]:44617 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751485AbcHZDn7 (ORCPT ); Thu, 25 Aug 2016 23:43:59 -0400 X-Greylist: delayed 21758 seconds by postgrey-1.27 at vger.kernel.org; Thu, 25 Aug 2016 23:43:59 EDT Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=peda@axentia.se; From: Peter Rosin To: CC: Peter Rosin , David Airlie , "Wolfram Sang" , , Subject: [PATCH v2] i2c: move locking operations to their own struct Date: Thu, 25 Aug 2016 23:07:01 +0200 Message-ID: <1472159221-10807-1-git-send-email-peda@axentia.se> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [217.210.101.82] X-ClientProxiedBy: HE1PR05CA0006.eurprd05.prod.outlook.com (10.162.181.16) To HE1PR0201MB2314.eurprd02.prod.outlook.com (10.168.145.149) X-MS-Office365-Filtering-Correlation-Id: 797e2218-dbb1-415c-144d-08d3cd2bc975 X-Microsoft-Exchange-Diagnostics: 1;HE1PR0201MB2314;2:+HoyEgsenfiX39XYzyPlUYzSznN/bexImZHwK0D4CubHq1SNwLsCKpX5YYYFIy3n3bjkJgYZ+z51dVNvhGOW2FGjHxtEK23oTd50J5iMTyboQqYzWx6klnfl2stHAdf2+0AIpEBVrpXlgW1pTk3VxPqtm2Cu4USq14ObNhuixNRlX1+zejNvR0j6zJMrv9QC;3:t4jE8ppzrH3jeb+kqRJ5P9N8UAc32J8SlTRv6eU1cw8IFJkVBDao6Lb+gWLHNSa7rCqJkWVLv/Obak8WO0sbZhBhJU3BVKU3bAwbTrja0q5aHLPQ9KQX7cG2EJmZYuFI X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HE1PR0201MB2314; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0201MB2314;25:HTZwyJ9aUPnzq3IBs046mN4kyvcQpdE67a9XZp7m1gaEvWs1bBCK7uUGru60RBuQUZq2I6hEaNkyG22C4sdd8XQPYqvR/oo1A0tXBH+nhSYbjNwkzNgPkSo1AThWYZUgueH5rzRKJfti635fI3mag3lYrwj+xnovyCkyfymXpPzRZVErfZUcet06L3tXtshTS4nIeLtVPRVXfZoSx/CWqMT/yzR7ea1UE4o52dDdG65WI4YyJLskPxuF8/0AGInFUIr0phOu2hED+JeEAH3wF03DPoMrlRnamA4D+MrfdAWrTiiFLrnB4tj6CsB3ozVk9JjkiM+xoPbVR4aAOk16ySFLfCp1RAaiLqDOrdk1byO+Y6uSqWWsqw59PjScCXw22n8kwAWef0rjyuAznd3MixfAk5/qyzv9/uZbEN5D78SjTo17pfQrBw6DsLtN41ZsuPANXdLWdH07VBvKYJeUkU3L7clSKZK/KJfoR97G5AZqUjqjqlNPTP8WYCbyfgoAlIwovhVgV5fnEehXEX5wSaMwllhLt9XOnMFPlk1miMWEpQ3ighlS/aPcV6aScJOuK5bIKxnrYXER2ppKw2iGh5AwUsOi344oCdYqEQqPdOweIvRT2QREXXW2QU4n1G44cWUQmzlW+pqRKuvOslZsJbgqnStnK+RRu53Mi3n6A13tQV8xW6iI1q4h7EReSPMPaLvHT2oHkQs8vvEEwYexAwlWoPwbLa6rnwd/f2pG0dqDFM1lWecpEkkN0wBm3chAXpiH8HqiMBZSTz1DYL8ZFyRqyCGvo5cdaGVs8q0nb/9zN6mJbCiu5bSoL4Z4ko0w X-Microsoft-Exchange-Diagnostics: 1;HE1PR0201MB2314;31:V4yokqwFmNwJTxu35FtCUB9TpnKyWW/swJb27tGUGPD0iea+JJrwA5F0e3OQG47qrFdUyv+qWo59OGVoatb+dVE19nCopIc3H0SvY9KKOtFvAOnOyXtdMMGXnmIKFmUjpWGzh0Q0bcEXVEin31cdyXyqlYfWaQC/VQ/NPjRDa5vI+8XSDhTJ9lGeOLJb9c0HnpD+cyeI/Nv5KX0TpcNfi89Dx2DTJMylxvEdPZNOYBk=;4:wFiGgoXQCGn5HcnPA12fu6E7JbkqS25WcFVyhW9NTZW26KtbrRJBcOxXEkXbfTe4LTVa61wFce+KyGjhPsfzBkK1LbsTxleNRRGd8SoqPCHx2qUTNygy2v6BrT8tT/RliE8mG8mtiFvyZnV3B9MbjIa8Z0QPFdknAXdgYNRSyvzHttHjLi4CCoQbOxh/k9vXH/VpavQkczOrFHNiO88ah83P4rBUXqCHLVLRqoqwR+jtNqeEZQ+0uiIrjxkhcfchAP8zut4U0vcv6KuOeJW3bBbMoY6yu2Mb46gNkRoQJmViE44XSLfXQsR7sanzf6VytUa6DOknWvEOw6ApvMOQ2AP8CHNTEDqtxiHxPyuDHiHoE9tA4Z8uAtP2CByzQVpI5+ZKmOT/4Z5AACXJsuX4Ix9MdDM7kbBODvnd/D9GFoc= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6043046)(6042046);SRVR:HE1PR0201MB2314;BCL:0;PCL:0;RULEID:;SRVR:HE1PR0201MB2314; X-Forefront-PRVS: 0045236D47 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(979002)(6009001)(6069001)(7916002)(209900001)(199003)(189002)(15395725005)(42186005)(7846002)(33646002)(3846002)(7736002)(105586002)(5003940100001)(50986999)(6116002)(36756003)(586003)(110136002)(5660300001)(97736004)(68736007)(189998001)(305945005)(101416001)(50226002)(66066001)(92566002)(15975445007)(47776003)(229853001)(2906002)(19580405001)(4326007)(19580395003)(106356001)(77096005)(86362001)(81166006)(50466002)(2351001)(48376002)(8676002)(74482002)(81156014)(42262002)(6606295002)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1102;SCL:1;SRVR:HE1PR0201MB2314;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;HE1PR0201MB2314;23:sKEiXCyr6hFoR+CNiVxiqd2GpBgfr5k0fI26Z4E?= =?us-ascii?Q?VynIoc3mvgztjFNQOUuj2W1JyNygpr9L28RaBBZdMntzdyTOYRAbbdDc3MYj?= =?us-ascii?Q?EXjo7dSWgC0h/gHU8GSLS3j+rHvVq0oXoAayewDfYDFTX4RHzbmDXOJ/RdvW?= =?us-ascii?Q?J3iW1htyEg3Lyjo7TQfgEO2puD3TSddD+j7K8D1h2S/mcDe3ALCK7DsxA/RM?= =?us-ascii?Q?EdkwGDNHd0GT+px51f5tIJ7gUcNknY45FU40Aat1Ax4GdwK93/fCFWbhdjeR?= =?us-ascii?Q?pe61OG79VYyE67jLapzDdGXNsYML8rXPFuWET+8aBt2J7AHL4jD/1jmCPizD?= =?us-ascii?Q?/1YNICzWUtOyruNu5+xN489f6bC4kbvwyfOtu98Eub5fuXnBFGLX8EDFXKHB?= =?us-ascii?Q?LcBKjUAxJ/G1sQlqar9nYcb2750dHZSEenTtAvWGyFao38xcko3oCxlEYEmO?= =?us-ascii?Q?s3CNJqq2tkmqLFiznMDClMXTwy6j3nC07k+g9mLXB1VUdAZOF189Orv9kYA8?= =?us-ascii?Q?t05Y7Z3PZdEtuCsCtE6XXbuZj+KDcGFiUZ5enCLFhK6zF3NcZeEQu+REpv64?= =?us-ascii?Q?YDt4IuaMycC8mxAQjC9UgZ2ZK/EhOC2z/bZuWNQnL7HOIze1TTGdtTEybeqF?= =?us-ascii?Q?V5EzmwaC4Wok2mqgk49azasWl2V+vGDGFKzN8lAnlgmdYYlLexKIlu+5jwG7?= =?us-ascii?Q?NzlYA1dfRwwE9CGIXg6ZVlEHF2sg5Uc87ZUzpSVuflCN3il4O3n9BV22LR09?= =?us-ascii?Q?PQTzOGXWRuaILVpT2EMDLDf1bOl+ti29MNM2a2gWsRc4Kk6wRSoa0gGBqo3M?= =?us-ascii?Q?+i4eyjQDpI4DLCLiUcEVoim6q8aHXKHoWmRnFL3XbnB4+NnQsUlnjhlNmRnq?= =?us-ascii?Q?ITgAhYI+gK8Ah1VzCYlgkk/6CqIWRd+fL+7Vt2WttpQbfYqLV73jAK8DYneQ?= =?us-ascii?Q?QbxALxmtlRuNVF81Vb8g1axpyN2bAXZeD0yQ63443hgtUk0nHjwem5thfp8Z?= =?us-ascii?Q?AiemOzuQE9HT+PEbNBVvvLbVUV/KJvuMYLv+Q7RxmRfiEr59/7Paul7cD124?= =?us-ascii?Q?DsrKoqRsdukKF0RLBqjaRrPhOoHSeYn5WzIpMlCsuEQ+L+WjatfkG1a2thng?= =?us-ascii?Q?MnZUTlRFiJyVuhWwOvLF0Qfgkjd6h2EAVe9/rjhVvAabs4U2CDv//8i/sf3U?= =?us-ascii?Q?YFyfiIID2OTegmPwHfl0xzGLvP9gS6P3o4VraycnPecFHPVE/Y2Ck1BkUGuY?= =?us-ascii?Q?CgVkZIxmQ6dSyl46z6FcMdgJ4j1TaPUv3LfyIMLS+?= X-Microsoft-Exchange-Diagnostics: 1;HE1PR0201MB2314;6:jVQUrfubT5ZsSnaKzaOzJXoLtqVv+8yynw318eGxLmu1dxdYJJodJY+QjeA2VvtomKwxojnXNbdSRmburA4zXNIy/4K5bsdCK/vV+mECpZyBYdoD9a+9Pyo0IXx13c5S63UCJLflsHxlvah18P1/ip8IHTJsa5+6AZSq8y3hcqLJ3tKOfzdaNDXj2pd0Scx7uYhvbUyEl9gYxXr4OgSlGKpii/t3gygU0RkmVtoItNEvCtIDsQS0SDLJ+QvTskw6Fu9CsTeUgi+8J4pX+SmwgFeV5S67b5Nr+DQgLFDoKQSkhaFrUFwt/X716SdjKo3P;5:r31L8PlX7yam2vOaixKfZeoS74hBPpHKH4UPGphfcny/sa5fafBGOoQlKolCRB5fo5A9TLayaUzobh5n6vcOC+bICQv5AuA3OLhIDvfSj1h9jePH/RR5q7VYzZI18YQv8xVtdZwEJeB0DcNgnkJbOg==;24:rLfCcALaPpxyz7j7r7TJJ7si1hIMw2dI0Q6YzrLvCjLYIg/E/MMdbdXjLcgCPohw5d39B5pwZ7JgzQQ1oNLasrwWdg2fEvLp8OdTqF8yiHg=;7:M/ax0XtMvrA7dGXTMpg6Opg5RqNIgpsnVjlHOdixBmGoEC6hshxBJbUbn1C0HwQIKAhysnvJhgYf1DmQnlPmwhC2FqJiQhP8RZweDw5gHKlkuE0ilggccwqO0x29w1zf5BHCs/WgMjQYxFbD2ar+wE5OuX6uaY6pn0BzgWCDA++/Ti1zMoMM3cIjRhFc+engoMg627ha3L9smp8X0zDJ6538F7v2OQd00V2RNmOuAncIj8JVdQ7KUqnXWn2xy5LV SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: axentia.se X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Aug 2016 21:07:13.1058 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0201MB2314 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This makes it trivial to constify them, so do that. Signed-off-by: Peter Rosin --- drivers/gpu/drm/drm_dp_helper.c | 10 +++++++--- drivers/i2c/i2c-core.c | 13 ++++++++----- drivers/i2c/i2c-mux.c | 25 ++++++++++++++++--------- include/linux/i2c.h | 25 ++++++++++++++++++------- 4 files changed, 49 insertions(+), 24 deletions(-) Changes since v1: - Also fix the user in drivers/gpu (only compile-tested, but it's simple enough...) This takes care of the 0-day splat reported in: http://marc.info/?l=linux-i2c&m=147215193023544&w=2 Cheers, Peter diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index eae5ef963cb7..2bd064493ae7 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -790,6 +790,12 @@ static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags) mutex_unlock(&i2c_to_aux(i2c)->hw_mutex); } +static const struct i2c_lock_operations drm_dp_i2c_lock_ops = { + .lock_bus = lock_bus, + .trylock_bus = trylock_bus, + .unlock_bus = unlock_bus, +}; + /** * drm_dp_aux_init() - minimally initialise an aux channel * @aux: DisplayPort AUX channel @@ -807,9 +813,7 @@ void drm_dp_aux_init(struct drm_dp_aux *aux) aux->ddc.algo_data = aux; aux->ddc.retries = 3; - aux->ddc.lock_bus = lock_bus; - aux->ddc.trylock_bus = trylock_bus; - aux->ddc.unlock_bus = unlock_bus; + aux->ddc.lock_ops = &drm_dp_i2c_lock_ops; } EXPORT_SYMBOL(drm_dp_aux_init); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 56e50ca905ba..0bdda24a10b2 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1691,6 +1691,12 @@ static int __process_new_adapter(struct device_driver *d, void *data) return i2c_do_add_adapter(to_i2c_driver(d), data); } +static const struct i2c_lock_operations i2c_adapter_lock_ops = { + .lock_bus = i2c_adapter_lock_bus, + .trylock_bus = i2c_adapter_trylock_bus, + .unlock_bus = i2c_adapter_unlock_bus, +}; + static int i2c_register_adapter(struct i2c_adapter *adap) { int res = -EINVAL; @@ -1710,11 +1716,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } - if (!adap->lock_bus) { - adap->lock_bus = i2c_adapter_lock_bus; - adap->trylock_bus = i2c_adapter_trylock_bus; - adap->unlock_bus = i2c_adapter_unlock_bus; - } + if (!adap->lock_ops) + adap->lock_ops = &i2c_adapter_lock_ops; rt_mutex_init(&adap->bus_lock); rt_mutex_init(&adap->mux_lock); diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 764f195795e4..14741ff31041 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -263,6 +263,18 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent, } EXPORT_SYMBOL_GPL(i2c_mux_alloc); +static const struct i2c_lock_operations i2c_mux_lock_ops = { + .lock_bus = i2c_mux_lock_bus, + .trylock_bus = i2c_mux_trylock_bus, + .unlock_bus = i2c_mux_unlock_bus, +}; + +static const struct i2c_lock_operations i2c_parent_lock_ops = { + .lock_bus = i2c_parent_lock_bus, + .trylock_bus = i2c_parent_trylock_bus, + .unlock_bus = i2c_parent_unlock_bus, +}; + int i2c_mux_add_adapter(struct i2c_mux_core *muxc, u32 force_nr, u32 chan_id, unsigned int class) @@ -312,15 +324,10 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, priv->adap.retries = parent->retries; priv->adap.timeout = parent->timeout; priv->adap.quirks = parent->quirks; - if (muxc->mux_locked) { - priv->adap.lock_bus = i2c_mux_lock_bus; - priv->adap.trylock_bus = i2c_mux_trylock_bus; - priv->adap.unlock_bus = i2c_mux_unlock_bus; - } else { - priv->adap.lock_bus = i2c_parent_lock_bus; - priv->adap.trylock_bus = i2c_parent_trylock_bus; - priv->adap.unlock_bus = i2c_parent_unlock_bus; - } + if (muxc->mux_locked) + priv->adap.lock_ops = &i2c_mux_lock_ops; + else + priv->adap.lock_ops = &i2c_parent_lock_ops; /* Sanity check on class */ if (i2c_mux_parent_classes(parent) & class) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index c1f60a345db7..616f67635734 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -427,6 +427,20 @@ struct i2c_algorithm { }; /** + * struct i2c_lock_operations - represent I2C locking operations + * @lock_bus: Get exclusive access to an I2C bus segment + * @trylock_bus: Try to get exclusive access to an I2C bus segment + * @unlock_bus: Release exclusive access to an I2C bus segment + * + * The main operations are wrapped by i2c_lock_bus and i2c_unlock_bus. + */ +struct i2c_lock_operations { + void (*lock_bus)(struct i2c_adapter *, unsigned int flags); + int (*trylock_bus)(struct i2c_adapter *, unsigned int flags); + void (*unlock_bus)(struct i2c_adapter *, unsigned int flags); +}; + +/** * struct i2c_timings - I2C timing information * @bus_freq_hz: the bus frequency in Hz * @scl_rise_ns: time SCL signal takes to rise in ns; t(r) in the I2C specification @@ -536,6 +550,7 @@ struct i2c_adapter { void *algo_data; /* data fields that are valid for all devices */ + const struct i2c_lock_operations *lock_ops; struct rt_mutex bus_lock; struct rt_mutex mux_lock; @@ -552,10 +567,6 @@ struct i2c_adapter { struct i2c_bus_recovery_info *bus_recovery_info; const struct i2c_adapter_quirks *quirks; - - void (*lock_bus)(struct i2c_adapter *, unsigned int flags); - int (*trylock_bus)(struct i2c_adapter *, unsigned int flags); - void (*unlock_bus)(struct i2c_adapter *, unsigned int flags); }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) @@ -597,7 +608,7 @@ int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *)); static inline void i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags) { - adapter->lock_bus(adapter, flags); + adapter->lock_ops->lock_bus(adapter, flags); } /** @@ -611,7 +622,7 @@ i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags) static inline int i2c_trylock_bus(struct i2c_adapter *adapter, unsigned int flags) { - return adapter->trylock_bus(adapter, flags); + return adapter->lock_ops->trylock_bus(adapter, flags); } /** @@ -623,7 +634,7 @@ i2c_trylock_bus(struct i2c_adapter *adapter, unsigned int flags) static inline void i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags) { - adapter->unlock_bus(adapter, flags); + adapter->lock_ops->unlock_bus(adapter, flags); } static inline void -- 2.1.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Peter Rosin Subject: [PATCH v2] i2c: move locking operations to their own struct Date: Thu, 25 Aug 2016 23:07:01 +0200 Message-ID: <1472159221-10807-1-git-send-email-peda@axentia.se> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from mail-db5eur01on0123.outbound.protection.outlook.com ([104.47.2.123]:51271 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753021AbcHYVlV (ORCPT ); Thu, 25 Aug 2016 17:41:21 -0400 Sender: linux-i2c-owner@vger.kernel.org List-Id: linux-i2c@vger.kernel.org To: linux-kernel@vger.kernel.org Cc: Peter Rosin , David Airlie , Wolfram Sang , dri-devel@lists.freedesktop.org, linux-i2c@vger.kernel.org This makes it trivial to constify them, so do that. Signed-off-by: Peter Rosin --- drivers/gpu/drm/drm_dp_helper.c | 10 +++++++--- drivers/i2c/i2c-core.c | 13 ++++++++----- drivers/i2c/i2c-mux.c | 25 ++++++++++++++++--------- include/linux/i2c.h | 25 ++++++++++++++++++------- 4 files changed, 49 insertions(+), 24 deletions(-) Changes since v1: - Also fix the user in drivers/gpu (only compile-tested, but it's simple enough...) This takes care of the 0-day splat reported in: http://marc.info/?l=linux-i2c&m=147215193023544&w=2 Cheers, Peter diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index eae5ef963cb7..2bd064493ae7 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -790,6 +790,12 @@ static void unlock_bus(struct i2c_adapter *i2c, unsigned int flags) mutex_unlock(&i2c_to_aux(i2c)->hw_mutex); } +static const struct i2c_lock_operations drm_dp_i2c_lock_ops = { + .lock_bus = lock_bus, + .trylock_bus = trylock_bus, + .unlock_bus = unlock_bus, +}; + /** * drm_dp_aux_init() - minimally initialise an aux channel * @aux: DisplayPort AUX channel @@ -807,9 +813,7 @@ void drm_dp_aux_init(struct drm_dp_aux *aux) aux->ddc.algo_data = aux; aux->ddc.retries = 3; - aux->ddc.lock_bus = lock_bus; - aux->ddc.trylock_bus = trylock_bus; - aux->ddc.unlock_bus = unlock_bus; + aux->ddc.lock_ops = &drm_dp_i2c_lock_ops; } EXPORT_SYMBOL(drm_dp_aux_init); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 56e50ca905ba..0bdda24a10b2 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1691,6 +1691,12 @@ static int __process_new_adapter(struct device_driver *d, void *data) return i2c_do_add_adapter(to_i2c_driver(d), data); } +static const struct i2c_lock_operations i2c_adapter_lock_ops = { + .lock_bus = i2c_adapter_lock_bus, + .trylock_bus = i2c_adapter_trylock_bus, + .unlock_bus = i2c_adapter_unlock_bus, +}; + static int i2c_register_adapter(struct i2c_adapter *adap) { int res = -EINVAL; @@ -1710,11 +1716,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap) goto out_list; } - if (!adap->lock_bus) { - adap->lock_bus = i2c_adapter_lock_bus; - adap->trylock_bus = i2c_adapter_trylock_bus; - adap->unlock_bus = i2c_adapter_unlock_bus; - } + if (!adap->lock_ops) + adap->lock_ops = &i2c_adapter_lock_ops; rt_mutex_init(&adap->bus_lock); rt_mutex_init(&adap->mux_lock); diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 764f195795e4..14741ff31041 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -263,6 +263,18 @@ struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent, } EXPORT_SYMBOL_GPL(i2c_mux_alloc); +static const struct i2c_lock_operations i2c_mux_lock_ops = { + .lock_bus = i2c_mux_lock_bus, + .trylock_bus = i2c_mux_trylock_bus, + .unlock_bus = i2c_mux_unlock_bus, +}; + +static const struct i2c_lock_operations i2c_parent_lock_ops = { + .lock_bus = i2c_parent_lock_bus, + .trylock_bus = i2c_parent_trylock_bus, + .unlock_bus = i2c_parent_unlock_bus, +}; + int i2c_mux_add_adapter(struct i2c_mux_core *muxc, u32 force_nr, u32 chan_id, unsigned int class) @@ -312,15 +324,10 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, priv->adap.retries = parent->retries; priv->adap.timeout = parent->timeout; priv->adap.quirks = parent->quirks; - if (muxc->mux_locked) { - priv->adap.lock_bus = i2c_mux_lock_bus; - priv->adap.trylock_bus = i2c_mux_trylock_bus; - priv->adap.unlock_bus = i2c_mux_unlock_bus; - } else { - priv->adap.lock_bus = i2c_parent_lock_bus; - priv->adap.trylock_bus = i2c_parent_trylock_bus; - priv->adap.unlock_bus = i2c_parent_unlock_bus; - } + if (muxc->mux_locked) + priv->adap.lock_ops = &i2c_mux_lock_ops; + else + priv->adap.lock_ops = &i2c_parent_lock_ops; /* Sanity check on class */ if (i2c_mux_parent_classes(parent) & class) diff --git a/include/linux/i2c.h b/include/linux/i2c.h index c1f60a345db7..616f67635734 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -427,6 +427,20 @@ struct i2c_algorithm { }; /** + * struct i2c_lock_operations - represent I2C locking operations + * @lock_bus: Get exclusive access to an I2C bus segment + * @trylock_bus: Try to get exclusive access to an I2C bus segment + * @unlock_bus: Release exclusive access to an I2C bus segment + * + * The main operations are wrapped by i2c_lock_bus and i2c_unlock_bus. + */ +struct i2c_lock_operations { + void (*lock_bus)(struct i2c_adapter *, unsigned int flags); + int (*trylock_bus)(struct i2c_adapter *, unsigned int flags); + void (*unlock_bus)(struct i2c_adapter *, unsigned int flags); +}; + +/** * struct i2c_timings - I2C timing information * @bus_freq_hz: the bus frequency in Hz * @scl_rise_ns: time SCL signal takes to rise in ns; t(r) in the I2C specification @@ -536,6 +550,7 @@ struct i2c_adapter { void *algo_data; /* data fields that are valid for all devices */ + const struct i2c_lock_operations *lock_ops; struct rt_mutex bus_lock; struct rt_mutex mux_lock; @@ -552,10 +567,6 @@ struct i2c_adapter { struct i2c_bus_recovery_info *bus_recovery_info; const struct i2c_adapter_quirks *quirks; - - void (*lock_bus)(struct i2c_adapter *, unsigned int flags); - int (*trylock_bus)(struct i2c_adapter *, unsigned int flags); - void (*unlock_bus)(struct i2c_adapter *, unsigned int flags); }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) @@ -597,7 +608,7 @@ int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *)); static inline void i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags) { - adapter->lock_bus(adapter, flags); + adapter->lock_ops->lock_bus(adapter, flags); } /** @@ -611,7 +622,7 @@ i2c_lock_bus(struct i2c_adapter *adapter, unsigned int flags) static inline int i2c_trylock_bus(struct i2c_adapter *adapter, unsigned int flags) { - return adapter->trylock_bus(adapter, flags); + return adapter->lock_ops->trylock_bus(adapter, flags); } /** @@ -623,7 +634,7 @@ i2c_trylock_bus(struct i2c_adapter *adapter, unsigned int flags) static inline void i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags) { - adapter->unlock_bus(adapter, flags); + adapter->lock_ops->unlock_bus(adapter, flags); } static inline void -- 2.1.4