+
+int __init board_staging_gic_setup_xlate(const char *gic_match,
+ unsigned int base)
+{
+ WARN_ON(irqc_node);
+
+ irqc_node = of_find_compatible_node(NULL, NULL, gic_match);
+
+ WARN_ON(!irqc_node);
+ if (!irqc_node)
+ return -ENOENT;
+
+ irqc_base = base;
+ return 0;
+}
+
+static void __init gic_fixup_resource(struct resource *res)
+{
+ struct of_phandle_args irq_data;
+ unsigned int hwirq = res->start;
+ unsigned int virq;
+
+ if (resource_type(res) != IORESOURCE_IRQ || !irqc_node)
+ return;
+
+ irq_data.np = irqc_node;
+ irq_data.args_count = 3;
+ irq_data.args[0] = 0;
+ irq_data.args[1] = hwirq - irqc_base;
+ switch (res->flags &
+ (IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL)) {
+ case IORESOURCE_IRQ_LOWEDGE:
+ irq_data.args[2] = IRQ_TYPE_EDGE_FALLING;
+ break;
+ case IORESOURCE_IRQ_HIGHEDGE:
+ irq_data.args[2] = IRQ_TYPE_EDGE_RISING;
+ break;
+ case IORESOURCE_IRQ_LOWLEVEL:
+ irq_data.args[2] = IRQ_TYPE_LEVEL_LOW;
+ break;
+ case IORESOURCE_IRQ_HIGHLEVEL:
+ default:
+ irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH;
+ break;
+ }
+
+ virq = irq_create_of_mapping(&irq_data);
+ if (WARN_ON(!virq))
+ return;
+
+ pr_debug("hwirq %u -> virq %u\n", hwirq, virq);
+ res->start = virq;
+}
+
+void __init board_staging_gic_fixup_resources(struct resource *res,
+ unsigned int nres)
+{
+ unsigned int i;
+
+ for (i = 0; i < nres; i++)
+ gic_fixup_resource(&res[i]);
+}
+
+int __init board_staging_register_clock(const struct board_staging_clk *bsc)
+{
+ int error;
+
+ pr_debug("Aliasing clock %s for con_id %s dev_id %s\n", bsc->clk,
+ bsc->con_id, bsc->dev_id);
+ error = clk_add_alias(bsc->con_id, bsc->dev_id, bsc->clk, NULL);
+ if (error)
+ pr_err("Failed to alias clock %s (%d)\n", bsc->clk, error);
+
+ return error;
+}
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+static int board_staging_add_dev_domain(struct platform_device *pdev,
+ const char *domain)
+{
+ struct of_phandle_args pd_args;
+ struct generic_pm_domain *pd;
+ struct device_node *np;
+
+ np = of_find_node_by_path(domain);
+ if (!np) {
+ pr_err("Cannot find domain node %s\n", domain);
+ return -ENOENT;
+ }
+
+ pd_args.np = np;
+ pd_args.args_count = 0;
+ pd = of_genpd_get_from_provider(&pd_args);
+ if (IS_ERR(pd)) {
+ pr_err("Cannot find genpd %s (%ld)\n", domain, PTR_ERR(pd));
+ return PTR_ERR(pd);
+
+ }
+ pr_debug("Found genpd %s for device %s\n", pd->name, pdev->name);
+
+ return pm_genpd_add_device(pd, &pdev->dev);
+}
+#else
+static inline int board_staging_add_dev_domain(struct platform_device *pdev,
+ const char *domain)
+{
+ return 0;
+}
+#endif
+
+int __init board_staging_register_device(const struct board_staging_dev *dev)
+{
+ struct platform_device *pdev = dev->pdev;
+ unsigned int i;
+ int error;
+
+ pr_debug("Trying to register device %s\n", pdev->name);
+ if (board_staging_dt_node_available(pdev->resource,
+ pdev->num_resources)) {
+ pr_warn("Skipping %s, already in DT\n", pdev->name);
+ return -EEXIST;
+ }
+
+ board_staging_gic_fixup_resources(pdev->resource, pdev->num_resources);
+
+ for (i = 0; i < dev->nclocks; i++)
+ board_staging_register_clock(&dev->clocks[i]);
+
+ if (dev->domain)
+ board_staging_add_dev_domain(pdev, dev->domain);
+
+ error = platform_device_register(pdev);
+ if (error) {
+ pr_err("Failed to register device %s (%d)\n", pdev->name,
+ error);
+ return error;
+ }
+
+ return error;
+}
+
+void __init board_staging_register_devices(const struct board_staging_dev *devs,
+ unsigned int ndevs)
+{
+ unsigned int i;
+
+ for (i = 0; i < ndevs; i++)
+ board_staging_register_device(&devs[i]);
+}