linux/drivers
Phil Elwell 06bbe23870 sc16is7xx: Fix for multi-channel stall
[ Upstream commit 8344498721 ]

The SC16IS752 is a dual-channel device. The two channels are largely
independent, but the IRQ signals are wired together as an open-drain,
active low signal which will be driven low while either of the
channels requires attention, which can be for significant periods of
time until operations complete and the interrupt can be acknowledged.
In that respect it is should be treated as a true level-sensitive IRQ.

The kernel, however, needs to be able to exit interrupt context in
order to use I2C or SPI to access the device registers (which may
involve sleeping).  Therefore the interrupt needs to be masked out or
paused in some way.

The usual way to manage sleeping from within an interrupt handler
is to use a threaded interrupt handler - a regular interrupt routine
does the minimum amount of work needed to triage the interrupt before
waking the interrupt service thread. If the threaded IRQ is marked as
IRQF_ONESHOT the kernel will automatically mask out the interrupt
until the thread runs to completion. The sc16is7xx driver used to
use a threaded IRQ, but a patch switched to using a kthread_worker
in order to set realtime priorities on the handler thread and for
other optimisations. The end result is non-threaded IRQ that
schedules some work then returns IRQ_HANDLED, making the kernel
think that all IRQ processing has completed.

The work-around to prevent a constant stream of interrupts is to
mark the interrupt as edge-sensitive rather than level-sensitive,
but interpreting an active-low source as a falling-edge source
requires care to prevent a total cessation of interrupts. Whereas
an edge-triggering source will generate a new edge for every interrupt
condition a level-triggering source will keep the signal at the
interrupting level until it no longer requires attention; in other
words, the host won't see another edge until all interrupt conditions
are cleared. It is therefore vital that the interrupt handler does not
exit with an outstanding interrupt condition, otherwise the kernel
will not receive another interrupt unless some other operation causes
the interrupt state on the device to be cleared.

The existing sc16is7xx driver has a very simple interrupt "thread"
(kthread_work job) that processes interrupts on each channel in turn
until there are no more. If both channels are active and the first
channel starts interrupting while the handler for the second channel
is running then it will not be detected and an IRQ stall ensues. This
could be handled easily if there was a shared IRQ status register, or
a convenient way to determine if the IRQ had been deasserted for any
length of time, but both appear to be lacking.

Avoid this problem (or at least make it much less likely to happen)
by reducing the granularity of per-channel interrupt processing
to one condition per iteration, only exiting the overall loop when
both channels are no longer interrupting.

Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-11-21 09:27:39 +01:00
..
accessibility
acpi ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers 2018-11-21 09:27:32 +01:00
amba ARM: amba: Don't read past the end of sysfs "driver_override" buffer 2018-05-02 07:53:42 -07:00
android binder: add missing binder_unlock() 2018-02-28 10:17:23 +01:00
ata ahci: don't ignore result code of ahci_reset_controller() 2018-11-10 07:41:42 -08:00
atm atm: zatm: Fix potential Spectre v1 2018-07-22 14:25:52 +02:00
auxdisplay
base PM / core: Clear the direct_complete flag on errors 2018-10-13 09:11:32 +02:00
bcma bcma: use (get|put)_device when probing/removing device driver 2017-03-12 06:37:30 +01:00
block swim: fix cleanup on setup error 2018-11-21 09:27:31 +01:00
bluetooth Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth 2018-11-21 09:27:31 +01:00
bus bus: brcmstb_gisb: correct support for 64-bit address output 2018-04-13 19:50:05 +02:00
cdrom cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status 2018-09-05 09:18:41 +02:00
char tpm: Restore functionality to xen vtpm driver. 2018-11-21 09:27:33 +01:00
clk clk: imx6ul: fix missing of_node_put() 2018-09-26 08:35:05 +02:00
clocksource clocksource/drivers/ti-32k: Add CLOCK_SOURCE_SUSPEND_NONSTOP flag for non-am43 SoCs 2018-10-20 09:52:37 +02:00
connector connector: bump skb->users before callback invocation 2016-01-04 21:46:45 -05:00
cpufreq cpufreq: Fix new policy initialization during limits updates via sysfs 2018-07-03 11:21:26 +02:00
cpuidle cpuidle: powernv: Fix promotion from snooze if next state disabled 2018-07-03 11:21:29 +02:00
crypto crypto: mxs-dcp - Fix wait logic on chan threads 2018-10-10 08:52:13 +02:00
dca
devfreq PM / devfreq: tegra: fix error return code in tegra_devfreq_probe() 2018-11-10 07:41:40 -08:00
dio
dma dmaengine: dma-jz4780: Return error if not probed from DT 2018-11-21 09:27:33 +01:00
dma-buf
edac EDAC, i7core: Fix memleaks and use-after-free on probe and remove 2018-10-10 08:52:06 +02:00
eisa
extcon extcon: palmas: Check the parent instance to prevent the NULL 2017-11-21 09:21:18 +01:00
firewire firewire-ohci: work around oversized DMA reads on JMicron controllers 2018-05-30 07:48:52 +02:00
firmware firmware: dmi_scan: Fix handling of empty DMI strings 2018-05-30 07:48:56 +02:00
fmc
fpga
gpio gpio: msic: fix error return code in platform_msic_gpio_probe() 2018-11-10 07:41:39 -08:00
gpu drm/omap: fix memory barrier bug in DMM driver 2018-11-21 09:27:38 +01:00
hid HID: hiddev: fix potential Spectre v1 2018-11-21 09:27:34 +01:00
hsi HSI: ssi_protocol: double free in ssip_pn_xmit() 2018-03-24 10:58:42 +01:00
hv HV: properly delay KVP packets when negotiation is in progress 2018-10-20 09:52:38 +02:00
hwmon hwmon: (pmbus) Fix page count auto-detection. 2018-11-21 09:27:30 +01:00
hwspinlock drivers/hwspinlock: fix race between radix tree insertion and lookup 2016-02-25 12:01:23 -08:00
hwtracing coresight: tpiu: Fix disabling timeouts 2018-09-26 08:35:09 +02:00
i2c i2c: i2c-scmi: fix for i2c_smbus_write_block_data 2018-10-20 09:52:35 +02:00
ide cdrom: do not call check_disk_change() inside cdrom_open() 2018-05-30 07:49:13 +02:00
idle idle: i7300: add PCI dependency 2018-02-25 11:03:51 +01:00
iio iio: adc: at91: fix wrong channel number in triggered buffer mode 2018-11-21 09:27:35 +01:00
infiniband IB/ucm: Fix Spectre v1 vulnerability 2018-11-10 07:41:42 -08:00
input Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15IGM 2018-11-10 07:41:43 -08:00
iommu iommu/arm-smmu-v3: sync the OVACKFLG to PRIQ consumer register 2018-09-26 08:35:04 +02:00
ipack
irqchip irqchip/gic: Make interrupt ID 1020 invalid 2018-09-15 09:40:41 +02:00
isdn ser_gigaset: use container_of() instead of detour 2018-11-10 07:41:34 -08:00
leds leds: pca955x: Correct I2C Functionality 2018-04-13 19:50:09 +02:00
lguest
lightnvm lightnvm: put bio before return 2016-09-24 10:07:35 +02:00
macintosh macintosh/via-pmu: Add missing mmio accessors 2018-09-19 22:48:57 +02:00
mailbox mailbox: handle empty message in tx_tick 2017-08-06 19:19:41 -07:00
mcb mcb: Fixed bar number assignment for the gdd 2016-06-01 12:15:53 -07:00
md MD: fix invalid stored role for a disk - try2 2018-11-21 09:27:38 +01:00
media media: pci: cx23885: handle adding to list failure 2018-11-21 09:27:38 +01:00
memory memory: tegra: Apply interrupts mask per SoC 2018-08-06 16:24:38 +02:00
memstick memstick: rtsx_usb_ms: Manage runtime PM when accessing the device 2016-10-28 03:01:35 -04:00
message scsi: mptfusion: Add bounds check in mptctl_hp_targetinfo() 2018-05-30 07:48:58 +02:00
mfd thermal: allow u8500-thermal driver to be a module 2018-11-10 07:41:36 -08:00
misc signal/GenWQE: Fix sending of SIGKILL 2018-11-21 09:27:34 +01:00
mmc mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01 2018-11-21 09:27:31 +01:00
mtd mtd: spi-nor: Add support for is25wp series chips 2018-11-10 07:41:41 -08:00
net ath10k: schedule hardware restart if WMI command times out 2018-11-21 09:27:32 +01:00
nfc NFC: nfcmrvl: double free on error path 2018-03-22 09:23:23 +01:00
ntb ntb_transport: Fix bug with max_mw_size parameter 2018-05-30 07:48:55 +02:00
nubus
nvdimm libnvdimm: Hold reference on parent while scheduling async init 2018-11-21 09:27:34 +01:00
nvme nvme-pci: initialize queue memory before interrupts 2018-07-11 16:03:47 +02:00
nvmem nvmem: imx-ocotp: Fix wrong register size 2017-08-06 19:19:46 -07:00
of of: unittest: Disable interrupt node tests for old world MAC systems 2018-10-13 09:11:33 +02:00
oprofile
parisc parisc/pci: Switch LBA PCI bus from Hard Fail to Soft Fail mode 2018-05-30 07:49:10 +02:00
parport parport: sunbpp: fix error return code 2018-09-26 08:35:09 +02:00
pci PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk 2018-11-21 09:27:34 +01:00
pcmcia pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges 2018-11-21 09:27:30 +01:00
perf drivers/perf: arm_pmu: handle no platform_device 2018-03-22 09:23:26 +01:00
phy phy: work around 'phys' references to usb-nop-xceiv devices 2018-01-23 19:50:16 +01:00
pinctrl pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant 2018-11-21 09:27:32 +01:00
platform platform/x86: alienware-wmi: Correct a memory leak 2018-09-29 03:08:51 -07:00
pnp PNP: Add Broadwell to Intel MCH size workaround 2016-08-16 09:30:48 +02:00
power power: vexpress: fix corruption in notifier registration 2018-10-10 08:52:04 +02:00
powercap PowerCap: Fix an error code in powercap_register_zone() 2018-04-13 19:50:05 +02:00
pps pps: do not crash when failed to register 2016-08-10 11:49:25 +02:00
ps3
ptp ptp: fix Spectre v1 vulnerability 2018-11-10 07:41:42 -08:00
pwm pwm: tiehrpwm: Fix disabling of output of PWMs 2018-09-09 20:04:35 +02:00
rapidio
ras
regulator regulator: pfuze100: add .is_enable() for pfuze100_swb_regulator_ops 2018-08-06 16:24:35 +02:00
remoteproc remoteproc: Fix potential race condition in rproc_add 2016-08-20 18:09:20 +02:00
reset
rpmsg
rtc rtc: bq4802: add error handling for devm_ioremap 2018-09-26 08:35:09 +02:00
s390 s390/qeth: don't dump past end of unknown HW header 2018-10-10 08:52:12 +02:00
sbus
scsi scsi: lpfc: Correct soft lockup when running mds diagnostics 2018-11-21 09:27:33 +01:00
sfi
sh drivers: sh: Restore legacy clock domain on SuperH platforms 2016-03-09 15:34:49 -08:00
sn
soc soc/tegra: pmc: Fix child-node lookup 2018-11-21 09:27:37 +01:00
spi spi: xlp: fix error return code in xlp_spi_probe() 2018-11-10 07:41:40 -08:00
spmi spmi: Include OF based modalias in device uevent 2017-07-27 15:06:10 -07:00
ssb ssb: mark ssb_bus_register as __maybe_unused 2018-02-25 11:03:44 +01:00
staging staging: android: ashmem: Fix mmap size validation 2018-10-10 08:52:06 +02:00
target scsi: target: iscsi: Use bin2hex instead of a re-implementation 2018-10-10 08:52:08 +02:00
tc TC: Set DMA masks for devices 2018-11-21 09:27:36 +01:00
thermal thermal: allow u8500-thermal driver to be a module 2018-11-10 07:41:36 -08:00
thunderbolt thunderbolt: Resume control channel after hibernation image is created 2018-04-24 09:32:07 +02:00
tty sc16is7xx: Fix for multi-channel stall 2018-11-21 09:27:39 +01:00
uio uio: ensure class is registered before devices 2018-11-21 09:27:33 +01:00
usb usb: chipidea: Prevent unbalanced IRQ disable 2018-11-21 09:27:33 +01:00
uwb uwb: hwa-rc: fix memory leak at probe 2018-10-10 08:52:04 +02:00
vfio vfio/pci: Virtualize Maximum Read Request Size 2018-04-24 09:32:09 +02:00
vhost vhost: Fix Spectre V1 vulnerability 2018-11-10 07:41:42 -08:00
video video: fbdev: pxa3xx_gcu: fix error return code in pxa3xx_gcu_probe() 2018-11-10 07:41:39 -08:00
virt
virtio virtio_balloon: fix another race between migration and ballooning 2018-08-06 16:24:42 +02:00
vlynq
vme vme: Fix wrong pointer utilization in ca91cx42_slave_get 2017-01-19 20:17:21 +01:00
w1 w1: omap-hdq: fix missing bus unregister at removal 2018-11-21 09:27:35 +01:00
watchdog watchdog: f71808e_wdt: Fix magic close handling 2018-05-30 07:49:03 +02:00
xen xen-swiotlb: use actually allocated size on check physical continuous 2018-11-21 09:27:33 +01:00
zorro zorro: Set up z->dev.dma_mask for the DMA API 2018-05-30 07:49:11 +02:00
Kconfig
Makefile usb: build drivers/usb/common/ when USB_SUPPORT is set 2018-02-25 11:03:38 +01:00