You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This patch series was initially conceived as a requirement for the sllin driver to support LIN slave responses within the specified response time. While the kernel currently contains some limited support for 16550A devices, there is not currently universal support for any additional devices, despite the fact that most modern chipsets support programmable FIFO interrupt levels at the hardware level. This issue has been discussed extensively on the sllin github repo.
Development Goals
This patch series aspires to maintain support for the current rx_trigger_bytes sysfs interface for 16550a based devices and expand it to other drivers, as well as create an API for use by other drivers within the kernel itself. Additionally, the ability to disable the FIFO altogether is required by some drivers which don't necessary support single-byte trigger levels. Furthermore, the ability to set Tx trigger levels, although not necessary for the sllin project, has been implemented for completeness.
Implementation Overview
The first patch implements the core plumbing for the FIFO control by defining two uart_ops functions, get_fifo_control & set_fifo_control to enable access to FIFO control within the kernel. The original rx_trigger_bytes for 16550A based devices has been moved to serial_core and has been reworked to call the new internal set_fifo_control, and get_fifo_control which have been implemented in uart_ops. Other patches implement the uart_ops as per their respective hardware specifications.
Status
This patch series currently supports the most commonly available serial devices, including 16550a, 16650, 16750, 16950, PL011, CH38X & AX99100 based chipsets. Development of other devices is ongoing.
Testing
A suite of testing tools has been created to assist developers in implementing and verifying FIFO control on a variety of devices. The tests include some kernel level debugFS modules for testing 8250 compatible devices, as well as some universal userspace level tests.
Limitations and Known Issues
This patch series currently breaks sysfs API compatibility with the initial 16550a rx_trigger_bytes sysfs entry by not rounding down to the next nearest level. The reasoning was that we'd like to inform other drivers when we reject unsupported trigger levels. However, in order to maintain kernel API compatibility this feature should probably be re-enabled for the sysfs entry. The core uart_ops used by other drivers (such as sllin) can reject the trigger levels at the kernel level, and other userspace programs can re-check the trigger levels via the sysfs if they need to verify the level was set appropriately.
The current implementation uses a function to dispatch the appropriate callbacks. This should probably be moved to the uart_config array in serial_core.
Discussion Points
Existing sysfs API compatibility
This implementation abandons the round down method previously used in the 8250 rx_trig_bytes sysfs. This should be reimplemented on the sysfs side to maintain backwards compatibility with the existing rx_trig_bytes interface so as to not break existing userspace software which uses this interface.
Changes to existing 8250 based drivers
Many 8250 based drivers set their port-type based on closely matching existing definitions in 8250_port.c's uart_config. For example, the CH38x used 16850 config, presumably because the fifo size (and other config settings) matches it's default trigger level. However, the ch38x actually supports 16750 compatible registers, which is important if we want to actually change the fifo trigger levels.
The AX99100 previously relied on default 8250 probing, which detected a 16650. However, actual ax99100's are 16950 register compatible. I implemented a setup quirk in 8250_pci to set the port type to 16950. The other option was to fix the 8250 probe function, but I feel like this approach is cleaner.
Many other 8250 based drivers might make similar assumptions regarding the port type, and will likely need similar changes as the drivers above.
uart_config for set_fifo_control & get_fifo_control callbacks
This implementation uses a dispatch function to select the proper callbacks. It would probably be cleaner to specify the callback inside 8250_port uart_config.
Store or reconstruct uart_fifo_control to be returned by get_fifo_control
Should we store the FIFO control struct when set, or should we reconstruct a FIFO control struct based off of other driver data (such as FCR) in order to return the current FIFO contol via get_fifo_control? Many 8250-based devices don't allow reading the FCR register, and so we store the FCR in the port anyways. Storing the entire uart_fifo_control seems simpler.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Overview and Requirements
This patch series was initially conceived as a requirement for the sllin driver to support LIN slave responses within the specified response time. While the kernel currently contains some limited support for 16550A devices, there is not currently universal support for any additional devices, despite the fact that most modern chipsets support programmable FIFO interrupt levels at the hardware level. This issue has been discussed extensively on the sllin github repo.
Development Goals
This patch series aspires to maintain support for the current rx_trigger_bytes sysfs interface for 16550a based devices and expand it to other drivers, as well as create an API for use by other drivers within the kernel itself. Additionally, the ability to disable the FIFO altogether is required by some drivers which don't necessary support single-byte trigger levels. Furthermore, the ability to set Tx trigger levels, although not necessary for the sllin project, has been implemented for completeness.
Implementation Overview
The first patch implements the core plumbing for the FIFO control by defining two uart_ops functions, get_fifo_control & set_fifo_control to enable access to FIFO control within the kernel. The original rx_trigger_bytes for 16550A based devices has been moved to serial_core and has been reworked to call the new internal set_fifo_control, and get_fifo_control which have been implemented in uart_ops. Other patches implement the uart_ops as per their respective hardware specifications.
Status
This patch series currently supports the most commonly available serial devices, including 16550a, 16650, 16750, 16950, PL011, CH38X & AX99100 based chipsets. Development of other devices is ongoing.
Testing
A suite of testing tools has been created to assist developers in implementing and verifying FIFO control on a variety of devices. The tests include some kernel level debugFS modules for testing 8250 compatible devices, as well as some universal userspace level tests.
Limitations and Known Issues
This patch series currently breaks sysfs API compatibility with the initial 16550a rx_trigger_bytes sysfs entry by not rounding down to the next nearest level. The reasoning was that we'd like to inform other drivers when we reject unsupported trigger levels. However, in order to maintain kernel API compatibility this feature should probably be re-enabled for the sysfs entry. The core uart_ops used by other drivers (such as sllin) can reject the trigger levels at the kernel level, and other userspace programs can re-check the trigger levels via the sysfs if they need to verify the level was set appropriately.
The current implementation uses a function to dispatch the appropriate callbacks. This should probably be moved to the uart_config array in serial_core.
Discussion Points
Existing sysfs API compatibility
This implementation abandons the round down method previously used in the 8250 rx_trig_bytes sysfs. This should be reimplemented on the sysfs side to maintain backwards compatibility with the existing rx_trig_bytes interface so as to not break existing userspace software which uses this interface.
Changes to existing 8250 based drivers
Many 8250 based drivers set their port-type based on closely matching existing definitions in 8250_port.c's uart_config. For example, the CH38x used 16850 config, presumably because the fifo size (and other config settings) matches it's default trigger level. However, the ch38x actually supports 16750 compatible registers, which is important if we want to actually change the fifo trigger levels.
The AX99100 previously relied on default 8250 probing, which detected a 16650. However, actual ax99100's are 16950 register compatible. I implemented a setup quirk in 8250_pci to set the port type to 16950. The other option was to fix the 8250 probe function, but I feel like this approach is cleaner.
Many other 8250 based drivers might make similar assumptions regarding the port type, and will likely need similar changes as the drivers above.
uart_config for set_fifo_control & get_fifo_control callbacks
This implementation uses a dispatch function to select the proper callbacks. It would probably be cleaner to specify the callback inside 8250_port uart_config.
Store or reconstruct uart_fifo_control to be returned by get_fifo_control
Should we store the FIFO control struct when set, or should we reconstruct a FIFO control struct based off of other driver data (such as FCR) in order to return the current FIFO contol via get_fifo_control? Many 8250-based devices don't allow reading the FCR register, and so we store the FCR in the port anyways. Storing the entire uart_fifo_control seems simpler.
Additional HW support
Any other feedback is appreciated!
Beta Was this translation helpful? Give feedback.
All reactions