From patchwork Wed Feb 13 16:36:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heikki Krogerus X-Patchwork-Id: 10810355 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 88BB1922 for ; Wed, 13 Feb 2019 16:37:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 762C42D96F for ; Wed, 13 Feb 2019 16:37:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6A1572DA86; Wed, 13 Feb 2019 16:37:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0B4612D96F for ; Wed, 13 Feb 2019 16:37:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392610AbfBMQg7 (ORCPT ); Wed, 13 Feb 2019 11:36:59 -0500 Received: from mga18.intel.com ([134.134.136.126]:43649 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391852AbfBMQg6 (ORCPT ); Wed, 13 Feb 2019 11:36:58 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Feb 2019 08:36:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,366,1544515200"; d="scan'208";a="146548693" Received: from black.fi.intel.com (HELO black.fi.intel.com.) ([10.237.72.28]) by fmsmga001.fm.intel.com with ESMTP; 13 Feb 2019 08:36:56 -0800 From: Heikki Krogerus To: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Subject: [PATCH] usb: typec: tps6598x: Check mode of operation Date: Wed, 13 Feb 2019 19:36:55 +0300 Message-Id: <20190213163655.14540-1-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP To prevent loading of the driver when the PD controller is still in some operational mode that the driver does not support, checking the mode in driver probe callback function. TI PD controllers may be in undefined mode of operation for example when the application code (firmware) is completely missing. Signed-off-by: Heikki Krogerus --- drivers/usb/typec/tps6598x.c | 53 +++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c index 1c0033ad8738..9947c87d2a1e 100644 --- a/drivers/usb/typec/tps6598x.c +++ b/drivers/usb/typec/tps6598x.c @@ -14,6 +14,8 @@ #include /* Register offsets */ +#define TPS_REG_VID 0x00 +#define TPS_REG_MODE 0x03 #define TPS_REG_CMD1 0x08 #define TPS_REG_DATA1 0x09 #define TPS_REG_INT_EVENT1 0x14 @@ -66,6 +68,20 @@ struct tps6598x_rx_identity_reg { #define TPS_TASK_TIMEOUT 1 #define TPS_TASK_REJECTED 3 +enum { + TPS_MODE_APP, + TPS_MODE_BOOT, + TPS_MODE_BIST, + TPS_MODE_DISC, +}; + +static const char *const modes[] = { + [TPS_MODE_APP] = "APP ", + [TPS_MODE_BOOT] = "BOOT", + [TPS_MODE_BIST] = "BIST", + [TPS_MODE_DISC] = "DISC", +}; + /* Unrecognized commands will be replaced with "!CMD" */ #define INVALID_CMD(_cmd_) (_cmd_ == 0x444d4321) @@ -384,6 +400,32 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data) return IRQ_HANDLED; } +static int tps6598x_check_mode(struct tps6598x *tps) +{ + char mode[5] = { }; + int ret; + + ret = tps6598x_read32(tps, TPS_REG_MODE, (void *)mode); + if (ret) + return ret; + + switch (match_string(modes, ARRAY_SIZE(modes), mode)) { + case TPS_MODE_APP: + return 0; + case TPS_MODE_BOOT: + dev_warn(tps->dev, "dead-battery condition\n"); + return 0; + case TPS_MODE_BIST: + case TPS_MODE_DISC: + default: + dev_err(tps->dev, "controller in unsupported mode \"%s\"\n", + mode); + break; + } + + return -ENODEV; +} + static const struct regmap_config tps6598x_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -409,10 +451,8 @@ static int tps6598x_probe(struct i2c_client *client) if (IS_ERR(tps->regmap)) return PTR_ERR(tps->regmap); - ret = tps6598x_read32(tps, 0, &vid); - if (ret < 0) - return ret; - if (!vid) + ret = tps6598x_read32(tps, TPS_REG_VID, &vid); + if (ret < 0 || !vid) return -ENODEV; /* @@ -425,6 +465,11 @@ static int tps6598x_probe(struct i2c_client *client) if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) tps->i2c_protocol = true; + /* Make sure the controller has application firmware running */ + ret = tps6598x_check_mode(tps); + if (ret) + return ret; + ret = tps6598x_read32(tps, TPS_REG_STATUS, &status); if (ret < 0) return ret;