From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) (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 9CED92D7DF1; Thu, 2 Jul 2026 15:08:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.171.202.116 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783004890; cv=none; b=o97KQaflpnvJuUlo9IKZ6VPzREePAzz4WTk+qVdW6jG5oyAZfNkVKDJlfMQLT7Y7yOQkRs4jxMpn4b1sW2eSpAZwtjUJ0GW0y5foN5zRUXmq3yHzferhlEQhOU3COuYEWxvFTfdGgnwazea7djvGcvEyQAZ/ZJ6dveU1I03TLdo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783004890; c=relaxed/simple; bh=uRXk7IpS0wFu3ywjC32sSrvBhgbyOYWYQsk3/STViQQ=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=ZKbcXWVM1xtkLojFCfhgV04iJfG9V4Zkyc53iE3lgaAkG7f07C9bTSqaUSZZTN3vB0o9dVYmIusFOhqcPwDUeFTS6BxkmI8oOXMdbD880w9kmYF8JzKPnvN18NABRMdqUOQeY4IG9U5XjU1Hg4ZsgyPIeeKOsqPiljKlCVS1xEc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Cgb+nrv/; arc=none smtp.client-ip=185.171.202.116 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Cgb+nrv/" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 1E3BAC4FEE3; Thu, 2 Jul 2026 15:08:17 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7C8B75FF03; Thu, 2 Jul 2026 15:08:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F2B6C104C9546; Thu, 2 Jul 2026 17:08:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1783004884; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=1F6WcObOnrqVzWCe6S/Ifbf3Oxz0U7OhbfWsObhKvwM=; b=Cgb+nrv/thIirZ882qafwmxhh7CtfuS++fJG7QYKjG4kOJhnLe7LtUlnUvr1Q5rNM8EpJP uvrcGu0WIkD7RMendKazlcQ3S67K+4x8cNTYNV64hrEajOnWVfQspJxjBjAkA4pAPS3wQB gIRoCHNaye50g22c0oJbFrobwtfhzojXLCLMZKjQIqsBSzk4yGOuEqyO/rgiBwZGRkgAS/ kc8zJac8o2iaYWSFXcsuc/lhHe8ZaAqo6MaQEaQ2BRF+FgxF00Rhf+HG9P1UveMa0NkqkM TXuSgXwyJSfOT/t8GmAjOQ59o2aHOtsQBpT3ZmC0meoRff8V7vsBCv8O2rULNQ== From: Miquel Raynal To: Santhosh Kumar K Cc: , , , , , , , , , , , , , , , Subject: Re: [PATCH v4 14/16] mtd: spinand: negotiate optimal PHY operating point before dirmap creation In-Reply-To: <20260618073725.84733-15-s-k6@ti.com> (Santhosh Kumar K.'s message of "Thu, 18 Jun 2026 13:07:23 +0530") References: <20260618073725.84733-1-s-k6@ti.com> <20260618073725.84733-15-s-k6@ti.com> User-Agent: mu4e 1.12.7; emacs 30.2 Date: Thu, 02 Jul 2026 17:08:00 +0200 Message-ID: <87pl15pgz3.fsf@bootlin.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 On 18/06/2026 at 13:07:23 +0530, Santhosh Kumar K wrote: > Dirmap descriptors encode the op template including the operating > frequency at creation time, so PHY tuning must complete before dirmaps > are created to ensure the validated frequency is embedded in the > descriptors from the start. Good idea. > Move dirmap creation from spinand_init() to spinand_probe(), after a > new spinand_configure_phy() Fine with the idea, but in the core I would like to avoid TI specific naming. We can call this helper spinand_optimize_controller(); for instance. Please, do not use "PHY" in the SPI NAND core, because I find it too TI specific and we need generic enough naming so that we can include other controller's optimizations in this logic, if ever needed. > call that negotiates the best available PHY > operating point. spinand_configure_phy() tries the pre-selected variant > first. If the controller signals that PHY tuning is not applicable for > that op, spinand_try_phy_ranked() iterates remaining variants in > performance order =E2=80=94 DTR variants first, then SDR variants after > switching the bus interface if needed. On full failure the device falls > back to the best available non-PHY mode. Makes sense. > Add spinand_reset_max_ops() to copy op templates with max_freq zeroed spinand_reset_max_freq_ops()? > before each execute_tuning call, enforcing the invariant that a non-zero > max_freq only results from a successful tuning. > > PHY failure is non-fatal; the device operates at the conservative base > rate. > > Signed-off-by: Santhosh Kumar K > --- > drivers/mtd/nand/spi/core.c | 214 ++++++++++++++++++++++++++++++++++-- > include/linux/mtd/spinand.h | 11 ++ > 2 files changed, 216 insertions(+), 9 deletions(-) > > diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c > index b678d0534297..5dcfaabaf2cc 100644 > --- a/drivers/mtd/nand/spi/core.c > +++ b/drivers/mtd/nand/spi/core.c > @@ -1280,10 +1280,16 @@ static int spinand_create_dirmap(struct spinand_d= evice *spinand, > /* The plane number is passed in MSB just above the column address */ > info.offset =3D plane << fls(nand->memorg.pagesize); >=20=20 > + /* > + * Propagate the validated PHY frequency into the dirmap op templates > + * at construction time. > + */ > + > /* Write descriptor */ > info.length =3D nanddev_page_size(nand) + nanddev_per_page_oobsize(nand= ); > info.primary_op_tmpl =3D *spinand->op_templates->update_cache; > info.primary_op_tmpl.data.ecc =3D enable_ecc; > + info.primary_op_tmpl.max_freq =3D spinand->max_write_op.max_freq; > desc =3D devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, > spinand->spimem, &info); > if (IS_ERR(desc)) > @@ -1294,9 +1300,11 @@ static int spinand_create_dirmap(struct spinand_de= vice *spinand, > /* Read descriptor */ > info.primary_op_tmpl =3D *spinand->op_templates->read_cache; > info.primary_op_tmpl.data.ecc =3D enable_ecc; > + info.primary_op_tmpl.max_freq =3D spinand->max_read_op.max_freq; > if (secondary_op) { > info.secondary_op_tmpl =3D *spinand->op_templates->cont_read_cache; > info.secondary_op_tmpl.data.ecc =3D enable_ecc; > + info.secondary_op_tmpl.max_freq =3D spinand->max_read_op.max_freq; > } > desc =3D spinand_create_rdesc(spinand, &info); > if (IS_ERR(desc)) > @@ -1744,6 +1752,17 @@ int spinand_match_and_init(struct spinand_device *= spinand, > spinand->cont_read_possible =3D false; > } >=20=20 > + /* > + * Save the full read variant list (ODTR and SSDR ops) for PHY > + * tuning iteration. Only saved when all ODTR templates are > + * valid so spinand_configure_phy() knows ranked fallback is > + * available. > + */ > + if (spinand->odtr_op_templates.read_cache && > + spinand->odtr_op_templates.write_cache && > + spinand->odtr_op_templates.update_cache) > + spinand->phy_read_variants =3D info->op_variants.read_cache; > + > return 0; > } >=20=20 > @@ -1922,7 +1941,6 @@ static int spinand_mtd_suspend(struct mtd_info *mtd) >=20=20 > static int spinand_init(struct spinand_device *spinand) > { > - struct device *dev =3D &spinand->spimem->spi->dev; > struct mtd_info *mtd =3D spinand_to_mtd(spinand); > struct nand_device *nand =3D mtd_to_nanddev(mtd); > int ret; > @@ -2014,14 +2032,6 @@ static int spinand_init(struct spinand_device *spi= nand) > mtd->ecc_step_size =3D nanddev_get_ecc_conf(nand)->step_size; > mtd->bitflip_threshold =3D DIV_ROUND_UP(mtd->ecc_strength * 3, 4); >=20=20 > - ret =3D spinand_create_dirmaps(spinand); > - if (ret) { > - dev_err(dev, > - "Failed to create direct mappings for read/write operations (err =3D = %d)\n", > - ret); > - goto err_cleanup_ecc_engine; > - } > - > return 0; >=20=20 > err_cleanup_ecc_engine: > @@ -2050,6 +2060,178 @@ static void spinand_cleanup(struct spinand_device= *spinand) > kfree(spinand->scratchbuf); > } >=20=20 > +/* > + * spinand_try_phy_ranked() - Try PHY tuning on variants in performance = order. > + * @spinand: SPI NAND device > + * @mem: SPI memory device > + * @odtr: true to iterate ODTR variants, false for SSDR variants > + * @tried_mask: bitmask of already-tried variant indices; updated on eac= h try > + * > + * Iterates the full read variant list in descending performance order, > + * skipping variants in @tried_mask, and calls execute_tuning on each un= til one > + * succeeds. The fastest PHY-tunable variant is chosen regardless of whi= ch was > + * pre-selected at init; ranked iteration finds the best available varia= nt > + * without re-trying already-attempted ones. > + * > + * On success, sets spinand->max_read_op and updates the matching > + * odtr_op_templates.read_cache or ssdr_op_templates.read_cache. > + */ > +static bool spinand_try_phy_ranked(struct spinand_device *spinand, > + struct spi_mem *mem, bool odtr, > + u32 *tried_mask) > +{ > + const struct spinand_op_variants *variants =3D spinand->phy_read_varian= ts; > + const struct spi_mem_op *best; > + int ret; > + > + if (!variants) > + return false; > + > + while ((best =3D spinand_op_find_best(spinand, variants, odtr, > + *tried_mask))) { Ok, now I get the mask. Why do you care about odtr flag at all? We should just take the fastest modes in descending order, I don't really understand why mentioning odtr is needed? Maybe your goal is to make a faster loop, taking the fastest mode in each case and compare? This should work in most cases, given the fact that we tend to order the variants by speed, but they are not always in perfect order. I already faced cases where faster modes appeared to be down the list because of the game of dummy cycles. But that is probably not impacting PHY mode since we are using the fastest speed (with only the mode with the maximum number of dummy cycles) usable. So in the end, if you sort ODTR vs. SSDR for optimization reasons, ok. > + *tried_mask |=3D BIT(best - variants->ops); > + spinand->max_read_op =3D *best; > + spinand->max_read_op.max_freq =3D 0; > + ret =3D spi_mem_execute_tuning(mem, &spinand->max_read_op, > + &spinand->max_write_op); > + if (ret && ret !=3D -EOPNOTSUPP) > + dev_warn(&mem->spi->dev, "%s PHY tuning failed: %d\n", > + odtr ? "ODTR" : "SSDR", ret); > + if (!ret && spinand->max_read_op.max_freq) { > + if (odtr) > + spinand->odtr_op_templates.read_cache =3D best; > + else > + spinand->ssdr_op_templates.read_cache =3D best; > + return true; > + } > + } > + return false; > +} > + > +/* > + * spinand_reset_max_ops() - Copy op templates and zero max_freq on both. > + * @spinand: SPI NAND device > + * @templates: op template set to copy from > + * > + * Called before execute_tuning so max_freq starts at zero; execute_tuni= ng sets > + * it to the validated clock rate only on success. A non-zero max_freq m= eans > + * PHY-validated; zero means the base rate applies. > + */ > +static void spinand_reset_max_ops(struct spinand_device *spinand, > + struct spinand_mem_ops *templates) > +{ > + spinand->max_read_op =3D *templates->read_cache; > + spinand->max_read_op.max_freq =3D 0; > + spinand->max_write_op =3D *templates->write_cache; > + spinand->max_write_op.max_freq =3D 0; > +} > + > +/* > + * spinand_configure_phy() - Negotiate the optimal PHY operating point. > + * @spinand: SPI NAND device > + * @mem: SPI memory device > + * > + * Tries the pre-selected variant first. If the controller signals that > + * PHY tuning is not applicable for that specific op, iterates all remai= ning > + * variants in performance order. For devices that support both DTR and= SDR > + * interfaces, DTR variants are tried first; if all fail the device is > + * switched to SDR mode and SDR variants are tried. On full failure the > + * device falls back to the best available non-PHY mode. Devices that > + * support only SDR skip the DTR ranked pass entirely. > + * > + * PHY failure is never fatal. > + * > + * Note: tried_mask is u32, supporting up to 32 variants total across bo= th > + * ODTR and SSDR. Flash devices with more than 32 read variants are not > + * supported. > + */ > +static void spinand_configure_phy(struct spinand_device *spinand, > + struct spi_mem *mem) > +{ > + u32 tried_mask; > + int ret; > + > + spinand_reset_max_ops(spinand, spinand->op_templates); > + > + ret =3D spi_mem_execute_tuning(mem, &spinand->max_read_op, > + &spinand->max_write_op); > + if (ret && ret !=3D -EOPNOTSUPP) > + dev_warn(&mem->spi->dev, "Failed to execute PHY tuning: %d\n", > + ret); I guess we don't want to warn in this case. You can keep it as a dbg log if you want. > + /* > + * Any non-zero return or a set max_freq means we are done (error, > + * unsupported, or success). Fallback only for the op-specific "skip" > + * signal: ret =3D=3D 0 with max_freq still 0. > + */ > + if (ret || spinand->max_read_op.max_freq) > + return; > + > + if (!mem->spi->post_config_max_speed_hz || spinand->bus_iface =3D=3D SS= DR || > + !spinand->phy_read_variants) > + return; Why not moving this earlier? (except the SSDR check) this way we return even earlier if the tuning cannot happen. I am not sure I understand your use of phy_read_variants here. Can it really be NULL? > + if (WARN_ON(spinand->phy_read_variants->nops > 32)) > + return; > + > + /* Mark the pre-selected ODTR variant as already tried */ > + tried_mask =3D BIT(spinand->odtr_op_templates.read_cache - > + spinand->phy_read_variants->ops); > + > + dev_dbg(&mem->spi->dev, > + "PHY tuning skipped for current op; searching for best PHY variant\n"); > + > + /* Pass 1: try all remaining ODTR variants in performance order */ > + if (spinand_try_phy_ranked(spinand, mem, true, &tried_mask)) > + return; > + > + /* > + * Pass 2: switch to SSDR and try all SSDR variants in performance > + * order. > + * > + * Only enter if we actually have SSDR support and a reconfigure > + * callback. It is not possible to enable ODTR without the configure callback. > The hardware is still in ODTR mode here so no > + * configure_chip call is needed to undo; just set up the ODTR non-PHY > + * fallback and return. > + */ > + if (!spinand->ssdr_op_templates.read_cache || > + !spinand->ssdr_op_templates.write_cache || I don't think this is ever possible, is it? > + !spinand->configure_chip) > + goto use_odtr_non_phy; I don't think we will ever use this path. > + > + if (spinand->configure_chip(spinand, SSDR)) > + goto use_odtr_non_phy; We should handle chips with no ODTR support. I'm not sure the logic is robust enough for them. Have you tried by commenting out the ODTR variants of your chip? > + > + spinand->op_templates =3D &spinand->ssdr_op_templates; > + spinand->bus_iface =3D SSDR; > + spinand->max_write_op =3D *spinand->ssdr_op_templates.write_cache; > + spinand->max_write_op.max_freq =3D 0; > + > + /* > + * Only ODTR variants were candidates in Pass 1; SSDR bit positions > + * are clear > + */ > + if (spinand_try_phy_ranked(spinand, mem, false, &tried_mask)) > + return; > + > + /* > + * All PHY attempts exhausted. Revert to ODTR for non-PHY DTR > + * operation. If revert fails, stay in SSDR =E2=80=94 a mode mismatch > + * (ODTR op templates on SSDR-mode device) would corrupt data. > + */ > + if (spinand->configure_chip(spinand, ODTR)) { > + dev_warn(&mem->spi->dev, > + "Failed to revert to ODTR, staying in SSDR non-PHY\n"); > + spinand_reset_max_ops(spinand, &spinand->ssdr_op_templates); > + return; > + } > + > +use_odtr_non_phy: > + spinand->op_templates =3D &spinand->odtr_op_templates; > + spinand->bus_iface =3D ODTR; > + spinand_reset_max_ops(spinand, &spinand->odtr_op_templates); > +} > static int spinand_probe(struct spi_mem *mem) > { > struct spinand_device *spinand; > @@ -2072,6 +2254,20 @@ static int spinand_probe(struct spi_mem *mem) > if (ret) > return ret; >=20=20 > + /* > + * Negotiate the best PHY operating point before creating dirmaps so > + * the validated frequency is available at dirmap construction time. > + */ > + spinand_configure_phy(spinand, mem); > + > + ret =3D spinand_create_dirmaps(spinand); > + if (ret) { > + dev_err(&mem->spi->dev, > + "Failed to create direct mappings for read/write operations (err =3D = %d)\n", > + ret); > + goto err_spinand_cleanup; > + } > + > ret =3D mtd_device_register(mtd, NULL, 0); > if (ret) > goto err_spinand_cleanup; > diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h > index ec6efcfeef83..50a8319cf11e 100644 > --- a/include/linux/mtd/spinand.h > +++ b/include/linux/mtd/spinand.h > @@ -791,8 +791,19 @@ struct spinand_device { > struct spinand_mem_ops *op_templates; > enum spinand_bus_interface bus_iface; >=20=20 > + /* > + * Full read variant list (ODTR and SSDR ops together), saved when ODTR > + * templates are valid. Used by spinand_configure_phy() to iterate all > + * candidates when the pre-selected variant cannot be PHY-tuned. > + */ > + const struct spinand_op_variants *phy_read_variants; Why do you prefix this pointer name with "phy"? The variants pointed are basically all read variants, no more no less. Even though you want to use them for PHY tuning purposes, I don't think it is wise to name the member here. > + > struct spinand_dirmap *dirmaps; >=20=20 > + /* Persistent op templates updated by execute_tuning with validated spe= ed. */ > + struct spi_mem_op max_read_op; > + struct spi_mem_op max_write_op; > + > int (*select_target)(struct spinand_device *spinand, > unsigned int target); > unsigned int cur_target; Thanks, Miqu=C3=A8l From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 814A1C43458 for ; Thu, 2 Jul 2026 15:08:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:References :In-Reply-To:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=0jMtTURtHETLccRuXy+++9s7WIYF+4VzEX+aY0ypeV8=; b=Jfl4R9PRiyn2af XIisUEnNTSC2c5/o1kpAoLxCZc28NF3OjnnzqoCdUl97Nk2OelUGAICGb4/P2z71PHzJpt/RDvVEa hAxmFjqIURHmUNG0ieGplA8K3sZwefqqMCugcemnsxxEN4x+qMxqqxQv5ds4Mx3N0DQjs1Ugp2ENk PytToT2FcUrRV6EHO0LrCeJOb/mooxMVde9HWbMX+GFnWFoPl4WVHd6fqBMahRIUg7ffw7o9Q1EPE dNSMIh1kfEi/9dJK6ifH4VheyHGgcQFmYT6X0z83Zb2M5vaMi/1BAmh/+POOaSlJGF8YFo3bkHO0X XCObZGs6rcBjhUkpVzqw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wfJ1Q-00000004lJz-3UK3; Thu, 02 Jul 2026 15:08:12 +0000 Received: from smtpout-03.galae.net ([185.246.85.4]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wfJ1N-00000004lJ9-0hBT for linux-mtd@lists.infradead.org; Thu, 02 Jul 2026 15:08:11 +0000 Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id BC5CE4E40C32; Thu, 2 Jul 2026 15:08:05 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7C8B75FF03; Thu, 2 Jul 2026 15:08:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F2B6C104C9546; Thu, 2 Jul 2026 17:08:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1783004884; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=1F6WcObOnrqVzWCe6S/Ifbf3Oxz0U7OhbfWsObhKvwM=; b=Cgb+nrv/thIirZ882qafwmxhh7CtfuS++fJG7QYKjG4kOJhnLe7LtUlnUvr1Q5rNM8EpJP uvrcGu0WIkD7RMendKazlcQ3S67K+4x8cNTYNV64hrEajOnWVfQspJxjBjAkA4pAPS3wQB gIRoCHNaye50g22c0oJbFrobwtfhzojXLCLMZKjQIqsBSzk4yGOuEqyO/rgiBwZGRkgAS/ kc8zJac8o2iaYWSFXcsuc/lhHe8ZaAqo6MaQEaQ2BRF+FgxF00Rhf+HG9P1UveMa0NkqkM TXuSgXwyJSfOT/t8GmAjOQ59o2aHOtsQBpT3ZmC0meoRff8V7vsBCv8O2rULNQ== From: Miquel Raynal To: Santhosh Kumar K Cc: , , , , , , , , , , , , , , , Subject: Re: [PATCH v4 14/16] mtd: spinand: negotiate optimal PHY operating point before dirmap creation In-Reply-To: <20260618073725.84733-15-s-k6@ti.com> (Santhosh Kumar K.'s message of "Thu, 18 Jun 2026 13:07:23 +0530") References: <20260618073725.84733-1-s-k6@ti.com> <20260618073725.84733-15-s-k6@ti.com> User-Agent: mu4e 1.12.7; emacs 30.2 Date: Thu, 02 Jul 2026 17:08:00 +0200 Message-ID: <87pl15pgz3.fsf@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260702_080809_532639_64013AE8 X-CRM114-Status: GOOD ( 44.77 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org T24gMTgvMDYvMjAyNiBhdCAxMzowNzoyMyArMDUzMCwgU2FudGhvc2ggS3VtYXIgSyA8cy1rNkB0 aS5jb20+IHdyb3RlOgoKPiBEaXJtYXAgZGVzY3JpcHRvcnMgZW5jb2RlIHRoZSBvcCB0ZW1wbGF0 ZSBpbmNsdWRpbmcgdGhlIG9wZXJhdGluZwo+IGZyZXF1ZW5jeSBhdCBjcmVhdGlvbiB0aW1lLCBz byBQSFkgdHVuaW5nIG11c3QgY29tcGxldGUgYmVmb3JlIGRpcm1hcHMKPiBhcmUgY3JlYXRlZCB0 byBlbnN1cmUgdGhlIHZhbGlkYXRlZCBmcmVxdWVuY3kgaXMgZW1iZWRkZWQgaW4gdGhlCj4gZGVz Y3JpcHRvcnMgZnJvbSB0aGUgc3RhcnQuCgpHb29kIGlkZWEuCgo+IE1vdmUgZGlybWFwIGNyZWF0 aW9uIGZyb20gc3BpbmFuZF9pbml0KCkgdG8gc3BpbmFuZF9wcm9iZSgpLCBhZnRlciBhCj4gbmV3 IHNwaW5hbmRfY29uZmlndXJlX3BoeSgpCgpGaW5lIHdpdGggdGhlIGlkZWEsIGJ1dCBpbiB0aGUg Y29yZSBJIHdvdWxkIGxpa2UgdG8gYXZvaWQgVEkgc3BlY2lmaWMKbmFtaW5nLiBXZSBjYW4gY2Fs bCB0aGlzIGhlbHBlciBzcGluYW5kX29wdGltaXplX2NvbnRyb2xsZXIoKTsgZm9yCmluc3RhbmNl LgoKUGxlYXNlLCBkbyBub3QgdXNlICJQSFkiIGluIHRoZSBTUEkgTkFORCBjb3JlLCBiZWNhdXNl IEkgZmluZCBpdCB0b28gVEkKc3BlY2lmaWMgYW5kIHdlIG5lZWQgZ2VuZXJpYyBlbm91Z2ggbmFt aW5nIHNvIHRoYXQgd2UgY2FuIGluY2x1ZGUgb3RoZXIKY29udHJvbGxlcidzIG9wdGltaXphdGlv bnMgaW4gdGhpcyBsb2dpYywgaWYgZXZlciBuZWVkZWQuCgo+IGNhbGwgdGhhdCBuZWdvdGlhdGVz IHRoZSBiZXN0IGF2YWlsYWJsZSBQSFkKPiBvcGVyYXRpbmcgcG9pbnQuIHNwaW5hbmRfY29uZmln dXJlX3BoeSgpIHRyaWVzIHRoZSBwcmUtc2VsZWN0ZWQgdmFyaWFudAo+IGZpcnN0LiBJZiB0aGUg Y29udHJvbGxlciBzaWduYWxzIHRoYXQgUEhZIHR1bmluZyBpcyBub3QgYXBwbGljYWJsZSBmb3IK PiB0aGF0IG9wLCBzcGluYW5kX3RyeV9waHlfcmFua2VkKCkgaXRlcmF0ZXMgcmVtYWluaW5nIHZh cmlhbnRzIGluCj4gcGVyZm9ybWFuY2Ugb3JkZXIg4oCUIERUUiB2YXJpYW50cyBmaXJzdCwgdGhl biBTRFIgdmFyaWFudHMgYWZ0ZXIKPiBzd2l0Y2hpbmcgdGhlIGJ1cyBpbnRlcmZhY2UgaWYgbmVl ZGVkLiBPbiBmdWxsIGZhaWx1cmUgdGhlIGRldmljZSBmYWxscwo+IGJhY2sgdG8gdGhlIGJlc3Qg YXZhaWxhYmxlIG5vbi1QSFkgbW9kZS4KCk1ha2VzIHNlbnNlLgoKPiBBZGQgc3BpbmFuZF9yZXNl dF9tYXhfb3BzKCkgdG8gY29weSBvcCB0ZW1wbGF0ZXMgd2l0aCBtYXhfZnJlcSB6ZXJvZWQKCnNw aW5hbmRfcmVzZXRfbWF4X2ZyZXFfb3BzKCk/Cgo+IGJlZm9yZSBlYWNoIGV4ZWN1dGVfdHVuaW5n IGNhbGwsIGVuZm9yY2luZyB0aGUgaW52YXJpYW50IHRoYXQgYSBub24temVybwo+IG1heF9mcmVx IG9ubHkgcmVzdWx0cyBmcm9tIGEgc3VjY2Vzc2Z1bCB0dW5pbmcuCj4KPiBQSFkgZmFpbHVyZSBp cyBub24tZmF0YWw7IHRoZSBkZXZpY2Ugb3BlcmF0ZXMgYXQgdGhlIGNvbnNlcnZhdGl2ZSBiYXNl Cj4gcmF0ZS4KPgo+IFNpZ25lZC1vZmYtYnk6IFNhbnRob3NoIEt1bWFyIEsgPHMtazZAdGkuY29t Pgo+IC0tLQo+ICBkcml2ZXJzL210ZC9uYW5kL3NwaS9jb3JlLmMgfCAyMTQgKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKy0tCj4gIGluY2x1ZGUvbGludXgvbXRkL3NwaW5hbmQuaCB8 ICAxMSArKwo+ICAyIGZpbGVzIGNoYW5nZWQsIDIxNiBpbnNlcnRpb25zKCspLCA5IGRlbGV0aW9u cygtKQo+Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbXRkL25hbmQvc3BpL2NvcmUuYyBiL2RyaXZl cnMvbXRkL25hbmQvc3BpL2NvcmUuYwo+IGluZGV4IGI2NzhkMDUzNDI5Ny4uNWRjZmFhYmFmMmNj IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbXRkL25hbmQvc3BpL2NvcmUuYwo+ICsrKyBiL2RyaXZl cnMvbXRkL25hbmQvc3BpL2NvcmUuYwo+IEBAIC0xMjgwLDEwICsxMjgwLDE2IEBAIHN0YXRpYyBp bnQgc3BpbmFuZF9jcmVhdGVfZGlybWFwKHN0cnVjdCBzcGluYW5kX2RldmljZSAqc3BpbmFuZCwK PiAgCS8qIFRoZSBwbGFuZSBudW1iZXIgaXMgcGFzc2VkIGluIE1TQiBqdXN0IGFib3ZlIHRoZSBj b2x1bW4gYWRkcmVzcyAqLwo+ICAJaW5mby5vZmZzZXQgPSBwbGFuZSA8PCBmbHMobmFuZC0+bWVt b3JnLnBhZ2VzaXplKTsKPiAgCj4gKwkvKgo+ICsJICogUHJvcGFnYXRlIHRoZSB2YWxpZGF0ZWQg UEhZIGZyZXF1ZW5jeSBpbnRvIHRoZSBkaXJtYXAgb3AgdGVtcGxhdGVzCj4gKwkgKiBhdCBjb25z dHJ1Y3Rpb24gdGltZS4KPiArCSAqLwo+ICsKPiAgCS8qIFdyaXRlIGRlc2NyaXB0b3IgKi8KPiAg CWluZm8ubGVuZ3RoID0gbmFuZGRldl9wYWdlX3NpemUobmFuZCkgKyBuYW5kZGV2X3Blcl9wYWdl X29vYnNpemUobmFuZCk7Cj4gIAlpbmZvLnByaW1hcnlfb3BfdG1wbCA9ICpzcGluYW5kLT5vcF90 ZW1wbGF0ZXMtPnVwZGF0ZV9jYWNoZTsKPiAgCWluZm8ucHJpbWFyeV9vcF90bXBsLmRhdGEuZWNj ID0gZW5hYmxlX2VjYzsKPiArCWluZm8ucHJpbWFyeV9vcF90bXBsLm1heF9mcmVxID0gc3BpbmFu ZC0+bWF4X3dyaXRlX29wLm1heF9mcmVxOwo+ICAJZGVzYyA9IGRldm1fc3BpX21lbV9kaXJtYXBf Y3JlYXRlKCZzcGluYW5kLT5zcGltZW0tPnNwaS0+ZGV2LAo+ICAJCQkJCSAgc3BpbmFuZC0+c3Bp bWVtLCAmaW5mbyk7Cj4gIAlpZiAoSVNfRVJSKGRlc2MpKQo+IEBAIC0xMjk0LDkgKzEzMDAsMTEg QEAgc3RhdGljIGludCBzcGluYW5kX2NyZWF0ZV9kaXJtYXAoc3RydWN0IHNwaW5hbmRfZGV2aWNl ICpzcGluYW5kLAo+ICAJLyogUmVhZCBkZXNjcmlwdG9yICovCj4gIAlpbmZvLnByaW1hcnlfb3Bf dG1wbCA9ICpzcGluYW5kLT5vcF90ZW1wbGF0ZXMtPnJlYWRfY2FjaGU7Cj4gIAlpbmZvLnByaW1h cnlfb3BfdG1wbC5kYXRhLmVjYyA9IGVuYWJsZV9lY2M7Cj4gKwlpbmZvLnByaW1hcnlfb3BfdG1w bC5tYXhfZnJlcSA9IHNwaW5hbmQtPm1heF9yZWFkX29wLm1heF9mcmVxOwo+ICAJaWYgKHNlY29u ZGFyeV9vcCkgewo+ICAJCWluZm8uc2Vjb25kYXJ5X29wX3RtcGwgPSAqc3BpbmFuZC0+b3BfdGVt cGxhdGVzLT5jb250X3JlYWRfY2FjaGU7Cj4gIAkJaW5mby5zZWNvbmRhcnlfb3BfdG1wbC5kYXRh LmVjYyA9IGVuYWJsZV9lY2M7Cj4gKwkJaW5mby5zZWNvbmRhcnlfb3BfdG1wbC5tYXhfZnJlcSA9 IHNwaW5hbmQtPm1heF9yZWFkX29wLm1heF9mcmVxOwo+ICAJfQo+ICAJZGVzYyA9IHNwaW5hbmRf Y3JlYXRlX3JkZXNjKHNwaW5hbmQsICZpbmZvKTsKPiAgCWlmIChJU19FUlIoZGVzYykpCj4gQEAg LTE3NDQsNiArMTc1MiwxNyBAQCBpbnQgc3BpbmFuZF9tYXRjaF9hbmRfaW5pdChzdHJ1Y3Qgc3Bp bmFuZF9kZXZpY2UgKnNwaW5hbmQsCj4gIAkJCQlzcGluYW5kLT5jb250X3JlYWRfcG9zc2libGUg PSBmYWxzZTsKPiAgCQl9Cj4gIAo+ICsJCS8qCj4gKwkJICogU2F2ZSB0aGUgZnVsbCByZWFkIHZh cmlhbnQgbGlzdCAoT0RUUiBhbmQgU1NEUiBvcHMpIGZvciBQSFkKPiArCQkgKiB0dW5pbmcgaXRl cmF0aW9uLiBPbmx5IHNhdmVkIHdoZW4gYWxsIE9EVFIgdGVtcGxhdGVzIGFyZQo+ICsJCSAqIHZh bGlkIHNvIHNwaW5hbmRfY29uZmlndXJlX3BoeSgpIGtub3dzIHJhbmtlZCBmYWxsYmFjayBpcwo+ ICsJCSAqIGF2YWlsYWJsZS4KPiArCQkgKi8KPiArCQlpZiAoc3BpbmFuZC0+b2R0cl9vcF90ZW1w bGF0ZXMucmVhZF9jYWNoZSAmJgo+ICsJCSAgICBzcGluYW5kLT5vZHRyX29wX3RlbXBsYXRlcy53 cml0ZV9jYWNoZSAmJgo+ICsJCSAgICBzcGluYW5kLT5vZHRyX29wX3RlbXBsYXRlcy51cGRhdGVf Y2FjaGUpCj4gKwkJCXNwaW5hbmQtPnBoeV9yZWFkX3ZhcmlhbnRzID0gaW5mby0+b3BfdmFyaWFu dHMucmVhZF9jYWNoZTsKPiArCj4gIAkJcmV0dXJuIDA7Cj4gIAl9Cj4gIAo+IEBAIC0xOTIyLDcg KzE5NDEsNiBAQCBzdGF0aWMgaW50IHNwaW5hbmRfbXRkX3N1c3BlbmQoc3RydWN0IG10ZF9pbmZv ICptdGQpCj4gIAo+ICBzdGF0aWMgaW50IHNwaW5hbmRfaW5pdChzdHJ1Y3Qgc3BpbmFuZF9kZXZp Y2UgKnNwaW5hbmQpCj4gIHsKPiAtCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZzcGluYW5kLT5zcGlt ZW0tPnNwaS0+ZGV2Owo+ICAJc3RydWN0IG10ZF9pbmZvICptdGQgPSBzcGluYW5kX3RvX210ZChz cGluYW5kKTsKPiAgCXN0cnVjdCBuYW5kX2RldmljZSAqbmFuZCA9IG10ZF90b19uYW5kZGV2KG10 ZCk7Cj4gIAlpbnQgcmV0Owo+IEBAIC0yMDE0LDE0ICsyMDMyLDYgQEAgc3RhdGljIGludCBzcGlu YW5kX2luaXQoc3RydWN0IHNwaW5hbmRfZGV2aWNlICpzcGluYW5kKQo+ICAJbXRkLT5lY2Nfc3Rl cF9zaXplID0gbmFuZGRldl9nZXRfZWNjX2NvbmYobmFuZCktPnN0ZXBfc2l6ZTsKPiAgCW10ZC0+ Yml0ZmxpcF90aHJlc2hvbGQgPSBESVZfUk9VTkRfVVAobXRkLT5lY2Nfc3RyZW5ndGggKiAzLCA0 KTsKPiAgCj4gLQlyZXQgPSBzcGluYW5kX2NyZWF0ZV9kaXJtYXBzKHNwaW5hbmQpOwo+IC0JaWYg KHJldCkgewo+IC0JCWRldl9lcnIoZGV2LAo+IC0JCQkiRmFpbGVkIHRvIGNyZWF0ZSBkaXJlY3Qg bWFwcGluZ3MgZm9yIHJlYWQvd3JpdGUgb3BlcmF0aW9ucyAoZXJyID0gJWQpXG4iLAo+IC0JCQly ZXQpOwo+IC0JCWdvdG8gZXJyX2NsZWFudXBfZWNjX2VuZ2luZTsKPiAtCX0KPiAtCj4gIAlyZXR1 cm4gMDsKPiAgCj4gIGVycl9jbGVhbnVwX2VjY19lbmdpbmU6Cj4gQEAgLTIwNTAsNiArMjA2MCwx NzggQEAgc3RhdGljIHZvaWQgc3BpbmFuZF9jbGVhbnVwKHN0cnVjdCBzcGluYW5kX2RldmljZSAq c3BpbmFuZCkKPiAgCWtmcmVlKHNwaW5hbmQtPnNjcmF0Y2hidWYpOwo+ICB9Cj4gIAo+ICsvKgo+ ICsgKiBzcGluYW5kX3RyeV9waHlfcmFua2VkKCkgLSBUcnkgUEhZIHR1bmluZyBvbiB2YXJpYW50 cyBpbiBwZXJmb3JtYW5jZSBvcmRlci4KPiArICogQHNwaW5hbmQ6ICAgIFNQSSBOQU5EIGRldmlj ZQo+ICsgKiBAbWVtOiAgICAgICAgU1BJIG1lbW9yeSBkZXZpY2UKPiArICogQG9kdHI6ICAgICAg IHRydWUgdG8gaXRlcmF0ZSBPRFRSIHZhcmlhbnRzLCBmYWxzZSBmb3IgU1NEUiB2YXJpYW50cwo+ ICsgKiBAdHJpZWRfbWFzazogYml0bWFzayBvZiBhbHJlYWR5LXRyaWVkIHZhcmlhbnQgaW5kaWNl czsgdXBkYXRlZCBvbiBlYWNoIHRyeQo+ICsgKgo+ICsgKiBJdGVyYXRlcyB0aGUgZnVsbCByZWFk IHZhcmlhbnQgbGlzdCBpbiBkZXNjZW5kaW5nIHBlcmZvcm1hbmNlIG9yZGVyLAo+ICsgKiBza2lw cGluZyB2YXJpYW50cyBpbiBAdHJpZWRfbWFzaywgYW5kIGNhbGxzIGV4ZWN1dGVfdHVuaW5nIG9u IGVhY2ggdW50aWwgb25lCj4gKyAqIHN1Y2NlZWRzLiBUaGUgZmFzdGVzdCBQSFktdHVuYWJsZSB2 YXJpYW50IGlzIGNob3NlbiByZWdhcmRsZXNzIG9mIHdoaWNoIHdhcwo+ICsgKiBwcmUtc2VsZWN0 ZWQgYXQgaW5pdDsgcmFua2VkIGl0ZXJhdGlvbiBmaW5kcyB0aGUgYmVzdCBhdmFpbGFibGUgdmFy aWFudAo+ICsgKiB3aXRob3V0IHJlLXRyeWluZyBhbHJlYWR5LWF0dGVtcHRlZCBvbmVzLgo+ICsg Kgo+ICsgKiBPbiBzdWNjZXNzLCBzZXRzIHNwaW5hbmQtPm1heF9yZWFkX29wIGFuZCB1cGRhdGVz IHRoZSBtYXRjaGluZwo+ICsgKiBvZHRyX29wX3RlbXBsYXRlcy5yZWFkX2NhY2hlIG9yIHNzZHJf b3BfdGVtcGxhdGVzLnJlYWRfY2FjaGUuCj4gKyAqLwo+ICtzdGF0aWMgYm9vbCBzcGluYW5kX3Ry eV9waHlfcmFua2VkKHN0cnVjdCBzcGluYW5kX2RldmljZSAqc3BpbmFuZCwKPiArCQkJCSAgIHN0 cnVjdCBzcGlfbWVtICptZW0sIGJvb2wgb2R0ciwKPiArCQkJCSAgIHUzMiAqdHJpZWRfbWFzaykK PiArewo+ICsJY29uc3Qgc3RydWN0IHNwaW5hbmRfb3BfdmFyaWFudHMgKnZhcmlhbnRzID0gc3Bp bmFuZC0+cGh5X3JlYWRfdmFyaWFudHM7Cj4gKwljb25zdCBzdHJ1Y3Qgc3BpX21lbV9vcCAqYmVz dDsKPiArCWludCByZXQ7Cj4gKwo+ICsJaWYgKCF2YXJpYW50cykKPiArCQlyZXR1cm4gZmFsc2U7 Cj4gKwo+ICsJd2hpbGUgKChiZXN0ID0gc3BpbmFuZF9vcF9maW5kX2Jlc3Qoc3BpbmFuZCwgdmFy aWFudHMsIG9kdHIsCj4gKwkJCQkJICAgICp0cmllZF9tYXNrKSkpIHsKCk9rLCBub3cgSSBnZXQg dGhlIG1hc2suCgpXaHkgZG8geW91IGNhcmUgYWJvdXQgb2R0ciBmbGFnIGF0IGFsbD8gV2Ugc2hv dWxkIGp1c3QgdGFrZSB0aGUgZmFzdGVzdAptb2RlcyBpbiBkZXNjZW5kaW5nIG9yZGVyLCBJIGRv bid0IHJlYWxseSB1bmRlcnN0YW5kIHdoeSBtZW50aW9uaW5nIG9kdHIKaXMgbmVlZGVkPyBNYXli ZSB5b3VyIGdvYWwgaXMgdG8gbWFrZSBhIGZhc3RlciBsb29wLCB0YWtpbmcgdGhlIGZhc3Rlc3QK bW9kZSBpbiBlYWNoIGNhc2UgYW5kIGNvbXBhcmU/IFRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBj YXNlcywgZ2l2ZW4gdGhlCmZhY3QgdGhhdCB3ZSB0ZW5kIHRvIG9yZGVyIHRoZSB2YXJpYW50cyBi eSBzcGVlZCwgYnV0IHRoZXkgYXJlIG5vdAphbHdheXMgaW4gcGVyZmVjdCBvcmRlci4gSSBhbHJl YWR5IGZhY2VkIGNhc2VzIHdoZXJlIGZhc3RlciBtb2RlcwphcHBlYXJlZCB0byBiZSBkb3duIHRo ZSBsaXN0IGJlY2F1c2Ugb2YgdGhlIGdhbWUgb2YgZHVtbXkgY3ljbGVzLiBCdXQKdGhhdCBpcyBw cm9iYWJseSBub3QgaW1wYWN0aW5nIFBIWSBtb2RlIHNpbmNlIHdlIGFyZSB1c2luZyB0aGUgZmFz dGVzdApzcGVlZCAod2l0aCBvbmx5IHRoZSBtb2RlIHdpdGggdGhlIG1heGltdW0gbnVtYmVyIG9m IGR1bW15IGN5Y2xlcykKdXNhYmxlLgoKU28gaW4gdGhlIGVuZCwgaWYgeW91IHNvcnQgT0RUUiB2 cy4gU1NEUiBmb3Igb3B0aW1pemF0aW9uIHJlYXNvbnMsIG9rLgoKPiArCQkqdHJpZWRfbWFzayB8 PSBCSVQoYmVzdCAtIHZhcmlhbnRzLT5vcHMpOwo+ICsJCXNwaW5hbmQtPm1heF9yZWFkX29wID0g KmJlc3Q7Cj4gKwkJc3BpbmFuZC0+bWF4X3JlYWRfb3AubWF4X2ZyZXEgPSAwOwo+ICsJCXJldCA9 IHNwaV9tZW1fZXhlY3V0ZV90dW5pbmcobWVtLCAmc3BpbmFuZC0+bWF4X3JlYWRfb3AsCj4gKwkJ CQkJICAgICAmc3BpbmFuZC0+bWF4X3dyaXRlX29wKTsKPiArCQlpZiAocmV0ICYmIHJldCAhPSAt RU9QTk9UU1VQUCkKPiArCQkJZGV2X3dhcm4oJm1lbS0+c3BpLT5kZXYsICIlcyBQSFkgdHVuaW5n IGZhaWxlZDogJWRcbiIsCj4gKwkJCQkgb2R0ciA/ICJPRFRSIiA6ICJTU0RSIiwgcmV0KTsKPiAr CQlpZiAoIXJldCAmJiBzcGluYW5kLT5tYXhfcmVhZF9vcC5tYXhfZnJlcSkgewo+ICsJCQlpZiAo b2R0cikKPiArCQkJCXNwaW5hbmQtPm9kdHJfb3BfdGVtcGxhdGVzLnJlYWRfY2FjaGUgPSBiZXN0 Owo+ICsJCQllbHNlCj4gKwkJCQlzcGluYW5kLT5zc2RyX29wX3RlbXBsYXRlcy5yZWFkX2NhY2hl ID0gYmVzdDsKPiArCQkJcmV0dXJuIHRydWU7Cj4gKwkJfQo+ICsJfQo+ICsJcmV0dXJuIGZhbHNl Owo+ICt9Cj4gKwo+ICsvKgo+ICsgKiBzcGluYW5kX3Jlc2V0X21heF9vcHMoKSAtIENvcHkgb3Ag dGVtcGxhdGVzIGFuZCB6ZXJvIG1heF9mcmVxIG9uIGJvdGguCj4gKyAqIEBzcGluYW5kOiAgICBT UEkgTkFORCBkZXZpY2UKPiArICogQHRlbXBsYXRlczogIG9wIHRlbXBsYXRlIHNldCB0byBjb3B5 IGZyb20KPiArICoKPiArICogQ2FsbGVkIGJlZm9yZSBleGVjdXRlX3R1bmluZyBzbyBtYXhfZnJl cSBzdGFydHMgYXQgemVybzsgZXhlY3V0ZV90dW5pbmcgc2V0cwo+ICsgKiBpdCB0byB0aGUgdmFs aWRhdGVkIGNsb2NrIHJhdGUgb25seSBvbiBzdWNjZXNzLiBBIG5vbi16ZXJvIG1heF9mcmVxIG1l YW5zCj4gKyAqIFBIWS12YWxpZGF0ZWQ7IHplcm8gbWVhbnMgdGhlIGJhc2UgcmF0ZSBhcHBsaWVz Lgo+ICsgKi8KPiArc3RhdGljIHZvaWQgc3BpbmFuZF9yZXNldF9tYXhfb3BzKHN0cnVjdCBzcGlu YW5kX2RldmljZSAqc3BpbmFuZCwKPiArCQkJCSAgc3RydWN0IHNwaW5hbmRfbWVtX29wcyAqdGVt cGxhdGVzKQo+ICt7Cj4gKwlzcGluYW5kLT5tYXhfcmVhZF9vcCA9ICp0ZW1wbGF0ZXMtPnJlYWRf Y2FjaGU7Cj4gKwlzcGluYW5kLT5tYXhfcmVhZF9vcC5tYXhfZnJlcSA9IDA7Cj4gKwlzcGluYW5k LT5tYXhfd3JpdGVfb3AgPSAqdGVtcGxhdGVzLT53cml0ZV9jYWNoZTsKPiArCXNwaW5hbmQtPm1h eF93cml0ZV9vcC5tYXhfZnJlcSA9IDA7Cj4gK30KPiArCj4gKy8qCj4gKyAqIHNwaW5hbmRfY29u ZmlndXJlX3BoeSgpIC0gTmVnb3RpYXRlIHRoZSBvcHRpbWFsIFBIWSBvcGVyYXRpbmcgcG9pbnQu Cj4gKyAqIEBzcGluYW5kOiAgICBTUEkgTkFORCBkZXZpY2UKPiArICogQG1lbTogICAgICAgIFNQ SSBtZW1vcnkgZGV2aWNlCj4gKyAqCj4gKyAqIFRyaWVzIHRoZSBwcmUtc2VsZWN0ZWQgdmFyaWFu dCBmaXJzdC4gIElmIHRoZSBjb250cm9sbGVyIHNpZ25hbHMgdGhhdAo+ICsgKiBQSFkgdHVuaW5n IGlzIG5vdCBhcHBsaWNhYmxlIGZvciB0aGF0IHNwZWNpZmljIG9wLCBpdGVyYXRlcyBhbGwgcmVt YWluaW5nCj4gKyAqIHZhcmlhbnRzIGluIHBlcmZvcm1hbmNlIG9yZGVyLiAgRm9yIGRldmljZXMg dGhhdCBzdXBwb3J0IGJvdGggRFRSIGFuZCBTRFIKPiArICogaW50ZXJmYWNlcywgRFRSIHZhcmlh bnRzIGFyZSB0cmllZCBmaXJzdDsgaWYgYWxsIGZhaWwgdGhlIGRldmljZSBpcwo+ICsgKiBzd2l0 Y2hlZCB0byBTRFIgbW9kZSBhbmQgU0RSIHZhcmlhbnRzIGFyZSB0cmllZC4gIE9uIGZ1bGwgZmFp bHVyZSB0aGUKPiArICogZGV2aWNlIGZhbGxzIGJhY2sgdG8gdGhlIGJlc3QgYXZhaWxhYmxlIG5v bi1QSFkgbW9kZS4gIERldmljZXMgdGhhdAo+ICsgKiBzdXBwb3J0IG9ubHkgU0RSIHNraXAgdGhl IERUUiByYW5rZWQgcGFzcyBlbnRpcmVseS4KPiArICoKPiArICogUEhZIGZhaWx1cmUgaXMgbmV2 ZXIgZmF0YWwuCj4gKyAqCj4gKyAqIE5vdGU6IHRyaWVkX21hc2sgaXMgdTMyLCBzdXBwb3J0aW5n IHVwIHRvIDMyIHZhcmlhbnRzIHRvdGFsIGFjcm9zcyBib3RoCj4gKyAqIE9EVFIgYW5kIFNTRFIu IEZsYXNoIGRldmljZXMgd2l0aCBtb3JlIHRoYW4gMzIgcmVhZCB2YXJpYW50cyBhcmUgbm90Cj4g KyAqIHN1cHBvcnRlZC4KPiArICovCj4gK3N0YXRpYyB2b2lkIHNwaW5hbmRfY29uZmlndXJlX3Bo eShzdHJ1Y3Qgc3BpbmFuZF9kZXZpY2UgKnNwaW5hbmQsCj4gKwkJCQkgIHN0cnVjdCBzcGlfbWVt ICptZW0pCj4gK3sKPiArCXUzMiB0cmllZF9tYXNrOwo+ICsJaW50IHJldDsKPiArCj4gKwlzcGlu YW5kX3Jlc2V0X21heF9vcHMoc3BpbmFuZCwgc3BpbmFuZC0+b3BfdGVtcGxhdGVzKTsKPiArCj4g KwlyZXQgPSBzcGlfbWVtX2V4ZWN1dGVfdHVuaW5nKG1lbSwgJnNwaW5hbmQtPm1heF9yZWFkX29w LAo+ICsJCQkJICAgICAmc3BpbmFuZC0+bWF4X3dyaXRlX29wKTsKPiArCWlmIChyZXQgJiYgcmV0 ICE9IC1FT1BOT1RTVVBQKQo+ICsJCWRldl93YXJuKCZtZW0tPnNwaS0+ZGV2LCAiRmFpbGVkIHRv IGV4ZWN1dGUgUEhZIHR1bmluZzogJWRcbiIsCj4gKwkJCSByZXQpOwoKSSBndWVzcyB3ZSBkb24n dCB3YW50IHRvIHdhcm4gaW4gdGhpcyBjYXNlLiBZb3UgY2FuIGtlZXAgaXQgYXMgYSBkYmcgbG9n CmlmIHlvdSB3YW50LgoKPiArCS8qCj4gKwkgKiBBbnkgbm9uLXplcm8gcmV0dXJuIG9yIGEgc2V0 IG1heF9mcmVxIG1lYW5zIHdlIGFyZSBkb25lIChlcnJvciwKPiArCSAqIHVuc3VwcG9ydGVkLCBv ciBzdWNjZXNzKS4gRmFsbGJhY2sgb25seSBmb3IgdGhlIG9wLXNwZWNpZmljICJza2lwIgo+ICsJ ICogc2lnbmFsOiByZXQgPT0gMCB3aXRoIG1heF9mcmVxIHN0aWxsIDAuCj4gKwkgKi8KPiArCWlm IChyZXQgfHwgc3BpbmFuZC0+bWF4X3JlYWRfb3AubWF4X2ZyZXEpCj4gKwkJcmV0dXJuOwo+ICsK PiArCWlmICghbWVtLT5zcGktPnBvc3RfY29uZmlnX21heF9zcGVlZF9oeiB8fCBzcGluYW5kLT5i dXNfaWZhY2UgPT0gU1NEUiB8fAo+ICsJICAgICFzcGluYW5kLT5waHlfcmVhZF92YXJpYW50cykK PiArCQlyZXR1cm47CgpXaHkgbm90IG1vdmluZyB0aGlzIGVhcmxpZXI/IChleGNlcHQgdGhlIFNT RFIgY2hlY2spIHRoaXMgd2F5IHdlIHJldHVybgpldmVuIGVhcmxpZXIgaWYgdGhlIHR1bmluZyBj YW5ub3QgaGFwcGVuLgoKSSBhbSBub3Qgc3VyZSBJIHVuZGVyc3RhbmQgeW91ciB1c2Ugb2YgcGh5 X3JlYWRfdmFyaWFudHMgaGVyZS4gQ2FuIGl0CnJlYWxseSBiZSBOVUxMPwoKPiArCWlmIChXQVJO X09OKHNwaW5hbmQtPnBoeV9yZWFkX3ZhcmlhbnRzLT5ub3BzID4gMzIpKQo+ICsJCXJldHVybjsK PiArCj4gKwkvKiBNYXJrIHRoZSBwcmUtc2VsZWN0ZWQgT0RUUiB2YXJpYW50IGFzIGFscmVhZHkg dHJpZWQgKi8KPiArCXRyaWVkX21hc2sgPSBCSVQoc3BpbmFuZC0+b2R0cl9vcF90ZW1wbGF0ZXMu cmVhZF9jYWNoZSAtCj4gKwkJCSBzcGluYW5kLT5waHlfcmVhZF92YXJpYW50cy0+b3BzKTsKPiAr Cj4gKwlkZXZfZGJnKCZtZW0tPnNwaS0+ZGV2LAo+ICsJCSJQSFkgdHVuaW5nIHNraXBwZWQgZm9y IGN1cnJlbnQgb3A7IHNlYXJjaGluZyBmb3IgYmVzdCBQSFkgdmFyaWFudFxuIik7Cj4gKwo+ICsJ LyogUGFzcyAxOiB0cnkgYWxsIHJlbWFpbmluZyBPRFRSIHZhcmlhbnRzIGluIHBlcmZvcm1hbmNl IG9yZGVyICovCj4gKwlpZiAoc3BpbmFuZF90cnlfcGh5X3JhbmtlZChzcGluYW5kLCBtZW0sIHRy dWUsICZ0cmllZF9tYXNrKSkKPiArCQlyZXR1cm47Cj4gKwo+ICsJLyoKPiArCSAqIFBhc3MgMjog c3dpdGNoIHRvIFNTRFIgYW5kIHRyeSBhbGwgU1NEUiB2YXJpYW50cyBpbiBwZXJmb3JtYW5jZQo+ ICsJICogb3JkZXIuCj4gKwkgKgo+ICsJICogT25seSBlbnRlciBpZiB3ZSBhY3R1YWxseSBoYXZl IFNTRFIgc3VwcG9ydCBhbmQgYSByZWNvbmZpZ3VyZQo+ICsJICogY2FsbGJhY2suCgpJdCBpcyBu b3QgcG9zc2libGUgdG8gZW5hYmxlIE9EVFIgd2l0aG91dCB0aGUgY29uZmlndXJlIGNhbGxiYWNr LgoKPiBUaGUgaGFyZHdhcmUgaXMgc3RpbGwgaW4gT0RUUiBtb2RlIGhlcmUgc28gbm8KPiArCSAq IGNvbmZpZ3VyZV9jaGlwIGNhbGwgaXMgbmVlZGVkIHRvIHVuZG87IGp1c3Qgc2V0IHVwIHRoZSBP RFRSIG5vbi1QSFkKPiArCSAqIGZhbGxiYWNrIGFuZCByZXR1cm4uCj4gKwkgKi8KPiArCWlmICgh c3BpbmFuZC0+c3Nkcl9vcF90ZW1wbGF0ZXMucmVhZF9jYWNoZSB8fAo+ICsJICAgICFzcGluYW5k LT5zc2RyX29wX3RlbXBsYXRlcy53cml0ZV9jYWNoZSB8fAoKSSBkb24ndCB0aGluayB0aGlzIGlz IGV2ZXIgcG9zc2libGUsIGlzIGl0PwoKPiArCSAgICAhc3BpbmFuZC0+Y29uZmlndXJlX2NoaXAp Cj4gKwkJZ290byB1c2Vfb2R0cl9ub25fcGh5OwoKSSBkb24ndCB0aGluayB3ZSB3aWxsIGV2ZXIg dXNlIHRoaXMgcGF0aC4KCj4gKwo+ICsJaWYgKHNwaW5hbmQtPmNvbmZpZ3VyZV9jaGlwKHNwaW5h bmQsIFNTRFIpKQo+ICsJCWdvdG8gdXNlX29kdHJfbm9uX3BoeTsKCldlIHNob3VsZCBoYW5kbGUg Y2hpcHMgd2l0aCBubyBPRFRSIHN1cHBvcnQuIEknbSBub3Qgc3VyZSB0aGUgbG9naWMgaXMKcm9i dXN0IGVub3VnaCBmb3IgdGhlbS4gSGF2ZSB5b3UgdHJpZWQgYnkgY29tbWVudGluZyBvdXQgdGhl IE9EVFIKdmFyaWFudHMgb2YgeW91ciBjaGlwPwoKPiArCj4gKwlzcGluYW5kLT5vcF90ZW1wbGF0 ZXMgPSAmc3BpbmFuZC0+c3Nkcl9vcF90ZW1wbGF0ZXM7Cj4gKwlzcGluYW5kLT5idXNfaWZhY2Ug PSBTU0RSOwo+ICsJc3BpbmFuZC0+bWF4X3dyaXRlX29wID0gKnNwaW5hbmQtPnNzZHJfb3BfdGVt cGxhdGVzLndyaXRlX2NhY2hlOwo+ICsJc3BpbmFuZC0+bWF4X3dyaXRlX29wLm1heF9mcmVxID0g MDsKPiArCj4gKwkvKgo+ICsJICogT25seSBPRFRSIHZhcmlhbnRzIHdlcmUgY2FuZGlkYXRlcyBp biBQYXNzIDE7IFNTRFIgYml0IHBvc2l0aW9ucwo+ICsJICogYXJlIGNsZWFyCj4gKwkgKi8KPiAr CWlmIChzcGluYW5kX3RyeV9waHlfcmFua2VkKHNwaW5hbmQsIG1lbSwgZmFsc2UsICZ0cmllZF9t YXNrKSkKPiArCQlyZXR1cm47Cj4gKwo+ICsJLyoKPiArCSAqIEFsbCBQSFkgYXR0ZW1wdHMgZXho YXVzdGVkLiAgUmV2ZXJ0IHRvIE9EVFIgZm9yIG5vbi1QSFkgRFRSCj4gKwkgKiBvcGVyYXRpb24u ICBJZiByZXZlcnQgZmFpbHMsIHN0YXkgaW4gU1NEUiDigJQgYSBtb2RlIG1pc21hdGNoCj4gKwkg KiAoT0RUUiBvcCB0ZW1wbGF0ZXMgb24gU1NEUi1tb2RlIGRldmljZSkgd291bGQgY29ycnVwdCBk YXRhLgo+ICsJICovCj4gKwlpZiAoc3BpbmFuZC0+Y29uZmlndXJlX2NoaXAoc3BpbmFuZCwgT0RU UikpIHsKPiArCQlkZXZfd2FybigmbWVtLT5zcGktPmRldiwKPiArCQkJICJGYWlsZWQgdG8gcmV2 ZXJ0IHRvIE9EVFIsIHN0YXlpbmcgaW4gU1NEUiBub24tUEhZXG4iKTsKPiArCQlzcGluYW5kX3Jl c2V0X21heF9vcHMoc3BpbmFuZCwgJnNwaW5hbmQtPnNzZHJfb3BfdGVtcGxhdGVzKTsKPiArCQly ZXR1cm47Cj4gKwl9Cj4gKwo+ICt1c2Vfb2R0cl9ub25fcGh5Ogo+ICsJc3BpbmFuZC0+b3BfdGVt cGxhdGVzID0gJnNwaW5hbmQtPm9kdHJfb3BfdGVtcGxhdGVzOwo+ICsJc3BpbmFuZC0+YnVzX2lm YWNlID0gT0RUUjsKPiArCXNwaW5hbmRfcmVzZXRfbWF4X29wcyhzcGluYW5kLCAmc3BpbmFuZC0+ b2R0cl9vcF90ZW1wbGF0ZXMpOwo+ICt9Cgo+ICBzdGF0aWMgaW50IHNwaW5hbmRfcHJvYmUoc3Ry dWN0IHNwaV9tZW0gKm1lbSkKPiAgewo+ICAJc3RydWN0IHNwaW5hbmRfZGV2aWNlICpzcGluYW5k Owo+IEBAIC0yMDcyLDYgKzIyNTQsMjAgQEAgc3RhdGljIGludCBzcGluYW5kX3Byb2JlKHN0cnVj dCBzcGlfbWVtICptZW0pCj4gIAlpZiAocmV0KQo+ICAJCXJldHVybiByZXQ7Cj4gIAo+ICsJLyoK PiArCSAqIE5lZ290aWF0ZSB0aGUgYmVzdCBQSFkgb3BlcmF0aW5nIHBvaW50IGJlZm9yZSBjcmVh dGluZyBkaXJtYXBzIHNvCj4gKwkgKiB0aGUgdmFsaWRhdGVkIGZyZXF1ZW5jeSBpcyBhdmFpbGFi bGUgYXQgZGlybWFwIGNvbnN0cnVjdGlvbiB0aW1lLgo+ICsJICovCj4gKwlzcGluYW5kX2NvbmZp Z3VyZV9waHkoc3BpbmFuZCwgbWVtKTsKPiArCj4gKwlyZXQgPSBzcGluYW5kX2NyZWF0ZV9kaXJt YXBzKHNwaW5hbmQpOwo+ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoJm1lbS0+c3BpLT5kZXYs Cj4gKwkJCSJGYWlsZWQgdG8gY3JlYXRlIGRpcmVjdCBtYXBwaW5ncyBmb3IgcmVhZC93cml0ZSBv cGVyYXRpb25zIChlcnIgPSAlZClcbiIsCj4gKwkJCXJldCk7Cj4gKwkJZ290byBlcnJfc3BpbmFu ZF9jbGVhbnVwOwo+ICsJfQo+ICsKPiAgCXJldCA9IG10ZF9kZXZpY2VfcmVnaXN0ZXIobXRkLCBO VUxMLCAwKTsKPiAgCWlmIChyZXQpCj4gIAkJZ290byBlcnJfc3BpbmFuZF9jbGVhbnVwOwo+IGRp ZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L210ZC9zcGluYW5kLmggYi9pbmNsdWRlL2xpbnV4L210 ZC9zcGluYW5kLmgKPiBpbmRleCBlYzZlZmNmZWVmODMuLjUwYTgzMTljZjExZSAxMDA2NDQKPiAt LS0gYS9pbmNsdWRlL2xpbnV4L210ZC9zcGluYW5kLmgKPiArKysgYi9pbmNsdWRlL2xpbnV4L210 ZC9zcGluYW5kLmgKPiBAQCAtNzkxLDggKzc5MSwxOSBAQCBzdHJ1Y3Qgc3BpbmFuZF9kZXZpY2Ug ewo+ICAJc3RydWN0IHNwaW5hbmRfbWVtX29wcyAqb3BfdGVtcGxhdGVzOwo+ICAJZW51bSBzcGlu YW5kX2J1c19pbnRlcmZhY2UgYnVzX2lmYWNlOwo+ICAKPiArCS8qCj4gKwkgKiBGdWxsIHJlYWQg dmFyaWFudCBsaXN0IChPRFRSIGFuZCBTU0RSIG9wcyB0b2dldGhlciksIHNhdmVkIHdoZW4gT0RU Ugo+ICsJICogdGVtcGxhdGVzIGFyZSB2YWxpZC4gVXNlZCBieSBzcGluYW5kX2NvbmZpZ3VyZV9w aHkoKSB0byBpdGVyYXRlIGFsbAo+ICsJICogY2FuZGlkYXRlcyB3aGVuIHRoZSBwcmUtc2VsZWN0 ZWQgdmFyaWFudCBjYW5ub3QgYmUgUEhZLXR1bmVkLgo+ICsJICovCj4gKwljb25zdCBzdHJ1Y3Qg c3BpbmFuZF9vcF92YXJpYW50cyAqcGh5X3JlYWRfdmFyaWFudHM7CgpXaHkgZG8geW91IHByZWZp eCB0aGlzIHBvaW50ZXIgbmFtZSB3aXRoICJwaHkiPyBUaGUgdmFyaWFudHMgcG9pbnRlZCBhcmUK YmFzaWNhbGx5IGFsbCByZWFkIHZhcmlhbnRzLCBubyBtb3JlIG5vIGxlc3MuIEV2ZW4gdGhvdWdo IHlvdSB3YW50IHRvCnVzZSB0aGVtIGZvciBQSFkgdHVuaW5nIHB1cnBvc2VzLCBJIGRvbid0IHRo aW5rIGl0IGlzIHdpc2UgdG8gbmFtZSB0aGUKbWVtYmVyIGhlcmUuCgo+ICsKPiAgCXN0cnVjdCBz cGluYW5kX2Rpcm1hcCAqZGlybWFwczsKPiAgCj4gKwkvKiBQZXJzaXN0ZW50IG9wIHRlbXBsYXRl cyB1cGRhdGVkIGJ5IGV4ZWN1dGVfdHVuaW5nIHdpdGggdmFsaWRhdGVkIHNwZWVkLiAqLwo+ICsJ c3RydWN0IHNwaV9tZW1fb3AgbWF4X3JlYWRfb3A7Cj4gKwlzdHJ1Y3Qgc3BpX21lbV9vcCBtYXhf d3JpdGVfb3A7Cj4gKwo+ICAJaW50ICgqc2VsZWN0X3RhcmdldCkoc3RydWN0IHNwaW5hbmRfZGV2 aWNlICpzcGluYW5kLAo+ICAJCQkgICAgIHVuc2lnbmVkIGludCB0YXJnZXQpOwo+ICAJdW5zaWdu ZWQgaW50IGN1cl90YXJnZXQ7CgpUaGFua3MsCk1pcXXDqGwKCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpMaW51eCBNVEQgZGlzY3Vzc2lvbiBt YWlsaW5nIGxpc3QKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9s aW51eC1tdGQvCg==