From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751571AbeABPv3 (ORCPT + 1 other); Tue, 2 Jan 2018 10:51:29 -0500 Received: from mail1.bemta5.messagelabs.com ([195.245.231.146]:18395 "EHLO mail1.bemta5.messagelabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751444AbeABPu5 (ORCPT ); Tue, 2 Jan 2018 10:50:57 -0500 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprMKsWRWlGSWpSXmKPExsUSt3OpsW78Ku8 og86ZghbNi9ezWbw5Pp3Jomv1ThaLy7vmsFl87j3CaLFoWSuzxZOFZ5gsGhe8Z7E4vbvE4s/z W2wOXB47Z91l99i0qpPNY97JQI/9c9ewe7zfd5XNY+f3BnaPz5vkAtijWDPzkvIrElgzPr05y VTwoYWxYvrObvYGxnkFXYycHEIC6xglHh9Ng7ArJBZvXMoKYvMKZEr83juPvYuRg4NTwF1i6y dmEFNIwE1i1ts6kAo2AQuJyScesIGEWQRUJJbucQMJCwtESNxr/sbSxcjFISIwj0ni1Ya7bCA JZoE6id7fb1kgpgtKnJz5hAUiLiFx8MULZogLDCROL2gEi0sI2EtMf38VbK2EgL5E47FYiLCh xPdZ36BKzCV23L7BOoFRcBaSqbOQTF3AyLSKUaM4tagstUjXyEAvqSgzPaMkNzEzR9fQwFQvN 7W4ODE9NScxqVgvOT93EyMwUuoZGBh3MDbO9jvEKMnBpCTKm5PqHSXEl5SfUpmRWJwRX1Sak1 p8iFGDg0Og5eLJg0xSLHn5ealKEryRK4HqBItS01Mr0jJzgLEMUyrBwaMkwpsBkuYtLkjMLc5 Mh0idYtTleDbzdQOzENgMKXGIIgGQoozSPLgRsLRyiVFWSpiXkYGBQYinILUoN7MEVf4VozgH o5IwrzbIFJ7MvBK4Ta+AjmACOuLPeU+QI0oSEVJSDYyKbZdlYq8eeNrbxP2qnm/io69N0RtW3 gq4L6lzZ6qq1HJuZeOTM7VctdWTlE5leAWJ7O6+U1pxzLxVKKxtvvTCpac4K0QZm/Zfebsz8P JBs34RjW57rnny+oLzZvHFuD8R27ZpdfXvqT9EfcozzCd7bz8cmbPR8v2l327f4vv2LpyzbM8 /Y3klluKMREMt5qLiRAC3bqSOJgMAAA== X-Env-Sender: Adam.Thomson.Opensource@diasemi.com X-Msg-Ref: server-7.tower-179.messagelabs.com!1514908255!108298806!1 X-Originating-IP: [94.185.165.51] X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Message-ID: In-Reply-To: References: From: Adam Thomson Date: Tue, 2 Jan 2018 15:50:54 +0000 Subject: [PATCH v4 6/7] typec: tcpm: Represent source supply through power_supply class To: Heikki Krogerus , Guenter Roeck , Greg Kroah-Hartman , Sebastian Reichel , Hans de Goede , Yueyao Zhu , Rui Miguel Silva CC: , , , MIME-Version: 1.0 Content-Type: text/plain X-KSE-AttachmentFiltering-Interceptor-Info: protection disabled X-KSE-ServerInfo: sw-ex-cashub01.diasemi.com, 9 X-KSE-Antivirus-Interceptor-Info: scan successful X-KSE-Antivirus-Info: Clean, bases: 02/01/2018 11:56:00 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: This commit adds a power_supply class instance to represent a PD source's voltage and current properties. This provides an interface for reading these properties from user-space or other drivers. For PPS enabled Sources, this also provides write access to set the current and voltage and allows for swapping between standard PDO and PPS APDO. As this represents a superset of the information provided in the fusb302 driver, the power_supply instance in that code is removed as part of this change, so reverting the commit titled 'typec: tcpm: Represent source supply through power_supply class' Signed-off-by: Adam Thomson --- .../ABI/testing/sysfs-class-power-tcpm-source-psy | 92 ++++++++ drivers/usb/typec/Kconfig | 1 + drivers/usb/typec/fusb302/Kconfig | 2 +- drivers/usb/typec/fusb302/fusb302.c | 63 +----- drivers/usb/typec/tcpm.c | 233 ++++++++++++++++++++- 5 files changed, 328 insertions(+), 63 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy diff --git a/Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy b/Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy new file mode 100644 index 0000000..4986cba --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy @@ -0,0 +1,92 @@ +What: /sys/class/power_supply/tcpm-source-psy/type +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the main type of source supply. + Type-C is a USB standard so this property always returns "USB". + +What: /sys/class/power_supply/tcpm-source-psy/connected_type +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the type of source supply that is + connected, if the supply is online. The value is always Type C + unless a source has been attached which is identified as USB-PD capable. + + Valid values: + - "USB_TYPE_C" : Type C connected supply, not UBS-PD capable + (default value) + - "USB_PD" : USB-PD capable source supply connected + - "USB_PD_PPS" : USB-PD PPS capable source supply connected + +What: /sys/class/power_supply/tcpm-source-psy/online +Date: December 2017 +Contact: Adam Thomson +Description: + This read-write property describes the online state of the source + supply. When the value of this property is not 0, and the supply allows + it, then it's possible to switch between online states (i.e. 1 -> 2, + 2 -> 1) + + Valid values: + - 0 : Offline, no source supply attached + - 1 : Fixed Online, Type-C or USB-PD capable supply + attached, non-configurable current and voltage + properties in this state. + - 2 : PPS Online, USB-PD PPS feature enabled, 'current_now' + and 'voltage_now' properties can be modified in this + state. Re-writing of this value again, once already + set, will re-request the same configured voltage and + current values. This can be used as a keep-alive for + the PPS connection. + [NOTE: This is value only selectable if + 'connected_type' reports a value of "USB_PD_PPS"] + +What: /sys/class/power_supply/tcpm-source-psy/voltage_min +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the minimum voltage the source supply + can provide. + + Value in microvolts. + +What: /sys/class/power_supply/tcpm-source-psy/voltage_max +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the maximum voltage the source supply + can provide. + + Value in microvolts. + +What: /sys/class/power_supply/tcpm-source-psy/voltage_now +Date: December 2017 +Contact: Adam Thomson +Description: + This read-write property describes the voltage the source supply is + providing now. This property can only be written to if the source supply + is in online state '2' (PPS enabled), otherwise it's read-only + information. + + Value in microvolts. + +What: /sys/class/power_supply/tcpm-source-psy/current_max +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the maximum current the source supply + can provide. + + Value in microamps. + +What: /sys/class/power_supply/tcpm-source-psy/current_now +Date: December 2017 +Contact: Adam Thomson +Description: + This read-write property describes the current the source supply can + provide now. This property can only be written to if the source supply + is in online state '2' (PPS enabled), otherwise it's read-only + information. + + Value in microamps. diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index bcb2744..1ef606d 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -48,6 +48,7 @@ if TYPEC config TYPEC_TCPM tristate "USB Type-C Port Controller Manager" depends on USB + select POWER_SUPPLY help The Type-C Port Controller Manager provides a USB PD and USB Type-C state machine for use with Type-C Port Controllers. diff --git a/drivers/usb/typec/fusb302/Kconfig b/drivers/usb/typec/fusb302/Kconfig index 48a4f2f..fce099f 100644 --- a/drivers/usb/typec/fusb302/Kconfig +++ b/drivers/usb/typec/fusb302/Kconfig @@ -1,6 +1,6 @@ config TYPEC_FUSB302 tristate "Fairchild FUSB302 Type-C chip driver" - depends on I2C && POWER_SUPPLY + depends on I2C help The Fairchild FUSB302 Type-C chip driver that works with Type-C Port Controller Manager to provide USB PD and USB diff --git a/drivers/usb/typec/fusb302/fusb302.c b/drivers/usb/typec/fusb302/fusb302.c index 9ce4756..82fddc7 100644 --- a/drivers/usb/typec/fusb302/fusb302.c +++ b/drivers/usb/typec/fusb302/fusb302.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -99,11 +98,6 @@ struct fusb302_chip { /* lock for sharing chip states */ struct mutex lock; - /* psy + psy status */ - struct power_supply *psy; - u32 current_limit; - u32 supply_voltage; - /* chip status */ enum toggling_mode toggling_mode; enum src_current_status src_current_status; @@ -872,13 +866,11 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge) chip->vbus_on = on; fusb302_log(chip, "vbus := %s", on ? "On" : "Off"); } - if (chip->charge_on == charge) { + if (chip->charge_on == charge) fusb302_log(chip, "charge is already %s", charge ? "On" : "Off"); - } else { + else chip->charge_on = charge; - power_supply_changed(chip->psy); - } done: mutex_unlock(&chip->lock); @@ -894,11 +886,6 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv) fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)", max_ma, mv); - chip->supply_voltage = mv; - chip->current_limit = max_ma; - - power_supply_changed(chip->psy); - return 0; } @@ -1697,43 +1684,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) return IRQ_HANDLED; } -static int fusb302_psy_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct fusb302_chip *chip = power_supply_get_drvdata(psy); - - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = chip->charge_on; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = chip->supply_voltage * 1000; /* mV -> µV */ - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - val->intval = chip->current_limit * 1000; /* mA -> µA */ - break; - default: - return -ENODATA; - } - - return 0; -} - -static enum power_supply_property fusb302_psy_properties[] = { - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_MAX, -}; - -static const struct power_supply_desc fusb302_psy_desc = { - .name = "fusb302-typec-source", - .type = POWER_SUPPLY_TYPE_USB_TYPE_C, - .properties = fusb302_psy_properties, - .num_properties = ARRAY_SIZE(fusb302_psy_properties), - .get_property = fusb302_psy_get_property, -}; - static int init_gpio(struct fusb302_chip *chip) { struct device_node *node; @@ -1773,7 +1723,6 @@ static int fusb302_probe(struct i2c_client *client, struct fusb302_chip *chip; struct i2c_adapter *adapter; struct device *dev = &client->dev; - struct power_supply_config cfg = {}; const char *name; int ret = 0; u32 v; @@ -1820,14 +1769,6 @@ static int fusb302_probe(struct i2c_client *client, return -EPROBE_DEFER; } - cfg.drv_data = chip; - chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg); - if (IS_ERR(chip->psy)) { - ret = PTR_ERR(chip->psy); - dev_err(chip->dev, "Error registering power-supply: %d\n", ret); - return ret; - } - ret = fusb302_debugfs_init(chip); if (ret < 0) return ret; diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index b66d26c..b86a51c 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -281,6 +282,11 @@ struct tcpm_port { u32 current_limit; u32 supply_voltage; + /* Used to export TA voltage and current */ + struct power_supply *psy; + struct power_supply_desc psy_desc; + enum power_supply_conn_type connected_type; + u32 bist_request; /* PD state for Vendor Defined Messages */ @@ -1893,6 +1899,7 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, int ret = -EINVAL; port->pps_data.supported = false; + port->connected_type = POWER_SUPPLY_CONN_TYPE_USB_PD; /* * Select the source PDO providing the most power which has a @@ -1974,8 +1981,11 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, } break; case PDO_TYPE_APDO: - if (pdo_apdo_type(pdo) == APDO_TYPE_PPS) + if (pdo_apdo_type(pdo) == APDO_TYPE_PPS) { port->pps_data.supported = true; + port->connected_type = + POWER_SUPPLY_CONN_TYPE_USB_PD_PPS; + } continue; default: tcpm_log(port, "Invalid PDO type, ignoring"); @@ -2459,6 +2469,9 @@ static void tcpm_reset_port(struct tcpm_port *port) port->try_snk_count = 0; port->supply_voltage = 0; port->current_limit = 0; + port->connected_type = POWER_SUPPLY_CONN_TYPE_USB_TYPE_C; + + power_supply_changed(port->psy); } static void tcpm_detach(struct tcpm_port *port) @@ -2991,6 +3004,8 @@ static void run_state_machine(struct tcpm_port *port) tcpm_pps_complete(port, port->pps_status); + power_supply_changed(port->psy); + break; /* Accessory states */ @@ -4170,6 +4185,218 @@ static int nr_type_pdos(const u32 *pdo, unsigned int nr_pdo, return count; } +/* Power Supply access to expose source power information */ +enum tcpm_psy_online_states { + TCPM_PSY_OFFLINE = 0, + TCPM_PSY_FIXED_ONLINE, + TCPM_PSY_PROG_ONLINE, +}; + +static enum power_supply_property tcpm_psy_props[] = { + POWER_SUPPLY_PROP_CONNECTED_TYPE, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_MIN, + POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_CURRENT_NOW, +}; + +static int tcpm_psy_get_online(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->vbus_charge) { + if (port->pps_data.active) + val->intval = TCPM_PSY_PROG_ONLINE; + else + val->intval = TCPM_PSY_FIXED_ONLINE; + } else { + val->intval = TCPM_PSY_OFFLINE; + } + + return 0; +} + +static int tcpm_psy_get_voltage_min(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->pps_data.active) + val->intval = port->pps_data.min_volt * 1000; + else + val->intval = port->supply_voltage * 1000; + + return 0; +} + +static int tcpm_psy_get_voltage_max(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->pps_data.active) + val->intval = port->pps_data.max_volt * 1000; + else + val->intval = port->supply_voltage * 1000; + + return 0; +} + +static int tcpm_psy_get_voltage_now(struct tcpm_port *port, + union power_supply_propval *val) +{ + val->intval = port->supply_voltage * 1000; + + return 0; +} + +static int tcpm_psy_get_current_max(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->pps_data.active) + val->intval = port->pps_data.max_curr * 1000; + else + val->intval = port->current_limit * 1000; + + return 0; +} + +static int tcpm_psy_get_current_now(struct tcpm_port *port, + union power_supply_propval *val) +{ + val->intval = port->current_limit * 1000; + + return 0; +} + +static int tcpm_psy_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct tcpm_port *port = power_supply_get_drvdata(psy); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_CONNECTED_TYPE: + val->intval = port->connected_type; + break; + case POWER_SUPPLY_PROP_ONLINE: + ret = tcpm_psy_get_online(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN: + ret = tcpm_psy_get_voltage_min(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + ret = tcpm_psy_get_voltage_max(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = tcpm_psy_get_voltage_now(port, val); + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + ret = tcpm_psy_get_current_max(port, val); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + ret = tcpm_psy_get_current_now(port, val); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int tcpm_psy_set_online(struct tcpm_port *port, + const union power_supply_propval *val) +{ + int ret; + + switch (val->intval) { + case TCPM_PSY_FIXED_ONLINE: + ret = tcpm_pps_activate(port, false); + break; + case TCPM_PSY_PROG_ONLINE: + ret = tcpm_pps_activate(port, true); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int tcpm_psy_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct tcpm_port *port = power_supply_get_drvdata(psy); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + ret = tcpm_psy_set_online(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if ((val->intval < (port->pps_data.min_volt * 1000)) || + (val->intval > (port->pps_data.max_volt * 1000))) + ret = -EINVAL; + else + ret = tcpm_pps_set_out_volt(port, (val->intval / 1000)); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + if (val->intval > (port->pps_data.max_curr * 1000)) + ret = -EINVAL; + else + ret = tcpm_pps_set_op_curr(port, (val->intval / 1000)); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int tcpm_psy_prop_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_CURRENT_NOW: + return 1; + default: + return 0; + } +} + +static enum power_supply_conn_type tcpm_psy_conn_types[] = { + POWER_SUPPLY_CONN_TYPE_USB_TYPE_C, + POWER_SUPPLY_CONN_TYPE_USB_PD, + POWER_SUPPLY_CONN_TYPE_USB_PD_PPS, +}; + +static int devm_tcpm_psy_register(struct tcpm_port *port) +{ + struct power_supply_config psy_cfg = {}; + + psy_cfg.drv_data = port; + port->psy_desc.name = "tcpm-source-psy", + port->psy_desc.type = POWER_SUPPLY_TYPE_USB, + port->psy_desc.conn_types = tcpm_psy_conn_types; + port->psy_desc.num_conn_types = ARRAY_SIZE(tcpm_psy_conn_types); + port->psy_desc.properties = tcpm_psy_props, + port->psy_desc.num_properties = ARRAY_SIZE(tcpm_psy_props), + port->psy_desc.get_property = tcpm_psy_get_prop, + port->psy_desc.set_property = tcpm_psy_set_prop, + port->psy_desc.property_is_writeable = tcpm_psy_prop_writeable, + + port->connected_type = POWER_SUPPLY_CONN_TYPE_USB_TYPE_C; + + port->psy = devm_power_supply_register(port->dev, &port->psy_desc, + &psy_cfg); + + return PTR_ERR_OR_ZERO(port->psy); +} + struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) { struct tcpm_port *port; @@ -4253,6 +4480,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) port->partner_desc.identity = &port->partner_ident; port->port_type = tcpc->config->type; + err = devm_tcpm_psy_register(port); + if (err) + goto out_destroy_wq; + port->typec_port = typec_register_port(port->dev, &port->typec_caps); if (!port->typec_port) { err = -ENOMEM; -- 1.9.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v4,6/7] typec: tcpm: Represent source supply through power_supply class From: "Opensource \[Adam Thomson\]" Message-Id: Date: Tue, 2 Jan 2018 15:50:54 +0000 To: Heikki Krogerus , Guenter Roeck , Greg Kroah-Hartman , Sebastian Reichel , Hans de Goede , Yueyao Zhu , Rui Miguel Silva Cc: linux-usb@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, support.opensource@diasemi.com List-ID: VGhpcyBjb21taXQgYWRkcyBhIHBvd2VyX3N1cHBseSBjbGFzcyBpbnN0YW5jZSB0byByZXByZXNl bnQgYQpQRCBzb3VyY2UncyB2b2x0YWdlIGFuZCBjdXJyZW50IHByb3BlcnRpZXMuIFRoaXMgcHJv dmlkZXMgYW4KaW50ZXJmYWNlIGZvciByZWFkaW5nIHRoZXNlIHByb3BlcnRpZXMgZnJvbSB1c2Vy LXNwYWNlIG9yIG90aGVyCmRyaXZlcnMuCgpGb3IgUFBTIGVuYWJsZWQgU291cmNlcywgdGhpcyBh bHNvIHByb3ZpZGVzIHdyaXRlIGFjY2VzcyB0byBzZXQKdGhlIGN1cnJlbnQgYW5kIHZvbHRhZ2Ug YW5kIGFsbG93cyBmb3Igc3dhcHBpbmcgYmV0d2VlbiBzdGFuZGFyZApQRE8gYW5kIFBQUyBBUERP LgoKQXMgdGhpcyByZXByZXNlbnRzIGEgc3VwZXJzZXQgb2YgdGhlIGluZm9ybWF0aW9uIHByb3Zp ZGVkIGluIHRoZQpmdXNiMzAyIGRyaXZlciwgdGhlIHBvd2VyX3N1cHBseSBpbnN0YW5jZSBpbiB0 aGF0IGNvZGUgaXMgcmVtb3ZlZAphcyBwYXJ0IG9mIHRoaXMgY2hhbmdlLCBzbyByZXZlcnRpbmcg dGhlIGNvbW1pdCB0aXRsZWQKJ3R5cGVjOiB0Y3BtOiBSZXByZXNlbnQgc291cmNlIHN1cHBseSB0 aHJvdWdoIHBvd2VyX3N1cHBseSBjbGFzcycKClNpZ25lZC1vZmYtYnk6IEFkYW0gVGhvbXNvbiA8 QWRhbS5UaG9tc29uLk9wZW5zb3VyY2VAZGlhc2VtaS5jb20+Ci0tLQogLi4uL0FCSS90ZXN0aW5n L3N5c2ZzLWNsYXNzLXBvd2VyLXRjcG0tc291cmNlLXBzeSAgfCAgOTIgKysrKysrKysKIGRyaXZl cnMvdXNiL3R5cGVjL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAxICsKIGRy aXZlcnMvdXNiL3R5cGVjL2Z1c2IzMDIvS2NvbmZpZyAgICAgICAgICAgICAgICAgIHwgICAyICst CiBkcml2ZXJzL3VzYi90eXBlYy9mdXNiMzAyL2Z1c2IzMDIuYyAgICAgICAgICAgICAgICB8ICA2 MyArLS0tLS0KIGRyaXZlcnMvdXNiL3R5cGVjL3RjcG0uYyAgICAgICAgICAgICAgICAgICAgICAg ICAgIHwgMjMzICsrKysrKysrKysrKysrKysrKysrLQogNSBmaWxlcyBjaGFuZ2VkLCAzMjggaW5z ZXJ0aW9ucygrKSwgNjMgZGVsZXRpb25zKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRh dGlvbi9BQkkvdGVzdGluZy9zeXNmcy1jbGFzcy1wb3dlci10Y3BtLXNvdXJjZS1wc3kKCmRpZmYg LS1naXQgYS9Eb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5nL3N5c2ZzLWNsYXNzLXBvd2VyLXRjcG0t c291cmNlLXBzeSBiL0RvY3VtZW50YXRpb24vQUJJL3Rlc3Rpbmcvc3lzZnMtY2xhc3MtcG93ZXIt dGNwbS1zb3VyY2UtcHN5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5ODZj YmEKLS0tIC9kZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL0FCSS90ZXN0aW5nL3N5c2ZzLWNs YXNzLXBvd2VyLXRjcG0tc291cmNlLXBzeQpAQCAtMCwwICsxLDkyIEBACitXaGF0OiAJCS9zeXMv Y2xhc3MvcG93ZXJfc3VwcGx5L3RjcG0tc291cmNlLXBzeS90eXBlCitEYXRlOgkJRGVjZW1iZXIg MjAxNworQ29udGFjdDoJQWRhbSBUaG9tc29uIDxBZGFtLlRob21zb24uT3BlbnNvdXJjZUBkaWFz ZW1pLmNvbT4KK0Rlc2NyaXB0aW9uOgorCVRoaXMgcmVhZC1vbmx5IHByb3BlcnR5IGRlc2NyaWJl cyB0aGUgbWFpbiB0eXBlIG9mIHNvdXJjZSBzdXBwbHkuCisJVHlwZS1DIGlzIGEgVVNCIHN0YW5k YXJkIHNvIHRoaXMgcHJvcGVydHkgYWx3YXlzIHJldHVybnMgIlVTQiIuCisKK1doYXQ6IAkJL3N5 cy9jbGFzcy9wb3dlcl9zdXBwbHkvdGNwbS1zb3VyY2UtcHN5L2Nvbm5lY3RlZF90eXBlCitEYXRl OgkJRGVjZW1iZXIgMjAxNworQ29udGFjdDoJQWRhbSBUaG9tc29uIDxBZGFtLlRob21zb24uT3Bl bnNvdXJjZUBkaWFzZW1pLmNvbT4KK0Rlc2NyaXB0aW9uOgorCVRoaXMgcmVhZC1vbmx5IHByb3Bl cnR5IGRlc2NyaWJlcyB0aGUgdHlwZSBvZiBzb3VyY2Ugc3VwcGx5IHRoYXQgaXMKKwljb25uZWN0 ZWQsIGlmIHRoZSBzdXBwbHkgaXMgb25saW5lLiBUaGUgdmFsdWUgaXMgYWx3YXlzIFR5cGUgQwor CXVubGVzcyBhIHNvdXJjZSBoYXMgYmVlbiBhdHRhY2hlZCB3aGljaCBpcyBpZGVudGlmaWVkIGFz IFVTQi1QRCBjYXBhYmxlLgorCisJVmFsaWQgdmFsdWVzOgorCQktICJVU0JfVFlQRV9DIgk6IFR5 cGUgQyBjb25uZWN0ZWQgc3VwcGx5LCBub3QgVUJTLVBEIGNhcGFibGUKKwkJCQkgIChkZWZhdWx0 IHZhbHVlKQorCQktICJVU0JfUEQiCTogVVNCLVBEIGNhcGFibGUgc291cmNlIHN1cHBseSBjb25u ZWN0ZWQKKwkJLSAiVVNCX1BEX1BQUyIJOiBVU0ItUEQgUFBTIGNhcGFibGUgc291cmNlIHN1cHBs eSBjb25uZWN0ZWQKKworV2hhdDogCQkvc3lzL2NsYXNzL3Bvd2VyX3N1cHBseS90Y3BtLXNvdXJj ZS1wc3kvb25saW5lCitEYXRlOgkJRGVjZW1iZXIgMjAxNworQ29udGFjdDoJQWRhbSBUaG9tc29u IDxBZGFtLlRob21zb24uT3BlbnNvdXJjZUBkaWFzZW1pLmNvbT4KK0Rlc2NyaXB0aW9uOgorCVRo aXMgcmVhZC13cml0ZSBwcm9wZXJ0eSBkZXNjcmliZXMgdGhlIG9ubGluZSBzdGF0ZSBvZiB0aGUg c291cmNlCisJc3VwcGx5LiBXaGVuIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIG5vdCAw LCBhbmQgdGhlIHN1cHBseSBhbGxvd3MKKwlpdCwgdGhlbiBpdCdzIHBvc3NpYmxlIHRvIHN3aXRj aCBiZXR3ZWVuIG9ubGluZSBzdGF0ZXMgKGkuZS4gMSAtPiAyLAorCTIgLT4gMSkKKworCVZhbGlk IHZhbHVlczoKKwkJLSAwCTogT2ZmbGluZSwgbm8gc291cmNlIHN1cHBseSBhdHRhY2hlZAorCQkt IDEJOiBGaXhlZCBPbmxpbmUsIFR5cGUtQyBvciBVU0ItUEQgY2FwYWJsZSBzdXBwbHkKKwkJCSAg YXR0YWNoZWQsIG5vbi1jb25maWd1cmFibGUgY3VycmVudCBhbmQgdm9sdGFnZQorCQkJICBwcm9w ZXJ0aWVzIGluIHRoaXMgc3RhdGUuCisJCS0gMgk6IFBQUyBPbmxpbmUsIFVTQi1QRCBQUFMgZmVh dHVyZSBlbmFibGVkLCAnY3VycmVudF9ub3cnCisJCQkgIGFuZCAndm9sdGFnZV9ub3cnIHByb3Bl cnRpZXMgY2FuIGJlIG1vZGlmaWVkIGluIHRoaXMKKwkJCSAgc3RhdGUuIFJlLXdyaXRpbmcgb2Yg dGhpcyB2YWx1ZSBhZ2Fpbiwgb25jZSBhbHJlYWR5CisJCQkgIHNldCwgd2lsbCByZS1yZXF1ZXN0 IHRoZSBzYW1lIGNvbmZpZ3VyZWQgdm9sdGFnZSBhbmQKKwkJCSAgY3VycmVudCB2YWx1ZXMuIFRo aXMgY2FuIGJlIHVzZWQgYXMgYSBrZWVwLWFsaXZlIGZvcgorCQkJICB0aGUgUFBTIGNvbm5lY3Rp b24uCisJCQkgIFtOT1RFOiBUaGlzIGlzIHZhbHVlIG9ubHkgc2VsZWN0YWJsZSBpZgorCQkJICAg J2Nvbm5lY3RlZF90eXBlJyByZXBvcnRzIGEgdmFsdWUgb2YgIlVTQl9QRF9QUFMiXQorCitXaGF0 OiAJCS9zeXMvY2xhc3MvcG93ZXJfc3VwcGx5L3RjcG0tc291cmNlLXBzeS92b2x0YWdlX21pbgor RGF0ZToJCURlY2VtYmVyIDIwMTcKK0NvbnRhY3Q6CUFkYW0gVGhvbXNvbiA8QWRhbS5UaG9tc29u Lk9wZW5zb3VyY2VAZGlhc2VtaS5jb20+CitEZXNjcmlwdGlvbjoKKwlUaGlzIHJlYWQtb25seSBw cm9wZXJ0eSBkZXNjcmliZXMgdGhlIG1pbmltdW0gdm9sdGFnZSB0aGUgc291cmNlIHN1cHBseQor CWNhbiBwcm92aWRlLgorCisJVmFsdWUgaW4gbWljcm92b2x0cy4KKworV2hhdDogCQkvc3lzL2Ns YXNzL3Bvd2VyX3N1cHBseS90Y3BtLXNvdXJjZS1wc3kvdm9sdGFnZV9tYXgKK0RhdGU6CQlEZWNl bWJlciAyMDE3CitDb250YWN0OglBZGFtIFRob21zb24gPEFkYW0uVGhvbXNvbi5PcGVuc291cmNl QGRpYXNlbWkuY29tPgorRGVzY3JpcHRpb246CisJVGhpcyByZWFkLW9ubHkgcHJvcGVydHkgZGVz Y3JpYmVzIHRoZSBtYXhpbXVtIHZvbHRhZ2UgdGhlIHNvdXJjZSBzdXBwbHkKKwljYW4gcHJvdmlk ZS4KKworCVZhbHVlIGluIG1pY3Jvdm9sdHMuCisKK1doYXQ6IAkJL3N5cy9jbGFzcy9wb3dlcl9z dXBwbHkvdGNwbS1zb3VyY2UtcHN5L3ZvbHRhZ2Vfbm93CitEYXRlOgkJRGVjZW1iZXIgMjAxNwor Q29udGFjdDoJQWRhbSBUaG9tc29uIDxBZGFtLlRob21zb24uT3BlbnNvdXJjZUBkaWFzZW1pLmNv bT4KK0Rlc2NyaXB0aW9uOgorCVRoaXMgcmVhZC13cml0ZSBwcm9wZXJ0eSBkZXNjcmliZXMgdGhl IHZvbHRhZ2UgdGhlIHNvdXJjZSBzdXBwbHkgaXMKKwlwcm92aWRpbmcgbm93LiBUaGlzIHByb3Bl cnR5IGNhbiBvbmx5IGJlIHdyaXR0ZW4gdG8gaWYgdGhlIHNvdXJjZSBzdXBwbHkKKwlpcyBpbiBv bmxpbmUgc3RhdGUgJzInIChQUFMgZW5hYmxlZCksIG90aGVyd2lzZSBpdCdzIHJlYWQtb25seQor CWluZm9ybWF0aW9uLgorCisJVmFsdWUgaW4gbWljcm92b2x0cy4KKworV2hhdDogCQkvc3lzL2Ns YXNzL3Bvd2VyX3N1cHBseS90Y3BtLXNvdXJjZS1wc3kvY3VycmVudF9tYXgKK0RhdGU6CQlEZWNl bWJlciAyMDE3CitDb250YWN0OglBZGFtIFRob21zb24gPEFkYW0uVGhvbXNvbi5PcGVuc291cmNl QGRpYXNlbWkuY29tPgorRGVzY3JpcHRpb246CisJVGhpcyByZWFkLW9ubHkgcHJvcGVydHkgZGVz Y3JpYmVzIHRoZSBtYXhpbXVtIGN1cnJlbnQgdGhlIHNvdXJjZSBzdXBwbHkKKwljYW4gcHJvdmlk ZS4KKworCVZhbHVlIGluIG1pY3JvYW1wcy4KKworV2hhdDogCQkvc3lzL2NsYXNzL3Bvd2VyX3N1 cHBseS90Y3BtLXNvdXJjZS1wc3kvY3VycmVudF9ub3cKK0RhdGU6CQlEZWNlbWJlciAyMDE3CitD b250YWN0OglBZGFtIFRob21zb24gPEFkYW0uVGhvbXNvbi5PcGVuc291cmNlQGRpYXNlbWkuY29t PgorRGVzY3JpcHRpb246CisJVGhpcyByZWFkLXdyaXRlIHByb3BlcnR5IGRlc2NyaWJlcyB0aGUg Y3VycmVudCB0aGUgc291cmNlIHN1cHBseSBjYW4KKwlwcm92aWRlIG5vdy4gVGhpcyBwcm9wZXJ0 eSBjYW4gb25seSBiZSB3cml0dGVuIHRvIGlmIHRoZSBzb3VyY2Ugc3VwcGx5CisJaXMgaW4gb25s aW5lIHN0YXRlICcyJyAoUFBTIGVuYWJsZWQpLCBvdGhlcndpc2UgaXQncyByZWFkLW9ubHkKKwlp bmZvcm1hdGlvbi4KKworCVZhbHVlIGluIG1pY3JvYW1wcy4KZGlmZiAtLWdpdCBhL2RyaXZlcnMv dXNiL3R5cGVjL0tjb25maWcgYi9kcml2ZXJzL3VzYi90eXBlYy9LY29uZmlnCmluZGV4IGJjYjI3 NDQuLjFlZjYwNmQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3R5cGVjL0tjb25maWcKKysrIGIv ZHJpdmVycy91c2IvdHlwZWMvS2NvbmZpZwpAQCAtNDgsNiArNDgsNyBAQCBpZiBUWVBFQwogY29u ZmlnIFRZUEVDX1RDUE0KIAl0cmlzdGF0ZSAiVVNCIFR5cGUtQyBQb3J0IENvbnRyb2xsZXIgTWFu YWdlciIKIAlkZXBlbmRzIG9uIFVTQgorCXNlbGVjdCBQT1dFUl9TVVBQTFkKIAloZWxwCiAJICBU aGUgVHlwZS1DIFBvcnQgQ29udHJvbGxlciBNYW5hZ2VyIHByb3ZpZGVzIGEgVVNCIFBEIGFuZCBV U0IgVHlwZS1DCiAJICBzdGF0ZSBtYWNoaW5lIGZvciB1c2Ugd2l0aCBUeXBlLUMgUG9ydCBDb250 cm9sbGVycy4KZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL3R5cGVjL2Z1c2IzMDIvS2NvbmZpZyBi L2RyaXZlcnMvdXNiL3R5cGVjL2Z1c2IzMDIvS2NvbmZpZwppbmRleCA0OGE0ZjJmLi5mY2UwOTlm IDEwMDY0NAotLS0gYS9kcml2ZXJzL3VzYi90eXBlYy9mdXNiMzAyL0tjb25maWcKKysrIGIvZHJp dmVycy91c2IvdHlwZWMvZnVzYjMwMi9LY29uZmlnCkBAIC0xLDYgKzEsNiBAQAogY29uZmlnIFRZ UEVDX0ZVU0IzMDIKIAl0cmlzdGF0ZSAiRmFpcmNoaWxkIEZVU0IzMDIgVHlwZS1DIGNoaXAgZHJp dmVyIgotCWRlcGVuZHMgb24gSTJDICYmIFBPV0VSX1NVUFBMWQorCWRlcGVuZHMgb24gSTJDCiAJ aGVscAogCSAgVGhlIEZhaXJjaGlsZCBGVVNCMzAyIFR5cGUtQyBjaGlwIGRyaXZlciB0aGF0IHdv cmtzIHdpdGgKIAkgIFR5cGUtQyBQb3J0IENvbnRyb2xsZXIgTWFuYWdlciB0byBwcm92aWRlIFVT QiBQRCBhbmQgVVNCCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi90eXBlYy9mdXNiMzAyL2Z1c2Iz MDIuYyBiL2RyaXZlcnMvdXNiL3R5cGVjL2Z1c2IzMDIvZnVzYjMwMi5jCmluZGV4IDljZTQ3NTYu LjgyZmRkYzcgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3R5cGVjL2Z1c2IzMDIvZnVzYjMwMi5j CisrKyBiL2RyaXZlcnMvdXNiL3R5cGVjL2Z1c2IzMDIvZnVzYjMwMi5jCkBAIC0xOCw3ICsxOCw2 IEBACiAjaW5jbHVkZSA8bGludXgvb2ZfZGV2aWNlLmg+CiAjaW5jbHVkZSA8bGludXgvb2ZfZ3Bp by5oPgogI2luY2x1ZGUgPGxpbnV4L3BpbmN0cmwvY29uc3VtZXIuaD4KLSNpbmNsdWRlIDxsaW51 eC9wb3dlcl9zdXBwbHkuaD4KICNpbmNsdWRlIDxsaW51eC9wcm9jX2ZzLmg+CiAjaW5jbHVkZSA8 bGludXgvcmVndWxhdG9yL2NvbnN1bWVyLmg+CiAjaW5jbHVkZSA8bGludXgvc2NoZWQvY2xvY2su aD4KQEAgLTk5LDExICs5OCw2IEBAIHN0cnVjdCBmdXNiMzAyX2NoaXAgewogCS8qIGxvY2sgZm9y IHNoYXJpbmcgY2hpcCBzdGF0ZXMgKi8KIAlzdHJ1Y3QgbXV0ZXggbG9jazsKIAotCS8qIHBzeSAr IHBzeSBzdGF0dXMgKi8KLQlzdHJ1Y3QgcG93ZXJfc3VwcGx5ICpwc3k7Ci0JdTMyIGN1cnJlbnRf bGltaXQ7Ci0JdTMyIHN1cHBseV92b2x0YWdlOwotCiAJLyogY2hpcCBzdGF0dXMgKi8KIAllbnVt IHRvZ2dsaW5nX21vZGUgdG9nZ2xpbmdfbW9kZTsKIAllbnVtIHNyY19jdXJyZW50X3N0YXR1cyBz cmNfY3VycmVudF9zdGF0dXM7CkBAIC04NzIsMTMgKzg2NiwxMSBAQCBzdGF0aWMgaW50IHRjcG1f c2V0X3ZidXMoc3RydWN0IHRjcGNfZGV2ICpkZXYsIGJvb2wgb24sIGJvb2wgY2hhcmdlKQogCQlj aGlwLT52YnVzX29uID0gb247CiAJCWZ1c2IzMDJfbG9nKGNoaXAsICJ2YnVzIDo9ICVzIiwgb24g PyAiT24iIDogIk9mZiIpOwogCX0KLQlpZiAoY2hpcC0+Y2hhcmdlX29uID09IGNoYXJnZSkgewor CWlmIChjaGlwLT5jaGFyZ2Vfb24gPT0gY2hhcmdlKQogCQlmdXNiMzAyX2xvZyhjaGlwLCAiY2hh cmdlIGlzIGFscmVhZHkgJXMiLAogCQkJICAgIGNoYXJnZSA/ICJPbiIgOiAiT2ZmIik7Ci0JfSBl bHNlIHsKKwllbHNlCiAJCWNoaXAtPmNoYXJnZV9vbiA9IGNoYXJnZTsKLQkJcG93ZXJfc3VwcGx5 X2NoYW5nZWQoY2hpcC0+cHN5KTsKLQl9CiAKIGRvbmU6CiAJbXV0ZXhfdW5sb2NrKCZjaGlwLT5s b2NrKTsKQEAgLTg5NCwxMSArODg2LDYgQEAgc3RhdGljIGludCB0Y3BtX3NldF9jdXJyZW50X2xp bWl0KHN0cnVjdCB0Y3BjX2RldiAqZGV2LCB1MzIgbWF4X21hLCB1MzIgbXYpCiAJZnVzYjMwMl9s b2coY2hpcCwgImN1cnJlbnQgbGltaXQ6ICVkIG1hLCAlZCBtdiAobm90IGltcGxlbWVudGVkKSIs CiAJCSAgICBtYXhfbWEsIG12KTsKIAotCWNoaXAtPnN1cHBseV92b2x0YWdlID0gbXY7Ci0JY2hp cC0+Y3VycmVudF9saW1pdCA9IG1heF9tYTsKLQotCXBvd2VyX3N1cHBseV9jaGFuZ2VkKGNoaXAt PnBzeSk7Ci0KIAlyZXR1cm4gMDsKIH0KIApAQCAtMTY5Nyw0MyArMTY4NCw2IEBAIHN0YXRpYyBp cnFyZXR1cm5fdCBmdXNiMzAyX2lycV9pbnRuKGludCBpcnEsIHZvaWQgKmRldl9pZCkKIAlyZXR1 cm4gSVJRX0hBTkRMRUQ7CiB9CiAKLXN0YXRpYyBpbnQgZnVzYjMwMl9wc3lfZ2V0X3Byb3BlcnR5 KHN0cnVjdCBwb3dlcl9zdXBwbHkgKnBzeSwKLQkJCQkgICAgZW51bSBwb3dlcl9zdXBwbHlfcHJv cGVydHkgcHNwLAotCQkJCSAgICB1bmlvbiBwb3dlcl9zdXBwbHlfcHJvcHZhbCAqdmFsKQotewot CXN0cnVjdCBmdXNiMzAyX2NoaXAgKmNoaXAgPSBwb3dlcl9zdXBwbHlfZ2V0X2RydmRhdGEocHN5 KTsKLQotCXN3aXRjaCAocHNwKSB7Ci0JY2FzZSBQT1dFUl9TVVBQTFlfUFJPUF9PTkxJTkU6Ci0J CXZhbC0+aW50dmFsID0gY2hpcC0+Y2hhcmdlX29uOwotCQlicmVhazsKLQljYXNlIFBPV0VSX1NV UFBMWV9QUk9QX1ZPTFRBR0VfTk9XOgotCQl2YWwtPmludHZhbCA9IGNoaXAtPnN1cHBseV92b2x0 YWdlICogMTAwMDsgLyogbVYgLT4gwrVWICovCi0JCWJyZWFrOwotCWNhc2UgUE9XRVJfU1VQUExZ X1BST1BfQ1VSUkVOVF9NQVg6Ci0JCXZhbC0+aW50dmFsID0gY2hpcC0+Y3VycmVudF9saW1pdCAq IDEwMDA7IC8qIG1BIC0+IMK1QSAqLwotCQlicmVhazsKLQlkZWZhdWx0OgotCQlyZXR1cm4gLUVO T0RBVEE7Ci0JfQotCi0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyBlbnVtIHBvd2VyX3N1cHBseV9w cm9wZXJ0eSBmdXNiMzAyX3BzeV9wcm9wZXJ0aWVzW10gPSB7Ci0JUE9XRVJfU1VQUExZX1BST1Bf T05MSU5FLAotCVBPV0VSX1NVUFBMWV9QUk9QX1ZPTFRBR0VfTk9XLAotCVBPV0VSX1NVUFBMWV9Q Uk9QX0NVUlJFTlRfTUFYLAotfTsKLQotc3RhdGljIGNvbnN0IHN0cnVjdCBwb3dlcl9zdXBwbHlf ZGVzYyBmdXNiMzAyX3BzeV9kZXNjID0gewotCS5uYW1lCQk9ICJmdXNiMzAyLXR5cGVjLXNvdXJj ZSIsCi0JLnR5cGUJCT0gUE9XRVJfU1VQUExZX1RZUEVfVVNCX1RZUEVfQywKLQkucHJvcGVydGll cwk9IGZ1c2IzMDJfcHN5X3Byb3BlcnRpZXMsCi0JLm51bV9wcm9wZXJ0aWVzCT0gQVJSQVlfU0la RShmdXNiMzAyX3BzeV9wcm9wZXJ0aWVzKSwKLQkuZ2V0X3Byb3BlcnR5CT0gZnVzYjMwMl9wc3lf Z2V0X3Byb3BlcnR5LAotfTsKLQogc3RhdGljIGludCBpbml0X2dwaW8oc3RydWN0IGZ1c2IzMDJf Y2hpcCAqY2hpcCkKIHsKIAlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5vZGU7CkBAIC0xNzczLDcgKzE3 MjMsNiBAQCBzdGF0aWMgaW50IGZ1c2IzMDJfcHJvYmUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVu dCwKIAlzdHJ1Y3QgZnVzYjMwMl9jaGlwICpjaGlwOwogCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRh cHRlcjsKIAlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmY2xpZW50LT5kZXY7Ci0Jc3RydWN0IHBvd2Vy X3N1cHBseV9jb25maWcgY2ZnID0ge307CiAJY29uc3QgY2hhciAqbmFtZTsKIAlpbnQgcmV0ID0g MDsKIAl1MzIgdjsKQEAgLTE4MjAsMTQgKzE3NjksNiBAQCBzdGF0aWMgaW50IGZ1c2IzMDJfcHJv YmUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwKIAkJCXJldHVybiAtRVBST0JFX0RFRkVSOwog CX0KIAotCWNmZy5kcnZfZGF0YSA9IGNoaXA7Ci0JY2hpcC0+cHN5ID0gZGV2bV9wb3dlcl9zdXBw bHlfcmVnaXN0ZXIoZGV2LCAmZnVzYjMwMl9wc3lfZGVzYywgJmNmZyk7Ci0JaWYgKElTX0VSUihj aGlwLT5wc3kpKSB7Ci0JCXJldCA9IFBUUl9FUlIoY2hpcC0+cHN5KTsKLQkJZGV2X2VycihjaGlw LT5kZXYsICJFcnJvciByZWdpc3RlcmluZyBwb3dlci1zdXBwbHk6ICVkXG4iLCByZXQpOwotCQly ZXR1cm4gcmV0OwotCX0KLQogCXJldCA9IGZ1c2IzMDJfZGVidWdmc19pbml0KGNoaXApOwogCWlm IChyZXQgPCAwKQogCQlyZXR1cm4gcmV0OwpkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvdHlwZWMv dGNwbS5jIGIvZHJpdmVycy91c2IvdHlwZWMvdGNwbS5jCmluZGV4IGI2NmQyNmMuLmI4NmE1MWMg MTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL3R5cGVjL3RjcG0uYworKysgYi9kcml2ZXJzL3VzYi90 eXBlYy90Y3BtLmMKQEAgLTEyLDYgKzEyLDcgQEAKICNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4K ICNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KICNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgorI2lu Y2x1ZGUgPGxpbnV4L3Bvd2VyX3N1cHBseS5oPgogI2luY2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4K ICNpbmNsdWRlIDxsaW51eC9zY2hlZC9jbG9jay5oPgogI2luY2x1ZGUgPGxpbnV4L3NlcV9maWxl Lmg+CkBAIC0yODEsNiArMjgyLDExIEBAIHN0cnVjdCB0Y3BtX3BvcnQgewogCXUzMiBjdXJyZW50 X2xpbWl0OwogCXUzMiBzdXBwbHlfdm9sdGFnZTsKIAorCS8qIFVzZWQgdG8gZXhwb3J0IFRBIHZv bHRhZ2UgYW5kIGN1cnJlbnQgKi8KKwlzdHJ1Y3QgcG93ZXJfc3VwcGx5ICpwc3k7CisJc3RydWN0 IHBvd2VyX3N1cHBseV9kZXNjIHBzeV9kZXNjOworCWVudW0gcG93ZXJfc3VwcGx5X2Nvbm5fdHlw ZSBjb25uZWN0ZWRfdHlwZTsKKwogCXUzMiBiaXN0X3JlcXVlc3Q7CiAKIAkvKiBQRCBzdGF0ZSBm b3IgVmVuZG9yIERlZmluZWQgTWVzc2FnZXMgKi8KQEAgLTE4OTMsNiArMTg5OSw3IEBAIHN0YXRp YyBpbnQgdGNwbV9wZF9zZWxlY3RfcGRvKHN0cnVjdCB0Y3BtX3BvcnQgKnBvcnQsIGludCAqc2lu a19wZG8sCiAJaW50IHJldCA9IC1FSU5WQUw7CiAKIAlwb3J0LT5wcHNfZGF0YS5zdXBwb3J0ZWQg PSBmYWxzZTsKKwlwb3J0LT5jb25uZWN0ZWRfdHlwZSA9IFBPV0VSX1NVUFBMWV9DT05OX1RZUEVf VVNCX1BEOwogCiAJLyoKIAkgKiBTZWxlY3QgdGhlIHNvdXJjZSBQRE8gcHJvdmlkaW5nIHRoZSBt b3N0IHBvd2VyIHdoaWNoIGhhcyBhCkBAIC0xOTc0LDggKzE5ODEsMTEgQEAgc3RhdGljIGludCB0 Y3BtX3BkX3NlbGVjdF9wZG8oc3RydWN0IHRjcG1fcG9ydCAqcG9ydCwgaW50ICpzaW5rX3BkbywK IAkJCX0KIAkJCWJyZWFrOwogCQljYXNlIFBET19UWVBFX0FQRE86Ci0JCQlpZiAocGRvX2FwZG9f dHlwZShwZG8pID09IEFQRE9fVFlQRV9QUFMpCisJCQlpZiAocGRvX2FwZG9fdHlwZShwZG8pID09 IEFQRE9fVFlQRV9QUFMpIHsKIAkJCQlwb3J0LT5wcHNfZGF0YS5zdXBwb3J0ZWQgPSB0cnVlOwor CQkJCXBvcnQtPmNvbm5lY3RlZF90eXBlID0KKwkJCQkJUE9XRVJfU1VQUExZX0NPTk5fVFlQRV9V U0JfUERfUFBTOworCQkJfQogCQkJY29udGludWU7CiAJCWRlZmF1bHQ6CiAJCQl0Y3BtX2xvZyhw b3J0LCAiSW52YWxpZCBQRE8gdHlwZSwgaWdub3JpbmciKTsKQEAgLTI0NTksNiArMjQ2OSw5IEBA IHN0YXRpYyB2b2lkIHRjcG1fcmVzZXRfcG9ydChzdHJ1Y3QgdGNwbV9wb3J0ICpwb3J0KQogCXBv cnQtPnRyeV9zbmtfY291bnQgPSAwOwogCXBvcnQtPnN1cHBseV92b2x0YWdlID0gMDsKIAlwb3J0 LT5jdXJyZW50X2xpbWl0ID0gMDsKKwlwb3J0LT5jb25uZWN0ZWRfdHlwZSA9IFBPV0VSX1NVUFBM WV9DT05OX1RZUEVfVVNCX1RZUEVfQzsKKworCXBvd2VyX3N1cHBseV9jaGFuZ2VkKHBvcnQtPnBz eSk7CiB9CiAKIHN0YXRpYyB2b2lkIHRjcG1fZGV0YWNoKHN0cnVjdCB0Y3BtX3BvcnQgKnBvcnQp CkBAIC0yOTkxLDYgKzMwMDQsOCBAQCBzdGF0aWMgdm9pZCBydW5fc3RhdGVfbWFjaGluZShzdHJ1 Y3QgdGNwbV9wb3J0ICpwb3J0KQogCiAJCXRjcG1fcHBzX2NvbXBsZXRlKHBvcnQsIHBvcnQtPnBw c19zdGF0dXMpOwogCisJCXBvd2VyX3N1cHBseV9jaGFuZ2VkKHBvcnQtPnBzeSk7CisKIAkJYnJl YWs7CiAKIAkvKiBBY2Nlc3Nvcnkgc3RhdGVzICovCkBAIC00MTcwLDYgKzQxODUsMjE4IEBAIHN0 YXRpYyBpbnQgbnJfdHlwZV9wZG9zKGNvbnN0IHUzMiAqcGRvLCB1bnNpZ25lZCBpbnQgbnJfcGRv LAogCXJldHVybiBjb3VudDsKIH0KIAorLyogUG93ZXIgU3VwcGx5IGFjY2VzcyB0byBleHBvc2Ug c291cmNlIHBvd2VyIGluZm9ybWF0aW9uICovCitlbnVtIHRjcG1fcHN5X29ubGluZV9zdGF0ZXMg eworCVRDUE1fUFNZX09GRkxJTkUgPSAwLAorCVRDUE1fUFNZX0ZJWEVEX09OTElORSwKKwlUQ1BN X1BTWV9QUk9HX09OTElORSwKK307CisKK3N0YXRpYyBlbnVtIHBvd2VyX3N1cHBseV9wcm9wZXJ0 eSB0Y3BtX3BzeV9wcm9wc1tdID0geworCVBPV0VSX1NVUFBMWV9QUk9QX0NPTk5FQ1RFRF9UWVBF LAorCVBPV0VSX1NVUFBMWV9QUk9QX09OTElORSwKKwlQT1dFUl9TVVBQTFlfUFJPUF9WT0xUQUdF X01JTiwKKwlQT1dFUl9TVVBQTFlfUFJPUF9WT0xUQUdFX01BWCwKKwlQT1dFUl9TVVBQTFlfUFJP UF9WT0xUQUdFX05PVywKKwlQT1dFUl9TVVBQTFlfUFJPUF9DVVJSRU5UX01BWCwKKwlQT1dFUl9T VVBQTFlfUFJPUF9DVVJSRU5UX05PVywKK307CisKK3N0YXRpYyBpbnQgdGNwbV9wc3lfZ2V0X29u bGluZShzdHJ1Y3QgdGNwbV9wb3J0ICpwb3J0LAorCQkJICAgICAgIHVuaW9uIHBvd2VyX3N1cHBs eV9wcm9wdmFsICp2YWwpCit7CisJaWYgKHBvcnQtPnZidXNfY2hhcmdlKSB7CisJCWlmIChwb3J0 LT5wcHNfZGF0YS5hY3RpdmUpCisJCQl2YWwtPmludHZhbCA9IFRDUE1fUFNZX1BST0dfT05MSU5F OworCQllbHNlCisJCQl2YWwtPmludHZhbCA9IFRDUE1fUFNZX0ZJWEVEX09OTElORTsKKwl9IGVs c2UgeworCQl2YWwtPmludHZhbCA9IFRDUE1fUFNZX09GRkxJTkU7CisJfQorCisJcmV0dXJuIDA7 Cit9CisKK3N0YXRpYyBpbnQgdGNwbV9wc3lfZ2V0X3ZvbHRhZ2VfbWluKHN0cnVjdCB0Y3BtX3Bv cnQgKnBvcnQsCisJCQkJICAgIHVuaW9uIHBvd2VyX3N1cHBseV9wcm9wdmFsICp2YWwpCit7CisJ aWYgKHBvcnQtPnBwc19kYXRhLmFjdGl2ZSkKKwkJdmFsLT5pbnR2YWwgPSBwb3J0LT5wcHNfZGF0 YS5taW5fdm9sdCAqIDEwMDA7CisJZWxzZQorCQl2YWwtPmludHZhbCA9IHBvcnQtPnN1cHBseV92 b2x0YWdlICogMTAwMDsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IHRjcG1fcHN5X2dl dF92b2x0YWdlX21heChzdHJ1Y3QgdGNwbV9wb3J0ICpwb3J0LAorCQkJCSAgICB1bmlvbiBwb3dl cl9zdXBwbHlfcHJvcHZhbCAqdmFsKQoreworCWlmIChwb3J0LT5wcHNfZGF0YS5hY3RpdmUpCisJ CXZhbC0+aW50dmFsID0gcG9ydC0+cHBzX2RhdGEubWF4X3ZvbHQgKiAxMDAwOworCWVsc2UKKwkJ dmFsLT5pbnR2YWwgPSBwb3J0LT5zdXBwbHlfdm9sdGFnZSAqIDEwMDA7CisKKwlyZXR1cm4gMDsK K30KKworc3RhdGljIGludCB0Y3BtX3BzeV9nZXRfdm9sdGFnZV9ub3coc3RydWN0IHRjcG1fcG9y dCAqcG9ydCwKKwkJCQkgICAgdW5pb24gcG93ZXJfc3VwcGx5X3Byb3B2YWwgKnZhbCkKK3sKKwl2 YWwtPmludHZhbCA9IHBvcnQtPnN1cHBseV92b2x0YWdlICogMTAwMDsKKworCXJldHVybiAwOwor fQorCitzdGF0aWMgaW50IHRjcG1fcHN5X2dldF9jdXJyZW50X21heChzdHJ1Y3QgdGNwbV9wb3J0 ICpwb3J0LAorCQkJCSAgICB1bmlvbiBwb3dlcl9zdXBwbHlfcHJvcHZhbCAqdmFsKQoreworCWlm IChwb3J0LT5wcHNfZGF0YS5hY3RpdmUpCisJCXZhbC0+aW50dmFsID0gcG9ydC0+cHBzX2RhdGEu bWF4X2N1cnIgKiAxMDAwOworCWVsc2UKKwkJdmFsLT5pbnR2YWwgPSBwb3J0LT5jdXJyZW50X2xp bWl0ICogMTAwMDsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IHRjcG1fcHN5X2dldF9j dXJyZW50X25vdyhzdHJ1Y3QgdGNwbV9wb3J0ICpwb3J0LAorCQkJCSAgICB1bmlvbiBwb3dlcl9z dXBwbHlfcHJvcHZhbCAqdmFsKQoreworCXZhbC0+aW50dmFsID0gcG9ydC0+Y3VycmVudF9saW1p dCAqIDEwMDA7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCB0Y3BtX3BzeV9nZXRfcHJv cChzdHJ1Y3QgcG93ZXJfc3VwcGx5ICpwc3ksCisJCQkgICAgIGVudW0gcG93ZXJfc3VwcGx5X3By b3BlcnR5IHBzcCwKKwkJCSAgICAgdW5pb24gcG93ZXJfc3VwcGx5X3Byb3B2YWwgKnZhbCkKK3sK KwlzdHJ1Y3QgdGNwbV9wb3J0ICpwb3J0ID0gcG93ZXJfc3VwcGx5X2dldF9kcnZkYXRhKHBzeSk7 CisJaW50IHJldCA9IDA7CisKKwlzd2l0Y2ggKHBzcCkgeworCWNhc2UgUE9XRVJfU1VQUExZX1BS T1BfQ09OTkVDVEVEX1RZUEU6CisJCXZhbC0+aW50dmFsID0gcG9ydC0+Y29ubmVjdGVkX3R5cGU7 CisJCWJyZWFrOworCWNhc2UgUE9XRVJfU1VQUExZX1BST1BfT05MSU5FOgorCQlyZXQgPSB0Y3Bt X3BzeV9nZXRfb25saW5lKHBvcnQsIHZhbCk7CisJCWJyZWFrOworCWNhc2UgUE9XRVJfU1VQUExZ X1BST1BfVk9MVEFHRV9NSU46CisJCXJldCA9IHRjcG1fcHN5X2dldF92b2x0YWdlX21pbihwb3J0 LCB2YWwpOworCQlicmVhazsKKwljYXNlIFBPV0VSX1NVUFBMWV9QUk9QX1ZPTFRBR0VfTUFYOgor CQlyZXQgPSB0Y3BtX3BzeV9nZXRfdm9sdGFnZV9tYXgocG9ydCwgdmFsKTsKKwkJYnJlYWs7CisJ Y2FzZSBQT1dFUl9TVVBQTFlfUFJPUF9WT0xUQUdFX05PVzoKKwkJcmV0ID0gdGNwbV9wc3lfZ2V0 X3ZvbHRhZ2Vfbm93KHBvcnQsIHZhbCk7CisJCWJyZWFrOworCWNhc2UgUE9XRVJfU1VQUExZX1BS T1BfQ1VSUkVOVF9NQVg6CisJCXJldCA9IHRjcG1fcHN5X2dldF9jdXJyZW50X21heChwb3J0LCB2 YWwpOworCQlicmVhazsKKwljYXNlIFBPV0VSX1NVUFBMWV9QUk9QX0NVUlJFTlRfTk9XOgorCQly ZXQgPSB0Y3BtX3BzeV9nZXRfY3VycmVudF9ub3cocG9ydCwgdmFsKTsKKwkJYnJlYWs7CisJZGVm YXVsdDoKKwkJcmV0ID0gLUVJTlZBTDsKKwkJYnJlYWs7CisJfQorCisJcmV0dXJuIHJldDsKK30K Kworc3RhdGljIGludCB0Y3BtX3BzeV9zZXRfb25saW5lKHN0cnVjdCB0Y3BtX3BvcnQgKnBvcnQs CisJCQkgICAgICAgY29uc3QgdW5pb24gcG93ZXJfc3VwcGx5X3Byb3B2YWwgKnZhbCkKK3sKKwlp bnQgcmV0OworCisJc3dpdGNoICh2YWwtPmludHZhbCkgeworCWNhc2UgVENQTV9QU1lfRklYRURf T05MSU5FOgorCQlyZXQgPSB0Y3BtX3Bwc19hY3RpdmF0ZShwb3J0LCBmYWxzZSk7CisJCWJyZWFr OworCWNhc2UgVENQTV9QU1lfUFJPR19PTkxJTkU6CisJCXJldCA9IHRjcG1fcHBzX2FjdGl2YXRl KHBvcnQsIHRydWUpOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlyZXQgPSAtRUlOVkFMOworCQli cmVhazsKKwl9CisKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgaW50IHRjcG1fcHN5X3NldF9w cm9wKHN0cnVjdCBwb3dlcl9zdXBwbHkgKnBzeSwKKwkJCSAgICAgZW51bSBwb3dlcl9zdXBwbHlf cHJvcGVydHkgcHNwLAorCQkJICAgICBjb25zdCB1bmlvbiBwb3dlcl9zdXBwbHlfcHJvcHZhbCAq dmFsKQoreworCXN0cnVjdCB0Y3BtX3BvcnQgKnBvcnQgPSBwb3dlcl9zdXBwbHlfZ2V0X2RydmRh dGEocHN5KTsKKwlpbnQgcmV0ID0gMDsKKworCXN3aXRjaCAocHNwKSB7CisJY2FzZSBQT1dFUl9T VVBQTFlfUFJPUF9PTkxJTkU6CisJCXJldCA9IHRjcG1fcHN5X3NldF9vbmxpbmUocG9ydCwgdmFs KTsKKwkJYnJlYWs7CisJY2FzZSBQT1dFUl9TVVBQTFlfUFJPUF9WT0xUQUdFX05PVzoKKwkJaWYg KCh2YWwtPmludHZhbCA8IChwb3J0LT5wcHNfZGF0YS5taW5fdm9sdCAqIDEwMDApKSB8fAorCQkg ICAgKHZhbC0+aW50dmFsID4gKHBvcnQtPnBwc19kYXRhLm1heF92b2x0ICogMTAwMCkpKQorCQkJ cmV0ID0gLUVJTlZBTDsKKwkJZWxzZQorCQkJcmV0ID0gdGNwbV9wcHNfc2V0X291dF92b2x0KHBv cnQsICh2YWwtPmludHZhbCAvIDEwMDApKTsKKwkJYnJlYWs7CisJY2FzZSBQT1dFUl9TVVBQTFlf UFJPUF9DVVJSRU5UX05PVzoKKwkJaWYgKHZhbC0+aW50dmFsID4gKHBvcnQtPnBwc19kYXRhLm1h eF9jdXJyICogMTAwMCkpCisJCQlyZXQgPSAtRUlOVkFMOworCQllbHNlCisJCQlyZXQgPSB0Y3Bt X3Bwc19zZXRfb3BfY3Vycihwb3J0LCAodmFsLT5pbnR2YWwgLyAxMDAwKSk7CisJCWJyZWFrOwor CWRlZmF1bHQ6CisJCXJldCA9IC1FSU5WQUw7CisJCWJyZWFrOworCX0KKworCXJldHVybiByZXQ7 Cit9CisKK3N0YXRpYyBpbnQgdGNwbV9wc3lfcHJvcF93cml0ZWFibGUoc3RydWN0IHBvd2VyX3N1 cHBseSAqcHN5LAorCQkJCSAgIGVudW0gcG93ZXJfc3VwcGx5X3Byb3BlcnR5IHBzcCkKK3sKKwlz d2l0Y2ggKHBzcCkgeworCWNhc2UgUE9XRVJfU1VQUExZX1BST1BfT05MSU5FOgorCWNhc2UgUE9X RVJfU1VQUExZX1BST1BfVk9MVEFHRV9OT1c6CisJY2FzZSBQT1dFUl9TVVBQTFlfUFJPUF9DVVJS RU5UX05PVzoKKwkJcmV0dXJuIDE7CisJZGVmYXVsdDoKKwkJcmV0dXJuIDA7CisJfQorfQorCitz dGF0aWMgZW51bSBwb3dlcl9zdXBwbHlfY29ubl90eXBlIHRjcG1fcHN5X2Nvbm5fdHlwZXNbXSA9 IHsKKwlQT1dFUl9TVVBQTFlfQ09OTl9UWVBFX1VTQl9UWVBFX0MsCisJUE9XRVJfU1VQUExZX0NP Tk5fVFlQRV9VU0JfUEQsCisJUE9XRVJfU1VQUExZX0NPTk5fVFlQRV9VU0JfUERfUFBTLAorfTsK Kworc3RhdGljIGludCBkZXZtX3RjcG1fcHN5X3JlZ2lzdGVyKHN0cnVjdCB0Y3BtX3BvcnQgKnBv cnQpCit7CisJc3RydWN0IHBvd2VyX3N1cHBseV9jb25maWcgcHN5X2NmZyA9IHt9OworCisJcHN5 X2NmZy5kcnZfZGF0YSA9IHBvcnQ7CisJcG9ydC0+cHN5X2Rlc2MubmFtZSA9ICJ0Y3BtLXNvdXJj ZS1wc3kiLAorCXBvcnQtPnBzeV9kZXNjLnR5cGUgPSBQT1dFUl9TVVBQTFlfVFlQRV9VU0IsCisJ cG9ydC0+cHN5X2Rlc2MuY29ubl90eXBlcyA9IHRjcG1fcHN5X2Nvbm5fdHlwZXM7CisJcG9ydC0+ cHN5X2Rlc2MubnVtX2Nvbm5fdHlwZXMgPSBBUlJBWV9TSVpFKHRjcG1fcHN5X2Nvbm5fdHlwZXMp OworCXBvcnQtPnBzeV9kZXNjLnByb3BlcnRpZXMgPSB0Y3BtX3BzeV9wcm9wcywKKwlwb3J0LT5w c3lfZGVzYy5udW1fcHJvcGVydGllcyA9IEFSUkFZX1NJWkUodGNwbV9wc3lfcHJvcHMpLAorCXBv cnQtPnBzeV9kZXNjLmdldF9wcm9wZXJ0eSA9IHRjcG1fcHN5X2dldF9wcm9wLAorCXBvcnQtPnBz eV9kZXNjLnNldF9wcm9wZXJ0eSA9IHRjcG1fcHN5X3NldF9wcm9wLAorCXBvcnQtPnBzeV9kZXNj LnByb3BlcnR5X2lzX3dyaXRlYWJsZSA9IHRjcG1fcHN5X3Byb3Bfd3JpdGVhYmxlLAorCisJcG9y dC0+Y29ubmVjdGVkX3R5cGUgPSBQT1dFUl9TVVBQTFlfQ09OTl9UWVBFX1VTQl9UWVBFX0M7CisK Kwlwb3J0LT5wc3kgPSBkZXZtX3Bvd2VyX3N1cHBseV9yZWdpc3Rlcihwb3J0LT5kZXYsICZwb3J0 LT5wc3lfZGVzYywKKwkJCQkJICAgICAgICZwc3lfY2ZnKTsKKworCXJldHVybiBQVFJfRVJSX09S X1pFUk8ocG9ydC0+cHN5KTsKK30KKwogc3RydWN0IHRjcG1fcG9ydCAqdGNwbV9yZWdpc3Rlcl9w b3J0KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHRjcGNfZGV2ICp0Y3BjKQogewogCXN0cnVj dCB0Y3BtX3BvcnQgKnBvcnQ7CkBAIC00MjUzLDYgKzQ0ODAsMTAgQEAgc3RydWN0IHRjcG1fcG9y dCAqdGNwbV9yZWdpc3Rlcl9wb3J0KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHRjcGNfZGV2 ICp0Y3BjKQogCXBvcnQtPnBhcnRuZXJfZGVzYy5pZGVudGl0eSA9ICZwb3J0LT5wYXJ0bmVyX2lk ZW50OwogCXBvcnQtPnBvcnRfdHlwZSA9IHRjcGMtPmNvbmZpZy0+dHlwZTsKIAorCWVyciA9IGRl dm1fdGNwbV9wc3lfcmVnaXN0ZXIocG9ydCk7CisJaWYgKGVycikKKwkJZ290byBvdXRfZGVzdHJv eV93cTsKKwogCXBvcnQtPnR5cGVjX3BvcnQgPSB0eXBlY19yZWdpc3Rlcl9wb3J0KHBvcnQtPmRl diwgJnBvcnQtPnR5cGVjX2NhcHMpOwogCWlmICghcG9ydC0+dHlwZWNfcG9ydCkgewogCQllcnIg PSAtRU5PTUVNOwo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adam Thomson Subject: [PATCH v4 6/7] typec: tcpm: Represent source supply through power_supply class Date: Tue, 2 Jan 2018 15:50:54 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org To: Heikki Krogerus , Guenter Roeck , Greg Kroah-Hartman , Sebastian Reichel , Hans de Goede , Yueyao Zhu , Rui Miguel Silva Cc: linux-usb@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, support.opensource@diasemi.com List-Id: linux-pm@vger.kernel.org This commit adds a power_supply class instance to represent a PD source's voltage and current properties. This provides an interface for reading these properties from user-space or other drivers. For PPS enabled Sources, this also provides write access to set the current and voltage and allows for swapping between standard PDO and PPS APDO. As this represents a superset of the information provided in the fusb302 driver, the power_supply instance in that code is removed as part of this change, so reverting the commit titled 'typec: tcpm: Represent source supply through power_supply class' Signed-off-by: Adam Thomson --- .../ABI/testing/sysfs-class-power-tcpm-source-psy | 92 ++++++++ drivers/usb/typec/Kconfig | 1 + drivers/usb/typec/fusb302/Kconfig | 2 +- drivers/usb/typec/fusb302/fusb302.c | 63 +----- drivers/usb/typec/tcpm.c | 233 ++++++++++++++++++++- 5 files changed, 328 insertions(+), 63 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy diff --git a/Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy b/Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy new file mode 100644 index 0000000..4986cba --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-power-tcpm-source-psy @@ -0,0 +1,92 @@ +What: /sys/class/power_supply/tcpm-source-psy/type +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the main type of source supply. + Type-C is a USB standard so this property always returns "USB". + +What: /sys/class/power_supply/tcpm-source-psy/connected_type +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the type of source supply that is + connected, if the supply is online. The value is always Type C + unless a source has been attached which is identified as USB-PD capable. + + Valid values: + - "USB_TYPE_C" : Type C connected supply, not UBS-PD capable + (default value) + - "USB_PD" : USB-PD capable source supply connected + - "USB_PD_PPS" : USB-PD PPS capable source supply connected + +What: /sys/class/power_supply/tcpm-source-psy/online +Date: December 2017 +Contact: Adam Thomson +Description: + This read-write property describes the online state of the source + supply. When the value of this property is not 0, and the supply allows + it, then it's possible to switch between online states (i.e. 1 -> 2, + 2 -> 1) + + Valid values: + - 0 : Offline, no source supply attached + - 1 : Fixed Online, Type-C or USB-PD capable supply + attached, non-configurable current and voltage + properties in this state. + - 2 : PPS Online, USB-PD PPS feature enabled, 'current_now' + and 'voltage_now' properties can be modified in this + state. Re-writing of this value again, once already + set, will re-request the same configured voltage and + current values. This can be used as a keep-alive for + the PPS connection. + [NOTE: This is value only selectable if + 'connected_type' reports a value of "USB_PD_PPS"] + +What: /sys/class/power_supply/tcpm-source-psy/voltage_min +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the minimum voltage the source supply + can provide. + + Value in microvolts. + +What: /sys/class/power_supply/tcpm-source-psy/voltage_max +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the maximum voltage the source supply + can provide. + + Value in microvolts. + +What: /sys/class/power_supply/tcpm-source-psy/voltage_now +Date: December 2017 +Contact: Adam Thomson +Description: + This read-write property describes the voltage the source supply is + providing now. This property can only be written to if the source supply + is in online state '2' (PPS enabled), otherwise it's read-only + information. + + Value in microvolts. + +What: /sys/class/power_supply/tcpm-source-psy/current_max +Date: December 2017 +Contact: Adam Thomson +Description: + This read-only property describes the maximum current the source supply + can provide. + + Value in microamps. + +What: /sys/class/power_supply/tcpm-source-psy/current_now +Date: December 2017 +Contact: Adam Thomson +Description: + This read-write property describes the current the source supply can + provide now. This property can only be written to if the source supply + is in online state '2' (PPS enabled), otherwise it's read-only + information. + + Value in microamps. diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index bcb2744..1ef606d 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -48,6 +48,7 @@ if TYPEC config TYPEC_TCPM tristate "USB Type-C Port Controller Manager" depends on USB + select POWER_SUPPLY help The Type-C Port Controller Manager provides a USB PD and USB Type-C state machine for use with Type-C Port Controllers. diff --git a/drivers/usb/typec/fusb302/Kconfig b/drivers/usb/typec/fusb302/Kconfig index 48a4f2f..fce099f 100644 --- a/drivers/usb/typec/fusb302/Kconfig +++ b/drivers/usb/typec/fusb302/Kconfig @@ -1,6 +1,6 @@ config TYPEC_FUSB302 tristate "Fairchild FUSB302 Type-C chip driver" - depends on I2C && POWER_SUPPLY + depends on I2C help The Fairchild FUSB302 Type-C chip driver that works with Type-C Port Controller Manager to provide USB PD and USB diff --git a/drivers/usb/typec/fusb302/fusb302.c b/drivers/usb/typec/fusb302/fusb302.c index 9ce4756..82fddc7 100644 --- a/drivers/usb/typec/fusb302/fusb302.c +++ b/drivers/usb/typec/fusb302/fusb302.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -99,11 +98,6 @@ struct fusb302_chip { /* lock for sharing chip states */ struct mutex lock; - /* psy + psy status */ - struct power_supply *psy; - u32 current_limit; - u32 supply_voltage; - /* chip status */ enum toggling_mode toggling_mode; enum src_current_status src_current_status; @@ -872,13 +866,11 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge) chip->vbus_on = on; fusb302_log(chip, "vbus := %s", on ? "On" : "Off"); } - if (chip->charge_on == charge) { + if (chip->charge_on == charge) fusb302_log(chip, "charge is already %s", charge ? "On" : "Off"); - } else { + else chip->charge_on = charge; - power_supply_changed(chip->psy); - } done: mutex_unlock(&chip->lock); @@ -894,11 +886,6 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv) fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)", max_ma, mv); - chip->supply_voltage = mv; - chip->current_limit = max_ma; - - power_supply_changed(chip->psy); - return 0; } @@ -1697,43 +1684,6 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id) return IRQ_HANDLED; } -static int fusb302_psy_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct fusb302_chip *chip = power_supply_get_drvdata(psy); - - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = chip->charge_on; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = chip->supply_voltage * 1000; /* mV -> µV */ - break; - case POWER_SUPPLY_PROP_CURRENT_MAX: - val->intval = chip->current_limit * 1000; /* mA -> µA */ - break; - default: - return -ENODATA; - } - - return 0; -} - -static enum power_supply_property fusb302_psy_properties[] = { - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_MAX, -}; - -static const struct power_supply_desc fusb302_psy_desc = { - .name = "fusb302-typec-source", - .type = POWER_SUPPLY_TYPE_USB_TYPE_C, - .properties = fusb302_psy_properties, - .num_properties = ARRAY_SIZE(fusb302_psy_properties), - .get_property = fusb302_psy_get_property, -}; - static int init_gpio(struct fusb302_chip *chip) { struct device_node *node; @@ -1773,7 +1723,6 @@ static int fusb302_probe(struct i2c_client *client, struct fusb302_chip *chip; struct i2c_adapter *adapter; struct device *dev = &client->dev; - struct power_supply_config cfg = {}; const char *name; int ret = 0; u32 v; @@ -1820,14 +1769,6 @@ static int fusb302_probe(struct i2c_client *client, return -EPROBE_DEFER; } - cfg.drv_data = chip; - chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg); - if (IS_ERR(chip->psy)) { - ret = PTR_ERR(chip->psy); - dev_err(chip->dev, "Error registering power-supply: %d\n", ret); - return ret; - } - ret = fusb302_debugfs_init(chip); if (ret < 0) return ret; diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index b66d26c..b86a51c 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -281,6 +282,11 @@ struct tcpm_port { u32 current_limit; u32 supply_voltage; + /* Used to export TA voltage and current */ + struct power_supply *psy; + struct power_supply_desc psy_desc; + enum power_supply_conn_type connected_type; + u32 bist_request; /* PD state for Vendor Defined Messages */ @@ -1893,6 +1899,7 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, int ret = -EINVAL; port->pps_data.supported = false; + port->connected_type = POWER_SUPPLY_CONN_TYPE_USB_PD; /* * Select the source PDO providing the most power which has a @@ -1974,8 +1981,11 @@ static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, } break; case PDO_TYPE_APDO: - if (pdo_apdo_type(pdo) == APDO_TYPE_PPS) + if (pdo_apdo_type(pdo) == APDO_TYPE_PPS) { port->pps_data.supported = true; + port->connected_type = + POWER_SUPPLY_CONN_TYPE_USB_PD_PPS; + } continue; default: tcpm_log(port, "Invalid PDO type, ignoring"); @@ -2459,6 +2469,9 @@ static void tcpm_reset_port(struct tcpm_port *port) port->try_snk_count = 0; port->supply_voltage = 0; port->current_limit = 0; + port->connected_type = POWER_SUPPLY_CONN_TYPE_USB_TYPE_C; + + power_supply_changed(port->psy); } static void tcpm_detach(struct tcpm_port *port) @@ -2991,6 +3004,8 @@ static void run_state_machine(struct tcpm_port *port) tcpm_pps_complete(port, port->pps_status); + power_supply_changed(port->psy); + break; /* Accessory states */ @@ -4170,6 +4185,218 @@ static int nr_type_pdos(const u32 *pdo, unsigned int nr_pdo, return count; } +/* Power Supply access to expose source power information */ +enum tcpm_psy_online_states { + TCPM_PSY_OFFLINE = 0, + TCPM_PSY_FIXED_ONLINE, + TCPM_PSY_PROG_ONLINE, +}; + +static enum power_supply_property tcpm_psy_props[] = { + POWER_SUPPLY_PROP_CONNECTED_TYPE, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_MIN, + POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_MAX, + POWER_SUPPLY_PROP_CURRENT_NOW, +}; + +static int tcpm_psy_get_online(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->vbus_charge) { + if (port->pps_data.active) + val->intval = TCPM_PSY_PROG_ONLINE; + else + val->intval = TCPM_PSY_FIXED_ONLINE; + } else { + val->intval = TCPM_PSY_OFFLINE; + } + + return 0; +} + +static int tcpm_psy_get_voltage_min(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->pps_data.active) + val->intval = port->pps_data.min_volt * 1000; + else + val->intval = port->supply_voltage * 1000; + + return 0; +} + +static int tcpm_psy_get_voltage_max(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->pps_data.active) + val->intval = port->pps_data.max_volt * 1000; + else + val->intval = port->supply_voltage * 1000; + + return 0; +} + +static int tcpm_psy_get_voltage_now(struct tcpm_port *port, + union power_supply_propval *val) +{ + val->intval = port->supply_voltage * 1000; + + return 0; +} + +static int tcpm_psy_get_current_max(struct tcpm_port *port, + union power_supply_propval *val) +{ + if (port->pps_data.active) + val->intval = port->pps_data.max_curr * 1000; + else + val->intval = port->current_limit * 1000; + + return 0; +} + +static int tcpm_psy_get_current_now(struct tcpm_port *port, + union power_supply_propval *val) +{ + val->intval = port->current_limit * 1000; + + return 0; +} + +static int tcpm_psy_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct tcpm_port *port = power_supply_get_drvdata(psy); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_CONNECTED_TYPE: + val->intval = port->connected_type; + break; + case POWER_SUPPLY_PROP_ONLINE: + ret = tcpm_psy_get_online(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN: + ret = tcpm_psy_get_voltage_min(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + ret = tcpm_psy_get_voltage_max(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + ret = tcpm_psy_get_voltage_now(port, val); + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + ret = tcpm_psy_get_current_max(port, val); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + ret = tcpm_psy_get_current_now(port, val); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int tcpm_psy_set_online(struct tcpm_port *port, + const union power_supply_propval *val) +{ + int ret; + + switch (val->intval) { + case TCPM_PSY_FIXED_ONLINE: + ret = tcpm_pps_activate(port, false); + break; + case TCPM_PSY_PROG_ONLINE: + ret = tcpm_pps_activate(port, true); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int tcpm_psy_set_prop(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct tcpm_port *port = power_supply_get_drvdata(psy); + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + ret = tcpm_psy_set_online(port, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if ((val->intval < (port->pps_data.min_volt * 1000)) || + (val->intval > (port->pps_data.max_volt * 1000))) + ret = -EINVAL; + else + ret = tcpm_pps_set_out_volt(port, (val->intval / 1000)); + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + if (val->intval > (port->pps_data.max_curr * 1000)) + ret = -EINVAL; + else + ret = tcpm_pps_set_op_curr(port, (val->intval / 1000)); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int tcpm_psy_prop_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_CURRENT_NOW: + return 1; + default: + return 0; + } +} + +static enum power_supply_conn_type tcpm_psy_conn_types[] = { + POWER_SUPPLY_CONN_TYPE_USB_TYPE_C, + POWER_SUPPLY_CONN_TYPE_USB_PD, + POWER_SUPPLY_CONN_TYPE_USB_PD_PPS, +}; + +static int devm_tcpm_psy_register(struct tcpm_port *port) +{ + struct power_supply_config psy_cfg = {}; + + psy_cfg.drv_data = port; + port->psy_desc.name = "tcpm-source-psy", + port->psy_desc.type = POWER_SUPPLY_TYPE_USB, + port->psy_desc.conn_types = tcpm_psy_conn_types; + port->psy_desc.num_conn_types = ARRAY_SIZE(tcpm_psy_conn_types); + port->psy_desc.properties = tcpm_psy_props, + port->psy_desc.num_properties = ARRAY_SIZE(tcpm_psy_props), + port->psy_desc.get_property = tcpm_psy_get_prop, + port->psy_desc.set_property = tcpm_psy_set_prop, + port->psy_desc.property_is_writeable = tcpm_psy_prop_writeable, + + port->connected_type = POWER_SUPPLY_CONN_TYPE_USB_TYPE_C; + + port->psy = devm_power_supply_register(port->dev, &port->psy_desc, + &psy_cfg); + + return PTR_ERR_OR_ZERO(port->psy); +} + struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) { struct tcpm_port *port; @@ -4253,6 +4480,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) port->partner_desc.identity = &port->partner_ident; port->port_type = tcpc->config->type; + err = devm_tcpm_psy_register(port); + if (err) + goto out_destroy_wq; + port->typec_port = typec_register_port(port->dev, &port->typec_caps); if (!port->typec_port) { err = -ENOMEM; -- 1.9.1