From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 848C542AFB5 for ; Wed, 5 Aug 2026 13:22:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.16 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785936138; cv=none; b=AyjcjyN+cuaQtiz1z0qni3nElPjLMvVQfmyq0JSIvNrOfTLycfLggMSpWNMB1zo/48rIweswjmFvfqt2V/XTfHMvXmIUHjwGECh+71v4cAjJhMagumHJDCHjDY5KGZ1ECkZqNQnQeGK/G78pbWOJplbY2cbxXHU9SBbAOlVZdPA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785936138; c=relaxed/simple; bh=aQ9zGPNEkGKeGkyVcOJS4LseLHByzydOO/VceNvlFqU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=L+rGP6rhk9fwWqu7rZs+VgCZQ/clY/USdjvdDx5sgd2uPje4YBYs7c6m/Sqv/UJRihDAXNiCeLqm1mZNnTVfuzTdAT6jxMKxI2fSTaU7mv7kxvDuVz1hEh6qMNjPkcBZW3gCck7tcBbg2PuBPj3msESta1juXcq6e6xLerkd2Qs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=FYmA9OGR; arc=none smtp.client-ip=198.175.65.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="FYmA9OGR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1785936136; x=1817472136; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=aQ9zGPNEkGKeGkyVcOJS4LseLHByzydOO/VceNvlFqU=; b=FYmA9OGRrULNubxv3D+pOsQzALWnW6JlS/bq27J4cs/TWESI6cWeo4ro 8MlWFtsxPN8+upwanp2Q9IEqPX9ZEUSZrLrAYu1KyxifUmhs+VeURWMmx BkM00TNLazIR5Byy+QV4yr7f8RZFFRsqN9beIlJvyLIMnVtPzOFrfCzm9 ceqCXrbvAq5OHvbtHvNshgh/yX3sq/Q0UPqvN3YCiQuUQiocdAWXkjJ5e SXkel2jlf6X/3HkRs8kYoRmEMKrHWPtxc0AuwcxebZuTF9emOYPlg2zrp cfmbWnZw6WRW8S3mhYqHjIuTDeEmmS0wKgGbh1rWFY+iJVOBrFIqmPZli w==; X-CSE-ConnectionGUID: nMBTb4d/Sv2NwKd7jqzJVw== X-CSE-MsgGUID: fHLHWcE+RLS32pybDkQ4TQ== X-IronPort-AV: E=McAfee;i="6800,10657,11865"; a="86713075" X-IronPort-AV: E=Sophos;i="6.25,206,1779174000"; d="scan'208";a="86713075" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by orvoesa108.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Aug 2026 06:22:15 -0700 X-CSE-ConnectionGUID: gEe9b6UWSzGlfh2/Uo2Ikw== X-CSE-MsgGUID: yetdcU3lQ42mE2G6pbUaPA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,206,1779174000"; d="scan'208";a="259180442" Received: from mkosciow-mobl1.ger.corp.intel.com (HELO pujfalus-desk.intel.com) ([10.245.246.218]) by fmviesa008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Aug 2026 06:22:13 -0700 From: Peter Ujfalusi To: Mark Brown Cc: Charles Keepax , Richard Fitzgerald , Pierre-Louis Bossart , Peter Ujfalusi , linux-kernel@vger.kernel.org Subject: [PATCH] regcache: Sort the local copy of an unsorted reg_defaults array Date: Wed, 5 Aug 2026 16:22:50 +0300 Message-ID: <20260805132250.2637-1-peter.ujfalusi@linux.intel.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit regcache_lookup_reg() bsearch()es the reg_defaults array, which requires it to be sorted by ascending register address. Entries following a descending step are never found, so regcache_reg_needs_sync() reports that they need a sync and they are written to the device on every regcache_sync() even when they were never touched. Detect the misordering while reg_defaults is validated against the register stride and sort the local copy. The check needs no new loop and sort() only runs for the affected drivers, which are also warned about. Note that sort() is not stable, so for arrays with duplicated register addresses it remains unspecified which entry is found. Signed-off-by: Peter Ujfalusi --- Hi, Fixes for affected in-tree codec drivers have been posted separately, so this is meant as a safety net for out-of-tree and future drivers rather than a replacement for fixing them, as discussed on the Cirrus codec patches. I'm not sure about the print level: dev_warn() makes the problem visible to whoever boots the affected machine, but the person who can act on it is the driver author. Should this be dev_dbg()? Regards, Peter drivers/base/regmap/regcache.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index be167ee6f57c..aa7f6c30f232 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -123,6 +123,8 @@ static void regcache_hw_exit(struct regmap *map) int regcache_init(struct regmap *map, const struct regmap_config *config) { + bool sort_defaults = false; + unsigned int reg_prev = 0; int count = 0; int ret; int i; @@ -149,10 +151,16 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) return -EINVAL; } - for (i = 0; i < config->num_reg_defaults; i++) + for (i = 0; i < config->num_reg_defaults; i++) { if (config->reg_defaults[i].reg % map->reg_stride) return -EINVAL; + if (reg_prev > config->reg_defaults[i].reg) + sort_defaults = true; + + reg_prev = config->reg_defaults[i].reg; + } + for (i = 0; i < ARRAY_SIZE(cache_types); i++) if (cache_types[i]->type == map->cache_type) break; @@ -186,6 +194,13 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) sizeof(*map->reg_defaults), GFP_KERNEL); if (!tmp_buf) return -ENOMEM; + + /* regcache_lookup_reg() bsearch()es this array */ + if (sort_defaults) { + dev_warn(map->dev, + "Driver needs fixing: Unsorted reg_defaults, sorting the copy\n"); + regcache_sort_defaults(tmp_buf, map->num_reg_defaults); + } map->reg_defaults = tmp_buf; } else if (map->num_reg_defaults_raw) { count = regcache_count_cacheable_registers(map); -- 2.55.0