|
@@ -2614,3 +2614,118 @@ static int __init _register(struct omap_hwmod *oh)
|
|
|
* @sl: pointer to a struct omap_hwmod_link * for the slave link
|
|
|
*
|
|
|
* Return pointers to two struct omap_hwmod_link records, via the
|
|
|
+ * addresses pointed to by @ml and @sl. Will first attempt to return
|
|
|
+ * memory allocated as part of a large initial block, but if that has
|
|
|
+ * been exhausted, will allocate memory itself. Since ideally this
|
|
|
+ * second allocation path will never occur, the number of these
|
|
|
+ * 'supplemental' allocations will be logged when debugging is
|
|
|
+ * enabled. Returns 0.
|
|
|
+ */
|
|
|
+static int __init _alloc_links(struct omap_hwmod_link **ml,
|
|
|
+ struct omap_hwmod_link **sl)
|
|
|
+{
|
|
|
+ unsigned int sz;
|
|
|
+
|
|
|
+ if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) {
|
|
|
+ *ml = &linkspace[free_ls++];
|
|
|
+ *sl = &linkspace[free_ls++];
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF;
|
|
|
+
|
|
|
+ *sl = NULL;
|
|
|
+ *ml = alloc_bootmem(sz);
|
|
|
+
|
|
|
+ memset(*ml, 0, sz);
|
|
|
+
|
|
|
+ *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link);
|
|
|
+
|
|
|
+ ls_supp++;
|
|
|
+ pr_debug("omap_hwmod: supplemental link allocations needed: %d\n",
|
|
|
+ ls_supp * LINKS_PER_OCP_IF);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * _add_link - add an interconnect between two IP blocks
|
|
|
+ * @oi: pointer to a struct omap_hwmod_ocp_if record
|
|
|
+ *
|
|
|
+ * Add struct omap_hwmod_link records connecting the master IP block
|
|
|
+ * specified in @oi->master to @oi, and connecting the slave IP block
|
|
|
+ * specified in @oi->slave to @oi. This code is assumed to run before
|
|
|
+ * preemption or SMP has been enabled, thus avoiding the need for
|
|
|
+ * locking in this code. Changes to this assumption will require
|
|
|
+ * additional locking. Returns 0.
|
|
|
+ */
|
|
|
+static int __init _add_link(struct omap_hwmod_ocp_if *oi)
|
|
|
+{
|
|
|
+ struct omap_hwmod_link *ml, *sl;
|
|
|
+
|
|
|
+ pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name,
|
|
|
+ oi->slave->name);
|
|
|
+
|
|
|
+ _alloc_links(&ml, &sl);
|
|
|
+
|
|
|
+ ml->ocp_if = oi;
|
|
|
+ INIT_LIST_HEAD(&ml->node);
|
|
|
+ list_add(&ml->node, &oi->master->master_ports);
|
|
|
+ oi->master->masters_cnt++;
|
|
|
+
|
|
|
+ sl->ocp_if = oi;
|
|
|
+ INIT_LIST_HEAD(&sl->node);
|
|
|
+ list_add(&sl->node, &oi->slave->slave_ports);
|
|
|
+ oi->slave->slaves_cnt++;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _register_link - register a struct omap_hwmod_ocp_if
|
|
|
+ * @oi: struct omap_hwmod_ocp_if *
|
|
|
+ *
|
|
|
+ * Registers the omap_hwmod_ocp_if record @oi. Returns -EEXIST if it
|
|
|
+ * has already been registered; -EINVAL if @oi is NULL or if the
|
|
|
+ * record pointed to by @oi is missing required fields; or 0 upon
|
|
|
+ * success.
|
|
|
+ *
|
|
|
+ * XXX The data should be copied into bootmem, so the original data
|
|
|
+ * should be marked __initdata and freed after init. This would allow
|
|
|
+ * unneeded omap_hwmods to be freed on multi-OMAP configurations.
|
|
|
+ */
|
|
|
+static int __init _register_link(struct omap_hwmod_ocp_if *oi)
|
|
|
+{
|
|
|
+ if (!oi || !oi->master || !oi->slave || !oi->user)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED)
|
|
|
+ return -EEXIST;
|
|
|
+
|
|
|
+ pr_debug("omap_hwmod: registering link from %s to %s\n",
|
|
|
+ oi->master->name, oi->slave->name);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Register the connected hwmods, if they haven't been
|
|
|
+ * registered already
|
|
|
+ */
|
|
|
+ if (oi->master->_state != _HWMOD_STATE_REGISTERED)
|
|
|
+ _register(oi->master);
|
|
|
+
|
|
|
+ if (oi->slave->_state != _HWMOD_STATE_REGISTERED)
|
|
|
+ _register(oi->slave);
|
|
|
+
|
|
|
+ _add_link(oi);
|
|
|
+
|
|
|
+ oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _alloc_linkspace - allocate large block of hwmod links
|
|
|
+ * @ois: pointer to an array of struct omap_hwmod_ocp_if records to count
|
|
|
+ *
|
|
|
+ * Allocate a large block of struct omap_hwmod_link records. This
|
|
|
+ * improves boot time significantly by avoiding the need to allocate
|
|
|
+ * individual records one by one. If the number of records to
|