Loading drivers/bus/fsl-mc/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,8 @@ mc-bus-driver-objs := fsl-mc-bus.o \ dprc-driver.o \ fsl-mc-allocator.o \ fsl-mc-msi.o \ dpmcp.o dpmcp.o \ obj-api.o # MC userspace support obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o drivers/bus/fsl-mc/fsl-mc-private.h +35 −4 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ struct dpmng_rsp_get_version { /* DPMCP command IDs */ #define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800) #define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b) #define DPMCP_CMDID_RESET DPMCP_CMD(0x005) struct dpmcp_cmd_open { Loading Loading @@ -91,7 +90,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, /* DPRC command IDs */ #define DPRC_CMDID_CLOSE DPRC_CMD(0x800) #define DPRC_CMDID_OPEN DPRC_CMD(0x805) #define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) #define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) Loading Loading @@ -453,7 +451,6 @@ int dprc_get_connection(struct fsl_mc_io *mc_io, /* Command IDs */ #define DPBP_CMDID_CLOSE DPBP_CMD(0x800) #define DPBP_CMDID_OPEN DPBP_CMD(0x804) #define DPBP_CMDID_ENABLE DPBP_CMD(0x002) #define DPBP_CMDID_DISABLE DPBP_CMD(0x003) Loading Loading @@ -492,7 +489,6 @@ struct dpbp_rsp_get_attributes { /* Command IDs */ #define DPCON_CMDID_CLOSE DPCON_CMD(0x800) #define DPCON_CMDID_OPEN DPCON_CMD(0x808) #define DPCON_CMDID_ENABLE DPCON_CMD(0x002) #define DPCON_CMDID_DISABLE DPCON_CMD(0x003) Loading Loading @@ -524,6 +520,41 @@ struct dpcon_cmd_set_notification { __le64 user_ctx; }; /* * Generic FSL MC API */ /* generic command versioning */ #define OBJ_CMD_BASE_VERSION 1 #define OBJ_CMD_ID_OFFSET 4 #define OBJ_CMD(id) (((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION) /* open command codes */ #define DPRTC_CMDID_OPEN OBJ_CMD(0x810) #define DPNI_CMDID_OPEN OBJ_CMD(0x801) #define DPSW_CMDID_OPEN OBJ_CMD(0x802) #define DPIO_CMDID_OPEN OBJ_CMD(0x803) #define DPBP_CMDID_OPEN OBJ_CMD(0x804) #define DPRC_CMDID_OPEN OBJ_CMD(0x805) #define DPDMUX_CMDID_OPEN OBJ_CMD(0x806) #define DPCI_CMDID_OPEN OBJ_CMD(0x807) #define DPCON_CMDID_OPEN OBJ_CMD(0x808) #define DPSECI_CMDID_OPEN OBJ_CMD(0x809) #define DPAIOP_CMDID_OPEN OBJ_CMD(0x80a) #define DPMCP_CMDID_OPEN OBJ_CMD(0x80b) #define DPMAC_CMDID_OPEN OBJ_CMD(0x80c) #define DPDCEI_CMDID_OPEN OBJ_CMD(0x80d) #define DPDMAI_CMDID_OPEN OBJ_CMD(0x80e) #define DPDBG_CMDID_OPEN OBJ_CMD(0x80f) /* Generic object command IDs */ #define OBJ_CMDID_CLOSE OBJ_CMD(0x800) #define OBJ_CMDID_RESET OBJ_CMD(0x005) struct fsl_mc_obj_cmd_open { __le32 obj_id; }; /** * struct fsl_mc_resource_pool - Pool of MC resources of a given Loading drivers/bus/fsl-mc/obj-api.c 0 → 100644 +103 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2021 NXP * */ #include <linux/kernel.h> #include <linux/fsl/mc.h> #include "fsl-mc-private.h" static int fsl_mc_get_open_cmd_id(const char *type) { static const struct { int cmd_id; const char *type; } dev_ids[] = { { DPRTC_CMDID_OPEN, "dprtc" }, { DPRC_CMDID_OPEN, "dprc" }, { DPNI_CMDID_OPEN, "dpni" }, { DPIO_CMDID_OPEN, "dpio" }, { DPSW_CMDID_OPEN, "dpsw" }, { DPBP_CMDID_OPEN, "dpbp" }, { DPCON_CMDID_OPEN, "dpcon" }, { DPMCP_CMDID_OPEN, "dpmcp" }, { DPMAC_CMDID_OPEN, "dpmac" }, { DPSECI_CMDID_OPEN, "dpseci" }, { DPDMUX_CMDID_OPEN, "dpdmux" }, { DPDCEI_CMDID_OPEN, "dpdcei" }, { DPAIOP_CMDID_OPEN, "dpaiop" }, { DPCI_CMDID_OPEN, "dpci" }, { DPDMAI_CMDID_OPEN, "dpdmai" }, { DPDBG_CMDID_OPEN, "dpdbg" }, { 0, NULL } }; int i; for (i = 0; dev_ids[i].type; i++) if (!strcmp(dev_ids[i].type, type)) return dev_ids[i].cmd_id; return -1; } int fsl_mc_obj_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int obj_id, char *obj_type, u16 *token) { struct fsl_mc_command cmd = { 0 }; struct fsl_mc_obj_cmd_open *cmd_params; int err = 0; int cmd_id = fsl_mc_get_open_cmd_id(obj_type); if (cmd_id == -1) return -ENODEV; /* prepare command */ cmd.header = mc_encode_cmd_header(cmd_id, cmd_flags, 0); cmd_params = (struct fsl_mc_obj_cmd_open *)cmd.params; cmd_params->obj_id = cpu_to_le32(obj_id); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); if (err) return err; /* retrieve response parameters */ *token = mc_cmd_hdr_read_token(&cmd); return err; } EXPORT_SYMBOL_GPL(fsl_mc_obj_open); int fsl_mc_obj_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) { struct fsl_mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(OBJ_CMDID_CLOSE, cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } EXPORT_SYMBOL_GPL(fsl_mc_obj_close); int fsl_mc_obj_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) { struct fsl_mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(OBJ_CMDID_RESET, cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } EXPORT_SYMBOL_GPL(fsl_mc_obj_reset); drivers/vfio/fsl-mc/vfio_fsl_mc.c +30 −15 Original line number Diff line number Diff line Loading @@ -65,6 +65,34 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) kfree(vdev->regions); } static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev) { struct fsl_mc_device *mc_dev = vdev->mc_dev; int ret = 0; if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { return dprc_reset_container(mc_dev->mc_io, 0, mc_dev->mc_handle, mc_dev->obj_desc.id, DPRC_RESET_OPTION_NON_RECURSIVE); } else { u16 token; ret = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, mc_dev->obj_desc.type, &token); if (ret) goto out; ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token); if (ret) { fsl_mc_obj_close(mc_dev->mc_io, 0, token); goto out; } ret = fsl_mc_obj_close(mc_dev->mc_io, 0, token); } out: return ret; } static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) { Loading @@ -78,9 +106,7 @@ static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) vfio_fsl_mc_regions_cleanup(vdev); /* reset the device before cleaning up the interrupts */ ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle, mc_cont->obj_desc.id, DPRC_RESET_OPTION_NON_RECURSIVE); ret = vfio_fsl_mc_reset_device(vdev); if (WARN_ON(ret)) dev_warn(&mc_cont->dev, Loading Loading @@ -203,18 +229,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, } case VFIO_DEVICE_RESET: { int ret; struct fsl_mc_device *mc_dev = vdev->mc_dev; /* reset is supported only for the DPRC */ if (!is_fsl_mc_bus_dprc(mc_dev)) return -ENOTTY; ret = dprc_reset_container(mc_dev->mc_io, 0, mc_dev->mc_handle, mc_dev->obj_desc.id, DPRC_RESET_OPTION_NON_RECURSIVE); return ret; return vfio_fsl_mc_reset_device(vdev); } default: Loading include/linux/fsl/mc.h +14 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,20 @@ int dpcon_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); int fsl_mc_obj_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int obj_id, char *obj_type, u16 *token); int fsl_mc_obj_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); int fsl_mc_obj_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); /** * struct dpcon_attr - Structure representing DPCON attributes * @id: DPCON object ID Loading Loading
drivers/bus/fsl-mc/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,8 @@ mc-bus-driver-objs := fsl-mc-bus.o \ dprc-driver.o \ fsl-mc-allocator.o \ fsl-mc-msi.o \ dpmcp.o dpmcp.o \ obj-api.o # MC userspace support obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o
drivers/bus/fsl-mc/fsl-mc-private.h +35 −4 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ struct dpmng_rsp_get_version { /* DPMCP command IDs */ #define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800) #define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b) #define DPMCP_CMDID_RESET DPMCP_CMD(0x005) struct dpmcp_cmd_open { Loading Loading @@ -91,7 +90,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, /* DPRC command IDs */ #define DPRC_CMDID_CLOSE DPRC_CMD(0x800) #define DPRC_CMDID_OPEN DPRC_CMD(0x805) #define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) #define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) Loading Loading @@ -453,7 +451,6 @@ int dprc_get_connection(struct fsl_mc_io *mc_io, /* Command IDs */ #define DPBP_CMDID_CLOSE DPBP_CMD(0x800) #define DPBP_CMDID_OPEN DPBP_CMD(0x804) #define DPBP_CMDID_ENABLE DPBP_CMD(0x002) #define DPBP_CMDID_DISABLE DPBP_CMD(0x003) Loading Loading @@ -492,7 +489,6 @@ struct dpbp_rsp_get_attributes { /* Command IDs */ #define DPCON_CMDID_CLOSE DPCON_CMD(0x800) #define DPCON_CMDID_OPEN DPCON_CMD(0x808) #define DPCON_CMDID_ENABLE DPCON_CMD(0x002) #define DPCON_CMDID_DISABLE DPCON_CMD(0x003) Loading Loading @@ -524,6 +520,41 @@ struct dpcon_cmd_set_notification { __le64 user_ctx; }; /* * Generic FSL MC API */ /* generic command versioning */ #define OBJ_CMD_BASE_VERSION 1 #define OBJ_CMD_ID_OFFSET 4 #define OBJ_CMD(id) (((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION) /* open command codes */ #define DPRTC_CMDID_OPEN OBJ_CMD(0x810) #define DPNI_CMDID_OPEN OBJ_CMD(0x801) #define DPSW_CMDID_OPEN OBJ_CMD(0x802) #define DPIO_CMDID_OPEN OBJ_CMD(0x803) #define DPBP_CMDID_OPEN OBJ_CMD(0x804) #define DPRC_CMDID_OPEN OBJ_CMD(0x805) #define DPDMUX_CMDID_OPEN OBJ_CMD(0x806) #define DPCI_CMDID_OPEN OBJ_CMD(0x807) #define DPCON_CMDID_OPEN OBJ_CMD(0x808) #define DPSECI_CMDID_OPEN OBJ_CMD(0x809) #define DPAIOP_CMDID_OPEN OBJ_CMD(0x80a) #define DPMCP_CMDID_OPEN OBJ_CMD(0x80b) #define DPMAC_CMDID_OPEN OBJ_CMD(0x80c) #define DPDCEI_CMDID_OPEN OBJ_CMD(0x80d) #define DPDMAI_CMDID_OPEN OBJ_CMD(0x80e) #define DPDBG_CMDID_OPEN OBJ_CMD(0x80f) /* Generic object command IDs */ #define OBJ_CMDID_CLOSE OBJ_CMD(0x800) #define OBJ_CMDID_RESET OBJ_CMD(0x005) struct fsl_mc_obj_cmd_open { __le32 obj_id; }; /** * struct fsl_mc_resource_pool - Pool of MC resources of a given Loading
drivers/bus/fsl-mc/obj-api.c 0 → 100644 +103 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2021 NXP * */ #include <linux/kernel.h> #include <linux/fsl/mc.h> #include "fsl-mc-private.h" static int fsl_mc_get_open_cmd_id(const char *type) { static const struct { int cmd_id; const char *type; } dev_ids[] = { { DPRTC_CMDID_OPEN, "dprtc" }, { DPRC_CMDID_OPEN, "dprc" }, { DPNI_CMDID_OPEN, "dpni" }, { DPIO_CMDID_OPEN, "dpio" }, { DPSW_CMDID_OPEN, "dpsw" }, { DPBP_CMDID_OPEN, "dpbp" }, { DPCON_CMDID_OPEN, "dpcon" }, { DPMCP_CMDID_OPEN, "dpmcp" }, { DPMAC_CMDID_OPEN, "dpmac" }, { DPSECI_CMDID_OPEN, "dpseci" }, { DPDMUX_CMDID_OPEN, "dpdmux" }, { DPDCEI_CMDID_OPEN, "dpdcei" }, { DPAIOP_CMDID_OPEN, "dpaiop" }, { DPCI_CMDID_OPEN, "dpci" }, { DPDMAI_CMDID_OPEN, "dpdmai" }, { DPDBG_CMDID_OPEN, "dpdbg" }, { 0, NULL } }; int i; for (i = 0; dev_ids[i].type; i++) if (!strcmp(dev_ids[i].type, type)) return dev_ids[i].cmd_id; return -1; } int fsl_mc_obj_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int obj_id, char *obj_type, u16 *token) { struct fsl_mc_command cmd = { 0 }; struct fsl_mc_obj_cmd_open *cmd_params; int err = 0; int cmd_id = fsl_mc_get_open_cmd_id(obj_type); if (cmd_id == -1) return -ENODEV; /* prepare command */ cmd.header = mc_encode_cmd_header(cmd_id, cmd_flags, 0); cmd_params = (struct fsl_mc_obj_cmd_open *)cmd.params; cmd_params->obj_id = cpu_to_le32(obj_id); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); if (err) return err; /* retrieve response parameters */ *token = mc_cmd_hdr_read_token(&cmd); return err; } EXPORT_SYMBOL_GPL(fsl_mc_obj_open); int fsl_mc_obj_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) { struct fsl_mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(OBJ_CMDID_CLOSE, cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } EXPORT_SYMBOL_GPL(fsl_mc_obj_close); int fsl_mc_obj_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) { struct fsl_mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(OBJ_CMDID_RESET, cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } EXPORT_SYMBOL_GPL(fsl_mc_obj_reset);
drivers/vfio/fsl-mc/vfio_fsl_mc.c +30 −15 Original line number Diff line number Diff line Loading @@ -65,6 +65,34 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) kfree(vdev->regions); } static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev) { struct fsl_mc_device *mc_dev = vdev->mc_dev; int ret = 0; if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { return dprc_reset_container(mc_dev->mc_io, 0, mc_dev->mc_handle, mc_dev->obj_desc.id, DPRC_RESET_OPTION_NON_RECURSIVE); } else { u16 token; ret = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, mc_dev->obj_desc.type, &token); if (ret) goto out; ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token); if (ret) { fsl_mc_obj_close(mc_dev->mc_io, 0, token); goto out; } ret = fsl_mc_obj_close(mc_dev->mc_io, 0, token); } out: return ret; } static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) { Loading @@ -78,9 +106,7 @@ static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) vfio_fsl_mc_regions_cleanup(vdev); /* reset the device before cleaning up the interrupts */ ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle, mc_cont->obj_desc.id, DPRC_RESET_OPTION_NON_RECURSIVE); ret = vfio_fsl_mc_reset_device(vdev); if (WARN_ON(ret)) dev_warn(&mc_cont->dev, Loading Loading @@ -203,18 +229,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, } case VFIO_DEVICE_RESET: { int ret; struct fsl_mc_device *mc_dev = vdev->mc_dev; /* reset is supported only for the DPRC */ if (!is_fsl_mc_bus_dprc(mc_dev)) return -ENOTTY; ret = dprc_reset_container(mc_dev->mc_io, 0, mc_dev->mc_handle, mc_dev->obj_desc.id, DPRC_RESET_OPTION_NON_RECURSIVE); return ret; return vfio_fsl_mc_reset_device(vdev); } default: Loading
include/linux/fsl/mc.h +14 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,20 @@ int dpcon_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); int fsl_mc_obj_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int obj_id, char *obj_type, u16 *token); int fsl_mc_obj_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); int fsl_mc_obj_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); /** * struct dpcon_attr - Structure representing DPCON attributes * @id: DPCON object ID Loading