Author: manu
Date: Fri Dec  9 20:35:01 2016
New Revision: 309762
URL: https://svnweb.freebsd.org/changeset/base/309762

Log:
  MFC r304795, r307366 (jmcneill):
  
  r304795:
  Add support for Allwinner multi-parent bus gates.
  
  Reviewed by:  andrew, manu
  
  r307366:
  Match "allwinner,sun8i-h3-apb0-gates-clk" compatible string.

Modified:
  stable/11/sys/arm/allwinner/clk/aw_gate.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/allwinner/clk/aw_gate.c
==============================================================================
--- stable/11/sys/arm/allwinner/clk/aw_gate.c   Fri Dec  9 20:28:28 2016        
(r309761)
+++ stable/11/sys/arm/allwinner/clk/aw_gate.c   Fri Dec  9 20:35:01 2016        
(r309762)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 #include <dev/ofw/ofw_subr.h>
+#include <dev/fdt/fdt_common.h>
 
 #include <dev/extres/clk/clk_gate.h>
 
@@ -89,11 +90,16 @@ static struct ofw_compat_data compat_dat
          (uintptr_t)"Allwinner APB0 Clock Gates" },
 
        { "allwinner,sun8i-h3-bus-gates-clk",
-         (uintptr_t)"Allwinner Bus Clock Gates"},
+         (uintptr_t)"Allwinner Bus Clock Gates" },
+       { "allwinner,sun8i-h3-apb0-gates-clk",
+         (uintptr_t)"Allwinner APB0 Clock Gates" },
 
        { "allwinner,sun9i-a80-apbs-gates-clk",
          (uintptr_t)"Allwinner APBS Clock Gates" },
 
+       { "allwinner,sunxi-multi-bus-gates-clk",
+         (uintptr_t)"Allwinner Multi Bus Clock Gates" },
+
        { NULL, 0 }
 };
 
@@ -119,6 +125,43 @@ aw_gate_create(device_t dev, bus_addr_t 
 }
 
 static int
+aw_gate_add(device_t dev, struct clkdom *clkdom, phandle_t node,
+    bus_addr_t paddr)
+{
+       const char **names;
+       uint32_t *indices;
+       clk_t clk_parent;
+       int index, nout, error;
+
+       indices = NULL;
+
+       nout = clk_parse_ofw_out_names(dev, node, &names, &indices);
+       if (nout == 0) {
+               device_printf(dev, "no clock outputs found\n");
+               return (ENOENT);
+       }
+       if (indices == NULL) {
+               device_printf(dev, "no clock-indices property\n");
+               return (ENXIO);
+       }
+
+       error = clk_get_by_ofw_index(dev, node, 0, &clk_parent);
+       if (error != 0) {
+               device_printf(dev, "cannot parse clock parent\n");
+               return (ENXIO);
+       }
+
+       for (index = 0; index < nout; index++) {
+               error = aw_gate_create(dev, paddr, clkdom,
+                   clk_get_name(clk_parent), names[index], indices[index]);
+               if (error)
+                       return (error);
+       }
+
+       return (0);
+}
+
+static int
 aw_gate_probe(device_t dev)
 {
        const char *d;
@@ -138,16 +181,11 @@ static int
 aw_gate_attach(device_t dev)
 {
        struct clkdom *clkdom;
-       const char **names;
-       int index, nout, error;
-       uint32_t *indices;
-       clk_t clk_parent;
        bus_addr_t paddr;
        bus_size_t psize;
-       phandle_t node;
+       phandle_t node, child;
 
        node = ofw_bus_get_node(dev);
-       indices = NULL;
 
        if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
                device_printf(dev, "cannot parse 'reg' property\n");
@@ -156,44 +194,21 @@ aw_gate_attach(device_t dev)
 
        clkdom = clkdom_create(dev);
 
-       nout = clk_parse_ofw_out_names(dev, node, &names, &indices);
-       if (nout == 0) {
-               device_printf(dev, "no clock outputs found\n");
-               error = ENOENT;
-               goto fail;
-       }
-       if (indices == NULL) {
-               device_printf(dev, "no clock-indices property\n");
-               error = ENXIO;
-               goto fail;
-       }
-
-       error = clk_get_by_ofw_index(dev, 0, 0, &clk_parent);
-       if (error != 0) {
-               device_printf(dev, "cannot parse clock parent\n");
-               return (ENXIO);
-       }
-
-       for (index = 0; index < nout; index++) {
-               error = aw_gate_create(dev, paddr, clkdom,
-                   clk_get_name(clk_parent), names[index], indices[index]);
-               if (error)
-                       goto fail;
-       }
+       if (ofw_bus_is_compatible(dev, "allwinner,sunxi-multi-bus-gates-clk")) {
+               for (child = OF_child(node); child > 0; child = OF_peer(child))
+                       aw_gate_add(dev, clkdom, child, paddr);
+       } else
+               aw_gate_add(dev, clkdom, node, paddr);
 
        if (clkdom_finit(clkdom) != 0) {
                device_printf(dev, "cannot finalize clkdom initialization\n");
-               error = ENXIO;
-               goto fail;
+               return (ENXIO);
        }
 
        if (bootverbose)
                clkdom_dump(clkdom);
 
        return (0);
-
-fail:
-       return (error);
 }
 
 static device_method_t aw_gate_methods[] = {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to