Skip to content

Commit

Permalink
dmaengine: idxd: add configuration component of driver
Browse files Browse the repository at this point in the history
The device is left unconfigured when the driver is loaded. Various
components are configured via the driver sysfs attributes. Once
configuration is done, the device can be enabled by writing the device name
to the bind attribute of the device driver sysfs. Disabling can be done
similarly. Also the individual work queues can also be enabled and disabled
through the bind/unbind attributes. A constructed hierarchy is created
through the struct device framework in order to provide appropriate
configuration points and device state and status. This hierarchy is
presented off the virtual DSA bus.

i.e. /sys/bus/dsa/...

Signed-off-by: Dave Jiang <[email protected]>
Link: https://lore.kernel.org/r/157965024585.73301.6431413676230150589.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Vinod Koul <[email protected]>
  • Loading branch information
davejiang authored and vinodkoul committed Jan 24, 2020
1 parent bfe1d56 commit c52ca47
Show file tree
Hide file tree
Showing 6 changed files with 1,536 additions and 3 deletions.
2 changes: 1 addition & 1 deletion drivers/dma/idxd/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
obj-$(CONFIG_INTEL_IDXD) += idxd.o
idxd-y := init.o irq.o device.o
idxd-y := init.o irq.o device.o sysfs.o
31 changes: 31 additions & 0 deletions drivers/dma/idxd/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ int idxd_wq_alloc_resources(struct idxd_wq *wq)
struct device *dev = &idxd->pdev->dev;
int rc, num_descs, i;

if (wq->type != IDXD_WQT_KERNEL)
return 0;

num_descs = wq->size +
idxd->hw.gen_cap.max_descs_per_engine * group->num_engines;
wq->num_descs = num_descs;
Expand Down Expand Up @@ -206,6 +209,9 @@ void idxd_wq_free_resources(struct idxd_wq *wq)
{
struct device *dev = &wq->idxd->pdev->dev;

if (wq->type != IDXD_WQT_KERNEL)
return;

free_hw_descs(wq);
free_descs(wq);
dma_free_coherent(dev, wq->compls_size, wq->compls, wq->compls_addr);
Expand Down Expand Up @@ -277,6 +283,31 @@ int idxd_wq_disable(struct idxd_wq *wq)
return 0;
}

int idxd_wq_map_portal(struct idxd_wq *wq)
{
struct idxd_device *idxd = wq->idxd;
struct pci_dev *pdev = idxd->pdev;
struct device *dev = &pdev->dev;
resource_size_t start;

start = pci_resource_start(pdev, IDXD_WQ_BAR);
start = start + wq->id * IDXD_PORTAL_SIZE;

wq->dportal = devm_ioremap(dev, start, IDXD_PORTAL_SIZE);
if (!wq->dportal)
return -ENOMEM;
dev_dbg(dev, "wq %d portal mapped at %p\n", wq->id, wq->dportal);

return 0;
}

void idxd_wq_unmap_portal(struct idxd_wq *wq)
{
struct device *dev = &wq->idxd->pdev->dev;

devm_iounmap(dev, wq->dportal);
}

/* Device control bits */
static inline bool idxd_is_enabled(struct idxd_device *idxd)
{
Expand Down
24 changes: 24 additions & 0 deletions drivers/dma/idxd/idxd.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ struct idxd_device {
int max_wqs;
int max_wq_size;
int token_limit;
int nr_tokens; /* non-reserved tokens */

union sw_err_reg sw_err;

Expand Down Expand Up @@ -195,7 +196,28 @@ static inline void idxd_set_type(struct idxd_device *idxd)
idxd->type = IDXD_TYPE_UNKNOWN;
}

static inline void idxd_wq_get(struct idxd_wq *wq)
{
wq->client_count++;
}

static inline void idxd_wq_put(struct idxd_wq *wq)
{
wq->client_count--;
}

static inline int idxd_wq_refcount(struct idxd_wq *wq)
{
return wq->client_count;
};

const char *idxd_get_dev_name(struct idxd_device *idxd);
int idxd_register_bus_type(void);
void idxd_unregister_bus_type(void);
int idxd_setup_sysfs(struct idxd_device *idxd);
void idxd_cleanup_sysfs(struct idxd_device *idxd);
int idxd_register_driver(void);
void idxd_unregister_driver(void);

/* device interrupt control */
irqreturn_t idxd_irq_handler(int vec, void *data);
Expand All @@ -221,5 +243,7 @@ int idxd_wq_alloc_resources(struct idxd_wq *wq);
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);
int idxd_wq_map_portal(struct idxd_wq *wq);
void idxd_wq_unmap_portal(struct idxd_wq *wq);

#endif
27 changes: 26 additions & 1 deletion drivers/dma/idxd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ static void idxd_read_caps(struct idxd_device *idxd)
dev_dbg(dev, "max groups: %u\n", idxd->max_groups);
idxd->max_tokens = idxd->hw.group_cap.total_tokens;
dev_dbg(dev, "max tokens: %u\n", idxd->max_tokens);
idxd->nr_tokens = idxd->max_tokens;

/* read engine capabilities */
idxd->hw.engine_cap.bits =
Expand Down Expand Up @@ -381,6 +382,14 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENODEV;
}

rc = idxd_setup_sysfs(idxd);
if (rc) {
dev_err(dev, "IDXD sysfs setup failed\n");
return -ENODEV;
}

idxd->state = IDXD_DEV_CONF_READY;

dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
idxd->hw.version);

Expand Down Expand Up @@ -418,6 +427,7 @@ static void idxd_remove(struct pci_dev *pdev)
struct idxd_device *idxd = pci_get_drvdata(pdev);

dev_dbg(&pdev->dev, "%s called\n", __func__);
idxd_cleanup_sysfs(idxd);
idxd_shutdown(pdev);
idxd_wqs_free_lock(idxd);
mutex_lock(&idxd_idr_lock);
Expand Down Expand Up @@ -453,16 +463,31 @@ static int __init idxd_init_module(void)
for (i = 0; i < IDXD_TYPE_MAX; i++)
idr_init(&idxd_idrs[i]);

err = idxd_register_bus_type();
if (err < 0)
return err;

err = idxd_register_driver();
if (err < 0)
goto err_idxd_driver_register;

err = pci_register_driver(&idxd_pci_driver);
if (err)
return err;
goto err_pci_register;

return 0;

err_pci_register:
idxd_unregister_driver();
err_idxd_driver_register:
idxd_unregister_bus_type();
return err;
}
module_init(idxd_init_module);

static void __exit idxd_exit_module(void)
{
pci_unregister_driver(&idxd_pci_driver);
idxd_unregister_bus_type();
}
module_exit(idxd_exit_module);
3 changes: 2 additions & 1 deletion drivers/dma/idxd/registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#define IDXD_MMIO_BAR 0
#define IDXD_WQ_BAR 2
#define IDXD_PORTAL_SIZE 0x4000

/* MMIO Device BAR0 Registers */
#define IDXD_VER_OFFSET 0x00
Expand Down Expand Up @@ -223,7 +224,7 @@ enum idxd_cmdsts_err {
};

#define IDXD_SWERR_OFFSET 0xc0
#define IDXD_SWERR_VALID 0x00000001
#define IDXD_SWERR_VALID 0x00000001
#define IDXD_SWERR_OVERFLOW 0x00000002
#define IDXD_SWERR_ACK (IDXD_SWERR_VALID | IDXD_SWERR_OVERFLOW)
union sw_err_reg {
Expand Down
Loading

0 comments on commit c52ca47

Please sign in to comment.