diff options
author | Frederic Barrat <fbarrat@linux.vnet.ibm.com> | 2018-01-23 12:31:43 +0100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-01-24 01:42:59 +0100 |
commit | 280b983ce2b8759722d911ea4b5af66e95d84e09 (patch) | |
tree | d3f3ffe5ee5acd780749b690921e97c09aa76845 /drivers/misc/ocxl | |
parent | ocxl: Add AFU interrupt support (diff) | |
download | linux-280b983ce2b8759722d911ea4b5af66e95d84e09.tar.xz linux-280b983ce2b8759722d911ea4b5af66e95d84e09.zip |
ocxl: Add a kernel API for other opencapi drivers
Some of the functions done by the generic driver should also be needed
by other opencapi drivers: attaching a context to an adapter,
translation fault handling, AFU interrupt allocation...
So to avoid code duplication, the driver provides a kernel API that
other drivers can use, similar to calling a in-kernel library.
It is still a bit theoretical, for lack of real hardware, and will
likely need adjustements down the road. But we used the cxlflash
driver as a guinea pig.
Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'drivers/misc/ocxl')
-rw-r--r-- | drivers/misc/ocxl/config.c | 13 | ||||
-rw-r--r-- | drivers/misc/ocxl/link.c | 7 | ||||
-rw-r--r-- | drivers/misc/ocxl/ocxl_internal.h | 71 |
3 files changed, 20 insertions, 71 deletions
diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c index ea8cca50ea06..2e30de9c694a 100644 --- a/drivers/misc/ocxl/config.c +++ b/drivers/misc/ocxl/config.c @@ -2,8 +2,8 @@ // Copyright 2017 IBM Corp. #include <linux/pci.h> #include <asm/pnv-ocxl.h> +#include <misc/ocxl.h> #include <misc/ocxl-config.h> -#include "ocxl_internal.h" #define EXTRACT_BIT(val, bit) (!!(val & BIT(bit))) #define EXTRACT_BITS(val, s, e) ((val & GENMASK(e, s)) >> s) @@ -243,6 +243,7 @@ int ocxl_config_read_function(struct pci_dev *dev, struct ocxl_fn_config *fn) rc = validate_function(dev, fn); return rc; } +EXPORT_SYMBOL_GPL(ocxl_config_read_function); static int read_afu_info(struct pci_dev *dev, struct ocxl_fn_config *fn, int offset, u32 *data) @@ -301,6 +302,7 @@ int ocxl_config_check_afu_index(struct pci_dev *dev, } return 1; } +EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index); static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn, struct ocxl_afu_config *afu) @@ -498,6 +500,7 @@ int ocxl_config_read_afu(struct pci_dev *dev, struct ocxl_fn_config *fn, rc = validate_afu(dev, afu); return rc; } +EXPORT_SYMBOL_GPL(ocxl_config_read_afu); int ocxl_config_get_actag_info(struct pci_dev *dev, u16 *base, u16 *enabled, u16 *supported) @@ -516,6 +519,7 @@ int ocxl_config_get_actag_info(struct pci_dev *dev, u16 *base, u16 *enabled, } return 0; } +EXPORT_SYMBOL_GPL(ocxl_config_get_actag_info); void ocxl_config_set_afu_actag(struct pci_dev *dev, int pos, int actag_base, int actag_count) @@ -528,11 +532,13 @@ void ocxl_config_set_afu_actag(struct pci_dev *dev, int pos, int actag_base, val = actag_base & OCXL_DVSEC_ACTAG_MASK; pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_ACTAG_BASE, val); } +EXPORT_SYMBOL_GPL(ocxl_config_set_afu_actag); int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count) { return pnv_ocxl_get_pasid_count(dev, count); } +EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info); void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base, u32 pasid_count_log) @@ -550,6 +556,7 @@ void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base, pci_write_config_dword(dev, pos + OCXL_DVSEC_AFU_CTRL_PASID_BASE, val32); } +EXPORT_SYMBOL_GPL(ocxl_config_set_afu_pasid); void ocxl_config_set_afu_state(struct pci_dev *dev, int pos, int enable) { @@ -562,6 +569,7 @@ void ocxl_config_set_afu_state(struct pci_dev *dev, int pos, int enable) val &= 0xFE; pci_write_config_byte(dev, pos + OCXL_DVSEC_AFU_CTRL_ENABLE, val); } +EXPORT_SYMBOL_GPL(ocxl_config_set_afu_state); int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec) { @@ -660,6 +668,7 @@ out: kfree(recv_rate); return rc; } +EXPORT_SYMBOL_GPL(ocxl_config_set_TL); int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, int pasid) { @@ -699,6 +708,7 @@ int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, int pasid) } return 0; } +EXPORT_SYMBOL_GPL(ocxl_config_terminate_pasid); void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, u32 tag_first, u32 tag_count) @@ -710,3 +720,4 @@ void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, u32 tag_first, pci_write_config_dword(dev, func_dvsec + OCXL_DVSEC_FUNC_OFF_ACTAG, val); } +EXPORT_SYMBOL_GPL(ocxl_config_set_actag); diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c index 8bdcef9c3cba..fbca3feec592 100644 --- a/drivers/misc/ocxl/link.c +++ b/drivers/misc/ocxl/link.c @@ -5,6 +5,7 @@ #include <linux/mmu_context.h> #include <asm/copro.h> #include <asm/pnv-ocxl.h> +#include <misc/ocxl.h> #include "ocxl_internal.h" @@ -420,6 +421,7 @@ unlock: mutex_unlock(&links_list_lock); return rc; } +EXPORT_SYMBOL_GPL(ocxl_link_setup); static void release_xsl(struct kref *ref) { @@ -439,6 +441,7 @@ void ocxl_link_release(struct pci_dev *dev, void *link_handle) kref_put(&link->ref, release_xsl); mutex_unlock(&links_list_lock); } +EXPORT_SYMBOL_GPL(ocxl_link_release); static u64 calculate_cfg_state(bool kernel) { @@ -533,6 +536,7 @@ unlock: mutex_unlock(&spa->spa_lock); return rc; } +EXPORT_SYMBOL_GPL(ocxl_link_add_pe); int ocxl_link_remove_pe(void *link_handle, int pasid) { @@ -601,6 +605,7 @@ unlock: mutex_unlock(&spa->spa_lock); return rc; } +EXPORT_SYMBOL_GPL(ocxl_link_remove_pe); int ocxl_link_irq_alloc(void *link_handle, int *hw_irq, u64 *trigger_addr) { @@ -621,6 +626,7 @@ int ocxl_link_irq_alloc(void *link_handle, int *hw_irq, u64 *trigger_addr) *trigger_addr = addr; return 0; } +EXPORT_SYMBOL_GPL(ocxl_link_irq_alloc); void ocxl_link_free_irq(void *link_handle, int hw_irq) { @@ -629,3 +635,4 @@ void ocxl_link_free_irq(void *link_handle, int hw_irq) pnv_ocxl_free_xive_irq(hw_irq); atomic_inc(&link->irq_available); } +EXPORT_SYMBOL_GPL(ocxl_link_free_irq); diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h index a89b88ac67eb..5d421824afd9 100644 --- a/drivers/misc/ocxl/ocxl_internal.h +++ b/drivers/misc/ocxl/ocxl_internal.h @@ -6,8 +6,8 @@ #include <linux/pci.h> #include <linux/cdev.h> #include <linux/list.h> +#include <misc/ocxl.h> -#define OCXL_AFU_NAME_SZ (24+1) /* add 1 for NULL termination */ #define MAX_IRQ_PER_LINK 2000 #define MAX_IRQ_PER_CONTEXT MAX_IRQ_PER_LINK @@ -16,38 +16,6 @@ extern struct pci_driver ocxl_pci_driver; -/* - * The following 2 structures are a fairly generic way of representing - * the configuration data for a function and AFU, as read from the - * configuration space. - */ -struct ocxl_afu_config { - u8 idx; - int dvsec_afu_control_pos; - char name[OCXL_AFU_NAME_SZ]; - u8 version_major; - u8 version_minor; - u8 afuc_type; - u8 afum_type; - u8 profile; - u8 global_mmio_bar; - u64 global_mmio_offset; - u32 global_mmio_size; - u8 pp_mmio_bar; - u64 pp_mmio_offset; - u32 pp_mmio_stride; - u8 log_mem_size; - u8 pasid_supported_log; - u16 actag_supported; -}; - -struct ocxl_fn_config { - int dvsec_tl_pos; - int dvsec_function_pos; - int dvsec_afu_info_pos; - s8 max_pasid_log; - s8 max_afu_index; -}; struct ocxl_fn { struct device dev; @@ -135,43 +103,6 @@ extern void ocxl_unregister_afu(struct ocxl_afu *afu); extern int ocxl_file_init(void); extern void ocxl_file_exit(void); -extern int ocxl_config_read_function(struct pci_dev *dev, - struct ocxl_fn_config *fn); - -extern int ocxl_config_check_afu_index(struct pci_dev *dev, - struct ocxl_fn_config *fn, int afu_idx); -extern int ocxl_config_read_afu(struct pci_dev *dev, - struct ocxl_fn_config *fn, - struct ocxl_afu_config *afu, - u8 afu_idx); -extern int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count); -extern void ocxl_config_set_afu_pasid(struct pci_dev *dev, - int afu_control, - int pasid_base, u32 pasid_count_log); -extern int ocxl_config_get_actag_info(struct pci_dev *dev, - u16 *base, u16 *enabled, u16 *supported); -extern void ocxl_config_set_actag(struct pci_dev *dev, int func_dvsec, - u32 tag_first, u32 tag_count); -extern void ocxl_config_set_afu_actag(struct pci_dev *dev, int afu_control, - int actag_base, int actag_count); -extern void ocxl_config_set_afu_state(struct pci_dev *dev, int afu_control, - int enable); -extern int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec); -extern int ocxl_config_terminate_pasid(struct pci_dev *dev, int afu_control, - int pasid); - -extern int ocxl_link_setup(struct pci_dev *dev, int PE_mask, - void **link_handle); -extern void ocxl_link_release(struct pci_dev *dev, void *link_handle); -extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr, - u64 amr, struct mm_struct *mm, - void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr), - void *xsl_err_data); -extern int ocxl_link_remove_pe(void *link_handle, int pasid); -extern int ocxl_link_irq_alloc(void *link_handle, int *hw_irq, - u64 *addr); -extern void ocxl_link_free_irq(void *link_handle, int hw_irq); - extern int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size); extern void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size); extern int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size); |