Commit 63606522 authored by Vinod Koul's avatar Vinod Koul
Browse files

Merge branch 'fixes' into next

parents 361e5fc7 ea9aadc0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1086,6 +1086,7 @@ static int __dma_async_device_channel_register(struct dma_device *device,
	kfree(chan->dev);
 err_free_local:
	free_percpu(chan->local);
	chan->local = NULL;
	return rc;
}

+2 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ config DW_DMAC_CORE

config DW_DMAC
	tristate "Synopsys DesignWare AHB DMA platform driver"
	depends on HAS_IOMEM
	select DW_DMAC_CORE
	help
	  Support the Synopsys DesignWare AHB DMA controller. This
@@ -18,6 +19,7 @@ config DW_DMAC
config DW_DMAC_PCI
	tristate "Synopsys DesignWare AHB DMA PCI driver"
	depends on PCI
	depends on HAS_IOMEM
	select DW_DMAC_CORE
	help
	  Support the Synopsys DesignWare AHB DMA controller on the
+54 −11
Original line number Diff line number Diff line
@@ -282,6 +282,22 @@ void idxd_wq_drain(struct idxd_wq *wq)
	idxd_cmd_exec(idxd, IDXD_CMD_DRAIN_WQ, operand, NULL);
}

void idxd_wq_reset(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
	struct device *dev = &idxd->pdev->dev;
	u32 operand;

	if (wq->state != IDXD_WQ_ENABLED) {
		dev_dbg(dev, "WQ %d in wrong state: %d\n", wq->id, wq->state);
		return;
	}

	operand = BIT(wq->id % 16) | ((wq->id / 16) << 16);
	idxd_cmd_exec(idxd, IDXD_CMD_RESET_WQ, operand, NULL);
	wq->state = IDXD_WQ_DISABLED;
}

int idxd_wq_map_portal(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
@@ -363,8 +379,6 @@ int idxd_wq_disable_pasid(struct idxd_wq *wq)
void idxd_wq_disable_cleanup(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
	struct device *dev = &idxd->pdev->dev;
	int i, wq_offset;

	lockdep_assert_held(&idxd->dev_lock);
	memset(wq->wqcfg, 0, idxd->wqcfg_size);
@@ -376,14 +390,6 @@ void idxd_wq_disable_cleanup(struct idxd_wq *wq)
	wq->ats_dis = 0;
	clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
	memset(wq->name, 0, WQ_NAME_SIZE);

	for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
		wq_offset = WQCFG_OFFSET(idxd, wq->id, i);
		iowrite32(0, idxd->reg_base + wq_offset);
		dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
			wq->id, i, wq_offset,
			ioread32(idxd->reg_base + wq_offset));
	}
}

/* Device control bits */
@@ -575,6 +581,36 @@ void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid)
}

/* Device configuration bits */
void idxd_msix_perm_setup(struct idxd_device *idxd)
{
	union msix_perm mperm;
	int i, msixcnt;

	msixcnt = pci_msix_vec_count(idxd->pdev);
	if (msixcnt < 0)
		return;

	mperm.bits = 0;
	mperm.pasid = idxd->pasid;
	mperm.pasid_en = device_pasid_enabled(idxd);
	for (i = 1; i < msixcnt; i++)
		iowrite32(mperm.bits, idxd->reg_base + idxd->msix_perm_offset + i * 8);
}

void idxd_msix_perm_clear(struct idxd_device *idxd)
{
	union msix_perm mperm;
	int i, msixcnt;

	msixcnt = pci_msix_vec_count(idxd->pdev);
	if (msixcnt < 0)
		return;

	mperm.bits = 0;
	for (i = 1; i < msixcnt; i++)
		iowrite32(mperm.bits, idxd->reg_base + idxd->msix_perm_offset + i * 8);
}

static void idxd_group_config_write(struct idxd_group *group)
{
	struct idxd_device *idxd = group->idxd;
@@ -643,7 +679,14 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
	if (!wq->group)
		return 0;

	memset(wq->wqcfg, 0, idxd->wqcfg_size);
	/*
	 * Instead of memset the entire shadow copy of WQCFG, copy from the hardware after
	 * wq reset. This will copy back the sticky values that are present on some devices.
	 */
	for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
		wq_offset = WQCFG_OFFSET(idxd, wq->id, i);
		wq->wqcfg->bits[i] = ioread32(idxd->reg_base + wq_offset);
	}

	/* byte 0-3 */
	wq->wqcfg->wq_size = wq->size;
+3 −0
Original line number Diff line number Diff line
@@ -316,6 +316,8 @@ void idxd_unregister_driver(void);
struct bus_type *idxd_get_bus_type(struct idxd_device *idxd);

/* device interrupt control */
void idxd_msix_perm_setup(struct idxd_device *idxd);
void idxd_msix_perm_clear(struct idxd_device *idxd);
irqreturn_t idxd_irq_handler(int vec, void *data);
irqreturn_t idxd_misc_thread(int vec, void *data);
irqreturn_t idxd_wq_thread(int irq, void *data);
@@ -341,6 +343,7 @@ void idxd_wq_free_resources(struct idxd_wq *wq);
int idxd_wq_enable(struct idxd_wq *wq);
int idxd_wq_disable(struct idxd_wq *wq);
void idxd_wq_drain(struct idxd_wq *wq);
void idxd_wq_reset(struct idxd_wq *wq);
int idxd_wq_map_portal(struct idxd_wq *wq);
void idxd_wq_unmap_portal(struct idxd_wq *wq);
void idxd_wq_disable_cleanup(struct idxd_wq *wq);
+2 −9
Original line number Diff line number Diff line
@@ -65,7 +65,6 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
	struct idxd_irq_entry *irq_entry;
	int i, msixcnt;
	int rc = 0;
	union msix_perm mperm;

	msixcnt = pci_msix_vec_count(pdev);
	if (msixcnt < 0) {
@@ -144,14 +143,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
	}

	idxd_unmask_error_interrupts(idxd);

	/* Setup MSIX permission table */
	mperm.bits = 0;
	mperm.pasid = idxd->pasid;
	mperm.pasid_en = device_pasid_enabled(idxd);
	for (i = 1; i < msixcnt; i++)
		iowrite32(mperm.bits, idxd->reg_base + idxd->msix_perm_offset + i * 8);

	idxd_msix_perm_setup(idxd);
	return 0;

 err_no_irq:
@@ -510,6 +502,7 @@ static void idxd_shutdown(struct pci_dev *pdev)
		idxd_flush_work_list(irq_entry);
	}

	idxd_msix_perm_clear(idxd);
	destroy_workqueue(idxd->wq);
}

Loading