spi: dw: Disable all IRQs when controller is unused

It's a good practice to disable all IRQs if a device is fully unused. In
our case it is supposed to be done before requesting the IRQ and after the
last byte of an SPI transfer is received. In the former case it's required
to prevent the IRQ handler invocation before the driver data is fully
initialized (which may happen if the IRQs status has been left uncleared
before the device is probed). So we just moved the spi_hw_init() method
invocation to the earlier stage before requesting the IRQ. In the later
case there is just no point in having any of the IRQs enabled between SPI
transfers and when there is no SPI message currently being processed.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Link: https://lore.kernel.org/r/20200920112914.26501-7-Sergey.Semin@baikalelectronics.ru
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Serge Semin 2020-09-20 14:28:50 +03:00 committed by Mark Brown
parent a128f6ecd5
commit a1d5aa6f7f
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -204,7 +204,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
dw_reader(dws); dw_reader(dws);
if (dws->rx_end == dws->rx) { if (dws->rx_end == dws->rx) {
spi_mask_intr(dws, SPI_INT_TXEI); spi_mask_intr(dws, 0xff);
spi_finalize_current_transfer(dws->master); spi_finalize_current_transfer(dws->master);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -228,7 +228,7 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
if (!master->cur_msg) { if (!master->cur_msg) {
spi_mask_intr(dws, SPI_INT_TXEI); spi_mask_intr(dws, 0xff);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -468,6 +468,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
spi_controller_set_devdata(master, dws); spi_controller_set_devdata(master, dws);
/* Basic HW init */
spi_hw_init(dev, dws);
ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
master); master);
if (ret < 0) { if (ret < 0) {
@ -498,9 +501,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
device_property_read_u32(dev, "rx-sample-delay-ns", device_property_read_u32(dev, "rx-sample-delay-ns",
&dws->def_rx_sample_dly_ns); &dws->def_rx_sample_dly_ns);
/* Basic HW init */
spi_hw_init(dev, dws);
if (dws->dma_ops && dws->dma_ops->dma_init) { if (dws->dma_ops && dws->dma_ops->dma_init) {
ret = dws->dma_ops->dma_init(dev, dws); ret = dws->dma_ops->dma_init(dev, dws);
if (ret) { if (ret) {