#include #include static int parent_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct platform_device *middle; dev_info(dev, "probe\n"); middle = platform_device_register_data(dev, "middle", PLATFORM_DEVID_AUTO, NULL, 0); if (IS_ERR(middle)) return dev_err_probe(dev, PTR_ERR(middle), "failed to create middle\n"); return 0; } static int middle_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct platform_device *child; struct device_link *link; dev_info(dev, "probe\n"); child = platform_device_register_data(dev, "child", PLATFORM_DEVID_AUTO, NULL, 0); if (IS_ERR(child)) return dev_err_probe(dev, PTR_ERR(child), "failed to create child\n"); dev_info(dev, "device_link_add\n"); /* * Note how the device link is created between the parent device and the * child device. This is equivalent to what happens in the phy-core * because ci_hdrc calls phy_get(dev->parent, "usb-phy"); */ link = device_link_add(dev->parent, &child->dev, DL_FLAG_STATELESS); if (link) dev_err(dev, "Creating circular device link should have failed!\n"); else dev_info(dev, "Creating device link failed (as it should)\n"); return 0; } static int child_probe(struct platform_device *pdev) { dev_info(&pdev->dev, "probe\n"); return 0; } static struct platform_driver parent_driver = { .probe = parent_probe, .driver = { .name = "parent", }, }; static struct platform_driver middle_driver = { .probe = middle_probe, .driver = { .name = "middle", }, }; static struct platform_driver child_driver = { .probe = child_probe, .driver = { .name = "child", }, }; static int __init circdl_init(void) { platform_driver_register(&parent_driver); platform_driver_register(&middle_driver); platform_driver_register(&child_driver); platform_device_register_simple("parent", PLATFORM_DEVID_AUTO, NULL, 0); return 0; } module_init(circdl_init) MODULE_LICENSE("GPL v2");