Page MenuHomeFreeBSD

D26402.1794744078.diff
No OneTemporary

Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None

D26402.1794744078.diff

Index: sys/dev/extres/syscon/syscon_generic.h
===================================================================
--- sys/dev/extres/syscon/syscon_generic.h
+++ sys/dev/extres/syscon/syscon_generic.h
@@ -30,6 +30,7 @@
#define DEV_SYSCON_GENERIC_H
struct syscon_generic_softc {
+ struct simplebus_softc sc_simplebus;
device_t dev;
struct syscon *syscon;
struct resource *mem_res;
Index: sys/dev/extres/syscon/syscon_generic.c
===================================================================
--- sys/dev/extres/syscon/syscon_generic.c
+++ sys/dev/extres/syscon/syscon_generic.c
@@ -46,12 +46,15 @@
#include <machine/bus.h>
+#include <dev/fdt/simplebus.h>
+
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "syscon_if.h"
#include "syscon.h"
#include "syscon_generic.h"
+#include "clkdev_if.h"
MALLOC_DECLARE(M_SYSCON);
@@ -77,14 +80,14 @@
#define SYSCON_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED);
#define SYSCON_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_NOTOWNED);
-static syscon_method_t syscon_generic_methods[] = {
+static syscon_method_t syscon_generic_syscon_methods[] = {
SYSCONMETHOD(syscon_read_4, syscon_generic_read_4),
SYSCONMETHOD(syscon_write_4, syscon_generic_write_4),
SYSCONMETHOD(syscon_modify_4, syscon_generic_modify_4),
SYSCONMETHOD_END
};
-DEFINE_CLASS_1(syscon_generic, syscon_generic_class, syscon_generic_methods,
+DEFINE_CLASS_1(syscon_generic_syscon, syscon_generic_syscon_class, syscon_generic_syscon_methods,
0, syscon_class);
static uint32_t
@@ -145,6 +148,8 @@
if (!bootverbose)
device_quiet(dev);
+ if (ofw_bus_is_compatible(dev, "simple-bus"))
+ return (BUS_PROBE_DEFAULT);
return (BUS_PROBE_GENERIC);
}
@@ -153,6 +158,8 @@
{
struct syscon_generic_softc *sc;
int rid;
+ phandle_t node, child;
+ device_t cdev;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -166,12 +173,24 @@
}
SYSCON_LOCK_INIT(sc);
- sc->syscon = syscon_create_ofw_node(dev, &syscon_generic_class,
- ofw_bus_get_node(dev));
+ node = ofw_bus_get_node(sc->dev);
+ sc->syscon = syscon_create_ofw_node(dev, &syscon_generic_syscon_class,
+ node);
if (sc->syscon == NULL) {
device_printf(dev, "Failed to create/register syscon\n");
return (ENXIO);
}
+
+ if (ofw_bus_is_compatible(dev, "simple-bus")) {
+ simplebus_init(sc->dev, node);
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ cdev = simplebus_add_device(sc->dev, child, 0, NULL, -1, NULL);
+ if (cdev != NULL)
+ device_probe_and_attach(cdev);
+ }
+ }
+
return (0);
}
@@ -186,6 +205,10 @@
free(sc->syscon, M_SYSCON);
}
+ /* Memory allocated in simplebus_init */
+ if (sc->sc_simplebus.ranges != NULL)
+ free(sc->sc_simplebus.ranges, M_DEVBUF);
+
SYSCON_LOCK_DESTROY(sc);
if (sc->mem_res != NULL)
@@ -193,19 +216,83 @@
return (0);
}
+/* clkdev interface */
+static int
+syscon_generic_clk_write_4(device_t dev, bus_addr_t offset, uint32_t val)
+{
+ struct syscon_generic_softc *sc;
+
+ sc = device_get_softc(dev);
+ bus_write_4(sc->mem_res, offset, val);
+ return (0);
+}
+
+static int
+syscon_generic_clk_read_4(device_t dev, bus_addr_t offset, uint32_t *val)
+{
+ struct syscon_generic_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ *val = bus_read_4(sc->mem_res, offset);
+ return (0);
+}
+
+static int
+syscon_generic_clk_modify_4(device_t dev, bus_addr_t offset, uint32_t clear_bits, uint32_t set_bits)
+{
+ struct syscon_generic_softc *sc;
+ uint32_t val;
+
+ sc = device_get_softc(dev);
+
+ val = bus_read_4(sc->mem_res, offset);
+ val &= ~clear_bits;
+ val |= set_bits;
+ bus_write_4(sc->mem_res, offset, val);
+
+ return (0);
+}
+
+static void
+syscon_generic_clk_device_lock(device_t dev)
+{
+ struct syscon_generic_softc *sc;
+
+ sc = device_get_softc(dev);
+ SYSCON_LOCK(sc);
+}
+
+static void
+syscon_generic_clk_device_unlock(device_t dev)
+{
+ struct syscon_generic_softc *sc;
+
+ sc = device_get_softc(dev);
+ SYSCON_UNLOCK(sc);
+}
+
static device_method_t syscon_generic_dmethods[] = {
/* Device interface */
DEVMETHOD(device_probe, syscon_generic_probe),
DEVMETHOD(device_attach, syscon_generic_attach),
DEVMETHOD(device_detach, syscon_generic_detach),
+ /* clkdev interface */
+ DEVMETHOD(clkdev_write_4, syscon_generic_clk_write_4),
+ DEVMETHOD(clkdev_read_4, syscon_generic_clk_read_4),
+ DEVMETHOD(clkdev_modify_4, syscon_generic_clk_modify_4),
+ DEVMETHOD(clkdev_device_lock, syscon_generic_clk_device_lock),
+ DEVMETHOD(clkdev_device_unlock, syscon_generic_clk_device_unlock),
+
DEVMETHOD_END
};
-DEFINE_CLASS_0(syscon_generic, syscon_generic_driver, syscon_generic_dmethods,
- sizeof(struct syscon_generic_softc));
+DEFINE_CLASS_1(syscon_generic, 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,
- syscon_generic_devclass, 0, 0, BUS_PASS_DEFAULT);
+ syscon_generic_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
MODULE_VERSION(syscon_generic, 1);
+

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 15, 12:01 PM (20 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41742510
Default Alt Text
D26402.1794744078.diff (5 KB)

Event Timeline