2016-03-30 13:26:20

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH v6 1/2] dt: bindings: add MARVELL's sd8xxx wireless device

From: Xinming Hu <[email protected]>

Add device tree binding documentation for MARVELL's sd8xxx
(sd8897 and sd8997) wlan chip.

Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
Listing changelist for both 1/2 and 2/2 patches
v3: Don't update adapter->dt_node if mwifiex_plt_dev is NULL

v4: a)Corrected the 'name' and 'compatible' property names.(Arnd Bergmann and Rob
Herring)
b)Patch description wraped in 72 columns(Rob Herring)
c)Moved DT binding file to bindings/net/wireless/(Rob Herring)
d)Renamed "mwifiex,chip-gpio" to "marvell,wakeup-gpios"(Rob Herring/
Arnd Bergmann)
e)Replaced #ifdef with __maybe_unused(Arnd Bergmann)

v5: a)Removed wildcards from compatible string(Arnd Bergmann)
b)Prepared single patch for all binding changes(Rob Herring)
c)Specified our node as a subnode of SDIO controller. With this approach, we
don't need to register new platform driver. (Rob herring)

v6: a)List out the specific property names for marvell,caldata* and size of the data(Rob Herring)
b)Use sdio function number for both the unit address and reg(Rob Herring)
---
.../bindings/net/wireless/marvell-sd8xxx.txt | 63 ++++++++++++++++++++++
1 file changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
new file mode 100644
index 0000000..337fed4
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
@@ -0,0 +1,63 @@
+Marvell 8897/8997 (sd8897/sd8997) SDIO devices
+------
+
+This node provides properties for controlling the marvell sdio wireless device.
+The node is expected to be specified as a child node to the SDIO controller that
+connects the device to the system.
+
+Required properties:
+
+ - compatible : should be one of the following:
+ * "marvell,sd8897"
+ * "marvell,sd8997"
+
+Optional properties:
+
+ - marvell,caldata* : A series of properties with marvell,caldata prefix,
+ represent calibration data downloaded to the device during
+ initialization. This is an array of unsigned values.
+ the properties should follow below property name and
+ corresponding array length:
+ "marvell,caldata_00_txpwrlimit_2g_cfg_set" (length = 566).
+ "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub0" (length = 502).
+ "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub1" (length = 688).
+ "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub2" (length = 750).
+ "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub3" (length = 502).
+ - marvell,wakeup-pin : 'wakeuppin' is a wakeup pin number of wifi chip which will
+ be configured to firmware. firmware will wakeup host side use
+ the pin during suspend/resume stage.
+ - interrupt-parent: phandle of the parent interrupt controller
+ - interrupts : interrupt pin number to the cpu. driver will request an irq based on
+ this interrupt number. during system suspend, the irq will be enabled
+ as system wakeup source, so that the wifi chip can wakeup host
+ platform under certain condition. during system resume, the irq will
+ be disabled to make sure unnecessary interrupt is not received.
+
+Example:
+
+Tx power limit calibration data is configured in below example.
+The calibration data is an array of unsigned values, the length
+can vary between hw versions.
+IRQ pin 38 is used as system wakeup source interrupt. wakeup pin 3 is configured
+so that firmware can wakeup host using this device side pin.
+
+&mmc3 {
+ status = "okay";
+ vmmc-supply = <&wlan_en_reg>;
+ bus-width = <4>;
+ cap-power-off-card;
+ keep-power-in-suspend;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ mwifiex: mwifiex@1 {
+ compatible = "marvell,sd8897";
+ reg = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
+
+ marvell,caldata_00_txpwrlimit_2g_cfg_set = /bits/ 8 <
+ 0x01 0x00 0x06 0x00 0x08 0x02 0x89 0x01>;
+ marvell,wakeup-pin = <3>;
+ };
+};
--
1.8.1.4



2016-03-30 13:26:30

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH v6 2/2] mwifiex: add platform specific wakeup interrupt support

From: Xinming Hu <[email protected]>

On some arm-based platforms, we need to configure platform specific
parameters by device tree node and also define our node as a child
node of parent SDIO host controller.
This patch parses these parameters from device tree. It includes
calibration data dowoload to firmware, wakeup pin configured to firmware,
and soc specific wake up gpio, which will be set as wakeup interrupt pin.

Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/marvell/mwifiex/main.h | 11 ++++
drivers/net/wireless/marvell/mwifiex/sdio.c | 77 ++++++++++++++++++++++++++
drivers/net/wireless/marvell/mwifiex/sdio.h | 7 +++
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 14 ++++-
4 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index eb2c90c..9da27cf 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -37,6 +37,17 @@
#include <linux/idr.h>
#include <linux/inetdevice.h>
#include <linux/devcoredump.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/gfp.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/of_irq.h>

#include "decl.h"
#include "ioctl.h"
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index 901c064..c55e69b 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -73,6 +73,66 @@ static struct memory_type_mapping mem_type_mapping_tbl[] = {
{"EXTLAST", NULL, 0, 0xFE},
};

+static const struct of_device_id mwifiex_sdio_of_match_table[] = {
+ { .compatible = "marvell,sd8897" },
+ { .compatible = "marvell,sd8997" },
+ { }
+};
+
+static irqreturn_t mwifiex_wake_irq_wifi(int irq, void *priv)
+{
+ struct mwifiex_plt_wake_cfg *cfg = priv;
+
+ if (cfg->irq_wifi >= 0) {
+ pr_info("%s: wake by wifi", __func__);
+ cfg->wake_by_wifi = true;
+ disable_irq_nosync(irq);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* This function parse device tree node using mmc subnode devicetree API.
+ * The device node is saved in card->plt_of_node.
+ * if the device tree node exist and include interrupts attributes, this
+ * function will also request platform specific wakeup interrupt.
+ */
+static int mwifiex_sdio_probe_of(struct device *dev, struct sdio_mmc_card *card)
+{
+ struct mwifiex_plt_wake_cfg *cfg;
+ int ret;
+
+ if (!dev->of_node ||
+ !of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) {
+ pr_err("sdio platform data not available");
+ return -1;
+ }
+
+ card->plt_of_node = dev->of_node;
+ card->plt_wake_cfg = devm_kzalloc(dev, sizeof(*card->plt_wake_cfg),
+ GFP_KERNEL);
+ cfg = card->plt_wake_cfg;
+ if (cfg && card->plt_of_node) {
+ cfg->irq_wifi = irq_of_parse_and_map(card->plt_of_node, 0);
+ if (!cfg->irq_wifi) {
+ dev_err(dev, "fail to parse irq_wifi from device tree");
+ } else {
+ ret = devm_request_irq(dev, cfg->irq_wifi,
+ mwifiex_wake_irq_wifi,
+ IRQF_TRIGGER_LOW,
+ "wifi_wake", cfg);
+ if (ret) {
+ dev_err(dev,
+ "Failed to request irq_wifi %d (%d)\n",
+ cfg->irq_wifi, ret);
+ }
+ disable_irq(cfg->irq_wifi);
+ }
+ }
+
+ return 0;
+}
+
/*
* SDIO probe.
*
@@ -127,6 +187,9 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
return -EIO;
}

+ /* device tree node parsing and platform specific configuration*/
+ mwifiex_sdio_probe_of(&func->dev, card);
+
if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops,
MWIFIEX_SDIO)) {
pr_err("%s: add card failed\n", __func__);
@@ -183,6 +246,13 @@ static int mwifiex_sdio_resume(struct device *dev)
mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
MWIFIEX_SYNC_CMD);

+ /* Disable platform specific wakeup interrupt */
+ if (card->plt_wake_cfg && card->plt_wake_cfg->irq_wifi >= 0) {
+ disable_irq_wake(card->plt_wake_cfg->irq_wifi);
+ if (!card->plt_wake_cfg->wake_by_wifi)
+ disable_irq(card->plt_wake_cfg->irq_wifi);
+ }
+
return 0;
}

@@ -262,6 +332,13 @@ static int mwifiex_sdio_suspend(struct device *dev)

adapter = card->adapter;

+ /* Enable platform specific wakeup interrupt */
+ if (card->plt_wake_cfg && card->plt_wake_cfg->irq_wifi >= 0) {
+ card->plt_wake_cfg->wake_by_wifi = false;
+ enable_irq(card->plt_wake_cfg->irq_wifi);
+ enable_irq_wake(card->plt_wake_cfg->irq_wifi);
+ }
+
/* Enable the Host Sleep */
if (!mwifiex_enable_hs(adapter)) {
mwifiex_dbg(adapter, ERROR,
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h
index b9fbc5c..db837f1 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
@@ -154,6 +154,11 @@
a->mpa_rx.start_port = 0; \
} while (0)

+struct mwifiex_plt_wake_cfg {
+ int irq_wifi;
+ bool wake_by_wifi;
+};
+
/* data structure for SDIO MPA TX */
struct mwifiex_sdio_mpa_tx {
/* multiport tx aggregation buffer pointer */
@@ -237,6 +242,8 @@ struct mwifiex_sdio_card_reg {
struct sdio_mmc_card {
struct sdio_func *func;
struct mwifiex_adapter *adapter;
+ struct device_node *plt_of_node;
+ struct mwifiex_plt_wake_cfg *plt_wake_cfg;

const char *firmware;
const struct mwifiex_sdio_card_reg *reg;
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 30f1526..930495b 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -2134,6 +2134,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
enum state_11d_t state_11d;
struct mwifiex_ds_11n_tx_cfg tx_cfg;
u8 sdio_sp_rx_aggr_enable;
+ int data;

if (first_sta) {
if (priv->adapter->iface_type == MWIFIEX_PCIE) {
@@ -2154,9 +2155,16 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
* The cal-data can be read from device tree and/or
* a configuration file and downloaded to firmware.
*/
- adapter->dt_node =
- of_find_node_by_name(NULL, "marvell_cfgdata");
- if (adapter->dt_node) {
+ if (priv->adapter->iface_type == MWIFIEX_SDIO &&
+ adapter->dev->of_node) {
+ adapter->dt_node = adapter->dev->of_node;
+ if (of_property_read_u32(adapter->dt_node,
+ "marvell,wakeup-pin",
+ &data) == 0) {
+ pr_debug("Wakeup pin = 0x%x\n", data);
+ adapter->hs_cfg.gpio = data;
+ }
+
ret = mwifiex_dnld_dt_cfgdata(priv, adapter->dt_node,
"marvell,caldata");
if (ret)
--
1.8.1.4


2016-03-30 14:16:08

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v6 1/2] dt: bindings: add MARVELL's sd8xxx wireless device

On Wed, Mar 30, 2016 at 8:19 AM, Amitkumar Karwar <[email protected]> wrote:
> From: Xinming Hu <[email protected]>
>
> Add device tree binding documentation for MARVELL's sd8xxx
> (sd8897 and sd8997) wlan chip.
>
> Signed-off-by: Xinming Hu <[email protected]>
> Signed-off-by: Amitkumar Karwar <[email protected]>
> ---
> Listing changelist for both 1/2 and 2/2 patches
> v3: Don't update adapter->dt_node if mwifiex_plt_dev is NULL
>
> v4: a)Corrected the 'name' and 'compatible' property names.(Arnd Bergmann and Rob
> Herring)
> b)Patch description wraped in 72 columns(Rob Herring)
> c)Moved DT binding file to bindings/net/wireless/(Rob Herring)
> d)Renamed "mwifiex,chip-gpio" to "marvell,wakeup-gpios"(Rob Herring/
> Arnd Bergmann)
> e)Replaced #ifdef with __maybe_unused(Arnd Bergmann)
>
> v5: a)Removed wildcards from compatible string(Arnd Bergmann)
> b)Prepared single patch for all binding changes(Rob Herring)
> c)Specified our node as a subnode of SDIO controller. With this approach, we
> don't need to register new platform driver. (Rob herring)
>
> v6: a)List out the specific property names for marvell,caldata* and size of the data(Rob Herring)
> b)Use sdio function number for both the unit address and reg(Rob Herring)
> ---
> .../bindings/net/wireless/marvell-sd8xxx.txt | 63 ++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
>
> diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
> new file mode 100644
> index 0000000..337fed4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
> @@ -0,0 +1,63 @@
> +Marvell 8897/8997 (sd8897/sd8997) SDIO devices
> +------
> +
> +This node provides properties for controlling the marvell sdio wireless device.
> +The node is expected to be specified as a child node to the SDIO controller that
> +connects the device to the system.
> +
> +Required properties:
> +
> + - compatible : should be one of the following:
> + * "marvell,sd8897"
> + * "marvell,sd8997"
> +
> +Optional properties:
> +
> + - marvell,caldata* : A series of properties with marvell,caldata prefix,
> + represent calibration data downloaded to the device during
> + initialization. This is an array of unsigned values.

unsigned 8-bit values...

> + the properties should follow below property name and
> + corresponding array length:
> + "marvell,caldata_00_txpwrlimit_2g_cfg_set" (length = 566).
> + "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub0" (length = 502).
> + "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub1" (length = 688).
> + "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub2" (length = 750).
> + "marvell,caldata_00_txpwrlimit_5g_cfg_set_sub3" (length = 502).

The 00 and cfg_set seem pretty pointless, and '-' is preferred over '_'. So:

marvell,caldata-txpwrlimit-5g-sub3

> + - marvell,wakeup-pin : 'wakeuppin' is a wakeup pin number of wifi chip which will

Drop "wakeuppin is"

> + be configured to firmware. firmware will wakeup host side use
> + the pin during suspend/resume stage.
> + - interrupt-parent: phandle of the parent interrupt controller
> + - interrupts : interrupt pin number to the cpu. driver will request an irq based on
> + this interrupt number. during system suspend, the irq will be enabled
> + as system wakeup source, so that the wifi chip can wakeup host

You need to use the wakeup-source binding here
(bindings/power/wakeup-source.txt). Probably on the BT binding too?

> + platform under certain condition. during system resume, the irq will
> + be disabled to make sure unnecessary interrupt is not received.
> +
> +Example:
> +
> +Tx power limit calibration data is configured in below example.
> +The calibration data is an array of unsigned values, the length
> +can vary between hw versions.
> +IRQ pin 38 is used as system wakeup source interrupt. wakeup pin 3 is configured
> +so that firmware can wakeup host using this device side pin.
> +
> +&mmc3 {
> + status = "okay";
> + vmmc-supply = <&wlan_en_reg>;
> + bus-width = <4>;
> + cap-power-off-card;
> + keep-power-in-suspend;
> +
> + #address-cells = <1>;
> + #size-cells = <0>;
> + mwifiex: mwifiex@1 {

wifi@1

> + compatible = "marvell,sd8897";
> + reg = <1>;
> + interrupt-parent = <&pio>;
> + interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
> +
> + marvell,caldata_00_txpwrlimit_2g_cfg_set = /bits/ 8 <
> + 0x01 0x00 0x06 0x00 0x08 0x02 0x89 0x01>;
> + marvell,wakeup-pin = <3>;
> + };
> +};
> --
> 1.8.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2016-04-11 11:23:58

by Amitkumar Karwar

[permalink] [raw]
Subject: RE: [PATCH v6 1/2] dt: bindings: add MARVELL's sd8xxx wireless device

SGkgUm9iLA0KDQpUaGFua3MgZm9yIHRoZSByZXZpZXcuDQoNCj4gRnJvbTogUm9iIEhlcnJpbmcg
W21haWx0bzpyb2JoQGtlcm5lbC5vcmddDQo+IFNlbnQ6IFdlZG5lc2RheSwgTWFyY2ggMzAsIDIw
MTYgNzo0NiBQTQ0KPiBUbzogQW1pdGt1bWFyIEthcndhcg0KPiBDYzogbGludXgtd2lyZWxlc3NA
dmdlci5rZXJuZWwub3JnOyBDYXRoeSBMdW87IE5pc2hhbnQgU2FybXVrYWRhbTsNCj4gZGV2aWNl
dHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFdlaS1OaW5nIEh1YW5nOyBYaW5taW5nIEh1DQo+IFN1Ympl
Y3Q6IFJlOiBbUEFUQ0ggdjYgMS8yXSBkdDogYmluZGluZ3M6IGFkZCBNQVJWRUxMJ3Mgc2Q4eHh4
IHdpcmVsZXNzDQo+IGRldmljZQ0KPiANCj4gT24gV2VkLCBNYXIgMzAsIDIwMTYgYXQgODoxOSBB
TSwgQW1pdGt1bWFyIEthcndhciA8YWthcndhckBtYXJ2ZWxsLmNvbT4NCj4gd3JvdGU6DQo+ID4g
RnJvbTogWGlubWluZyBIdSA8aHV4bUBtYXJ2ZWxsLmNvbT4NCj4gPg0KPiA+IEFkZCBkZXZpY2Ug
dHJlZSBiaW5kaW5nIGRvY3VtZW50YXRpb24gZm9yIE1BUlZFTEwncyBzZDh4eHgNCj4gPiAoc2Q4
ODk3IGFuZCBzZDg5OTcpIHdsYW4gY2hpcC4NCj4gPg0KPiA+IFNpZ25lZC1vZmYtYnk6IFhpbm1p
bmcgSHUgPGh1eG1AbWFydmVsbC5jb20+DQo+ID4gU2lnbmVkLW9mZi1ieTogQW1pdGt1bWFyIEth
cndhciA8YWthcndhckBtYXJ2ZWxsLmNvbT4NCj4gPiAtLS0NCj4gPiBMaXN0aW5nIGNoYW5nZWxp
c3QgZm9yIGJvdGggMS8yIGFuZCAyLzIgcGF0Y2hlcw0KPiA+IHYzOiBEb24ndCB1cGRhdGUgYWRh
cHRlci0+ZHRfbm9kZSBpZiBtd2lmaWV4X3BsdF9kZXYgaXMgTlVMTA0KPiA+DQo+ID4gdjQ6IGEp
Q29ycmVjdGVkIHRoZSAnbmFtZScgYW5kICdjb21wYXRpYmxlJyBwcm9wZXJ0eSBuYW1lcy4oQXJu
ZA0KPiBCZXJnbWFubiBhbmQgUm9iDQo+ID4gICAgIEhlcnJpbmcpDQo+ID4gICAgIGIpUGF0Y2gg
ZGVzY3JpcHRpb24gd3JhcGVkIGluIDcyIGNvbHVtbnMoUm9iIEhlcnJpbmcpDQo+ID4gICAgIGMp
TW92ZWQgRFQgYmluZGluZyBmaWxlIHRvIGJpbmRpbmdzL25ldC93aXJlbGVzcy8oUm9iIEhlcnJp
bmcpDQo+ID4gICAgIGQpUmVuYW1lZCAibXdpZmlleCxjaGlwLWdwaW8iIHRvICJtYXJ2ZWxsLHdh
a2V1cC1ncGlvcyIoUm9iDQo+IEhlcnJpbmcvDQo+ID4gICAgIEFybmQgQmVyZ21hbm4pDQo+ID4g
ICAgIGUpUmVwbGFjZWQgI2lmZGVmIHdpdGggX19tYXliZV91bnVzZWQoQXJuZCBCZXJnbWFubikN
Cj4gPg0KPiA+IHY1OiBhKVJlbW92ZWQgd2lsZGNhcmRzIGZyb20gY29tcGF0aWJsZSBzdHJpbmco
QXJuZCBCZXJnbWFubikNCj4gPiAgICAgYilQcmVwYXJlZCBzaW5nbGUgcGF0Y2ggZm9yIGFsbCBi
aW5kaW5nIGNoYW5nZXMoUm9iIEhlcnJpbmcpDQo+ID4gICAgIGMpU3BlY2lmaWVkIG91ciBub2Rl
IGFzIGEgc3Vibm9kZSBvZiBTRElPIGNvbnRyb2xsZXIuIFdpdGggdGhpcw0KPiBhcHByb2FjaCwg
d2UNCj4gPiAgICAgZG9uJ3QgbmVlZCB0byByZWdpc3RlciBuZXcgcGxhdGZvcm0gZHJpdmVyLiAo
Um9iIGhlcnJpbmcpDQo+ID4NCj4gPiB2NjogYSlMaXN0IG91dCB0aGUgc3BlY2lmaWMgcHJvcGVy
dHkgbmFtZXMgZm9yIG1hcnZlbGwsY2FsZGF0YSogYW5kDQo+IHNpemUgb2YgdGhlIGRhdGEoUm9i
IEhlcnJpbmcpDQo+ID4gICAgIGIpVXNlIHNkaW8gZnVuY3Rpb24gbnVtYmVyIGZvciBib3RoIHRo
ZSB1bml0IGFkZHJlc3MgYW5kIHJlZyhSb2INCj4gPiBIZXJyaW5nKQ0KPiA+IC0tLQ0KPiA+ICAu
Li4vYmluZGluZ3MvbmV0L3dpcmVsZXNzL21hcnZlbGwtc2Q4eHh4LnR4dCAgICAgICB8IDYzDQo+
ICsrKysrKysrKysrKysrKysrKysrKysNCj4gPiAgMSBmaWxlIGNoYW5nZWQsIDYzIGluc2VydGlv
bnMoKykNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0DQo+ID4gRG9jdW1lbnRhdGlvbi9kZXZpY2V0
cmVlL2JpbmRpbmdzL25ldC93aXJlbGVzcy9tYXJ2ZWxsLXNkOHh4eC50eHQNCj4gPg0KPiA+IGRp
ZmYgLS1naXQNCj4gPiBhL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9uZXQvd2ly
ZWxlc3MvbWFydmVsbC1zZDh4eHgudHh0DQo+ID4gYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUv
YmluZGluZ3MvbmV0L3dpcmVsZXNzL21hcnZlbGwtc2Q4eHh4LnR4dA0KPiA+IG5ldyBmaWxlIG1v
ZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMC4uMzM3ZmVkNA0KPiA+IC0tLSAvZGV2L251bGwN
Cj4gPiArKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvbmV0L3dpcmVsZXNz
L21hcnZlbGwtc2Q4eHh4LnR4DQo+ID4gKysrIHQNCj4gPiBAQCAtMCwwICsxLDYzIEBADQo+ID4g
K01hcnZlbGwgODg5Ny84OTk3IChzZDg4OTcvc2Q4OTk3KSBTRElPIGRldmljZXMNCj4gPiArLS0t
LS0tDQo+ID4gKw0KPiA+ICtUaGlzIG5vZGUgcHJvdmlkZXMgcHJvcGVydGllcyBmb3IgY29udHJv
bGxpbmcgdGhlIG1hcnZlbGwgc2Rpbw0KPiB3aXJlbGVzcyBkZXZpY2UuDQo+ID4gK1RoZSBub2Rl
IGlzIGV4cGVjdGVkIHRvIGJlIHNwZWNpZmllZCBhcyBhIGNoaWxkIG5vZGUgdG8gdGhlIFNESU8N
Cj4gPiArY29udHJvbGxlciB0aGF0IGNvbm5lY3RzIHRoZSBkZXZpY2UgdG8gdGhlIHN5c3RlbS4N
Cj4gPiArDQo+ID4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ID4gKw0KPiA+ICsgIC0gY29tcGF0
aWJsZSA6IHNob3VsZCBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZzoNCj4gPiArICAgICAgICogIm1h
cnZlbGwsc2Q4ODk3Ig0KPiA+ICsgICAgICAgKiAibWFydmVsbCxzZDg5OTciDQo+ID4gKw0KPiA+
ICtPcHRpb25hbCBwcm9wZXJ0aWVzOg0KPiA+ICsNCj4gPiArICAtIG1hcnZlbGwsY2FsZGF0YSog
OiBBIHNlcmllcyBvZiBwcm9wZXJ0aWVzIHdpdGggbWFydmVsbCxjYWxkYXRhDQo+IHByZWZpeCwN
Cj4gPiArICAgICAgICAgICAgICAgICAgICAgcmVwcmVzZW50IGNhbGlicmF0aW9uIGRhdGEgZG93
bmxvYWRlZCB0byB0aGUNCj4gZGV2aWNlIGR1cmluZw0KPiA+ICsgICAgICAgICAgICAgICAgICAg
ICBpbml0aWFsaXphdGlvbi4gVGhpcyBpcyBhbiBhcnJheSBvZiB1bnNpZ25lZA0KPiB2YWx1ZXMu
DQo+IA0KPiB1bnNpZ25lZCA4LWJpdCB2YWx1ZXMuLi4NCj4gDQo+ID4gKyAgICAgICAgICAgICAg
ICAgICAgIHRoZSBwcm9wZXJ0aWVzIHNob3VsZCBmb2xsb3cgYmVsb3cgcHJvcGVydHkgbmFtZQ0K
PiBhbmQNCj4gPiArICAgICAgICAgICAgICAgICAgICAgY29ycmVzcG9uZGluZyBhcnJheSBsZW5n
dGg6DQo+ID4gKyAgICAgICAibWFydmVsbCxjYWxkYXRhXzAwX3R4cHdybGltaXRfMmdfY2ZnX3Nl
dCIgKGxlbmd0aCA9IDU2NikuDQo+ID4gKyAgICAgICAibWFydmVsbCxjYWxkYXRhXzAwX3R4cHdy
bGltaXRfNWdfY2ZnX3NldF9zdWIwIiAobGVuZ3RoID0NCj4gNTAyKS4NCj4gPiArICAgICAgICJt
YXJ2ZWxsLGNhbGRhdGFfMDBfdHhwd3JsaW1pdF81Z19jZmdfc2V0X3N1YjEiIChsZW5ndGggPQ0K
PiA2ODgpLg0KPiA+ICsgICAgICAgIm1hcnZlbGwsY2FsZGF0YV8wMF90eHB3cmxpbWl0XzVnX2Nm
Z19zZXRfc3ViMiIgKGxlbmd0aCA9DQo+IDc1MCkuDQo+ID4gKyAgICAgICAibWFydmVsbCxjYWxk
YXRhXzAwX3R4cHdybGltaXRfNWdfY2ZnX3NldF9zdWIzIiAobGVuZ3RoID0NCj4gNTAyKS4NCj4g
DQo+IFRoZSAwMCBhbmQgY2ZnX3NldCBzZWVtIHByZXR0eSBwb2ludGxlc3MsIGFuZCAnLScgaXMg
cHJlZmVycmVkIG92ZXIgJ18nLg0KPiBTbzoNCj4gDQo+IG1hcnZlbGwsY2FsZGF0YS10eHB3cmxp
bWl0LTVnLXN1YjMNCj4gDQo+ID4gKyAgLSBtYXJ2ZWxsLHdha2V1cC1waW4gOiAnd2FrZXVwcGlu
JyBpcyBhIHdha2V1cCBwaW4gbnVtYmVyIG9mIHdpZmkNCj4gPiArIGNoaXAgd2hpY2ggd2lsbA0K
PiANCj4gRHJvcCAid2FrZXVwcGluIGlzIg0KPiANCj4gPiArICAgICAgICAgICAgICAgICAgICAg
YmUgY29uZmlndXJlZCB0byBmaXJtd2FyZS4gZmlybXdhcmUgd2lsbCB3YWtldXANCj4gaG9zdCBz
aWRlIHVzZQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICB0aGUgcGluIGR1cmluZyBzdXNwZW5k
L3Jlc3VtZSBzdGFnZS4NCj4gPiArICAtIGludGVycnVwdC1wYXJlbnQ6IHBoYW5kbGUgb2YgdGhl
IHBhcmVudCBpbnRlcnJ1cHQgY29udHJvbGxlcg0KPiA+ICsgIC0gaW50ZXJydXB0cyA6IGludGVy
cnVwdCBwaW4gbnVtYmVyIHRvIHRoZSBjcHUuIGRyaXZlciB3aWxsIHJlcXVlc3QNCj4gYW4gaXJx
IGJhc2VkIG9uDQo+ID4gKyAgICAgICAgICAgICAgICB0aGlzIGludGVycnVwdCBudW1iZXIuIGR1
cmluZyBzeXN0ZW0gc3VzcGVuZCwgdGhlIGlycQ0KPiB3aWxsIGJlIGVuYWJsZWQNCj4gPiArICAg
ICAgICAgICAgICAgIGFzIHN5c3RlbSB3YWtldXAgc291cmNlLCBzbyB0aGF0IHRoZSB3aWZpIGNo
aXAgY2FuDQo+ID4gKyB3YWtldXAgaG9zdA0KPiANCj4gWW91IG5lZWQgdG8gdXNlIHRoZSB3YWtl
dXAtc291cmNlIGJpbmRpbmcgaGVyZSAoYmluZGluZ3MvcG93ZXIvd2FrZXVwLQ0KPiBzb3VyY2Uu
dHh0KS4gUHJvYmFibHkgb24gdGhlIEJUIGJpbmRpbmcgdG9vPw0KDQpXZSBkaWQgc29tZSBleHBl
cmltZW50cyBhbmQgdHJpZWQgdG8gZXhwbG9yZSB0aGlzIG9wdGlvbi4gSXQgc2VlbXMgdG8gYmUg
c3BlY2lmaWMgdG8gcnVudGltZSBwb3dlciBtYW5hZ2VtZW50Lg0KV2UgZG9uJ3QgdXNlIHJ1bnRp
bWUgUE0gZm9yIG91ciBkZXZpY2UuIFdlIGFyZSBpbnRlcmVzdGVkIGluIHN5c3RlbSBzdXNwZW5k
IGFuZCB3YWtldXAgKHVwb24gY2hhbmdpbmcgdGhlIElSUSBzdGF0dXMpDQpJIHdpbGwgc3VibWl0
IHVwZGF0ZWQgdmVyc2lvbiBhZGRyZXNzaW5nIG90aGVyIHJldmlldyBjb21tZW50cy4NCg0KUmVn
YXJkcywNCkFtaXRrdW1hcg0KDQo=