From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?ISO-8859-15?Q?Christian_K=F6nig?= Subject: Re: [PATCH] drm/radeon: add a i2c bus mutex Date: Mon, 12 May 2014 15:24:20 +0200 Message-ID: <5370CB84.5060405@vodafone.de> References: <1399561084-2017-1-git-send-email-alexander.deucher@amd.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from pegasos-out.vodafone.de (pegasos-out.vodafone.de [80.84.1.38]) by gabe.freedesktop.org (Postfix) with ESMTP id 82EFC6E514 for ; Mon, 12 May 2014 06:24:34 -0700 (PDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by pegasos-out.vodafone.de (Rohrpostix1 Daemon) with ESMTP id C608C2607A7 for ; Mon, 12 May 2014 15:24:33 +0200 (CEST) Received: from pegasos-out.vodafone.de ([127.0.0.1]) by localhost (rohrpostix1.prod.vfnet.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bdKW1Lqt9bwv for ; Mon, 12 May 2014 15:24:28 +0200 (CEST) In-Reply-To: <1399561084-2017-1-git-send-email-alexander.deucher@amd.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Alex Deucher , dri-devel@lists.freedesktop.org Cc: Alex Deucher List-Id: dri-devel@lists.freedesktop.org Am 08.05.2014 16:58, schrieb Alex Deucher: > The i2c and aux buses use the same pads so add > a mutex to protect access to the pads. > > Signed-off-by: Alex Deucher I've applied this one, "drm/radeon: fix DCE83 check for mullins" and "drm/radeon: handle non-VGA class pci devices with ATRM" my 3.15 queue. Thanks, Christian. > --- > drivers/gpu/drm/radeon/atombios_dp.c | 18 ++++++++++++++---- > drivers/gpu/drm/radeon/atombios_i2c.c | 17 +++++++++++++---- > drivers/gpu/drm/radeon/radeon_i2c.c | 9 +++++++++ > drivers/gpu/drm/radeon/radeon_mode.h | 1 + > 4 files changed, 37 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c > index 54e4f52..3bb0933 100644 > --- a/drivers/gpu/drm/radeon/atombios_dp.c > +++ b/drivers/gpu/drm/radeon/atombios_dp.c > @@ -95,9 +95,12 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, > int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); > unsigned char *base; > int recv_bytes; > + int r = 0; > > memset(&args, 0, sizeof(args)); > > + mutex_lock(&chan->mutex); > + > base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); > > radeon_atom_copy_swap(base, send, send_bytes, true); > @@ -117,19 +120,22 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, > /* timeout */ > if (args.v1.ucReplyStatus == 1) { > DRM_DEBUG_KMS("dp_aux_ch timeout\n"); > - return -ETIMEDOUT; > + r = -ETIMEDOUT; > + goto done; > } > > /* flags not zero */ > if (args.v1.ucReplyStatus == 2) { > DRM_DEBUG_KMS("dp_aux_ch flags not zero\n"); > - return -EBUSY; > + r = -EBUSY; > + goto done; > } > > /* error */ > if (args.v1.ucReplyStatus == 3) { > DRM_DEBUG_KMS("dp_aux_ch error\n"); > - return -EIO; > + r = -EIO; > + goto done; > } > > recv_bytes = args.v1.ucDataOutLen; > @@ -139,7 +145,11 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, > if (recv && recv_size) > radeon_atom_copy_swap(recv, base + 16, recv_bytes, false); > > - return recv_bytes; > + r = recv_bytes; > +done: > + mutex_unlock(&chan->mutex); > + > + return r; > } > > #define BARE_ADDRESS_SIZE 3 > diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c > index b5162c3..9c570fb 100644 > --- a/drivers/gpu/drm/radeon/atombios_i2c.c > +++ b/drivers/gpu/drm/radeon/atombios_i2c.c > @@ -43,15 +43,19 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, > int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); > unsigned char *base; > u16 out = cpu_to_le16(0); > + int r = 0; > > memset(&args, 0, sizeof(args)); > > + mutex_lock(&chan->mutex); > + > base = (unsigned char *)rdev->mode_info.atom_context->scratch; > > if (flags & HW_I2C_WRITE) { > if (num > ATOM_MAX_HW_I2C_WRITE) { > DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num); > - return -EINVAL; > + r = -EINVAL; > + goto done; > } > if (buf == NULL) > args.ucRegIndex = 0; > @@ -65,7 +69,8 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, > } else { > if (num > ATOM_MAX_HW_I2C_READ) { > DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); > - return -EINVAL; > + r = -EINVAL; > + goto done; > } > args.ucRegIndex = 0; > args.lpI2CDataOut = 0; > @@ -82,13 +87,17 @@ static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, > /* error */ > if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { > DRM_DEBUG_KMS("hw_i2c error\n"); > - return -EIO; > + r = -EIO; > + goto done; > } > > if (!(flags & HW_I2C_WRITE)) > radeon_atom_copy_swap(buf, base, num, false); > > - return 0; > +done: > + mutex_unlock(&chan->mutex); > + > + return r; > } > > int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, > diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c > index 7b94414..427ee4d 100644 > --- a/drivers/gpu/drm/radeon/radeon_i2c.c > +++ b/drivers/gpu/drm/radeon/radeon_i2c.c > @@ -94,6 +94,8 @@ static int pre_xfer(struct i2c_adapter *i2c_adap) > struct radeon_i2c_bus_rec *rec = &i2c->rec; > uint32_t temp; > > + mutex_lock(&i2c->mutex); > + > /* RV410 appears to have a bug where the hw i2c in reset > * holds the i2c port in a bad state - switch hw i2c away before > * doing DDC - do this for all r200s/r300s/r400s for safety sake > @@ -170,6 +172,8 @@ static void post_xfer(struct i2c_adapter *i2c_adap) > temp = RREG32(rec->mask_data_reg) & ~rec->mask_data_mask; > WREG32(rec->mask_data_reg, temp); > temp = RREG32(rec->mask_data_reg); > + > + mutex_unlock(&i2c->mutex); > } > > static int get_clock(void *i2c_priv) > @@ -813,6 +817,8 @@ static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap, > struct radeon_i2c_bus_rec *rec = &i2c->rec; > int ret = 0; > > + mutex_lock(&i2c->mutex); > + > switch (rdev->family) { > case CHIP_R100: > case CHIP_RV100: > @@ -879,6 +885,8 @@ static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap, > break; > } > > + mutex_unlock(&i2c->mutex); > + > return ret; > } > > @@ -919,6 +927,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, > i2c->adapter.dev.parent = &dev->pdev->dev; > i2c->dev = dev; > i2c_set_adapdata(&i2c->adapter, i2c); > + mutex_init(&i2c->mutex); > if (rec->mm_i2c || > (rec->hw_capable && > radeon_hw_i2c && > diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h > index 6ddf31a..b265a8b 100644 > --- a/drivers/gpu/drm/radeon/radeon_mode.h > +++ b/drivers/gpu/drm/radeon/radeon_mode.h > @@ -191,6 +191,7 @@ struct radeon_i2c_chan { > struct radeon_i2c_bus_rec rec; > struct drm_dp_aux aux; > bool has_aux; > + struct mutex mutex; > }; > > /* mostly for macs, but really any system without connector tables */