diff options
| -rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index d4762799351d..6795f094f737 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | struct tda998x_priv { | 32 | struct tda998x_priv { |
| 33 | struct i2c_client *cec; | 33 | struct i2c_client *cec; |
| 34 | struct i2c_client *hdmi; | 34 | struct i2c_client *hdmi; |
| 35 | struct mutex mutex; | ||
| 35 | uint16_t rev; | 36 | uint16_t rev; |
| 36 | uint8_t current_page; | 37 | uint8_t current_page; |
| 37 | int dpms; | 38 | int dpms; |
| @@ -402,9 +403,10 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) | |||
| 402 | uint8_t addr = REG2ADDR(reg); | 403 | uint8_t addr = REG2ADDR(reg); |
| 403 | int ret; | 404 | int ret; |
| 404 | 405 | ||
| 406 | mutex_lock(&priv->mutex); | ||
| 405 | ret = set_page(priv, reg); | 407 | ret = set_page(priv, reg); |
| 406 | if (ret < 0) | 408 | if (ret < 0) |
| 407 | return ret; | 409 | goto out; |
| 408 | 410 | ||
| 409 | ret = i2c_master_send(client, &addr, sizeof(addr)); | 411 | ret = i2c_master_send(client, &addr, sizeof(addr)); |
| 410 | if (ret < 0) | 412 | if (ret < 0) |
| @@ -414,10 +416,12 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) | |||
| 414 | if (ret < 0) | 416 | if (ret < 0) |
| 415 | goto fail; | 417 | goto fail; |
| 416 | 418 | ||
| 417 | return ret; | 419 | goto out; |
| 418 | 420 | ||
| 419 | fail: | 421 | fail: |
| 420 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); | 422 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); |
| 423 | out: | ||
| 424 | mutex_unlock(&priv->mutex); | ||
| 421 | return ret; | 425 | return ret; |
| 422 | } | 426 | } |
| 423 | 427 | ||
| @@ -431,13 +435,16 @@ reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) | |||
| 431 | buf[0] = REG2ADDR(reg); | 435 | buf[0] = REG2ADDR(reg); |
| 432 | memcpy(&buf[1], p, cnt); | 436 | memcpy(&buf[1], p, cnt); |
| 433 | 437 | ||
| 438 | mutex_lock(&priv->mutex); | ||
| 434 | ret = set_page(priv, reg); | 439 | ret = set_page(priv, reg); |
| 435 | if (ret < 0) | 440 | if (ret < 0) |
| 436 | return; | 441 | goto out; |
| 437 | 442 | ||
| 438 | ret = i2c_master_send(client, buf, cnt + 1); | 443 | ret = i2c_master_send(client, buf, cnt + 1); |
| 439 | if (ret < 0) | 444 | if (ret < 0) |
| 440 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 445 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 446 | out: | ||
| 447 | mutex_unlock(&priv->mutex); | ||
| 441 | } | 448 | } |
| 442 | 449 | ||
| 443 | static int | 450 | static int |
| @@ -459,13 +466,16 @@ reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) | |||
| 459 | uint8_t buf[] = {REG2ADDR(reg), val}; | 466 | uint8_t buf[] = {REG2ADDR(reg), val}; |
| 460 | int ret; | 467 | int ret; |
| 461 | 468 | ||
| 469 | mutex_lock(&priv->mutex); | ||
| 462 | ret = set_page(priv, reg); | 470 | ret = set_page(priv, reg); |
| 463 | if (ret < 0) | 471 | if (ret < 0) |
| 464 | return; | 472 | goto out; |
| 465 | 473 | ||
| 466 | ret = i2c_master_send(client, buf, sizeof(buf)); | 474 | ret = i2c_master_send(client, buf, sizeof(buf)); |
| 467 | if (ret < 0) | 475 | if (ret < 0) |
| 468 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 476 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 477 | out: | ||
| 478 | mutex_unlock(&priv->mutex); | ||
| 469 | } | 479 | } |
| 470 | 480 | ||
| 471 | static void | 481 | static void |
| @@ -475,13 +485,16 @@ reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) | |||
| 475 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; | 485 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; |
| 476 | int ret; | 486 | int ret; |
| 477 | 487 | ||
| 488 | mutex_lock(&priv->mutex); | ||
| 478 | ret = set_page(priv, reg); | 489 | ret = set_page(priv, reg); |
| 479 | if (ret < 0) | 490 | if (ret < 0) |
| 480 | return; | 491 | goto out; |
| 481 | 492 | ||
| 482 | ret = i2c_master_send(client, buf, sizeof(buf)); | 493 | ret = i2c_master_send(client, buf, sizeof(buf)); |
| 483 | if (ret < 0) | 494 | if (ret < 0) |
| 484 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 495 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
| 496 | out: | ||
| 497 | mutex_unlock(&priv->mutex); | ||
| 485 | } | 498 | } |
| 486 | 499 | ||
| 487 | static void | 500 | static void |
| @@ -1268,6 +1281,8 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
| 1268 | 1281 | ||
| 1269 | priv->dpms = DRM_MODE_DPMS_OFF; | 1282 | priv->dpms = DRM_MODE_DPMS_OFF; |
| 1270 | 1283 | ||
| 1284 | mutex_init(&priv->mutex); /* protect the page access */ | ||
| 1285 | |||
| 1271 | /* wake up the device: */ | 1286 | /* wake up the device: */ |
| 1272 | cec_write(priv, REG_CEC_ENAMODS, | 1287 | cec_write(priv, REG_CEC_ENAMODS, |
| 1273 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); | 1288 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); |
