I’m developing a device driver in a socfpga-linux provided by SoC EDS 15.1.1.60 for a custom FPGA based PCIe Root Complex design on Altera Arria 10 board. I’m taking pcie-altera.c for reference. When my driver parses the device tree for the “ranges” property, it fails. Let me give out the 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 code checks the device node flags, and decides whether the device node (in device tree) is prefetchable or not:
resource_list_for_each_entry(win, &pcie->resources) {
struct resource *parent, *res = win->res;
switch (resource_type(res)) {
case IORESOURCE_MEM:
parent = &iomem_resource;
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
break;
default:
continue;
}
err = devm_request_resource(dev, parent, res);
if (err)
goto out_release_res;
}
if (!res_valid) {
dev_err(dev, "non-prefetchable memory resource required\n");
err = -EINVAL;
goto out_release_res;
}
In my case, the device node flag seems to be IORESOURCE_BUS, so it falls into the “default” case of switch. Since the res_valid variable is initialized to zero in the beginning, my code falls into “if(!res-valid)” block and exits with error.
My DTS file is similar to altera’s/rocketboard’s pcie DTS file. I’ve given below a part of my DTS 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>;
}; //end unknown@0x000000000 (test_subsys_pcie)
Part of 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>,
<0xff210000 0x00004000>;
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 0x00000000 0x10000000>;
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_0_pcie_a10_hip_avmm 1>,
<0 0 0 2 &pcie_0_pcie_a10_hip_avmm 2>,
<0 0 0 3 &pcie_0_pcie_a10_hip_avmm 3>,
<0 0 0 4 &pcie_0_pcie_a10_hip_avmm 4>;
}; //end pcie@0x010000000 (pcie_0_pcie_a10_hip_avmm)
Both in my DTS file and rocketboard’s DTS file, the flags of the device node have NOT been mentioned. Since the rocketboard’s pcie-altera.c file has ONLY the “case IORESOURCE_MEM” in switch…, it is obvious that their device node seems to be of IORESOURCE_MEM.
I’ve 4 questions here.
-
How does the rocketboard’s device node is taken to be of IORESOURCE_MEM type in spite of their DTS file not mentioning the device node flag anywhere?
-
How does my device node is taken to be of IORESOURCE_BUS type, inspite of me following the same format as rocketboard in DTS as well as code?
-
Is there actually any way to specify the device node flags in DTS file?
-
When the kernel parses the DTS file, how does it determine the flags of a particular device node?
Please help me out.