Received: by 10.192.165.148 with SMTP id m20csp4133845imm; Tue, 8 May 2018 03:36:25 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrb3CItZoMHbTYTpiOoz+10VXy8MCuoj7pOz4Yd5e6+wgsZXyBUf1glOrjsOUIATK8AaeG4 X-Received: by 2002:a17:902:a585:: with SMTP id az5-v6mr34643063plb.79.1525775785543; Tue, 08 May 2018 03:36:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525775785; cv=none; d=google.com; s=arc-20160816; b=H6tkiz94gIzsbuNvGj1Fyq4i9qJreu957Wzunoz98o6fwBH2TwwmRc3kCYKrTFwl0H ZrrZSqrLGtl02K0iioreSiwalGRnWnDxLLyQyPgxaiOrYtenSrp8eeUinwIIVIwkRgzv I4HvJ5ZFaQJLW+teGq5RAqDhLsYp7ls4u8G8M9IeQif9Ho3tJok75CTbsAzGYW642q1N DWF+lVD4ojcbj/cGJGRJbQUnDMgrneFwkAVAL4L5K4NUg2A4X+ukK1EAwWGLf1sAQwHz XcKdkbjYth1ci315bj6kOX4ofBfcPQ5+vPSESm7x3EAzbyo8RGztPw9/b8bknrnKPhWt 9YnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:message-id:references :in-reply-to:subject:cc:to:from:date:content-transfer-encoding :mime-version:dkim-signature:dkim-signature :arc-authentication-results; bh=oW54fr2Kciw7gp1mvjNaKGJvJ4lLSWPBs4WAFo9Witw=; b=rrtyPucdsBHB++23l/OQ2gLOvH1twRr9/cnPpTs5ZCLuIFv7nHYYzgbWCjMOWtpFEc FWKx2/sp9Scpn30DziqxFGjxAjkehFf2S4LyrQ64OWhk2Xh994DEQoLf3rtThB/+Udgd ijdkIbANYEREFq28g02q7N6oaBDKJQo6bE4yLyjQTXpDzIrMaeYfqAfVyU30xRWUw4gO ttN6rdq7Nu4livaDrbMVZu4inifzE/0tYW67nACJvJbLMCk0Hgf8HETkc3Pnfl5+cqOr e0wMVrTdbd5sdGagVQx/0tWNtaMOx0Hgi5flZVxFXI08pJt6HhyJ7hjN6D1mfXDC+c0q O7eg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=ZtjqYavG; dkim=pass header.i=@codeaurora.org header.s=default header.b=dWkqL9V6; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t11-v6si19029487pgn.337.2018.05.08.03.36.11; Tue, 08 May 2018 03:36:25 -0700 (PDT) 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=@codeaurora.org header.s=default header.b=ZtjqYavG; dkim=pass header.i=@codeaurora.org header.s=default header.b=dWkqL9V6; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932229AbeEHKfm (ORCPT + 99 others); Tue, 8 May 2018 06:35:42 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:40084 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754408AbeEHKfj (ORCPT ); Tue, 8 May 2018 06:35:39 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 307A5600D0; Tue, 8 May 2018 10:35:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525775739; bh=bQDIqUxplUTvjhrJSqBlf7Lhz22iFEIG9oy1LgiaPrk=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=ZtjqYavG4kvqFpuBTJNtEPP6VdLcTsY49C8XQFsc0sYY0RglLPHow4oz5zQ5ZiEOB 7kHuhbJAQdhzgH9/e1QDkBYFzX5SAYjsSCw++rzegAOQptOQuanvxc58dzvkSsXAho pNEtutwC/cOi9ExhjEmsmIWXkj7Yg+bgnwkodXFg= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from mail.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id D2274600D0; Tue, 8 May 2018 10:35:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525775737; bh=bQDIqUxplUTvjhrJSqBlf7Lhz22iFEIG9oy1LgiaPrk=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=dWkqL9V6RLio6HwUiSYIpcjv4QTwaoIayVhfjTW5v+WtSBxyKUYNRIW57nnEQTrHh s6Em7nyd0YYuhWHvkvi3wWkhHDQPjisrJwq8veGZrduyNmDPknTCP+lF5tS+otm4Ky M6JtXOyB+79CIpQlmWkScTkeUxf5bDiEebNP8CEU= MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Date: Tue, 08 May 2018 16:05:37 +0530 From: kgunda@codeaurora.org To: Bjorn Andersson Cc: Lee Jones , Daniel Thompson , Jingoo Han , Bartlomiej Zolnierkiewicz , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-leds@vger.kernel.org Subject: Re: [PATCH V1 3/5] backlight: qcom-wled: Add support for short circuit handling In-Reply-To: <20180507170652.GC2259@tuxbook-pro> References: <1525341432-15818-1-git-send-email-kgunda@codeaurora.org> <1525341432-15818-4-git-send-email-kgunda@codeaurora.org> <20180507170652.GC2259@tuxbook-pro> Message-ID: X-Sender: kgunda@codeaurora.org User-Agent: Roundcube Webmail/1.2.5 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2018-05-07 22:36, Bjorn Andersson wrote: > On Thu 03 May 02:57 PDT 2018, Kiran Gunda wrote: > >> Handle the short circuit interrupt and check if the short circuit >> interrupt is valid. Re-enable the module to check if it goes >> away. Disable the module altogether if the short circuit event >> persists. >> >> Signed-off-by: Kiran Gunda >> --- >> drivers/video/backlight/qcom-wled.c | 134 >> ++++++++++++++++++++++++++++++++++-- >> 1 file changed, 130 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/video/backlight/qcom-wled.c >> b/drivers/video/backlight/qcom-wled.c >> index be8b8d3..2cfba77 100644 >> --- a/drivers/video/backlight/qcom-wled.c >> +++ b/drivers/video/backlight/qcom-wled.c >> @@ -10,6 +10,9 @@ >> * GNU General Public License for more details. >> */ >> >> +#include >> +#include >> +#include >> #include >> #include >> #include >> @@ -23,7 +26,9 @@ >> >> #define WLED3_SINK_REG_BRIGHT_MAX 0xFFF >> >> -/* Control registers */ >> +/* WLED3 Control registers */ > > Minor nit, please move the change of this comment to the previous > patch. > Ok. Will do it the next series. >> +#define WLED3_CTRL_REG_FAULT_STATUS 0x08 > > Unused. > Will remove it in the next series. >> + >> #define WLED3_CTRL_REG_MOD_EN 0x46 >> #define WLED3_CTRL_REG_MOD_EN_MASK BIT(7) >> >> @@ -36,7 +41,17 @@ >> #define WLED3_CTRL_REG_ILIMIT 0x4e >> #define WLED3_CTRL_REG_ILIMIT_MASK GENMASK(2, 0) >> >> -/* sink registers */ > > Please move comment change to previous commit. > Will remove it in the next series. >> +/* WLED4 control registers */ >> +#define WLED4_CTRL_REG_SHORT_PROTECT 0x5e >> +#define WLED4_CTRL_REG_SHORT_EN_MASK BIT(7) >> + >> +#define WLED4_CTRL_REG_SEC_ACCESS 0xd0 >> +#define WLED4_CTRL_REG_SEC_UNLOCK 0xa5 >> + >> +#define WLED4_CTRL_REG_TEST1 0xe2 >> +#define WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2 0x09 >> + >> +/* WLED3 sink registers */ >> #define WLED3_SINK_REG_SYNC 0x47 >> #define WLED3_SINK_REG_SYNC_MASK GENMASK(2, 0) >> #define WLED4_SINK_REG_SYNC_MASK GENMASK(3, 0) >> @@ -130,17 +145,23 @@ struct wled_config { >> bool cs_out_en; >> bool ext_gen; >> bool cabc; >> + bool external_pfet; >> }; >> >> struct wled { >> const char *name; >> struct device *dev; >> struct regmap *regmap; >> + struct mutex lock; /* Lock to avoid race from ISR */ >> + ktime_t last_short_event; >> u16 ctrl_addr; >> u16 sink_addr; >> u32 brightness; >> u32 max_brightness; >> + u32 short_count; >> const int *version; >> + int short_irq; >> + bool force_mod_disable; > > "bool disabled_by_short" would describe what's going on better. > Will rename it in the next series. >> >> struct wled_config cfg; >> int (*wled_set_brightness)(struct wled *wled, u16 brightness); >> @@ -192,6 +213,9 @@ static int wled_module_enable(struct wled *wled, >> int val) >> { >> int rc; >> >> + if (wled->force_mod_disable) >> + return 0; >> + > > I don't fancy the idea of not telling user space that it's request to > turn on the backlight is ignored. Can we return some error here so that > it's possible for something to do something about this problem? > Sure. Will do it in the next series. >> rc = regmap_update_bits(wled->regmap, wled->ctrl_addr + >> WLED3_CTRL_REG_MOD_EN, >> WLED3_CTRL_REG_MOD_EN_MASK, >> @@ -248,12 +272,13 @@ static int wled_update_status(struct >> backlight_device *bl) >> bl->props.state & BL_CORE_FBBLANK) >> brightness = 0; >> >> + mutex_lock(&wled->lock); >> if (brightness) { >> rc = wled->wled_set_brightness(wled, brightness); >> if (rc < 0) { >> dev_err(wled->dev, "wled failed to set brightness rc:%d\n", >> rc); >> - return rc; >> + goto unlock_mutex; >> } >> >> rc = wled->wled_sync_toggle(wled); >> @@ -267,15 +292,60 @@ static int wled_update_status(struct >> backlight_device *bl) >> rc = wled_module_enable(wled, !!brightness); >> if (rc < 0) { >> dev_err(wled->dev, "wled enable failed rc:%d\n", rc); >> - return rc; >> + goto unlock_mutex; >> } >> } >> >> wled->brightness = brightness; >> >> +unlock_mutex: >> + mutex_unlock(&wled->lock); >> + >> return rc; >> } >> >> +#define WLED_SHORT_DLY_MS 20 >> +#define WLED_SHORT_CNT_MAX 5 >> +#define WLED_SHORT_RESET_CNT_DLY_US HZ > > HZ is in the unit of jiffies, not micro seconds. > Will address in next series. >> +static irqreturn_t wled_short_irq_handler(int irq, void *_wled) >> +{ >> + struct wled *wled = _wled; >> + int rc; >> + s64 elapsed_time; >> + >> + wled->short_count++; >> + mutex_lock(&wled->lock); >> + rc = wled_module_enable(wled, false); >> + if (rc < 0) { >> + dev_err(wled->dev, "wled disable failed rc:%d\n", rc); >> + goto unlock_mutex; >> + } >> + >> + elapsed_time = ktime_us_delta(ktime_get(), >> + wled->last_short_event); >> + if (elapsed_time > WLED_SHORT_RESET_CNT_DLY_US) >> + wled->short_count = 0; >> + >> + if (wled->short_count > WLED_SHORT_CNT_MAX) { >> + dev_err(wled->dev, "Short trigged %d times, disabling WLED >> forever!\n", >> + wled->short_count); >> + wled->force_mod_disable = true; >> + goto unlock_mutex; >> + } >> + >> + wled->last_short_event = ktime_get(); >> + >> + msleep(WLED_SHORT_DLY_MS); >> + rc = wled_module_enable(wled, true); >> + if (rc < 0) >> + dev_err(wled->dev, "wled enable failed rc:%d\n", rc); >> + >> +unlock_mutex: >> + mutex_unlock(&wled->lock); >> + >> + return IRQ_HANDLED; >> +} >> + >> static int wled3_setup(struct wled *wled) >> { >> u16 addr; >> @@ -435,6 +505,21 @@ static int wled4_setup(struct wled *wled) >> return rc; >> } >> >> + if (wled->cfg.external_pfet) { >> + /* Unlock the secure register access */ >> + rc = regmap_write(wled->regmap, wled->ctrl_addr + >> + WLED4_CTRL_REG_SEC_ACCESS, >> + WLED4_CTRL_REG_SEC_UNLOCK); >> + if (rc < 0) >> + return rc; >> + >> + rc = regmap_write(wled->regmap, >> + wled->ctrl_addr + WLED4_CTRL_REG_TEST1, >> + WLED4_CTRL_REG_TEST1_EXT_FET_DTEST2); >> + if (rc < 0) >> + return rc; >> + } >> + >> return 0; >> } >> >> @@ -446,6 +531,7 @@ static int wled4_setup(struct wled *wled) >> .switch_freq = 11, >> .enabled_strings = 0xf, >> .cabc = false, >> + .external_pfet = true, > > You added the "qcom,external-pfet" boolean to dt, but this forces it to > always be set - i.e. this is either wrong or you can omit the new dt > property. > I will make it to false in the next series. >> }; >> >> static const u32 wled3_boost_i_limit_values[] = { >> @@ -628,6 +714,7 @@ static int wled_configure(struct wled *wled) >> { "qcom,cs-out", &cfg->cs_out_en, }, >> { "qcom,ext-gen", &cfg->ext_gen, }, >> { "qcom,cabc", &cfg->cabc, }, >> + { "qcom,external-pfet", &cfg->external_pfet, }, >> }; >> >> prop_addr = of_get_address(dev->of_node, 0, NULL, NULL); >> @@ -701,6 +788,39 @@ static int wled_configure(struct wled *wled) >> return 0; >> } >> >> +static int wled_configure_short_irq(struct wled *wled, >> + struct platform_device *pdev) >> +{ >> + int rc = 0; >> + >> + /* PM8941 doesn't have the short detection support */ >> + if (*wled->version == WLED_PM8941) >> + return 0; > > If you attempt to acquire the "short" irq first in this function you > don't need this check - as "short" won't exist on pm8941. > > Otherwise, it would be better if you add a "bool has_short_detect" to > the wled struct and check that, rather than sprinkling version checks > throughout. > > > Or...is cfg->external_pfet already denoting this? > I think it is better to add the has_short_detect variable, as the external_pfet is only specific to PMI8998. >> + >> + rc = regmap_update_bits(wled->regmap, wled->ctrl_addr + >> + WLED4_CTRL_REG_SHORT_PROTECT, >> + WLED4_CTRL_REG_SHORT_EN_MASK, >> + WLED4_CTRL_REG_SHORT_EN_MASK); > > Do you really want to enable the short protect thing before figuring > out > if you have a "short" irq. > Yes. Irrespective of the interrupt, the short circuit detection should be enabled to protect the HW from the short circuit. >> + if (rc < 0) >> + return rc; >> + >> + wled->short_irq = platform_get_irq_byname(pdev, "short"); > > short_irq isn't used outside this function, so preferably you turn it > into a local variable. > Ok. Will do that in the next series. >> + if (wled->short_irq < 0) { >> + dev_dbg(&pdev->dev, "short irq is not used\n"); >> + return 0; >> + } >> + >> + rc = devm_request_threaded_irq(wled->dev, wled->short_irq, >> + NULL, wled_short_irq_handler, >> + IRQF_ONESHOT, >> + "wled_short_irq", wled); >> + if (rc < 0) >> + dev_err(wled->dev, "Unable to request short_irq (err:%d)\n", >> + rc); >> + >> + return rc; >> +} >> + >> static const struct backlight_ops wled_ops = { >> .update_status = wled_update_status, >> }; >> @@ -733,6 +853,8 @@ static int wled_probe(struct platform_device >> *pdev) >> return -ENODEV; >> } >> >> + mutex_init(&wled->lock); >> + >> rc = wled_configure(wled); >> if (rc) >> return rc; >> @@ -752,6 +874,10 @@ static int wled_probe(struct platform_device >> *pdev) >> } >> } >> >> + rc = wled_configure_short_irq(wled, pdev); >> + if (rc < 0) >> + return rc; >> + >> val = WLED_DEFAULT_BRIGHTNESS; >> of_property_read_u32(pdev->dev.of_node, "default-brightness", &val); > > Regards, > Bjorn