Altera_Forum
Honored Contributor
9 years agoHow does the kernel determine the resource flags of a device node in a device tree?
I'm developing a devicedriver in a socfpga-linux provided by SoC EDS 15.1.1.60 for a customFPGA based PCIe Root Complex design on Altera Arria 10 board. I'mtaking pcie-altera.c for reference. When my driver parses the devicetree for the "ranges" property, it fails. Let me give outthe sequence:
drivers/pci/host/pcie-altera.c: altera_pcie_probe() ->altera_pcie_parse_request_of_pci_ranges(). In altera_pcie_parse_request_of_pci_ranges(), the foll. piece of codedecides checks the device node flags, and decides whether the devicenode (in device tree) is prefetchable or not: resource_list_for_each_entry(win, &pcie->resources) { structresource *parent, *res = win->res; switch(resource_type(res)) { caseIORESOURCE_MEM: parent = &iomem_resource; res_valid |= !(res->flags & IORESOURCE_PREFETCH); break; default: continue; } err =devm_request_resource(dev, parent, res); if (err) gotoout_release_res; } if (!res_valid) { dev_err(dev,"non-prefetchable memory resource required\n"); err =-EINVAL; gotoout_release_res; } In my case, the device nodeflag happens to be IORESOURCE_BUS, so it falls into the "default"case of switch. Since the res_valid variable is initialized to zeroin the beginning, my code falls into "if(!res-valid)"block and exits with error. My DTS file is similar toaltera's/rocketboard's pcie DTS file. I've given below a part of myDTS file for reference: sopc0: sopc@0 { device_type= "soc"; ranges; # address-cells = <1>; # size-cells= <1>; compatible ="ALTR,avalon", "simple-bus"; bus-frequency = <0>; test_subsys_pcie: pcie@0x000000000 { compatible = "altera, my-pcie"; reg= <0xc0000000 0x00001000>, <0xc0001000 0x00010000>, <0xff200000 0x00010000>; reg-names = "axi_slave_1", "axi_slave_2","axi_slave_3"; interrupt-parent = <&HPS_arm_gic_0>; interrupts = <0 19 4>; clocks = <&test_subsys_clk_125M>; device_type = "pci"; bus-range = <0x00000000 0x000000ff>; # address-cells = <1>; # size-cells = <1>; ranges = <0x00000000 0xc0000000 0x00001000>; }; //endunknown@0x000000000 (test_subsys_pcie) Partof Rocketboard's DTS file is given below for reference: sopc0:sopc@0 { device_type= "soc"; ranges; # address-cells= <1>; # size-cells= <1>; compatible= "ALTR,avalon", "simple-bus"; bus-frequency= <0>; pcie_0_pcie_a10_hip_avmm:pcie@0x010000000 { compatible= "altr,pcie-root-port-15.1", "altr,pcie-root-port-1.0"; reg= <0xd0000000 0x10000000>, <0xff2100000x00004000>; reg-names= "Txs", "Cra"; interrupt-parent= <&arria10_hps_0_arm_gic_0>; interrupts= <0 24 4>; interrupt-controller; # interrupt-cells= <1>; device_type= "pci"; /* embeddedsw.dts.params.device_type type STRING*/ msi-parent= <&pcie_0_msi_to_gic_gen_0>; bus-range= <0x00000000 0x000000ff>; # address-cells= <3>; # size-cells= <2>; ranges= <0x82000000 0x00000000 0x00000000 0xd0000000 0x000000000x10000000>; interrupt-map-mask= <0 0 0 7>; interrupt-map= <0 0 0 1 &pcie_0_pcie_a10_hip_avmm 1>, <00 0 2 &pcie_0_pcie_a10_hip_avmm 2>, <00 0 3 &pcie_0_pcie_a10_hip_avmm 3>, <00 0 4 &pcie_0_pcie_a10_hip_avmm 4>; };//end pcie@0x010000000 (pcie_0_pcie_a10_hip_avmm) Both in my DTS file androcketboard's DTS file, the flags of the device node have NOT beenmentioned. Since the rocketboard's pcie-altera.c file has ONLY the"case IORESOURCE_MEM" in switch..., it is obvious thattheir device node seems to be of IORESOURCE_MEM. I've 4 questions here. 1) How does therocketboard's device node is taken to be of IORESOURCE_MEM type inspite of their DTS file not mentioning the device node flag anywhere? 2) How does my device nodeis taken to be of IORESOURCE_BUS type, inspite of me following thesame format as rocketboard in DTS as well as code? 3) Is there actually any wayto specify the device node flags in DTS file? 4) When the kernel parsesthe DTS file, how does it determine the flags of a particular devicenode? Please help me out.