Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Driver: VMBus: Add Devicetree support

Update the driver to support Devicetree boot as well along with ACPI.
At present the Devicetree parsing only provides the mmio region info
and is not the exact copy of ACPI parsing. This is sufficient to cater
all the current Devicetree usecases for VMBus.

Currently Devicetree is supported only for x86 systems.

Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/1679298460-11855-6-git-send-email-ssengar@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>

authored by

Saurabh Sengar and committed by
Wei Liu
f83705a5 61f7a325

+65 -6
+3 -2
drivers/hv/Kconfig
··· 4 4 5 5 config HYPERV 6 6 tristate "Microsoft Hyper-V client drivers" 7 - depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \ 8 - || (ARM64 && !CPU_BIG_ENDIAN)) 7 + depends on (X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \ 8 + || (ACPI && ARM64 && !CPU_BIG_ENDIAN) 9 9 select PARAVIRT 10 10 select X86_HV_CALLBACK_VECTOR if X86 11 11 select VMAP_PFN 12 + select OF_EARLY_FLATTREE if OF 12 13 help 13 14 Select this option to run Linux as a Hyper-V client operating 14 15 system.
+62 -4
drivers/hv/vmbus_drv.c
··· 20 20 #include <linux/completion.h> 21 21 #include <linux/hyperv.h> 22 22 #include <linux/kernel_stat.h> 23 + #include <linux/of_address.h> 23 24 #include <linux/clockchips.h> 24 25 #include <linux/cpu.h> 25 26 #include <linux/sched/isolation.h> ··· 2153 2152 device_unregister(&device_obj->device); 2154 2153 } 2155 2154 2156 - 2155 + #ifdef CONFIG_ACPI 2157 2156 /* 2158 2157 * VMBUS is an acpi enumerated device. Get the information we 2159 2158 * need from DSDT. ··· 2263 2262 2264 2263 return AE_OK; 2265 2264 } 2265 + #endif 2266 2266 2267 2267 static void vmbus_mmio_remove(void) 2268 2268 { ··· 2284 2282 } 2285 2283 } 2286 2284 2287 - static void vmbus_reserve_fb(void) 2285 + static void __maybe_unused vmbus_reserve_fb(void) 2288 2286 { 2289 2287 resource_size_t start = 0, size; 2290 2288 struct pci_dev *pdev; ··· 2444 2442 } 2445 2443 EXPORT_SYMBOL_GPL(vmbus_free_mmio); 2446 2444 2445 + #ifdef CONFIG_ACPI 2447 2446 static int vmbus_acpi_add(struct platform_device *pdev) 2448 2447 { 2449 2448 acpi_status result; ··· 2497 2494 vmbus_mmio_remove(); 2498 2495 return ret_val; 2499 2496 } 2497 + #else 2498 + static int vmbus_acpi_add(struct platform_device *pdev) 2499 + { 2500 + return 0; 2501 + } 2502 + #endif 2503 + 2504 + static int vmbus_device_add(struct platform_device *pdev) 2505 + { 2506 + struct resource **cur_res = &hyperv_mmio; 2507 + struct of_range range; 2508 + struct of_range_parser parser; 2509 + struct device_node *np = pdev->dev.of_node; 2510 + int ret; 2511 + 2512 + hv_dev = &pdev->dev; 2513 + 2514 + ret = of_range_parser_init(&parser, np); 2515 + if (ret) 2516 + return ret; 2517 + 2518 + for_each_of_range(&parser, &range) { 2519 + struct resource *res; 2520 + 2521 + res = kzalloc(sizeof(*res), GFP_KERNEL); 2522 + if (!res) { 2523 + vmbus_mmio_remove(); 2524 + return -ENOMEM; 2525 + } 2526 + 2527 + res->name = "hyperv mmio"; 2528 + res->flags = range.flags; 2529 + res->start = range.cpu_addr; 2530 + res->end = range.cpu_addr + range.size; 2531 + 2532 + *cur_res = res; 2533 + cur_res = &res->sibling; 2534 + } 2535 + 2536 + return ret; 2537 + } 2500 2538 2501 2539 static int vmbus_platform_driver_probe(struct platform_device *pdev) 2502 2540 { 2503 - return vmbus_acpi_add(pdev); 2541 + if (acpi_disabled) 2542 + return vmbus_device_add(pdev); 2543 + else 2544 + return vmbus_acpi_add(pdev); 2504 2545 } 2505 2546 2506 2547 static int vmbus_platform_driver_remove(struct platform_device *pdev) ··· 2690 2643 #define vmbus_bus_resume NULL 2691 2644 #endif /* CONFIG_PM_SLEEP */ 2692 2645 2693 - static const struct acpi_device_id vmbus_acpi_device_ids[] = { 2646 + static const __maybe_unused struct of_device_id vmbus_of_match[] = { 2647 + { 2648 + .compatible = "microsoft,vmbus", 2649 + }, 2650 + { 2651 + /* sentinel */ 2652 + }, 2653 + }; 2654 + MODULE_DEVICE_TABLE(of, vmbus_of_match); 2655 + 2656 + static const __maybe_unused struct acpi_device_id vmbus_acpi_device_ids[] = { 2694 2657 {"VMBUS", 0}, 2695 2658 {"VMBus", 0}, 2696 2659 {"", 0}, ··· 2734 2677 .driver = { 2735 2678 .name = "vmbus", 2736 2679 .acpi_match_table = ACPI_PTR(vmbus_acpi_device_ids), 2680 + .of_match_table = of_match_ptr(vmbus_of_match), 2737 2681 .pm = &vmbus_bus_pm, 2738 2682 .probe_type = PROBE_FORCE_SYNCHRONOUS, 2739 2683 }