aboutsummaryrefslogtreecommitdiff
path: root/hdata
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-04-12 17:27:26 +1000
committerMichael Neuling <mikey@neuling.org>2017-04-13 12:02:21 +1000
commitbcfa5f2160bcf6b1dd5d037fda831c20294c5f53 (patch)
tree7d2397d32f01b840dbd95ffada5ac0f3172f6817 /hdata
parent044fe827e02734451a1299166d1d020a7d57ff63 (diff)
downloadskiboot-bcfa5f2160bcf6b1dd5d037fda831c20294c5f53.zip
skiboot-bcfa5f2160bcf6b1dd5d037fda831c20294c5f53.tar.gz
skiboot-bcfa5f2160bcf6b1dd5d037fda831c20294c5f53.tar.bz2
hdata/i2c: Workaround broken i2c devices
Some older revisions of hostboot populate the host i2c device fields with all zero entires. Detect and ignore these so we don't crash on boot. Without this we get: [ 151.251240444,3] DT: dt_attach_root failed, duplicate unknown@0 [ 151.251300274,3] *********************************************** [ 151.251339330,3] Unexpected exception 200 ! [ 151.251363654,3] SRR0 : 0000000030090c28 SRR1 : 9000000000201000 [ 151.251409207,3] HSRR0: 0000000000000010 HSRR1: 9000000000001000 [ 151.251444114,3] LR : 30034018300c5ab0 CTR : 30034018300a343c [ 151.251478314,3] CFAR : 0000000030024804 [ 151.251500346,3] CR : 40004208 XER: 00000000 <snip GPRS> [ 151.252083372,0] Aborting! CPU 0034 Backtrace: S: 0000000031cd36a0 R: 000000003001364c .backtrace+0x2c S: 0000000031cd3730 R: 0000000030018db8 ._abort+0x4c S: 0000000031cd37b0 R: 0000000030025c6c .exception_entry+0x114 S: 0000000031cd3840 R: 0000000000001f00 * +0x1f00 S: 0000000031cd3a10 R: 0000000031cd3ab0 * S: 0000000031cd3aa0 R: 00000000300248b8 .new_property+0x90 S: 0000000031cd3b30 R: 0000000030024b50 .__dt_add_property_cells+0x30 S: 0000000031cd3bd0 R: 000000003009abec .parse_i2c_devs+0x350 S: 0000000031cd3cf0 R: 0000000030093ffc .parse_hdat+0x11e4 S: 0000000031cd3e30 R: 00000000300144c8 .main_cpu_entry+0x138 S: 0000000031cd3f00 R: 0000000030002648 boot_entry+0x198 (Modified: removed backtrace() call and added in backtrace to commit) Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Michael Neuling <mikey@neuling.org>
Diffstat (limited to 'hdata')
-rw-r--r--hdata/i2c.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/hdata/i2c.c b/hdata/i2c.c
index 127068f..5a74a7f 100644
--- a/hdata/i2c.c
+++ b/hdata/i2c.c
@@ -132,6 +132,18 @@ static const char *map_label(uint32_t type)
return NULL;
}
+static bool is_zeros(const void *p, size_t size)
+{
+ const char *c = p;
+ size_t i;
+
+ for (i = 0; i < size; i++)
+ if (c[i] != 0)
+ return false;
+
+ return true;
+}
+
int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
struct dt_node *xscom)
{
@@ -140,6 +152,7 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
const struct i2c_dev *dev;
const char *label, *name, *compat;
uint32_t i2c_addr;
+ uint32_t size;
int i, count;
/*
@@ -150,7 +163,16 @@ int parse_i2c_devs(const struct HDIF_common_hdr *hdr, int idata_index,
count = HDIF_get_iarray_size(hdr, idata_index);
for (i = 0; i < count; i++) {
- dev = HDIF_get_iarray_item(hdr, idata_index, i, NULL);
+ dev = HDIF_get_iarray_item(hdr, idata_index, i, &size);
+
+ /*
+ * XXX: Some broken hostboots populate i2c devs with zeros.
+ * Workaround them for now.
+ */
+ if (is_zeros(dev, size)) {
+ prerror("I2C: Ignoring broken i2c dev %d\n", i);
+ continue;
+ }
i2cm = get_i2cm_node(xscom, dev->i2cm_engine);
bus = get_bus_node(i2cm, dev->i2cm_port,