From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752474AbeEOI2k (ORCPT ); Tue, 15 May 2018 04:28:40 -0400 Received: from mail-lf0-f68.google.com ([209.85.215.68]:34613 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752186AbeEOI2h (ORCPT ); Tue, 15 May 2018 04:28:37 -0400 X-Google-Smtp-Source: AB8JxZqSqxLsbcwUVgdIti3eJRxThMPdYsQ3lx35osvYKKjWFbikjSf0ZGc99qCqJJ8myN6SWAIVHA== Subject: Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver To: Hans Verkuil , airlied@linux.ie, hans.verkuil@cisco.com, lee.jones@linaro.org, olof@lixom.net, seanpaul@google.com Cc: sadolfsson@google.com, felixe@google.com, bleung@google.com, darekm@google.com, marcheu@chromium.org, fparent@baylibre.com, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org References: <1526337639-3568-1-git-send-email-narmstrong@baylibre.com> <1526337639-3568-6-git-send-email-narmstrong@baylibre.com> <331d45a4-e496-d0f0-5a0b-ead2cc66da6f@xs4all.nl> From: Neil Armstrong Openpgp: preference=signencrypt Autocrypt: addr=narmstrong@baylibre.com; prefer-encrypt=mutual; keydata= xsBNBE1ZBs8BCAD78xVLsXPwV/2qQx2FaO/7mhWL0Qodw8UcQJnkrWmgTFRobtTWxuRx8WWP GTjuhvbleoQ5Cxjr+v+1ARGCH46MxFP5DwauzPekwJUD5QKZlaw/bURTLmS2id5wWi3lqVH4 BVF2WzvGyyeV1o4RTCYDnZ9VLLylJ9bneEaIs/7cjCEbipGGFlfIML3sfqnIvMAxIMZrvcl9 qPV2k+KQ7q+aXavU5W+yLNn7QtXUB530Zlk/d2ETgzQ5FLYYnUDAaRl+8JUTjc0CNOTpCeik 80TZcE6f8M76Xa6yU8VcNko94Ck7iB4vj70q76P/J7kt98hklrr85/3NU3oti3nrIHmHABEB AAHNKE5laWwgQXJtc3Ryb25nIDxuYXJtc3Ryb25nQGJheWxpYnJlLmNvbT7CwHsEEwEKACUC GyMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheABQJXDO2CAhkBAAoJEBaat7Gkz/iubGIH/iyk RqvgB62oKOFlgOTYCMkYpm2aAOZZLf6VKHKc7DoVwuUkjHfIRXdslbrxi4pk5VKU6ZP9AKsN NtMZntB8WrBTtkAZfZbTF7850uwd3eU5cN/7N1Q6g0JQihE7w4GlIkEpQ8vwSg5W7hkx3yQ6 2YzrUZh/b7QThXbNZ7xOeSEms014QXazx8+txR7jrGF3dYxBsCkotO/8DNtZ1R+aUvRfpKg5 ZgABTC0LmAQnuUUf2PHcKFAHZo5KrdO+tyfL+LgTUXIXkK+tenkLsAJ0cagz1EZ5gntuheLD YJuzS4zN+1Asmb9kVKxhjSQOcIh6g2tw7vaYJgL/OzJtZi6JlIXOwE0ETVkGzwEIALyKDN/O GURaHBVzwjgYq+ZtifvekdrSNl8TIDH8g1xicBYpQTbPn6bbSZbdvfeQPNCcD4/EhXZuhQXM coJsQQQnO4vwVULmPGgtGf8PVc7dxKOeta+qUh6+SRh3vIcAUFHDT3f/Zdspz+e2E0hPV2hi SvICLk11qO6cyJE13zeNFoeY3ggrKY+IzbFomIZY4yG6xI99NIPEVE9lNBXBKIlewIyVlkOa YvJWSV+p5gdJXOvScNN1epm5YHmf9aE2ZjnqZGoMMtsyw18YoX9BqMFInxqYQQ3j/HpVgTSv mo5ea5qQDDUaCsaTf8UeDcwYOtgI8iL4oHcsGtUXoUk33HEAEQEAAcLAXwQYAQIACQUCTVkG zwIbDAAKCRAWmrexpM/4rrXiB/sGbkQ6itMrAIfnM7IbRuiSZS1unlySUVYu3SD6YBYnNi3G 5EpbwfBNuT3H8//rVvtOFK4OD8cRYkxXRQmTvqa33eDIHu/zr1HMKErm+2SD6PO9umRef8V8 2o2oaCLvf4WeIssFjwB0b6a12opuRP7yo3E3gTCSKmbUuLv1CtxKQF+fUV1cVaTPMyT25Od+ RC1K+iOR0F54oUJvJeq7fUzbn/KdlhA8XPGzwGRy4zcsPWvwnXgfe5tk680fEKZVwOZKIEuJ C3v+/yZpQzDvGYJvbyix0lHnrCzq43WefRHI5XTTQbM0WUIBIcGmq38+OgUsMYu4NzLu7uZF Acmp6h8g Organization: Baylibre Message-ID: <43b84663-da56-25fd-8e16-ba67f5a7c762@baylibre.com> Date: Tue, 15 May 2018 10:28:33 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 In-Reply-To: <331d45a4-e496-d0f0-5a0b-ead2cc66da6f@xs4all.nl> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 15/05/2018 10:10, Hans Verkuil wrote: > On 05/15/18 09:25, Neil Armstrong wrote: >> Hi Hans, >> >> Thanks for the extensive review. >> >> On 15/05/2018 08:58, Hans Verkuil wrote: >>> On 05/15/2018 12:40 AM, Neil Armstrong wrote: >>>> The Chrome OS Embedded Controller can expose a CEC bus, this patch add the >>>> driver for such feature of the Embedded Controller. >>>> >>>> This driver is part of the cros-ec MFD and will be add as a sub-device when >>>> the feature bit is exposed by the EC. >>>> >>>> The controller will only handle a single logical address and handles >>>> all the messages retries and will only expose Success or Error. >>>> >>>> When the logical address is invalid, the controller will act as a CEC sniffer >>>> and transfer all messages on the bus. >>> >>> I did not see any support for this. If this works as you state here, then adding >>> support for CEC_CAP_MONITOR_ALL is highly recommended. >> >> Oops, I forgot to remove this phrase, the FW will maybe support it, but it has been >> dropped for the first revision. >> >>> >>>> >>>> Signed-off-by: Neil Armstrong >>>> --- >>>> drivers/media/platform/Kconfig | 11 + >>>> drivers/media/platform/Makefile | 2 + >>>> drivers/media/platform/cros-ec/Makefile | 1 + >>>> drivers/media/platform/cros-ec/cros-ec-cec.c | 331 +++++++++++++++++++++++++++ >>>> 4 files changed, 345 insertions(+) >>>> create mode 100644 drivers/media/platform/cros-ec/Makefile >>>> create mode 100644 drivers/media/platform/cros-ec/cros-ec-cec.c >>> >>> Shouldn't the directory be called cros-ec-cec? Forgot this one, moved to cros-ec-cec directory. >>> >>>> >>>> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig >>>> index c7a1cf8..e55a8ed2 100644 >>>> --- a/drivers/media/platform/Kconfig >>>> +++ b/drivers/media/platform/Kconfig >>>> @@ -546,6 +546,17 @@ menuconfig CEC_PLATFORM_DRIVERS >>>> >>>> if CEC_PLATFORM_DRIVERS >>>> >>>> +config VIDEO_CROS_EC_CEC >>>> + tristate "Chrome OS EC CEC driver" >>>> + depends on MFD_CROS_EC || COMPILE_TEST >>>> + select CEC_CORE >>>> + select CEC_NOTIFIER >>>> + ---help--- >>>> + If you say yes here you will get support for the >>>> + Chrome OS Embedded Controller's CEC. >>>> + The CEC bus is present in the HDMI connector and enables communication >>>> + between compatible devices. >>>> + >>>> config VIDEO_MESON_AO_CEC >>>> tristate "Amlogic Meson AO CEC driver" >>>> depends on ARCH_MESON || COMPILE_TEST >>>> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile >>>> index 932515d..0e0582e 100644 >>>> --- a/drivers/media/platform/Makefile >>>> +++ b/drivers/media/platform/Makefile >>>> @@ -92,3 +92,5 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/camss-8x16/ >>>> obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ >>>> >>>> obj-y += meson/ >>>> + >>>> +obj-y += cros-ec/ >>>> diff --git a/drivers/media/platform/cros-ec/Makefile b/drivers/media/platform/cros-ec/Makefile >>>> new file mode 100644 >>>> index 0000000..9ce97f9 >>>> --- /dev/null >>>> +++ b/drivers/media/platform/cros-ec/Makefile >>>> @@ -0,0 +1 @@ >>>> +obj-$(CONFIG_VIDEO_CROS_EC_CEC) += cros-ec-cec.o >>>> diff --git a/drivers/media/platform/cros-ec/cros-ec-cec.c b/drivers/media/platform/cros-ec/cros-ec-cec.c >>>> new file mode 100644 >>>> index 0000000..fea90da >>>> --- /dev/null >>>> +++ b/drivers/media/platform/cros-ec/cros-ec-cec.c >>>> @@ -0,0 +1,331 @@ >>>> +// SPDX-License-Identifier: GPL-2.0+ >>>> +/* >>>> + * CEC driver for Chrome OS Embedded Controller >>>> + * >>>> + * Copyright (c) 2018 BayLibre, SAS >>>> + * Author: Neil Armstrong >>>> + */ >>>> + >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +#define DRV_NAME "cros-ec-cec" >>>> + >>>> +/** >>>> + * struct cros_ec_cec - Driver data for EC CEC >>>> + * >>>> + * @cros_ec: Pointer to EC device >>>> + * @notifier: Notifier info for responding to EC events >>>> + * @adap: CEC adapter >>>> + * @notify: CEC notifier pointer >>>> + * @rc_msg: storage for a received message >>>> + */ >>>> +struct cros_ec_cec { >>>> + struct cros_ec_device *cros_ec; >>>> + struct notifier_block notifier; >>>> + struct cec_adapter *adap; >>>> + struct cec_notifier *notify; >>>> + struct cec_msg rx_msg; >>>> +}; >>>> + >>>> +static void handle_cec_message(struct cros_ec_cec *cros_ec_cec) >>>> +{ >>>> + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >>>> + uint8_t *cec_message = cros_ec->event_data.data.cec_message; >>>> + unsigned int len = cros_ec->event_size; >>>> + >>>> + cros_ec_cec->rx_msg.len = len; >>> >>> How robust is the underlying code and hardware? What happens if a >>> CEC message with more than 16 bytes is received? >>> >>> Hard to test unless you have an RPi3 set up as a CEC debugger. See >>> last section in https://hverkuil.home.xs4all.nl/cec-status.txt. >>> >>> Since you worked with CEC for a while now I recommend you set up such >>> a system. It's cheap and very useful. >> >> I will definitely setup this kind of system, I tried using am Amlogic SoC, but it really can't monitor the bus.... >> >> But I also have an ST STM32F0 Development board with double HDMI connector to develop CEC, I'll maybe try to use it for that purpose. > > You really want a setup that uses the cec-gpio driver since that allows > you to do CEC error injection. If you can hook up the CEC pin to a GPIO > on the stm32 board, than that should work just as well as with the RPi3. > >> >>> >>>> + memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); >>>> + >>>> + cec_received_msg(cros_ec_cec->adap, &cros_ec_cec->rx_msg); >>>> +} >>>> + >>>> +static void handle_cec_event(struct cros_ec_cec *cros_ec_cec) >>>> +{ >>>> + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >>>> + uint32_t events = cros_ec->event_data.data.cec_events; >>>> + >>>> + if (events & EC_MKBP_CEC_SEND_OK) >>>> + cec_transmit_attempt_done(cros_ec_cec->adap, >>>> + CEC_TX_STATUS_OK); >>>> + >>>> + if (events & EC_MKBP_CEC_SEND_FAILED) >>>> + cec_transmit_attempt_done(cros_ec_cec->adap, >>>> + CEC_TX_STATUS_ERROR); >>> >>> You said above that the HW takes care of all the message retries. >>> If that's the case, then you need to use cec_transmit_done here >>> and pass in status CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK. >>> The MAX_RETRIES flag tells the cec core that it shouldn't attempt >>> to retry the message because the HW already did that. >>> >>> NACK is better than ERROR if the hardware supports only an OK/FAIL >>> result. >> >> Ok, we were unsure about this, thanks for the clarification. >> >>> >>>> +} >>>> + >>>> +static int cros_ec_cec_event(struct notifier_block *nb, >>>> + unsigned long queued_during_suspend, void *_notify) >>>> +{ >>>> + struct cros_ec_cec *cros_ec_cec; >>>> + struct cros_ec_device *cros_ec; >>>> + >>>> + cros_ec_cec = container_of(nb, struct cros_ec_cec, notifier); >>>> + cros_ec = cros_ec_cec->cros_ec; >>>> + >>>> + if (cros_ec->event_data.event_type == EC_MKBP_CEC_EVENT) { >>>> + handle_cec_event(cros_ec_cec); >>>> + return NOTIFY_OK; >>>> + } >>>> + >>>> + if (cros_ec->event_data.event_type == EC_MKBP_EVENT_CEC_MESSAGE) { >>>> + handle_cec_message(cros_ec_cec); >>>> + return NOTIFY_OK; >>>> + } >>>> + >>>> + return NOTIFY_DONE; >>>> +} >>>> + >>>> +static int cros_ec_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr) >>>> +{ >>>> + struct cros_ec_cec *cros_ec_cec = adap->priv; >>>> + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >>>> + struct { >>>> + struct cros_ec_command msg; >>>> + struct ec_params_cec_set data; >>>> + } __packed msg; >>> >>> Just say: ... msg = {}; >>> >>>> + int ret = 0; >>>> + >>>> + if (logical_addr == CEC_LOG_ADDR_INVALID) >>>> + return 0; >>> >>> This looks weird. If I had configured a LA before, then this should unconfigure >>> it. But it just keeps the existing LA, so any poll messages to us will still >>> be Acked. Or am I missing something? > > Did you miss this comment? It's weird what is happening here. I forgot to answer, there was a bug in the firmware, now it's fixed and we can unconfigure the LA with CEC_LOG_ADDR_INVALID. > >>> >>>> + >>>> + memset(&msg, 0, sizeof(msg)); >>> >>> and you can drop this memset. >> >> I always forget this trick. >> >>> >>>> + msg.msg.command = EC_CMD_CEC_SET; >>>> + msg.msg.outsize = sizeof(msg.data); >>>> + msg.data.cmd = CEC_CMD_LOGICAL_ADDRESS; >>>> + msg.data.address = logical_addr; >>>> + >>>> + ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); >>>> + if (ret < 0) { >>>> + dev_err(cros_ec->dev, >>>> + "error setting CEC logical address on EC: %d\n", ret); >>>> + return ret; >>>> + } >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static int cros_ec_cec_transmit(struct cec_adapter *adap, u8 attempts, >>>> + u32 signal_free_time, struct cec_msg *cec_msg) >>>> +{ >>>> + struct cros_ec_cec *cros_ec_cec = adap->priv; >>>> + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >>>> + struct { >>>> + struct cros_ec_command msg; >>>> + struct ec_params_cec_write data; >>>> + } __packed msg; >>> >>> ... msg = {}; >>> >>>> + int ret = 0; >>>> + >>>> + if (cec_msg->len > MAX_CEC_MSG_LEN) >>>> + return -EINVAL; >>> >>> No need, can never happen. >> >> Forgor to remove it, the API changed in the meantime, now it can never happen ! >> >>> >>>> + >>>> + memset(&msg, 0, sizeof(msg)); >>> >>> and drop this. >>> >>>> + msg.msg.command = EC_CMD_CEC_WRITE_MSG; >>>> + msg.msg.outsize = cec_msg->len; >>>> + memcpy(msg.data.msg, cec_msg->msg, cec_msg->len); >>>> + >>>> + ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); >>>> + if (ret < 0) { >>>> + dev_err(cros_ec->dev, >>>> + "error writting CEC msg on EC: %d\n", ret); >>>> + return ret; >>>> + } >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static int cros_ec_cec_adap_enable(struct cec_adapter *adap, bool enable) >>>> +{ >>>> + struct cros_ec_cec *cros_ec_cec = adap->priv; >>>> + struct cros_ec_device *cros_ec = cros_ec_cec->cros_ec; >>>> + struct { >>>> + struct cros_ec_command msg; >>>> + struct ec_params_cec_set data; >>>> + } __packed msg; >>>> + int ret = 0; >>>> + >>>> + memset(&msg, 0, sizeof(msg)); >>>> + msg.msg.command = EC_CMD_CEC_SET; >>>> + msg.msg.outsize = sizeof(msg.data); >>>> + msg.data.cmd = CEC_CMD_ENABLE; >>>> + msg.data.enable = enable; >>>> + >>>> + ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); >>>> + if (ret < 0) { >>>> + dev_err(cros_ec->dev, >>>> + "error %sabling CEC on EC: %d\n", >>>> + (enable ? "en" : "dis"), ret); >>>> + return ret; >>>> + } >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static const struct cec_adap_ops cros_ec_cec_ops = { >>>> + .adap_enable = cros_ec_cec_adap_enable, >>>> + .adap_log_addr = cros_ec_cec_set_log_addr, >>>> + .adap_transmit = cros_ec_cec_transmit, >>>> +}; >>>> + >>>> +#ifdef CONFIG_PM_SLEEP >>>> +static int cros_ec_cec_suspend(struct device *dev) >>>> +{ >>>> + struct platform_device *pdev = to_platform_device(dev); >>>> + struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev); >>>> + >>>> + if (device_may_wakeup(dev)) >>>> + enable_irq_wake(cros_ec_cec->cros_ec->irq); >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static int cros_ec_cec_resume(struct device *dev) >>>> +{ >>>> + struct platform_device *pdev = to_platform_device(dev); >>>> + struct cros_ec_cec *cros_ec_cec = dev_get_drvdata(&pdev->dev); >>>> + >>>> + if (device_may_wakeup(dev)) >>>> + disable_irq_wake(cros_ec_cec->cros_ec->irq); >>>> + >>>> + return 0; >>>> +} >>>> +#endif >>>> + >>>> +static SIMPLE_DEV_PM_OPS(cros_ec_cec_pm_ops, >>>> + cros_ec_cec_suspend, cros_ec_cec_resume); >>>> + >>>> + >>>> +struct cec_dmi_match { >>>> + char *sys_vendor; >>>> + char *product_name; >>>> + char *devname; >>>> + char *conn; >>>> +}; >>>> + >>>> +static const struct cec_dmi_match cec_dmi_match_table[] = { >>>> + /* Google Fizz */ >>>> + { "Google", "Fizz", "0000:00:02.0", "HDMI-A-1" }, >>>> +}; >>>> + >>>> +static int cros_ec_cec_get_notifier(struct cec_notifier **notify) >>>> +{ >>>> + int i; >>>> + >>>> + for (i = 0 ; i < ARRAY_SIZE(cec_dmi_match_table) ; ++i) { >>>> + const struct cec_dmi_match *m = &cec_dmi_match_table[i]; >>>> + >>>> + if (dmi_match(DMI_SYS_VENDOR, m->sys_vendor) && >>>> + dmi_match(DMI_PRODUCT_NAME, m->product_name)) { >>>> + *notify = cec_notifier_get_byname(m->devname, m->conn); >>> >>> See my comments for patch 2/5. >> >> I will change with you comment, looks way cleaner. >> >>> >>>> + return 0; >>>> + } >>>> + } >>>> + >>>> + return -EINVAL; >>>> +} >>>> + >>>> +static int cros_ec_cec_probe(struct platform_device *pdev) >>>> +{ >>>> + struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent); >>>> + struct cros_ec_device *cros_ec = ec_dev->ec_dev; >>>> + struct cros_ec_cec *cros_ec_cec; >>>> + unsigned int cec_caps = CEC_CAP_DEFAULTS; >>> >>> Does this need CEC_CAP_NEEDS_HPD? Can it still use CEC if there is no HPD >>> signal? >> >> No, Yes, the EC FW is independent of the HPD status >> >>> >>>> + int ret; >>>> + >>>> + cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec), >>>> + GFP_KERNEL); >>>> + if (!cros_ec_cec) >>>> + return -ENOMEM; >>>> + >>>> + platform_set_drvdata(pdev, cros_ec_cec); >>>> + cros_ec_cec->cros_ec = cros_ec; >>>> + >>>> + ret = cros_ec_cec_get_notifier(&cros_ec_cec->notify); >>>> + if (ret) { >>>> + dev_warn(&pdev->dev, "no CEC notifier available\n"); >>>> + cec_caps |= CEC_CAP_PHYS_ADDR; >>> >>> Can this happen? What hardware has this? I am strongly opposed to CEC drivers >>> using this capability unless there is no other option. It's a pain for userspace. >> >> It's in case an HW having a CEC capable FW but not in the cec_dmi_match_table, in this case >> it won't fail but still enable the CEC interface without a notifier. > > I don't think that's a good idea. CAP_PHYS_ADDR should *only* be used in situations > where it is truly impossible to tell which output is connected to the CEC adapter. > That's the case with e.g. USB CEC dongles where you have no idea how the user > connected the HDMI cables. > > But I assume that in this case it just means that the cec_dmi_match_table needs > to be updated, i.e. it is a driver bug. Yep, maybe a dev_warn should be added to notify this bug ? > > Another thing: this driver assumes that there is only one CEC adapter for only > one HDMI output. But what if there are more HDMI outputs? Will there be one > CEC adapter for each output? Or does the hardware have no provisions for that? The current EC interface only exposes a single CEC interface for now, there is no plan yet for multiple HDMI outputs handling. > > Something should be mentioned about this in a comment. Ok Thanks, Neil > > Regards, > > Hans > >> >>> >>>> + } else if (!cros_ec_cec->notify) { >>>> + return -EPROBE_DEFER; >>>> + } >>>> + >>>> + ret = device_init_wakeup(&pdev->dev, 1); >>>> + if (ret) { >>>> + dev_err(&pdev->dev, "failed to initialize wakeup\n"); >>>> + return ret; >>>> + } >>>> + >>>> + cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec, >>>> + DRV_NAME, cec_caps, 1); >>>> + if (IS_ERR(cros_ec_cec->adap)) >>>> + return PTR_ERR(cros_ec_cec->adap); >>>> + >>>> + cros_ec_cec->adap->owner = THIS_MODULE; >>> >>> This can be dropped, cec_register_adapter() sets this already. >> >> Noted. >> >>> >>>> + >>>> + /* Get CEC events from the EC. */ >>>> + cros_ec_cec->notifier.notifier_call = cros_ec_cec_event; >>>> + ret = blocking_notifier_chain_register(&cros_ec->event_notifier, >>>> + &cros_ec_cec->notifier); >>>> + if (ret) { >>>> + dev_err(&pdev->dev, "failed to register notifier\n"); >>>> + cec_delete_adapter(cros_ec_cec->adap); >>>> + return ret; >>>> + } >>>> + >>>> + ret = cec_register_adapter(cros_ec_cec->adap, &pdev->dev); >>>> + if (ret < 0) { >>>> + cec_delete_adapter(cros_ec_cec->adap); >>>> + return ret; >>>> + } >>>> + >>>> + cec_register_cec_notifier(cros_ec_cec->adap, cros_ec_cec->notify); >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static int cros_ec_cec_remove(struct platform_device *pdev) >>>> +{ >>>> + struct cros_ec_cec *cros_ec_cec = platform_get_drvdata(pdev); >>>> + struct device *dev = &pdev->dev; >>>> + int ret; >>>> + >>>> + ret = blocking_notifier_chain_unregister( >>>> + &cros_ec_cec->cros_ec->event_notifier, >>>> + &cros_ec_cec->notifier); >>>> + >>>> + if (ret) { >>>> + dev_err(dev, "failed to unregister notifier\n"); >>>> + return ret; >>>> + } >>>> + >>>> + cec_unregister_adapter(cros_ec_cec->adap); >>>> + >>>> + if (cros_ec_cec->notify) >>>> + cec_notifier_put(cros_ec_cec->notify); >>>> + >>>> + return 0; >>>> +} >>>> + >>>> +static struct platform_driver cros_ec_cec_driver = { >>>> + .probe = cros_ec_cec_probe, >>>> + .remove = cros_ec_cec_remove, >>>> + .driver = { >>>> + .name = DRV_NAME, >>>> + .pm = &cros_ec_cec_pm_ops, >>>> + }, >>>> +}; >>>> + >>>> +module_platform_driver(cros_ec_cec_driver); >>>> + >>>> +MODULE_DESCRIPTION("CEC driver for Chrome OS ECs"); >>>> +MODULE_AUTHOR("Neil Armstrong "); >>>> +MODULE_LICENSE("GPL"); >>>> +MODULE_ALIAS("platform:" DRV_NAME); >>>> >>> >>> Regards, >>> >>> Hans >>> >> >> Thanks, >> Neil >> > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Neil Armstrong Subject: Re: [RFC PATCH 5/5] media: platform: Add Chrome OS EC CEC driver Date: Tue, 15 May 2018 10:28:33 +0200 Message-ID: <43b84663-da56-25fd-8e16-ba67f5a7c762@baylibre.com> References: <1526337639-3568-1-git-send-email-narmstrong@baylibre.com> <1526337639-3568-6-git-send-email-narmstrong@baylibre.com> <331d45a4-e496-d0f0-5a0b-ead2cc66da6f@xs4all.nl> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x241.google.com (mail-lf0-x241.google.com [IPv6:2a00:1450:4010:c07::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id D8F5989A83 for ; Tue, 15 May 2018 08:28:36 +0000 (UTC) Received: by mail-lf0-x241.google.com with SMTP id y72-v6so22049475lfd.2 for ; Tue, 15 May 2018 01:28:36 -0700 (PDT) In-Reply-To: <331d45a4-e496-d0f0-5a0b-ead2cc66da6f@xs4all.nl> Content-Language: en-US List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Hans Verkuil , airlied@linux.ie, hans.verkuil@cisco.com, lee.jones@linaro.org, olof@lixom.net, seanpaul@google.com Cc: sadolfsson@google.com, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, fparent@baylibre.com, felixe@google.com, marcheu@chromium.org, bleung@google.com, darekm@google.com, linux-media@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org T24gMTUvMDUvMjAxOCAxMDoxMCwgSGFucyBWZXJrdWlsIHdyb3RlOgo+IE9uIDA1LzE1LzE4IDA5 OjI1LCBOZWlsIEFybXN0cm9uZyB3cm90ZToKPj4gSGkgSGFucywKPj4KPj4gVGhhbmtzIGZvciB0 aGUgZXh0ZW5zaXZlIHJldmlldy4KPj4KPj4gT24gMTUvMDUvMjAxOCAwODo1OCwgSGFucyBWZXJr dWlsIHdyb3RlOgo+Pj4gT24gMDUvMTUvMjAxOCAxMjo0MCBBTSwgTmVpbCBBcm1zdHJvbmcgd3Jv dGU6Cj4+Pj4gVGhlIENocm9tZSBPUyBFbWJlZGRlZCBDb250cm9sbGVyIGNhbiBleHBvc2UgYSBD RUMgYnVzLCB0aGlzIHBhdGNoIGFkZCB0aGUKPj4+PiBkcml2ZXIgZm9yIHN1Y2ggZmVhdHVyZSBv ZiB0aGUgRW1iZWRkZWQgQ29udHJvbGxlci4KPj4+Pgo+Pj4+IFRoaXMgZHJpdmVyIGlzIHBhcnQg b2YgdGhlIGNyb3MtZWMgTUZEIGFuZCB3aWxsIGJlIGFkZCBhcyBhIHN1Yi1kZXZpY2Ugd2hlbgo+ Pj4+IHRoZSBmZWF0dXJlIGJpdCBpcyBleHBvc2VkIGJ5IHRoZSBFQy4KPj4+Pgo+Pj4+IFRoZSBj b250cm9sbGVyIHdpbGwgb25seSBoYW5kbGUgYSBzaW5nbGUgbG9naWNhbCBhZGRyZXNzIGFuZCBo YW5kbGVzCj4+Pj4gYWxsIHRoZSBtZXNzYWdlcyByZXRyaWVzIGFuZCB3aWxsIG9ubHkgZXhwb3Nl IFN1Y2Nlc3Mgb3IgRXJyb3IuCj4+Pj4KPj4+PiBXaGVuIHRoZSBsb2dpY2FsIGFkZHJlc3MgaXMg aW52YWxpZCwgdGhlIGNvbnRyb2xsZXIgd2lsbCBhY3QgYXMgYSBDRUMgc25pZmZlcgo+Pj4+IGFu ZCB0cmFuc2ZlciBhbGwgbWVzc2FnZXMgb24gdGhlIGJ1cy4KPj4+Cj4+PiBJIGRpZCBub3Qgc2Vl IGFueSBzdXBwb3J0IGZvciB0aGlzLiBJZiB0aGlzIHdvcmtzIGFzIHlvdSBzdGF0ZSBoZXJlLCB0 aGVuIGFkZGluZwo+Pj4gc3VwcG9ydCBmb3IgQ0VDX0NBUF9NT05JVE9SX0FMTCBpcyBoaWdobHkg cmVjb21tZW5kZWQuCj4+Cj4+IE9vcHMsIEkgZm9yZ290IHRvIHJlbW92ZSB0aGlzIHBocmFzZSwg dGhlIEZXIHdpbGwgbWF5YmUgc3VwcG9ydCBpdCwgYnV0IGl0IGhhcyBiZWVuCj4+IGRyb3BwZWQg Zm9yIHRoZSBmaXJzdCByZXZpc2lvbi4KPj4KPj4+Cj4+Pj4KPj4+PiBTaWduZWQtb2ZmLWJ5OiBO ZWlsIEFybXN0cm9uZyA8bmFybXN0cm9uZ0BiYXlsaWJyZS5jb20+Cj4+Pj4gLS0tCj4+Pj4gIGRy aXZlcnMvbWVkaWEvcGxhdGZvcm0vS2NvbmZpZyAgICAgICAgICAgICAgIHwgIDExICsKPj4+PiAg ZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9NYWtlZmlsZSAgICAgICAgICAgICAgfCAgIDIgKwo+Pj4+ ICBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL2Nyb3MtZWMvTWFrZWZpbGUgICAgICB8ICAgMSArCj4+ Pj4gIGRyaXZlcnMvbWVkaWEvcGxhdGZvcm0vY3Jvcy1lYy9jcm9zLWVjLWNlYy5jIHwgMzMxICsr KysrKysrKysrKysrKysrKysrKysrKysrKwo+Pj4+ICA0IGZpbGVzIGNoYW5nZWQsIDM0NSBpbnNl cnRpb25zKCspCj4+Pj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21lZGlhL3BsYXRmb3Jt L2Nyb3MtZWMvTWFrZWZpbGUKPj4+PiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbWVkaWEv cGxhdGZvcm0vY3Jvcy1lYy9jcm9zLWVjLWNlYy5jCj4+Pgo+Pj4gU2hvdWxkbid0IHRoZSBkaXJl Y3RvcnkgYmUgY2FsbGVkIGNyb3MtZWMtY2VjPwoKRm9yZ290IHRoaXMgb25lLCBtb3ZlZCB0byBj cm9zLWVjLWNlYyBkaXJlY3RvcnkuCgo+Pj4KPj4+Pgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L21lZGlhL3BsYXRmb3JtL0tjb25maWcgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL0tjb25maWcK Pj4+PiBpbmRleCBjN2ExY2Y4Li5lNTVhOGVkMiAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL21l ZGlhL3BsYXRmb3JtL0tjb25maWcKPj4+PiArKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL0tj b25maWcKPj4+PiBAQCAtNTQ2LDYgKzU0NiwxNyBAQCBtZW51Y29uZmlnIENFQ19QTEFURk9STV9E UklWRVJTCj4+Pj4gIAo+Pj4+ICBpZiBDRUNfUExBVEZPUk1fRFJJVkVSUwo+Pj4+ICAKPj4+PiAr Y29uZmlnIFZJREVPX0NST1NfRUNfQ0VDCj4+Pj4gKwl0cmlzdGF0ZSAiQ2hyb21lIE9TIEVDIENF QyBkcml2ZXIiCj4+Pj4gKwlkZXBlbmRzIG9uIE1GRF9DUk9TX0VDIHx8IENPTVBJTEVfVEVTVAo+ Pj4+ICsJc2VsZWN0IENFQ19DT1JFCj4+Pj4gKwlzZWxlY3QgQ0VDX05PVElGSUVSCj4+Pj4gKwkt LS1oZWxwLS0tCj4+Pj4gKwkgIElmIHlvdSBzYXkgeWVzIGhlcmUgeW91IHdpbGwgZ2V0IHN1cHBv cnQgZm9yIHRoZQo+Pj4+ICsJICBDaHJvbWUgT1MgRW1iZWRkZWQgQ29udHJvbGxlcidzIENFQy4K Pj4+PiArCSAgVGhlIENFQyBidXMgaXMgcHJlc2VudCBpbiB0aGUgSERNSSBjb25uZWN0b3IgYW5k IGVuYWJsZXMgY29tbXVuaWNhdGlvbgo+Pj4+ICsJICBiZXR3ZWVuIGNvbXBhdGlibGUgZGV2aWNl cy4KPj4+PiArCj4+Pj4gIGNvbmZpZyBWSURFT19NRVNPTl9BT19DRUMKPj4+PiAgCXRyaXN0YXRl ICJBbWxvZ2ljIE1lc29uIEFPIENFQyBkcml2ZXIiCj4+Pj4gIAlkZXBlbmRzIG9uIEFSQ0hfTUVT T04gfHwgQ09NUElMRV9URVNUCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZv cm0vTWFrZWZpbGUgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL01ha2VmaWxlCj4+Pj4gaW5kZXgg OTMyNTE1ZC4uMGUwNTgyZSAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3Jt L01ha2VmaWxlCj4+Pj4gKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9NYWtlZmlsZQo+Pj4+ IEBAIC05MiwzICs5Miw1IEBAIG9iai0kKENPTkZJR19WSURFT19RQ09NX0NBTVNTKQkJKz0gcWNv bS9jYW1zcy04eDE2Lwo+Pj4+ICBvYmotJChDT05GSUdfVklERU9fUUNPTV9WRU5VUykJCSs9IHFj b20vdmVudXMvCj4+Pj4gIAo+Pj4+ICBvYmoteQkJCQkJKz0gbWVzb24vCj4+Pj4gKwo+Pj4+ICtv YmoteQkJCQkJKz0gY3Jvcy1lYy8KPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0 Zm9ybS9jcm9zLWVjL01ha2VmaWxlIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9jcm9zLWVjL01h a2VmaWxlCj4+Pj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPj4+PiBpbmRleCAwMDAwMDAwLi45Y2U5 N2Y5Cj4+Pj4gLS0tIC9kZXYvbnVsbAo+Pj4+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0v Y3Jvcy1lYy9NYWtlZmlsZQo+Pj4+IEBAIC0wLDAgKzEgQEAKPj4+PiArb2JqLSQoQ09ORklHX1ZJ REVPX0NST1NfRUNfQ0VDKSArPSBjcm9zLWVjLWNlYy5vCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvbWVkaWEvcGxhdGZvcm0vY3Jvcy1lYy9jcm9zLWVjLWNlYy5jIGIvZHJpdmVycy9tZWRpYS9w bGF0Zm9ybS9jcm9zLWVjL2Nyb3MtZWMtY2VjLmMKPj4+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+ Pj4+IGluZGV4IDAwMDAwMDAuLmZlYTkwZGEKPj4+PiAtLS0gL2Rldi9udWxsCj4+Pj4gKysrIGIv ZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9jcm9zLWVjL2Nyb3MtZWMtY2VjLmMKPj4+PiBAQCAtMCww ICsxLDMzMSBAQAo+Pj4+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsKPj4+ PiArLyoKPj4+PiArICogQ0VDIGRyaXZlciBmb3IgQ2hyb21lIE9TIEVtYmVkZGVkIENvbnRyb2xs ZXIKPj4+PiArICoKPj4+PiArICogQ29weXJpZ2h0IChjKSAyMDE4IEJheUxpYnJlLCBTQVMKPj4+ PiArICogQXV0aG9yOiBOZWlsIEFybXN0cm9uZyA8bmFybXN0cm9uZ0BiYXlsaWJyZS5jb20+Cj4+ Pj4gKyAqLwo+Pj4+ICsKPj4+PiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+Pj4+ICsjaW5j bHVkZSA8bGludXgvbW9kdWxlLmg+Cj4+Pj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZp Y2UuaD4KPj4+PiArI2luY2x1ZGUgPGxpbnV4L2RtaS5oPgo+Pj4+ICsjaW5jbHVkZSA8bGludXgv Y2VjLmg+Cj4+Pj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4+Pj4gKyNpbmNsdWRlIDxsaW51 eC9pbnRlcnJ1cHQuaD4KPj4+PiArI2luY2x1ZGUgPG1lZGlhL2NlYy5oPgo+Pj4+ICsjaW5jbHVk ZSA8bWVkaWEvY2VjLW5vdGlmaWVyLmg+Cj4+Pj4gKyNpbmNsdWRlIDxsaW51eC9tZmQvY3Jvc19l Yy5oPgo+Pj4+ICsjaW5jbHVkZSA8bGludXgvbWZkL2Nyb3NfZWNfY29tbWFuZHMuaD4KPj4+PiAr Cj4+Pj4gKyNkZWZpbmUgRFJWX05BTUUJImNyb3MtZWMtY2VjIgo+Pj4+ICsKPj4+PiArLyoqCj4+ Pj4gKyAqIHN0cnVjdCBjcm9zX2VjX2NlYyAtIERyaXZlciBkYXRhIGZvciBFQyBDRUMKPj4+PiAr ICoKPj4+PiArICogQGNyb3NfZWM6IFBvaW50ZXIgdG8gRUMgZGV2aWNlCj4+Pj4gKyAqIEBub3Rp ZmllcjogTm90aWZpZXIgaW5mbyBmb3IgcmVzcG9uZGluZyB0byBFQyBldmVudHMKPj4+PiArICog QGFkYXA6IENFQyBhZGFwdGVyCj4+Pj4gKyAqIEBub3RpZnk6IENFQyBub3RpZmllciBwb2ludGVy Cj4+Pj4gKyAqIEByY19tc2c6IHN0b3JhZ2UgZm9yIGEgcmVjZWl2ZWQgbWVzc2FnZQo+Pj4+ICsg Ki8KPj4+PiArc3RydWN0IGNyb3NfZWNfY2VjIHsKPj4+PiArCXN0cnVjdCBjcm9zX2VjX2Rldmlj ZSAqY3Jvc19lYzsKPj4+PiArCXN0cnVjdCBub3RpZmllcl9ibG9jayBub3RpZmllcjsKPj4+PiAr CXN0cnVjdCBjZWNfYWRhcHRlciAqYWRhcDsKPj4+PiArCXN0cnVjdCBjZWNfbm90aWZpZXIgKm5v dGlmeTsKPj4+PiArCXN0cnVjdCBjZWNfbXNnIHJ4X21zZzsKPj4+PiArfTsKPj4+PiArCj4+Pj4g K3N0YXRpYyB2b2lkIGhhbmRsZV9jZWNfbWVzc2FnZShzdHJ1Y3QgY3Jvc19lY19jZWMgKmNyb3Nf ZWNfY2VjKQo+Pj4+ICt7Cj4+Pj4gKwlzdHJ1Y3QgY3Jvc19lY19kZXZpY2UgKmNyb3NfZWMgPSBj cm9zX2VjX2NlYy0+Y3Jvc19lYzsKPj4+PiArCXVpbnQ4X3QgKmNlY19tZXNzYWdlID0gY3Jvc19l Yy0+ZXZlbnRfZGF0YS5kYXRhLmNlY19tZXNzYWdlOwo+Pj4+ICsJdW5zaWduZWQgaW50IGxlbiA9 IGNyb3NfZWMtPmV2ZW50X3NpemU7Cj4+Pj4gKwo+Pj4+ICsJY3Jvc19lY19jZWMtPnJ4X21zZy5s ZW4gPSBsZW47Cj4+Pgo+Pj4gSG93IHJvYnVzdCBpcyB0aGUgdW5kZXJseWluZyBjb2RlIGFuZCBo YXJkd2FyZT8gV2hhdCBoYXBwZW5zIGlmIGEKPj4+IENFQyBtZXNzYWdlIHdpdGggbW9yZSB0aGFu IDE2IGJ5dGVzIGlzIHJlY2VpdmVkPwo+Pj4KPj4+IEhhcmQgdG8gdGVzdCB1bmxlc3MgeW91IGhh dmUgYW4gUlBpMyBzZXQgdXAgYXMgYSBDRUMgZGVidWdnZXIuIFNlZQo+Pj4gbGFzdCBzZWN0aW9u IGluIGh0dHBzOi8vaHZlcmt1aWwuaG9tZS54czRhbGwubmwvY2VjLXN0YXR1cy50eHQuCj4+Pgo+ Pj4gU2luY2UgeW91IHdvcmtlZCB3aXRoIENFQyBmb3IgYSB3aGlsZSBub3cgSSByZWNvbW1lbmQg eW91IHNldCB1cCBzdWNoCj4+PiBhIHN5c3RlbS4gSXQncyBjaGVhcCBhbmQgdmVyeSB1c2VmdWwu Cj4+Cj4+IEkgd2lsbCBkZWZpbml0ZWx5IHNldHVwIHRoaXMga2luZCBvZiBzeXN0ZW0sIEkgdHJp ZWQgdXNpbmcgYW0gQW1sb2dpYyBTb0MsIGJ1dCBpdCByZWFsbHkgY2FuJ3QgbW9uaXRvciB0aGUg YnVzLi4uLgo+Pgo+PiBCdXQgSSBhbHNvIGhhdmUgYW4gU1QgU1RNMzJGMCBEZXZlbG9wbWVudCBi b2FyZCB3aXRoIGRvdWJsZSBIRE1JIGNvbm5lY3RvciB0byBkZXZlbG9wIENFQywgSSdsbCBtYXli ZSB0cnkgdG8gdXNlIGl0IGZvciB0aGF0IHB1cnBvc2UuCj4gCj4gWW91IHJlYWxseSB3YW50IGEg c2V0dXAgdGhhdCB1c2VzIHRoZSBjZWMtZ3BpbyBkcml2ZXIgc2luY2UgdGhhdCBhbGxvd3MKPiB5 b3UgdG8gZG8gQ0VDIGVycm9yIGluamVjdGlvbi4gSWYgeW91IGNhbiBob29rIHVwIHRoZSBDRUMg cGluIHRvIGEgR1BJTwo+IG9uIHRoZSBzdG0zMiBib2FyZCwgdGhhbiB0aGF0IHNob3VsZCB3b3Jr IGp1c3QgYXMgd2VsbCBhcyB3aXRoIHRoZSBSUGkzLgo+IAo+Pgo+Pj4KPj4+PiArCW1lbWNweShj cm9zX2VjX2NlYy0+cnhfbXNnLm1zZywgY2VjX21lc3NhZ2UsIGxlbik7Cj4+Pj4gKwo+Pj4+ICsJ Y2VjX3JlY2VpdmVkX21zZyhjcm9zX2VjX2NlYy0+YWRhcCwgJmNyb3NfZWNfY2VjLT5yeF9tc2cp Owo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtzdGF0aWMgdm9pZCBoYW5kbGVfY2VjX2V2ZW50KHN0cnVj dCBjcm9zX2VjX2NlYyAqY3Jvc19lY19jZWMpCj4+Pj4gK3sKPj4+PiArCXN0cnVjdCBjcm9zX2Vj X2RldmljZSAqY3Jvc19lYyA9IGNyb3NfZWNfY2VjLT5jcm9zX2VjOwo+Pj4+ICsJdWludDMyX3Qg ZXZlbnRzID0gY3Jvc19lYy0+ZXZlbnRfZGF0YS5kYXRhLmNlY19ldmVudHM7Cj4+Pj4gKwo+Pj4+ ICsJaWYgKGV2ZW50cyAmIEVDX01LQlBfQ0VDX1NFTkRfT0spCj4+Pj4gKwkJY2VjX3RyYW5zbWl0 X2F0dGVtcHRfZG9uZShjcm9zX2VjX2NlYy0+YWRhcCwKPj4+PiArCQkJCQkgIENFQ19UWF9TVEFU VVNfT0spOwo+Pj4+ICsKPj4+PiArCWlmIChldmVudHMgJiBFQ19NS0JQX0NFQ19TRU5EX0ZBSUxF RCkKPj4+PiArCQljZWNfdHJhbnNtaXRfYXR0ZW1wdF9kb25lKGNyb3NfZWNfY2VjLT5hZGFwLAo+ Pj4+ICsJCQkJCSAgQ0VDX1RYX1NUQVRVU19FUlJPUik7Cj4+Pgo+Pj4gWW91IHNhaWQgYWJvdmUg dGhhdCB0aGUgSFcgdGFrZXMgY2FyZSBvZiBhbGwgdGhlIG1lc3NhZ2UgcmV0cmllcy4KPj4+IElm IHRoYXQncyB0aGUgY2FzZSwgdGhlbiB5b3UgbmVlZCB0byB1c2UgY2VjX3RyYW5zbWl0X2RvbmUg aGVyZQo+Pj4gYW5kIHBhc3MgaW4gc3RhdHVzIENFQ19UWF9TVEFUVVNfTUFYX1JFVFJJRVMgfCBD RUNfVFhfU1RBVFVTX05BQ0suCj4+PiBUaGUgTUFYX1JFVFJJRVMgZmxhZyB0ZWxscyB0aGUgY2Vj IGNvcmUgdGhhdCBpdCBzaG91bGRuJ3QgYXR0ZW1wdAo+Pj4gdG8gcmV0cnkgdGhlIG1lc3NhZ2Ug YmVjYXVzZSB0aGUgSFcgYWxyZWFkeSBkaWQgdGhhdC4KPj4+Cj4+PiBOQUNLIGlzIGJldHRlciB0 aGFuIEVSUk9SIGlmIHRoZSBoYXJkd2FyZSBzdXBwb3J0cyBvbmx5IGFuIE9LL0ZBSUwKPj4+IHJl c3VsdC4KPj4KPj4gT2ssIHdlIHdlcmUgdW5zdXJlIGFib3V0IHRoaXMsIHRoYW5rcyBmb3IgdGhl IGNsYXJpZmljYXRpb24uCj4+Cj4+Pgo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtzdGF0aWMgaW50IGNy b3NfZWNfY2VjX2V2ZW50KHN0cnVjdCBub3RpZmllcl9ibG9jayAqbmIsCj4+Pj4gKwl1bnNpZ25l ZCBsb25nIHF1ZXVlZF9kdXJpbmdfc3VzcGVuZCwgdm9pZCAqX25vdGlmeSkKPj4+PiArewo+Pj4+ ICsJc3RydWN0IGNyb3NfZWNfY2VjICpjcm9zX2VjX2NlYzsKPj4+PiArCXN0cnVjdCBjcm9zX2Vj X2RldmljZSAqY3Jvc19lYzsKPj4+PiArCj4+Pj4gKwljcm9zX2VjX2NlYyA9IGNvbnRhaW5lcl9v ZihuYiwgc3RydWN0IGNyb3NfZWNfY2VjLCBub3RpZmllcik7Cj4+Pj4gKwljcm9zX2VjID0gY3Jv c19lY19jZWMtPmNyb3NfZWM7Cj4+Pj4gKwo+Pj4+ICsJaWYgKGNyb3NfZWMtPmV2ZW50X2RhdGEu ZXZlbnRfdHlwZSA9PSBFQ19NS0JQX0NFQ19FVkVOVCkgewo+Pj4+ICsJCWhhbmRsZV9jZWNfZXZl bnQoY3Jvc19lY19jZWMpOwo+Pj4+ICsJCXJldHVybiBOT1RJRllfT0s7Cj4+Pj4gKwl9Cj4+Pj4g Kwo+Pj4+ICsJaWYgKGNyb3NfZWMtPmV2ZW50X2RhdGEuZXZlbnRfdHlwZSA9PSBFQ19NS0JQX0VW RU5UX0NFQ19NRVNTQUdFKSB7Cj4+Pj4gKwkJaGFuZGxlX2NlY19tZXNzYWdlKGNyb3NfZWNfY2Vj KTsKPj4+PiArCQlyZXR1cm4gTk9USUZZX09LOwo+Pj4+ICsJfQo+Pj4+ICsKPj4+PiArCXJldHVy biBOT1RJRllfRE9ORTsKPj4+PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIGludCBjcm9zX2VjX2Nl Y19zZXRfbG9nX2FkZHIoc3RydWN0IGNlY19hZGFwdGVyICphZGFwLCB1OCBsb2dpY2FsX2FkZHIp Cj4+Pj4gK3sKPj4+PiArCXN0cnVjdCBjcm9zX2VjX2NlYyAqY3Jvc19lY19jZWMgPSBhZGFwLT5w cml2Owo+Pj4+ICsJc3RydWN0IGNyb3NfZWNfZGV2aWNlICpjcm9zX2VjID0gY3Jvc19lY19jZWMt PmNyb3NfZWM7Cj4+Pj4gKwlzdHJ1Y3Qgewo+Pj4+ICsJCXN0cnVjdCBjcm9zX2VjX2NvbW1hbmQg bXNnOwo+Pj4+ICsJCXN0cnVjdCBlY19wYXJhbXNfY2VjX3NldCBkYXRhOwo+Pj4+ICsJfSBfX3Bh Y2tlZCBtc2c7Cj4+Pgo+Pj4gSnVzdCBzYXk6IC4uLiBtc2cgPSB7fTsKPj4+Cj4+Pj4gKwlpbnQg cmV0ID0gMDsKPj4+PiArCj4+Pj4gKwlpZiAobG9naWNhbF9hZGRyID09IENFQ19MT0dfQUREUl9J TlZBTElEKQo+Pj4+ICsJCXJldHVybiAwOwo+Pj4KPj4+IFRoaXMgbG9va3Mgd2VpcmQuIElmIEkg aGFkIGNvbmZpZ3VyZWQgYSBMQSBiZWZvcmUsIHRoZW4gdGhpcyBzaG91bGQgdW5jb25maWd1cmUK Pj4+IGl0LiBCdXQgaXQganVzdCBrZWVwcyB0aGUgZXhpc3RpbmcgTEEsIHNvIGFueSBwb2xsIG1l c3NhZ2VzIHRvIHVzIHdpbGwgc3RpbGwKPj4+IGJlIEFja2VkLiBPciBhbSBJIG1pc3Npbmcgc29t ZXRoaW5nPwo+IAo+IERpZCB5b3UgbWlzcyB0aGlzIGNvbW1lbnQ/IEl0J3Mgd2VpcmQgd2hhdCBp cyBoYXBwZW5pbmcgaGVyZS4KCkkgZm9yZ290IHRvIGFuc3dlciwgdGhlcmUgd2FzIGEgYnVnIGlu IHRoZSBmaXJtd2FyZSwgbm93IGl0J3MgZml4ZWQgYW5kIHdlIGNhbiB1bmNvbmZpZ3VyZSB0aGUg TEEgd2l0aCBDRUNfTE9HX0FERFJfSU5WQUxJRC4KCj4gCj4+Pgo+Pj4+ICsKPj4+PiArCW1lbXNl dCgmbXNnLCAwLCBzaXplb2YobXNnKSk7Cj4+Pgo+Pj4gYW5kIHlvdSBjYW4gZHJvcCB0aGlzIG1l bXNldC4KPj4KPj4gSSBhbHdheXMgZm9yZ2V0IHRoaXMgdHJpY2suCj4+Cj4+Pgo+Pj4+ICsJbXNn Lm1zZy5jb21tYW5kID0gRUNfQ01EX0NFQ19TRVQ7Cj4+Pj4gKwltc2cubXNnLm91dHNpemUgPSBz aXplb2YobXNnLmRhdGEpOwo+Pj4+ICsJbXNnLmRhdGEuY21kID0gQ0VDX0NNRF9MT0dJQ0FMX0FE RFJFU1M7Cj4+Pj4gKwltc2cuZGF0YS5hZGRyZXNzID0gbG9naWNhbF9hZGRyOwo+Pj4+ICsKPj4+ PiArCXJldCA9IGNyb3NfZWNfY21kX3hmZXJfc3RhdHVzKGNyb3NfZWMsICZtc2cubXNnKTsKPj4+ PiArCWlmIChyZXQgPCAwKSB7Cj4+Pj4gKwkJZGV2X2Vycihjcm9zX2VjLT5kZXYsCj4+Pj4gKwkJ CSJlcnJvciBzZXR0aW5nIENFQyBsb2dpY2FsIGFkZHJlc3Mgb24gRUM6ICVkXG4iLCByZXQpOwo+ Pj4+ICsJCXJldHVybiByZXQ7Cj4+Pj4gKwl9Cj4+Pj4gKwo+Pj4+ICsJcmV0dXJuIDA7Cj4+Pj4g K30KPj4+PiArCj4+Pj4gK3N0YXRpYyBpbnQgY3Jvc19lY19jZWNfdHJhbnNtaXQoc3RydWN0IGNl Y19hZGFwdGVyICphZGFwLCB1OCBhdHRlbXB0cywKPj4+PiArCQkJCXUzMiBzaWduYWxfZnJlZV90 aW1lLCBzdHJ1Y3QgY2VjX21zZyAqY2VjX21zZykKPj4+PiArewo+Pj4+ICsJc3RydWN0IGNyb3Nf ZWNfY2VjICpjcm9zX2VjX2NlYyA9IGFkYXAtPnByaXY7Cj4+Pj4gKwlzdHJ1Y3QgY3Jvc19lY19k ZXZpY2UgKmNyb3NfZWMgPSBjcm9zX2VjX2NlYy0+Y3Jvc19lYzsKPj4+PiArCXN0cnVjdCB7Cj4+ Pj4gKwkJc3RydWN0IGNyb3NfZWNfY29tbWFuZCBtc2c7Cj4+Pj4gKwkJc3RydWN0IGVjX3BhcmFt c19jZWNfd3JpdGUgZGF0YTsKPj4+PiArCX0gX19wYWNrZWQgbXNnOwo+Pj4KPj4+IC4uLiBtc2cg PSB7fTsKPj4+Cj4+Pj4gKwlpbnQgcmV0ID0gMDsKPj4+PiArCj4+Pj4gKwlpZiAoY2VjX21zZy0+ bGVuID4gTUFYX0NFQ19NU0dfTEVOKQo+Pj4+ICsJCXJldHVybiAtRUlOVkFMOwo+Pj4KPj4+IE5v IG5lZWQsIGNhbiBuZXZlciBoYXBwZW4uCj4+Cj4+IEZvcmdvciB0byByZW1vdmUgaXQsIHRoZSBB UEkgY2hhbmdlZCBpbiB0aGUgbWVhbnRpbWUsIG5vdyBpdCBjYW4gbmV2ZXIgaGFwcGVuICEKPj4K Pj4+Cj4+Pj4gKwo+Pj4+ICsJbWVtc2V0KCZtc2csIDAsIHNpemVvZihtc2cpKTsKPj4+Cj4+PiBh bmQgZHJvcCB0aGlzLgo+Pj4KPj4+PiArCW1zZy5tc2cuY29tbWFuZCA9IEVDX0NNRF9DRUNfV1JJ VEVfTVNHOwo+Pj4+ICsJbXNnLm1zZy5vdXRzaXplID0gY2VjX21zZy0+bGVuOwo+Pj4+ICsJbWVt Y3B5KG1zZy5kYXRhLm1zZywgY2VjX21zZy0+bXNnLCBjZWNfbXNnLT5sZW4pOwo+Pj4+ICsKPj4+ PiArCXJldCA9IGNyb3NfZWNfY21kX3hmZXJfc3RhdHVzKGNyb3NfZWMsICZtc2cubXNnKTsKPj4+ PiArCWlmIChyZXQgPCAwKSB7Cj4+Pj4gKwkJZGV2X2Vycihjcm9zX2VjLT5kZXYsCj4+Pj4gKwkJ CSJlcnJvciB3cml0dGluZyBDRUMgbXNnIG9uIEVDOiAlZFxuIiwgcmV0KTsKPj4+PiArCQlyZXR1 cm4gcmV0Owo+Pj4+ICsJfQo+Pj4+ICsKPj4+PiArCXJldHVybiAwOwo+Pj4+ICt9Cj4+Pj4gKwo+ Pj4+ICtzdGF0aWMgaW50IGNyb3NfZWNfY2VjX2FkYXBfZW5hYmxlKHN0cnVjdCBjZWNfYWRhcHRl ciAqYWRhcCwgYm9vbCBlbmFibGUpCj4+Pj4gK3sKPj4+PiArCXN0cnVjdCBjcm9zX2VjX2NlYyAq Y3Jvc19lY19jZWMgPSBhZGFwLT5wcml2Owo+Pj4+ICsJc3RydWN0IGNyb3NfZWNfZGV2aWNlICpj cm9zX2VjID0gY3Jvc19lY19jZWMtPmNyb3NfZWM7Cj4+Pj4gKwlzdHJ1Y3Qgewo+Pj4+ICsJCXN0 cnVjdCBjcm9zX2VjX2NvbW1hbmQgbXNnOwo+Pj4+ICsJCXN0cnVjdCBlY19wYXJhbXNfY2VjX3Nl dCBkYXRhOwo+Pj4+ICsJfSBfX3BhY2tlZCBtc2c7Cj4+Pj4gKwlpbnQgcmV0ID0gMDsKPj4+PiAr Cj4+Pj4gKwltZW1zZXQoJm1zZywgMCwgc2l6ZW9mKG1zZykpOwo+Pj4+ICsJbXNnLm1zZy5jb21t YW5kID0gRUNfQ01EX0NFQ19TRVQ7Cj4+Pj4gKwltc2cubXNnLm91dHNpemUgPSBzaXplb2YobXNn LmRhdGEpOwo+Pj4+ICsJbXNnLmRhdGEuY21kID0gQ0VDX0NNRF9FTkFCTEU7Cj4+Pj4gKwltc2cu ZGF0YS5lbmFibGUgPSBlbmFibGU7Cj4+Pj4gKwo+Pj4+ICsJcmV0ID0gY3Jvc19lY19jbWRfeGZl cl9zdGF0dXMoY3Jvc19lYywgJm1zZy5tc2cpOwo+Pj4+ICsJaWYgKHJldCA8IDApIHsKPj4+PiAr CQlkZXZfZXJyKGNyb3NfZWMtPmRldiwKPj4+PiArCQkJImVycm9yICVzYWJsaW5nIENFQyBvbiBF QzogJWRcbiIsCj4+Pj4gKwkJCShlbmFibGUgPyAiZW4iIDogImRpcyIpLCByZXQpOwo+Pj4+ICsJ CXJldHVybiByZXQ7Cj4+Pj4gKwl9Cj4+Pj4gKwo+Pj4+ICsJcmV0dXJuIDA7Cj4+Pj4gK30KPj4+ PiArCj4+Pj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2VjX2FkYXBfb3BzIGNyb3NfZWNfY2VjX29w cyA9IHsKPj4+PiArCS5hZGFwX2VuYWJsZSA9IGNyb3NfZWNfY2VjX2FkYXBfZW5hYmxlLAo+Pj4+ ICsJLmFkYXBfbG9nX2FkZHIgPSBjcm9zX2VjX2NlY19zZXRfbG9nX2FkZHIsCj4+Pj4gKwkuYWRh cF90cmFuc21pdCA9IGNyb3NfZWNfY2VjX3RyYW5zbWl0LAo+Pj4+ICt9Owo+Pj4+ICsKPj4+PiAr I2lmZGVmIENPTkZJR19QTV9TTEVFUAo+Pj4+ICtzdGF0aWMgaW50IGNyb3NfZWNfY2VjX3N1c3Bl bmQoc3RydWN0IGRldmljZSAqZGV2KQo+Pj4+ICt7Cj4+Pj4gKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2ID0gdG9fcGxhdGZvcm1fZGV2aWNlKGRldik7Cj4+Pj4gKwlzdHJ1Y3QgY3Jvc19l Y19jZWMgKmNyb3NfZWNfY2VjID0gZGV2X2dldF9kcnZkYXRhKCZwZGV2LT5kZXYpOwo+Pj4+ICsK Pj4+PiArCWlmIChkZXZpY2VfbWF5X3dha2V1cChkZXYpKQo+Pj4+ICsJCWVuYWJsZV9pcnFfd2Fr ZShjcm9zX2VjX2NlYy0+Y3Jvc19lYy0+aXJxKTsKPj4+PiArCj4+Pj4gKwlyZXR1cm4gMDsKPj4+ PiArfQo+Pj4+ICsKPj4+PiArc3RhdGljIGludCBjcm9zX2VjX2NlY19yZXN1bWUoc3RydWN0IGRl dmljZSAqZGV2KQo+Pj4+ICt7Cj4+Pj4gKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2ID0g dG9fcGxhdGZvcm1fZGV2aWNlKGRldik7Cj4+Pj4gKwlzdHJ1Y3QgY3Jvc19lY19jZWMgKmNyb3Nf ZWNfY2VjID0gZGV2X2dldF9kcnZkYXRhKCZwZGV2LT5kZXYpOwo+Pj4+ICsKPj4+PiArCWlmIChk ZXZpY2VfbWF5X3dha2V1cChkZXYpKQo+Pj4+ICsJCWRpc2FibGVfaXJxX3dha2UoY3Jvc19lY19j ZWMtPmNyb3NfZWMtPmlycSk7Cj4+Pj4gKwo+Pj4+ICsJcmV0dXJuIDA7Cj4+Pj4gK30KPj4+PiAr I2VuZGlmCj4+Pj4gKwo+Pj4+ICtzdGF0aWMgU0lNUExFX0RFVl9QTV9PUFMoY3Jvc19lY19jZWNf cG1fb3BzLAo+Pj4+ICsJY3Jvc19lY19jZWNfc3VzcGVuZCwgY3Jvc19lY19jZWNfcmVzdW1lKTsK Pj4+PiArCj4+Pj4gKwo+Pj4+ICtzdHJ1Y3QgY2VjX2RtaV9tYXRjaCB7Cj4+Pj4gKwljaGFyICpz eXNfdmVuZG9yOwo+Pj4+ICsJY2hhciAqcHJvZHVjdF9uYW1lOwo+Pj4+ICsJY2hhciAqZGV2bmFt ZTsKPj4+PiArCWNoYXIgKmNvbm47Cj4+Pj4gK307Cj4+Pj4gKwo+Pj4+ICtzdGF0aWMgY29uc3Qg c3RydWN0IGNlY19kbWlfbWF0Y2ggY2VjX2RtaV9tYXRjaF90YWJsZVtdID0gewo+Pj4+ICsJLyog R29vZ2xlIEZpenogKi8KPj4+PiArCXsgIkdvb2dsZSIsICJGaXp6IiwgIjAwMDA6MDA6MDIuMCIs ICJIRE1JLUEtMSIgfSwKPj4+PiArfTsKPj4+PiArCj4+Pj4gK3N0YXRpYyBpbnQgY3Jvc19lY19j ZWNfZ2V0X25vdGlmaWVyKHN0cnVjdCBjZWNfbm90aWZpZXIgKipub3RpZnkpCj4+Pj4gK3sKPj4+ PiArCWludCBpOwo+Pj4+ICsKPj4+PiArCWZvciAoaSA9IDAgOyBpIDwgQVJSQVlfU0laRShjZWNf ZG1pX21hdGNoX3RhYmxlKSA7ICsraSkgewo+Pj4+ICsJCWNvbnN0IHN0cnVjdCBjZWNfZG1pX21h dGNoICptID0gJmNlY19kbWlfbWF0Y2hfdGFibGVbaV07Cj4+Pj4gKwo+Pj4+ICsJCWlmIChkbWlf bWF0Y2goRE1JX1NZU19WRU5ET1IsIG0tPnN5c192ZW5kb3IpICYmCj4+Pj4gKwkJICAgIGRtaV9t YXRjaChETUlfUFJPRFVDVF9OQU1FLCBtLT5wcm9kdWN0X25hbWUpKSB7Cj4+Pj4gKwkJCSpub3Rp ZnkgPSBjZWNfbm90aWZpZXJfZ2V0X2J5bmFtZShtLT5kZXZuYW1lLCBtLT5jb25uKTsKPj4+Cj4+ PiBTZWUgbXkgY29tbWVudHMgZm9yIHBhdGNoIDIvNS4KPj4KPj4gSSB3aWxsIGNoYW5nZSB3aXRo IHlvdSBjb21tZW50LCBsb29rcyB3YXkgY2xlYW5lci4KPj4KPj4+Cj4+Pj4gKwkJCXJldHVybiAw Owo+Pj4+ICsJCX0KPj4+PiArCX0KPj4+PiArCj4+Pj4gKwlyZXR1cm4gLUVJTlZBTDsKPj4+PiAr fQo+Pj4+ICsKPj4+PiArc3RhdGljIGludCBjcm9zX2VjX2NlY19wcm9iZShzdHJ1Y3QgcGxhdGZv cm1fZGV2aWNlICpwZGV2KQo+Pj4+ICt7Cj4+Pj4gKwlzdHJ1Y3QgY3Jvc19lY19kZXYgKmVjX2Rl diA9IGRldl9nZXRfZHJ2ZGF0YShwZGV2LT5kZXYucGFyZW50KTsKPj4+PiArCXN0cnVjdCBjcm9z X2VjX2RldmljZSAqY3Jvc19lYyA9IGVjX2Rldi0+ZWNfZGV2Owo+Pj4+ICsJc3RydWN0IGNyb3Nf ZWNfY2VjICpjcm9zX2VjX2NlYzsKPj4+PiArCXVuc2lnbmVkIGludCBjZWNfY2FwcyA9IENFQ19D QVBfREVGQVVMVFM7Cj4+Pgo+Pj4gRG9lcyB0aGlzIG5lZWQgQ0VDX0NBUF9ORUVEU19IUEQ/IENh biBpdCBzdGlsbCB1c2UgQ0VDIGlmIHRoZXJlIGlzIG5vIEhQRAo+Pj4gc2lnbmFsPwo+Pgo+PiBO bywgWWVzLCB0aGUgRUMgRlcgaXMgaW5kZXBlbmRlbnQgb2YgdGhlIEhQRCBzdGF0dXMKPj4KPj4+ Cj4+Pj4gKwlpbnQgcmV0Owo+Pj4+ICsKPj4+PiArCWNyb3NfZWNfY2VjID0gZGV2bV9remFsbG9j KCZwZGV2LT5kZXYsIHNpemVvZigqY3Jvc19lY19jZWMpLAo+Pj4+ICsJCQkJICAgR0ZQX0tFUk5F TCk7Cj4+Pj4gKwlpZiAoIWNyb3NfZWNfY2VjKQo+Pj4+ICsJCXJldHVybiAtRU5PTUVNOwo+Pj4+ ICsKPj4+PiArCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGNyb3NfZWNfY2VjKTsKPj4+PiAr CWNyb3NfZWNfY2VjLT5jcm9zX2VjID0gY3Jvc19lYzsKPj4+PiArCj4+Pj4gKwlyZXQgPSBjcm9z X2VjX2NlY19nZXRfbm90aWZpZXIoJmNyb3NfZWNfY2VjLT5ub3RpZnkpOwo+Pj4+ICsJaWYgKHJl dCkgewo+Pj4+ICsJCWRldl93YXJuKCZwZGV2LT5kZXYsICJubyBDRUMgbm90aWZpZXIgYXZhaWxh YmxlXG4iKTsKPj4+PiArCQljZWNfY2FwcyB8PSBDRUNfQ0FQX1BIWVNfQUREUjsKPj4+Cj4+PiBD YW4gdGhpcyBoYXBwZW4/IFdoYXQgaGFyZHdhcmUgaGFzIHRoaXM/IEkgYW0gc3Ryb25nbHkgb3Bw b3NlZCB0byBDRUMgZHJpdmVycwo+Pj4gdXNpbmcgdGhpcyBjYXBhYmlsaXR5IHVubGVzcyB0aGVy ZSBpcyBubyBvdGhlciBvcHRpb24uIEl0J3MgYSBwYWluIGZvciB1c2Vyc3BhY2UuCj4+Cj4+IEl0 J3MgaW4gY2FzZSBhbiBIVyBoYXZpbmcgYSBDRUMgY2FwYWJsZSBGVyBidXQgbm90IGluIHRoZSBj ZWNfZG1pX21hdGNoX3RhYmxlLCBpbiB0aGlzIGNhc2UKPj4gaXQgd29uJ3QgZmFpbCBidXQgc3Rp bGwgZW5hYmxlIHRoZSBDRUMgaW50ZXJmYWNlIHdpdGhvdXQgYSBub3RpZmllci4KPiAKPiBJIGRv bid0IHRoaW5rIHRoYXQncyBhIGdvb2QgaWRlYS4gQ0FQX1BIWVNfQUREUiBzaG91bGQgKm9ubHkq IGJlIHVzZWQgaW4gc2l0dWF0aW9ucwo+IHdoZXJlIGl0IGlzIHRydWx5IGltcG9zc2libGUgdG8g dGVsbCB3aGljaCBvdXRwdXQgaXMgY29ubmVjdGVkIHRvIHRoZSBDRUMgYWRhcHRlci4KPiBUaGF0 J3MgdGhlIGNhc2Ugd2l0aCBlLmcuIFVTQiBDRUMgZG9uZ2xlcyB3aGVyZSB5b3UgaGF2ZSBubyBp ZGVhIGhvdyB0aGUgdXNlcgo+IGNvbm5lY3RlZCB0aGUgSERNSSBjYWJsZXMuCj4gCj4gQnV0IEkg YXNzdW1lIHRoYXQgaW4gdGhpcyBjYXNlIGl0IGp1c3QgbWVhbnMgdGhhdCB0aGUgY2VjX2RtaV9t YXRjaF90YWJsZSBuZWVkcwo+IHRvIGJlIHVwZGF0ZWQsIGkuZS4gaXQgaXMgYSBkcml2ZXIgYnVn LgoKWWVwLCBtYXliZSBhIGRldl93YXJuIHNob3VsZCBiZSBhZGRlZCB0byBub3RpZnkgdGhpcyBi dWcgPwoKPiAKPiBBbm90aGVyIHRoaW5nOiB0aGlzIGRyaXZlciBhc3N1bWVzIHRoYXQgdGhlcmUg aXMgb25seSBvbmUgQ0VDIGFkYXB0ZXIgZm9yIG9ubHkKPiBvbmUgSERNSSBvdXRwdXQuIEJ1dCB3 aGF0IGlmIHRoZXJlIGFyZSBtb3JlIEhETUkgb3V0cHV0cz8gV2lsbCB0aGVyZSBiZSBvbmUKPiBD RUMgYWRhcHRlciBmb3IgZWFjaCBvdXRwdXQ/IE9yIGRvZXMgdGhlIGhhcmR3YXJlIGhhdmUgbm8g cHJvdmlzaW9ucyBmb3IgdGhhdD8KClRoZSBjdXJyZW50IEVDIGludGVyZmFjZSBvbmx5IGV4cG9z ZXMgYSBzaW5nbGUgQ0VDIGludGVyZmFjZSBmb3Igbm93LCB0aGVyZSBpcyBubwpwbGFuIHlldCBm b3IgbXVsdGlwbGUgSERNSSBvdXRwdXRzIGhhbmRsaW5nLgoKPiAKPiBTb21ldGhpbmcgc2hvdWxk IGJlIG1lbnRpb25lZCBhYm91dCB0aGlzIGluIGEgY29tbWVudC4KCk9rCgpUaGFua3MsCk5laWwK Cj4gCj4gUmVnYXJkcywKPiAKPiAJSGFucwo+IAo+Pgo+Pj4KPj4+PiArCX0gZWxzZSBpZiAoIWNy b3NfZWNfY2VjLT5ub3RpZnkpIHsKPj4+PiArCQlyZXR1cm4gLUVQUk9CRV9ERUZFUjsKPj4+PiAr CX0KPj4+PiArCj4+Pj4gKwlyZXQgPSBkZXZpY2VfaW5pdF93YWtldXAoJnBkZXYtPmRldiwgMSk7 Cj4+Pj4gKwlpZiAocmV0KSB7Cj4+Pj4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFpbGVkIHRv IGluaXRpYWxpemUgd2FrZXVwXG4iKTsKPj4+PiArCQlyZXR1cm4gcmV0Owo+Pj4+ICsJfQo+Pj4+ ICsKPj4+PiArCWNyb3NfZWNfY2VjLT5hZGFwID0gY2VjX2FsbG9jYXRlX2FkYXB0ZXIoJmNyb3Nf ZWNfY2VjX29wcywgY3Jvc19lY19jZWMsCj4+Pj4gKwkJCQkJCSBEUlZfTkFNRSwgY2VjX2NhcHMs IDEpOwo+Pj4+ICsJaWYgKElTX0VSUihjcm9zX2VjX2NlYy0+YWRhcCkpCj4+Pj4gKwkJcmV0dXJu IFBUUl9FUlIoY3Jvc19lY19jZWMtPmFkYXApOwo+Pj4+ICsKPj4+PiArCWNyb3NfZWNfY2VjLT5h ZGFwLT5vd25lciA9IFRISVNfTU9EVUxFOwo+Pj4KPj4+IFRoaXMgY2FuIGJlIGRyb3BwZWQsIGNl Y19yZWdpc3Rlcl9hZGFwdGVyKCkgc2V0cyB0aGlzIGFscmVhZHkuCj4+Cj4+IE5vdGVkLgo+Pgo+ Pj4KPj4+PiArCj4+Pj4gKwkvKiBHZXQgQ0VDIGV2ZW50cyBmcm9tIHRoZSBFQy4gKi8KPj4+PiAr CWNyb3NfZWNfY2VjLT5ub3RpZmllci5ub3RpZmllcl9jYWxsID0gY3Jvc19lY19jZWNfZXZlbnQ7 Cj4+Pj4gKwlyZXQgPSBibG9ja2luZ19ub3RpZmllcl9jaGFpbl9yZWdpc3RlcigmY3Jvc19lYy0+ ZXZlbnRfbm90aWZpZXIsCj4+Pj4gKwkJCQkJICAgICAgICZjcm9zX2VjX2NlYy0+bm90aWZpZXIp Owo+Pj4+ICsJaWYgKHJldCkgewo+Pj4+ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgImZhaWxlZCB0 byByZWdpc3RlciBub3RpZmllclxuIik7Cj4+Pj4gKwkJY2VjX2RlbGV0ZV9hZGFwdGVyKGNyb3Nf ZWNfY2VjLT5hZGFwKTsKPj4+PiArCQlyZXR1cm4gcmV0Owo+Pj4+ICsJfQo+Pj4+ICsKPj4+PiAr CXJldCA9IGNlY19yZWdpc3Rlcl9hZGFwdGVyKGNyb3NfZWNfY2VjLT5hZGFwLCAmcGRldi0+ZGV2 KTsKPj4+PiArCWlmIChyZXQgPCAwKSB7Cj4+Pj4gKwkJY2VjX2RlbGV0ZV9hZGFwdGVyKGNyb3Nf ZWNfY2VjLT5hZGFwKTsKPj4+PiArCQlyZXR1cm4gcmV0Owo+Pj4+ICsJfQo+Pj4+ICsKPj4+PiAr CWNlY19yZWdpc3Rlcl9jZWNfbm90aWZpZXIoY3Jvc19lY19jZWMtPmFkYXAsIGNyb3NfZWNfY2Vj LT5ub3RpZnkpOwo+Pj4+ICsKPj4+PiArCXJldHVybiAwOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICtz dGF0aWMgaW50IGNyb3NfZWNfY2VjX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2 KQo+Pj4+ICt7Cj4+Pj4gKwlzdHJ1Y3QgY3Jvc19lY19jZWMgKmNyb3NfZWNfY2VjID0gcGxhdGZv cm1fZ2V0X2RydmRhdGEocGRldik7Cj4+Pj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ ZGV2Owo+Pj4+ICsJaW50IHJldDsKPj4+PiArCj4+Pj4gKwlyZXQgPSBibG9ja2luZ19ub3RpZmll cl9jaGFpbl91bnJlZ2lzdGVyKAo+Pj4+ICsJCQkmY3Jvc19lY19jZWMtPmNyb3NfZWMtPmV2ZW50 X25vdGlmaWVyLAo+Pj4+ICsJCQkmY3Jvc19lY19jZWMtPm5vdGlmaWVyKTsKPj4+PiArCj4+Pj4g KwlpZiAocmV0KSB7Cj4+Pj4gKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gdW5yZWdpc3RlciBu b3RpZmllclxuIik7Cj4+Pj4gKwkJcmV0dXJuIHJldDsKPj4+PiArCX0KPj4+PiArCj4+Pj4gKwlj ZWNfdW5yZWdpc3Rlcl9hZGFwdGVyKGNyb3NfZWNfY2VjLT5hZGFwKTsKPj4+PiArCj4+Pj4gKwlp ZiAoY3Jvc19lY19jZWMtPm5vdGlmeSkKPj4+PiArCQljZWNfbm90aWZpZXJfcHV0KGNyb3NfZWNf Y2VjLT5ub3RpZnkpOwo+Pj4+ICsKPj4+PiArCXJldHVybiAwOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBjcm9zX2VjX2NlY19kcml2ZXIgPSB7Cj4+ Pj4gKwkucHJvYmUgPSBjcm9zX2VjX2NlY19wcm9iZSwKPj4+PiArCS5yZW1vdmUgID0gY3Jvc19l Y19jZWNfcmVtb3ZlLAo+Pj4+ICsJLmRyaXZlciA9IHsKPj4+PiArCQkubmFtZSA9IERSVl9OQU1F LAo+Pj4+ICsJCS5wbSA9ICZjcm9zX2VjX2NlY19wbV9vcHMsCj4+Pj4gKwl9LAo+Pj4+ICt9Owo+ Pj4+ICsKPj4+PiArbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihjcm9zX2VjX2NlY19kcml2ZXIpOwo+ Pj4+ICsKPj4+PiArTU9EVUxFX0RFU0NSSVBUSU9OKCJDRUMgZHJpdmVyIGZvciBDaHJvbWUgT1Mg RUNzIik7Cj4+Pj4gK01PRFVMRV9BVVRIT1IoIk5laWwgQXJtc3Ryb25nIDxuYXJtc3Ryb25nQGJh eWxpYnJlLmNvbT4iKTsKPj4+PiArTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo+Pj4+ICtNT0RVTEVf QUxJQVMoInBsYXRmb3JtOiIgRFJWX05BTUUpOwo+Pj4+Cj4+Pgo+Pj4gUmVnYXJkcywKPj4+Cj4+ PiAJSGFucwo+Pj4KPj4KPj4gVGhhbmtzLAo+PiBOZWlsCj4+Cj4gCgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRy aS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5v cmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK