svn commit: r367224 - in stable/12/sys/dev: extres/syscon fdt
Michal Meloun
mmel at FreeBSD.org
Sat Oct 31 17:09:26 UTC 2020
Author: mmel
Date: Sat Oct 31 17:09:25 2020
New Revision: 367224
URL: https://svnweb.freebsd.org/changeset/base/367224
Log:
MFC r366156:
Correctly handle nodes compatible with "syscon", "simple-bus". Syscon can
also have child nodes that share a registration file with it. To do this
correctly, follow these steps: - subclass syscon from simplebus and expose it
if the node is also
"simple-bus" compatible.
- block simplebus probe for this compatible string, so it's priority
(bus pass) doesn't colide with syscon driver.
Modified:
stable/12/sys/dev/extres/syscon/syscon_generic.c
stable/12/sys/dev/extres/syscon/syscon_generic.h
stable/12/sys/dev/fdt/simplebus.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/dev/extres/syscon/syscon_generic.c
==============================================================================
--- stable/12/sys/dev/extres/syscon/syscon_generic.c Sat Oct 31 17:07:43 2020 (r367223)
+++ stable/12/sys/dev/extres/syscon/syscon_generic.c Sat Oct 31 17:09:25 2020 (r367224)
@@ -59,7 +59,7 @@ static int syscon_generic_write_4(struct syscon *sysco
uint32_t val);
static int syscon_generic_modify_4(struct syscon *syscon, bus_size_t offset,
uint32_t clear_bits, uint32_t set_bits);
-
+static int syscon_generic_detach(device_t dev);
/*
* Generic syscon driver (FDT)
*/
@@ -148,7 +148,7 @@ static int
syscon_generic_attach(device_t dev)
{
struct syscon_generic_softc *sc;
- int rid;
+ int rid, rv;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -166,9 +166,20 @@ syscon_generic_attach(device_t dev)
ofw_bus_get_node(dev));
if (sc->syscon == NULL) {
device_printf(dev, "Failed to create/register syscon\n");
+ syscon_generic_detach(dev);
return (ENXIO);
}
- return (0);
+ if (ofw_bus_is_compatible(dev, "simple-bus")) {
+ rv = simplebus_attach_impl(sc->dev);
+ if (rv != 0) {
+ device_printf(dev, "Failed to create simplebus\n");
+ syscon_generic_detach(dev);
+ return (ENXIO);
+ }
+ sc->simplebus_attached = true;
+ }
+
+ return (bus_generic_attach(dev));
}
static int
@@ -181,7 +192,8 @@ syscon_generic_detach(device_t dev)
syscon_unregister(sc->syscon);
free(sc->syscon, M_SYSCON);
}
-
+ if (sc->simplebus_attached)
+ simplebus_detach(dev);
SYSCON_LOCK_DESTROY(sc);
if (sc->mem_res != NULL)
@@ -198,8 +210,8 @@ static device_method_t syscon_generic_dmethods[] = {
DEVMETHOD_END
};
-DEFINE_CLASS_0(syscon_generic, syscon_generic_driver, syscon_generic_dmethods,
- sizeof(struct syscon_generic_softc));
+DEFINE_CLASS_1(syscon_generic_dev, syscon_generic_driver, syscon_generic_dmethods,
+ sizeof(struct syscon_generic_softc), simplebus_driver);
static devclass_t syscon_generic_devclass;
EARLY_DRIVER_MODULE(syscon_generic, simplebus, syscon_generic_driver,
Modified: stable/12/sys/dev/extres/syscon/syscon_generic.h
==============================================================================
--- stable/12/sys/dev/extres/syscon/syscon_generic.h Sat Oct 31 17:07:43 2020 (r367223)
+++ stable/12/sys/dev/extres/syscon/syscon_generic.h Sat Oct 31 17:09:25 2020 (r367224)
@@ -29,11 +29,15 @@
#ifndef DEV_SYSCON_GENERIC_H
#define DEV_SYSCON_GENERIC_H
+#include <dev/fdt/simplebus.h>
+
struct syscon_generic_softc {
+ struct simplebus_softc simplebus;
device_t dev;
struct syscon *syscon;
struct resource *mem_res;
struct mtx mtx;
+ bool simplebus_attached;
};
DECLARE_CLASS(syscon_generic_driver);
Modified: stable/12/sys/dev/fdt/simplebus.c
==============================================================================
--- stable/12/sys/dev/fdt/simplebus.c Sat Oct 31 17:07:43 2020 (r367223)
+++ stable/12/sys/dev/fdt/simplebus.c Sat Oct 31 17:09:25 2020 (r367224)
@@ -116,6 +116,16 @@ simplebus_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
+ /*
+ * XXX We should attach only to pure' compatible = "simple-bus"',
+ * without any other compatible string.
+ * For now, filter only know cases:
+ * "syscon", "simple-bus"; is handled by fdt/syscon driver
+ * "simple-mfd", "simple-bus"; is handled by fdt/simple-mfd driver
+ */
+ if (ofw_bus_is_compatible(dev, "syscon") ||
+ ofw_bus_is_compatible(dev, "simple-mfd"))
+ return (ENXIO);
/*
* FDT data puts a "simple-bus" compatible string on many things that
More information about the svn-src-stable-12
mailing list