| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * CXL Flash Device Driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Uma Krishnan <ukrishn@linux.vnet.ibm.com>, IBM Corporation |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Copyright (C) 2018 IBM Corporation |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or |
|---|
| 10 | | - * modify it under the terms of the GNU General Public License |
|---|
| 11 | | - * as published by the Free Software Foundation; either version |
|---|
| 12 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <linux/file.h> |
|---|
| 16 | 12 | #include <linux/idr.h> |
|---|
| 17 | 13 | #include <linux/module.h> |
|---|
| 18 | 14 | #include <linux/mount.h> |
|---|
| 15 | +#include <linux/pseudo_fs.h> |
|---|
| 19 | 16 | #include <linux/poll.h> |
|---|
| 20 | 17 | #include <linux/sched/signal.h> |
|---|
| 21 | | - |
|---|
| 18 | +#include <linux/interrupt.h> |
|---|
| 19 | +#include <asm/xive.h> |
|---|
| 22 | 20 | #include <misc/ocxl.h> |
|---|
| 23 | 21 | |
|---|
| 24 | 22 | #include <uapi/misc/cxl.h> |
|---|
| .. | .. |
|---|
| 35 | 33 | static int ocxlflash_fs_cnt; |
|---|
| 36 | 34 | static struct vfsmount *ocxlflash_vfs_mount; |
|---|
| 37 | 35 | |
|---|
| 38 | | -static const struct dentry_operations ocxlflash_fs_dops = { |
|---|
| 39 | | - .d_dname = simple_dname, |
|---|
| 40 | | -}; |
|---|
| 41 | | - |
|---|
| 42 | | -/* |
|---|
| 43 | | - * ocxlflash_fs_mount() - mount the pseudo-filesystem |
|---|
| 44 | | - * @fs_type: File system type. |
|---|
| 45 | | - * @flags: Flags for the filesystem. |
|---|
| 46 | | - * @dev_name: Device name associated with the filesystem. |
|---|
| 47 | | - * @data: Data pointer. |
|---|
| 48 | | - * |
|---|
| 49 | | - * Return: pointer to the directory entry structure |
|---|
| 50 | | - */ |
|---|
| 51 | | -static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type, |
|---|
| 52 | | - int flags, const char *dev_name, |
|---|
| 53 | | - void *data) |
|---|
| 36 | +static int ocxlflash_fs_init_fs_context(struct fs_context *fc) |
|---|
| 54 | 37 | { |
|---|
| 55 | | - return mount_pseudo(fs_type, "ocxlflash:", NULL, &ocxlflash_fs_dops, |
|---|
| 56 | | - OCXLFLASH_FS_MAGIC); |
|---|
| 38 | + return init_pseudo(fc, OCXLFLASH_FS_MAGIC) ? 0 : -ENOMEM; |
|---|
| 57 | 39 | } |
|---|
| 58 | 40 | |
|---|
| 59 | 41 | static struct file_system_type ocxlflash_fs_type = { |
|---|
| 60 | 42 | .name = "ocxlflash", |
|---|
| 61 | 43 | .owner = THIS_MODULE, |
|---|
| 62 | | - .mount = ocxlflash_fs_mount, |
|---|
| 44 | + .init_fs_context = ocxlflash_fs_init_fs_context, |
|---|
| 63 | 45 | .kill_sb = kill_anon_super, |
|---|
| 64 | 46 | }; |
|---|
| 65 | 47 | |
|---|
| .. | .. |
|---|
| 199 | 181 | struct ocxl_hw_afu *afu = ctx->hw_afu; |
|---|
| 200 | 182 | struct device *dev = afu->dev; |
|---|
| 201 | 183 | struct ocxlflash_irqs *irq; |
|---|
| 202 | | - void __iomem *vtrig; |
|---|
| 184 | + struct xive_irq_data *xd; |
|---|
| 203 | 185 | u32 virq; |
|---|
| 204 | 186 | int rc = 0; |
|---|
| 205 | 187 | |
|---|
| .. | .. |
|---|
| 223 | 205 | goto err1; |
|---|
| 224 | 206 | } |
|---|
| 225 | 207 | |
|---|
| 226 | | - vtrig = ioremap(irq->ptrig, PAGE_SIZE); |
|---|
| 227 | | - if (unlikely(!vtrig)) { |
|---|
| 228 | | - dev_err(dev, "%s: Trigger page mapping failed\n", __func__); |
|---|
| 229 | | - rc = -ENOMEM; |
|---|
| 208 | + xd = irq_get_handler_data(virq); |
|---|
| 209 | + if (unlikely(!xd)) { |
|---|
| 210 | + dev_err(dev, "%s: Can't get interrupt data\n", __func__); |
|---|
| 211 | + rc = -ENXIO; |
|---|
| 230 | 212 | goto err2; |
|---|
| 231 | 213 | } |
|---|
| 232 | 214 | |
|---|
| 233 | 215 | irq->virq = virq; |
|---|
| 234 | | - irq->vtrig = vtrig; |
|---|
| 216 | + irq->vtrig = xd->trig_mmio; |
|---|
| 235 | 217 | out: |
|---|
| 236 | 218 | return rc; |
|---|
| 237 | 219 | err2: |
|---|
| .. | .. |
|---|
| 278 | 260 | } |
|---|
| 279 | 261 | |
|---|
| 280 | 262 | irq = &ctx->irqs[num]; |
|---|
| 281 | | - if (irq->vtrig) |
|---|
| 282 | | - iounmap(irq->vtrig); |
|---|
| 283 | 263 | |
|---|
| 284 | 264 | if (irq_find_mapping(NULL, irq->hwirq)) { |
|---|
| 285 | 265 | free_irq(irq->virq, cookie); |
|---|
| .. | .. |
|---|
| 634 | 614 | struct ocxl_hw_afu *afu = ctx->hw_afu; |
|---|
| 635 | 615 | struct device *dev = afu->dev; |
|---|
| 636 | 616 | struct ocxlflash_irqs *irqs; |
|---|
| 637 | | - u64 addr; |
|---|
| 638 | 617 | int rc = 0; |
|---|
| 639 | 618 | int hwirq; |
|---|
| 640 | 619 | int i; |
|---|
| .. | .. |
|---|
| 659 | 638 | } |
|---|
| 660 | 639 | |
|---|
| 661 | 640 | for (i = 0; i < num; i++) { |
|---|
| 662 | | - rc = ocxl_link_irq_alloc(afu->link_token, &hwirq, &addr); |
|---|
| 641 | + rc = ocxl_link_irq_alloc(afu->link_token, &hwirq); |
|---|
| 663 | 642 | if (unlikely(rc)) { |
|---|
| 664 | 643 | dev_err(dev, "%s: ocxl_link_irq_alloc failed rc=%d\n", |
|---|
| 665 | 644 | __func__, rc); |
|---|
| .. | .. |
|---|
| 667 | 646 | } |
|---|
| 668 | 647 | |
|---|
| 669 | 648 | irqs[i].hwirq = hwirq; |
|---|
| 670 | | - irqs[i].ptrig = addr; |
|---|
| 671 | 649 | } |
|---|
| 672 | 650 | |
|---|
| 673 | 651 | ctx->irqs = irqs; |
|---|