Module Name:    src
Committed By:   thorpej
Date:           Fri May 14 00:44:13 UTC 2021

Modified Files:
        src/sys/arch/macppc/dev [thorpej-i2c-spi-conf]: pmu.c smu.c
        src/sys/arch/macppc/include [thorpej-i2c-spi-conf]: types.h
        src/sys/dev/ofw [thorpej-i2c-spi-conf]: ofw_i2c_subr.c openfirm.h

Log Message:
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).


To generate a diff of this commit:
cvs rdiff -u -r1.37.2.1 -r1.37.2.2 src/sys/arch/macppc/dev/pmu.c
cvs rdiff -u -r1.13.2.1 -r1.13.2.2 src/sys/arch/macppc/dev/smu.c
cvs rdiff -u -r1.14 -r1.14.70.1 src/sys/arch/macppc/include/types.h
cvs rdiff -u -r1.1.6.2 -r1.1.6.3 src/sys/dev/ofw/ofw_i2c_subr.c
cvs rdiff -u -r1.47.2.1 -r1.47.2.2 src/sys/dev/ofw/openfirm.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/macppc/dev/pmu.c
diff -u src/sys/arch/macppc/dev/pmu.c:1.37.2.1 src/sys/arch/macppc/dev/pmu.c:1.37.2.2
--- src/sys/arch/macppc/dev/pmu.c:1.37.2.1	Sat May  8 22:39:41 2021
+++ src/sys/arch/macppc/dev/pmu.c	Fri May 14 00:44:13 2021
@@ -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;
 		}

Index: src/sys/arch/macppc/dev/smu.c
diff -u src/sys/arch/macppc/dev/smu.c:1.13.2.1 src/sys/arch/macppc/dev/smu.c:1.13.2.2
--- src/sys/arch/macppc/dev/smu.c:1.13.2.1	Sun May  9 21:37:04 2021
+++ src/sys/arch/macppc/dev/smu.c	Fri May 14 00:44:13 2021
@@ -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);
 	}
 }

Index: src/sys/arch/macppc/include/types.h
diff -u src/sys/arch/macppc/include/types.h:1.14 src/sys/arch/macppc/include/types.h:1.14.70.1
--- src/sys/arch/macppc/include/types.h:1.14	Sun Jul 17 23:23:53 2011
+++ src/sys/arch/macppc/include/types.h	Fri May 14 00:44:13 2021
@@ -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

Index: src/sys/dev/ofw/ofw_i2c_subr.c
diff -u src/sys/dev/ofw/ofw_i2c_subr.c:1.1.6.2 src/sys/dev/ofw/ofw_i2c_subr.c:1.1.6.3
--- src/sys/dev/ofw/ofw_i2c_subr.c:1.1.6.2	Sat May  8 15:51:30 2021
+++ src/sys/dev/ofw/ofw_i2c_subr.c	Fri May 14 00:44:13 2021
@@ -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;
 		}
 
@@ -146,3 +151,4 @@ of_i2c_enumerate_devices_ext(device_t de
 
 	return 0;
 }
+OF_DEVICE_CALL_REGISTER("i2c-enumerate-devices", of_i2c_enumerate_devices);

Index: src/sys/dev/ofw/openfirm.h
diff -u src/sys/dev/ofw/openfirm.h:1.47.2.1 src/sys/dev/ofw/openfirm.h:1.47.2.2
--- src/sys/dev/ofw/openfirm.h:1.47.2.1	Sun Apr 25 22:16:05 2021
+++ src/sys/dev/ofw/openfirm.h	Fri May 14 00:44:13 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: openfirm.h,v 1.47.2.1 2021/04/25 22:16:05 thorpej Exp $	*/
+/*	$NetBSD: openfirm.h,v 1.47.2.2 2021/05/14 00:44:13 thorpej Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -129,8 +129,6 @@ device_t of_device_from_phandle(int);
 int	*of_network_decode_media(int, int *, int *);
 char	*of_get_mode_string(char *, int);
 
-int	of_i2c_enumerate_devices_ext(device_t, devhandle_t, void *,
-	    bool (*)(int, uint32_t *));
 void	of_enter_spi_devs(prop_dictionary_t, int, size_t);
 #endif /* _KERNEL */
 

Reply via email to