- Migrated MC bus driver to use DPRC API 0.6. - Changed IRQ setup infrastructure to be able to program MSIs for MC objects in an object-independent way. Signed-off-by: J. German Rivera <German.Rivera@xxxxxxxxxxxxx> --- Changes in v4: - Fixed new checkpatch warnings and checks - Add missing error handling in dprc_probe() drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 79 --------- drivers/staging/fsl-mc/bus/dprc-cmd.h | 6 +- drivers/staging/fsl-mc/bus/dprc-driver.c | 64 +++++-- drivers/staging/fsl-mc/bus/dprc.c | 253 +++++++++++++++++++--------- drivers/staging/fsl-mc/bus/mc-allocator.c | 26 ++- drivers/staging/fsl-mc/bus/mc-bus.c | 58 ++++--- drivers/staging/fsl-mc/bus/mc-sys.c | 8 +- drivers/staging/fsl-mc/include/dpmng.h | 4 +- drivers/staging/fsl-mc/include/dprc.h | 244 +++++++++++++++++---------- drivers/staging/fsl-mc/include/mc-private.h | 31 +++- drivers/staging/fsl-mc/include/mc.h | 4 + 11 files changed, 474 insertions(+), 303 deletions(-) diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h index 57f326b..62bdc18 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h @@ -54,83 +54,4 @@ #define DPMCP_CMDID_GET_IRQ_STATUS 0x016 #define DPMCP_CMDID_CLEAR_IRQ_STATUS 0x017 -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_CREATE(cmd, cfg) \ - MC_CMD_OP(cmd, 0, 0, 32, int, cfg->portal_id) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_SET_IRQ(cmd, irq_index, irq_addr, irq_val, user_irq_id) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\ - MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_val);\ - MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_addr); \ - MC_CMD_OP(cmd, 2, 0, 32, int, user_irq_id); \ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_GET_IRQ(cmd, irq_index) \ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_RSP_GET_IRQ(cmd, type, irq_addr, irq_val, user_irq_id) \ -do { \ - MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_val); \ - MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_addr); \ - MC_RSP_OP(cmd, 2, 0, 32, int, user_irq_id); \ - MC_RSP_OP(cmd, 2, 32, 32, int, type); \ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_GET_IRQ_ENABLE(cmd, irq_index) \ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_RSP_GET_IRQ_ENABLE(cmd, en) \ - MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask);\ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_GET_IRQ_MASK(cmd, irq_index) \ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_RSP_GET_IRQ_MASK(cmd, mask) \ - MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_GET_IRQ_STATUS(cmd, irq_index) \ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_RSP_GET_IRQ_STATUS(cmd, status) \ - MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \ -do { \ - MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \ - MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\ -} while (0) - -/* cmd, param, offset, width, type, arg_name */ -#define DPMCP_RSP_GET_ATTRIBUTES(cmd, attr) \ -do { \ - MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\ - MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\ - MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\ -} while (0) - #endif /* _FSL_DPMCP_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h index 0920248..df5ad5f 100644 --- a/drivers/staging/fsl-mc/bus/dprc-cmd.h +++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h @@ -41,7 +41,7 @@ #define _FSL_DPRC_CMD_H /* DPRC Version */ -#define DPRC_VER_MAJOR 3 +#define DPRC_VER_MAJOR 4 #define DPRC_VER_MINOR 0 /* Command IDs */ @@ -72,12 +72,14 @@ #define DPRC_CMDID_GET_RES_COUNT 0x15B #define DPRC_CMDID_GET_RES_IDS 0x15C #define DPRC_CMDID_GET_OBJ_REG 0x15E +#define DPRC_CMDID_OBJ_SET_IRQ 0x15F +#define DPRC_CMDID_OBJ_GET_IRQ 0x160 +#define DPRC_CMDID_SET_OBJ_LABEL 0x161 #define DPRC_CMDID_CONNECT 0x167 #define DPRC_CMDID_DISCONNECT 0x168 #define DPRC_CMDID_GET_POOL 0x169 #define DPRC_CMDID_GET_POOL_COUNT 0x16A -#define DPRC_CMDID_GET_PORTAL_PADDR 0x16B #define DPRC_CMDID_GET_CONNECTION 0x16C diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c index 85ec91b..6bd20c0 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -500,6 +500,19 @@ static int register_dprc_irq_handlers(struct fsl_mc_device *mc_dev) for (i = 0; i < ARRAY_SIZE(irq_handlers); i++) { irq = mc_dev->irqs[i]; + + if (WARN_ON(irq->dev_irq_index != i)) + return -EINVAL; + + /* + * NOTE: Normally, devm_request_threaded_irq() programs the MSI + * physically in the device (by invoking a device-specific + * callback). However, for MC IRQs, we have to program the MSI + * outside of this callback in an object-specific way, because + * the object-independent way of programming MSI is not reliable + * yet. For now, the MC callback just sets the msi_paddr and + * msi_value fields of the irq structure. + */ error = devm_request_threaded_irq(&mc_dev->dev, irq->irq_number, irq_handlers[i].irq_handler, @@ -518,18 +531,17 @@ static int register_dprc_irq_handlers(struct fsl_mc_device *mc_dev) /* * Program the MSI (paddr, value) pair in the device: - * - * TODO: This needs to be moved to mc_bus_msi_domain_write_msg() - * when the MC object-independent dprc_set_irq() flib API - * becomes available */ - error = dprc_set_irq(mc_dev->mc_io, mc_dev->mc_handle, - i, irq->msi_paddr, + error = dprc_set_irq(mc_dev->mc_io, + mc_dev->mc_handle, + i, + irq->msi_paddr, irq->msi_value, irq->irq_number); if (error < 0) { dev_err(&mc_dev->dev, - "mc_set_irq() failed: %d\n", error); + "dprc_set_irq() failed for IRQ %u: %d\n", + i, error); return error; } } @@ -620,14 +632,28 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) int error; size_t region_size; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); + bool mc_io_created = false; + bool dev_root_set = false; if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) return -EINVAL; - if (!mc_dev->mc_io) { + if (mc_dev->mc_io) { /* - * This is a child DPRC: + * This is the root DPRC */ + if (WARN_ON(fsl_mc_bus_type.dev_root)) + return -EINVAL; + + fsl_mc_bus_type.dev_root = &mc_dev->dev; + dev_root_set = true; + } else { + /* + * This is a child DPRC + */ + if (WARN_ON(!fsl_mc_bus_type.dev_root)) + return -EINVAL; + if (WARN_ON(mc_dev->obj_desc.region_count == 0)) return -EINVAL; @@ -640,6 +666,8 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) NULL, 0, &mc_dev->mc_io); if (error < 0) return error; + + mc_io_created = true; } error = dprc_open(mc_dev->mc_io, mc_dev->obj_desc.id, @@ -663,19 +691,27 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) */ error = dprc_setup_irqs(mc_dev); if (error < 0) - goto error_cleanup_open; + goto error_cleanup_dprc_scan; dev_info(&mc_dev->dev, "DPRC device bound to driver"); return 0; -error_cleanup_open: - if (mc_bus->irq_resources) - fsl_mc_cleanup_irq_pool(mc_bus); +error_cleanup_dprc_scan: + device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); + fsl_mc_cleanup_irq_pool(mc_bus); +error_cleanup_open: (void)dprc_close(mc_dev->mc_io, mc_dev->mc_handle); error_cleanup_mc_io: - fsl_destroy_mc_io(mc_dev->mc_io); + if (mc_io_created) { + fsl_destroy_mc_io(mc_dev->mc_io); + mc_dev->mc_io = NULL; + } + + if (dev_root_set) + fsl_mc_bus_type.dev_root = NULL; + return error; } diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c index 19b26e6..4a5f13a 100644 --- a/drivers/staging/fsl-mc/bus/dprc.c +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -34,7 +34,7 @@ #include "../include/dprc.h" #include "dprc-cmd.h" -int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) +int dprc_open(struct fsl_mc_io *mc_io, int container_id, u16 *token) { struct mc_command cmd = { 0 }; int err; @@ -56,7 +56,7 @@ int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) } EXPORT_SYMBOL(dprc_open); -int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) +int dprc_close(struct fsl_mc_io *mc_io, u16 token) { struct mc_command cmd = { 0 }; @@ -70,10 +70,10 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) EXPORT_SYMBOL(dprc_close); int dprc_create_container(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, struct dprc_cfg *cfg, int *child_container_id, - uint64_t *child_portal_paddr) + u64 *child_portal_offset) { struct mc_command cmd = { 0 }; int err; @@ -82,6 +82,22 @@ int dprc_create_container(struct fsl_mc_io *mc_io, cmd.params[0] |= mc_enc(32, 16, cfg->icid); cmd.params[0] |= mc_enc(0, 32, cfg->options); cmd.params[1] |= mc_enc(32, 32, cfg->portal_id); + cmd.params[2] |= mc_enc(0, 8, cfg->label[0]); + cmd.params[2] |= mc_enc(8, 8, cfg->label[1]); + cmd.params[2] |= mc_enc(16, 8, cfg->label[2]); + cmd.params[2] |= mc_enc(24, 8, cfg->label[3]); + cmd.params[2] |= mc_enc(32, 8, cfg->label[4]); + cmd.params[2] |= mc_enc(40, 8, cfg->label[5]); + cmd.params[2] |= mc_enc(48, 8, cfg->label[6]); + cmd.params[2] |= mc_enc(56, 8, cfg->label[7]); + cmd.params[3] |= mc_enc(0, 8, cfg->label[8]); + cmd.params[3] |= mc_enc(8, 8, cfg->label[9]); + cmd.params[3] |= mc_enc(16, 8, cfg->label[10]); + cmd.params[3] |= mc_enc(24, 8, cfg->label[11]); + cmd.params[3] |= mc_enc(32, 8, cfg->label[12]); + cmd.params[3] |= mc_enc(40, 8, cfg->label[13]); + cmd.params[3] |= mc_enc(48, 8, cfg->label[14]); + cmd.params[3] |= mc_enc(56, 8, cfg->label[15]); cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT, MC_CMD_PRI_LOW, token); @@ -93,13 +109,13 @@ int dprc_create_container(struct fsl_mc_io *mc_io, /* retrieve response parameters */ *child_container_id = mc_dec(cmd.params[1], 0, 32); - *child_portal_paddr = mc_dec(cmd.params[2], 0, 64); + *child_portal_offset = mc_dec(cmd.params[2], 0, 64); return 0; } int dprc_destroy_container(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id) { struct mc_command cmd = { 0 }; @@ -114,7 +130,7 @@ int dprc_destroy_container(struct fsl_mc_io *mc_io, } int dprc_reset_container(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id) { struct mc_command cmd = { 0 }; @@ -129,11 +145,11 @@ int dprc_reset_container(struct fsl_mc_io *mc_io, } int dprc_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, + u16 token, + u8 irq_index, int *type, - uint64_t *irq_paddr, - uint32_t *irq_val, + u64 *irq_paddr, + u32 *irq_val, int *user_irq_id) { struct mc_command cmd = { 0 }; @@ -159,11 +175,44 @@ int dprc_get_irq(struct fsl_mc_io *mc_io, return 0; } +int dprc_obj_get_irq(struct fsl_mc_io *mc_io, + u16 token, + int obj_index, + u8 irq_index, + int *type, + u64 *irq_addr, + u32 *irq_val, + int *user_irq_id) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_OBJ_GET_IRQ, + MC_CMD_PRI_LOW, + token); + + cmd.params[0] |= mc_enc(0, 32, obj_index); + cmd.params[0] |= mc_enc(32, 8, irq_index); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + *irq_val = mc_dec(cmd.params[0], 0, 32); + *irq_addr = mc_dec(cmd.params[1], 0, 64); + *user_irq_id = mc_dec(cmd.params[2], 0, 32); + *type = mc_dec(cmd.params[2], 32, 32); + return 0; +} + int dprc_set_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint64_t irq_paddr, - uint32_t irq_val, + u16 token, + u8 irq_index, + u64 irq_paddr, + u32 irq_val, int user_irq_id) { struct mc_command cmd = { 0 }; @@ -181,10 +230,35 @@ int dprc_set_irq(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +int dprc_obj_set_irq(struct fsl_mc_io *mc_io, + u16 token, + int obj_index, + u8 irq_index, + u64 irq_addr, + u32 irq_val, + int user_irq_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_OBJ_SET_IRQ, + MC_CMD_PRI_LOW, + token); + + cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd.params[0] |= mc_enc(0, 32, irq_val); + cmd.params[1] |= mc_enc(0, 64, irq_addr); + cmd.params[2] |= mc_enc(0, 32, user_irq_id); + cmd.params[2] |= mc_enc(32, 32, obj_index); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + int dprc_get_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t *en) + u16 token, + u8 irq_index, + u8 *en) { struct mc_command cmd = { 0 }; int err; @@ -206,9 +280,9 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, } int dprc_set_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t en) + u16 token, + u8 irq_index, + u8 en) { struct mc_command cmd = { 0 }; @@ -223,9 +297,9 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, } int dprc_get_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *mask) + u16 token, + u8 irq_index, + u32 *mask) { struct mc_command cmd = { 0 }; int err; @@ -247,9 +321,9 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, } int dprc_set_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t mask) + u16 token, + u8 irq_index, + u32 mask) { struct mc_command cmd = { 0 }; @@ -264,9 +338,9 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, } int dprc_get_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *status) + u16 token, + u8 irq_index, + u32 *status) { struct mc_command cmd = { 0 }; int err; @@ -288,9 +362,9 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, } int dprc_clear_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t status) + u16 token, + u8 irq_index, + u32 status) { struct mc_command cmd = { 0 }; @@ -305,7 +379,7 @@ int dprc_clear_irq_status(struct fsl_mc_io *mc_io, } int dprc_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, struct dprc_attributes *attr) { struct mc_command cmd = { 0 }; @@ -333,10 +407,10 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, } int dprc_set_res_quota(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id, char *type, - uint16_t quota) + u16 quota) { struct mc_command cmd = { 0 }; @@ -367,10 +441,10 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, } int dprc_get_res_quota(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id, char *type, - uint16_t *quota) + u16 *quota) { struct mc_command cmd = { 0 }; int err; @@ -408,7 +482,7 @@ int dprc_get_res_quota(struct fsl_mc_io *mc_io, } int dprc_assign(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int container_id, struct dprc_res_req *res_req) { @@ -443,7 +517,7 @@ int dprc_assign(struct fsl_mc_io *mc_io, } int dprc_unassign(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id, struct dprc_res_req *res_req) { @@ -479,7 +553,7 @@ int dprc_unassign(struct fsl_mc_io *mc_io, } int dprc_get_pool_count(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int *pool_count) { struct mc_command cmd = { 0 }; @@ -501,7 +575,7 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io, } int dprc_get_pool(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int pool_index, char *type) { @@ -540,7 +614,7 @@ int dprc_get_pool(struct fsl_mc_io *mc_io, return 0; } -int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) +int dprc_get_obj_count(struct fsl_mc_io *mc_io, u16 token, int *obj_count) { struct mc_command cmd = { 0 }; int err; @@ -562,7 +636,7 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) EXPORT_SYMBOL(dprc_get_obj_count); int dprc_get_obj(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int obj_index, struct dprc_obj_desc *obj_desc) { @@ -604,13 +678,28 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, obj_desc->type[13] = mc_dec(cmd.params[4], 40, 8); obj_desc->type[14] = mc_dec(cmd.params[4], 48, 8); obj_desc->type[15] = '\0'; - + obj_desc->label[0] = mc_dec(cmd.params[5], 0, 8); + obj_desc->label[1] = mc_dec(cmd.params[5], 8, 8); + obj_desc->label[2] = mc_dec(cmd.params[5], 16, 8); + obj_desc->label[3] = mc_dec(cmd.params[5], 24, 8); + obj_desc->label[4] = mc_dec(cmd.params[5], 32, 8); + obj_desc->label[5] = mc_dec(cmd.params[5], 40, 8); + obj_desc->label[6] = mc_dec(cmd.params[5], 48, 8); + obj_desc->label[7] = mc_dec(cmd.params[5], 56, 8); + obj_desc->label[8] = mc_dec(cmd.params[6], 0, 8); + obj_desc->label[9] = mc_dec(cmd.params[6], 8, 8); + obj_desc->label[10] = mc_dec(cmd.params[6], 16, 8); + obj_desc->label[11] = mc_dec(cmd.params[6], 24, 8); + obj_desc->label[12] = mc_dec(cmd.params[6], 32, 8); + obj_desc->label[13] = mc_dec(cmd.params[6], 40, 8); + obj_desc->label[14] = mc_dec(cmd.params[6], 48, 8); + obj_desc->label[15] = '\0'; return 0; } EXPORT_SYMBOL(dprc_get_obj); int dprc_get_res_count(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, char *type, int *res_count) { @@ -652,7 +741,7 @@ int dprc_get_res_count(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dprc_get_res_count); int dprc_get_res_ids(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, char *type, struct dprc_res_ids_range_desc *range_desc) { @@ -696,36 +785,11 @@ int dprc_get_res_ids(struct fsl_mc_io *mc_io, } EXPORT_SYMBOL(dprc_get_res_ids); -int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, - uint16_t token, - int portal_id, - uint64_t *portal_addr) -{ - struct mc_command cmd = { 0 }; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_PORTAL_PADDR, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(0, 32, portal_id); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - *portal_addr = mc_dec(cmd.params[1], 0, 64); - - return 0; -} -EXPORT_SYMBOL(dprc_get_portal_paddr); - int dprc_get_obj_region(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, char *obj_type, int obj_id, - uint8_t region_index, + u8 region_index, struct dprc_region_desc *region_desc) { struct mc_command cmd = { 0 }; @@ -759,15 +823,48 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - region_desc->base_paddr = mc_dec(cmd.params[1], 0, 64); + region_desc->base_offset = mc_dec(cmd.params[1], 0, 64); region_desc->size = mc_dec(cmd.params[2], 0, 32); return 0; } EXPORT_SYMBOL(dprc_get_obj_region); +int dprc_set_obj_label(struct fsl_mc_io *mc_io, + u16 token, + int obj_index, + char *label) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_LABEL, + MC_CMD_PRI_LOW, token); + + cmd.params[0] |= mc_enc(0, 32, obj_index); + cmd.params[1] |= mc_enc(0, 8, label[0]); + cmd.params[1] |= mc_enc(8, 8, label[1]); + cmd.params[1] |= mc_enc(16, 8, label[2]); + cmd.params[1] |= mc_enc(24, 8, label[3]); + cmd.params[1] |= mc_enc(32, 8, label[4]); + cmd.params[1] |= mc_enc(40, 8, label[5]); + cmd.params[1] |= mc_enc(48, 8, label[6]); + cmd.params[1] |= mc_enc(56, 8, label[7]); + cmd.params[2] |= mc_enc(0, 8, label[8]); + cmd.params[2] |= mc_enc(8, 8, label[9]); + cmd.params[2] |= mc_enc(16, 8, label[10]); + cmd.params[2] |= mc_enc(24, 8, label[11]); + cmd.params[2] |= mc_enc(32, 8, label[12]); + cmd.params[2] |= mc_enc(40, 8, label[13]); + cmd.params[2] |= mc_enc(48, 8, label[14]); + cmd.params[2] |= mc_enc(56, 8, label[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + int dprc_connect(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, const struct dprc_endpoint *endpoint1, const struct dprc_endpoint *endpoint2) { @@ -819,7 +916,7 @@ int dprc_connect(struct fsl_mc_io *mc_io, } int dprc_disconnect(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, const struct dprc_endpoint *endpoint) { struct mc_command cmd = { 0 }; @@ -852,7 +949,7 @@ int dprc_disconnect(struct fsl_mc_io *mc_io, } int dprc_get_connection(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, const struct dprc_endpoint *endpoint1, struct dprc_endpoint *endpoint2, int *state) diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c b/drivers/staging/fsl-mc/bus/mc-allocator.c index aa8280a..e445f79 100644 --- a/drivers/staging/fsl-mc/bus/mc-allocator.c +++ b/drivers/staging/fsl-mc/bus/mc-allocator.c @@ -523,14 +523,20 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev) irqs[i] = to_fsl_mc_irq(resource); res_allocated_count++; + + WARN_ON(irqs[i]->mc_dev); + irqs[i]->mc_dev = mc_dev; + irqs[i]->dev_irq_index = i; } mc_dev->irqs = irqs; return 0; error_resource_alloc: - for (i = 0; i < res_allocated_count; i++) + for (i = 0; i < res_allocated_count; i++) { + irqs[i]->mc_dev = NULL; fsl_mc_resource_free(&irqs[i]->resource); + } return error; } @@ -545,8 +551,9 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev) int i; int irq_count; struct fsl_mc_bus *mc_bus; + struct fsl_mc_device_irq **irqs = mc_dev->irqs; - if (WARN_ON(!mc_dev->irqs)) + if (WARN_ON(!irqs)) return; irq_count = mc_dev->obj_desc.irq_count; @@ -559,8 +566,11 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev) if (WARN_ON(!mc_bus->irq_resources)) return; - for (i = 0; i < irq_count; i++) - fsl_mc_resource_free(&mc_dev->irqs[i]->resource); + for (i = 0; i < irq_count; i++) { + WARN_ON(!irqs[i]->mc_dev); + irqs[i]->mc_dev = NULL; + fsl_mc_resource_free(&irqs[i]->resource); + } mc_dev->irqs = NULL; } @@ -593,8 +603,8 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev) if (error < 0) goto error; - dev_info(&mc_dev->dev, - "Allocatable MC object device bound to fsl_mc_allocator driver"); + dev_dbg(&mc_dev->dev, + "Allocatable MC object device bound to fsl_mc_allocator driver"); return 0; error: @@ -616,8 +626,8 @@ static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev) if (error < 0) goto out; - dev_info(&mc_dev->dev, - "Allocatable MC object device unbound from fsl_mc_allocator driver"); + dev_dbg(&mc_dev->dev, + "Allocatable MC object device unbound from fsl_mc_allocator driver"); error = 0; out: return error; diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c index 60e45be..e5ea3ea 100644 --- a/drivers/staging/fsl-mc/bus/mc-bus.c +++ b/drivers/staging/fsl-mc/bus/mc-bus.c @@ -55,9 +55,6 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) bool major_version_mismatch = false; bool minor_version_mismatch = false; - if (WARN_ON(!fsl_mc_bus_type.dev_root)) - goto out; - /* When driver_override is set, only bind to the matching driver */ if (mc_dev->driver_override) { found = !strcmp(mc_dev->driver_override, mc_drv->driver.name); @@ -70,9 +67,12 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) /* * If the object is not 'plugged' don't match. * Only exception is the root DPRC, which is a special case. + * + * NOTE: Only when this function is invoked for the root DPRC, + * mc_dev->mc_io is not NULL */ if ((mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED) == 0 && - &mc_dev->dev != fsl_mc_bus_type.dev_root) + !mc_dev->mc_io) goto out; /* @@ -315,7 +315,8 @@ common_cleanup: return error; } -static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr) +static int translate_mc_addr(enum fsl_mc_region_types mc_region_type, + u64 mc_offset, phys_addr_t *phys_addr) { int i; struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent); @@ -324,7 +325,7 @@ static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr) /* * Do identity mapping: */ - *phys_addr = mc_addr; + *phys_addr = mc_offset; return 0; } @@ -332,10 +333,11 @@ static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr) struct fsl_mc_addr_translation_range *range = &mc->translation_ranges[i]; - if (mc_addr >= range->start_mc_addr && - mc_addr < range->end_mc_addr) { + if (mc_region_type == range->mc_region_type && + mc_offset >= range->start_mc_offset && + mc_offset < range->end_mc_offset) { *phys_addr = range->start_phys_addr + - (mc_addr - range->start_mc_addr); + (mc_offset - range->start_mc_offset); return 0; } } @@ -351,6 +353,22 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, struct resource *regions; struct dprc_obj_desc *obj_desc = &mc_dev->obj_desc; struct device *parent_dev = mc_dev->dev.parent; + enum fsl_mc_region_types mc_region_type; + + if (strcmp(obj_desc->type, "dprc") == 0 || + strcmp(obj_desc->type, "dpmcp") == 0) { + mc_region_type = FSL_MC_PORTAL; + } else if (strcmp(obj_desc->type, "dpio") == 0) { + mc_region_type = FSL_QBMAN_PORTAL; + } else { + /* + * This function should not have been called for this MC object + * type, as this object type is not supposed to have MMIO + * regions + */ + WARN_ON(true); + return -EINVAL; + } regions = kmalloc_array(obj_desc->region_count, sizeof(regions[0]), GFP_KERNEL); @@ -370,14 +388,14 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, goto error_cleanup_regions; } - WARN_ON(region_desc.base_paddr == 0x0); WARN_ON(region_desc.size == 0); - error = translate_mc_addr(region_desc.base_paddr, + error = translate_mc_addr(mc_region_type, + region_desc.base_offset, ®ions[i].start); if (error < 0) { dev_err(parent_dev, - "Invalid MC address: %#llx (for %s.%d\'s region %d)\n", - region_desc.base_paddr, + "Invalid MC offset: %#llx (for %s.%d\'s region %d)\n", + region_desc.base_offset, obj_desc->type, obj_desc->id, i); goto error_cleanup_regions; } @@ -481,9 +499,6 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, } mc_io2 = mc_io; - - if (!fsl_mc_bus_type.dev_root) - fsl_mc_bus_type.dev_root = &mc_dev->dev; } error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid); @@ -674,6 +689,9 @@ void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus) struct fsl_mc_resource_pool *res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ]; + if (WARN_ON(!mc_bus->irq_resources)) + return; + if (WARN_ON(res_pool->max_count == 0)) return; @@ -778,12 +796,14 @@ static int get_mc_addr_translation_ranges(struct device *dev, for (i = 0; i < *num_ranges; ++i) { struct fsl_mc_addr_translation_range *range = &(*ranges)[i]; - range->start_mc_addr = of_read_number(cell, mc_addr_cells); + range->mc_region_type = of_read_number(cell, 1); + range->start_mc_offset = of_read_number(cell + 1, + mc_addr_cells - 1); cell += mc_addr_cells; range->start_phys_addr = of_read_number(cell, paddr_cells); cell += paddr_cells; - range->end_mc_addr = range->start_mc_addr + - of_read_number(cell, mc_size_cells); + range->end_mc_offset = range->start_mc_offset + + of_read_number(cell, mc_size_cells); cell += mc_size_cells; } diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c index 5737f59..f421411 100644 --- a/drivers/staging/fsl-mc/bus/mc-sys.c +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -256,11 +256,13 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) * TODO: When MC command completion interrupts are supported * call wait function here instead of usleep_range() */ - usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS, - MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS); + if (preemptible()) { + usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS, + MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS); + } if (time_after_eq(jiffies, jiffies_until_timeout)) { - pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n", + pr_debug("MC timed out (portal: %#llx, obj handle: %#x, command: %#x)\n", mc_io->portal_phys_addr, (unsigned int) MC_CMD_HDR_READ_TOKEN(cmd->header), diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h index 1b052b8..a38eb1a 100644 --- a/drivers/staging/fsl-mc/include/dpmng.h +++ b/drivers/staging/fsl-mc/include/dpmng.h @@ -41,11 +41,11 @@ struct fsl_mc_io; /** * Management Complex firmware version information */ -#define MC_VER_MAJOR 6 +#define MC_VER_MAJOR 7 #define MC_VER_MINOR 0 /** - * struct mc_versoin + * struct mc_version * @major: Major version number: incremented on API compatibility changes * @minor: Minor version number: incremented on API additions (that are * backward compatible); reset when major version is incremented diff --git a/drivers/staging/fsl-mc/include/dprc.h b/drivers/staging/fsl-mc/include/dprc.h index f1862a7..1646e63 100644 --- a/drivers/staging/fsl-mc/include/dprc.h +++ b/drivers/staging/fsl-mc/include/dprc.h @@ -43,7 +43,7 @@ struct fsl_mc_io; * container, in case the ICID is not selected by the user and should be * allocated by the DPRC from the pool of ICIDs. */ -#define DPRC_GET_ICID_FROM_POOL (uint16_t)(~(0)) +#define DPRC_GET_ICID_FROM_POOL (u16)(~(0)) /** * Set this value as the portal_id value in dprc_cfg structure when creating a @@ -62,7 +62,7 @@ struct fsl_mc_io; * * @warning Required before any operation on the object. */ -int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); +int dprc_open(struct fsl_mc_io *mc_io, int container_id, u16 *token); /** * dprc_close() - Close the control session of the object @@ -74,7 +74,7 @@ int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); * * Return: '0' on Success; Error code otherwise. */ -int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); +int dprc_close(struct fsl_mc_io *mc_io, u16 token); /** * Container general options @@ -99,7 +99,7 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); /* Object initialization allowed - software context associated with this * container is allowed to invoke object initialization operations. */ -#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 +#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 /* Topology change allowed - software context associated with this * container is allowed to invoke topology operations, such as attach/detach @@ -115,6 +115,9 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); /* AIOP - Indicates that container belongs to AIOP. */ #define DPRC_CFG_OPT_AIOP 0x00000020 +/* IRQ Config - Indicates that the container allowed to configure its IRQs. */ +#define DPRC_CFG_OPT_IRQ_CFG_ALLOWED 0x00000040 + /** * struct dprc_cfg - Container configuration options * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free @@ -122,11 +125,13 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free * portal ID is allocated by the DPRC * @options: Combination of 'DPRC_CFG_OPT_<X>' options + * @label: Object's label */ struct dprc_cfg { - uint16_t icid; + u16 icid; int portal_id; - uint64_t options; + u64 options; + char label[16]; }; /** @@ -135,16 +140,15 @@ struct dprc_cfg { * @token: Token of DPRC object * @cfg: Child container configuration * @child_container_id: Returned child container ID - * @child_portal_paddr: Returned base physical address of the - * child portal + * @child_portal_offset: Returned child portal offset from MC portal base * * Return: '0' on Success; Error code otherwise. */ int dprc_create_container(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, struct dprc_cfg *cfg, int *child_container_id, - uint64_t *child_portal_paddr); + u64 *child_portal_offset); /** * dprc_destroy_container() - Destroy child container. @@ -168,7 +172,7 @@ int dprc_create_container(struct fsl_mc_io *mc_io, * */ int dprc_destroy_container(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id); /** @@ -193,7 +197,7 @@ int dprc_destroy_container(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_reset_container(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id); /* IRQ */ @@ -201,16 +205,20 @@ int dprc_reset_container(struct fsl_mc_io *mc_io, /* Number of dprc's IRQs */ #define DPRC_NUM_OF_IRQS 1 -/* Object irq events */ +/* DPRC IRQ events */ -/* IRQ event - Indicates that a new object assigned to the container */ +/* IRQ event - Indicates that a new object added to the container */ #define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 -/* IRQ event - Indicates that an object was unassigned from the container */ + +/* IRQ event - Indicates that an object was removed from the container */ #define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 -/* IRQ event - Indicates that resources assigned to the container */ + +/* IRQ event - Indicates that resources added to the container */ #define DPRC_IRQ_EVENT_RES_ADDED 0x00000004 -/* IRQ event - Indicates that resources unassigned from the container */ + +/* IRQ event - Indicates that resources removed from the container */ #define DPRC_IRQ_EVENT_RES_REMOVED 0x00000008 + /* IRQ event - Indicates that one of the descendant containers that opened by * this container is destroyed */ @@ -237,10 +245,10 @@ int dprc_reset_container(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_set_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint64_t irq_addr, - uint32_t irq_val, + u16 token, + u8 irq_index, + u64 irq_addr, + u32 irq_val, int user_irq_id); /** @@ -258,11 +266,11 @@ int dprc_set_irq(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, + u16 token, + u8 irq_index, int *type, - uint64_t *irq_addr, - uint32_t *irq_val, + u64 *irq_addr, + u32 *irq_val, int *user_irq_id); /** @@ -280,9 +288,9 @@ int dprc_get_irq(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t en); + u16 token, + u8 irq_index, + u8 en); /** * dprc_get_irq_enable() - Get overall interrupt state. @@ -294,9 +302,9 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t *en); + u16 token, + u8 irq_index, + u8 *en); /** * dprc_set_irq_mask() - Set interrupt mask. @@ -314,9 +322,9 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t mask); + u16 token, + u8 irq_index, + u32 mask); /** * dprc_get_irq_mask() - Get interrupt mask. @@ -331,9 +339,9 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *mask); + u16 token, + u8 irq_index, + u32 *mask); /** * dprc_get_irq_status() - Get the current status of any pending interrupts. @@ -347,9 +355,9 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *status); + u16 token, + u8 irq_index, + u32 *status); /** * dprc_clear_irq_status() - Clear a pending interrupt's status @@ -363,9 +371,9 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_clear_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t status); + u16 token, + u8 irq_index, + u32 status); /** * struct dprc_attributes - Container attributes @@ -377,17 +385,17 @@ int dprc_clear_irq_status(struct fsl_mc_io *mc_io, */ struct dprc_attributes { int container_id; - uint16_t icid; + u16 icid; int portal_id; - uint64_t options; + u64 options; /** * struct version - DPRC version * @major: DPRC major version * @minor: DPRC minor version */ struct { - uint16_t major; - uint16_t minor; + u16 major; + u16 minor; } version; }; @@ -400,7 +408,7 @@ struct dprc_attributes { * Return: '0' on Success; Error code otherwise. */ int dprc_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, struct dprc_attributes *attributes); /** @@ -428,10 +436,10 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, * @warning Only the parent container is allowed to change a child policy. */ int dprc_set_res_quota(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id, char *type, - uint16_t quota); + u16 quota); /** * dprc_get_res_quota() - Gets the allocation policy of a specific @@ -448,10 +456,10 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_res_quota(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id, char *type, - uint16_t *quota); + u16 *quota); /* Resource request options */ @@ -492,8 +500,8 @@ int dprc_get_res_quota(struct fsl_mc_io *mc_io, */ struct dprc_res_req { char type[16]; - uint32_t num; - uint32_t options; + u32 num; + u32 options; int id_base_align; }; @@ -529,7 +537,7 @@ struct dprc_res_req { * Return: '0' on Success; Error code otherwise. */ int dprc_assign(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int container_id, struct dprc_res_req *res_req); @@ -548,7 +556,7 @@ int dprc_assign(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_unassign(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int child_container_id, struct dprc_res_req *res_req); @@ -561,7 +569,7 @@ int dprc_unassign(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_pool_count(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int *pool_count); /** @@ -579,7 +587,7 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_pool(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int pool_index, char *type); @@ -591,7 +599,7 @@ int dprc_get_pool(struct fsl_mc_io *mc_io, * * Return: '0' on Success; Error code otherwise. */ -int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count); +int dprc_get_obj_count(struct fsl_mc_io *mc_io, u16 token, int *obj_count); /* Objects Attributes Flags */ @@ -610,16 +618,18 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count); * @irq_count: Number of interrupts supported by the object * @region_count: Number of mappable regions supported by the object * @state: Object state: combination of DPRC_OBJ_STATE_ states + * @label: Object label */ struct dprc_obj_desc { char type[16]; int id; - uint16_t vendor; - uint16_t ver_major; - uint16_t ver_minor; - uint8_t irq_count; - uint8_t region_count; - uint32_t state; + u16 vendor; + u16 ver_major; + u16 ver_minor; + u8 irq_count; + u8 region_count; + u32 state; + char label[16]; }; /** @@ -637,11 +647,58 @@ struct dprc_obj_desc { * Return: '0' on Success; Error code otherwise. */ int dprc_get_obj(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, int obj_index, struct dprc_obj_desc *obj_desc); /** + * dprc_obj_set_irq() - Set IRQ information for object to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_index: Index of the object to set its IRQ (< obj_count returned from + * dprc_get_obj_count()) + * @irq_index: Identifies the interrupt index to configure + * @irq_addr: Address that must be written to + * signal a message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: Returned a user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_obj_set_irq(struct fsl_mc_io *mc_io, + u16 token, + int obj_index, + u8 irq_index, + u64 irq_addr, + u32 irq_val, + int user_irq_id); + +/** + * dprc_obj_get_irq() - Get IRQ information from object. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_index: Index of the object to get its IRQ (< obj_count returned from + * dprc_get_obj_count()) + * @irq_index: The interrupt index to configure + * @type: Returned interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_addr: Returned address that must be written to + * signal the message-based interrupt + * @irq_val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_obj_get_irq(struct fsl_mc_io *mc_io, + u16 token, + int obj_index, + u8 irq_index, + int *type, + u64 *irq_addr, + u32 *irq_val, + int *user_irq_id); + +/** * dprc_get_res_count() - Obtains the number of free resources that are assigned * to this container, by pool type * @mc_io: Pointer to MC portal's I/O object @@ -653,7 +710,7 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_res_count(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, char *type, int *res_count); @@ -694,32 +751,21 @@ struct dprc_res_ids_range_desc { * Return: '0' on Success; Error code otherwise. */ int dprc_get_res_ids(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, char *type, struct dprc_res_ids_range_desc *range_desc); /** - * dprc_get_portal_paddr() - Get the physical address of MC portals - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @portal_id: MC portal ID - * @portal_addr: The physical address of the MC portal ID - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, - uint16_t token, - int portal_id, - uint64_t *portal_addr); - -/** * struct dprc_region_desc - Mappable region descriptor - * @base_paddr: Region base physical address + * @base_offset: Region offset from region's base address. + * For DPMCP and DPRC objects, region base is offset from SoC MC portals + * base address; For DPIO, region base is offset from SoC QMan portals + * base address * @size: Region size (in bytes) */ struct dprc_region_desc { - uint64_t base_paddr; - uint32_t size; + u64 base_offset; + u32 size; }; /** @@ -734,13 +780,27 @@ struct dprc_region_desc { * Return: '0' on Success; Error code otherwise. */ int dprc_get_obj_region(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, char *obj_type, int obj_id, - uint8_t region_index, + u8 region_index, struct dprc_region_desc *region_desc); /** + * dprc_set_obj_label() - Set object label. + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @obj_index; Object index + * @label: The required label. The maximum length is 16 chars. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_obj_label(struct fsl_mc_io *mc_io, + u16 token, + int obj_index, + char *label); + +/** * struct dprc_endpoint - Endpoint description for link connect/disconnect * operations * @type: Endpoint object type: NULL terminated string @@ -764,7 +824,7 @@ struct dprc_endpoint { * Return: '0' on Success; Error code otherwise. */ int dprc_connect(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, const struct dprc_endpoint *endpoint1, const struct dprc_endpoint *endpoint2); @@ -777,14 +837,14 @@ int dprc_connect(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_disconnect(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, const struct dprc_endpoint *endpoint); /** * dprc_get_connection() - Get connected endpoint and link status if connection * exists. -* @mc_io Pointer to MC portal's I/O object -* @token Token of DPRC object +* @mc_io Pointer to MC portal's I/O object +* @token Token of DPRC object * @endpoint1 Endpoint 1 configuration parameters * @endpoint2 Returned endpoint 2 configuration parameters * @state: Returned link state: 1 - link is up, 0 - link is down @@ -792,7 +852,7 @@ int dprc_disconnect(struct fsl_mc_io *mc_io, * Return: '0' on Success; -ENAVAIL if connection does not exist. */ int dprc_get_connection(struct fsl_mc_io *mc_io, - uint16_t token, + u16 token, const struct dprc_endpoint *endpoint1, struct dprc_endpoint *endpoint2, int *state); diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-private.h index 5b9c8f2..8e02dc9 100644 --- a/drivers/staging/fsl-mc/include/mc-private.h +++ b/drivers/staging/fsl-mc/include/mc-private.h @@ -47,21 +47,36 @@ struct fsl_mc { struct fsl_mc_device *root_mc_bus_dev; struct irq_domain *irq_domain; - uint8_t num_translation_ranges; + u8 num_translation_ranges; struct fsl_mc_addr_translation_range *translation_ranges; }; /** + * enum mc_region_types - Types of MC MMIO regions + */ +enum fsl_mc_region_types { + FSL_MC_PORTAL = 0x0, + FSL_QBMAN_PORTAL, + + /* + * New offset types must be added above this entry + */ + FSL_NUM_MC_OFFSET_TYPES +}; + +/** * struct fsl_mc_addr_translation_range - bus to system address translation * range - * @start_mc_addr: Start MC address of the range being translated - * @end_mc_addr: MC address of the first byte after the range (last MC - * address of the range is end_mc_addr - 1) + * @mc_region_type: Type of MC region for the range being translated + * @start_mc_offset: Start MC offset of the range being translated + * @end_mc_offset: MC offset of the first byte after the range (last MC + * offset of the range is end_mc_offset - 1) * @start_phys_addr: system physical address corresponding to start_mc_addr */ struct fsl_mc_addr_translation_range { - uint64_t start_mc_addr; - uint64_t end_mc_addr; + enum fsl_mc_region_types mc_region_type; + u64 start_mc_offset; + u64 end_mc_offset; phys_addr_t start_phys_addr; }; @@ -115,6 +130,10 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, const char *driver_override, unsigned int *total_irq_count); +int dprc_lookup_object(struct fsl_mc_device *mc_bus_dev, + struct fsl_mc_device *child_dev, + u32 *child_obj_index); + int __init dprc_driver_init(void); void __exit dprc_driver_exit(void); diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h index 322b594..7fa2816 100644 --- a/drivers/staging/fsl-mc/include/mc.h +++ b/drivers/staging/fsl-mc/include/mc.h @@ -110,12 +110,16 @@ struct fsl_mc_resource { * @msi_paddr: message-based interrupt physical address * @msi_value: message-based interrupt data value * @irq_number: Linux IRQ number assigned to the interrupt + * @mc_dev: MC object device that owns this interrupt + * @dev_irq_index: device-relative IRQ index * @resource: MC generic resource associated with the interrupt */ struct fsl_mc_device_irq { phys_addr_t msi_paddr; u32 msi_value; u32 irq_number; + struct fsl_mc_device *mc_dev; + u8 dev_irq_index; struct fsl_mc_resource resource; }; -- 2.3.3 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel