Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Upgrading from 5.1_STABLE to 5.99.46 on Sun Fire V100
On Mon, Feb 28, 2011 at 06:53:30PM +0000, Eduardo Horvath wrote:
> On Mon, 28 Feb 2011, Rafal Boni wrote:
>
> > and the OF device tree looks like so:
> >
> > f0069d48: /pci
> > [...]
> > f007b6bc: /pci/pmu@3
> > f007be84: /pci/pmu@3/i2c@0,0
> > f007d31c: /pci/pmu@3/i2c@0,0/temperature@0,30 ("i2c-max1617")
> > f007d48c: /pci/pmu@3/i2c@0,0/dimm@0,a8 ("i2c-at34c02")
> > (more dimms)
> > f007d6b4: /pci/pmu@3/i2c@0,0/i2c-nvram@0,a0 ("i2c-at24c64")
> > f007e1cc: /pci/pmu@3/i2c@0,0/i2c-nvram@0,a0/idprom@1fd8
> > f007e480: /pci/pmu@3/i2c@0,0/motherboard-fru@0,a2 ("i2c-at24c64")
> > f007f018: /pci/pmu@3/ppm@0,b3 ("SUNW,smbus-ppm")
> > f007f28c: /pci/pmu@3/beep@0,b2 ("SUNW,smbus-beep")
> > f007f3a4: /pci/pmu@3/fan-control@0,c8 ("SUNW,smbus-fan-control")
> > [...]
> >
> > Note that what the i2c controller sees as children on my machine are the
> > 'ppm', 'beep' and 'fan-control' instead of (what I would expect):
> > "temparature", N instances of "dimm", "i2c-nvram", "motherboard-fru".
> >
> > What I'm not 100% sure of is whether the peers of the i2c bus should be
> > passed as well or not -- it doesn't make sense to me from the OF tree,
> > but I'm also relatively clueless about OF, so maybe I am missing some-
> > thing.
>
> I think what you're seeing here is that pmu@3 is the SMBUS controller and
> /pci/pmu@3/i2c@0,0 is SMBUS to I2C bridge chip. You should dump the
> properties of /pci/pmu@3 and /pci/pmu@3/i2c@0,0 to be sure.
I think you're right... this is what /pci/pmu@3/i2c@0,0 has for props:
f007be84: /pci/pmu@3/i2c@0,0
#address-cells 00000002 ........ ........ ........ 2
#size-cells 00000000 ........ ........ ........ 0
compatible 6932632d 736d6275 7300.... ........ "i2c-smbus"
interrupts 00000001 ........ ........ ........ ....
name 69326300 ........ ........ ........ "i2c"
reg 00000000 00000000 00000100 00000001 ................
0010: 00000000 00000100 ........ ........ ........
And here's /pci/pmu@3:
f007b6bc: /pci/pmu@3
#address-cells 00000002 ........ ........ ........ 2
#size-cells 00000001 ........ ........ ........ 1
class-code 00000000 ........ ........ ........ ....
compatible 70636931 3062392c 37313031 00...... "pci10b9,7101"
000d: 70636963 6c617373 2c303030 30303000 "pciclass,000000"
device-id 00007101 ........ ........ ........ ..q.
devsel-speed 00000001 ........ ........ ........ ....
max-latency 00000000 ........ ........ ........ ....
min-grant 00000000 ........ ........ ........ ....
name 706d7500 ........ ........ ........ "pmu"
ranges 00000000 00000000 00001800 00000000 ................
0010: 00000000 00000100 00000001 00000000 ................
0020: 81001810 00000000 00004000 00000100 ..........@.....
0030: 00000002 00000000 81001814 00000000 ................
0040: 00000000 00000100 ........ ........ ........
reg 00001800 00000000 00000000 00000000 ................
0010: 00000000 81001810 00000000 00004000 ..............@.
0020: 00000000 00000010 ........ ........ ........
revision-id 00000000 ........ ........ ........ ....
vendor-id 000010b9 ........ ........ ........ ....
But I'm still slightly clueless as far as whether that means I can treat
the smbus devices (fan-control, ppm, beep) as dumb i2c devices, or not.
Adding a loop in of_enter_i2c_devs() that checks for the 'i2c' child
device and enumerates its' children if found gets me the missing i2c
devices, but I'm not sure if I should skip all the smbus devices or
not (and if so, how best to detect the situation):
diff --git a/sys/dev/ofw/ofw_subr.c b/sys/dev/ofw/ofw_subr.c
index 0b074d0..2fa5044 100644
--- a/sys/dev/ofw/ofw_subr.c
+++ b/sys/dev/ofw/ofw_subr.c
@@ -335,7 +335,7 @@ of_get_mode_string(char *buffer, int len)
void
of_enter_i2c_devs(prop_dictionary_t props, int ofnode, size_t cell_size)
{
- int node, len;
+ int node, iicnode, len;
char name[32];
uint64_t reg64;
uint32_t reg32;
@@ -345,9 +345,20 @@ of_enter_i2c_devs(prop_dictionary_t props, int ofnode,
size_t cell_size)
array = prop_array_create();
+ iicnode = 0;
for (node = OF_child(ofnode); node; node = OF_peer(node)) {
if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
continue;
+
+ /*
+ * Could be an SMBus with e.g. an SMBus-I2C bridge; handle the
+ * I2C bus below if we find one.
+ */
+ if (strcmp(name, "i2c") == 0) {
+ iicnode = node;
+ continue;
+ }
+
len = OF_getproplen(node, "reg");
addr = 0;
if (cell_size == 8 && len >= sizeof(reg64)) {
@@ -375,6 +386,39 @@ of_enter_i2c_devs(prop_dictionary_t props, int ofnode,
size_t cell_size)
prop_object_release(dev);
}
+ if (iicnode != 0) {
+ for (node = OF_child(iicnode); node; node = OF_peer(node)) {
+ if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
+ continue;
+
+ len = OF_getproplen(node, "reg");
+ addr = 0;
+ if (cell_size == 8 && len >= sizeof(reg64)) {
+ if (OF_getprop(node, "reg", ®64,
+ sizeof(reg64)) < sizeof(reg64))
+ continue;
+ addr = reg64;
+ } else if (cell_size == 4 && len >= sizeof(reg32)) {
+ if (OF_getprop(node, "reg", ®32,
+ sizeof(reg32)) < sizeof(reg32))
+ continue;
+ addr = reg32;
+ } else {
+ continue;
+ }
+ addr >>= 1;
+ if (addr == 0) continue;
+
+ dev = prop_dictionary_create();
+ prop_dictionary_set_cstring(dev, "name", name);
+ prop_dictionary_set_uint32(dev, "addr", addr);
+ prop_dictionary_set_uint64(dev, "cookie", node);
+ of_to_dataprop(dev, node, "compatible", "compatible");
+ prop_array_add(array, dev);
+ prop_object_release(dev);
+ }
+ }
+
prop_dictionary_set(props, "i2c-child-devices", array);
prop_object_release(array);
}
--
Time is an illusion; lunchtime, doubly so. |/\/\| Rafal Boni
-- Ford Prefect |\/\/|
rafal%pobox.com@localhost
Home |
Main Index |
Thread Index |
Old Index