diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2014-11-29 02:30:51 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-12-01 05:49:27 -0500 |
commit | ed9a84262a83ab0260325c2f5eae39e441003d55 (patch) | |
tree | 7a88d3a033b4366a6391b4b456c8d1fda46ca765 | |
parent | f114040e3ea6e07372334ade75d1ee0775c355e1 (diff) |
drm: tda998x: Protect the page register
As the HDMI registers of the TDA998x chips are accessed by pages,
the page register must be protected.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-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); |