From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oa1-f41.google.com (mail-oa1-f41.google.com [209.85.160.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0279381B15 for ; Sat, 9 May 2026 19:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778354509; cv=none; b=tpYiRNgNzIa6GFqfHbo9FcYIAkfa7on1OX/e6JlGkzq+NXPEGrjBY1tw7ZjYeUxaxdoqcHr9lNKyOzZW9x1AwJH9wVdDEdCTDUjUcfeGD52ugt0EOOcBMcn+73h8p3fc/nhdDdAHETpfFc49slcBdqbCF9yKVqT4TCxN+bsI2z0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778354509; c=relaxed/simple; bh=Fpfhe5gz6iR4ioKm1P+M2DU0XaM+rPaTOdGwdtkvCTY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HyKjJ1PCzr+xc/h6RuIdJTBIzdB8jnUzBE2zr7/3DMtn0Vo1cSueKSucodNgibp9Jy5fV86GBj/3KOQ9luIu+2R6Ol3W0sR9hXnEPwp33emJ5yOIp7LGK9bQ+fgCpYVETa+Y7cWUhezrQrWiR/WUha7oIHaTJYalMyS+uJzSNeo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bX/Gtbgs; arc=none smtp.client-ip=209.85.160.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bX/Gtbgs" Received: by mail-oa1-f41.google.com with SMTP id 586e51a60fabf-4042fe53946so1183286fac.3 for ; Sat, 09 May 2026 12:21:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778354506; x=1778959306; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MS6Gmp6sQE6Gv493THZsD+PQMLRdz/0QWUf4zH2ZT5E=; b=bX/GtbgstKt7uy0dzBhCVYIIGBVeDEmfg0ECeai+gjooctZcqlFYBagoV5HipUD1oT 9iYc0r8bmIP2J032x9zolr+MGW4hAFcAcjU0k4Ak+bQSJaYH+BC/qsWlbdgiP8dXFhdt U1ng/FpOnopewKBKIn7OiBTIYYl0fNsLbk6yeKPTicChp1QVeG/UR+ILeqfrq+BHVuHd pH/U1N35cebNcrDSBrHvKIMeB2nYfpUYOc+JvIz8SXG3+KpNq7VnrKWUqaATWyh02v/A 7WJ5Biv9fTSzfzLeFoQ5uSkNl2/MpfeM+PhF0m/QfjlasGL0eNIYza2zACNKsOEyV1AH BjIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778354506; x=1778959306; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=MS6Gmp6sQE6Gv493THZsD+PQMLRdz/0QWUf4zH2ZT5E=; b=lKdWnh60ZAujl1P5qBJB+iGZ1/y2jRLtPQvpKoN0lYBl8HYIGGx3OqhntLdKyT+P/k SeeUciD0kcpguPt0R62aAwlrB6o5ktYXuK3SoX+xh7tWciS7928HuX4kPrtQx1c2utXR QHg8mXv35EZBPsGPZ/VUcO6bbIeu8PD4ow4FjPJ/PAnxkbdAGZcAnU+j2+ZfjQLIHhgT qd4FGcryrpr3qw5kF8S0BpESHAoXWawofi7ies/rZzJzNFK5iwqLWZlD/l1OpzKdxh+O llnF878hdeJYJA1ixox4298E1YN6YA8G8EnAFkeYcFI5R4HgMJ0faF7cku+3F9m7WYK5 E0Wg== X-Forwarded-Encrypted: i=1; AFNElJ9CBli90gF0R2bdKfkVMeKU5ZBOZY8lROlFMYVqh0yj2VPrATPun+Eh/OQIlCM0XmYHx7RoHrt69U3m@vger.kernel.org X-Gm-Message-State: AOJu0Yz3OTXi5VjZLeYhexRMmlTTgm/ugTmZq2geqDn2sgKoj8XxPvk8 2J5QUrIxr3EYyveS8o5R3VSWn5woLWHScNLbXaT3Kj7+k3G5PrFHLoJ/ X-Gm-Gg: Acq92OFEvmh6H5rxAU4oET6GeGN+bnzcQECGIuN4ZcnFxfbdapUaI4d/gFmz9JAEDLG rMiSD8efyBtdUKJ9gO1e8lUNgNTeZtTftV/laCCgLSbIPx5ide4yK5gFpcck1QEIfxLJDNrcpve +FV2poCJ7ovYtCAKIhlmbvvVo2/KxiT6Qo14mam4XydLsKSJBy2IhHRj6Eq147hZmSJi/sorOY/ 9QicNEEtSBcss+yx0cPL5eziDYhe8z57UNhvkAjh5PDxYskrmhhGor1VXID5OvkQzd9mAPSnwAe C0NRNW2MTPU5+aoA7IUQimv/GWDn/BE7bf35rXZ8Rgb5ZvyoI5r1Rp63Eto0qBT8vaH+1559+yQ FXRsz6rAiQRxNtNazYZJuN67ZuyPYxfuTYQpOBz4Ap16EIEOZCtYDUH6jOFXeouPsk24rdClb69 5tMDdETHSEcS8sZ7/verE9 X-Received: by 2002:a05:6870:b2c2:b0:42c:711:a235 with SMTP id 586e51a60fabf-434f65ee768mr10899586fac.35.1778354506285; Sat, 09 May 2026 12:21:46 -0700 (PDT) Received: from localhost.localdomain ([2600:1700:fb0:1bc0::54]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-4355736f517sm5243896fac.12.2026.05.09.12.21.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 May 2026 12:21:45 -0700 (PDT) From: Chris Morgan To: linux-iio@vger.kernel.org Cc: andy@kernel.org, nuno.sa@analog.com, dlechner@baylibre.com, jic23@kernel.org, jean-baptiste.maneyrol@tdk.com, linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org, heiko@sntech.de, conor+dt@kernel.org, krzk+dt@kernel.org, robh@kernel.org, andriy.shevchenko@intel.com, Chris Morgan Subject: [PATCH V5 09/11] iio: imu: inv_icm42607: Add Wake on Movement to icm42607 Date: Sat, 9 May 2026 14:19:03 -0500 Message-ID: <20260509191907.24734-10-macroalpha82@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260509191907.24734-1-macroalpha82@gmail.com> References: <20260509191907.24734-1-macroalpha82@gmail.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: 8bit From: Chris Morgan Add support for wake on movement for the icm42607 driver. Signed-off-by: Chris Morgan --- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 17 + .../iio/imu/inv_icm42607/inv_icm42607_accel.c | 301 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 213 ++++++++++++- 3 files changed, 521 insertions(+), 10 deletions(-) diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607.h b/drivers/iio/imu/inv_icm42607/inv_icm42607.h index cfda60905d71..ab79a056f28c 100644 --- a/drivers/iio/imu/inv_icm42607/inv_icm42607.h +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607.h @@ -119,6 +119,14 @@ struct inv_icm42607_suspended { bool temp; }; +struct inv_icm42607_apex { + unsigned int on; + struct { + u64 value; + bool enable; + } wom; +}; + /** * struct inv_icm42607_state - driver state variables * @lock: lock for serializing multiple registers access. @@ -132,6 +140,7 @@ struct inv_icm42607_suspended { * @indio_gyro: gyroscope IIO device. * @indio_accel: accelerometer IIO device. * @timestamp: interrupt timestamps. + * @apex: APEX (Advanced Pedometer and Event detection) management * @fifo: FIFO management structure. * @buffer: data transfer buffer aligned for DMA. */ @@ -149,6 +158,7 @@ struct inv_icm42607_state { struct { s64 accel; } timestamp; + struct inv_icm42607_apex apex; struct inv_icm42607_fifo fifo; __be16 buffer[3] __aligned(IIO_DMA_MINALIGN); }; @@ -401,6 +411,9 @@ int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st, int inv_icm42607_set_temp_conf(struct inv_icm42607_state *st, bool enable, unsigned int *sleep_ms); +int inv_icm42607_enable_wom(struct inv_icm42607_state *st); +int inv_icm42607_disable_wom(struct inv_icm42607_state *st); + int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw, inv_icm42607_bus_setup bus_setup); @@ -408,4 +421,8 @@ struct iio_dev *inv_icm42607_accel_init(struct inv_icm42607_state *st); int inv_icm42607_accel_parse_fifo(struct iio_dev *indio_dev); +void inv_icm42607_accel_handle_events(struct iio_dev *indio_dev, + unsigned int status2, unsigned int status3, + s64 timestamp); + #endif diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c index f90ba46bd7e4..99aaa370bd12 100644 --- a/drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c @@ -69,6 +69,16 @@ static const struct iio_chan_spec_ext_info inv_icm42607_accel_ext_infos[] = { { } }; +/* WoM event: rising ROC */ +static const struct iio_event_spec inv_icm42607_wom_events[] = { + { + .type = IIO_EV_TYPE_ROC, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_VALUE), + }, +}; + static const struct iio_chan_spec inv_icm42607_accel_channels[] = { INV_ICM42607_ACCEL_CHAN(IIO_MOD_X, INV_ICM42607_ACCEL_SCAN_X, inv_icm42607_accel_ext_infos), @@ -78,6 +88,8 @@ static const struct iio_chan_spec inv_icm42607_accel_channels[] = { inv_icm42607_accel_ext_infos), INV_ICM42607_TEMP_CHAN(INV_ICM42607_ACCEL_SCAN_TEMP), IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42607_ACCEL_SCAN_TIMESTAMP), + INV_ICM42607_ACCEL_EVENT_CHAN(IIO_MOD_X_OR_Y_OR_Z, inv_icm42607_wom_events, + ARRAY_SIZE(inv_icm42607_wom_events)), }; static const struct iio_event_spec inv_icm42607_motion_events[] = { @@ -209,6 +221,178 @@ static int inv_icm42607_accel_read_sensor(struct iio_dev *indio_dev, return 0; } +static unsigned int inv_icm42607_accel_convert_roc_to_wom(u64 roc, + int accel_hz, int accel_uhz) +{ + /* 1000/256mg per LSB converted in µm/s² */ + const unsigned int convert = (9807U * (MICRO / MILLI)) / 256U; + u64 value; + u64 freq_uhz; + + /* return 0 only if roc is 0 */ + if (roc == 0) + return 0; + + freq_uhz = (u64)accel_hz * MICRO + (u64)accel_uhz; + value = div64_u64(roc * MICRO, freq_uhz * (u64)convert); + + /* limit value to 8 bits and prevent 0 */ + return clamp(value, 1, 255); +} + +static u64 inv_icm42607_accel_convert_wom_to_roc(unsigned int threshold, + int accel_hz, int accel_uhz) +{ + /* 1000/256mg per LSB converted in µm/s² */ + const unsigned int convert = (9807U * (MICRO / MILLI)) / 256U; + u64 value; + u64 freq_uhz; + + value = threshold * convert; + freq_uhz = (u64)accel_hz * MICRO + (u64)accel_uhz; + + /* compute the differential by multiplying by the frequency */ + return div_u64(value * freq_uhz, MICRO); +} + +static int inv_icm42607_accel_set_wom_threshold(struct inv_icm42607_state *st, + u64 value, + int accel_hz, int accel_uhz) +{ + unsigned int threshold; + int ret; + + /* convert roc to wom threshold and convert back to handle clipping */ + threshold = inv_icm42607_accel_convert_roc_to_wom(value, accel_hz, accel_uhz); + value = inv_icm42607_accel_convert_wom_to_roc(threshold, accel_hz, accel_uhz); + + dev_dbg(regmap_get_device(st->map), "wom_threshold: 0x%x\n", threshold); + + /* set accel WoM threshold for the 3 axes */ + st->buffer[0] = threshold; + st->buffer[1] = threshold; + st->buffer[2] = threshold; + ret = regmap_bulk_write(st->map, INV_ICM42607_REG_ACCEL_WOM_X_THR, st->buffer, 3); + if (ret) + return ret; + + st->apex.wom.value = value; + + return 0; +} + +static int _inv_icm42607_accel_enable_wom(struct iio_dev *indio_dev) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42607_sensor_state *accel_st = iio_priv(indio_dev); + struct inv_icm42607_sensor_conf conf = INV_ICM42607_SENSOR_CONF_INIT; + unsigned int sleep_ms = 0; + int ret; + + scoped_guard(mutex, &st->lock) { + /* turn on accel sensor */ + conf.mode = accel_st->power_mode; + conf.filter = accel_st->filter; + ret = inv_icm42607_set_accel_conf(st, &conf, &sleep_ms); + if (ret) + return ret; + } + + if (sleep_ms) + msleep(sleep_ms); + + scoped_guard(mutex, &st->lock) { + ret = inv_icm42607_enable_wom(st); + if (ret) + return ret; + st->apex.on++; + st->apex.wom.enable = true; + } + + return 0; +} + +static int inv_icm42607_accel_enable_wom(struct iio_dev *indio_dev) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + struct device *pdev = regmap_get_device(st->map); + int ret; + + ret = pm_runtime_resume_and_get(pdev); + if (ret) + return ret; + + ret = _inv_icm42607_accel_enable_wom(indio_dev); + if (ret) { + pm_runtime_put_autosuspend(pdev); + return ret; + } + + return 0; +} + +static int _inv_icm42607_accel_disable_wom(struct iio_dev *indio_dev) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42607_sensor_conf conf = INV_ICM42607_SENSOR_CONF_INIT; + unsigned int sleep_ms = 0; + int ret; + + scoped_guard(mutex, &st->lock) { + /* + * Consider that turning off WoM is always working to avoid + * blocking the chip in on mode and prevent going back to sleep. + * If there is an error, the chip will anyway go back to sleep + * and the feature will not work anymore. + */ + st->apex.wom.enable = false; + st->apex.on--; + ret = inv_icm42607_disable_wom(st); + if (ret) + return ret; + /* turn off accel sensor if not used */ + if (!st->apex.on && !iio_buffer_enabled(indio_dev)) { + conf.mode = INV_ICM42607_SENSOR_MODE_OFF; + ret = inv_icm42607_set_accel_conf(st, &conf, &sleep_ms); + if (ret) + return ret; + } + } + + if (sleep_ms) + msleep(sleep_ms); + + return 0; +} + +static int inv_icm42607_accel_disable_wom(struct iio_dev *indio_dev) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + struct device *pdev = regmap_get_device(st->map); + int ret; + + ret = _inv_icm42607_accel_disable_wom(indio_dev); + + pm_runtime_put_autosuspend(pdev); + + return ret; +} + +void inv_icm42607_accel_handle_events(struct iio_dev *indio_dev, + unsigned int status2, unsigned int status3, + s64 timestamp) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + u64 ev_code; + + /* handle WoM event */ + if (st->apex.wom.enable && (status2 & INV_ICM42607_INT_STATUS2_WOM_INT)) { + ev_code = IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING); + iio_push_event(indio_dev, ev_code, timestamp); + } +} + static const int inv_icm42607_accel_scale_nano[][2] = { [INV_ICM42607_ACCEL_FS_16G] = { 0, 4788403 }, [INV_ICM42607_ACCEL_FS_8G] = { 0, 2394202 }, @@ -329,6 +513,10 @@ static int inv_icm42607_accel_write_odr(struct iio_dev *indio_dev, if (ret) return ret; + ret = inv_icm42607_accel_set_wom_threshold(st, st->apex.wom.value, val, val2); + if (ret) + return ret; + inv_icm42607_buffer_update_fifo_period(st); inv_icm42607_buffer_update_watermark(st); @@ -467,6 +655,115 @@ static int inv_icm42607_accel_hwfifo_flush(struct iio_dev *indio_dev, return st->fifo.nb.accel; } +static int inv_icm42607_accel_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + + /* handle only WoM (roc rising) event */ + if (type != IIO_EV_TYPE_ROC || dir != IIO_EV_DIR_RISING) + return -EINVAL; + + guard(mutex)(&st->lock); + + return st->apex.wom.enable ? 1 : 0; +} + +static int inv_icm42607_accel_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + + /* handle only WoM (roc rising) event */ + if (type != IIO_EV_TYPE_ROC || dir != IIO_EV_DIR_RISING) + return -EINVAL; + + scoped_guard(mutex, &st->lock) { + if (st->apex.wom.enable == state) + return 0; + + if (state) + return inv_icm42607_accel_enable_wom(indio_dev); + } + + return inv_icm42607_accel_disable_wom(indio_dev); +} + +static int inv_icm42607_accel_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + u32 rem; + + /* handle only WoM (roc rising) event value */ + if (type != IIO_EV_TYPE_ROC || dir != IIO_EV_DIR_RISING) + return -EINVAL; + + guard(mutex)(&st->lock); + + /* return value in micro */ + *val = div_u64_rem(st->apex.wom.value, MICRO, &rem); + *val2 = rem; + return IIO_VAL_INT_PLUS_MICRO; +} + +static int _inv_icm42607_accel_wom_value(struct inv_icm42607_state *st, + int val, int val2) +{ + u64 value; + unsigned int accel_hz, accel_uhz; + int ret; + + guard(mutex)(&st->lock); + + ret = inv_icm42607_accel_read_odr(st, &accel_hz, &accel_uhz); + if (ret < 0) + return ret; + + value = (u64)val * MICRO + (u64)val2; + + return inv_icm42607_accel_set_wom_threshold(st, value, + accel_hz, accel_uhz); +} + +static int inv_icm42607_accel_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + struct inv_icm42607_state *st = iio_device_get_drvdata(indio_dev); + struct device *dev = regmap_get_device(st->map); + int ret; + + /* handle only WoM (roc rising) event value */ + if (type != IIO_EV_TYPE_ROC || dir != IIO_EV_DIR_RISING) + return -EINVAL; + + if (val < 0 || val2 < 0) + return -EINVAL; + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + + ret = _inv_icm42607_accel_wom_value(st, val, val2); + + pm_runtime_put_autosuspend(dev); + + return ret; +} + static const struct iio_info inv_icm42607_accel_info = { .read_raw = inv_icm42607_accel_read_raw, .read_avail = inv_icm42607_accel_read_avail, @@ -475,6 +772,10 @@ static const struct iio_info inv_icm42607_accel_info = { .update_scan_mode = inv_icm42607_accel_update_scan_mode, .hwfifo_set_watermark = inv_icm42607_accel_hwfifo_set_watermark, .hwfifo_flush_to_buffer = inv_icm42607_accel_hwfifo_flush, + .read_event_config = inv_icm42607_accel_read_event_config, + .write_event_config = inv_icm42607_accel_write_event_config, + .read_event_value = inv_icm42607_accel_read_event_value, + .write_event_value = inv_icm42607_accel_write_event_value, }; struct iio_dev *inv_icm42607_accel_init(struct inv_icm42607_state *st) diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c index ce59f9337ed9..e5d031ca631d 100644 --- a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c @@ -233,6 +233,38 @@ int inv_icm42607_set_temp_conf(struct inv_icm42607_state *st, bool enable, sleep_ms); } +int inv_icm42607_enable_wom(struct inv_icm42607_state *st) +{ + int ret; + + /* enable WoM hardware */ + ret = regmap_write(st->map, INV_ICM42607_REG_WOM_CONFIG, + FIELD_PREP(INV_ICM42607_WOM_CONFIG_INT_DUR_MASK, 1) | + INV_ICM42607_WOM_CONFIG_MODE | + INV_ICM42607_WOM_CONFIG_EN); + if (ret) + return ret; + + /* enable WoM interrupt */ + return regmap_set_bits(st->map, INV_ICM42607_REG_INT_SOURCE1, + INV_ICM42607_INT_SOURCE1_WOM_INT1_EN); +} + +int inv_icm42607_disable_wom(struct inv_icm42607_state *st) +{ + int ret; + + /* disable WoM interrupt */ + ret = regmap_clear_bits(st->map, INV_ICM42607_REG_INT_SOURCE1, + INV_ICM42607_INT_SOURCE1_WOM_INT1_EN); + if (ret) + return ret; + + /* disable WoM hardware */ + return regmap_clear_bits(st->map, INV_ICM42607_REG_WOM_CONFIG, + INV_ICM42607_WOM_CONFIG_EN); +} + static int inv_icm42607_set_conf(struct inv_icm42607_state *st, const struct inv_icm42607_conf *conf) { @@ -343,6 +375,112 @@ static int inv_icm42607_setup(struct inv_icm42607_state *st, return inv_icm42607_set_conf(st, st->hw->conf); } +static irqreturn_t inv_icm42607_irq_timestamp(int irq, void *_data) +{ + struct inv_icm42607_state *st = _data; + + st->timestamp.accel = iio_get_time_ns(st->indio_accel); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t inv_icm42607_irq_handler(int irq, void *_data) +{ + struct inv_icm42607_state *st = _data; + struct device *dev = regmap_get_device(st->map); + unsigned int status; + int ret; + + guard(mutex)(&st->lock); + + if (st->apex.on) { + unsigned int status2, status3; + + /* read INT_STATUS2 and INT_STATUS3 in 1 operation */ + ret = regmap_bulk_read(st->map, INV_ICM42607_REG_INT_STATUS2, st->buffer, 2); + if (ret) { + dev_err(dev, "Interrupt status read error %d\n", ret); + return IRQ_HANDLED; + } + + status2 = st->buffer[0]; + status3 = st->buffer[1]; + inv_icm42607_accel_handle_events(st->indio_accel, status2, status3, + st->timestamp.accel); + } + + ret = regmap_read(st->map, INV_ICM42607_REG_INT_STATUS, &status); + if (ret) { + dev_err(dev, "Interrut status read error %d\n", ret); + return IRQ_HANDLED; + } + + if (status & INV_ICM42607_INT_STATUS_FIFO_FULL) + dev_warn(dev, "FIFO full data lost!\n"); + + if (status & INV_ICM42607_INT_STATUS_FIFO_THS) { + ret = inv_icm42607_buffer_fifo_read(st, 0); + if (ret) { + dev_err(dev, "FIFO read error %d\n", ret); + return IRQ_HANDLED; + } + + ret = inv_icm42607_buffer_fifo_parse(st); + if (ret) + dev_err(dev, "FIFO parsing error %d\n", ret); + } + + return IRQ_HANDLED; +} + +/** + * inv_icm42607_irq_init() - initialize int pin and interrupt handler + * @st: driver internal state + * @irq: irq number + * @irq_type: irq trigger type + * @open_drain: true if irq is open drain, false for push-pull + * + * Returns 0 on success, a negative error code otherwise. + */ +static int inv_icm42607_irq_init(struct inv_icm42607_state *st, int irq, + int irq_type, bool open_drain) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int val = 0; + int ret; + + switch (irq_type) { + case IRQF_TRIGGER_RISING: + case IRQF_TRIGGER_HIGH: + val = INV_ICM42607_INT_CONFIG_INT1_ACTIVE_HIGH; + break; + default: + val = INV_ICM42607_INT_CONFIG_INT1_ACTIVE_LOW; + break; + } + + switch (irq_type) { + case IRQF_TRIGGER_LOW: + case IRQF_TRIGGER_HIGH: + val |= INV_ICM42607_INT_CONFIG_INT1_LATCHED; + break; + default: + break; + } + + if (!open_drain) + val |= INV_ICM42607_INT_CONFIG_INT1_PUSH_PULL; + + ret = regmap_write(st->map, INV_ICM42607_REG_INT_CONFIG, val); + if (ret) + return ret; + + irq_type |= IRQF_ONESHOT; + return devm_request_threaded_irq(dev, irq, inv_icm42607_irq_timestamp, + inv_icm42607_irq_handler, irq_type, + st->hw->name, st); +} + static int inv_icm42607_enable_vddio_reg(struct inv_icm42607_state *st) { int ret; @@ -371,13 +509,18 @@ int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw struct device *dev = regmap_get_device(regmap); struct fwnode_handle *fwnode = dev_fwnode(dev); struct inv_icm42607_state *st; - int irq; + int irq, irq_type; + bool open_drain; int ret; irq = fwnode_irq_get_byname(fwnode, "INT1"); if (irq < 0) return dev_err_probe(dev, irq, "error missing INT1 interrupt\n"); + irq_type = irq_get_trigger_type(irq); + + open_drain = device_property_read_bool(dev, "drive-open-drain"); + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; @@ -437,6 +580,11 @@ int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw if (IS_ERR(st->indio_accel)) return PTR_ERR(st->indio_accel); + /* Initialize interrupt handling */ + ret = inv_icm42607_irq_init(st, irq, irq_type, open_drain); + if (ret) + return ret; + return 0; } EXPORT_SYMBOL_NS_GPL(inv_icm42607_core_probe, "IIO_ICM42607"); @@ -448,6 +596,9 @@ EXPORT_SYMBOL_NS_GPL(inv_icm42607_core_probe, "IIO_ICM42607"); static int inv_icm42607_suspend(struct device *dev) { struct inv_icm42607_state *st = dev_get_drvdata(dev); + struct device *accel_dev; + bool wakeup; + int accel_conf; int ret; guard(mutex)(&st->lock); @@ -464,12 +615,36 @@ static int inv_icm42607_suspend(struct device *dev) return ret; } - ret = inv_icm42607_set_pwr_mgmt0(st, INV_ICM42607_SENSOR_MODE_OFF, - INV_ICM42607_SENSOR_MODE_OFF, - false, NULL); - if (ret) - return ret; - regulator_disable(st->vddio_supply); + /* keep chip on and wake-up capable if APEX and wakeup on */ + accel_dev = &st->indio_accel->dev; + wakeup = st->apex.on && device_may_wakeup(accel_dev); + if (wakeup) { + /* keep accel on and setup irq for wakeup */ + accel_conf = st->conf.accel.mode; + enable_irq_wake(st->irq); + disable_irq(st->irq); + ret = inv_icm42607_set_pwr_mgmt0(st, INV_ICM42607_SENSOR_MODE_OFF, + accel_conf, false, NULL); + if (ret) { + enable_irq(st->irq); + disable_irq_wake(st->irq); + return ret; + } + } else { + /* disable APEX features and accel if wakeup disabled */ + if (st->apex.wom.enable) { + ret = inv_icm42607_disable_wom(st); + if (ret) + return ret; + } + accel_conf = INV_ICM42607_SENSOR_MODE_OFF; + ret = inv_icm42607_set_pwr_mgmt0(st, INV_ICM42607_SENSOR_MODE_OFF, + INV_ICM42607_SENSOR_MODE_OFF, + false, NULL); + if (ret) + return ret; + regulator_disable(st->vddio_supply); + } return 0; } @@ -482,6 +657,8 @@ static int inv_icm42607_resume(struct device *dev) { struct inv_icm42607_state *st = dev_get_drvdata(dev); struct inv_icm42607_sensor_state *accel_st = iio_priv(st->indio_accel); + struct device *accel_dev; + bool wakeup; int ret; guard(mutex)(&st->lock); @@ -489,9 +666,18 @@ static int inv_icm42607_resume(struct device *dev) if (pm_runtime_suspended(dev)) return 0; - ret = inv_icm42607_enable_vddio_reg(st); - if (ret) - return ret; + /* check wakeup capability */ + accel_dev = &st->indio_accel->dev; + wakeup = st->apex.on && device_may_wakeup(accel_dev); + /* restore irq state */ + if (wakeup) { + enable_irq(st->irq); + disable_irq_wake(st->irq); + } else { + ret = inv_icm42607_enable_vddio_reg(st); + if (ret) + return ret; + } /* restore sensors state, noting gyro still not yet supported. */ ret = inv_icm42607_set_pwr_mgmt0(st, INV_ICM42607_SENSOR_MODE_OFF, @@ -500,6 +686,13 @@ static int inv_icm42607_resume(struct device *dev) if (ret) return ret; + /* restore APEX features if disabled */ + if (!wakeup && st->apex.wom.enable) { + ret = inv_icm42607_enable_wom(st); + if (ret) + return ret; + } + if (st->fifo.on) { inv_sensors_timestamp_reset(&accel_st->ts); ret = regmap_write(st->map, INV_ICM42607_REG_FIFO_CONFIG1, -- 2.43.0 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 40ED3CD37BB for ; Sat, 9 May 2026 19:21:59 +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:References:In-Reply-To: Message-ID:Date: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=2XN0Bd0yfTXrSNqwOh3y8LETiC7r87mByibKu1TvJxU=; b=U3HDTRtdzgSLY9 sBDLWr5YFM1gMNOeEWTYP9yDektBSpGh/5EyATVfuQciflkn2c6AhHGH7A/Hwwx2vIVxs7Wsx0zBW d7oy9RW5o17Rgb44fB79NIh2CgPIY1OJrBQkzICOjsIhjKI5rQIWCvpjkV0nts+L1hXw4gwqM0T7t khl8hsgKODTdOAnZciisXn9MGerZVDL4jBhwUjLIClWrsjX6cLJEAhy8jiXU/1R4NxilbMnztTh5+ 37Hflduy3Zdwg5eHB3ooxtiVQjWaETDE1g7yfHoiiOwmglPcCxTuKYmJVgtM6I5wn5vDn+sYqYT+a huwRVuC4/Ztit/NyGM9A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wLnFH-00000009WAU-0Jqb; Sat, 09 May 2026 19:21:51 +0000 Received: from mail-oa1-x2e.google.com ([2001:4860:4864:20::2e]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wLnFD-00000009W6G-3EV0 for linux-rockchip@lists.infradead.org; Sat, 09 May 2026 19:21:49 +0000 Received: by mail-oa1-x2e.google.com with SMTP id 586e51a60fabf-4042fe53946so1183285fac.3 for ; Sat, 09 May 2026 12:21:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778354506; x=1778959306; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MS6Gmp6sQE6Gv493THZsD+PQMLRdz/0QWUf4zH2ZT5E=; b=aPGFsqyI2YzlpNnIRsEEY1ktzbVJvMUOvvTOWFNqBA/ovTDPgYzETHYTNH9IE/k3Qh sls0nAO/vGQq1ckjJRKPAMjE6vBzQQTu5ePBpL3XqxX/eVXjC38a2zH3fI7ysDJBpyJD Uow2okVSNkqr37e3W2t8kt6ddjp6OZUyKyFMR5Wr9doqfe3UoS/mD14fNCkYwMWA6AXD J8gwyh5s0T0eZPmDPHZQCfxFmk7bcdxyHVgpC8Oc0WSRkonGswv7wO5RqBGsm2K4RDDe IzD2UZMzhxUcQ4Rr3oVWF847wrKeNgHgKj/b22KfWOc5xUx3EHnOQh7fa9QZ0bxu+Zzk QM2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778354506; x=1778959306; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=MS6Gmp6sQE6Gv493THZsD+PQMLRdz/0QWUf4zH2ZT5E=; b=YMhf6XJtaiLo1NmpEKZEuOT+cCVrwU7IeNK8TFez2Ueok2KKC5/HJBkb/EnWi37eZo XMIFNbK+rPfioqpVnETGG1SfRlgGaHGyoXT9kIEWqrphTxbpB65iaXGD+Mye/vLH3uHr 3MRzpD5SKBo7WVofuiblX7e7TGSqp8RxUqbvbPOlr5+CZ7PnCj+SensnF8mekFuaLhML jN8gZTblL/SfkK6P22ohD/dwJH9L6yBPiMc4qOibuvXYOLAi8ExHgwYer/JPREzKBJHQ aT+huDKDRiBZ1ApleUCdIDN76TOB2ahkvBpR7OkC2R70LpCDY6jx0BfbzdB45vuxdr+c xmrg== X-Forwarded-Encrypted: i=1; AFNElJ/dlXMZxE6bO3XI0KWC+xVhBPizkd4bnPNIviAm+9Bj/ZCis1p4TUQYsUwKCGQbYHvvk6G/XdatZLMRMdYYJQ==@lists.infradead.org X-Gm-Message-State: AOJu0YxPlDKqjoJuA5rKRrxLjbnZnMcyFKjl8ZekME3iK5RP0cKaclYc rQVczT6OoTRMAluvbCc1fWYGfYYPOvWc/T49cAhcnUSXVR0J9UQCkD+X X-Gm-Gg: Acq92OFbBSt/nll3C4DokoSaQMvAxtiK+ddt4iFPCrNy/MolLDVneT1tbNkgTU8xEix zfRhv4/qX9VpEEqtTVgBBxbsf/yqld95OoPK2aUpV+lzFJzRYadO5K8kyxGf9bETpZHNlVDS8rw KuzTIzHIqdn5ONa0r5VEEZuXX0qWIqWCk6d/K+WKwNKakAIPnKsMtkZwj4BSkqtpx4Ik3UCYKn6 NH4/rQrLnMe/85oawUepsd4Q592G6xor31KfL0YEYs3SVQBER85jcgsjt10jH2i3Ev1/E5V32/S T2MaWOpmz78NZENSvfeygx84lj+L9yqt9Q7CI/ey0qM9lHvued9q15Q+fYrvHjaR02kKnycFXwy 8MWyFjbLqktZN0xIQyPmtEw+f+yR3EtrcWmk2a3ag5hxVml0G8ZDOdRbZhRi8l1tdnsB68Hu4wy 7ulM1uaE1oQ366XMjENad7 X-Received: by 2002:a05:6870:b2c2:b0:42c:711:a235 with SMTP id 586e51a60fabf-434f65ee768mr10899586fac.35.1778354506285; Sat, 09 May 2026 12:21:46 -0700 (PDT) Received: from localhost.localdomain ([2600:1700:fb0:1bc0::54]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-4355736f517sm5243896fac.12.2026.05.09.12.21.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 May 2026 12:21:45 -0700 (PDT) From: Chris Morgan To: linux-iio@vger.kernel.org Cc: andy@kernel.org, nuno.sa@analog.com, dlechner@baylibre.com, jic23@kernel.org, jean-baptiste.maneyrol@tdk.com, linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org, heiko@sntech.de, conor+dt@kernel.org, krzk+dt@kernel.org, robh@kernel.org, andriy.shevchenko@intel.com, Chris Morgan Subject: [PATCH V5 09/11] iio: imu: inv_icm42607: Add Wake on Movement to icm42607 Date: Sat, 9 May 2026 14:19:03 -0500 Message-ID: <20260509191907.24734-10-macroalpha82@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260509191907.24734-1-macroalpha82@gmail.com> References: <20260509191907.24734-1-macroalpha82@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260509_122147_884752_E19F8414 X-CRM114-Status: GOOD ( 22.23 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org RnJvbTogQ2hyaXMgTW9yZ2FuIDxtYWNyb21vcmdhbkBob3RtYWlsLmNvbT4KCkFkZCBzdXBwb3J0 IGZvciB3YWtlIG9uIG1vdmVtZW50IGZvciB0aGUgaWNtNDI2MDcgZHJpdmVyLgoKU2lnbmVkLW9m Zi1ieTogQ2hyaXMgTW9yZ2FuIDxtYWNyb21vcmdhbkBob3RtYWlsLmNvbT4KLS0tCiBkcml2ZXJz L2lpby9pbXUvaW52X2ljbTQyNjA3L2ludl9pY200MjYwNy5oICAgfCAgMTcgKwogLi4uL2lpby9p bXUvaW52X2ljbTQyNjA3L2ludl9pY200MjYwN19hY2NlbC5jIHwgMzAxICsrKysrKysrKysrKysr KysrKwogLi4uL2lpby9pbXUvaW52X2ljbTQyNjA3L2ludl9pY200MjYwN19jb3JlLmMgIHwgMjEz ICsrKysrKysrKysrKy0KIDMgZmlsZXMgY2hhbmdlZCwgNTIxIGluc2VydGlvbnMoKyksIDEwIGRl bGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvaWlvL2ltdS9pbnZfaWNtNDI2MDcvaW52 X2ljbTQyNjA3LmggYi9kcml2ZXJzL2lpby9pbXUvaW52X2ljbTQyNjA3L2ludl9pY200MjYwNy5o CmluZGV4IGNmZGE2MDkwNWQ3MS4uYWI3OWEwNTZmMjhjIDEwMDY0NAotLS0gYS9kcml2ZXJzL2lp by9pbXUvaW52X2ljbTQyNjA3L2ludl9pY200MjYwNy5oCisrKyBiL2RyaXZlcnMvaWlvL2ltdS9p bnZfaWNtNDI2MDcvaW52X2ljbTQyNjA3LmgKQEAgLTExOSw2ICsxMTksMTQgQEAgc3RydWN0IGlu dl9pY200MjYwN19zdXNwZW5kZWQgewogCWJvb2wgdGVtcDsKIH07CiAKK3N0cnVjdCBpbnZfaWNt NDI2MDdfYXBleCB7CisJdW5zaWduZWQgaW50IG9uOworCXN0cnVjdCB7CisJCXU2NCB2YWx1ZTsK KwkJYm9vbCBlbmFibGU7CisJfSB3b207Cit9OworCiAvKioKICAqICBzdHJ1Y3QgaW52X2ljbTQy NjA3X3N0YXRlIC0gZHJpdmVyIHN0YXRlIHZhcmlhYmxlcwogICogIEBsb2NrOgkJbG9jayBmb3Ig c2VyaWFsaXppbmcgbXVsdGlwbGUgcmVnaXN0ZXJzIGFjY2Vzcy4KQEAgLTEzMiw2ICsxNDAsNyBA QCBzdHJ1Y3QgaW52X2ljbTQyNjA3X3N1c3BlbmRlZCB7CiAgKiAgQGluZGlvX2d5cm86CWd5cm9z Y29wZSBJSU8gZGV2aWNlLgogICogIEBpbmRpb19hY2NlbDoJYWNjZWxlcm9tZXRlciBJSU8gZGV2 aWNlLgogICogIEB0aW1lc3RhbXA6ICAgICAgICAgaW50ZXJydXB0IHRpbWVzdGFtcHMuCisgKiAg QGFwZXg6CQlBUEVYIChBZHZhbmNlZCBQZWRvbWV0ZXIgYW5kIEV2ZW50IGRldGVjdGlvbikgbWFu YWdlbWVudAogICogIEBmaWZvOgkJRklGTyBtYW5hZ2VtZW50IHN0cnVjdHVyZS4KICAqICBAYnVm ZmVyOgkJZGF0YSB0cmFuc2ZlciBidWZmZXIgYWxpZ25lZCBmb3IgRE1BLgogICovCkBAIC0xNDks NiArMTU4LDcgQEAgc3RydWN0IGludl9pY200MjYwN19zdGF0ZSB7CiAJc3RydWN0IHsKIAkJczY0 IGFjY2VsOwogCX0gdGltZXN0YW1wOworCXN0cnVjdCBpbnZfaWNtNDI2MDdfYXBleCBhcGV4Owog CXN0cnVjdCBpbnZfaWNtNDI2MDdfZmlmbyBmaWZvOwogCV9fYmUxNiBidWZmZXJbM10gX19hbGln bmVkKElJT19ETUFfTUlOQUxJR04pOwogfTsKQEAgLTQwMSw2ICs0MTEsOSBAQCBpbnQgaW52X2lj bTQyNjA3X3NldF9hY2NlbF9jb25mKHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0LAogaW50 IGludl9pY200MjYwN19zZXRfdGVtcF9jb25mKHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0 LCBib29sIGVuYWJsZSwKIAkJCSAgICAgICB1bnNpZ25lZCBpbnQgKnNsZWVwX21zKTsKIAoraW50 IGludl9pY200MjYwN19lbmFibGVfd29tKHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0KTsK K2ludCBpbnZfaWNtNDI2MDdfZGlzYWJsZV93b20oc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAq c3QpOworCiBpbnQgaW52X2ljbTQyNjA3X2NvcmVfcHJvYmUoc3RydWN0IHJlZ21hcCAqcmVnbWFw LCBjb25zdCBzdHJ1Y3QgaW52X2ljbTQyNjA3X2h3ICpodywKIAkJCSAgICBpbnZfaWNtNDI2MDdf YnVzX3NldHVwIGJ1c19zZXR1cCk7CiAKQEAgLTQwOCw0ICs0MjEsOCBAQCBzdHJ1Y3QgaWlvX2Rl diAqaW52X2ljbTQyNjA3X2FjY2VsX2luaXQoc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3Qp OwogCiBpbnQgaW52X2ljbTQyNjA3X2FjY2VsX3BhcnNlX2ZpZm8oc3RydWN0IGlpb19kZXYgKmlu ZGlvX2Rldik7CiAKK3ZvaWQgaW52X2ljbTQyNjA3X2FjY2VsX2hhbmRsZV9ldmVudHMoc3RydWN0 IGlpb19kZXYgKmluZGlvX2RldiwKKwkJCQkgICAgICB1bnNpZ25lZCBpbnQgc3RhdHVzMiwgdW5z aWduZWQgaW50IHN0YXR1czMsCisJCQkJICAgICAgczY0IHRpbWVzdGFtcCk7CisKICNlbmRpZgpk aWZmIC0tZ2l0IGEvZHJpdmVycy9paW8vaW11L2ludl9pY200MjYwNy9pbnZfaWNtNDI2MDdfYWNj ZWwuYyBiL2RyaXZlcnMvaWlvL2ltdS9pbnZfaWNtNDI2MDcvaW52X2ljbTQyNjA3X2FjY2VsLmMK aW5kZXggZjkwYmE0NmJkN2U0Li45OWFhYTM3MGJkMTIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvaWlv L2ltdS9pbnZfaWNtNDI2MDcvaW52X2ljbTQyNjA3X2FjY2VsLmMKKysrIGIvZHJpdmVycy9paW8v aW11L2ludl9pY200MjYwNy9pbnZfaWNtNDI2MDdfYWNjZWwuYwpAQCAtNjksNiArNjksMTYgQEAg c3RhdGljIGNvbnN0IHN0cnVjdCBpaW9fY2hhbl9zcGVjX2V4dF9pbmZvIGludl9pY200MjYwN19h Y2NlbF9leHRfaW5mb3NbXSA9IHsKIAl7IH0KIH07CiAKKy8qIFdvTSBldmVudDogcmlzaW5nIFJP QyAqLworc3RhdGljIGNvbnN0IHN0cnVjdCBpaW9fZXZlbnRfc3BlYyBpbnZfaWNtNDI2MDdfd29t X2V2ZW50c1tdID0geworCXsKKwkJLnR5cGUgPSBJSU9fRVZfVFlQRV9ST0MsCisJCS5kaXIgPSBJ SU9fRVZfRElSX1JJU0lORywKKwkJLm1hc2tfc2VwYXJhdGUgPSBCSVQoSUlPX0VWX0lORk9fRU5B QkxFKSB8CisJCQkJIEJJVChJSU9fRVZfSU5GT19WQUxVRSksCisJfSwKK307CisKIHN0YXRpYyBj b25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyBpbnZfaWNtNDI2MDdfYWNjZWxfY2hhbm5lbHNbXSA9 IHsKIAlJTlZfSUNNNDI2MDdfQUNDRUxfQ0hBTihJSU9fTU9EX1gsIElOVl9JQ000MjYwN19BQ0NF TF9TQ0FOX1gsCiAJCQkJaW52X2ljbTQyNjA3X2FjY2VsX2V4dF9pbmZvcyksCkBAIC03OCw2ICs4 OCw4IEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyBpbnZfaWNtNDI2MDdfYWNj ZWxfY2hhbm5lbHNbXSA9IHsKIAkJCQlpbnZfaWNtNDI2MDdfYWNjZWxfZXh0X2luZm9zKSwKIAlJ TlZfSUNNNDI2MDdfVEVNUF9DSEFOKElOVl9JQ000MjYwN19BQ0NFTF9TQ0FOX1RFTVApLAogCUlJ T19DSEFOX1NPRlRfVElNRVNUQU1QKElOVl9JQ000MjYwN19BQ0NFTF9TQ0FOX1RJTUVTVEFNUCks CisJSU5WX0lDTTQyNjA3X0FDQ0VMX0VWRU5UX0NIQU4oSUlPX01PRF9YX09SX1lfT1JfWiwgaW52 X2ljbTQyNjA3X3dvbV9ldmVudHMsCisJCQkJICAgICAgQVJSQVlfU0laRShpbnZfaWNtNDI2MDdf d29tX2V2ZW50cykpLAogfTsKIAogc3RhdGljIGNvbnN0IHN0cnVjdCBpaW9fZXZlbnRfc3BlYyBp bnZfaWNtNDI2MDdfbW90aW9uX2V2ZW50c1tdID0gewpAQCAtMjA5LDYgKzIyMSwxNzggQEAgc3Rh dGljIGludCBpbnZfaWNtNDI2MDdfYWNjZWxfcmVhZF9zZW5zb3Ioc3RydWN0IGlpb19kZXYgKmlu ZGlvX2RldiwKIAlyZXR1cm4gMDsKIH0KIAorc3RhdGljIHVuc2lnbmVkIGludCBpbnZfaWNtNDI2 MDdfYWNjZWxfY29udmVydF9yb2NfdG9fd29tKHU2NCByb2MsCisJCQkJCQkJICBpbnQgYWNjZWxf aHosIGludCBhY2NlbF91aHopCit7CisJLyogMTAwMC8yNTZtZyBwZXIgTFNCIGNvbnZlcnRlZCBp biDCtW0vc8KyICovCisJY29uc3QgdW5zaWduZWQgaW50IGNvbnZlcnQgPSAoOTgwN1UgKiAoTUlD Uk8gLyBNSUxMSSkpIC8gMjU2VTsKKwl1NjQgdmFsdWU7CisJdTY0IGZyZXFfdWh6OworCisJLyog cmV0dXJuIDAgb25seSBpZiByb2MgaXMgMCAqLworCWlmIChyb2MgPT0gMCkKKwkJcmV0dXJuIDA7 CisKKwlmcmVxX3VoeiA9ICh1NjQpYWNjZWxfaHogKiBNSUNSTyArICh1NjQpYWNjZWxfdWh6Owor CXZhbHVlID0gZGl2NjRfdTY0KHJvYyAqIE1JQ1JPLCBmcmVxX3VoeiAqICh1NjQpY29udmVydCk7 CisKKwkvKiBsaW1pdCB2YWx1ZSB0byA4IGJpdHMgYW5kIHByZXZlbnQgMCAqLworCXJldHVybiBj bGFtcCh2YWx1ZSwgMSwgMjU1KTsKK30KKworc3RhdGljIHU2NCBpbnZfaWNtNDI2MDdfYWNjZWxf Y29udmVydF93b21fdG9fcm9jKHVuc2lnbmVkIGludCB0aHJlc2hvbGQsCisJCQkJCQkgaW50IGFj Y2VsX2h6LCBpbnQgYWNjZWxfdWh6KQoreworCS8qIDEwMDAvMjU2bWcgcGVyIExTQiBjb252ZXJ0 ZWQgaW4gwrVtL3PCsiAqLworCWNvbnN0IHVuc2lnbmVkIGludCBjb252ZXJ0ID0gKDk4MDdVICog KE1JQ1JPIC8gTUlMTEkpKSAvIDI1NlU7CisJdTY0IHZhbHVlOworCXU2NCBmcmVxX3VoejsKKwor CXZhbHVlID0gdGhyZXNob2xkICogY29udmVydDsKKwlmcmVxX3VoeiA9ICh1NjQpYWNjZWxfaHog KiBNSUNSTyArICh1NjQpYWNjZWxfdWh6OworCisJLyogY29tcHV0ZSB0aGUgZGlmZmVyZW50aWFs IGJ5IG11bHRpcGx5aW5nIGJ5IHRoZSBmcmVxdWVuY3kgKi8KKwlyZXR1cm4gZGl2X3U2NCh2YWx1 ZSAqIGZyZXFfdWh6LCBNSUNSTyk7Cit9CisKK3N0YXRpYyBpbnQgaW52X2ljbTQyNjA3X2FjY2Vs X3NldF93b21fdGhyZXNob2xkKHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0LAorCQkJCQkJ dTY0IHZhbHVlLAorCQkJCQkJaW50IGFjY2VsX2h6LCBpbnQgYWNjZWxfdWh6KQoreworCXVuc2ln bmVkIGludCB0aHJlc2hvbGQ7CisJaW50IHJldDsKKworCS8qIGNvbnZlcnQgcm9jIHRvIHdvbSB0 aHJlc2hvbGQgYW5kIGNvbnZlcnQgYmFjayB0byBoYW5kbGUgY2xpcHBpbmcgKi8KKwl0aHJlc2hv bGQgPSBpbnZfaWNtNDI2MDdfYWNjZWxfY29udmVydF9yb2NfdG9fd29tKHZhbHVlLCBhY2NlbF9o eiwgYWNjZWxfdWh6KTsKKwl2YWx1ZSA9IGludl9pY200MjYwN19hY2NlbF9jb252ZXJ0X3dvbV90 b19yb2ModGhyZXNob2xkLCBhY2NlbF9oeiwgYWNjZWxfdWh6KTsKKworCWRldl9kYmcocmVnbWFw X2dldF9kZXZpY2Uoc3QtPm1hcCksICJ3b21fdGhyZXNob2xkOiAweCV4XG4iLCB0aHJlc2hvbGQp OworCisJLyogc2V0IGFjY2VsIFdvTSB0aHJlc2hvbGQgZm9yIHRoZSAzIGF4ZXMgKi8KKwlzdC0+ YnVmZmVyWzBdID0gdGhyZXNob2xkOworCXN0LT5idWZmZXJbMV0gPSB0aHJlc2hvbGQ7CisJc3Qt PmJ1ZmZlclsyXSA9IHRocmVzaG9sZDsKKwlyZXQgPSByZWdtYXBfYnVsa193cml0ZShzdC0+bWFw LCBJTlZfSUNNNDI2MDdfUkVHX0FDQ0VMX1dPTV9YX1RIUiwgc3QtPmJ1ZmZlciwgMyk7CisJaWYg KHJldCkKKwkJcmV0dXJuIHJldDsKKworCXN0LT5hcGV4LndvbS52YWx1ZSA9IHZhbHVlOworCisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX2ludl9pY200MjYwN19hY2NlbF9lbmFibGVfd29t KHN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYpCit7CisJc3RydWN0IGludl9pY200MjYwN19zdGF0 ZSAqc3QgPSBpaW9fZGV2aWNlX2dldF9kcnZkYXRhKGluZGlvX2Rldik7CisJc3RydWN0IGludl9p Y200MjYwN19zZW5zb3Jfc3RhdGUgKmFjY2VsX3N0ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsKKwlz dHJ1Y3QgaW52X2ljbTQyNjA3X3NlbnNvcl9jb25mIGNvbmYgPSBJTlZfSUNNNDI2MDdfU0VOU09S X0NPTkZfSU5JVDsKKwl1bnNpZ25lZCBpbnQgc2xlZXBfbXMgPSAwOworCWludCByZXQ7CisKKwlz Y29wZWRfZ3VhcmQobXV0ZXgsICZzdC0+bG9jaykgeworCQkvKiB0dXJuIG9uIGFjY2VsIHNlbnNv ciAqLworCQljb25mLm1vZGUgPSBhY2NlbF9zdC0+cG93ZXJfbW9kZTsKKwkJY29uZi5maWx0ZXIg PSBhY2NlbF9zdC0+ZmlsdGVyOworCQlyZXQgPSBpbnZfaWNtNDI2MDdfc2V0X2FjY2VsX2NvbmYo c3QsICZjb25mLCAmc2xlZXBfbXMpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwl9CisK KwlpZiAoc2xlZXBfbXMpCisJCW1zbGVlcChzbGVlcF9tcyk7CisKKwlzY29wZWRfZ3VhcmQobXV0 ZXgsICZzdC0+bG9jaykgeworCQlyZXQgPSBpbnZfaWNtNDI2MDdfZW5hYmxlX3dvbShzdCk7CisJ CWlmIChyZXQpCisJCQlyZXR1cm4gcmV0OworCQlzdC0+YXBleC5vbisrOworCQlzdC0+YXBleC53 b20uZW5hYmxlID0gdHJ1ZTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBpbnZf aWNtNDI2MDdfYWNjZWxfZW5hYmxlX3dvbShzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2KQorewor CXN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0ID0gaWlvX2RldmljZV9nZXRfZHJ2ZGF0YShp bmRpb19kZXYpOworCXN0cnVjdCBkZXZpY2UgKnBkZXYgPSByZWdtYXBfZ2V0X2RldmljZShzdC0+ bWFwKTsKKwlpbnQgcmV0OworCisJcmV0ID0gcG1fcnVudGltZV9yZXN1bWVfYW5kX2dldChwZGV2 KTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJcmV0ID0gX2ludl9pY200MjYwN19hY2Nl bF9lbmFibGVfd29tKGluZGlvX2Rldik7CisJaWYgKHJldCkgeworCQlwbV9ydW50aW1lX3B1dF9h dXRvc3VzcGVuZChwZGV2KTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXR1cm4gMDsKK30KKwor c3RhdGljIGludCBfaW52X2ljbTQyNjA3X2FjY2VsX2Rpc2FibGVfd29tKHN0cnVjdCBpaW9fZGV2 ICppbmRpb19kZXYpCit7CisJc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3QgPSBpaW9fZGV2 aWNlX2dldF9kcnZkYXRhKGluZGlvX2Rldik7CisJc3RydWN0IGludl9pY200MjYwN19zZW5zb3Jf Y29uZiBjb25mID0gSU5WX0lDTTQyNjA3X1NFTlNPUl9DT05GX0lOSVQ7CisJdW5zaWduZWQgaW50 IHNsZWVwX21zID0gMDsKKwlpbnQgcmV0OworCisJc2NvcGVkX2d1YXJkKG11dGV4LCAmc3QtPmxv Y2spIHsKKwkJLyoKKwkJICogQ29uc2lkZXIgdGhhdCB0dXJuaW5nIG9mZiBXb00gaXMgYWx3YXlz IHdvcmtpbmcgdG8gYXZvaWQKKwkJICogYmxvY2tpbmcgdGhlIGNoaXAgaW4gb24gbW9kZSBhbmQg cHJldmVudCBnb2luZyBiYWNrIHRvIHNsZWVwLgorCQkgKiBJZiB0aGVyZSBpcyBhbiBlcnJvciwg dGhlIGNoaXAgd2lsbCBhbnl3YXkgZ28gYmFjayB0byBzbGVlcAorCQkgKiBhbmQgdGhlIGZlYXR1 cmUgd2lsbCBub3Qgd29yayBhbnltb3JlLgorCQkgKi8KKwkJc3QtPmFwZXgud29tLmVuYWJsZSA9 IGZhbHNlOworCQlzdC0+YXBleC5vbi0tOworCQlyZXQgPSBpbnZfaWNtNDI2MDdfZGlzYWJsZV93 b20oc3QpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwkJLyogdHVybiBvZmYgYWNjZWwg c2Vuc29yIGlmIG5vdCB1c2VkICovCisJCWlmICghc3QtPmFwZXgub24gJiYgIWlpb19idWZmZXJf ZW5hYmxlZChpbmRpb19kZXYpKSB7CisJCQljb25mLm1vZGUgPSBJTlZfSUNNNDI2MDdfU0VOU09S X01PREVfT0ZGOworCQkJcmV0ID0gaW52X2ljbTQyNjA3X3NldF9hY2NlbF9jb25mKHN0LCAmY29u ZiwgJnNsZWVwX21zKTsKKwkJCWlmIChyZXQpCisJCQkJcmV0dXJuIHJldDsKKwkJfQorCX0KKwor CWlmIChzbGVlcF9tcykKKwkJbXNsZWVwKHNsZWVwX21zKTsKKworCXJldHVybiAwOworfQorCitz dGF0aWMgaW50IGludl9pY200MjYwN19hY2NlbF9kaXNhYmxlX3dvbShzdHJ1Y3QgaWlvX2RldiAq aW5kaW9fZGV2KQoreworCXN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0ID0gaWlvX2Rldmlj ZV9nZXRfZHJ2ZGF0YShpbmRpb19kZXYpOworCXN0cnVjdCBkZXZpY2UgKnBkZXYgPSByZWdtYXBf Z2V0X2RldmljZShzdC0+bWFwKTsKKwlpbnQgcmV0OworCisJcmV0ID0gX2ludl9pY200MjYwN19h Y2NlbF9kaXNhYmxlX3dvbShpbmRpb19kZXYpOworCisJcG1fcnVudGltZV9wdXRfYXV0b3N1c3Bl bmQocGRldik7CisKKwlyZXR1cm4gcmV0OworfQorCit2b2lkIGludl9pY200MjYwN19hY2NlbF9o YW5kbGVfZXZlbnRzKHN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYsCisJCQkJICAgICAgdW5zaWdu ZWQgaW50IHN0YXR1czIsIHVuc2lnbmVkIGludCBzdGF0dXMzLAorCQkJCSAgICAgIHM2NCB0aW1l c3RhbXApCit7CisJc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3QgPSBpaW9fZGV2aWNlX2dl dF9kcnZkYXRhKGluZGlvX2Rldik7CisJdTY0IGV2X2NvZGU7CisKKwkvKiBoYW5kbGUgV29NIGV2 ZW50ICovCisJaWYgKHN0LT5hcGV4LndvbS5lbmFibGUgJiYgKHN0YXR1czIgJiBJTlZfSUNNNDI2 MDdfSU5UX1NUQVRVUzJfV09NX0lOVCkpIHsKKwkJZXZfY29kZSA9IElJT19NT0RfRVZFTlRfQ09E RShJSU9fQUNDRUwsIDAsIElJT19NT0RfWF9PUl9ZX09SX1osCisJCQkJCSAgICAgSUlPX0VWX1RZ UEVfUk9DLCBJSU9fRVZfRElSX1JJU0lORyk7CisJCWlpb19wdXNoX2V2ZW50KGluZGlvX2Rldiwg ZXZfY29kZSwgdGltZXN0YW1wKTsKKwl9Cit9CisKIHN0YXRpYyBjb25zdCBpbnQgaW52X2ljbTQy NjA3X2FjY2VsX3NjYWxlX25hbm9bXVsyXSA9IHsKIAlbSU5WX0lDTTQyNjA3X0FDQ0VMX0ZTXzE2 R10gPSB7IDAsIDQ3ODg0MDMgfSwKIAlbSU5WX0lDTTQyNjA3X0FDQ0VMX0ZTXzhHXSA9IHsgMCwg MjM5NDIwMiB9LApAQCAtMzI5LDYgKzUxMywxMCBAQCBzdGF0aWMgaW50IGludl9pY200MjYwN19h Y2NlbF93cml0ZV9vZHIoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwKIAlpZiAocmV0KQogCQly ZXR1cm4gcmV0OwogCisJcmV0ID0gaW52X2ljbTQyNjA3X2FjY2VsX3NldF93b21fdGhyZXNob2xk KHN0LCBzdC0+YXBleC53b20udmFsdWUsIHZhbCwgdmFsMik7CisJaWYgKHJldCkKKwkJcmV0dXJu IHJldDsKKwogCWludl9pY200MjYwN19idWZmZXJfdXBkYXRlX2ZpZm9fcGVyaW9kKHN0KTsKIAlp bnZfaWNtNDI2MDdfYnVmZmVyX3VwZGF0ZV93YXRlcm1hcmsoc3QpOwogCkBAIC00NjcsNiArNjU1 LDExNSBAQCBzdGF0aWMgaW50IGludl9pY200MjYwN19hY2NlbF9od2ZpZm9fZmx1c2goc3RydWN0 IGlpb19kZXYgKmluZGlvX2RldiwKIAlyZXR1cm4gc3QtPmZpZm8ubmIuYWNjZWw7CiB9CiAKK3N0 YXRpYyBpbnQgaW52X2ljbTQyNjA3X2FjY2VsX3JlYWRfZXZlbnRfY29uZmlnKHN0cnVjdCBpaW9f ZGV2ICppbmRpb19kZXYsCisJCQkJCQljb25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyAqY2hhbiwK KwkJCQkJCWVudW0gaWlvX2V2ZW50X3R5cGUgdHlwZSwKKwkJCQkJCWVudW0gaWlvX2V2ZW50X2Rp cmVjdGlvbiBkaXIpCit7CisJc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3QgPSBpaW9fZGV2 aWNlX2dldF9kcnZkYXRhKGluZGlvX2Rldik7CisKKwkvKiBoYW5kbGUgb25seSBXb00gKHJvYyBy aXNpbmcpIGV2ZW50ICovCisJaWYgKHR5cGUgIT0gSUlPX0VWX1RZUEVfUk9DIHx8IGRpciAhPSBJ SU9fRVZfRElSX1JJU0lORykKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlndWFyZChtdXRleCkoJnN0 LT5sb2NrKTsKKworCXJldHVybiBzdC0+YXBleC53b20uZW5hYmxlID8gMSA6IDA7Cit9CisKK3N0 YXRpYyBpbnQgaW52X2ljbTQyNjA3X2FjY2VsX3dyaXRlX2V2ZW50X2NvbmZpZyhzdHJ1Y3QgaWlv X2RldiAqaW5kaW9fZGV2LAorCQkJCQkJIGNvbnN0IHN0cnVjdCBpaW9fY2hhbl9zcGVjICpjaGFu LAorCQkJCQkJIGVudW0gaWlvX2V2ZW50X3R5cGUgdHlwZSwKKwkJCQkJCSBlbnVtIGlpb19ldmVu dF9kaXJlY3Rpb24gZGlyLAorCQkJCQkJIGJvb2wgc3RhdGUpCit7CisJc3RydWN0IGludl9pY200 MjYwN19zdGF0ZSAqc3QgPSBpaW9fZGV2aWNlX2dldF9kcnZkYXRhKGluZGlvX2Rldik7CisKKwkv KiBoYW5kbGUgb25seSBXb00gKHJvYyByaXNpbmcpIGV2ZW50ICovCisJaWYgKHR5cGUgIT0gSUlP X0VWX1RZUEVfUk9DIHx8IGRpciAhPSBJSU9fRVZfRElSX1JJU0lORykKKwkJcmV0dXJuIC1FSU5W QUw7CisKKwlzY29wZWRfZ3VhcmQobXV0ZXgsICZzdC0+bG9jaykgeworCQlpZiAoc3QtPmFwZXgu d29tLmVuYWJsZSA9PSBzdGF0ZSkKKwkJCXJldHVybiAwOworCisJaWYgKHN0YXRlKQorCQlyZXR1 cm4gaW52X2ljbTQyNjA3X2FjY2VsX2VuYWJsZV93b20oaW5kaW9fZGV2KTsKKwl9CisKKwlyZXR1 cm4gaW52X2ljbTQyNjA3X2FjY2VsX2Rpc2FibGVfd29tKGluZGlvX2Rldik7Cit9CisKK3N0YXRp YyBpbnQgaW52X2ljbTQyNjA3X2FjY2VsX3JlYWRfZXZlbnRfdmFsdWUoc3RydWN0IGlpb19kZXYg KmluZGlvX2RldiwKKwkJCQkJICAgICAgIGNvbnN0IHN0cnVjdCBpaW9fY2hhbl9zcGVjICpjaGFu LAorCQkJCQkgICAgICAgZW51bSBpaW9fZXZlbnRfdHlwZSB0eXBlLAorCQkJCQkgICAgICAgZW51 bSBpaW9fZXZlbnRfZGlyZWN0aW9uIGRpciwKKwkJCQkJICAgICAgIGVudW0gaWlvX2V2ZW50X2lu Zm8gaW5mbywKKwkJCQkJICAgICAgIGludCAqdmFsLCBpbnQgKnZhbDIpCit7CisJc3RydWN0IGlu dl9pY200MjYwN19zdGF0ZSAqc3QgPSBpaW9fZGV2aWNlX2dldF9kcnZkYXRhKGluZGlvX2Rldik7 CisJdTMyIHJlbTsKKworCS8qIGhhbmRsZSBvbmx5IFdvTSAocm9jIHJpc2luZykgZXZlbnQgdmFs dWUgKi8KKwlpZiAodHlwZSAhPSBJSU9fRVZfVFlQRV9ST0MgfHwgZGlyICE9IElJT19FVl9ESVJf UklTSU5HKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWd1YXJkKG11dGV4KSgmc3QtPmxvY2spOwor CisJLyogcmV0dXJuIHZhbHVlIGluIG1pY3JvICovCisJKnZhbCA9IGRpdl91NjRfcmVtKHN0LT5h cGV4LndvbS52YWx1ZSwgTUlDUk8sICZyZW0pOworCSp2YWwyID0gcmVtOworCXJldHVybiBJSU9f VkFMX0lOVF9QTFVTX01JQ1JPOworfQorCitzdGF0aWMgaW50IF9pbnZfaWNtNDI2MDdfYWNjZWxf d29tX3ZhbHVlKHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0LAorCQkJCQkgaW50IHZhbCwg aW50IHZhbDIpCit7CisJdTY0IHZhbHVlOworCXVuc2lnbmVkIGludCBhY2NlbF9oeiwgYWNjZWxf dWh6OworCWludCByZXQ7CisKKwlndWFyZChtdXRleCkoJnN0LT5sb2NrKTsKKworCXJldCA9IGlu dl9pY200MjYwN19hY2NlbF9yZWFkX29kcihzdCwgJmFjY2VsX2h6LCAmYWNjZWxfdWh6KTsKKwlp ZiAocmV0IDwgMCkKKwkJcmV0dXJuIHJldDsKKworCXZhbHVlID0gKHU2NCl2YWwgKiBNSUNSTyAr ICh1NjQpdmFsMjsKKworCXJldHVybiBpbnZfaWNtNDI2MDdfYWNjZWxfc2V0X3dvbV90aHJlc2hv bGQoc3QsIHZhbHVlLAorCQkJCQkJICAgIGFjY2VsX2h6LCBhY2NlbF91aHopOworfQorCitzdGF0 aWMgaW50IGludl9pY200MjYwN19hY2NlbF93cml0ZV9ldmVudF92YWx1ZShzdHJ1Y3QgaWlvX2Rl diAqaW5kaW9fZGV2LAorCQkJCQkJY29uc3Qgc3RydWN0IGlpb19jaGFuX3NwZWMgKmNoYW4sCisJ CQkJCQllbnVtIGlpb19ldmVudF90eXBlIHR5cGUsCisJCQkJCQllbnVtIGlpb19ldmVudF9kaXJl Y3Rpb24gZGlyLAorCQkJCQkJZW51bSBpaW9fZXZlbnRfaW5mbyBpbmZvLAorCQkJCQkJaW50IHZh bCwgaW50IHZhbDIpCit7CisJc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3QgPSBpaW9fZGV2 aWNlX2dldF9kcnZkYXRhKGluZGlvX2Rldik7CisJc3RydWN0IGRldmljZSAqZGV2ID0gcmVnbWFw X2dldF9kZXZpY2Uoc3QtPm1hcCk7CisJaW50IHJldDsKKworCS8qIGhhbmRsZSBvbmx5IFdvTSAo cm9jIHJpc2luZykgZXZlbnQgdmFsdWUgKi8KKwlpZiAodHlwZSAhPSBJSU9fRVZfVFlQRV9ST0Mg fHwgZGlyICE9IElJT19FVl9ESVJfUklTSU5HKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWlmICh2 YWwgPCAwIHx8IHZhbDIgPCAwKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCXJldCA9IHBtX3J1bnRp bWVfcmVzdW1lX2FuZF9nZXQoZGV2KTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJcmV0 ID0gX2ludl9pY200MjYwN19hY2NlbF93b21fdmFsdWUoc3QsIHZhbCwgdmFsMik7CisKKwlwbV9y dW50aW1lX3B1dF9hdXRvc3VzcGVuZChkZXYpOworCisJcmV0dXJuIHJldDsKK30KKwogc3RhdGlj IGNvbnN0IHN0cnVjdCBpaW9faW5mbyBpbnZfaWNtNDI2MDdfYWNjZWxfaW5mbyA9IHsKIAkucmVh ZF9yYXcgPSBpbnZfaWNtNDI2MDdfYWNjZWxfcmVhZF9yYXcsCiAJLnJlYWRfYXZhaWwgPSBpbnZf aWNtNDI2MDdfYWNjZWxfcmVhZF9hdmFpbCwKQEAgLTQ3NSw2ICs3NzIsMTAgQEAgc3RhdGljIGNv bnN0IHN0cnVjdCBpaW9faW5mbyBpbnZfaWNtNDI2MDdfYWNjZWxfaW5mbyA9IHsKIAkudXBkYXRl X3NjYW5fbW9kZSA9IGludl9pY200MjYwN19hY2NlbF91cGRhdGVfc2Nhbl9tb2RlLAogCS5od2Zp Zm9fc2V0X3dhdGVybWFyayA9IGludl9pY200MjYwN19hY2NlbF9od2ZpZm9fc2V0X3dhdGVybWFy aywKIAkuaHdmaWZvX2ZsdXNoX3RvX2J1ZmZlciA9IGludl9pY200MjYwN19hY2NlbF9od2ZpZm9f Zmx1c2gsCisJLnJlYWRfZXZlbnRfY29uZmlnID0gaW52X2ljbTQyNjA3X2FjY2VsX3JlYWRfZXZl bnRfY29uZmlnLAorCS53cml0ZV9ldmVudF9jb25maWcgPSBpbnZfaWNtNDI2MDdfYWNjZWxfd3Jp dGVfZXZlbnRfY29uZmlnLAorCS5yZWFkX2V2ZW50X3ZhbHVlID0gaW52X2ljbTQyNjA3X2FjY2Vs X3JlYWRfZXZlbnRfdmFsdWUsCisJLndyaXRlX2V2ZW50X3ZhbHVlID0gaW52X2ljbTQyNjA3X2Fj Y2VsX3dyaXRlX2V2ZW50X3ZhbHVlLAogfTsKIAogc3RydWN0IGlpb19kZXYgKmludl9pY200MjYw N19hY2NlbF9pbml0KHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0KQpkaWZmIC0tZ2l0IGEv ZHJpdmVycy9paW8vaW11L2ludl9pY200MjYwNy9pbnZfaWNtNDI2MDdfY29yZS5jIGIvZHJpdmVy cy9paW8vaW11L2ludl9pY200MjYwNy9pbnZfaWNtNDI2MDdfY29yZS5jCmluZGV4IGNlNTlmOTMz N2VkOS4uZTVkMDMxY2E2MzFkIDEwMDY0NAotLS0gYS9kcml2ZXJzL2lpby9pbXUvaW52X2ljbTQy NjA3L2ludl9pY200MjYwN19jb3JlLmMKKysrIGIvZHJpdmVycy9paW8vaW11L2ludl9pY200MjYw Ny9pbnZfaWNtNDI2MDdfY29yZS5jCkBAIC0yMzMsNiArMjMzLDM4IEBAIGludCBpbnZfaWNtNDI2 MDdfc2V0X3RlbXBfY29uZihzdHJ1Y3QgaW52X2ljbTQyNjA3X3N0YXRlICpzdCwgYm9vbCBlbmFi bGUsCiAJCQkJCSAgc2xlZXBfbXMpOwogfQogCitpbnQgaW52X2ljbTQyNjA3X2VuYWJsZV93b20o c3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3QpCit7CisJaW50IHJldDsKKworCS8qIGVuYWJs ZSBXb00gaGFyZHdhcmUgKi8KKwlyZXQgPSByZWdtYXBfd3JpdGUoc3QtPm1hcCwgSU5WX0lDTTQy NjA3X1JFR19XT01fQ09ORklHLAorCQkJICAgRklFTERfUFJFUChJTlZfSUNNNDI2MDdfV09NX0NP TkZJR19JTlRfRFVSX01BU0ssIDEpIHwKKwkJCSAgIElOVl9JQ000MjYwN19XT01fQ09ORklHX01P REUgfAorCQkJICAgSU5WX0lDTTQyNjA3X1dPTV9DT05GSUdfRU4pOworCWlmIChyZXQpCisJCXJl dHVybiByZXQ7CisKKwkvKiBlbmFibGUgV29NIGludGVycnVwdCAqLworCXJldHVybiByZWdtYXBf c2V0X2JpdHMoc3QtPm1hcCwgSU5WX0lDTTQyNjA3X1JFR19JTlRfU09VUkNFMSwKKwkJCSAgICAg ICBJTlZfSUNNNDI2MDdfSU5UX1NPVVJDRTFfV09NX0lOVDFfRU4pOworfQorCitpbnQgaW52X2lj bTQyNjA3X2Rpc2FibGVfd29tKHN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0KQoreworCWlu dCByZXQ7CisKKwkvKiBkaXNhYmxlIFdvTSBpbnRlcnJ1cHQgKi8KKwlyZXQgPSByZWdtYXBfY2xl YXJfYml0cyhzdC0+bWFwLCBJTlZfSUNNNDI2MDdfUkVHX0lOVF9TT1VSQ0UxLAorCQkJCUlOVl9J Q000MjYwN19JTlRfU09VUkNFMV9XT01fSU5UMV9FTik7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJl dDsKKworCS8qIGRpc2FibGUgV29NIGhhcmR3YXJlICovCisJcmV0dXJuIHJlZ21hcF9jbGVhcl9i aXRzKHN0LT5tYXAsIElOVl9JQ000MjYwN19SRUdfV09NX0NPTkZJRywKKwkJCQkgSU5WX0lDTTQy NjA3X1dPTV9DT05GSUdfRU4pOworfQorCiBzdGF0aWMgaW50IGludl9pY200MjYwN19zZXRfY29u ZihzdHJ1Y3QgaW52X2ljbTQyNjA3X3N0YXRlICpzdCwKIAkJCQkgY29uc3Qgc3RydWN0IGludl9p Y200MjYwN19jb25mICpjb25mKQogewpAQCAtMzQzLDYgKzM3NSwxMTIgQEAgc3RhdGljIGludCBp bnZfaWNtNDI2MDdfc2V0dXAoc3RydWN0IGludl9pY200MjYwN19zdGF0ZSAqc3QsCiAJcmV0dXJu IGludl9pY200MjYwN19zZXRfY29uZihzdCwgc3QtPmh3LT5jb25mKTsKIH0KIAorc3RhdGljIGly cXJldHVybl90IGludl9pY200MjYwN19pcnFfdGltZXN0YW1wKGludCBpcnEsIHZvaWQgKl9kYXRh KQoreworCXN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0ID0gX2RhdGE7CisKKwlzdC0+dGlt ZXN0YW1wLmFjY2VsID0gaWlvX2dldF90aW1lX25zKHN0LT5pbmRpb19hY2NlbCk7CisKKwlyZXR1 cm4gSVJRX1dBS0VfVEhSRUFEOworfQorCitzdGF0aWMgaXJxcmV0dXJuX3QgaW52X2ljbTQyNjA3 X2lycV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKl9kYXRhKQoreworCXN0cnVjdCBpbnZfaWNtNDI2 MDdfc3RhdGUgKnN0ID0gX2RhdGE7CisJc3RydWN0IGRldmljZSAqZGV2ID0gcmVnbWFwX2dldF9k ZXZpY2Uoc3QtPm1hcCk7CisJdW5zaWduZWQgaW50IHN0YXR1czsKKwlpbnQgcmV0OworCisJZ3Vh cmQobXV0ZXgpKCZzdC0+bG9jayk7CisKKwlpZiAoc3QtPmFwZXgub24pIHsKKwkJdW5zaWduZWQg aW50IHN0YXR1czIsIHN0YXR1czM7CisKKwkJLyogcmVhZCBJTlRfU1RBVFVTMiBhbmQgSU5UX1NU QVRVUzMgaW4gMSBvcGVyYXRpb24gKi8KKwkJcmV0ID0gcmVnbWFwX2J1bGtfcmVhZChzdC0+bWFw LCBJTlZfSUNNNDI2MDdfUkVHX0lOVF9TVEFUVVMyLCBzdC0+YnVmZmVyLCAyKTsKKwkJaWYgKHJl dCkgeworCQkJZGV2X2VycihkZXYsICJJbnRlcnJ1cHQgc3RhdHVzIHJlYWQgZXJyb3IgJWRcbiIs IHJldCk7CisJCQlyZXR1cm4gSVJRX0hBTkRMRUQ7CisJCX0KKworCQlzdGF0dXMyID0gc3QtPmJ1 ZmZlclswXTsKKwkJc3RhdHVzMyA9IHN0LT5idWZmZXJbMV07CisJCWludl9pY200MjYwN19hY2Nl bF9oYW5kbGVfZXZlbnRzKHN0LT5pbmRpb19hY2NlbCwgc3RhdHVzMiwgc3RhdHVzMywKKwkJCQkJ CSBzdC0+dGltZXN0YW1wLmFjY2VsKTsKKwl9CisKKwlyZXQgPSByZWdtYXBfcmVhZChzdC0+bWFw LCBJTlZfSUNNNDI2MDdfUkVHX0lOVF9TVEFUVVMsICZzdGF0dXMpOworCWlmIChyZXQpIHsKKwkJ ZGV2X2VycihkZXYsICJJbnRlcnJ1dCBzdGF0dXMgcmVhZCBlcnJvciAlZFxuIiwgcmV0KTsKKwkJ cmV0dXJuIElSUV9IQU5ETEVEOworCX0KKworCWlmIChzdGF0dXMgJiBJTlZfSUNNNDI2MDdfSU5U X1NUQVRVU19GSUZPX0ZVTEwpCisJCWRldl93YXJuKGRldiwgIkZJRk8gZnVsbCBkYXRhIGxvc3Qh XG4iKTsKKworCWlmIChzdGF0dXMgJiBJTlZfSUNNNDI2MDdfSU5UX1NUQVRVU19GSUZPX1RIUykg eworCQlyZXQgPSBpbnZfaWNtNDI2MDdfYnVmZmVyX2ZpZm9fcmVhZChzdCwgMCk7CisJCWlmIChy ZXQpIHsKKwkJCWRldl9lcnIoZGV2LCAiRklGTyByZWFkIGVycm9yICVkXG4iLCByZXQpOworCQkJ cmV0dXJuIElSUV9IQU5ETEVEOworCQl9CisKKwkJcmV0ID0gaW52X2ljbTQyNjA3X2J1ZmZlcl9m aWZvX3BhcnNlKHN0KTsKKwkJaWYgKHJldCkKKwkJCWRldl9lcnIoZGV2LCAiRklGTyBwYXJzaW5n IGVycm9yICVkXG4iLCByZXQpOworCX0KKworCXJldHVybiBJUlFfSEFORExFRDsKK30KKworLyoq CisgKiBpbnZfaWNtNDI2MDdfaXJxX2luaXQoKSAtIGluaXRpYWxpemUgaW50IHBpbiBhbmQgaW50 ZXJydXB0IGhhbmRsZXIKKyAqIEBzdDoJCWRyaXZlciBpbnRlcm5hbCBzdGF0ZQorICogQGlycToJ aXJxIG51bWJlcgorICogQGlycV90eXBlOglpcnEgdHJpZ2dlciB0eXBlCisgKiBAb3Blbl9kcmFp bjoJdHJ1ZSBpZiBpcnEgaXMgb3BlbiBkcmFpbiwgZmFsc2UgZm9yIHB1c2gtcHVsbAorICoKKyAq IFJldHVybnMgMCBvbiBzdWNjZXNzLCBhIG5lZ2F0aXZlIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgor ICovCitzdGF0aWMgaW50IGludl9pY200MjYwN19pcnFfaW5pdChzdHJ1Y3QgaW52X2ljbTQyNjA3 X3N0YXRlICpzdCwgaW50IGlycSwKKwkJCQlpbnQgaXJxX3R5cGUsIGJvb2wgb3Blbl9kcmFpbikK K3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSByZWdtYXBfZ2V0X2RldmljZShzdC0+bWFwKTsKKwl1 bnNpZ25lZCBpbnQgdmFsID0gMDsKKwlpbnQgcmV0OworCisJc3dpdGNoIChpcnFfdHlwZSkgewor CWNhc2UgSVJRRl9UUklHR0VSX1JJU0lORzoKKwljYXNlIElSUUZfVFJJR0dFUl9ISUdIOgorCQl2 YWwgPSBJTlZfSUNNNDI2MDdfSU5UX0NPTkZJR19JTlQxX0FDVElWRV9ISUdIOworCQlicmVhazsK KwlkZWZhdWx0OgorCQl2YWwgPSBJTlZfSUNNNDI2MDdfSU5UX0NPTkZJR19JTlQxX0FDVElWRV9M T1c7CisJCWJyZWFrOworCX0KKworCXN3aXRjaCAoaXJxX3R5cGUpIHsKKwljYXNlIElSUUZfVFJJ R0dFUl9MT1c6CisJY2FzZSBJUlFGX1RSSUdHRVJfSElHSDoKKwkJdmFsIHw9IElOVl9JQ000MjYw N19JTlRfQ09ORklHX0lOVDFfTEFUQ0hFRDsKKwkJYnJlYWs7CisJZGVmYXVsdDoKKwkJYnJlYWs7 CisJfQorCisJaWYgKCFvcGVuX2RyYWluKQorCQl2YWwgfD0gSU5WX0lDTTQyNjA3X0lOVF9DT05G SUdfSU5UMV9QVVNIX1BVTEw7CisKKwlyZXQgPSByZWdtYXBfd3JpdGUoc3QtPm1hcCwgSU5WX0lD TTQyNjA3X1JFR19JTlRfQ09ORklHLCB2YWwpOworCWlmIChyZXQpCisJCXJldHVybiByZXQ7CisK KwlpcnFfdHlwZSB8PSBJUlFGX09ORVNIT1Q7CisJcmV0dXJuIGRldm1fcmVxdWVzdF90aHJlYWRl ZF9pcnEoZGV2LCBpcnEsIGludl9pY200MjYwN19pcnFfdGltZXN0YW1wLAorCQkJCQkgaW52X2lj bTQyNjA3X2lycV9oYW5kbGVyLCBpcnFfdHlwZSwKKwkJCQkJIHN0LT5ody0+bmFtZSwgc3QpOwor fQorCiBzdGF0aWMgaW50IGludl9pY200MjYwN19lbmFibGVfdmRkaW9fcmVnKHN0cnVjdCBpbnZf aWNtNDI2MDdfc3RhdGUgKnN0KQogewogCWludCByZXQ7CkBAIC0zNzEsMTMgKzUwOSwxOCBAQCBp bnQgaW52X2ljbTQyNjA3X2NvcmVfcHJvYmUoc3RydWN0IHJlZ21hcCAqcmVnbWFwLCBjb25zdCBz dHJ1Y3QgaW52X2ljbTQyNjA3X2h3CiAJc3RydWN0IGRldmljZSAqZGV2ID0gcmVnbWFwX2dldF9k ZXZpY2UocmVnbWFwKTsKIAlzdHJ1Y3QgZndub2RlX2hhbmRsZSAqZndub2RlID0gZGV2X2Z3bm9k ZShkZXYpOwogCXN0cnVjdCBpbnZfaWNtNDI2MDdfc3RhdGUgKnN0OwotCWludCBpcnE7CisJaW50 IGlycSwgaXJxX3R5cGU7CisJYm9vbCBvcGVuX2RyYWluOwogCWludCByZXQ7CiAKIAlpcnEgPSBm d25vZGVfaXJxX2dldF9ieW5hbWUoZndub2RlLCAiSU5UMSIpOwogCWlmIChpcnEgPCAwKQogCQly ZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIGlycSwgImVycm9yIG1pc3NpbmcgSU5UMSBpbnRlcnJ1 cHRcbiIpOwogCisJaXJxX3R5cGUgPSBpcnFfZ2V0X3RyaWdnZXJfdHlwZShpcnEpOworCisJb3Bl bl9kcmFpbiA9IGRldmljZV9wcm9wZXJ0eV9yZWFkX2Jvb2woZGV2LCAiZHJpdmUtb3Blbi1kcmFp biIpOworCiAJc3QgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKnN0KSwgR0ZQX0tFUk5FTCk7 CiAJaWYgKCFzdCkKIAkJcmV0dXJuIC1FTk9NRU07CkBAIC00MzcsNiArNTgwLDExIEBAIGludCBp bnZfaWNtNDI2MDdfY29yZV9wcm9iZShzdHJ1Y3QgcmVnbWFwICpyZWdtYXAsIGNvbnN0IHN0cnVj dCBpbnZfaWNtNDI2MDdfaHcKIAlpZiAoSVNfRVJSKHN0LT5pbmRpb19hY2NlbCkpCiAJCXJldHVy biBQVFJfRVJSKHN0LT5pbmRpb19hY2NlbCk7CiAKKwkvKiBJbml0aWFsaXplIGludGVycnVwdCBo YW5kbGluZyAqLworCXJldCA9IGludl9pY200MjYwN19pcnFfaW5pdChzdCwgaXJxLCBpcnFfdHlw ZSwgb3Blbl9kcmFpbik7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJldDsKKwogCXJldHVybiAwOwog fQogRVhQT1JUX1NZTUJPTF9OU19HUEwoaW52X2ljbTQyNjA3X2NvcmVfcHJvYmUsICJJSU9fSUNN NDI2MDciKTsKQEAgLTQ0OCw2ICs1OTYsOSBAQCBFWFBPUlRfU1lNQk9MX05TX0dQTChpbnZfaWNt NDI2MDdfY29yZV9wcm9iZSwgIklJT19JQ000MjYwNyIpOwogc3RhdGljIGludCBpbnZfaWNtNDI2 MDdfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCiB7CiAJc3RydWN0IGludl9pY200MjYwN19z dGF0ZSAqc3QgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKwlzdHJ1Y3QgZGV2aWNlICphY2NlbF9k ZXY7CisJYm9vbCB3YWtldXA7CisJaW50IGFjY2VsX2NvbmY7CiAJaW50IHJldDsKIAogCWd1YXJk KG11dGV4KSgmc3QtPmxvY2spOwpAQCAtNDY0LDEyICs2MTUsMzYgQEAgc3RhdGljIGludCBpbnZf aWNtNDI2MDdfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCiAJCQlyZXR1cm4gcmV0OwogCX0K IAotCXJldCA9IGludl9pY200MjYwN19zZXRfcHdyX21nbXQwKHN0LCBJTlZfSUNNNDI2MDdfU0VO U09SX01PREVfT0ZGLAotCQkJCQkgSU5WX0lDTTQyNjA3X1NFTlNPUl9NT0RFX09GRiwKLQkJCQkJ IGZhbHNlLCBOVUxMKTsKLQlpZiAocmV0KQotCQlyZXR1cm4gcmV0OwotCXJlZ3VsYXRvcl9kaXNh YmxlKHN0LT52ZGRpb19zdXBwbHkpOworCS8qIGtlZXAgY2hpcCBvbiBhbmQgd2FrZS11cCBjYXBh YmxlIGlmIEFQRVggYW5kIHdha2V1cCBvbiAqLworCWFjY2VsX2RldiA9ICZzdC0+aW5kaW9fYWNj ZWwtPmRldjsKKwl3YWtldXAgPSBzdC0+YXBleC5vbiAmJiBkZXZpY2VfbWF5X3dha2V1cChhY2Nl bF9kZXYpOworCWlmICh3YWtldXApIHsKKwkJLyoga2VlcCBhY2NlbCBvbiBhbmQgc2V0dXAgaXJx IGZvciB3YWtldXAgKi8KKwkJYWNjZWxfY29uZiA9IHN0LT5jb25mLmFjY2VsLm1vZGU7CisJCWVu YWJsZV9pcnFfd2FrZShzdC0+aXJxKTsKKwkJZGlzYWJsZV9pcnEoc3QtPmlycSk7CisJCXJldCA9 IGludl9pY200MjYwN19zZXRfcHdyX21nbXQwKHN0LCBJTlZfSUNNNDI2MDdfU0VOU09SX01PREVf T0ZGLAorCQkJCQkJIGFjY2VsX2NvbmYsIGZhbHNlLCBOVUxMKTsKKwkJaWYgKHJldCkgeworCQkJ ZW5hYmxlX2lycShzdC0+aXJxKTsKKwkJCWRpc2FibGVfaXJxX3dha2Uoc3QtPmlycSk7CisJCQly ZXR1cm4gcmV0OworCQl9CisJfSBlbHNlIHsKKwkJLyogZGlzYWJsZSBBUEVYIGZlYXR1cmVzIGFu ZCBhY2NlbCBpZiB3YWtldXAgZGlzYWJsZWQgKi8KKwkJaWYgKHN0LT5hcGV4LndvbS5lbmFibGUp IHsKKwkJCXJldCA9IGludl9pY200MjYwN19kaXNhYmxlX3dvbShzdCk7CisJCQlpZiAocmV0KQor CQkJCXJldHVybiByZXQ7CisJCX0KKwkJYWNjZWxfY29uZiA9IElOVl9JQ000MjYwN19TRU5TT1Jf TU9ERV9PRkY7CisJCXJldCA9IGludl9pY200MjYwN19zZXRfcHdyX21nbXQwKHN0LCBJTlZfSUNN NDI2MDdfU0VOU09SX01PREVfT0ZGLAorCQkJCQkJIElOVl9JQ000MjYwN19TRU5TT1JfTU9ERV9P RkYsCisJCQkJCQkgZmFsc2UsIE5VTEwpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwkJ cmVndWxhdG9yX2Rpc2FibGUoc3QtPnZkZGlvX3N1cHBseSk7CisJfQogCiAJcmV0dXJuIDA7CiB9 CkBAIC00ODIsNiArNjU3LDggQEAgc3RhdGljIGludCBpbnZfaWNtNDI2MDdfcmVzdW1lKHN0cnVj dCBkZXZpY2UgKmRldikKIHsKIAlzdHJ1Y3QgaW52X2ljbTQyNjA3X3N0YXRlICpzdCA9IGRldl9n ZXRfZHJ2ZGF0YShkZXYpOwogCXN0cnVjdCBpbnZfaWNtNDI2MDdfc2Vuc29yX3N0YXRlICphY2Nl bF9zdCA9IGlpb19wcml2KHN0LT5pbmRpb19hY2NlbCk7CisJc3RydWN0IGRldmljZSAqYWNjZWxf ZGV2OworCWJvb2wgd2FrZXVwOwogCWludCByZXQ7CiAKIAlndWFyZChtdXRleCkoJnN0LT5sb2Nr KTsKQEAgLTQ4OSw5ICs2NjYsMTggQEAgc3RhdGljIGludCBpbnZfaWNtNDI2MDdfcmVzdW1lKHN0 cnVjdCBkZXZpY2UgKmRldikKIAlpZiAocG1fcnVudGltZV9zdXNwZW5kZWQoZGV2KSkKIAkJcmV0 dXJuIDA7CiAKLQlyZXQgPSBpbnZfaWNtNDI2MDdfZW5hYmxlX3ZkZGlvX3JlZyhzdCk7Ci0JaWYg KHJldCkKLQkJcmV0dXJuIHJldDsKKwkvKiBjaGVjayB3YWtldXAgY2FwYWJpbGl0eSAqLworCWFj Y2VsX2RldiA9ICZzdC0+aW5kaW9fYWNjZWwtPmRldjsKKwl3YWtldXAgPSBzdC0+YXBleC5vbiAm JiBkZXZpY2VfbWF5X3dha2V1cChhY2NlbF9kZXYpOworCS8qIHJlc3RvcmUgaXJxIHN0YXRlICov CisJaWYgKHdha2V1cCkgeworCQllbmFibGVfaXJxKHN0LT5pcnEpOworCQlkaXNhYmxlX2lycV93 YWtlKHN0LT5pcnEpOworCX0gZWxzZSB7CisJCXJldCA9IGludl9pY200MjYwN19lbmFibGVfdmRk aW9fcmVnKHN0KTsKKwkJaWYgKHJldCkKKwkJCXJldHVybiByZXQ7CisJfQogCiAJLyogcmVzdG9y ZSBzZW5zb3JzIHN0YXRlLCBub3RpbmcgZ3lybyBzdGlsbCBub3QgeWV0IHN1cHBvcnRlZC4gICov CiAJcmV0ID0gaW52X2ljbTQyNjA3X3NldF9wd3JfbWdtdDAoc3QsIElOVl9JQ000MjYwN19TRU5T T1JfTU9ERV9PRkYsCkBAIC01MDAsNiArNjg2LDEzIEBAIHN0YXRpYyBpbnQgaW52X2ljbTQyNjA3 X3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYpCiAJaWYgKHJldCkKIAkJcmV0dXJuIHJldDsKIAor CS8qIHJlc3RvcmUgQVBFWCBmZWF0dXJlcyBpZiBkaXNhYmxlZCAqLworCWlmICghd2FrZXVwICYm IHN0LT5hcGV4LndvbS5lbmFibGUpIHsKKwkJcmV0ID0gaW52X2ljbTQyNjA3X2VuYWJsZV93b20o c3QpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKwl9CisKIAlpZiAoc3QtPmZpZm8ub24p IHsKIAkJaW52X3NlbnNvcnNfdGltZXN0YW1wX3Jlc2V0KCZhY2NlbF9zdC0+dHMpOwogCQlyZXQg PSByZWdtYXBfd3JpdGUoc3QtPm1hcCwgSU5WX0lDTTQyNjA3X1JFR19GSUZPX0NPTkZJRzEsCi0t IAoyLjQzLjAKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f XwpMaW51eC1yb2NrY2hpcCBtYWlsaW5nIGxpc3QKTGludXgtcm9ja2NoaXBAbGlzdHMuaW5mcmFk ZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4 LXJvY2tjaGlwCg==