Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Add support for ACPI-based I2C mux attachment.



details:   https://anonhg.NetBSD.org/src/rev/c11fe29b76a7
branches:  trunk
changeset: 950338:c11fe29b76a7
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Jan 25 12:18:18 2021 +0000

description:
Add support for ACPI-based I2C mux attachment.

diffstat:

 sys/dev/fdt/i2cmux_fdt.c |   26 ++++----
 sys/dev/i2c/i2c.c        |    9 ++-
 sys/dev/i2c/i2cmux.c     |  148 +++++++++++++++++++++++++++++++++++++---------
 sys/dev/i2c/i2cmuxvar.h  |    8 +-
 sys/dev/i2c/pcai2cmux.c  |   71 ++++++++++++++++------
 5 files changed, 195 insertions(+), 67 deletions(-)

diffs (truncated from 502 to 300 lines):

diff -r ecf849f4df92 -r c11fe29b76a7 sys/dev/fdt/i2cmux_fdt.c
--- a/sys/dev/fdt/i2cmux_fdt.c  Mon Jan 25 12:17:24 2021 +0000
+++ b/sys/dev/fdt/i2cmux_fdt.c  Mon Jan 25 12:18:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i2cmux_fdt.c,v 1.6 2021/01/18 02:35:49 thorpej Exp $   */
+/*     $NetBSD: i2cmux_fdt.c,v 1.7 2021/01/25 12:18:18 jmcneill Exp $  */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i2cmux_fdt.c,v 1.6 2021/01/18 02:35:49 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i2cmux_fdt.c,v 1.7 2021/01/25 12:18:18 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/device.h>
@@ -63,7 +63,7 @@
 
        mux_data = kmem_zalloc(sizeof(*mux_data), KM_SLEEP);
 
-       mux_data->npins = fdtbus_gpio_count(sc->sc_phandle, "mux-gpios");
+       mux_data->npins = fdtbus_gpio_count(sc->sc_handle, "mux-gpios");
        if (mux_data->npins == 0) {
                aprint_error_dev(sc->sc_dev,
                    "unable to get mux-gpios property\n");
@@ -73,7 +73,7 @@
        mux_data->pins =
            kmem_zalloc(sizeof(*mux_data->pins) * mux_data->npins, KM_SLEEP);
        for (i = 0; i < mux_data->npins; i++) {
-               mux_data->pins[i] = fdtbus_gpio_acquire_index(sc->sc_phandle,
+               mux_data->pins[i] = fdtbus_gpio_acquire_index(sc->sc_handle,
                    "mux-gpios", i, GPIO_PIN_OUTPUT);
                if (mux_data->pins[i] == NULL) {
                        aprint_error_dev(sc->sc_dev,
@@ -83,7 +83,7 @@
        }
 
        mux_data->has_idle_value =
-           of_getprop_uint32(sc->sc_phandle, "idle-state",
+           of_getprop_uint32(sc->sc_handle, "idle-state",
                              &mux_data->idle_value) == 0;
 
        return mux_data;
@@ -107,7 +107,7 @@
 
        bus_info = kmem_zalloc(sizeof(*bus_info), KM_SLEEP);
 
-       error = fdtbus_get_reg(bus->phandle, 0, &bus_info->value, NULL);
+       error = fdtbus_get_reg(bus->handle, 0, &bus_info->value, NULL);
        if (error) {
                aprint_error_dev(sc->sc_dev,
                    "unable to get reg property for bus %d\n", bus->busidx);
@@ -177,7 +177,7 @@
        mux_info = kmem_alloc(sizeof(*mux_info), KM_SLEEP);
 
        mux_info->has_idle_idx =
-           fdtbus_get_index(sc->sc_phandle, "pinctrl-names", "idle",
+           fdtbus_get_index(sc->sc_handle, "pinctrl-names", "idle",
                             &mux_info->idle_idx) == 0;
 
        return mux_info;
@@ -192,7 +192,7 @@
 
        bus_info = kmem_alloc(sizeof(*bus_info), KM_SLEEP);
 
-       error = fdtbus_get_reg(bus->phandle, 0, &bus_info->idx, NULL);
+       error = fdtbus_get_reg(bus->handle, 0, &bus_info->idx, NULL);
        if (error) {
                aprint_error_dev(sc->sc_dev,
                    "unable to get reg property for bus %d\n", bus->busidx);
@@ -210,7 +210,7 @@
        struct iicmux_softc * const sc = bus->mux;
        struct bus_info_pinctrl * const bus_info = bus->bus_data;
 
-       return fdtbus_pinctrl_set_config_index(sc->sc_phandle, bus_info->idx);
+       return fdtbus_pinctrl_set_config_index(sc->sc_handle, bus_info->idx);
 }
 
 static void
@@ -221,7 +221,7 @@
        struct mux_info_pinctrl * const mux_info = sc->sc_mux_data;
 
        if (mux_info->has_idle_idx) {
-               (void) fdtbus_pinctrl_set_config_index(sc->sc_phandle,
+               (void) fdtbus_pinctrl_set_config_index(sc->sc_handle,
                    mux_info->idle_idx);
        }
 }
@@ -261,13 +261,13 @@
        struct fdt_attach_args * const faa = aux;
 
        sc->sc_dev = self;
-       sc->sc_phandle = faa->faa_phandle;
-       sc->sc_config = of_search_compatible(sc->sc_phandle, compat_data)->data;
+       sc->sc_handle = faa->faa_phandle;
+       sc->sc_config = of_search_compatible(sc->sc_handle, compat_data)->data;
 
        aprint_naive("\n");
        aprint_normal(": %s I2C mux\n", sc->sc_config->desc);
 
-       sc->sc_i2c_parent = fdtbus_i2c_acquire(sc->sc_phandle, "i2c-parent");
+       sc->sc_i2c_parent = fdtbus_i2c_acquire(sc->sc_handle, "i2c-parent");
        if (sc->sc_i2c_parent == NULL) {
                aprint_error_dev(sc->sc_dev, "unable to acquire i2c-parent\n");
                return;
diff -r ecf849f4df92 -r c11fe29b76a7 sys/dev/i2c/i2c.c
--- a/sys/dev/i2c/i2c.c Mon Jan 25 12:17:24 2021 +0000
+++ b/sys/dev/i2c/i2c.c Mon Jan 25 12:18:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i2c.c,v 1.76 2021/01/18 15:28:21 thorpej Exp $ */
+/*     $NetBSD: i2c.c,v 1.77 2021/01/25 12:18:18 jmcneill Exp $        */
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.76 2021/01/18 15:28:21 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.77 2021/01/25 12:18:18 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -439,6 +439,7 @@
                prop_data_t cdata;
                uint32_t addr;
                uint64_t cookie;
+               uint32_t cookietype;
                const char *name;
                struct i2c_attach_args ia;
                int loc[IICCF_NLOCS];
@@ -457,6 +458,9 @@
                                continue;
                        if (!prop_dictionary_get_uint64(dev, "cookie", &cookie))
                                cookie = 0;
+                       if (!prop_dictionary_get_uint32(dev, "cookietype",
+                           &cookietype))
+                               cookietype = I2C_COOKIE_NONE;
                        loc[IICCF_ADDR] = addr;
 
                        memset(&ia, 0, sizeof ia);
@@ -464,6 +468,7 @@
                        ia.ia_tag = ic;
                        ia.ia_name = name;
                        ia.ia_cookie = cookie;
+                       ia.ia_cookietype = cookietype;
                        ia.ia_prop = dev;
 
                        buf = NULL;
diff -r ecf849f4df92 -r c11fe29b76a7 sys/dev/i2c/i2cmux.c
--- a/sys/dev/i2c/i2cmux.c      Mon Jan 25 12:17:24 2021 +0000
+++ b/sys/dev/i2c/i2cmux.c      Mon Jan 25 12:18:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i2cmux.c,v 1.2 2021/01/24 19:35:21 jmcneill Exp $      */
+/*     $NetBSD: i2cmux.c,v 1.3 2021/01/25 12:18:18 jmcneill Exp $      */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -29,8 +29,12 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
+#include "acpica.h"
+#endif
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.2 2021/01/24 19:35:21 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.3 2021/01/25 12:18:18 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/device.h>
@@ -41,6 +45,11 @@
 #include <dev/i2c/i2cvar.h>
 #include <dev/i2c/i2cmuxvar.h>
 
+#if NACPICA > 0
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_i2c.h>
+#endif
+
 /*
  * i2c mux
  *
@@ -154,13 +163,14 @@
 
 static void
 iicmux_attach_bus(struct iicmux_softc * const sc,
-    int const phandle, int const busidx)
+    uintptr_t const handle, enum i2c_cookie_type handletype, int const busidx)
 {
        struct iicmux_bus * const bus = &sc->sc_busses[busidx];
 
        bus->mux = sc;
        bus->busidx = busidx;
-       bus->phandle = phandle;
+       bus->handle = handle;
+       bus->handletype = handletype;
 
        bus->bus_data = sc->sc_config->get_bus_info(bus);
        if (bus->bus_data == NULL) {
@@ -175,41 +185,41 @@
        bus->controller.ic_release_bus = iicmux_release_bus;
        bus->controller.ic_exec = iicmux_exec;
 
-       fdtbus_register_i2c_controller(&bus->controller, bus->phandle);
+       switch (handletype) {
+       case I2C_COOKIE_OF:
+               fdtbus_register_i2c_controller(&bus->controller,
+                   (int)bus->handle);
 
-       fdtbus_attach_i2cbus(sc->sc_dev, bus->phandle, &bus->controller,
-           iicmux_print);
+               fdtbus_attach_i2cbus(sc->sc_dev, (int)bus->handle,
+                   &bus->controller, iicmux_print);
+               break;
+#if NACPICA > 0
+       case I2C_COOKIE_ACPI: {
+               struct acpi_devnode *ad = acpi_match_node((ACPI_HANDLE)handle);
+               KASSERT(ad != NULL);
+               struct i2cbus_attach_args iba = {
+                       .iba_tag = &bus->controller,
+                       .iba_child_devices = acpi_enter_i2c_devs(ad)
+               };
+               config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
+       }       break;
+#endif
+       default:
+               aprint_error_dev(sc->sc_dev, "unknown handle type\n");
+               break;
+       }
 }
 
-void
-iicmux_attach(struct iicmux_softc * const sc)
+static void
+iicmux_attach_fdt(struct iicmux_softc * const sc)
 {
-
-       /*
-        * We expect sc->sc_phandle, sc->sc_config, and sc->sc_i2c_parent
-        * to be initialized by the front-end.
-        */
-       KASSERT(sc->sc_phandle > 0);
-       KASSERT(sc->sc_config != NULL);
-       KASSERT(sc->sc_i2c_parent != NULL);
-
        /*
         * We start out assuming that the i2c bus nodes are children of
         * our own node.  We'll adjust later if we encounter an "i2c-mux"
         * node when counting our children.  If we encounter such a node,
         * then it's that node that is the parent of the i2c bus children.
         */
-       sc->sc_i2c_mux_phandle = sc->sc_phandle;
-
-       /*
-        * Gather up all of the various bits of information needed
-        * for this particular type of i2c mux.
-        */
-       sc->sc_mux_data = sc->sc_config->get_mux_info(sc);
-       if (sc->sc_mux_data == NULL) {
-               aprint_error_dev(sc->sc_dev, "unable to get info for mux\n");
-               return;
-       }
+       sc->sc_i2c_mux_phandle = (int)sc->sc_handle;
 
        sc->sc_nbusses = iicmux_count_children(sc);
        if (sc->sc_nbusses == 0) {
@@ -223,6 +233,84 @@
        for (child = OF_child(sc->sc_i2c_mux_phandle), idx = 0; child;
             child = OF_peer(child), idx++) {
                KASSERT(idx < sc->sc_nbusses);
-               iicmux_attach_bus(sc, child, idx);
+               iicmux_attach_bus(sc, child, I2C_COOKIE_OF, idx);
+       }
+}
+
+#if NACPICA > 0
+static void
+iicmux_attach_acpi(struct iicmux_softc * const sc)
+{
+       ACPI_HANDLE hdl = (ACPI_HANDLE)sc->sc_handle;
+       struct acpi_devnode *devnode, *ad;
+       int idx;
+
+       devnode = acpi_match_node(hdl);
+       KASSERT(devnode != NULL);
+
+       /* Count child busses */
+       sc->sc_nbusses = 0;
+       SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
+               if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE ||
+                   !acpi_device_present(ad->ad_handle)) {
+                       continue;
+               }
+               sc->sc_nbusses++;
+       }
+



Home | Main Index | Thread Index | Old Index