aboutsummaryrefslogtreecommitdiff
path: root/hw/p8-i2c.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-06-23 14:26:00 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-06 17:06:54 +1000
commit3e58874e2b8b67d7050bb0e6da4e3f8d033e07f8 (patch)
tree2844dd28ef03d697dbb08bb0ca8153d354e3765c /hw/p8-i2c.c
parent6408e5a03b7c779b924b385af1506bcb0a3eb3b5 (diff)
downloadskiboot-3e58874e2b8b67d7050bb0e6da4e3f8d033e07f8.zip
skiboot-3e58874e2b8b67d7050bb0e6da4e3f8d033e07f8.tar.gz
skiboot-3e58874e2b8b67d7050bb0e6da4e3f8d033e07f8.tar.bz2
p8-i2c: Keep centaur OCC cache disabled during inits
To avoid possible XSCOM collisions Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/p8-i2c.c')
-rw-r--r--hw/p8-i2c.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index 510604a..5295ad8 100644
--- a/hw/p8-i2c.c
+++ b/hw/p8-i2c.c
@@ -866,7 +866,8 @@ static int p8_i2c_start_request(struct p8_i2c_master *master,
DBG("Disabling OCC cache...\n");
rc = centaur_disable_sensor_cache(master->chip_id);
if (rc < 0) {
- log_simple_error(&e_info(OPAL_RC_I2C_START_REQ), "I2C: Failed "
+ log_simple_error(&e_info(OPAL_RC_I2C_START_REQ),
+ "I2C: Failed "
"to disable the sensor cache\n");
return rc;
}
@@ -1225,7 +1226,7 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
struct list_head *chip_list;
uint64_t ex_stat;
static bool irq_printed;
- int rc;
+ int64_t rc;
master = zalloc(sizeof(*master));
if (!master) {
@@ -1254,6 +1255,10 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
struct centaur_chip *centaur = get_centaur(master->chip_id);
assert(centaur);
chip_list = &centaur->i2cms;
+
+ /* Detect bad device-tree from HostBoot giving us bogus
+ * i2c masters
+ */
if (master->engine_id > 0) {
prlog(PR_ERR, "I2C: Skipping Centaur Master #1\n");
free(master);
@@ -1272,11 +1277,24 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
prlog(PR_INFO, "I2C: Chip %08x Eng. %d\n",
master->chip_id, master->engine_id);
+ /* Disable OCC cache during inits */
+ if (master->type == I2C_CENTAUR) {
+ rc = centaur_disable_sensor_cache(master->chip_id);
+ if (rc < 0) {
+ log_simple_error(&e_info(OPAL_RC_I2C_INIT), "I2C: "
+ "Error %lld disabling sensor cache\n",
+ rc);
+ /* Ignore error and move on ... */
+ } else
+ time_wait(rc);
+ }
rc = xscom_read(master->chip_id, master->xscom_base +
I2C_EXTD_STAT_REG, &ex_stat);
if (rc) {
log_simple_error(&e_info(OPAL_RC_I2C_INIT), "I2C: "
"Failed to read EXTD_STAT_REG\n");
+ if (master->type == I2C_CENTAUR)
+ centaur_enable_sensor_cache(master->chip_id);
free(master);
return;
}
@@ -1294,6 +1312,12 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
/* Program the watermark register */
rc = p8_i2c_prog_watermark(master);
+
+ /* Re-enable the sensor cache, we aren't touching HW anymore */
+ if (master->type == I2C_CENTAUR)
+ centaur_enable_sensor_cache(master->chip_id);
+
+ /* Handle errors from p8_i2c_prog_watermark */
if (rc) {
log_simple_error(&e_info(OPAL_RC_I2C_INIT),
"I2C: Failed to program the "