Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp1018763rwl; Fri, 24 Mar 2023 05:20:18 -0700 (PDT) X-Google-Smtp-Source: AKy350aD109HJSyvyH1Ypp+qVMfqw9zzt5LCzhDOCtlnVoi840yuIH1zGAJquojJOezMWnOvG3AB X-Received: by 2002:a17:90b:3b85:b0:237:c7ed:8f4d with SMTP id pc5-20020a17090b3b8500b00237c7ed8f4dmr2887070pjb.15.1679660417903; Fri, 24 Mar 2023 05:20:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679660417; cv=none; d=google.com; s=arc-20160816; b=uWn8xsMB+aNARG/wZnah3rXPZ2wD+qBA9uOsE51lIx9HIzOXyPl5cAM57B/bfDo8XK z4+ioPqWGVBd28OdI41B572CJvW0p+oqUhjwKt4eLo4RrPLa9pzZ+A8Nd/VImSwqVT5D lpf6EnP296hPA3WiF06u49/xijyeD62aT0ckLExUo7kYpbh8xwtRGAPBbRyFeMBSxVZI kAvs3syFcK0kzDlW44sAWcVJASdl1KwDhfk2hHCz1pnnteS7r5iJVYPtoVBCW3N1IrA6 2L5ZCCwoVeFAru9mtURTSn0TVnERt7RLvls+aqESdAuY4Hh+Y3I6kzlqtW/xmkxFIf/0 JCgQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to :organization:from:references:cc:to:content-language:subject :user-agent:mime-version:date:message-id:dkim-signature; bh=NaIoSkXmzJEZ3N0DzXOGFikhqk+EUKbWNCmfU3OE+FU=; b=CKaCg+HFdgjbfxwmqVtOQVT8FO83smt4SsrwkmXlUqRenKYDmRkx4dLRttTaY2Y/pX FvCD++BbtsMauaySktD+3ws2XP8Bf8qfkHkuI/2CsZ8AAqR4JCVtFHvSZmp1ypQEcQVb 1qeThKOzja5NoEX2ACNMGd1h+tgxQqFgz3HW51Ct4iOGTj5BRZIpW/Z6dvoQvSkpH+fT 9aaTBDeSEpWzJfnox5Xw5w02RvL3Dvg61TjkOvuzP9Dxlpl4h1sALBiS4g/ZkKb2pWLq 4CuqNoSWtT5Hdz5OBu4cy3AtBe83ovGoq3Y9h2+0QPESflShDM4kJ5eSHhSmWVs7MMmn wREA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=MneyLKVW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q85-20020a632a58000000b0050f818e900dsi13638747pgq.761.2023.03.24.05.20.06; Fri, 24 Mar 2023 05:20:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=MneyLKVW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231494AbjCXMS3 (ORCPT + 99 others); Fri, 24 Mar 2023 08:18:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230329AbjCXMS1 (ORCPT ); Fri, 24 Mar 2023 08:18:27 -0400 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6758472B1 for ; Fri, 24 Mar 2023 05:18:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679660293; x=1711196293; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=PKE0MEshjiDwVlOUwR4Uz4lxMO0rQWAJqCRKBhjdS1k=; b=MneyLKVWYbdgYUDXS92K1vG0vYbn95j5h9yyQFgoAX54tAheg3HBwBAt q2LUw/KK4IHIf4zXLEVlT3cctafmMEKGGRAXuP2nTktxfWyU7x/zXWyUQ w0HMAJhsoOpTDkLUGsYLZ6/NGNKK8XyBZoLczqi6ntiGj2B3oMRFxj2Yp +Dlm+6unNk8+3oNdllT8hMR8rxL29ISF6IRnVjk/AT/AlfSR5HE12dGg/ JNFKAIqCIEXIGP8KuTnlSwSaRzy/BCbhuiDIdUgvSwGoaSXT80AxJwQK9 Rbqf+6NXWpebQXaKkAswoXPivd4C01UB3E/ea4JlZws1EW/AdC3JuahmZ g==; X-IronPort-AV: E=McAfee;i="6600,9927,10658"; a="328182534" X-IronPort-AV: E=Sophos;i="5.98,287,1673942400"; d="scan'208";a="328182534" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Mar 2023 05:18:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10658"; a="771867047" X-IronPort-AV: E=Sophos;i="5.98,287,1673942400"; d="scan'208";a="771867047" Received: from ahajda-mobl.ger.corp.intel.com (HELO [10.213.24.232]) ([10.213.24.232]) by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Mar 2023 05:18:09 -0700 Message-ID: Date: Fri, 24 Mar 2023 13:18:07 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0 Thunderbird/102.9.0 Subject: Re: [PATCH] drm/bridge: it6505: Add lock for it6505 i2c bank Content-Language: en-US To: Hsin-Yi Wang , Robert Foss , Douglas Anderson Cc: Neil Armstrong , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , David Airlie , Daniel Vetter , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, kenneth.hung@ite.corp-partner.google.com, xiazhengqiao References: <20230324072958.2993946-1-hsinyi@chromium.org> From: Andrzej Hajda Organization: Intel Technology Poland sp. z o.o. - ul. Slowackiego 173, 80-298 Gdansk - KRS 101882 - NIP 957-07-52-316 In-Reply-To: <20230324072958.2993946-1-hsinyi@chromium.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 24.03.2023 08:29, Hsin-Yi Wang wrote: > From: xiazhengqiao > > When the i2c bank register (REG_BANK_SEL) is set to 1, > only the registers belong to bank 1 can be written. > There will be a race condition when a process is writing > bank 0 registers while another process set the bank to 1. > Add a mutex to handle regmap read/write locking for > registers in multiple i2c bank. Since the driver now > owns the lock, there's no need to use regmap API's lock. > > Signed-off-by: xiazhengqiao > Signed-off-by: Hsin-Yi Wang > --- > drivers/gpu/drm/bridge/ite-it6505.c | 72 ++++++++++++++++++++++------- > 1 file changed, 55 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c > index bc451b2a77c28..1a8dcc49fc1ee 100644 > --- a/drivers/gpu/drm/bridge/ite-it6505.c > +++ b/drivers/gpu/drm/bridge/ite-it6505.c > @@ -258,12 +258,12 @@ > #define REG_AUD_INFOFRAM_SUM 0xFB > > /* the following six registers are in bank1 */ > -#define REG_DRV_0_DB_800_MV 0x7E > -#define REG_PRE_0_DB_800_MV 0x7F > -#define REG_PRE_3P5_DB_800_MV 0x81 > -#define REG_SSC_CTRL0 0x88 > -#define REG_SSC_CTRL1 0x89 > -#define REG_SSC_CTRL2 0x8A > +#define REG_DRV_0_DB_800_MV 0x17E > +#define REG_PRE_0_DB_800_MV 0x17F > +#define REG_PRE_3P5_DB_800_MV 0x181 > +#define REG_SSC_CTRL0 0x188 > +#define REG_SSC_CTRL1 0x189 > +#define REG_SSC_CTRL2 0x18A > > #define RBR DP_LINK_BW_1_62 > #define HBR DP_LINK_BW_2_7 > @@ -414,12 +414,14 @@ struct it6505 { > struct mutex extcon_lock; > struct mutex mode_lock; /* used to bridge_detect */ > struct mutex aux_lock; /* used to aux data transfers */ > + struct mutex bank_lock; /* used to protect i2c bank access */ > struct regmap *regmap; > struct drm_display_mode source_output_mode; > struct drm_display_mode video_info; > struct notifier_block event_nb; > struct extcon_dev *extcon; > struct work_struct extcon_wq; > + int bank_state; /* 1 indicates bank 1, 0 indicates bank 0 */ > int extcon_state; > enum drm_connector_status connector_status; > enum link_train_status link_state; > @@ -502,8 +504,22 @@ static const struct regmap_config it6505_regmap_config = { > .val_bits = 8, > .volatile_table = &it6505_bridge_volatile_table, > .cache_type = REGCACHE_NONE, > + .disable_locking = true, > + .can_sleep = true, > }; > > +static int it6505_config_bank(struct it6505 *it6505, unsigned int reg_addr) > +{ > + int err = 0, target = !!(reg_addr > 0xff); > + > + if (target != it6505->bank_state) { It would be better to return if equal, this way you can avoid indentation. > + err = regmap_write(it6505->regmap, REG_BANK_SEL, target); > + if (!err) > + it6505->bank_state = target; > + } > + return err; > +} > + > static int it6505_read(struct it6505 *it6505, unsigned int reg_addr) > { > unsigned int value; > @@ -513,7 +529,10 @@ static int it6505_read(struct it6505 *it6505, unsigned int reg_addr) > if (!it6505->powered) > return -ENODEV; > > - err = regmap_read(it6505->regmap, reg_addr, &value); > + mutex_lock(&it6505->bank_lock); > + err = it6505_config_bank(it6505, reg_addr); > + err |= regmap_read(it6505->regmap, reg_addr & 0xff, &value); Shoudn't be rather if (!err) err = regmap_read(...) ? > + mutex_unlock(&it6505->bank_lock); > if (err < 0) { > dev_err(dev, "read failed reg[0x%x] err: %d", reg_addr, err); > return err; > @@ -531,8 +550,10 @@ static int it6505_write(struct it6505 *it6505, unsigned int reg_addr, > if (!it6505->powered) > return -ENODEV; > > - err = regmap_write(it6505->regmap, reg_addr, reg_val); > - > + mutex_lock(&it6505->bank_lock); > + err = it6505_config_bank(it6505, reg_addr); > + err |= regmap_write(it6505->regmap, reg_addr & 0xff, reg_val); > + mutex_unlock(&it6505->bank_lock); > if (err < 0) { > dev_err(dev, "write failed reg[0x%x] = 0x%x err = %d", > reg_addr, reg_val, err); > @@ -551,7 +572,10 @@ static int it6505_set_bits(struct it6505 *it6505, unsigned int reg, > if (!it6505->powered) > return -ENODEV; > > - err = regmap_update_bits(it6505->regmap, reg, mask, value); > + mutex_lock(&it6505->bank_lock); > + err = it6505_config_bank(it6505, reg); > + err |= regmap_update_bits(it6505->regmap, reg & 0xff, mask, value); > + mutex_unlock(&it6505->bank_lock); > if (err < 0) { > dev_err(dev, "write reg[0x%x] = 0x%x mask = 0x%x failed err %d", > reg, value, mask, err); > @@ -892,7 +916,10 @@ static void it6505_aux_reset(struct it6505 *it6505) > > static void it6505_reset_logic(struct it6505 *it6505) > { > + mutex_lock(&it6505->bank_lock); > + it6505_config_bank(it6505, REG_RESET_CTRL); > regmap_write(it6505->regmap, REG_RESET_CTRL, ALL_LOGIC_RESET); > + mutex_unlock(&it6505->bank_lock); Why not call it6505_write ? > usleep_range(1000, 1500); > } > > @@ -972,9 +999,14 @@ static ssize_t it6505_aux_operation(struct it6505 *it6505, > it6505_write(it6505, REG_AUX_ADR_16_19, > ((address >> 16) & 0x0F) | ((size - 1) << 4)); > > - if (cmd == CMD_AUX_NATIVE_WRITE) > + if (cmd == CMD_AUX_NATIVE_WRITE) { > + mutex_lock(&it6505->bank_lock); > + it6505_config_bank(it6505, REG_AUX_OUT_DATA0); > regmap_bulk_write(it6505->regmap, REG_AUX_OUT_DATA0, buffer, > size); > + mutex_unlock(&it6505->bank_lock); > + } > + > > /* Aux Fire */ > it6505_write(it6505, REG_AUX_CMD_REQ, cmd); > @@ -1197,9 +1229,12 @@ static int it6505_send_video_infoframe(struct it6505 *it6505, > if (err) > return err; > > - err = regmap_bulk_write(it6505->regmap, REG_AVI_INFO_DB1, > + mutex_lock(&it6505->bank_lock); > + err = it6505_config_bank(it6505, REG_AVI_INFO_DB1); > + err |= regmap_bulk_write(it6505->regmap, REG_AVI_INFO_DB1, > buffer + HDMI_INFOFRAME_HEADER_SIZE, > frame->length); > + mutex_unlock(&it6505->bank_lock); Common code with it6505_aux_operation, maybe it6505_bulk_write ? Have you checked if regmap does not support banking? IMO it should be implemented there. Regards Andrzej > if (err) > return err; > > @@ -1267,7 +1302,6 @@ static void it6505_init(struct it6505 *it6505) > it6505_write(it6505, REG_TIME_STMP_CTRL, > EN_SSC_GAT | EN_ENHANCE_VID_STMP | EN_ENHANCE_AUD_STMP); > it6505_write(it6505, REG_INFOFRAME_CTRL, 0x00); > - it6505_write(it6505, REG_BANK_SEL, 0x01); > it6505_write(it6505, REG_DRV_0_DB_800_MV, > afe_setting_table[it6505->afe_setting][0]); > it6505_write(it6505, REG_PRE_0_DB_800_MV, > @@ -1277,7 +1311,6 @@ static void it6505_init(struct it6505 *it6505) > it6505_write(it6505, REG_SSC_CTRL0, 0x9E); > it6505_write(it6505, REG_SSC_CTRL1, 0x1C); > it6505_write(it6505, REG_SSC_CTRL2, 0x42); > - it6505_write(it6505, REG_BANK_SEL, 0x00); > } > > static void it6505_video_disable(struct it6505 *it6505) > @@ -1506,11 +1539,9 @@ static void it6505_setup_ssc(struct it6505 *it6505) > it6505_set_bits(it6505, REG_TRAIN_CTRL0, SPREAD_AMP_5, > it6505->enable_ssc ? SPREAD_AMP_5 : 0x00); > if (it6505->enable_ssc) { > - it6505_write(it6505, REG_BANK_SEL, 0x01); > it6505_write(it6505, REG_SSC_CTRL0, 0x9E); > it6505_write(it6505, REG_SSC_CTRL1, 0x1C); > it6505_write(it6505, REG_SSC_CTRL2, 0x42); > - it6505_write(it6505, REG_BANK_SEL, 0x00); > it6505_write(it6505, REG_SP_CTRL0, 0x07); > it6505_write(it6505, REG_IP_CTRL1, 0x29); > it6505_write(it6505, REG_IP_CTRL2, 0x03); > @@ -1983,8 +2014,11 @@ static int it6505_setup_sha1_input(struct it6505 *it6505, u8 *sha1_input) > it6505_set_bits(it6505, REG_HDCP_CTRL2, HDCP_EN_M0_READ, > HDCP_EN_M0_READ); > > - err = regmap_bulk_read(it6505->regmap, REG_M0_0_7, > + mutex_lock(&it6505->bank_lock); > + err = it6505_config_bank(it6505, REG_M0_0_7); > + err |= regmap_bulk_read(it6505->regmap, REG_M0_0_7, > sha1_input + msg_count, 8); > + mutex_unlock(&it6505->bank_lock); > > it6505_set_bits(it6505, REG_HDCP_CTRL2, HDCP_EN_M0_READ, 0x00); > > @@ -2577,6 +2611,9 @@ static int it6505_poweron(struct it6505 *it6505) > } > > it6505->powered = true; > + mutex_lock(&it6505->bank_lock); > + it6505->bank_state = 0; > + mutex_unlock(&it6505->bank_lock); > it6505_reset_logic(it6505); > it6505_int_mask_enable(it6505); > it6505_init(it6505); > @@ -3359,6 +3396,7 @@ static int it6505_i2c_probe(struct i2c_client *client) > mutex_init(&it6505->extcon_lock); > mutex_init(&it6505->mode_lock); > mutex_init(&it6505->aux_lock); > + mutex_init(&it6505->bank_lock); > > it6505->bridge.of_node = client->dev.of_node; > it6505->connector_status = connector_status_disconnected;