Received: by 10.223.164.202 with SMTP id h10csp1390973wrb; Wed, 15 Nov 2017 19:30:15 -0800 (PST) X-Google-Smtp-Source: AGs4zMaXWjBkd9swdyzstr7N9lof9rl6qG8/nFoMdYyymL9sBm/Kf6+h/2cnEq31Ira7ufwdJ8v9 X-Received: by 10.84.212.136 with SMTP id e8mr272238pli.205.1510803015059; Wed, 15 Nov 2017 19:30:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510803015; cv=none; d=google.com; s=arc-20160816; b=h8/415KWv/G1We7DLAtzptJB5xm9LdL6PaitH7Q1i505vcw7B96Dw5FL5EZyedcDOq GYSUU2MU54F8QtmJ4tGpTjjUFj3VBQGNmBvD6jIeyfCm2FNoXKwi2bBBlMj/7PFtN2S8 GRg3kvnXrr/W7GhNP4k1LAJmRVfXkVHycsHmxWqm0TH0bmiWpSzqVRwyghL0FXk9gUC5 2DNzs9027I0umUuo8pleRDevU1uLQBNVwmc/yjTtSP01YhPLfOyT33yJcftQSHtFnK3p Pw5I51fjqzadLoDcCFyG3DX80NMbqE8h03KUIH9/zVtr7ZL7CsaFCzeaQNOuY8Ie9r7g RRRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:subject :message-id:date:from:references:in-reply-to:mime-version :dkim-signature:arc-authentication-results; bh=32YDkTC0AslCOaENP52CYHaj+EoG05KgxjYJEF+X1Hc=; b=wwLHX6JKHlH9MMAM9VJEDnCXcbNI8vpf0sNN0JhTxxb/sRZ0b4chu0MWnINCvLv+O0 ofiAvah7k42dgZJjGj8xuWYXSJdXjm2E1VkoY3os687jGgA5XNmKiZOeNw7EtUSKVOYk 1jYvdBsYHJLPUDzho+9p7MHT+LAs9OHrzm/ss/ACaswG8MCsGiRyRIAexYHrnazrzuWr HDXI+Um5E/fY0Jbszqpc3AhSdcR+UrSCGPIYZ8Qer7L4O/8pYERMsfxKLmwPrBFje1b0 W41RMp1QTt6g7l9/E4iRmcxxttyZzlsKYXlvnvrs3oFnUDJgHCqsTxMPMHq6mFQp4mzW RDWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=KJxXpKsg; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i90si118322pli.491.2017.11.15.19.30.02; Wed, 15 Nov 2017 19:30:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=KJxXpKsg; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758382AbdKPBCA (ORCPT + 89 others); Wed, 15 Nov 2017 20:02:00 -0500 Received: from mail-oi0-f66.google.com ([209.85.218.66]:49822 "EHLO mail-oi0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757551AbdKPBBo (ORCPT ); Wed, 15 Nov 2017 20:01:44 -0500 Received: by mail-oi0-f66.google.com with SMTP id r190so8304612oie.6 for ; Wed, 15 Nov 2017 17:01:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=32YDkTC0AslCOaENP52CYHaj+EoG05KgxjYJEF+X1Hc=; b=KJxXpKsgiWHWGGNzyTvzFkwLuqjyVMbSmt8cWqTF5gu+BLWgUbhi/eGdIKy3IXwjLC fN3AI9+5XXwCK90OtK8xs36KGeL9A1aXbQA4YbYmiuPIjHqMZPMOuI0o3VejkGDg35Ck T6ygjjPspKmKBbD8097uXRbcbhOU2jEHXcGAdvF8RKkCW72Ce1yBcgyT6QRDA5vFooPq EsuGa2lzx4zTa6o6tYAzOO8R0pTqrZ4GnX2KI7jY+2sfJq/zXk080dR4+4d94k7x65PK DL0NxNen2/sLrUDYT2tZ3VsA8aiKqwngtTvuYhaO0BeGWtaovKS0xeVO+RJ7m3L5Vn/S 1Lag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=32YDkTC0AslCOaENP52CYHaj+EoG05KgxjYJEF+X1Hc=; b=XaHcr4s/M6cP8P8x/bMjgD3fewYCvrpBh4WvYMpX2WB1LCRU7O8U6fWyQy+FH0wwE3 Ktwi+Hal4EXeVNbdRVK6pGs/BiF7rOCb9Hf7N+Kcd8RW1kq/AX+MpcTU+uFrKF9qUa4f X3IilVXH1IVMwTc76pS0KQeeUqL/O3T+THF0tr063CzgGNuWNXOCZ130c/6E6gF1IU9H ggdXijnlEdTMmWmo5lE9tx4nicq9lmjPIU80nVVyhypcAMyEDhLGGCOQQOorZz5a7835 yuNFMpbLZcs9an5E2AcDlDIQdArXfqGOZmXQZjMLBO6hxJbT8yN/2VTH3Mo6sWXwKiuA CsOQ== X-Gm-Message-State: AJaThX58JWcrSneZI3kgk8vLVwFS3qg2Ympc4EdK/gc81kjhahd5vABd OsqQtuApQPbxVjgmMw+2j8YYKSA3APdZ/4FAuw0YoA== X-Received: by 10.202.10.70 with SMTP id 67mr10690391oik.271.1510794102852; Wed, 15 Nov 2017 17:01:42 -0800 (PST) MIME-Version: 1.0 Received: by 10.74.168.131 with HTTP; Wed, 15 Nov 2017 17:01:02 -0800 (PST) In-Reply-To: <20171114170531.GB1030@roeck-us.net> References: <20171113002317.29329-1-Badhri@google.com> <20171113002317.29329-2-Badhri@google.com> <20171114170531.GB1030@roeck-us.net> From: Badhri Jagan Sridharan Date: Wed, 15 Nov 2017 17:01:02 -0800 Message-ID: Subject: Re: [PATCH 2/2 v6] typec: tcpm: Only request matching pdos To: Guenter Roeck Cc: Heikki Krogerus , Greg Kroah-Hartman , Dan Carpenter , USB , LKML Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Nov 14, 2017 at 9:05 AM, Guenter Roeck wrote: > On Sun, Nov 12, 2017 at 04:23:17PM -0800, Badhri Jagan Sridharan wrote: >> At present, TCPM code assumes that local device supports >> variable/batt pdos and always selects the pdo with highest >> possible power within the board limit. This assumption >> might not hold good for all devices. To overcome this, >> this patch makes TCPM only accept a source_pdo when there is >> a matching sink pdo. >> >> For Fixed pdos: The voltage should match between the >> incoming source_cap and the registered snk_pdo >> For Variable/Batt pdos: The incoming source_cap voltage >> range should fall within the registered snk_pdo's voltage >> range. >> >> Also, when the cap_mismatch bit is set, the max_power/current >> should be set to the max_current/power of the sink_pdo. >> This is according to: >> >> "If the Capability Mismatch bit is set to one >> The Maximum Operating Current/Power field may contain a value >> larger than the maximum current/power offered in the Source >> Capabilities message=E2=80=99s PDO as referenced by the Object position = field. >> This enables the Sink to indicate that it requires more current/power >> than is being offered. If the Sink requires a different voltage this >> will be indicated by its Sink Capabilities message. >> >> Signed-off-by: Badhri Jagan Sridharan >> Acked-by: Heikki Krogerus > > Reviewed-by: Guenter Roeck > > /* Though I really dislike this new-world comment style. > * It hurts my eyes and distracts me from the code. > */ Did I somehow introduce this ? I dont think I introduced new comments. > >> --- >> Changelog since v1: >> - Rebased the patch on top of drivers/usb/type/tcpm.c >> - Added duplicate pdo check for variable/batt pdo. >> - Fixed tabs as suggested by dan.carpenter@oracle.com >> >> Changelog since v2: >> - Rebase >> >> Changelog since v3: >> - Refactored code fixed formatting issues as suggested >> by heikki.krogerus@linux.intel.com >> >> Changelog since v4: >> - Rebase >> >> Changelog since v5: >> - handling the sink pdo index as pointer argument in tcpm_pd_select_pdo >> - ACK by heikki.krogerus@linux.intel.com >> >> drivers/usb/typec/tcpm.c | 163 +++++++++++++++++++++++++++++++++++-----= ------- >> 1 file changed, 121 insertions(+), 42 deletions(-) >> >> diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c >> index 8b637a4b474b..f4d563ee7690 100644 >> --- a/drivers/usb/typec/tcpm.c >> +++ b/drivers/usb/typec/tcpm.c >> @@ -252,6 +252,9 @@ struct tcpm_port { >> unsigned int nr_src_pdo; >> u32 snk_pdo[PDO_MAX_OBJECTS]; >> unsigned int nr_snk_pdo; >> + unsigned int nr_fixed; /* number of fixed sink PDOs */ >> + unsigned int nr_var; /* number of variable sink PDOs */ >> + unsigned int nr_batt; /* number of battery sink PDOs */ >> u32 snk_vdo[VDO_MAX_OBJECTS]; >> unsigned int nr_snk_vdo; >> >> @@ -1767,39 +1770,90 @@ static int tcpm_pd_check_request(struct tcpm_por= t *port) >> return 0; >> } >> >> -static int tcpm_pd_select_pdo(struct tcpm_port *port) >> +#define min_power(x, y) min(pdo_max_power(x), pdo_max_power(y)) >> +#define min_current(x, y) min(pdo_max_current(x), pdo_max_current(y)) >> + >> +static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, >> + int *src_pdo) >> { >> - unsigned int i, max_mw =3D 0, max_mv =3D 0; >> + unsigned int i, j, max_mw =3D 0, max_mv =3D 0, mw =3D 0, mv =3D 0,= ma =3D 0; >> int ret =3D -EINVAL; >> >> /* >> - * Select the source PDO providing the most power while staying wi= thin >> - * the board's voltage limits. Prefer PDO providing exp >> + * Select the source PDO providing the most power which has a >> + * matchig sink cap. >> */ >> for (i =3D 0; i < port->nr_source_caps; i++) { >> u32 pdo =3D port->source_caps[i]; >> enum pd_pdo_type type =3D pdo_type(pdo); >> - unsigned int mv, ma, mw; >> >> - if (type =3D=3D PDO_TYPE_FIXED) >> - mv =3D pdo_fixed_voltage(pdo); >> - else >> - mv =3D pdo_min_voltage(pdo); >> - >> - if (type =3D=3D PDO_TYPE_BATT) { >> - mw =3D pdo_max_power(pdo); >> - } else { >> - ma =3D min(pdo_max_current(pdo), >> - port->max_snk_ma); >> - mw =3D ma * mv / 1000; >> - } >> - >> - /* Perfer higher voltages if available */ >> - if ((mw > max_mw || (mw =3D=3D max_mw && mv > max_mv)) && >> - mv <=3D port->max_snk_mv) { >> - ret =3D i; >> - max_mw =3D mw; >> - max_mv =3D mv; >> + if (type =3D=3D PDO_TYPE_FIXED) { >> + for (j =3D 0; j < port->nr_fixed; j++) { >> + if (pdo_fixed_voltage(pdo) =3D=3D >> + pdo_fixed_voltage(port->snk_pdo[j])) { >> + ma =3D min_current(pdo, port->snk_= pdo[j]); >> + mv =3D pdo_fixed_voltage(pdo); >> + mw =3D ma * mv / 1000; >> + if (mw > max_mw || >> + (mw =3D=3D max_mw && mv > max_= mv)) { >> + ret =3D 0; >> + *src_pdo =3D i; >> + *sink_pdo =3D j; >> + max_mw =3D mw; >> + max_mv =3D mv; >> + } >> + /* There could only be one fixed p= do >> + * at a specific voltage level. >> + * So breaking here. >> + */ >> + break; >> + } >> + } >> + } else if (type =3D=3D PDO_TYPE_BATT) { >> + for (j =3D port->nr_fixed; >> + j < port->nr_fixed + >> + port->nr_batt; >> + j++) { >> + if (pdo_min_voltage(pdo) >=3D >> + pdo_min_voltage(port->snk_pdo[j]) && >> + pdo_max_voltage(pdo) <=3D >> + pdo_max_voltage(port->snk_pdo[j])) { >> + mw =3D min_power(pdo, port->snk_pd= o[j]); >> + mv =3D pdo_min_voltage(pdo); >> + if (mw > max_mw || >> + (mw =3D=3D max_mw && mv > max_= mv)) { >> + ret =3D 0; >> + *src_pdo =3D i; >> + *sink_pdo =3D j; >> + max_mw =3D mw; >> + max_mv =3D mv; >> + } >> + } >> + } >> + } else if (type =3D=3D PDO_TYPE_VAR) { >> + for (j =3D port->nr_fixed + >> + port->nr_batt; >> + j < port->nr_fixed + >> + port->nr_batt + >> + port->nr_var; >> + j++) { >> + if (pdo_min_voltage(pdo) >=3D >> + pdo_min_voltage(port->snk_pdo[j]) && >> + pdo_max_voltage(pdo) <=3D >> + pdo_max_voltage(port->snk_pdo[j])) { >> + ma =3D min_current(pdo, port->snk_= pdo[j]); >> + mv =3D pdo_min_voltage(pdo); >> + mw =3D ma * mv / 1000; >> + if (mw > max_mw || >> + (mw =3D=3D max_mw && mv > max_= mv)) { >> + ret =3D 0; >> + *src_pdo =3D i; >> + *sink_pdo =3D j; >> + max_mw =3D mw; >> + max_mv =3D mv; >> + } >> + } >> + } >> } >> } >> >> @@ -1811,13 +1865,14 @@ static int tcpm_pd_build_request(struct tcpm_por= t *port, u32 *rdo) >> unsigned int mv, ma, mw, flags; >> unsigned int max_ma, max_mw; >> enum pd_pdo_type type; >> - int index; >> - u32 pdo; >> + int src_pdo_index, snk_pdo_index; >> + u32 pdo, matching_snk_pdo; >> >> - index =3D tcpm_pd_select_pdo(port); >> - if (index < 0) >> + if (tcpm_pd_select_pdo(port, &snk_pdo_index, &src_pdo_index) < 0) >> return -EINVAL; >> - pdo =3D port->source_caps[index]; >> + >> + pdo =3D port->source_caps[src_pdo_index]; >> + matching_snk_pdo =3D port->snk_pdo[snk_pdo_index]; >> type =3D pdo_type(pdo); >> >> if (type =3D=3D PDO_TYPE_FIXED) >> @@ -1825,26 +1880,28 @@ static int tcpm_pd_build_request(struct tcpm_por= t *port, u32 *rdo) >> else >> mv =3D pdo_min_voltage(pdo); >> >> - /* Select maximum available current within the board's power limit= */ >> + /* Select maximum available current within the sink pdo's limit */ >> if (type =3D=3D PDO_TYPE_BATT) { >> - mw =3D pdo_max_power(pdo); >> - ma =3D 1000 * min(mw, port->max_snk_mw) / mv; >> + mw =3D min_power(pdo, matching_snk_pdo); >> + ma =3D 1000 * mw / mv; >> } else { >> - ma =3D min(pdo_max_current(pdo), >> - 1000 * port->max_snk_mw / mv); >> + ma =3D min_current(pdo, matching_snk_pdo); >> + mw =3D ma * mv / 1000; >> } >> - ma =3D min(ma, port->max_snk_ma); >> >> flags =3D RDO_USB_COMM | RDO_NO_SUSPEND; >> >> /* Set mismatch bit if offered power is less than operating power = */ >> - mw =3D ma * mv / 1000; >> max_ma =3D ma; >> max_mw =3D mw; >> if (mw < port->operating_snk_mw) { >> flags |=3D RDO_CAP_MISMATCH; >> - max_mw =3D port->operating_snk_mw; >> - max_ma =3D max_mw * 1000 / mv; >> + if (type =3D=3D PDO_TYPE_BATT && >> + (pdo_max_power(matching_snk_pdo) > pdo_max_power(pdo))= ) >> + max_mw =3D pdo_max_power(matching_snk_pdo); >> + else if (pdo_max_current(matching_snk_pdo) > >> + pdo_max_current(pdo)) >> + max_ma =3D pdo_max_current(matching_snk_pdo); >> } >> >> tcpm_log(port, "cc=3D%d cc1=3D%d cc2=3D%d vbus=3D%d vconn=3D%s pol= arity=3D%d", >> @@ -1853,16 +1910,16 @@ static int tcpm_pd_build_request(struct tcpm_por= t *port, u32 *rdo) >> port->polarity); >> >> if (type =3D=3D PDO_TYPE_BATT) { >> - *rdo =3D RDO_BATT(index + 1, mw, max_mw, flags); >> + *rdo =3D RDO_BATT(src_pdo_index + 1, mw, max_mw, flags); >> >> tcpm_log(port, "Requesting PDO %d: %u mV, %u mW%s", >> - index, mv, mw, >> + src_pdo_index, mv, mw, >> flags & RDO_CAP_MISMATCH ? " [mismatch]" : ""); >> } else { >> - *rdo =3D RDO_FIXED(index + 1, ma, max_ma, flags); >> + *rdo =3D RDO_FIXED(src_pdo_index + 1, ma, max_ma, flags); >> >> tcpm_log(port, "Requesting PDO %d: %u mV, %u mA%s", >> - index, mv, ma, >> + src_pdo_index, mv, ma, >> flags & RDO_CAP_MISMATCH ? " [mismatch]" : ""); >> } >> >> @@ -3593,6 +3650,19 @@ int tcpm_update_sink_capabilities(struct tcpm_por= t *port, const u32 *pdo, >> } >> EXPORT_SYMBOL_GPL(tcpm_update_sink_capabilities); >> >> +static int nr_type_pdos(const u32 *pdo, unsigned int nr_pdo, >> + enum pd_pdo_type type) >> +{ >> + int count =3D 0; >> + int i; >> + >> + for (i =3D 0; i < nr_pdo; i++) { >> + if (pdo_type(pdo[i]) =3D=3D type) >> + count++; >> + } >> + return count; >> +} >> + >> struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_de= v *tcpc) >> { >> struct tcpm_port *port; >> @@ -3638,6 +3708,15 @@ struct tcpm_port *tcpm_register_port(struct devic= e *dev, struct tcpc_dev *tcpc) >> tcpc->config->nr_src_pdo); >> port->nr_snk_pdo =3D tcpm_copy_pdos(port->snk_pdo, tcpc->config->s= nk_pdo, >> tcpc->config->nr_snk_pdo); >> + port->nr_fixed =3D nr_type_pdos(port->snk_pdo, >> + port->nr_snk_pdo, >> + PDO_TYPE_FIXED); >> + port->nr_var =3D nr_type_pdos(port->snk_pdo, >> + port->nr_snk_pdo, >> + PDO_TYPE_VAR); >> + port->nr_batt =3D nr_type_pdos(port->snk_pdo, >> + port->nr_snk_pdo, >> + PDO_TYPE_BATT); >> port->nr_snk_vdo =3D tcpm_copy_vdos(port->snk_vdo, tcpc->config->s= nk_vdo, >> tcpc->config->nr_snk_vdo); >> >> -- >> 2.15.0.448.gf294e3d99a-goog >> From 1584191092145559917@xxx Thu Nov 16 03:19:16 +0000 2017 X-GM-THRID: 1581628275778143409 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread