Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/thorpej-i2c-spi-conf]: src/sys/dev/ofw Deal with quirks / differences in...



details:   https://anonhg.NetBSD.org/src/rev/f921e1f59861
branches:  thorpej-i2c-spi-conf
changeset: 378769:f921e1f59861
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri May 14 00:44:13 2021 +0000

description:
Deal with quirks / differences in OpenFirmware implementations'
interpreation of the i2c "reg" property by embedding knowledge
of those quicks directly, rather than forcing lots of drivers
to provide their own devhandle implementations.  We default to
assuming the Device Tree bindings, and tweak based on platform-
specific #ifdefs.

Start with __HAVE_OPENFIRMWARE_VARIANT_AAPL (all i2c "reg" properties
encode an address that's shifted left 1 bit to account for the R/W bit
that appears on the wire).

diffstat:

 sys/arch/macppc/dev/pmu.c       |  60 ++--------------------------------------
 sys/arch/macppc/dev/smu.c       |  59 +--------------------------------------
 sys/arch/macppc/include/types.h |   3 +-
 sys/dev/ofw/ofw_i2c_subr.c      |  40 +++++++++++++++-----------
 sys/dev/ofw/openfirm.h          |   4 +--
 5 files changed, 31 insertions(+), 135 deletions(-)

diffs (truncated from 323 to 300 lines):

diff -r 53330833b0d6 -r f921e1f59861 sys/arch/macppc/dev/pmu.c
--- a/sys/arch/macppc/dev/pmu.c Thu May 13 00:59:26 2021 +0000
+++ b/sys/arch/macppc/dev/pmu.c Fri May 14 00:44:13 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmu.c,v 1.37.2.1 2021/05/08 22:39:41 thorpej Exp $ */
+/*     $NetBSD: pmu.c,v 1.37.2.2 2021/05/14 00:44:13 thorpej Exp $ */
 
 /*-
  * Copyright (c) 2006 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmu.c,v 1.37.2.1 2021/05/08 22:39:41 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmu.c,v 1.37.2.2 2021/05/14 00:44:13 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,12 +91,6 @@ struct pmu_softc {
        bus_space_tag_t sc_memt;
        bus_space_handle_t sc_memh;
 
-       /*
-        * We provide our own i2c device enumeration method, so we
-        * need to provide our own devhandle_impl.
-        */
-       struct devhandle_impl sc_devhandle_impl;
-
        uint32_t sc_flags;
 #define PMU_HAS_BACKLIGHT_CONTROL      1
        int sc_node;
@@ -242,42 +236,6 @@ static const char *has_two_smart_batteri
        "PowerBook1,1",
        NULL };
 
-static bool
-pmu_i2c_get_address(int node, uint32_t *addrp)
-{
-       uint32_t reg;
-
-       if (of_getprop_uint32(node, "reg", &reg) == -1) {
-               return false;
-       }
-
-       *addrp = (reg & 0xff) >> 1;
-       return true;
-}
-
-static int
-pmu_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
-{
-       /*
-        * This follows the OpenFirmware I2C binding for the most
-        * part, but has the address shifted left for the READ bit.
-        */
-       return of_i2c_enumerate_devices_ext(dev, call_handle, v,
-           pmu_i2c_get_address);
-}
-
-static device_call_t
-pmu_devhandle_lookup_device_call(devhandle_t handle, const char *name,
-    devhandle_t *call_handlep)
-{
-       if (strcmp(name, "i2c-enumerate-devices") == 0) {
-               return pmu_i2c_enumerate_devices;
-       }
-
-       /* Defer everything else to the "super". */
-       return NULL;
-}
-
 static int
 pmu_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -382,18 +340,6 @@ pmu_attach(device_t parent, device_t sel
                        goto next;
 
                if (strncmp(name, "pmu-i2c", 8) == 0) {
-                       /*
-                        * Give the OFW node to the i2c bus instance,
-                        * but provide our own devhandle_impl, because
-                        * we have our own device enumeration method.
-                        */
-                       devhandle_t devhandle = devhandle_from_of(node);
-                       devhandle_impl_inherit(&sc->sc_devhandle_impl,
-                           devhandle.impl);
-                       sc->sc_devhandle_impl.lookup_device_call =
-                           pmu_devhandle_lookup_device_call;
-                       devhandle.impl = &sc->sc_devhandle_impl;
-
                        /* fill in the i2c tag */
                        iic_tag_init(&sc->sc_i2c);
                        sc->sc_i2c.ic_cookie = sc;
@@ -403,7 +349,7 @@ pmu_attach(device_t parent, device_t sel
                        iba.iba_tag = &sc->sc_i2c;
                        config_found(sc->sc_dev, &iba, iicbus_print,
                            CFARG_IATTR, "i2cbus",
-                           CFARG_DEVHANDLE, devhandle,
+                           CFARG_DEVHANDLE, devhandle_from_of(node),
                            CFARG_EOL);
                        goto next;
                }
diff -r 53330833b0d6 -r f921e1f59861 sys/arch/macppc/dev/smu.c
--- a/sys/arch/macppc/dev/smu.c Thu May 13 00:59:26 2021 +0000
+++ b/sys/arch/macppc/dev/smu.c Fri May 14 00:44:13 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smu.c,v 1.13.2.1 2021/05/09 21:37:04 thorpej Exp $     */
+/*     $NetBSD: smu.c,v 1.13.2.2 2021/05/14 00:44:13 thorpej Exp $     */
 
 /*-
  * Copyright (c) 2013 Phileas Fogg
@@ -117,11 +117,6 @@ struct smu_softc {
        int sc_num_fans;
        struct smu_fan sc_fans[SMU_MAX_FANS];
 
-       /*
-        * We provide our own i2c device enumeration method, so we
-        * need to provide our own devhandle_impl.
-        */
-       struct devhandle_impl sc_devhandle_impl;
        LIST_HEAD(, smu_iicbus) sc_iic_busses;
 
        struct todr_chip_handle sc_todr;
@@ -448,48 +443,11 @@ smu_setup_fans(struct smu_softc *sc)
        }
 }
 
-static bool
-smu_i2c_get_address(int node, uint32_t *addrp)
-{
-       uint32_t reg;
-
-       if (of_getprop_uint32(node, "reg", &reg) == -1) {
-               return false;
-       }
-
-       *addrp = (reg & 0xff) >> 1;
-       return true;
-}
-
-static int
-smu_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
-{
-       /*
-        * This follows the OpenFirmware I2C binding for the most
-        * part, but has the address shifted left for the READ bit.
-        */
-       return of_i2c_enumerate_devices_ext(dev, call_handle, v,
-           smu_i2c_get_address);
-}
-
-static device_call_t
-smu_devhandle_lookup_device_call(devhandle_t handle, const char *name,
-    devhandle_t *call_handlep)
-{
-       if (strcmp(name, "i2c-enumerate-devices") == 0) {
-               return smu_i2c_enumerate_devices;
-       }
-
-       /* Defer everything else to the "super". */
-       return NULL;
-}
-
 static void
 smu_setup_iicbus(struct smu_softc *sc)
 {
        struct smu_iicbus *iicbus;
        struct i2cbus_attach_args iba;
-       devhandle_t devhandle;
        int node;
        char name[32];
 
@@ -497,16 +455,6 @@ smu_setup_iicbus(struct smu_softc *sc)
        if (node == 0)
                node = sc->sc_node;
 
-       /*
-        * Set up our devhandle impl; we provide our own i2c device
-        * enumeration method.
-        */
-       devhandle = devhandle_from_of(node);
-       devhandle_impl_inherit(&sc->sc_devhandle_impl,
-           devhandle.impl);
-       sc->sc_devhandle_impl.lookup_device_call =
-           smu_devhandle_lookup_device_call;
-
        for (node = OF_child(node); node != 0; node = OF_peer(node)) {
 
                memset(name, 0, sizeof(name));
@@ -530,15 +478,12 @@ smu_setup_iicbus(struct smu_softc *sc)
                iicbus->i2c.ic_cookie = iicbus;
                iicbus->i2c.ic_exec = smu_iicbus_exec;
 
-               devhandle = devhandle_from_of(node);
-               devhandle.impl = &sc->sc_devhandle_impl;
-
                memset(&iba, 0, sizeof(iba));
                iba.iba_tag = &iicbus->i2c;
                iba.iba_bus = iicbus->reg;
 
                config_found(sc->sc_dev, &iba, iicbus_print_multi,
-                   CFARG_DEVHANDLE, devhandle,
+                   CFARG_DEVHANDLE, devhandle_from_of(node),
                    CFARG_EOL);
        }
 }
diff -r 53330833b0d6 -r f921e1f59861 sys/arch/macppc/include/types.h
--- a/sys/arch/macppc/include/types.h   Thu May 13 00:59:26 2021 +0000
+++ b/sys/arch/macppc/include/types.h   Fri May 14 00:44:13 2021 +0000
@@ -1,5 +1,6 @@
-/*     $NetBSD: types.h,v 1.14 2011/07/17 23:23:53 dyoung Exp $        */
+/*     $NetBSD: types.h,v 1.14.70.1 2021/05/14 00:44:13 thorpej Exp $  */
 
 #include <powerpc/types.h>
 
 #define        __HAVE_NEW_STYLE_BUS_H
+#define        __HAVE_OPENFIRMWARE_VARIANT_AAPL
diff -r 53330833b0d6 -r f921e1f59861 sys/dev/ofw/ofw_i2c_subr.c
--- a/sys/dev/ofw/ofw_i2c_subr.c        Thu May 13 00:59:26 2021 +0000
+++ b/sys/dev/ofw/ofw_i2c_subr.c        Fri May 14 00:44:13 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ofw_i2c_subr.c,v 1.1.6.2 2021/05/08 15:51:30 thorpej Exp $     */
+/*     $NetBSD: ofw_i2c_subr.c,v 1.1.6.3 2021/05/14 00:44:13 thorpej Exp $     */
 
 /*
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -60,44 +60,49 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ofw_i2c_subr.c,v 1.1.6.2 2021/05/08 15:51:30 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ofw_i2c_subr.c,v 1.1.6.3 2021/05/14 00:44:13 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
+#include <sys/endian.h>
 #include <sys/kmem.h>
 #include <sys/systm.h>
 #include <dev/ofw/openfirm.h>
 #include <dev/i2c/i2cvar.h>
 
-/*
- * Standard routine for fetching an i2c device address, according
- * to the standard OpenFirmware / Device Tree bindings.
- */
 static bool
 of_i2c_get_address(int node, uint32_t *addrp)
 {
        uint32_t reg;
 
-       if (of_getprop_uint32(node, "reg", &reg) == -1) {
+       if (OF_getprop(node, "reg", &reg, sizeof(reg)) != sizeof(reg)) {
                return false;
        }
 
+       reg = be32toh(reg);
+
+#ifdef __HAVE_OPENFIRMWARE_VARIANT_AAPL
+       /*
+        * Apple OpenFirmware implementations have the i2c device
+        * address shifted left 1 bit to account for the r/w bit
+        * on the wire.
+        */
+       reg = (reg & 0xff) >> 1;
+#endif /* __HAVE_OPENFIRMWARE_VARIANT_AAPL */
+
        *addrp = reg;
        return true;
 }
 
+/*
+ * This follows the Device Tree bindings for i2c, which for the most part
+ * work for the classical OpenFirmware implementations, as well.  There are
+ * some quirks do deal with for different OpenFirmware implementations, which
+ * are mainly in how the "reg" property is interpreted.
+ */
 static int
 of_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
 {
-       return of_i2c_enumerate_devices_ext(dev, call_handle, v,
-           of_i2c_get_address);
-}
-OF_DEVICE_CALL_REGISTER("i2c-enumerate-devices", of_i2c_enumerate_devices);
-
-int
-of_i2c_enumerate_devices_ext(device_t dev, devhandle_t call_handle, void *v,
-    bool (*get_address)(int, uint32_t *))
-{
        struct i2c_enumerate_devices_args *args = v;
        int i2c_node, node;
        char name[32], compat_buf[32];
@@ -113,7 +118,7 @@ of_i2c_enumerate_devices_ext(device_t de
                if (OF_getprop(node, "name", name, sizeof(name)) <= 0) {
                        continue;
                }
-               if (!get_address(node, &addr)) {
+               if (!of_i2c_get_address(node, &addr)) {
                        continue;
                }
 



Home | Main Index | Thread Index | Old Index