aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2014-11-29 02:30:51 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-12-01 05:49:27 -0500
commited9a84262a83ab0260325c2f5eae39e441003d55 (patch)
tree7a88d3a033b4366a6391b4b456c8d1fda46ca765
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (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.c25
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 @@
32struct tda998x_priv { 32struct 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
419fail: 421fail:
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);
423out:
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);
446out:
447 mutex_unlock(&priv->mutex);
441} 448}
442 449
443static int 450static 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);
477out:
478 mutex_unlock(&priv->mutex);
469} 479}
470 480
471static void 481static 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);
496out:
497 mutex_unlock(&priv->mutex);
485} 498}
486 499
487static void 500static 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);