Boot bus I2C based temperature and fan control does not currently work on (at least) SunBlade 2000 systems. This is caused by the resource bbc_i2c_bussel missing on the second BBC I2C bus the temp and fan sensors are attached to, only bbc_i2c_regs is present. While older drivers (2.6.24 era) could cope well with that situation, the present drivers refuse to attach. This seems to be a regression caused by the conversion to pure OF drivers on 2008-08-30: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/sbus/char/bbc_i2c.c?id=e21e245bcd9d5244735799387d14421789b20557 (look for the check "if (edev->num_addrs == 2)") This patch restores the old behavior by checking num_resources before trying to remap the bbc_i2c_bussel resource. If num_resources != 2, only the bbc_i2c_regs resource will be mapped. (The env & temp driver in bbc_envctrl still works well with i2c_bussel_reg set to NULL as it did before in older kernels.) In addition, INIT_LIST_HEAD invocations are needed to set up bbc_cpu_temperature and bbc_fan_control. The fact that these were missing was hidden by the fact that the bbc_envctrl driver obviously did not load at all anymore on the systems where this hardware exists due to the bbc_i2c_bussel problem as discussed above. With these patches, the SunBlade 2000 seems to work fine. The patch was originally developed against a 3.13 backport kernel from Debian. Both the patch against 3.13 and a recent 3.16-rc6 are included below. Please note that I could only test the 3.13 version as I do not have access to the affected machine anymore. PATCH 1 - KERNEL VERSION 3.13 ##################################################### diff -Naupr linux-source-3.13-orig/drivers/sbus/char/bbc_envctrl.c linux-source-3.13-patched/drivers/sbus/char/bbc_envctrl.c --- linux-source-3.13-orig/drivers/sbus/char/bbc_envctrl.c 2014-04-14 15:48:24.000000000 +0200 +++ linux-source-3.13-patched/drivers/sbus/char/bbc_envctrl.c 2014-07-27 14:29:58.000000000 +0200 @@ -452,6 +452,10 @@ static void attach_one_temp(struct bbc_i if (!tp) return; + /* Need to initialize some fields of bbc_cpu_temperature */ + INIT_LIST_HEAD(&(tp->bp_list)); + INIT_LIST_HEAD(&(tp->glob_list)); + tp->client = bbc_i2c_attach(bp, op); if (!tp->client) { kfree(tp); @@ -497,6 +501,10 @@ static void attach_one_fan(struct bbc_i2 if (!fp) return; + /* Need to initialize some fields of bbc_fan_control */ + INIT_LIST_HEAD(&(fp->bp_list)); + INIT_LIST_HEAD(&(fp->glob_list)); + fp->client = bbc_i2c_attach(bp, op); if (!fp->client) { kfree(fp); diff -Naupr linux-source-3.13-orig/drivers/sbus/char/bbc_i2c.c linux-source-3.13-patched/drivers/sbus/char/bbc_i2c.c --- linux-source-3.13-orig/drivers/sbus/char/bbc_i2c.c 2014-04-14 15:48:24.000000000 +0200 +++ linux-source-3.13-patched/drivers/sbus/char/bbc_i2c.c 2014-07-27 14:29:58.000000000 +0200 @@ -301,13 +301,20 @@ static struct bbc_i2c_bus * attach_one_i if (!bp) return NULL; + /* Need to initialize some fields of bbc_i2c_bus */ + INIT_LIST_HEAD(&(bp->temps)); + INIT_LIST_HEAD(&(bp->fans)); + bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs"); if (!bp->i2c_control_regs) goto fail; - bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); - if (!bp->i2c_bussel_reg) - goto fail; + if(op->num_resources == 2) { + bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); + if (!bp->i2c_bussel_reg) { + goto fail; + } + } bp->waiting = 0; init_waitqueue_head(&bp->wq); PATCH 2 - KERNEL VERSION 3.16 ##################################################### diff -Naupr linux-3.16-rc6-orig/drivers/sbus/char/bbc_envctrl.c linux-3.16-rc6-patched/drivers/sbus/char/bbc_envctrl.c --- linux-3.16-rc6-orig/drivers/sbus/char/bbc_envctrl.c 2014-07-27 11:49:21.000000000 +0200 +++ linux-3.16-rc6-patched/drivers/sbus/char/bbc_envctrl.c 2014-07-27 14:28:12.000000000 +0200 @@ -452,6 +452,10 @@ static void attach_one_temp(struct bbc_i if (!tp) return; + /* Need to initialize some fields of bbc_cpu_temperature */ + INIT_LIST_HEAD(&(tp->bp_list)); + INIT_LIST_HEAD(&(tp->glob_list)); + tp->client = bbc_i2c_attach(bp, op); if (!tp->client) { kfree(tp); @@ -497,6 +501,10 @@ static void attach_one_fan(struct bbc_i2 if (!fp) return; + /* Need to initialize some fields of bbc_fan_control */ + INIT_LIST_HEAD(&(fp->bp_list)); + INIT_LIST_HEAD(&(fp->glob_list)); + fp->client = bbc_i2c_attach(bp, op); if (!fp->client) { kfree(fp); diff -Naupr linux-3.16-rc6-orig/drivers/sbus/char/bbc_i2c.c linux-3.16-rc6-patched/drivers/sbus/char/bbc_i2c.c --- linux-3.16-rc6-orig/drivers/sbus/char/bbc_i2c.c 2014-07-27 11:49:45.000000000 +0200 +++ linux-3.16-rc6-patched/drivers/sbus/char/bbc_i2c.c 2014-07-27 14:28:12.000000000 +0200 @@ -300,13 +300,20 @@ static struct bbc_i2c_bus * attach_one_i if (!bp) return NULL; + /* Need to initialize some fields of bbc_i2c_bus */ + INIT_LIST_HEAD(&(bp->temps)); + INIT_LIST_HEAD(&(bp->fans)); + bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs"); if (!bp->i2c_control_regs) goto fail; - bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); - if (!bp->i2c_bussel_reg) - goto fail; + if(op->num_resources == 2) { + bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); + if (!bp->i2c_bussel_reg) { + goto fail; + } + } bp->waiting = 0; init_waitqueue_head(&bp->wq); Regards, Alexander Schulze -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html