static int etnaviv_pdev_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct component_match *match = NULL; dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (node) { struct device_node *core_node; int i; for (i = 0; ; i++) { core_node = of_parse_phandle(node, "cores", i); if (!core_node) break; component_match_add(&pdev->dev, &match, compare_of, core_node); of_node_put(core_node); } } else if (dev->platform_data) { char **names = dev->platform_data; unsigned i; for (i = 0; names[i]; i++) component_match_add(dev, &match, compare_str, names[i]); } return component_master_add_with_match(dev, &etnaviv_master_ops, match); }
static struct component_match *exynos_drm_match_add(struct device *dev) { struct component_match *match = NULL; int i; for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) { struct exynos_drm_driver_info *info = &exynos_drm_drivers[i]; struct device *p = NULL, *d; if (!info->driver || !(info->flags & DRM_COMPONENT_DRIVER)) continue; while ((d = bus_find_device(&platform_bus_type, p, &info->driver->driver, (void *)platform_bus_type.match))) { put_device(p); if (!(info->flags & DRM_FIMC_DEVICE) || exynos_drm_check_fimc_device(d) == 0) component_match_add(dev, &match, compare_dev, d); p = d; } put_device(p); } return match ?: ERR_PTR(-ENODEV); }
static int malidp_platform_probe(struct platform_device *pdev) { struct device_node *port, *ep; struct component_match *match = NULL; if (!pdev->dev.of_node) return -ENODEV; /* there is only one output port inside each device, find it */ ep = of_graph_get_next_endpoint(pdev->dev.of_node, NULL); if (!ep) return -ENODEV; if (!of_device_is_available(ep)) { of_node_put(ep); return -ENODEV; } /* add the remote encoder port as component */ port = of_graph_get_remote_port_parent(ep); of_node_put(ep); if (!port || !of_device_is_available(port)) { of_node_put(port); return -EAGAIN; } component_match_add(&pdev->dev, &match, malidp_compare_dev, port); return component_master_add_with_match(&pdev->dev, &malidp_master_ops, match); }
static int sti_tvout_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct sti_tvout *tvout; struct resource *res; struct device_node *child_np; struct component_match *match = NULL; DRM_INFO("%s\n", __func__); if (!node) return -ENODEV; tvout = devm_kzalloc(dev, sizeof(*tvout), GFP_KERNEL); if (!tvout) return -ENOMEM; tvout->dev = dev; /* get Memory ressources */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tvout-reg"); if (!res) { DRM_ERROR("Invalid glue resource\n"); return -ENOMEM; } tvout->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!tvout->regs) return -ENOMEM; /* get reset resources */ tvout->reset = devm_reset_control_get(dev, "tvout"); /* take tvout out of reset */ if (!IS_ERR(tvout->reset)) reset_control_deassert(tvout->reset); platform_set_drvdata(pdev, tvout); of_platform_populate(node, NULL, NULL, dev); child_np = of_get_next_available_child(node, NULL); while (child_np) { component_match_add(dev, &match, compare_of, child_np); of_node_put(child_np); child_np = of_get_next_available_child(node, child_np); } component_master_add_with_match(dev, &sti_tvout_master_ops, match); return component_add(dev, &sti_tvout_ops); }
static void armada_add_endpoints(struct device *dev, struct component_match **match, struct device_node *port) { struct device_node *ep, *remote; for_each_child_of_node(port, ep) { remote = of_graph_get_remote_port_parent(ep); if (!remote || !of_device_is_available(remote)) { of_node_put(remote); continue; } else if (!of_device_is_available(remote->parent)) { dev_warn(dev, "parent device of %s is not available\n", remote->full_name); of_node_put(remote); continue; } component_match_add(dev, match, compare_of, remote); of_node_put(remote); }
static void vc4_match_add_drivers(struct device *dev, struct component_match **match, struct platform_driver *const *drivers, int count) { int i; for (i = 0; i < count; i++) { struct device_driver *drv = &drivers[i]->driver; struct device *p = NULL, *d; while ((d = bus_find_device(&platform_bus_type, p, drv, (void *)platform_bus_type.match))) { put_device(p); component_match_add(dev, match, compare_dev, d); p = d; } put_device(p); } }
int snd_hdac_i915_init(struct hdac_bus *bus) { struct component_match *match = NULL; struct device *dev = bus->dev; struct i915_audio_component *acomp; int ret; acomp = kzalloc(sizeof(*acomp), GFP_KERNEL); if (!acomp) return -ENOMEM; bus->audio_component = acomp; hdac_acomp = acomp; component_match_add(dev, &match, hdac_component_master_match, bus); ret = component_master_add_with_match(dev, &hdac_component_master_ops, match); if (ret < 0) goto out_err; /* * Atm, we don't support deferring the component binding, so make sure * i915 is loaded and that the binding successfully completes. */ request_module("i915"); if (!acomp->ops) { ret = -ENODEV; goto out_master_del; } dev_dbg(dev, "bound to i915 component master\n"); return 0; out_master_del: component_master_del(dev, &hdac_component_master_ops); out_err: kfree(acomp); bus->audio_component = NULL; dev_err(dev, "failed to add i915 component master (%d)\n", ret); return ret; }
/** * snd_hdac_acomp_init - Initialize audio component * @bus: HDA core bus * @match_master: match function for finding components * @extra_size: Extra bytes to allocate * * This function is supposed to be used only by a HD-audio controller * driver that needs the interaction with graphics driver. * * This function initializes and sets up the audio component to communicate * with graphics driver. * * Unlike snd_hdac_i915_init(), this function doesn't synchronize with the * binding with the DRM component. Each caller needs to sync via master_bind * audio_ops. * * Returns zero for success or a negative error code. */ int snd_hdac_acomp_init(struct hdac_bus *bus, const struct drm_audio_component_audio_ops *aops, int (*match_master)(struct device *, void *), size_t extra_size) { struct component_match *match = NULL; struct device *dev = bus->dev; struct drm_audio_component *acomp; int ret; if (WARN_ON(hdac_get_acomp(dev))) return -EBUSY; acomp = devres_alloc(hdac_acomp_release, sizeof(*acomp) + extra_size, GFP_KERNEL); if (!acomp) return -ENOMEM; acomp->audio_ops = aops; bus->audio_component = acomp; devres_add(dev, acomp); component_match_add(dev, &match, match_master, bus); ret = component_master_add_with_match(dev, &hdac_component_master_ops, match); if (ret < 0) goto out_err; return 0; out_err: bus->audio_component = NULL; devres_destroy(dev, hdac_acomp_release, NULL, NULL); dev_info(dev, "failed to add audio component master (%d)\n", ret); return ret; }
static int sun4i_drv_add_endpoints(struct device *dev, struct component_match **match, struct device_node *node) { struct device_node *port, *ep, *remote; int count = 0; /* * We don't support the frontend for now, so we will never * have a device bound. Just skip over it, but we still want * the rest our pipeline to be added. */ if (!sun4i_drv_node_is_frontend(node) && !of_device_is_available(node)) return 0; if (!sun4i_drv_node_is_frontend(node)) { /* Add current component */ DRM_DEBUG_DRIVER("Adding component %s\n", of_node_full_name(node)); component_match_add(dev, match, compare_of, node); count++; } /* Inputs are listed first, then outputs */ port = of_graph_get_port_by_id(node, 1); if (!port) { DRM_DEBUG_DRIVER("No output to bind\n"); return count; } for_each_available_child_of_node(port, ep) { remote = of_graph_get_remote_port_parent(ep); if (!remote) { DRM_DEBUG_DRIVER("Error retrieving the output node\n"); of_node_put(remote); continue; } /* * If the node is our TCON, the first port is used for our * panel, and will not be part of the * component framework. */ if (sun4i_drv_node_is_tcon(node)) { struct of_endpoint endpoint; if (of_graph_parse_endpoint(ep, &endpoint)) { DRM_DEBUG_DRIVER("Couldn't parse endpoint\n"); continue; } if (!endpoint.id) { DRM_DEBUG_DRIVER("Endpoint is our panel... skipping\n"); continue; } } /* Walk down our tree */ count += sun4i_drv_add_endpoints(dev, match, remote); of_node_put(remote); }