diff options
Diffstat (limited to 'drivers/of/unittest.c')
| -rw-r--r-- | drivers/of/unittest.c | 156 |
1 files changed, 142 insertions, 14 deletions
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index daf9a2dddd7e..388e9ec2cccf 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -161,6 +161,15 @@ static void __init of_unittest_find_node_by_name(void) "option alias path test, subcase #1 failed\n"); of_node_put(np); + np = of_find_node_opts_by_path("testcase-alias/phandle-tests/consumer-a:testaliasoption", + &options); + name = kasprintf(GFP_KERNEL, "%pOF", np); + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name) && + !strcmp("testaliasoption", options), + "option alias path test, subcase #2 failed\n"); + of_node_put(np); + kfree(name); + np = of_find_node_opts_by_path("testcase-alias:testaliasoption", NULL); unittest(np, "NULL option alias path test failed\n"); of_node_put(np); @@ -1213,6 +1222,44 @@ static void __init of_unittest_pci_dma_ranges(void) of_node_put(np); } +static void __init of_unittest_pci_empty_dma_ranges(void) +{ + struct device_node *np; + struct of_pci_range range; + struct of_pci_range_parser parser; + + if (!IS_ENABLED(CONFIG_PCI)) + return; + + np = of_find_node_by_path("/testcase-data/address-tests2/pcie@d1070000/pci@0,0/dev@0,0/local-bus@0"); + if (!np) { + pr_err("missing testcase data\n"); + return; + } + + if (of_pci_dma_range_parser_init(&parser, np)) { + pr_err("missing dma-ranges property\n"); + return; + } + + /* + * Get the dma-ranges from the device tree + */ + for_each_of_pci_range(&parser, &range) { + unittest(range.size == 0x10000000, + "for_each_of_pci_range wrong size on node %pOF size=%llx\n", + np, range.size); + unittest(range.cpu_addr == 0x00000000, + "for_each_of_pci_range wrong CPU addr (%llx) on node %pOF", + range.cpu_addr, np); + unittest(range.pci_addr == 0xc0000000, + "for_each_of_pci_range wrong DMA addr (%llx) on node %pOF", + range.pci_addr, np); + } + + of_node_put(np); +} + static void __init of_unittest_bus_ranges(void) { struct device_node *np; @@ -1342,6 +1389,7 @@ static void __init of_unittest_bus_3cell_ranges(void) static void __init of_unittest_reg(void) { struct device_node *np; + struct resource res; int ret; u64 addr, size; @@ -1358,6 +1406,19 @@ static void __init of_unittest_reg(void) np, addr); of_node_put(np); + + np = of_find_node_by_path("/testcase-data/platform-tests-2/node/test-device@100"); + if (!np) { + pr_err("missing testcase data\n"); + return; + } + + ret = of_address_to_resource(np, 0, &res); + unittest(ret == -EINVAL, "of_address_to_resource(%pOF) expected error on untranslatable address\n", + np); + + of_node_put(np); + } struct of_unittest_expected_res { @@ -1593,6 +1654,72 @@ static void __init of_unittest_parse_interrupts_extended(void) of_node_put(np); } +#if IS_ENABLED(CONFIG_OF_DYNAMIC) +static void __init of_unittest_irq_refcount(void) +{ + struct of_phandle_args args; + struct device_node *intc0, *int_ext0; + struct device_node *int2, *intc_intmap0; + unsigned int ref_c0, ref_c1, ref_c2; + int rc; + bool passed; + + if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) + return; + + intc0 = of_find_node_by_path("/testcase-data/interrupts/intc0"); + int_ext0 = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); + intc_intmap0 = of_find_node_by_path("/testcase-data/interrupts/intc-intmap0"); + int2 = of_find_node_by_path("/testcase-data/interrupts/interrupts2"); + if (!intc0 || !int_ext0 || !intc_intmap0 || !int2) { + pr_err("missing testcase data\n"); + goto out; + } + + /* Test refcount for API of_irq_parse_one() */ + passed = true; + ref_c0 = OF_KREF_READ(intc0); + ref_c1 = ref_c0 + 1; + memset(&args, 0, sizeof(args)); + rc = of_irq_parse_one(int_ext0, 0, &args); + ref_c2 = OF_KREF_READ(intc0); + of_node_put(args.np); + + passed &= !rc; + passed &= (args.np == intc0); + passed &= (args.args_count == 1); + passed &= (args.args[0] == 1); + passed &= (ref_c1 == ref_c2); + unittest(passed, "IRQ refcount case #1 failed, original(%u) expected(%u) got(%u)\n", + ref_c0, ref_c1, ref_c2); + + /* Test refcount for API of_irq_parse_raw() */ + passed = true; + ref_c0 = OF_KREF_READ(intc_intmap0); + ref_c1 = ref_c0 + 1; + memset(&args, 0, sizeof(args)); + rc = of_irq_parse_one(int2, 0, &args); + ref_c2 = OF_KREF_READ(intc_intmap0); + of_node_put(args.np); + + passed &= !rc; + passed &= (args.np == intc_intmap0); + passed &= (args.args_count == 1); + passed &= (args.args[0] == 2); + passed &= (ref_c1 == ref_c2); + unittest(passed, "IRQ refcount case #2 failed, original(%u) expected(%u) got(%u)\n", + ref_c0, ref_c1, ref_c2); + +out: + of_node_put(int2); + of_node_put(intc_intmap0); + of_node_put(int_ext0); + of_node_put(intc0); +} +#else +static inline void __init of_unittest_irq_refcount(void) { } +#endif + static const struct of_device_id match_node_table[] = { { .data = "A", .name = "name0", }, /* Name alone is lowest priority */ { .data = "B", .type = "type1", }, /* followed by type alone */ @@ -1729,6 +1856,8 @@ static void __init of_unittest_platform_populate(void) of_platform_populate(np, match, NULL, &test_bus->dev); for_each_child_of_node(np, child) { for_each_child_of_node(child, grandchild) { + if (!of_property_present(grandchild, "compatible")) + continue; pdev = of_find_device_by_node(grandchild); unittest(pdev, "Could not create device for node '%pOFn'\n", @@ -1902,15 +2031,16 @@ static int __init unittest_data_add(void) rc = of_resolve_phandles(unittest_data_node); if (rc) { pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc); - of_overlay_mutex_unlock(); - return -EINVAL; + rc = -EINVAL; + goto unlock; } /* attach the sub-tree to live tree */ if (!of_root) { pr_warn("%s: no live tree to attach sub-tree\n", __func__); kfree(unittest_data); - return -ENODEV; + rc = -ENODEV; + goto unlock; } EXPECT_BEGIN(KERN_INFO, @@ -1929,9 +2059,10 @@ static int __init unittest_data_add(void) EXPECT_END(KERN_INFO, "Duplicate name in testcase-data, renamed to \"duplicate-name#1\""); +unlock: of_overlay_mutex_unlock(); - return 0; + return rc; } #ifdef CONFIG_OF_OVERLAY @@ -1970,7 +2101,7 @@ static const struct of_device_id unittest_match[] = { static struct platform_driver unittest_driver = { .probe = unittest_probe, - .remove_new = unittest_remove, + .remove = unittest_remove, .driver = { .name = "unittest", .of_match_table = unittest_match, @@ -2071,7 +2202,7 @@ static const struct of_device_id unittest_gpio_id[] = { static struct platform_driver unittest_gpio_driver = { .probe = unittest_gpio_probe, - .remove_new = unittest_gpio_remove, + .remove = unittest_gpio_remove, .driver = { .name = "unittest-gpio", .of_match_table = unittest_gpio_id, @@ -2891,7 +3022,7 @@ static const struct of_device_id unittest_i2c_bus_match[] = { static struct platform_driver unittest_i2c_bus_driver = { .probe = unittest_i2c_bus_probe, - .remove_new = unittest_i2c_bus_remove, + .remove = unittest_i2c_bus_remove, .driver = { .name = "unittest-i2c-bus", .of_match_table = unittest_i2c_bus_match, @@ -3628,13 +3759,7 @@ static struct device_node *overlay_base_root; static void * __init dt_alloc_memory(u64 size, u64 align) { - void *ptr = memblock_alloc(size, align); - - if (!ptr) - panic("%s: Failed to allocate %llu bytes align=0x%llx\n", - __func__, size, align); - - return ptr; + return memblock_alloc_or_panic(size, align); } /* @@ -4175,6 +4300,7 @@ static int of_unittest_pci_node_verify(struct pci_dev *pdev, bool add) unittest(!np, "Child device tree node is not removed\n"); child_dev = device_find_any_child(&pdev->dev); unittest(!child_dev, "Child device is not removed\n"); + put_device(child_dev); } failed: @@ -4269,9 +4395,11 @@ static int __init of_unittest(void) of_unittest_changeset_prop(); of_unittest_parse_interrupts(); of_unittest_parse_interrupts_extended(); + of_unittest_irq_refcount(); of_unittest_dma_get_max_cpu_address(); of_unittest_parse_dma_ranges(); of_unittest_pci_dma_ranges(); + of_unittest_pci_empty_dma_ranges(); of_unittest_bus_ranges(); of_unittest_bus_3cell_ranges(); of_unittest_reg(); |
