^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * CXL Flash Device Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Uma Krishnan <ukrishn@linux.vnet.ibm.com>, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2018 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <misc/cxl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "backend.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * The following routines map the cxlflash backend operations to existing CXL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * kernel API function and are largely simple shims that provide an abstraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * for converting generic context and AFU cookies into cxl_context or cxl_afu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static void __iomem *cxlflash_psa_map(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return cxl_psa_map(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void cxlflash_psa_unmap(void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) cxl_psa_unmap(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int cxlflash_process_element(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return cxl_process_element(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int cxlflash_map_afu_irq(void *ctx_cookie, int num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) irq_handler_t handler, void *cookie, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return cxl_map_afu_irq(ctx_cookie, num, handler, cookie, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static void cxlflash_unmap_afu_irq(void *ctx_cookie, int num, void *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) cxl_unmap_afu_irq(ctx_cookie, num, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static u64 cxlflash_get_irq_objhndl(void *ctx_cookie, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Dummy fop for cxl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int cxlflash_start_context(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return cxl_start_context(ctx_cookie, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int cxlflash_stop_context(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return cxl_stop_context(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int cxlflash_afu_reset(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return cxl_afu_reset(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static void cxlflash_set_master(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) cxl_set_master(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static void *cxlflash_get_context(struct pci_dev *dev, void *afu_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return cxl_get_context(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static void *cxlflash_dev_context_init(struct pci_dev *dev, void *afu_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return cxl_dev_context_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static int cxlflash_release_context(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return cxl_release_context(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void cxlflash_perst_reloads_same_image(void *afu_cookie, bool image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) cxl_perst_reloads_same_image(afu_cookie, image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static ssize_t cxlflash_read_adapter_vpd(struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return cxl_read_adapter_vpd(dev, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int cxlflash_allocate_afu_irqs(void *ctx_cookie, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return cxl_allocate_afu_irqs(ctx_cookie, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void cxlflash_free_afu_irqs(void *ctx_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) cxl_free_afu_irqs(ctx_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void *cxlflash_create_afu(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return cxl_pci_to_afu(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void cxlflash_destroy_afu(void *afu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Dummy fop for cxl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static struct file *cxlflash_get_fd(void *ctx_cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct file_operations *fops, int *fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return cxl_get_fd(ctx_cookie, fops, fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void *cxlflash_fops_get_context(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return cxl_fops_get_context(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int cxlflash_start_work(void *ctx_cookie, u64 irqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct cxl_ioctl_start_work work = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) work.num_interrupts = irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) work.flags = CXL_START_WORK_NUM_IRQS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return cxl_start_work(ctx_cookie, &work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int cxlflash_fd_mmap(struct file *file, struct vm_area_struct *vm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return cxl_fd_mmap(file, vm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int cxlflash_fd_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return cxl_fd_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) const struct cxlflash_backend_ops cxlflash_cxl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .psa_map = cxlflash_psa_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .psa_unmap = cxlflash_psa_unmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .process_element = cxlflash_process_element,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .map_afu_irq = cxlflash_map_afu_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .unmap_afu_irq = cxlflash_unmap_afu_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .get_irq_objhndl = cxlflash_get_irq_objhndl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) .start_context = cxlflash_start_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .stop_context = cxlflash_stop_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .afu_reset = cxlflash_afu_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .set_master = cxlflash_set_master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .get_context = cxlflash_get_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .dev_context_init = cxlflash_dev_context_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .release_context = cxlflash_release_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .perst_reloads_same_image = cxlflash_perst_reloads_same_image,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .read_adapter_vpd = cxlflash_read_adapter_vpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .allocate_afu_irqs = cxlflash_allocate_afu_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .free_afu_irqs = cxlflash_free_afu_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .create_afu = cxlflash_create_afu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .destroy_afu = cxlflash_destroy_afu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .get_fd = cxlflash_get_fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .fops_get_context = cxlflash_fops_get_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .start_work = cxlflash_start_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .fd_mmap = cxlflash_fd_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .fd_release = cxlflash_fd_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };