forked from Minki/linux
75ca758adb
The OCXL driver contains both frontend code for interacting with userspace, as well as backend code for interacting with the hardware. This patch separates the backend code from the frontend so that it can be used by other device drivers that communicate via OpenCAPI. Relocate dev, cdev & sysfs files to the frontend code to allow external drivers to maintain their own devices. Reference counting on the device in the backend is replaced with kref counting. Move file & sysfs layer initialisation from core.c (backend) to pci.c (frontend). Create an ocxl_function oriented interface for initing devices & enumerating AFUs. Signed-off-by: Alastair D'Silva <alastair@d-silva.org> Acked-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
67 lines
1.5 KiB
C
67 lines
1.5 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
// Copyright 2019 IBM Corp.
|
|
#include <linux/module.h>
|
|
#include "ocxl_internal.h"
|
|
|
|
/*
|
|
* Any opencapi device which wants to use this 'generic' driver should
|
|
* use the 0x062B device ID. Vendors should define the subsystem
|
|
* vendor/device ID to help differentiate devices.
|
|
*/
|
|
static const struct pci_device_id ocxl_pci_tbl[] = {
|
|
{ PCI_DEVICE(PCI_VENDOR_ID_IBM, 0x062B), },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(pci, ocxl_pci_tbl);
|
|
|
|
static int ocxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|
{
|
|
int rc;
|
|
struct ocxl_afu *afu, *tmp;
|
|
struct ocxl_fn *fn;
|
|
struct list_head *afu_list;
|
|
|
|
fn = ocxl_function_open(dev);
|
|
if (IS_ERR(fn))
|
|
return PTR_ERR(fn);
|
|
|
|
pci_set_drvdata(dev, fn);
|
|
|
|
afu_list = ocxl_function_afu_list(fn);
|
|
|
|
list_for_each_entry_safe(afu, tmp, afu_list, list) {
|
|
// Cleanup handled within ocxl_file_register_afu()
|
|
rc = ocxl_file_register_afu(afu);
|
|
if (rc) {
|
|
dev_err(&dev->dev, "Failed to register AFU '%s' index %d",
|
|
afu->config.name, afu->config.idx);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ocxl_remove(struct pci_dev *dev)
|
|
{
|
|
struct ocxl_fn *fn;
|
|
struct ocxl_afu *afu;
|
|
struct list_head *afu_list;
|
|
|
|
fn = pci_get_drvdata(dev);
|
|
afu_list = ocxl_function_afu_list(fn);
|
|
|
|
list_for_each_entry(afu, afu_list, list) {
|
|
ocxl_file_unregister_afu(afu);
|
|
}
|
|
|
|
ocxl_function_close(fn);
|
|
}
|
|
|
|
struct pci_driver ocxl_pci_driver = {
|
|
.name = "ocxl",
|
|
.id_table = ocxl_pci_tbl,
|
|
.probe = ocxl_probe,
|
|
.remove = ocxl_remove,
|
|
.shutdown = ocxl_remove,
|
|
};
|