cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
bsilverman
Visitor
Visitor
159 Views
Registered: ‎03-13-2019

MTD driver issue reporting "OF: ERROR: Bad of_node_put()"

I am using the Xilinx 2019.2 Linux on a custom board similar to the ZCU102. 

When using QSPI MTD driver, I get the following error:

zynqmp-qspi ff0f0000.spi: rx bus width not found
zynqmp-qspi ff0f0000.spi: tx bus width not found
m25p80 spi0.0: mt25ql02g (262144 Kbytes)
1 fixed-partitions partitions found on MTD device spi0.0
Creating 1 MTD partitions on "spi0.0":
0x000000000000-0x000001000000 : "qspi-fsbl-uboot"
OF: ERROR: Bad of_node_put() on /amba/spi@ff0f0000/flash@0
CPU: 1 PID: 17 Comm: kworker/1:0 Not tainted 4.19.0-xilinx-v2019.2 #1
Hardware name: Atlas-II Z8ev (DT)
Workqueue: events deferred_probe_work_func
Call trace:
 dump_backtrace+0x0/0x148
 show_stack+0x14/0x20
 dump_stack+0x90/0xb4
 of_node_release+0x74/0x78
 kobject_put+0x74/0xe8
 of_node_put+0x14/0x20
 of_get_next_available_child+0x88/0xd0
 spi_register_controller+0x2a4/0x618
 zynqmp_qspi_probe+0x3f4/0x530
 platform_drv_probe+0x50/0xa0
 really_probe+0x1c8/0x280
 driver_probe_device+0x54/0xe8
 __device_attach_driver+0xb8/0xe8
 bus_for_each_drv+0x78/0xc8
 __device_attach+0xd4/0x130
 device_initial_probe+0x10/0x18
 bus_probe_device+0x90/0x98
 deferred_probe_work_func+0x6c/0xa0
 process_one_work+0x1e4/0x340
 worker_thread+0x248/0x488
 kthread+0x124/0x128
 ret_from_fork+0x10/0x18

Note: the error is potentially benign, as I am still able to access (erase, read, and write) the flash.  However, it appears to be the result of incorrect of_node_get/put() usage, which could potentially cause a fault.

The issue appears to be that the function spi_nor_scan() in drivers/mtd/spi-nor/spi-nor.c improperly uses of_get_next_parent() 3 times.  Specifically, as noted in the of_get_next_parent() header comments:

/**
 *	of_get_next_parent - Iterate to a node's parent
 *	@node:	Node to get parent of
 *
 *	This is like of_get_parent() except that it drops the
 *	refcount on the passed node, making it suitable for iterating
 *	through a node's parents.

And, a cursory look through the other uses of this function in the Linux source (31 other instances) show that it is specifically used to iterate up the parents.

As a quick fix, if of_get_next_parent() is changed to of_get_parent(), the issue is resolved.  However, that is not a full fix - the fix should include of_node_put() when the node no longer needed.  Also, it does not seem necessary to get the same parent node 3 times, as it would be cleaner and more efficient to do just one of_get_parent()/of_node_put().

What is curious is that I am getting this error, and I have not seen it reported online anywhere.  I suspect that I have something subtly different in my DT that causes the problem to appear.  In addition, this code is still in the latest Xilinx source on github, so I suspect its occurrence is rare.

Finally, here's my device tree snippet:

&qspi {
    status = "okay";
    is-dual = <0>;
    
    flash@0 {
        /* Part is: MT25QL02G */
        compatible = "jedec,spi-nor";
        #address-cells = <1>;
        #size-cells = <1>;
        reg = <0x0>;
        spi-max-frequency = <50000000>;
        partition@0x00000000 {
            label = "qspi-fsbl-uboot";
            reg = <0x0 0x1000000>;
        };
    };
};

The above was built as an addition to the default zynqmp DT in meta-xilinx, so for completeness, here's output from "dtc -I dtb -O dts" of the spi node above:

		spi@ff0f0000 {
			u-boot,dm-pre-reloc;
			compatible = "xlnx,zynqmp-qspi-1.0";
			status = "okay";
			clock-names = "ref_clk\0pclk";
			interrupts = < 0x00 0x0f 0x04 >;
			interrupt-parent = < 0x04 >;
			num-cs = < 0x01 >;
			reg = < 0x00 0xff0f0000 0x00 0x1000 0x00 0xc0000000 0x00 0x8000000 >;
			#address-cells = < 0x01 >;
			#size-cells = < 0x00 >;
			#stream-id-cells = < 0x01 >;
			iommus = < 0x0d 0x873 >;
			power-domains = < 0x0c 0x2d >;
			clocks = < 0x03 0x35 0x03 0x1f >;
			is-dual = < 0x00 >;
			spi-rx-bus-width = < 0x04 >;
			spi-tx-bus-width = < 0x04 >;
			phandle = < 0x59 >;

			flash@0 {
				compatible = "jedec,spi-nor";
				#address-cells = < 0x01 >;
				#size-cells = < 0x01 >;
				reg = < 0x00 >;
				spi-max-frequency = < 0x2faf080 >;

				partition@0x00000000 {
					label = "qspi-fsbl-uboot";
					reg = < 0x00 0x1000000 >;
				};
			};
		};

Could this issue please be referred to the Xilinx source authors/maintainers, which may include:

  • Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
  • Amit Kumar Mahapatra <amit.kumar-mahapatra@xilinx.com>
  • Tejas Prajapati Rameshchandra <tejaspra@xilinx.com>
  • Michal Simek <michal.simek@xilinx.com>

Thanks!

0 Kudos
0 Replies