I am trying to export a pin (no. 110) using the following in linux:
echo 110 > /sys/class/gpio/export
When I try to do so, I getthe error message
ash: write error: Device or resource busy
As per my knowledge the pin is not being used by any module, but I may be wrong. I had the hardware line probed and the voltage is changing, the processor seems to be driving something to the line.
The pin according to the user manual is not multiplexed and is "commonly available".
The pin according to the user manual is not multiplexed and is "commonly available".
Apparently you are referring to a SoC manual.
Such a statement will only imply that the pin does not have a dedicated application by an integrated peripheral (as shipped by the SoC manufacturer).
That statement is invalidated when the SoC is designed into a circuit and/or installed on a board.
The document that you really need to consult is the board manual or the board schematics.
That should be the accurate documentation as to how the board designer used the available GPIO pins in that specific application.
When I try to do so, I getthe error message ...
Fortunately for you, the device driver that does use that pin (that you want to use) has properly performed the GPIO reserve/request call to prevent a hijack.
This prevented that other driver from breaking and/or a device/board malfunction.
As per my knowledge the pin is not being used by any module, but I may be wrong
How did you attain this "knowledge"?
Did you scan the .dts and .dtsi files used for your board?
Did you check the source code of every device driver used by your board?
Related
We have an embedded board that has an iMX8M-Plus Processor and Linux v5.4.161. This board has one PCIe bus and that one is connected to an FPGA. When we power up the board, the FPGA is not yet configured, so it acts as if it was not on the PCIe bus.
Once the Linux is fully booted, we configure the FPGA and only after that it starts acting as a PCIe endpoint (device).
At this point, when I run lspci -> it returns nothing.
When I first execute echo "1" > /sys/bus/pci/rescan as suggested here and here and then lspci, I still get nothing.
But if I reboot the linux without reseting the FPGA, it starts being visible in the lspci list. Rebooting the linux is not an option for us. Somehow I need to tell the linux that whatever it's doing at the boot time, please do it again at runtime. But I couldn't find a solution for this so far.
According to the Texas Instrument support forum, they said if the PCIe link is not trained at the boot time, rescan command never works.
At the boot time, while linux loads a pci driver, it tries to establish a PCIe link, I can see that with an oscilloscope, PERST pin is asserted and PCIE_CLK generated for a while and then stops if it can not detect any device. But the rescan command never does that.
Also in the system there is no pcie device to executeecho 1 > $pcidevice/remove in order to make rescan functional. Or there is no device or bus to set power off and on back like echo 0 > /sys/bus/pci/slots/.../power
I also learned that there was a method in old linux times (v2.6) called adding a Fake PCIe Device which physically doesn't exist to solve this problem. For that I took the fakephp.c driver from an old linux repo and ported it to ours. After solving a couple of deprecated function problems, it is compiled for Linux Kernel v5.4. modprobe fakephp worked and driver loaded but somehow I didn't get this fake device in my device list. Here it is mentioned that the fakephp driver was removed from mainstream linux since PCI core has similar functionality, but he never mentioned how.
Short of the story is that, I am stuck here, I need my FPGA to be visible in the lspci list without restarting the linux.
I recommend configuring the FPGA in u-boot to get away from these kinds of problems. Connect up SPI pins to FPGA's config pins & run it in Slave configuration mode.
Our product is a specialized device running minimal Ubuntu. Our C++ application on the device periodically scans I2C bus to detect if any new monitor/projector/etc. has been connected. This generally works well. However, once in two to three weeks, we see a random freeze.
As it happens randomly, we cannot consistently reproduce it.
From coding perspective, I essentially scan /dev/i2c-* files, open() the file, and try to read first 128 bytes using ioctl().
I guess we do something similar to what Linux tool i2cdetect does. From the manpage on i2cdtect, it states that "read byte" is known to lock SMBus on various write-only chips. Wondering if anyone knows this could be the problem we are running into. Regards.
I'm having trouble with an industrial Linux computer I'm working with to achieve communication over an RS485 bus with multiple connected devices. What I've encountered is that the IO pins used by the RS485 USART driver are set to different levels at startup instead of going to the RS485 idle/tri-state. As a result, the other devices on the bus are blocked for more than 30 seconds while the device boots up, triggering all sorts of external problems. The course of events can be viewed in the attached image, where I've measured the output voltages with an oscilloscope during startup.
My guess is that the actual driver is not started until the voltage levels reach their tri-state levels (e.g. ~2.2V for this device). After that everything works as expected.
I've tried to find any config-files to set the default IO level of the pins at boot (thinking this may be set by the bootloader) to no avail.
Also, I've tried to apply a startup-script to run "early enough" to set DATA- high, but the device in question does not provide any interface to control these pins as regular GPIOs as far as I can tell.
Any help, tips or insights would be much appreciated!
EDIT: I am not an experienced Linux developer, so please highlight if I've left out any important details.
Some specs:
ARM920T rev 0 (v41) CPU
Proprietary distribution of Linux 2.6
Uses Busybox
Atmel USART drivers
Extract from boot log:
Linux version 2.6.28.10 (root#) (gcc version 4.1.2) #94 PREEMPT Tue Oct 29 10:22:19 CET 2013
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0003177
/...
.../
RS485 mode for port /dev/ttyS3 enabled
/...
... (I'm guessing the ~30 secs elapse here)
.../
atmel_usart.3: ttyS3 at MMIO 0xfffcc000 (irq = 9) is a ATMEL_SERIAL
atmel_serial.3: Putting the RS485 RTS pin down
/...
...
.../
Full boot log: https://drive.google.com/file/d/0B2XYl1mNCa8jNUZ5V0Nic1hkU0U/view
Similar issue:
Possibly a similar issue is discussed here: UART initialisation: Prevent UART to pull RTS high
But I'm not sure how to proceed with the suggested solution.
This is little more than wild speculation, but it might be worth adding a start-up script that echoes a NULL character to the device (e.g. /dev/ttyS1 or whatever) as early as possible during start-up. This might be enough to kick the driver into initialising the hardware.
You could also try to locate the driver in the Linux source to look at how it starts up.
Probably you have access to the source code, so you can investigate who and when mess with the that GPIO. Just grep the kernel source for the atmel gpio controller port addresses to figure out what happen. If you are lucky may be there will be kernel command line option that you can pass from the bootloader to set the line to what you need in advance.
this answer may work if you can find required things mentioned below
of your board!
Once I also had a same issue on PWM. There I found that my bootloader was responsible for the same, I changed in bootloader configuration and it started working fine.
Check your BSP provided by board vendor or third party (If you have the source), If your bootloader is U-boot you can find it inside U-boot-(source)/include/configs/(your-board).h there you can find configuration for RS484. As per your datasheet for the board you can check for other things which are muxed on the same pin and disable those if not required for boot time and enable RS485.
enabling/disabling can be done by changing the values 0, 1 or 2 as per your configuration and also you can simply disable anything just by commenting // out the line.
I have a Freescale imx.6q (arm) based board.
Hardware is configured with devicetree.
It had a change major incompatible change to timings and voltage for an onboard fpga, but these changes are invisible to the kernel.
The EE's tell us we shouldn't load the old fpga firmware for fear of damaging it. I would like to support both hardware from the same code (It is already causing confusion)
The solution I have thought of is this:
There are several new spi temperature sensors on the board. If I can read from one of those devices, I can infer that I need the new firmware.
How can I (in one driver) grab an spi device and then release it?
I suspect that I might be able to do something like this with device tree,
But I don't want to make the device unavailable.
Any ideas or examples of something like this being done?
After reading question i think your concern is how to add software support for more than one hardware.
If that is the case i think we can write two drivers supporting both hardware's with different configuration such as irq, voltage, register set etc.
So i will enable both drivers in Makefile and config file.
So at the time of boot when probe of drivers gets called we can check the hardware id by using spi_read command from driver.
If hardware id matches then driver probe gets successful and driver can be used to interact with hardware.
If spi_read fails then driver probe itself will fail.
I think this will do the trick.
EDIT (answer the question)
To detect use an SPI device from another driver use a reference to the device in the devicetree structure.
Short answer: add a reference to the spi device in your devices dts entry.
Slightly longer answer:
When adding spi to another device driver, you are effectively adding a subdevice, which may want its own driver. I have an FPGA which loads its firmware over (something close enough to be considered) SPI. I started with the idea of just treating the spi device as part of the larger driver, but the more work went into it, the more obvious it was that it is its own device, with a purpose and function that is distinct from the rest of the driver. I separated that code into its own driver.
Now instead of a reference to an SPI device, my driver just has a reference to an FPGA Manager device.
See line 98, 370 of https://github.com/d4ddi0/linux/blob/v4.12evi/arch/arm/boot/dts/imx6q-evi.dts
and
make sure the spi driver is loaded before your driver completes loading
My original answer to my question (for historical purposes):
What I ended up doing was using different devicetree files. The difference is know at initial install time (based on the serial number). The bootloader knows which dts filename to load.
There are multiple FPGA firmware versions and the right one is chosen based on the description in the dts.
This way, I can still update the driver and/or dts without breakage.
This works well in practice even though it does not detect anything at runtime.
One problem still exists, if I take an SD card from a new revision, and put it into an old one, the incorrect firmware will be loaded. To really solve this last problem, we've talked about adding an EEPROM to uniquely identify the hardware revision on future boards.
I am working with Sasebo GII board that has two FPGAs on it:
Xilinx Spartan and Xilinx Virtex5 (and the board has several separate JTAG interfaces for configuration of fpgas).
I am useing ISE 14.4 under Linux and I have some troubles to configure the Virtex 5 FPGA.
(no problems with Spartan).
I am using "Impact" to send the configuration files to FPGAs.
At the beginning Impact scans the board and finds Spartan FPGA without problems
and I can configure it, but when I plug the cable to the other interface and press scan on Impact it says:
"There are many unknown devices being detected. Press Yes to continue or press No to stop."
If I press the NO option, well, obviously nothing happens :-)
And if I click on YES it fails, I can manually add Virtex5 FPGA, but than it fails to upload the config file to it (and even fails when I try to detect the device ID).
I already tried all JTAG interfaces on the board, nothing.
Same operations work on the same board with SPARTAN FPGA, so I'm stuck. Any ideas ?
Well, I am not familiar with that particular board, but there are many things you can look into when it comes to your JTAG problem.
Check the voltage of your VCC, make sure it has a good value for the board
Make sure your ground connection is well connected and you don't have much impedance
between the connector's GND and the boards GND
Try other JTAG connectors and see if you see any difference in the detection of the
devices.
Try to run the IMPACT in debug mode. Capture the data and see if the patterns look OK
Also something that may not be JTAG related, is to make sure your V5 device has all the powers it needs, if there are any power problems, it may cause the JTAG interface to behave like you explained here.
Also, look on the board and see if there are any switches or jumpers to chose different way of configuring the V5 device. This can be a big issues with multi-FPGA board, maybe the V5 is configured to be programmed from a controller or other devices on the board and the JTAG chain is not set up for programming.
These are just different thoughts, they may help you toward the right direction.
Found this on their site:
User guide for the board
To reprogram the flash ROM (ST45DB16D, U11) for the control FPGA (Spartan-3A), attach the configuration
cable to CN7. For configuration, use the provided mcs file sasebo_gii_ctrl.mcs.
Reprogram the flash ROM (ST45DB16D, U4) for the cryptographic FPGA (Virtex-5 LX30) with the provided
mcs file sasebo_aes_comp_lx30.mcs as well. Connect the configuration cable to CN4.
To configure the FPGA immediately after reprog
ramming of the flash ROM, cycle the power.
Blockquote
This means you can't program the FPGA directly, you need to convert your bit file into MCS file and then load it into the FLASH memory on the board.