aboutsummaryrefslogtreecommitdiff
path: root/kernel/async.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2020-11-08 16:32:42 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2020-11-18 09:23:50 -0800
commit6b48e5b8a20f653b7d64ccf99a498f2523bff752 (patch)
tree5ea9a4e6cb85cc766970f8fdc4b2c69ef4b2b723 /kernel/async.c
parent498fe261f0d6d5189f8e11d283705dd97b474b54 (diff)
xfs: directory scrub should check the null bestfree entries too
Teach the directory scrubber to check all the bestfree entries, including the null ones. We want to be able to detect the case where the entry is null but there actually /is/ a directory data block. Found by fuzzing lbests[0] = ones in xfs/391. Fixes: df481968f33b ("xfs: scrub directory freespace") Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'kernel/async.c')
0 files changed, 0 insertions, 0 deletions
8612dbc87dc7396affc9758e3bfbe92340'>drivers/spi/spi-bcm-qspi.h34
-rw-r--r--drivers/spi/spi-iproc-qspi.c163
4 files changed, 291 insertions, 5 deletions
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3e753db484d4..2dc1b71706f9 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_SPI_BCM2835AUX) += spi-bcm2835aux.o
obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o
obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o
-obj-$(CONFIG_SPI_BCM_QSPI) += spi-brcmstb-qspi.o spi-bcm-qspi.o
+obj-$(CONFIG_SPI_BCM_QSPI) += spi-iproc-qspi.o spi-brcmstb-qspi.o spi-bcm-qspi.o
obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o
obj-$(CONFIG_SPI_ADI_V3) += spi-adi-v3.o
obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c
index 2c121ba8f0cb..14f9dea3173f 100644
--- a/drivers/spi/spi-bcm-qspi.c
+++ b/drivers/spi/spi-bcm-qspi.c
@@ -175,9 +175,15 @@ enum base_type {
BASEMAX,
};
+enum irq_source {
+ SINGLE_L2,
+ MUXED_L1,
+};
+
struct bcm_qspi_irq {
const char *irq_name;
const irq_handler_t irq_handler;
+ int irq_source;
u32 mask;
};
@@ -198,6 +204,10 @@ struct bcm_qspi {
u32 base_clk;
u32 max_speed_hz;
void __iomem *base[BASEMAX];
+
+ /* Some SoCs provide custom interrupt status register(s) */
+ struct bcm_qspi_soc_intc *soc_intc;
+
struct bcm_qspi_parms last_parms;
struct qspi_trans trans_pos;
int curr_cs;
@@ -806,6 +816,7 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
u32 addr = 0, len, len_words;
int ret = 0;
unsigned long timeo = msecs_to_jiffies(100);
+ struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
if (bcm_qspi_bspi_ver_three(qspi))
if (msg->addr_width == BSPI_ADDRLEN_4BYTES)
@@ -850,6 +861,15 @@ static int bcm_qspi_bspi_flash_read(struct spi_device *spi,
bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words);
bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0);
+ if (qspi->soc_intc) {
+ /*
+ * clear soc MSPI and BSPI interrupts and enable
+ * BSPI interrupts.
+ */
+ soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_BSPI_DONE);
+ soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, true);
+ }
+
/* Must flush previous writes before starting BSPI operation */
mb();
@@ -952,9 +972,12 @@ static irqreturn_t bcm_qspi_mspi_l2_isr(int irq, void *dev_id)
u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
if (status & MSPI_MSPI_STATUS_SPIF) {
+ struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
/* clear interrupt */
status &= ~MSPI_MSPI_STATUS_SPIF;
bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status);
+ if (qspi->soc_intc)
+ soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_DONE);
complete(&qspi->mspi_done);
return IRQ_HANDLED;
}
@@ -966,20 +989,33 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_isr(int irq, void *dev_id)
{
struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
struct bcm_qspi *qspi = qspi_dev_id->dev;
- u32 status;
+ struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
+ u32 status = qspi_dev_id->irqp->mask;
if (qspi->bspi_enabled && qspi->bspi_rf_msg) {
bcm_qspi_bspi_lr_data_read(qspi);
if (qspi->bspi_rf_msg_len == 0) {
qspi->bspi_rf_msg = NULL;
+ if (qspi->soc_intc) {
+ /* disable soc BSPI interrupt */
+ soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE,
+ false);
+ /* indicate done */
+ status = INTR_BSPI_LR_SESSION_DONE_MASK;
+ }
+
if (qspi->bspi_rf_msg_status)
bcm_qspi_bspi_lr_clear(qspi);
else
bcm_qspi_bspi_flush_prefetch_buffers(qspi);
}
+
+ if (qspi->soc_intc)
+ /* clear soc BSPI interrupt */
+ soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_DONE);
}
- status = (qspi_dev_id->irqp->mask & INTR_BSPI_LR_SESSION_DONE_MASK);
+ status &= INTR_BSPI_LR_SESSION_DONE_MASK;
if (qspi->bspi_enabled && status && qspi->bspi_rf_msg_len == 0)
complete(&qspi->bspi_done);
@@ -990,13 +1026,39 @@ static irqreturn_t bcm_qspi_bspi_lr_err_l2_isr(int irq, void *dev_id)
{
struct bcm_qspi_dev_id *qspi_dev_id = dev_id;
struct bcm_qspi *qspi = qspi_dev_id->dev;
+ struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc;
dev_err(&qspi->pdev->dev, "BSPI INT error\n");
qspi->bspi_rf_msg_status = -EIO;
+ if (qspi->soc_intc)
+ /* clear soc interrupt */
+ soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_ERR);
+
complete(&qspi->bspi_done);
return IRQ_HANDLED;
}