]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
fdtbus
authorVladimir Serbinenko <phcoder@gmail.com>
Sat, 20 Feb 2016 13:30:43 +0000 (14:30 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sat, 20 Feb 2016 13:30:43 +0000 (14:30 +0100)
grub-core/bus/fdt.c [new file with mode: 0644]
include/grub/fdtbus.h [new file with mode: 0644]

diff --git a/grub-core/bus/fdt.c b/grub-core/bus/fdt.c
new file mode 100644 (file)
index 0000000..293d817
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2016  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/fdtbus.h>
+#include <grub/fdt.h>
+#include <grub/term.h>
+
+static const void *dtb;
+
+struct grub_fdtbus_device
+{
+  struct grub_fdtbus_device *next;
+  int node;
+  struct grub_fdtbus_driver *driver;
+};
+
+struct grub_fdtbus_device *devs;
+struct grub_fdtbus_driver *drivers;
+
+static int
+is_compatible (struct grub_fdtbus_driver *driver,
+              int node)
+{
+  const char *compatible = grub_fdt_get_prop (dtb, node, "compatible",
+                                             0);
+  return grub_strcmp (driver->compatible, compatible) == 0;
+}
+
+void
+grub_fdtbus_scan (int parent)
+{
+  int node;
+  for (node = grub_fdt_first_node (dtb, parent); node >= 0;
+       node = grub_fdt_next_node (dtb, node))
+    {
+      struct grub_fdtbus_device *dev;
+      struct grub_fdtbus_driver *driver;
+      dev = grub_zalloc (sizeof (*dev));
+      if (!dev)
+       {
+         grub_print_error ();
+         return;
+       }
+      dev->node = node;
+      dev->next = devs;
+      devs = dev;
+      FOR_LIST_ELEMENTS(driver, drivers)
+       if (is_compatible (driver, node))
+         {
+           if (driver->attach(dtb, dev->node) == GRUB_ERR_NONE)
+             {
+               dev->driver = driver;
+               break;
+             }
+           grub_print_error ();
+         }
+      grub_printf ("C: %s; %s\n", grub_fdt_get_nodename (dtb, node), compatible);
+    }
+}
+
+void
+grub_fdtbus_register (struct grub_fdtbus_driver *driver)
+{
+  struct grub_fdtbus_device *dev;
+  grub_list_push (GRUB_AS_LIST_P (&drivers),
+                 GRUB_AS_LIST (driver));
+  FOR_LIST_ELEMENTS(dev, devs)
+    if (is_compatible (driver, node))
+      {
+       if (driver->attach(dtb, dev->node) == GRUB_ERR_NONE)
+         {
+           dev->driver = driver;
+           break;
+         }
+       grub_print_error ();
+      }
+}
+
+void
+grub_fdtbus_unregister (struct grub_fdtbus_driver *driver)
+{
+  grub_list_remove (GRUB_AS_LIST (driver));
+  struct grub_fdtbus_device *dev;
+  grub_list_push (GRUB_AS_LIST_P (&drivers),
+                 GRUB_AS_LIST (driver));
+  FOR_LIST_ELEMENTS(dev, devs)
+    if (dev->driver == driver)
+      {
+       if (driver->detach)
+         driver->detach(dtb, dev->node);
+       dev->driver = 0;
+      }
+}
+
+void
+grub_fdtbus_init (const void *dtb_in, grub_size_t size)
+{
+  if (!dtb_in || grub_fdt_check_header (dtb_in, size) < 0)
+    return;
+  dtb = dtb_in;
+  grub_fdtbus_scan (0);
+}
diff --git a/include/grub/fdtbus.h b/include/grub/fdtbus.h
new file mode 100644 (file)
index 0000000..8d80802
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2016  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FDTBUS_HEADER
+#define GRUB_FDTBUS_HEADER     1
+
+#include <grub/fdt.h>
+#include <grub/err.h>
+
+struct grub_fdtbus_driver
+{
+  struct grub_fdtbus_driver *next;
+  struct grub_fdtbus_driver **prev;
+
+  const char *compatible;
+
+  grub_err_t (*attach) (const void *fdt, unsigned int nodeoffset);
+  void (*detach) (const void *fdt, unsigned int nodeoffset);
+};
+
+void
+grub_fdtbus_register (struct grub_fdtbus_driver *driver);
+
+void
+grub_fdtbus_unregister (struct grub_fdtbus_driver *driver);
+
+/* Must be called before any register(). */
+/* dtb is assumed to be unfreeable and must remain
+   valid for lifetime of GRUB.
+ */
+void
+grub_fdtbus_init (const void *dtb, grub_size_t size);
+
+void
+grub_fdtbus_scan (int nodeoffset);
+
+#endif