From b4b7ff4b08e691656c9d77c758fc355833128ac0 Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Wed, 20 Jan 2016 14:01:31 -0300 Subject: Linux-libre 4.4-gnu --- drivers/staging/fsl-mc/bus/dpbp.c | 356 +++++++++-- drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 81 +-- drivers/staging/fsl-mc/bus/dpmcp.c | 316 +++++++-- drivers/staging/fsl-mc/bus/dpmcp.h | 220 ++----- drivers/staging/fsl-mc/bus/dpmng.c | 31 +- drivers/staging/fsl-mc/bus/dprc-cmd.h | 7 +- drivers/staging/fsl-mc/bus/dprc-driver.c | 12 +- drivers/staging/fsl-mc/bus/dprc.c | 955 ++++++++++++++++++++++++---- drivers/staging/fsl-mc/bus/mc-allocator.c | 98 ++- drivers/staging/fsl-mc/bus/mc-bus.c | 136 +++- drivers/staging/fsl-mc/bus/mc-sys.c | 208 +++++- drivers/staging/fsl-mc/include/dpbp-cmd.h | 2 +- drivers/staging/fsl-mc/include/dpbp.h | 303 +++------ drivers/staging/fsl-mc/include/dpcon-cmd.h | 62 +- drivers/staging/fsl-mc/include/dpmng.h | 33 +- drivers/staging/fsl-mc/include/dprc.h | 638 ++++++------------- drivers/staging/fsl-mc/include/mc-cmd.h | 52 +- drivers/staging/fsl-mc/include/mc-private.h | 19 +- drivers/staging/fsl-mc/include/mc-sys.h | 55 +- drivers/staging/fsl-mc/include/mc.h | 18 +- 20 files changed, 2194 insertions(+), 1408 deletions(-) (limited to 'drivers/staging/fsl-mc') diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c index d99ab6d0b..2d97173f8 100644 --- a/drivers/staging/fsl-mc/bus/dpbp.c +++ b/drivers/staging/fsl-mc/bus/dpbp.c @@ -34,14 +34,34 @@ #include "../include/dpbp.h" #include "../include/dpbp-cmd.h" -int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) +/** + * dpbp_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @dpbp_id: DPBP unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpbp_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int dpbp_id, + u16 *token) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN, - MC_CMD_PRI_LOW, 0); + cmd_flags, 0); cmd.params[0] |= mc_enc(0, 32, dpbp_id); /* send command to mc*/ @@ -56,12 +76,25 @@ int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) } EXPORT_SYMBOL(dpbp_open); -int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpbp_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, cmd_flags, token); /* send command to mc*/ @@ -69,9 +102,31 @@ int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token) } EXPORT_SYMBOL(dpbp_close); +/** + * dpbp_create() - Create the DPBP object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @cfg: Configuration structure + * @token: Returned token; use in subsequent API calls + * + * Create the DPBP object, allocate required resources and + * perform required initialization. + * + * The object can be created either by declaring it in the + * DPL file, or by calling this function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent calls to + * this specific object. For objects that are created using the + * DPL file, call dpbp_open function to get an authentication + * token first. + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_create(struct fsl_mc_io *mc_io, + u32 cmd_flags, const struct dpbp_cfg *cfg, - uint16_t *token) + u16 *token) { struct mc_command cmd = { 0 }; int err; @@ -80,7 +135,7 @@ int dpbp_create(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CREATE, - MC_CMD_PRI_LOW, 0); + cmd_flags, 0); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -93,24 +148,44 @@ int dpbp_create(struct fsl_mc_io *mc_io, return 0; } -int dpbp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpbp_destroy() - Destroy the DPBP object and release all its resources. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * + * Return: '0' on Success; error code otherwise. + */ +int dpbp_destroy(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DESTROY, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpbp_enable() - Enable the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_enable(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, MC_CMD_PRI_LOW, + cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, cmd_flags, token); /* send command to mc*/ @@ -118,25 +193,47 @@ int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token) } EXPORT_SYMBOL(dpbp_enable); -int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpbp_disable() - Disable the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_disable(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } EXPORT_SYMBOL(dpbp_disable); -int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en) +/** + * dpbp_is_enabled() - Check if the DPBP is enabled. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @en: Returns '1' if object is enabled; '0' otherwise + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_is_enabled(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + int *en) { struct mc_command cmd = { 0 }; int err; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, MC_CMD_PRI_LOW, + cmd.header = mc_encode_cmd_header(DPBP_CMDID_IS_ENABLED, cmd_flags, token); /* send command to mc*/ @@ -150,53 +247,83 @@ int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en) return 0; } -int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpbp_reset() - Reset the DPBP, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpbp_reset(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dpbp_set_irq() - Set IRQ information for the DPBP to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: Identifies the interrupt index to configure + * @irq_cfg: IRQ configuration + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_set_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint64_t irq_paddr, - uint32_t irq_val, - int user_irq_id) + u32 cmd_flags, + u16 token, + u8 irq_index, + struct dpbp_irq_cfg *irq_cfg) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 8, irq_index); - cmd.params[0] |= mc_enc(32, 32, irq_val); - cmd.params[1] |= mc_enc(0, 64, irq_paddr); - cmd.params[2] |= mc_enc(0, 32, user_irq_id); + cmd.params[0] |= mc_enc(32, 32, irq_cfg->val); + cmd.params[1] |= mc_enc(0, 64, irq_cfg->addr); + cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dpbp_get_irq() - Get IRQ information from the DPBP. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @type: Interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_cfg: IRQ attributes + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, + u32 cmd_flags, + u16 token, + u8 irq_index, int *type, - uint64_t *irq_paddr, - uint32_t *irq_val, - int *user_irq_id) + struct dpbp_irq_cfg *irq_cfg) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -205,23 +332,39 @@ int dpbp_get_irq(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *irq_val = (uint32_t)mc_dec(cmd.params[0], 0, 32); - *irq_paddr = (uint64_t)mc_dec(cmd.params[1], 0, 64); - *user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32); + irq_cfg->addr = (u64)mc_dec(cmd.params[1], 0, 64); + irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); *type = (int)mc_dec(cmd.params[2], 32, 32); return 0; } +/** + * dpbp_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t en) + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 en) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 8, en); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -229,17 +372,28 @@ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpbp_get_irq_enable() - Get overall interrupt state + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t *en) + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 *en) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -248,20 +402,37 @@ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *en = (uint8_t)mc_dec(cmd.params[0], 0, 8); + *en = (u8)mc_dec(cmd.params[0], 0, 8); return 0; } +/** + * dpbp_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @mask: Event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting IRQ + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t mask) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 mask) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, mask); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -269,17 +440,31 @@ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpbp_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *mask) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *mask) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -288,21 +473,35 @@ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *mask = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *mask = (u32)mc_dec(cmd.params[0], 0, 32); return 0; } +/** + * dpbp_get_irq_status() - Get the current status of any pending interrupts. + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *status) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *status) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -311,20 +510,34 @@ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *status = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *status = (u32)mc_dec(cmd.params[0], 0, 32); return 0; } +/** + * dpbp_clear_irq_status() - Clear a pending interrupt's status + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @irq_index: The interrupt index to configure + * @status: Bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t status) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 status) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, status); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -332,8 +545,19 @@ int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpbp_get_attributes - Retrieve DPBP attributes. + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPBP object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise. + */ int dpbp_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, struct dpbp_attr *attr) { struct mc_command cmd = { 0 }; @@ -341,7 +565,7 @@ int dpbp_get_attributes(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -349,10 +573,10 @@ int dpbp_get_attributes(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - attr->bpid = (uint16_t)mc_dec(cmd.params[0], 16, 16); + attr->bpid = (u16)mc_dec(cmd.params[0], 16, 16); attr->id = (int)mc_dec(cmd.params[0], 32, 32); - attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16); - attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16); + attr->version.major = (u16)mc_dec(cmd.params[1], 0, 16); + attr->version.minor = (u16)mc_dec(cmd.params[1], 16, 16); return 0; } EXPORT_SYMBOL(dpbp_get_attributes); diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h index 57f326b60..a87e9f84f 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h @@ -34,7 +34,7 @@ /* DPMCP Version */ #define DPMCP_VER_MAJOR 2 -#define DPMCP_VER_MINOR 0 +#define DPMCP_VER_MINOR 1 /* Command IDs */ #define DPMCP_CMDID_CLOSE 0x800 @@ -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/dpmcp.c b/drivers/staging/fsl-mc/bus/dpmcp.c index 6b9da5b7f..b0248f574 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.c +++ b/drivers/staging/fsl-mc/bus/dpmcp.c @@ -34,14 +34,34 @@ #include "dpmcp.h" #include "dpmcp-cmd.h" -int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token) +/** + * dpmcp_open() - Open a control session for the specified object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @dpmcp_id: DPMCP unique ID + * @token: Returned token; use in subsequent API calls + * + * This function can be used to open a control session for an + * already created object; an object may have been declared in + * the DPL or by calling the dpmcp_create function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent commands for + * this specific object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int dpmcp_id, + u16 *token) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_OPEN, - MC_CMD_PRI_LOW, 0); + cmd_flags, 0); cmd.params[0] |= mc_enc(0, 32, dpmcp_id); /* send command to mc*/ @@ -55,28 +75,63 @@ int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token) return err; } -int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpmcp_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, MC_CMD_PRI_HIGH, - token); + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, + cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dpmcp_create() - Create the DPMCP object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @cfg: Configuration structure + * @token: Returned token; use in subsequent API calls + * + * Create the DPMCP object, allocate required resources and + * perform required initialization. + * + * The object can be created either by declaring it in the + * DPL file, or by calling this function. + * This function returns a unique authentication token, + * associated with the specific object ID and the specific MC + * portal; this token must be used in all subsequent calls to + * this specific object. For objects that are created using the + * DPL file, call dpmcp_open function to get an authentication + * token first. + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_create(struct fsl_mc_io *mc_io, + u32 cmd_flags, const struct dpmcp_cfg *cfg, - uint16_t *token) + u16 *token) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CREATE, - MC_CMD_PRI_LOW, 0); + cmd_flags, 0); cmd.params[0] |= mc_enc(0, 32, cfg->portal_id); /* send command to mc*/ @@ -90,65 +145,105 @@ int dpmcp_create(struct fsl_mc_io *mc_io, return 0; } -int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpmcp_destroy() - Destroy the DPMCP object and release all its resources. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * + * Return: '0' on Success; error code otherwise. + */ +int dpmcp_destroy(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_DESTROY, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token) +/** + * dpmcp_reset() - Reset the DPMCP, returns the object to initial state. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmcp_reset(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_RESET, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: Identifies the interrupt index to configure + * @irq_cfg: IRQ configuration + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_set_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint64_t irq_addr, - uint32_t irq_val, - int user_irq_id) + u32 cmd_flags, + u16 token, + u8 irq_index, + struct dpmcp_irq_cfg *irq_cfg) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 8, irq_index); - cmd.params[0] |= mc_enc(32, 32, irq_val); - cmd.params[1] |= mc_enc(0, 64, irq_addr); - cmd.params[2] |= mc_enc(0, 32, user_irq_id); + cmd.params[0] |= mc_enc(32, 32, irq_cfg->val); + cmd.params[1] |= mc_enc(0, 64, irq_cfg->paddr); + cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dpmcp_get_irq() - Get IRQ information from the DPMCP. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @type: Interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_cfg: IRQ attributes + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - int *type, - uint64_t *irq_addr, - uint32_t *irq_val, - int *user_irq_id) + u32 cmd_flags, + u16 token, + u8 irq_index, + int *type, + struct dpmcp_irq_cfg *irq_cfg) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -157,23 +252,39 @@ int dpmcp_get_irq(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *irq_val = (uint32_t)mc_dec(cmd.params[0], 0, 32); - *irq_addr = (uint64_t)mc_dec(cmd.params[1], 0, 64); - *user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32); + irq_cfg->paddr = (u64)mc_dec(cmd.params[1], 0, 64); + irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); *type = (int)mc_dec(cmd.params[2], 32, 32); return 0; } +/** + * dpmcp_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t en) + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 en) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 8, en); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -181,17 +292,28 @@ int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpmcp_get_irq_enable() - Get overall interrupt state + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t *en) + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 *en) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -200,20 +322,37 @@ int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *en = (uint8_t)mc_dec(cmd.params[0], 0, 8); + *en = (u8)mc_dec(cmd.params[0], 0, 8); return 0; } +/** + * dpmcp_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @mask: Event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting IRQ + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t mask) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 mask) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_SET_IRQ_MASK, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, mask); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -221,17 +360,31 @@ int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpmcp_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *mask) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *mask) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_MASK, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -240,21 +393,35 @@ int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *mask = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *mask = (u32)mc_dec(cmd.params[0], 0, 32); return 0; } +/** + * dpmcp_get_irq_status() - Get the current status of any pending interrupts. + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *status) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *status) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_IRQ_STATUS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -263,20 +430,34 @@ int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *status = (uint32_t)mc_dec(cmd.params[0], 0, 32); + *status = (u32)mc_dec(cmd.params[0], 0, 32); return 0; } +/** + * dpmcp_clear_irq_status() - Clear a pending interrupt's status + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @irq_index: The interrupt index to configure + * @status: Bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t status) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 status) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLEAR_IRQ_STATUS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, status); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -284,16 +465,27 @@ int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dpmcp_get_attributes - Retrieve DPMCP attributes. + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPMCP object + * @attr: Returned object's attributes + * + * Return: '0' on Success; Error code otherwise. + */ int dpmcp_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, - struct dpmcp_attr *attr) + u32 cmd_flags, + u16 token, + struct dpmcp_attr *attr) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_ATTR, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -302,7 +494,7 @@ int dpmcp_get_attributes(struct fsl_mc_io *mc_io, /* retrieve response parameters */ attr->id = (int)mc_dec(cmd.params[0], 32, 32); - attr->version.major = (uint16_t)mc_dec(cmd.params[1], 0, 16); - attr->version.minor = (uint16_t)mc_dec(cmd.params[1], 16, 16); + attr->version.major = (u16)mc_dec(cmd.params[1], 0, 16); + attr->version.minor = (u16)mc_dec(cmd.params[1], 16, 16); return 0; } diff --git a/drivers/staging/fsl-mc/bus/dpmcp.h b/drivers/staging/fsl-mc/bus/dpmcp.h index 5e7c21952..6df351f0c 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.h +++ b/drivers/staging/fsl-mc/bus/dpmcp.h @@ -38,41 +38,20 @@ struct fsl_mc_io; -/** - * dpmcp_open() - Open a control session for the specified object. - * @mc_io: Pointer to MC portal's I/O object - * @dpmcp_id: DPMCP unique ID - * @token: Returned token; use in subsequent API calls - * - * This function can be used to open a control session for an - * already created object; an object may have been declared in - * the DPL or by calling the dpmcp_create function. - * This function returns a unique authentication token, - * associated with the specific object ID and the specific MC - * portal; this token must be used in all subsequent commands for - * this specific object - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token); +int dpmcp_open(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + int dpmcp_id, + uint16_t *token); /* Get portal ID from pool */ #define DPMCP_GET_PORTAL_ID_FROM_POOL (-1) -/** - * dpmcp_close() - Close the control session of the object - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * - * After this function is called, no further operations are - * allowed on the object without opening a new control session. - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token); +int dpmcp_close(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); /** - * struct dpmcp_cfg() - Structure representing DPMCP configuration + * struct dpmcp_cfg - Structure representing DPMCP configuration * @portal_id: Portal ID; 'DPMCP_GET_PORTAL_ID_FROM_POOL' to get the portal ID * from pool */ @@ -80,199 +59,82 @@ struct dpmcp_cfg { int portal_id; }; -/** - * dpmcp_create() - Create the DPMCP object. - * @mc_io: Pointer to MC portal's I/O object - * @cfg: Configuration structure - * @token: Returned token; use in subsequent API calls - * - * Create the DPMCP object, allocate required resources and - * perform required initialization. - * - * The object can be created either by declaring it in the - * DPL file, or by calling this function. - * This function returns a unique authentication token, - * associated with the specific object ID and the specific MC - * portal; this token must be used in all subsequent calls to - * this specific object. For objects that are created using the - * DPL file, call dpmcp_open function to get an authentication - * token first. - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_create(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, const struct dpmcp_cfg *cfg, uint16_t *token); -/** - * dpmcp_destroy() - Destroy the DPMCP object and release all its resources. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * - * Return: '0' on Success; error code otherwise. - */ -int dpmcp_destroy(struct fsl_mc_io *mc_io, uint16_t token); +int dpmcp_destroy(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); -/** - * dpmcp_reset() - Reset the DPMCP, returns the object to initial state. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_reset(struct fsl_mc_io *mc_io, uint16_t token); +int dpmcp_reset(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); /* IRQ */ -/*! - * @name dpmcp IRQ Index and Events - */ +/* IRQ Index */ #define DPMCP_IRQ_INDEX 0 -/*!< Irq index */ +/* irq event - Indicates that the link state changed */ #define DPMCP_IRQ_EVENT_CMD_DONE 0x00000001 -/*!< irq event - Indicates that the link state changed */ -/* @} */ /** - * dpmcp_set_irq() - Set IRQ information for the DPMCP to trigger an interrupt. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @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 + * struct dpmcp_irq_cfg - IRQ configuration + * @paddr: Address that must be written to signal a message-based interrupt + * @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. */ +struct dpmcp_irq_cfg { + uint64_t paddr; + uint32_t val; + int user_irq_id; +}; + int dpmcp_set_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, - uint64_t irq_addr, - uint32_t irq_val, - int user_irq_id); + struct dpmcp_irq_cfg *irq_cfg); -/** - * dpmcp_get_irq() - Get IRQ information from the DPMCP. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @type: 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 dpmcp_get_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, int *type, - uint64_t *irq_addr, - uint32_t *irq_val, - int *user_irq_id); + struct dpmcp_irq_cfg *irq_cfg); -/** - * dpmcp_set_irq_enable() - Set overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @en: Interrupt state - enable = 1, disable = 0 - * - * Allows GPP software to control when interrupts are generated. - * Each interrupt can have up to 32 causes. The enable/disable control's the - * overall interrupt state. if the interrupt is disabled no causes will cause - * an interrupt. - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t en); -/** - * dpmcp_get_irq_enable() - Get overall interrupt state - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @en: Returned interrupt state - enable = 1, disable = 0 - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t *en); -/** - * dpmcp_set_irq_mask() - Set interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @mask: Event mask to trigger interrupt; - * each bit: - * 0 = ignore event - * 1 = consider event for asserting IRQ - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t mask); -/** - * dpmcp_get_irq_mask() - Get interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @mask: Returned event mask to trigger interrupt - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *mask); -/** - * dpmcp_get_irq_status() - Get the current status of any pending interrupts. - * - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @status: Returned interrupts status - one bit per cause: - * 0 = no interrupt pending - * 1 = interrupt pending - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *status); -/** - * dpmcp_clear_irq_status() - Clear a pending interrupt's status - * - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @irq_index: The interrupt index to configure - * @status: Bits to clear (W1C) - one bit per cause: - * 0 = don't change - * 1 = clear status bit - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t status); @@ -295,16 +157,8 @@ struct dpmcp_attr { } version; }; -/** - * dpmcp_get_attributes - Retrieve DPMCP attributes. - * - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPMCP object - * @attr: Returned object's attributes - * - * Return: '0' on Success; Error code otherwise. - */ int dpmcp_get_attributes(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, struct dpmcp_attr *attr); diff --git a/drivers/staging/fsl-mc/bus/dpmng.c b/drivers/staging/fsl-mc/bus/dpmng.c index 58328e811..f633fcd86 100644 --- a/drivers/staging/fsl-mc/bus/dpmng.c +++ b/drivers/staging/fsl-mc/bus/dpmng.c @@ -34,14 +34,26 @@ #include "../include/dpmng.h" #include "dpmng-cmd.h" -int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info) +/** + * mc_get_version() - Retrieves the Management Complex firmware + * version information + * @mc_io: Pointer to opaque I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @mc_ver_info: Returned version information structure + * + * Return: '0' on Success; Error code otherwise. + */ +int mc_get_version(struct fsl_mc_io *mc_io, + u32 cmd_flags, + struct mc_version *mc_ver_info) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION, - MC_CMD_PRI_LOW, 0); + cmd_flags, + 0); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -56,14 +68,25 @@ int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info) return 0; } -int dpmng_get_container_id(struct fsl_mc_io *mc_io, int *container_id) +/** + * dpmng_get_container_id() - Get container ID associated with a given portal. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @container_id: Requested container ID + * + * Return: '0' on Success; Error code otherwise. + */ +int dpmng_get_container_id(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int *container_id) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_CONT_ID, - MC_CMD_PRI_LOW, 0); + cmd_flags, + 0); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h index 09202489c..6552c2034 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,15 @@ #define DPRC_CMDID_GET_RES_COUNT 0x15B #define DPRC_CMDID_GET_RES_IDS 0x15C #define DPRC_CMDID_GET_OBJ_REG 0x15E +#define DPRC_CMDID_SET_OBJ_IRQ 0x15F +#define DPRC_CMDID_GET_OBJ_IRQ 0x160 +#define DPRC_CMDID_SET_OBJ_LABEL 0x161 +#define DPRC_CMDID_GET_OBJ_DESC 0x162 #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 35c06cff1..2c4cd70b4 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -126,7 +126,7 @@ static void check_plugged_state_change(struct fsl_mc_device *mc_dev, struct dprc_obj_desc *obj_desc) { int error; - uint32_t plugged_flag_at_mc = + u32 plugged_flag_at_mc = (obj_desc->state & DPRC_OBJ_STATE_PLUGGED); if (plugged_flag_at_mc != @@ -262,6 +262,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev) struct dprc_obj_desc *child_obj_desc_array = NULL; error = dprc_get_obj_count(mc_bus_dev->mc_io, + 0, mc_bus_dev->mc_handle, &num_child_objects); if (error < 0) { @@ -289,6 +290,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev) &child_obj_desc_array[i]; error = dprc_get_obj(mc_bus_dev->mc_io, + 0, mc_bus_dev->mc_handle, i, obj_desc); if (error < 0) { @@ -399,7 +401,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) return error; } - error = dprc_open(mc_dev->mc_io, mc_dev->obj_desc.id, + error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, &mc_dev->mc_handle); if (error < 0) { dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error); @@ -419,7 +421,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) return 0; error_cleanup_open: - (void)dprc_close(mc_dev->mc_io, mc_dev->mc_handle); + (void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); error_cleanup_mc_io: fsl_destroy_mc_io(mc_dev->mc_io); @@ -447,7 +449,7 @@ static int dprc_remove(struct fsl_mc_device *mc_dev) device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); dprc_cleanup_all_resource_pools(mc_dev); - error = dprc_close(mc_dev->mc_io, mc_dev->mc_handle); + error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); if (error < 0) dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error); @@ -480,7 +482,7 @@ int __init dprc_driver_init(void) return fsl_mc_driver_register(&dprc_driver); } -void __exit dprc_driver_exit(void) +void dprc_driver_exit(void) { fsl_mc_driver_unregister(&dprc_driver); } diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c index 19b26e630..381b9a96a 100644 --- a/drivers/staging/fsl-mc/bus/dprc.c +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -34,13 +34,27 @@ #include "../include/dprc.h" #include "dprc-cmd.h" -int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) +/** + * dprc_open() - Open DPRC object for use + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @container_id: Container ID to open + * @token: Returned token of DPRC object + * + * Return: '0' on Success; Error code otherwise. + * + * @warning Required before any operation on the object. + */ +int dprc_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int container_id, + u16 *token) { struct mc_command cmd = { 0 }; int err; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, MC_CMD_PRI_LOW, + cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags, 0); cmd.params[0] |= mc_enc(0, 32, container_id); @@ -56,12 +70,25 @@ 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) +/** + * dprc_close() - Close the control session of the object + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * + * After this function is called, no further operations are + * allowed on the object without opening a new control session. + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token) { struct mc_command cmd = { 0 }; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, MC_CMD_PRI_HIGH, + cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags, token); /* send command to mc*/ @@ -69,11 +96,23 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) } EXPORT_SYMBOL(dprc_close); +/** + * dprc_create_container() - Create child container + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @cfg: Child container configuration + * @child_container_id: Returned child container ID + * @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, + u32 cmd_flags, + 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,9 +121,25 @@ 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); + cmd_flags, token); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -93,55 +148,112 @@ 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; } +/** + * dprc_destroy_container() - Destroy child container. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @child_container_id: ID of the container to destroy + * + * This function terminates the child container, so following this call the + * child container ID becomes invalid. + * + * Notes: + * - All resources and objects of the destroyed container are returned to the + * parent container or destroyed if were created be the destroyed container. + * - This function destroy all the child containers of the specified + * container prior to destroying the container itself. + * + * warning: Only the parent container is allowed to destroy a child policy + * Container 0 can't be destroyed + * + * Return: '0' on Success; Error code otherwise. + * + */ int dprc_destroy_container(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, child_container_id); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dprc_reset_container - Reset child container. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @child_container_id: ID of the container to reset + * + * In case a software context crashes or becomes non-responsive, the parent + * may wish to reset its resources container before the software context is + * restarted. + * + * This routine informs all objects assigned to the child container that the + * container is being reset, so they may perform any cleanup operations that are + * needed. All objects handles that were owned by the child container shall be + * closed. + * + * Note that such request may be submitted even if the child software context + * has not crashed, but the resulting object cleanup operations will not be + * aware of that. + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_reset_container(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, child_container_id); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_irq() - Get IRQ information from the DPRC. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @type: Interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_cfg: IRQ attributes + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, + u32 cmd_flags, + u16 token, + u8 irq_index, int *type, - uint64_t *irq_paddr, - uint32_t *irq_val, - int *user_irq_id) + struct dprc_irq_cfg *irq_cfg) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -151,47 +263,67 @@ int dprc_get_irq(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - *irq_val = mc_dec(cmd.params[0], 0, 32); - *irq_paddr = mc_dec(cmd.params[1], 0, 64); - *user_irq_id = mc_dec(cmd.params[2], 0, 32); + irq_cfg->val = mc_dec(cmd.params[0], 0, 32); + irq_cfg->paddr = mc_dec(cmd.params[1], 0, 64); + irq_cfg->user_irq_id = mc_dec(cmd.params[2], 0, 32); *type = mc_dec(cmd.params[2], 32, 32); return 0; } +/** + * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: Identifies the interrupt index to configure + * @irq_cfg: IRQ configuration + * + * 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_paddr, - uint32_t irq_val, - int user_irq_id) + u32 cmd_flags, + u16 token, + u8 irq_index, + struct dprc_irq_cfg *irq_cfg) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ, - MC_CMD_PRI_LOW, + cmd_flags, 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_paddr); - cmd.params[2] |= mc_enc(0, 32, user_irq_id); + cmd.params[0] |= mc_enc(0, 32, irq_cfg->val); + cmd.params[1] |= mc_enc(0, 64, irq_cfg->paddr); + cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_irq_enable() - Get overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @en: Returned interrupt state - enable = 1, disable = 0 + * + * 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) + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 *en) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -205,16 +337,32 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, return 0; } +/** + * dprc_set_irq_enable() - Set overall interrupt state. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @en: Interrupt state - enable = 1, disable = 0 + * + * Allows GPP software to control when interrupts are generated. + * Each interrupt can have up to 32 causes. The enable/disable control's the + * overall interrupt state. if the interrupt is disabled no causes will cause + * an interrupt. + * + * 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) + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 en) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 8, en); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -222,17 +370,31 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_irq_mask() - Get interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @mask: Returned event mask to trigger interrupt + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * 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) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *mask) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_MASK, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -246,16 +408,33 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, return 0; } +/** + * dprc_set_irq_mask() - Set interrupt mask. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @mask: event mask to trigger interrupt; + * each bit: + * 0 = ignore event + * 1 = consider event for asserting irq + * + * Every interrupt can have up to 32 causes and the interrupt model supports + * masking/unmasking each cause independently + * + * 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) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 mask) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_IRQ_MASK, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, mask); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -263,17 +442,30 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_irq_status() - Get the current status of any pending interrupts. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @status: Returned interrupts status - one bit per cause: + * 0 = no interrupt pending + * 1 = interrupt pending + * + * 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) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *status) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(32, 8, irq_index); /* send command to mc*/ @@ -287,16 +479,29 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, return 0; } +/** + * dprc_clear_irq_status() - Clear a pending interrupt's status + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @irq_index: The interrupt index to configure + * @status: bits to clear (W1C) - one bit per cause: + * 0 = don't change + * 1 = clear status bit + * + * 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) + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 status) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLEAR_IRQ_STATUS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, status); cmd.params[0] |= mc_enc(32, 8, irq_index); @@ -304,8 +509,18 @@ int dprc_clear_irq_status(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_attributes() - Obtains container attributes + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @attributes Returned container attributes + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, struct dprc_attributes *attr) { struct mc_command cmd = { 0 }; @@ -313,7 +528,7 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR, - MC_CMD_PRI_LOW, + cmd_flags, token); /* send command to mc*/ @@ -332,17 +547,43 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, return 0; } +/** + * dprc_set_res_quota() - Set allocation policy for a specific resource/object + * type in a child container + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @child_container_id: ID of the child container + * @type: Resource/object type + * @quota: Sets the maximum number of resources of the selected type + * that the child container is allowed to allocate from its parent; + * when quota is set to -1, the policy is the same as container's + * general policy. + * + * Allocation policy determines whether or not a container may allocate + * resources from its parent. Each container has a 'global' allocation policy + * that is set when the container is created. + * + * This function sets allocation policy for a specific resource type. + * The default policy for all resource types matches the container's 'global' + * allocation policy. + * + * Return: '0' on Success; Error code otherwise. + * + * @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, + u32 cmd_flags, + u16 token, int child_container_id, char *type, - uint16_t quota) + u16 quota) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_RES_QUOTA, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, child_container_id); cmd.params[0] |= mc_enc(32, 16, quota); cmd.params[1] |= mc_enc(0, 8, type[0]); @@ -366,18 +607,34 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_res_quota() - Gets the allocation policy of a specific + * resource/object type in a child container + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @child_container_id; ID of the child container + * @type: resource/object type + * @quota: Returnes the maximum number of resources of the selected type + * that the child container is allowed to allocate from the parent; + * when quota is set to -1, the policy is the same as container's + * general policy. + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_res_quota(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id, char *type, - uint16_t *quota) + u16 *quota) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_QUOTA, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, child_container_id); cmd.params[1] |= mc_enc(0, 8, type[0]); cmd.params[1] |= mc_enc(8, 8, type[1]); @@ -407,8 +664,41 @@ int dprc_get_res_quota(struct fsl_mc_io *mc_io, return 0; } +/** + * dprc_assign() - Assigns objects or resource to a child container. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @container_id: ID of the child container + * @res_req: Describes the type and amount of resources to + * assign to the given container + * + * Assignment is usually done by a parent (this DPRC) to one of its child + * containers. + * + * According to the DPRC allocation policy, the assigned resources may be taken + * (allocated) from the container's ancestors, if not enough resources are + * available in the container itself. + * + * The type of assignment depends on the dprc_res_req options, as follows: + * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have + * the explicit base ID specified at the id_base_align field of res_req. + * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be + * aligned to the value given at id_base_align field of res_req. + * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment, + * and indicates that the object must be set to the plugged state. + * + * A container may use this function with its own ID in order to change a + * object state to plugged or unplugged. + * + * If IRQ information has been set in the child DPRC, it will signal an + * interrupt following every change in its object assignment. + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_assign(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int container_id, struct dprc_res_req *res_req) { @@ -416,7 +706,7 @@ int dprc_assign(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_ASSIGN, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, container_id); cmd.params[0] |= mc_enc(32, 32, res_req->options); cmd.params[1] |= mc_enc(0, 32, res_req->num); @@ -442,8 +732,24 @@ int dprc_assign(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_unassign() - Un-assigns objects or resources from a child container + * and moves them into this (parent) DPRC. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @child_container_id: ID of the child container + * @res_req: Describes the type and amount of resources to un-assign from + * the child container + * + * Un-assignment of objects can succeed only if the object is not in the + * plugged or opened state. + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_unassign(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id, struct dprc_res_req *res_req) { @@ -451,7 +757,7 @@ int dprc_unassign(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_UNASSIGN, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, child_container_id); cmd.params[0] |= mc_enc(32, 32, res_req->options); @@ -478,8 +784,18 @@ int dprc_unassign(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_get_pool_count() - Get the number of dprc's pools + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @mc_io: Pointer to MC portal's I/O object + * @token: Token of DPRC object + * @pool_count: Returned number of resource pools in the dprc + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_pool_count(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int *pool_count) { struct mc_command cmd = { 0 }; @@ -487,7 +803,7 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL_COUNT, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -500,8 +816,24 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io, return 0; } +/** + * dprc_get_pool() - Get the type (string) of a certain dprc's pool + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @pool_index; Index of the pool to be queried (< pool_count) + * @type: The type of the pool + * + * The pool types retrieved one by one by incrementing + * pool_index up to (not including) the value of pool_count returned + * from dprc_get_pool_count(). dprc_get_pool_count() must + * be called prior to dprc_get_pool(). + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_pool(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int pool_index, char *type) { @@ -510,7 +842,7 @@ int dprc_get_pool(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_POOL, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, pool_index); @@ -540,14 +872,26 @@ 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) +/** + * dprc_get_obj_count() - Obtains the number of objects in the DPRC + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_count: Number of objects assigned to the DPRC + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_count(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + int *obj_count) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT, - MC_CMD_PRI_LOW, token); + cmd_flags, token); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -561,8 +905,24 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) } EXPORT_SYMBOL(dprc_get_obj_count); +/** + * dprc_get_obj() - Get general information on an object + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_index: Index of the object to be queried (< obj_count) + * @obj_desc: Returns the requested object descriptor + * + * The object descriptors are retrieved one by one by incrementing + * obj_index up to (not including) the value of obj_count returned + * from dprc_get_obj_count(). dprc_get_obj_count() must + * be called prior to dprc_get_obj(). + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_obj(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int obj_index, struct dprc_obj_desc *obj_desc) { @@ -571,7 +931,7 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, obj_index); @@ -604,13 +964,253 @@ 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); +/** + * dprc_get_obj_desc() - Get object descriptor. + * + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_type: The type of the object to get its descriptor. + * @obj_id: The id of the object to get its descriptor + * @obj_desc: The returned descriptor to fill and return to the user + * + * Return: '0' on Success; Error code otherwise. + * + */ +int dprc_get_obj_desc(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + struct dprc_obj_desc *obj_desc) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_DESC, + cmd_flags, + token); + cmd.params[0] |= mc_enc(0, 32, obj_id); + cmd.params[1] |= mc_enc(0, 8, obj_type[0]); + cmd.params[1] |= mc_enc(8, 8, obj_type[1]); + cmd.params[1] |= mc_enc(16, 8, obj_type[2]); + cmd.params[1] |= mc_enc(24, 8, obj_type[3]); + cmd.params[1] |= mc_enc(32, 8, obj_type[4]); + cmd.params[1] |= mc_enc(40, 8, obj_type[5]); + cmd.params[1] |= mc_enc(48, 8, obj_type[6]); + cmd.params[1] |= mc_enc(56, 8, obj_type[7]); + cmd.params[2] |= mc_enc(0, 8, obj_type[8]); + cmd.params[2] |= mc_enc(8, 8, obj_type[9]); + cmd.params[2] |= mc_enc(16, 8, obj_type[10]); + cmd.params[2] |= mc_enc(24, 8, obj_type[11]); + cmd.params[2] |= mc_enc(32, 8, obj_type[12]); + cmd.params[2] |= mc_enc(40, 8, obj_type[13]); + cmd.params[2] |= mc_enc(48, 8, obj_type[14]); + cmd.params[2] |= mc_enc(56, 8, obj_type[15]); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + obj_desc->id = (int)mc_dec(cmd.params[0], 32, 32); + obj_desc->vendor = (u16)mc_dec(cmd.params[1], 0, 16); + obj_desc->vendor = (u8)mc_dec(cmd.params[1], 16, 8); + obj_desc->region_count = (u8)mc_dec(cmd.params[1], 24, 8); + obj_desc->state = (u32)mc_dec(cmd.params[1], 32, 32); + obj_desc->ver_major = (u16)mc_dec(cmd.params[2], 0, 16); + obj_desc->ver_minor = (u16)mc_dec(cmd.params[2], 16, 16); + obj_desc->type[0] = (char)mc_dec(cmd.params[3], 0, 8); + obj_desc->type[1] = (char)mc_dec(cmd.params[3], 8, 8); + obj_desc->type[2] = (char)mc_dec(cmd.params[3], 16, 8); + obj_desc->type[3] = (char)mc_dec(cmd.params[3], 24, 8); + obj_desc->type[4] = (char)mc_dec(cmd.params[3], 32, 8); + obj_desc->type[5] = (char)mc_dec(cmd.params[3], 40, 8); + obj_desc->type[6] = (char)mc_dec(cmd.params[3], 48, 8); + obj_desc->type[7] = (char)mc_dec(cmd.params[3], 56, 8); + obj_desc->type[8] = (char)mc_dec(cmd.params[4], 0, 8); + obj_desc->type[9] = (char)mc_dec(cmd.params[4], 8, 8); + obj_desc->type[10] = (char)mc_dec(cmd.params[4], 16, 8); + obj_desc->type[11] = (char)mc_dec(cmd.params[4], 24, 8); + obj_desc->type[12] = (char)mc_dec(cmd.params[4], 32, 8); + obj_desc->type[13] = (char)mc_dec(cmd.params[4], 40, 8); + obj_desc->type[14] = (char)mc_dec(cmd.params[4], 48, 8); + obj_desc->type[15] = (char)mc_dec(cmd.params[4], 56, 8); + obj_desc->label[0] = (char)mc_dec(cmd.params[5], 0, 8); + obj_desc->label[1] = (char)mc_dec(cmd.params[5], 8, 8); + obj_desc->label[2] = (char)mc_dec(cmd.params[5], 16, 8); + obj_desc->label[3] = (char)mc_dec(cmd.params[5], 24, 8); + obj_desc->label[4] = (char)mc_dec(cmd.params[5], 32, 8); + obj_desc->label[5] = (char)mc_dec(cmd.params[5], 40, 8); + obj_desc->label[6] = (char)mc_dec(cmd.params[5], 48, 8); + obj_desc->label[7] = (char)mc_dec(cmd.params[5], 56, 8); + obj_desc->label[8] = (char)mc_dec(cmd.params[6], 0, 8); + obj_desc->label[9] = (char)mc_dec(cmd.params[6], 8, 8); + obj_desc->label[10] = (char)mc_dec(cmd.params[6], 16, 8); + obj_desc->label[11] = (char)mc_dec(cmd.params[6], 24, 8); + obj_desc->label[12] = (char)mc_dec(cmd.params[6], 32, 8); + obj_desc->label[13] = (char)mc_dec(cmd.params[6], 40, 8); + obj_desc->label[14] = (char)mc_dec(cmd.params[6], 48, 8); + obj_desc->label[15] = (char)mc_dec(cmd.params[6], 56, 8); + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj_desc); + +/** + * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_type: Type of the object to set its IRQ + * @obj_id: ID of the object to set its IRQ + * @irq_index: The interrupt index to configure + * @irq_cfg: IRQ configuration + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_set_obj_irq(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + u8 irq_index, + struct dprc_irq_cfg *irq_cfg) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_IRQ, + cmd_flags, + token); + cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd.params[0] |= mc_enc(0, 32, irq_cfg->val); + cmd.params[1] |= mc_enc(0, 64, irq_cfg->paddr); + cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id); + cmd.params[2] |= mc_enc(32, 32, obj_id); + cmd.params[3] |= mc_enc(0, 8, obj_type[0]); + cmd.params[3] |= mc_enc(8, 8, obj_type[1]); + cmd.params[3] |= mc_enc(16, 8, obj_type[2]); + cmd.params[3] |= mc_enc(24, 8, obj_type[3]); + cmd.params[3] |= mc_enc(32, 8, obj_type[4]); + cmd.params[3] |= mc_enc(40, 8, obj_type[5]); + cmd.params[3] |= mc_enc(48, 8, obj_type[6]); + cmd.params[3] |= mc_enc(56, 8, obj_type[7]); + cmd.params[4] |= mc_enc(0, 8, obj_type[8]); + cmd.params[4] |= mc_enc(8, 8, obj_type[9]); + cmd.params[4] |= mc_enc(16, 8, obj_type[10]); + cmd.params[4] |= mc_enc(24, 8, obj_type[11]); + cmd.params[4] |= mc_enc(32, 8, obj_type[12]); + cmd.params[4] |= mc_enc(40, 8, obj_type[13]); + cmd.params[4] |= mc_enc(48, 8, obj_type[14]); + cmd.params[4] |= mc_enc(56, 8, obj_type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dprc_set_obj_irq); + +/** + * dprc_get_obj_irq() - Get IRQ information from object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_type: Type od the object to get its IRQ + * @obj_id: ID of the object to get its IRQ + * @irq_index: The interrupt index to configure + * @type: Interrupt type: 0 represents message interrupt + * type (both irq_addr and irq_val are valid) + * @irq_cfg: The returned IRQ attributes + * + * Return: '0' on Success; Error code otherwise. + */ +int dprc_get_obj_irq(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + u8 irq_index, + int *type, + struct dprc_irq_cfg *irq_cfg) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_IRQ, + cmd_flags, + token); + cmd.params[0] |= mc_enc(0, 32, obj_id); + cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd.params[1] |= mc_enc(0, 8, obj_type[0]); + cmd.params[1] |= mc_enc(8, 8, obj_type[1]); + cmd.params[1] |= mc_enc(16, 8, obj_type[2]); + cmd.params[1] |= mc_enc(24, 8, obj_type[3]); + cmd.params[1] |= mc_enc(32, 8, obj_type[4]); + cmd.params[1] |= mc_enc(40, 8, obj_type[5]); + cmd.params[1] |= mc_enc(48, 8, obj_type[6]); + cmd.params[1] |= mc_enc(56, 8, obj_type[7]); + cmd.params[2] |= mc_enc(0, 8, obj_type[8]); + cmd.params[2] |= mc_enc(8, 8, obj_type[9]); + cmd.params[2] |= mc_enc(16, 8, obj_type[10]); + cmd.params[2] |= mc_enc(24, 8, obj_type[11]); + cmd.params[2] |= mc_enc(32, 8, obj_type[12]); + cmd.params[2] |= mc_enc(40, 8, obj_type[13]); + cmd.params[2] |= mc_enc(48, 8, obj_type[14]); + cmd.params[2] |= mc_enc(56, 8, obj_type[15]); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32); + irq_cfg->paddr = (u64)mc_dec(cmd.params[1], 0, 64); + irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32); + *type = (int)mc_dec(cmd.params[2], 32, 32); + + return 0; +} +EXPORT_SYMBOL(dprc_get_obj_irq); + +/** + * 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 + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @type: pool type + * @res_count: Returned number of free resources of the given + * resource type that are assigned to this DPRC + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_res_count(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, char *type, int *res_count) { @@ -621,7 +1221,7 @@ int dprc_get_res_count(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[1] |= mc_enc(0, 8, type[0]); cmd.params[1] |= mc_enc(8, 8, type[1]); cmd.params[1] |= mc_enc(16, 8, type[2]); @@ -651,8 +1251,19 @@ int dprc_get_res_count(struct fsl_mc_io *mc_io, } EXPORT_SYMBOL(dprc_get_res_count); +/** + * dprc_get_res_ids() - Obtains IDs of free resources in the container + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @type: pool type + * @range_desc: range descriptor + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_res_ids(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, char *type, struct dprc_res_ids_range_desc *range_desc) { @@ -661,7 +1272,7 @@ int dprc_get_res_ids(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(42, 7, range_desc->iter_status); cmd.params[1] |= mc_enc(0, 32, range_desc->base_id); cmd.params[1] |= mc_enc(32, 32, range_desc->last_id); @@ -696,36 +1307,24 @@ 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); - +/** + * dprc_get_obj_region() - Get region information for a specified object. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_type; Object type as returned in dprc_get_obj() + * @obj_id: Unique object instance as returned in dprc_get_obj() + * @region_index: The specific region to query + * @region_desc: Returns the requested region descriptor + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_get_obj_region(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + 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 }; @@ -733,7 +1332,7 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG, - MC_CMD_PRI_LOW, token); + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, obj_id); cmd.params[0] |= mc_enc(48, 8, region_index); cmd.params[3] |= mc_enc(0, 8, obj_type[0]); @@ -759,28 +1358,113 @@ 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); +/** + * dprc_set_obj_label() - Set object label. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @obj_type: Object's type + * @obj_id: Object's ID + * @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, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + char *label) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPRC_CMDID_SET_OBJ_LABEL, + cmd_flags, + token); + + cmd.params[0] |= mc_enc(0, 32, obj_id); + 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]); + cmd.params[3] |= mc_enc(0, 8, obj_type[0]); + cmd.params[3] |= mc_enc(8, 8, obj_type[1]); + cmd.params[3] |= mc_enc(16, 8, obj_type[2]); + cmd.params[3] |= mc_enc(24, 8, obj_type[3]); + cmd.params[3] |= mc_enc(32, 8, obj_type[4]); + cmd.params[3] |= mc_enc(40, 8, obj_type[5]); + cmd.params[3] |= mc_enc(48, 8, obj_type[6]); + cmd.params[3] |= mc_enc(56, 8, obj_type[7]); + cmd.params[4] |= mc_enc(0, 8, obj_type[8]); + cmd.params[4] |= mc_enc(8, 8, obj_type[9]); + cmd.params[4] |= mc_enc(16, 8, obj_type[10]); + cmd.params[4] |= mc_enc(24, 8, obj_type[11]); + cmd.params[4] |= mc_enc(32, 8, obj_type[12]); + cmd.params[4] |= mc_enc(40, 8, obj_type[13]); + cmd.params[4] |= mc_enc(48, 8, obj_type[14]); + cmd.params[4] |= mc_enc(56, 8, obj_type[15]); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} +EXPORT_SYMBOL(dprc_set_obj_label); + +/** + * dprc_connect() - Connect two endpoints to create a network link between them + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @endpoint1: Endpoint 1 configuration parameters + * @endpoint2: Endpoint 2 configuration parameters + * @cfg: Connection configuration. The connection configuration is ignored for + * connections made to DPMAC objects, where rate is set according to + * MAC configuration. + * The committed rate is the guaranteed rate for the connection. + * The maximum rate is an upper limit allowed for the connection; it is + * expected to be equal or higher than the committed rate. + * When committed and maximum rates are both zero, the connection is set + * to "best effort" mode, having lower priority compared to connections + * with committed or maximum rates. + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_connect(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, const struct dprc_endpoint *endpoint1, - const struct dprc_endpoint *endpoint2) + const struct dprc_endpoint *endpoint2, + const struct dprc_connection_cfg *cfg) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, endpoint1->id); - cmd.params[0] |= mc_enc(32, 32, endpoint1->interface_id); + cmd.params[0] |= mc_enc(32, 32, endpoint1->if_id); cmd.params[1] |= mc_enc(0, 32, endpoint2->id); - cmd.params[1] |= mc_enc(32, 32, endpoint2->interface_id); + cmd.params[1] |= mc_enc(32, 32, endpoint2->if_id); cmd.params[2] |= mc_enc(0, 8, endpoint1->type[0]); cmd.params[2] |= mc_enc(8, 8, endpoint1->type[1]); cmd.params[2] |= mc_enc(16, 8, endpoint1->type[2]); @@ -797,6 +1481,8 @@ int dprc_connect(struct fsl_mc_io *mc_io, cmd.params[3] |= mc_enc(40, 8, endpoint1->type[13]); cmd.params[3] |= mc_enc(48, 8, endpoint1->type[14]); cmd.params[3] |= mc_enc(56, 8, endpoint1->type[15]); + cmd.params[4] |= mc_enc(0, 32, cfg->max_rate); + cmd.params[4] |= mc_enc(32, 32, cfg->committed_rate); cmd.params[5] |= mc_enc(0, 8, endpoint2->type[0]); cmd.params[5] |= mc_enc(8, 8, endpoint2->type[1]); cmd.params[5] |= mc_enc(16, 8, endpoint2->type[2]); @@ -818,18 +1504,28 @@ int dprc_connect(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** + * dprc_disconnect() - Disconnect one endpoint to remove its network connection + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPRC object + * @endpoint: Endpoint configuration parameters + * + * Return: '0' on Success; Error code otherwise. + */ int dprc_disconnect(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, const struct dprc_endpoint *endpoint) { struct mc_command cmd = { 0 }; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, endpoint->id); - cmd.params[0] |= mc_enc(32, 32, endpoint->interface_id); + cmd.params[0] |= mc_enc(32, 32, endpoint->if_id); cmd.params[1] |= mc_enc(0, 8, endpoint->type[0]); cmd.params[1] |= mc_enc(8, 8, endpoint->type[1]); cmd.params[1] |= mc_enc(16, 8, endpoint->type[2]); @@ -851,21 +1547,34 @@ int dprc_disconnect(struct fsl_mc_io *mc_io, return mc_send_command(mc_io, &cmd); } +/** +* dprc_get_connection() - Get connected endpoint and link status if connection +* exists. +* @mc_io: Pointer to MC portal's I/O object +* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' +* @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 +* +* Return: '0' on Success; -ENAVAIL if connection does not exist. +*/ int dprc_get_connection(struct fsl_mc_io *mc_io, - uint16_t token, - const struct dprc_endpoint *endpoint1, - struct dprc_endpoint *endpoint2, - int *state) + u32 cmd_flags, + u16 token, + const struct dprc_endpoint *endpoint1, + struct dprc_endpoint *endpoint2, + int *state) { struct mc_command cmd = { 0 }; int err; /* prepare command */ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION, - MC_CMD_PRI_LOW, + cmd_flags, token); cmd.params[0] |= mc_enc(0, 32, endpoint1->id); - cmd.params[0] |= mc_enc(32, 32, endpoint1->interface_id); + cmd.params[0] |= mc_enc(32, 32, endpoint1->if_id); cmd.params[1] |= mc_enc(0, 8, endpoint1->type[0]); cmd.params[1] |= mc_enc(8, 8, endpoint1->type[1]); cmd.params[1] |= mc_enc(16, 8, endpoint1->type[2]); @@ -890,7 +1599,7 @@ int dprc_get_connection(struct fsl_mc_io *mc_io, /* retrieve response parameters */ endpoint2->id = mc_dec(cmd.params[3], 0, 32); - endpoint2->interface_id = mc_dec(cmd.params[3], 32, 32); + endpoint2->if_id = mc_dec(cmd.params[3], 32, 32); endpoint2->type[0] = mc_dec(cmd.params[4], 0, 8); endpoint2->type[1] = mc_dec(cmd.params[4], 8, 8); endpoint2->type[2] = mc_dec(cmd.params[4], 16, 8); diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c b/drivers/staging/fsl-mc/bus/mc-allocator.c index e36235ddb..88d185752 100644 --- a/drivers/staging/fsl-mc/bus/mc-allocator.c +++ b/drivers/staging/fsl-mc/bus/mc-allocator.c @@ -111,7 +111,7 @@ static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device goto out; resource = mc_dev->resource; - if (WARN_ON(resource->data != mc_dev)) + if (WARN_ON(!resource || resource->data != mc_dev)) goto out; mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); @@ -277,14 +277,14 @@ EXPORT_SYMBOL_GPL(fsl_mc_resource_free); * portal is allocated from its own MC bus. */ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, - uint16_t mc_io_flags, + u16 mc_io_flags, struct fsl_mc_io **new_mc_io) { struct fsl_mc_device *mc_bus_dev; struct fsl_mc_bus *mc_bus; phys_addr_t mc_portal_phys_addr; size_t mc_portal_size; - struct fsl_mc_device *mc_adev; + struct fsl_mc_device *dpmcp_dev; int error = -EINVAL; struct fsl_mc_resource *resource = NULL; struct fsl_mc_io *mc_io = NULL; @@ -304,23 +304,23 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, if (error < 0) return error; - mc_adev = resource->data; - if (WARN_ON(!mc_adev)) + dpmcp_dev = resource->data; + if (WARN_ON(!dpmcp_dev)) goto error_cleanup_resource; - if (WARN_ON(mc_adev->obj_desc.region_count == 0)) + if (WARN_ON(dpmcp_dev->obj_desc.region_count == 0)) goto error_cleanup_resource; - mc_portal_phys_addr = mc_adev->regions[0].start; - mc_portal_size = mc_adev->regions[0].end - - mc_adev->regions[0].start + 1; + mc_portal_phys_addr = dpmcp_dev->regions[0].start; + mc_portal_size = dpmcp_dev->regions[0].end - + dpmcp_dev->regions[0].start + 1; if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size)) goto error_cleanup_resource; error = fsl_create_mc_io(&mc_bus_dev->dev, mc_portal_phys_addr, - mc_portal_size, resource, + mc_portal_size, dpmcp_dev, mc_io_flags, &mc_io); if (error < 0) goto error_cleanup_resource; @@ -342,12 +342,22 @@ EXPORT_SYMBOL_GPL(fsl_mc_portal_allocate); */ void fsl_mc_portal_free(struct fsl_mc_io *mc_io) { + struct fsl_mc_device *dpmcp_dev; struct fsl_mc_resource *resource; - resource = mc_io->resource; - if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP)) + /* + * Every mc_io obtained by calling fsl_mc_portal_allocate() is supposed + * to have a DPMCP object associated with. + */ + dpmcp_dev = mc_io->dpmcp_dev; + if (WARN_ON(!dpmcp_dev)) return; - if (WARN_ON(!resource->data)) + + resource = dpmcp_dev->resource; + if (WARN_ON(!resource || resource->type != FSL_MC_POOL_DPMCP)) + return; + + if (WARN_ON(resource->data != dpmcp_dev)) return; fsl_destroy_mc_io(mc_io); @@ -363,31 +373,14 @@ EXPORT_SYMBOL_GPL(fsl_mc_portal_free); int fsl_mc_portal_reset(struct fsl_mc_io *mc_io) { int error; - uint16_t token; - struct fsl_mc_resource *resource = mc_io->resource; - struct fsl_mc_device *mc_dev = resource->data; + struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; - if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP)) + if (WARN_ON(!dpmcp_dev)) return -EINVAL; - if (WARN_ON(!mc_dev)) - return -EINVAL; - - error = dpmcp_open(mc_io, mc_dev->obj_desc.id, &token); - if (error < 0) { - dev_err(&mc_dev->dev, "dpmcp_open() failed: %d\n", error); - return error; - } - - error = dpmcp_reset(mc_io, token); + error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle); if (error < 0) { - dev_err(&mc_dev->dev, "dpmcp_reset() failed: %d\n", error); - return error; - } - - error = dpmcp_close(mc_io, token); - if (error < 0) { - dev_err(&mc_dev->dev, "dpmcp_close() failed: %d\n", error); + dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error); return error; } @@ -481,30 +474,27 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev) enum fsl_mc_pool_type pool_type; struct fsl_mc_device *mc_bus_dev; struct fsl_mc_bus *mc_bus; - int error = -EINVAL; + int error; if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type))) - goto error; + return -EINVAL; mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); if (WARN_ON(mc_bus_dev->dev.bus != &fsl_mc_bus_type)) - goto error; + return -EINVAL; mc_bus = to_fsl_mc_bus(mc_bus_dev); error = object_type_to_pool_type(mc_dev->obj_desc.type, &pool_type); if (error < 0) - goto error; + return error; error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, mc_dev); if (error < 0) - goto error; + return 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: - - return error; } /** @@ -513,20 +503,20 @@ error: */ static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev) { - int error = -EINVAL; + int error; if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type))) - goto out; + return -EINVAL; - error = fsl_mc_resource_pool_remove_device(mc_dev); - if (error < 0) - goto out; + if (mc_dev->resource) { + error = fsl_mc_resource_pool_remove_device(mc_dev); + if (error < 0) + return error; + } - dev_info(&mc_dev->dev, - "Allocatable MC object device unbound from fsl_mc_allocator driver"); - error = 0; -out: - return error; + dev_dbg(&mc_dev->dev, + "Allocatable MC object device unbound from fsl_mc_allocator driver"); + return 0; } static const struct fsl_mc_device_match_id match_id_table[] = { diff --git a/drivers/staging/fsl-mc/bus/mc-bus.c b/drivers/staging/fsl-mc/bus/mc-bus.c index 766a65959..84db55b4d 100644 --- a/drivers/staging/fsl-mc/bus/mc-bus.c +++ b/drivers/staging/fsl-mc/bus/mc-bus.c @@ -22,6 +22,8 @@ static struct kmem_cache *mc_dev_cache; +static bool fsl_mc_is_root_dprc(struct device *dev); + /** * fsl_mc_bus_match - device to driver matching callback * @dev: the MC object device structure to match against @@ -39,7 +41,7 @@ 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)) + if (WARN_ON(!fsl_mc_bus_exists())) goto out; if (!mc_drv->match_id_table) @@ -50,7 +52,7 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) * Only exception is the root DPRC, which is a special case. */ if ((mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED) == 0 && - &mc_dev->dev != fsl_mc_bus_type.dev_root) + !fsl_mc_is_root_dprc(&mc_dev->dev)) goto out; /* @@ -107,6 +109,8 @@ struct bus_type fsl_mc_bus_type = { }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); +static atomic_t root_dprc_count = ATOMIC_INIT(0); + static int fsl_mc_driver_probe(struct device *dev) { struct fsl_mc_driver *mc_drv; @@ -206,21 +210,61 @@ void fsl_mc_driver_unregister(struct fsl_mc_driver *mc_driver) } EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister); +/** + * fsl_mc_bus_exists - check if a root dprc exists + */ +bool fsl_mc_bus_exists(void) +{ + return atomic_read(&root_dprc_count) > 0; +} +EXPORT_SYMBOL_GPL(fsl_mc_bus_exists); + +/** +* fsl_mc_get_root_dprc - function to traverse to the root dprc +*/ +static void fsl_mc_get_root_dprc(struct device *dev, + struct device **root_dprc_dev) +{ + if (WARN_ON(!dev)) { + *root_dprc_dev = NULL; + } else if (WARN_ON(dev->bus != &fsl_mc_bus_type)) { + *root_dprc_dev = NULL; + } else { + *root_dprc_dev = dev; + while ((*root_dprc_dev)->parent->bus == &fsl_mc_bus_type) + *root_dprc_dev = (*root_dprc_dev)->parent; + } +} + +/** + * fsl_mc_is_root_dprc - function to check if a given device is a root dprc + */ +static bool fsl_mc_is_root_dprc(struct device *dev) +{ + struct device *root_dprc_dev; + + fsl_mc_get_root_dprc(dev, &root_dprc_dev); + if (!root_dprc_dev) + return false; + else + return dev == root_dprc_dev; +} + static int get_dprc_icid(struct fsl_mc_io *mc_io, - int container_id, uint16_t *icid) + int container_id, u16 *icid) { - uint16_t dprc_handle; + u16 dprc_handle; struct dprc_attributes attr; int error; - error = dprc_open(mc_io, container_id, &dprc_handle); + error = dprc_open(mc_io, 0, container_id, &dprc_handle); if (error < 0) { pr_err("dprc_open() failed: %d\n", error); return error; } memset(&attr, 0, sizeof(attr)); - error = dprc_get_attributes(mc_io, dprc_handle, &attr); + error = dprc_get_attributes(mc_io, 0, dprc_handle, &attr); if (error < 0) { pr_err("dprc_get_attributes() failed: %d\n", error); goto common_cleanup; @@ -230,20 +274,28 @@ static int get_dprc_icid(struct fsl_mc_io *mc_io, error = 0; common_cleanup: - (void)dprc_close(mc_io, dprc_handle); + (void)dprc_close(mc_io, 0, dprc_handle); return error; } -static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr) +static int translate_mc_addr(struct fsl_mc_device *mc_dev, + enum dprc_region_type 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); + struct device *root_dprc_dev; + struct fsl_mc *mc; + + fsl_mc_get_root_dprc(&mc_dev->dev, &root_dprc_dev); + if (WARN_ON(!root_dprc_dev)) + return -EINVAL; + mc = dev_get_drvdata(root_dprc_dev->parent); if (mc->num_translation_ranges == 0) { /* * Do identity mapping: */ - *phys_addr = mc_addr; + *phys_addr = mc_offset; return 0; } @@ -251,10 +303,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; } } @@ -270,6 +323,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 dprc_region_type mc_region_type; + + if (strcmp(obj_desc->type, "dprc") == 0 || + strcmp(obj_desc->type, "dpmcp") == 0) { + mc_region_type = DPRC_REGION_TYPE_MC_PORTAL; + } else if (strcmp(obj_desc->type, "dpio") == 0) { + mc_region_type = DPRC_REGION_TYPE_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); @@ -280,6 +349,7 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, struct dprc_region_desc region_desc; error = dprc_get_obj_region(mc_bus_dev->mc_io, + 0, mc_bus_dev->mc_handle, obj_desc->type, obj_desc->id, i, ®ion_desc); @@ -289,14 +359,15 @@ 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_dev, mc_region_type, + region_desc.base_offset, ®ions[i].start); if (error < 0) { dev_err(parent_dev, - "Invalid MC address: %#llx\n", - region_desc.base_paddr); + "Invalid MC offset: %#x (for %s.%d\'s region %d)\n", + region_desc.base_offset, + obj_desc->type, obj_desc->id, i); goto error_cleanup_regions; } @@ -387,8 +458,7 @@ 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; + atomic_inc(&root_dprc_count); } error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid); @@ -471,8 +541,12 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev) mc_dev->mc_io = NULL; } - if (&mc_dev->dev == fsl_mc_bus_type.dev_root) - fsl_mc_bus_type.dev_root = NULL; + if (fsl_mc_is_root_dprc(&mc_dev->dev)) { + if (atomic_read(&root_dprc_count) > 0) + atomic_dec(&root_dprc_count); + else + WARN_ON(1); + } } if (mc_bus) @@ -487,7 +561,7 @@ static int parse_mc_ranges(struct device *dev, int *mc_addr_cells, int *mc_size_cells, const __be32 **ranges_start, - uint8_t *num_ranges) + u8 *num_ranges) { const __be32 *prop; int range_tuple_cell_count; @@ -535,7 +609,7 @@ static int parse_mc_ranges(struct device *dev, static int get_mc_addr_translation_ranges(struct device *dev, struct fsl_mc_addr_translation_range **ranges, - uint8_t *num_ranges) + u8 *num_ranges) { int error; int paddr_cells; @@ -574,11 +648,13 @@ 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 + + range->end_mc_offset = range->start_mc_offset + of_read_number(cell, mc_size_cells); cell += mc_size_cells; @@ -600,7 +676,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) struct fsl_mc_io *mc_io = NULL; int container_id; phys_addr_t mc_portal_phys_addr; - uint32_t mc_portal_size; + u32 mc_portal_size; struct mc_version mc_version; struct resource res; @@ -630,7 +706,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) if (error < 0) return error; - error = mc_get_version(mc_io, &mc_version); + error = mc_get_version(mc_io, 0, &mc_version); if (error != 0) { dev_err(&pdev->dev, "mc_get_version() failed with error %d\n", error); @@ -661,7 +737,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) if (error < 0) goto error_cleanup_mc_io; - error = dpmng_get_container_id(mc_io, &container_id); + error = dpmng_get_container_id(mc_io, 0, &container_id); if (error < 0) { dev_err(&pdev->dev, "dpmng_get_container_id() failed: %d\n", error); @@ -673,6 +749,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) obj_desc.id = container_id; obj_desc.ver_major = DPRC_VER_MAJOR; obj_desc.ver_minor = DPRC_VER_MINOR; + obj_desc.irq_count = 1; obj_desc.region_count = 0; error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev); @@ -695,7 +772,7 @@ static int fsl_mc_bus_remove(struct platform_device *pdev) { struct fsl_mc *mc = platform_get_drvdata(pdev); - if (WARN_ON(&mc->root_mc_bus_dev->dev != fsl_mc_bus_type.dev_root)) + if (WARN_ON(!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev))) return -EINVAL; fsl_mc_device_remove(mc->root_mc_bus_dev); @@ -713,6 +790,7 @@ MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table); static struct platform_driver fsl_mc_bus_driver = { .driver = { .name = "fsl_mc_bus", + .owner = THIS_MODULE, .pm = NULL, .of_match_table = fsl_mc_bus_match_table, }, diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c index 5737f599f..6e1489246 100644 --- a/drivers/staging/fsl-mc/bus/mc-sys.c +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -34,15 +34,17 @@ #include "../include/mc-sys.h" #include "../include/mc-cmd.h" +#include "../include/mc.h" #include #include #include #include +#include "dpmcp.h" /** - * Timeout in jiffies to wait for the completion of an MC command + * Timeout in milliseconds to wait for the completion of an MC command */ -#define MC_CMD_COMPLETION_TIMEOUT_JIFFIES (HZ / 2) /* 500 ms */ +#define MC_CMD_COMPLETION_TIMEOUT_MS 500 /* * usleep_range() min and max values used to throttle down polling @@ -52,7 +54,7 @@ #define MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS 500 #define MC_CMD_HDR_READ_CMDID(_hdr) \ - ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S)) + ((u16)mc_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S)) /** * Creates an MC I/O object @@ -60,8 +62,8 @@ * @dev: device to be associated with the MC I/O object * @mc_portal_phys_addr: physical address of the MC portal to use * @mc_portal_size: size in bytes of the MC portal - * @resource: Pointer to MC bus object allocator resource associated - * with this MC I/O object or NULL if none. + * @dpmcp-dev: Pointer to the DPMCP object associated with this MC I/O + * object or NULL if none. * @flags: flags for the new MC I/O object * @new_mc_io: Area to return pointer to newly created MC I/O object * @@ -69,10 +71,11 @@ */ int __must_check fsl_create_mc_io(struct device *dev, phys_addr_t mc_portal_phys_addr, - uint32_t mc_portal_size, - struct fsl_mc_resource *resource, - uint32_t flags, struct fsl_mc_io **new_mc_io) + u32 mc_portal_size, + struct fsl_mc_device *dpmcp_dev, + u32 flags, struct fsl_mc_io **new_mc_io) { + int error; struct fsl_mc_io *mc_io; void __iomem *mc_portal_virt_addr; struct resource *res; @@ -85,7 +88,11 @@ int __must_check fsl_create_mc_io(struct device *dev, mc_io->flags = flags; mc_io->portal_phys_addr = mc_portal_phys_addr; mc_io->portal_size = mc_portal_size; - mc_io->resource = resource; + if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) + spin_lock_init(&mc_io->spinlock); + else + mutex_init(&mc_io->mutex); + res = devm_request_mem_region(dev, mc_portal_phys_addr, mc_portal_size, @@ -108,8 +115,18 @@ int __must_check fsl_create_mc_io(struct device *dev, } mc_io->portal_virt_addr = mc_portal_virt_addr; + if (dpmcp_dev) { + error = fsl_mc_io_set_dpmcp(mc_io, dpmcp_dev); + if (error < 0) + goto error_destroy_mc_io; + } + *new_mc_io = mc_io; return 0; + +error_destroy_mc_io: + fsl_destroy_mc_io(mc_io); + return error; } EXPORT_SYMBOL_GPL(fsl_create_mc_io); @@ -120,6 +137,11 @@ EXPORT_SYMBOL_GPL(fsl_create_mc_io); */ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) { + struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; + + if (dpmcp_dev) + fsl_mc_io_unset_dpmcp(mc_io); + devm_iounmap(mc_io->dev, mc_io->portal_virt_addr); devm_release_mem_region(mc_io->dev, mc_io->portal_phys_addr, @@ -130,6 +152,57 @@ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) } EXPORT_SYMBOL_GPL(fsl_destroy_mc_io); +int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io, + struct fsl_mc_device *dpmcp_dev) +{ + int error; + + if (WARN_ON(!dpmcp_dev)) + return -EINVAL; + + if (WARN_ON(mc_io->dpmcp_dev)) + return -EINVAL; + + if (WARN_ON(dpmcp_dev->mc_io)) + return -EINVAL; + + error = dpmcp_open(mc_io, + 0, + dpmcp_dev->obj_desc.id, + &dpmcp_dev->mc_handle); + if (error < 0) + return error; + + mc_io->dpmcp_dev = dpmcp_dev; + dpmcp_dev->mc_io = mc_io; + return 0; +} +EXPORT_SYMBOL_GPL(fsl_mc_io_set_dpmcp); + +void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io) +{ + int error; + struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; + + if (WARN_ON(!dpmcp_dev)) + return; + + if (WARN_ON(dpmcp_dev->mc_io != mc_io)) + return; + + error = dpmcp_close(mc_io, + 0, + dpmcp_dev->mc_handle); + if (error < 0) { + dev_err(&dpmcp_dev->dev, "dpmcp_close() failed: %d\n", + error); + } + + mc_io->dpmcp_dev = NULL; + dpmcp_dev->mc_io = NULL; +} +EXPORT_SYMBOL_GPL(fsl_mc_io_unset_dpmcp); + static int mc_status_to_error(enum mc_cmd_status status) { static const int mc_status_to_error_map[] = { @@ -224,25 +297,20 @@ static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem * } /** - * Sends an command to the MC device using the given MC I/O object + * Waits for the completion of an MC command doing preemptible polling. + * uslepp_range() is called between polling iterations. * * @mc_io: MC I/O object to be used - * @cmd: command to be sent - * - * Returns '0' on Success; Error code otherwise. - * - * NOTE: This function cannot be invoked from from atomic contexts. + * @cmd: command buffer to receive MC response + * @mc_status: MC command completion status */ -int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) +static int mc_polling_wait_preemptible(struct fsl_mc_io *mc_io, + struct mc_command *cmd, + enum mc_cmd_status *mc_status) { enum mc_cmd_status status; unsigned long jiffies_until_timeout = - jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES; - - /* - * Send command to the MC hardware: - */ - mc_write_command(mc_io->portal_virt_addr, cmd); + jiffies + msecs_to_jiffies(MC_CMD_COMPLETION_TIMEOUT_MS); /* * Wait for response from the MC hardware: @@ -271,6 +339,90 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) } } + *mc_status = status; + return 0; +} + +/** + * Waits for the completion of an MC command doing atomic polling. + * udelay() is called between polling iterations. + * + * @mc_io: MC I/O object to be used + * @cmd: command buffer to receive MC response + * @mc_status: MC command completion status + */ +static int mc_polling_wait_atomic(struct fsl_mc_io *mc_io, + struct mc_command *cmd, + enum mc_cmd_status *mc_status) +{ + enum mc_cmd_status status; + unsigned long timeout_usecs = MC_CMD_COMPLETION_TIMEOUT_MS * 1000; + + BUILD_BUG_ON((MC_CMD_COMPLETION_TIMEOUT_MS * 1000) % + MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS != 0); + + for (;;) { + status = mc_read_response(mc_io->portal_virt_addr, cmd); + if (status != MC_CMD_STATUS_READY) + break; + + udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS); + timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS; + if (timeout_usecs == 0) { + pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n", + mc_io->portal_phys_addr, + (unsigned int) + MC_CMD_HDR_READ_TOKEN(cmd->header), + (unsigned int) + MC_CMD_HDR_READ_CMDID(cmd->header)); + + return -ETIMEDOUT; + } + } + + *mc_status = status; + return 0; +} + +/** + * Sends a command to the MC device using the given MC I/O object + * + * @mc_io: MC I/O object to be used + * @cmd: command to be sent + * + * Returns '0' on Success; Error code otherwise. + */ +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) +{ + int error; + enum mc_cmd_status status; + unsigned long irq_flags = 0; + + if (WARN_ON(in_irq() && + !(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL))) + return -EINVAL; + + if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) + spin_lock_irqsave(&mc_io->spinlock, irq_flags); + else + mutex_lock(&mc_io->mutex); + + /* + * Send command to the MC hardware: + */ + mc_write_command(mc_io->portal_virt_addr, cmd); + + /* + * Wait for response from the MC hardware: + */ + if (!(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)) + error = mc_polling_wait_preemptible(mc_io, cmd, &status); + else + error = mc_polling_wait_atomic(mc_io, cmd, &status); + + if (error < 0) + goto common_exit; + if (status != MC_CMD_STATUS_OK) { pr_debug("MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n", mc_io->portal_phys_addr, @@ -279,9 +431,17 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) mc_status_to_string(status), (unsigned int)status); - return mc_status_to_error(status); + error = mc_status_to_error(status); + goto common_exit; } - return 0; + error = 0; +common_exit: + if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) + spin_unlock_irqrestore(&mc_io->spinlock, irq_flags); + else + mutex_unlock(&mc_io->mutex); + + return error; } EXPORT_SYMBOL(mc_send_command); diff --git a/drivers/staging/fsl-mc/include/dpbp-cmd.h b/drivers/staging/fsl-mc/include/dpbp-cmd.h index 1fd70a215..efa9bf33c 100644 --- a/drivers/staging/fsl-mc/include/dpbp-cmd.h +++ b/drivers/staging/fsl-mc/include/dpbp-cmd.h @@ -34,7 +34,7 @@ /* DPBP Version */ #define DPBP_VER_MAJOR 2 -#define DPBP_VER_MINOR 0 +#define DPBP_VER_MINOR 1 /* Command IDs */ #define DPBP_CMDID_CLOSE 0x800 diff --git a/drivers/staging/fsl-mc/include/dpbp.h b/drivers/staging/fsl-mc/include/dpbp.h index 5f3c8e74d..37ed95143 100644 --- a/drivers/staging/fsl-mc/include/dpbp.h +++ b/drivers/staging/fsl-mc/include/dpbp.h @@ -38,258 +38,109 @@ struct fsl_mc_io; -/** - * dpbp_open() - Open a control session for the specified object. - * @mc_io: Pointer to MC portal's I/O object - * @dpbp_id: DPBP unique ID - * @token: Returned token; use in subsequent API calls - * - * This function can be used to open a control session for an - * already created object; an object may have been declared in - * the DPL or by calling the dpbp_create function. - * This function returns a unique authentication token, - * associated with the specific object ID and the specific MC - * portal; this token must be used in all subsequent commands for - * this specific object - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token); +int dpbp_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int dpbp_id, + u16 *token); -/** - * dpbp_close() - Close the control session of the object - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * - * After this function is called, no further operations are - * allowed on the object without opening a new control session. - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token); +int dpbp_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); /** - * struct dpbp_cfg() - Structure representing DPBP configuration + * struct dpbp_cfg - Structure representing DPBP configuration * @options: place holder */ struct dpbp_cfg { - uint32_t options; + u32 options; }; -/** - * dpbp_create() - Create the DPBP object. - * @mc_io: Pointer to MC portal's I/O object - * @cfg: Configuration structure - * @token: Returned token; use in subsequent API calls - * - * Create the DPBP object, allocate required resources and - * perform required initialization. - * - * The object can be created either by declaring it in the - * DPL file, or by calling this function. - * This function returns a unique authentication token, - * associated with the specific object ID and the specific MC - * portal; this token must be used in all subsequent calls to - * this specific object. For objects that are created using the - * DPL file, call dpbp_open function to get an authentication - * token first. - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_create(struct fsl_mc_io *mc_io, + u32 cmd_flags, const struct dpbp_cfg *cfg, - uint16_t *token); + u16 *token); -/** - * dpbp_destroy() - Destroy the DPBP object and release all its resources. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * - * Return: '0' on Success; error code otherwise. - */ -int dpbp_destroy(struct fsl_mc_io *mc_io, uint16_t token); +int dpbp_destroy(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); -/** - * dpbp_enable() - Enable the DPBP. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token); +int dpbp_enable(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); -/** - * dpbp_disable() - Disable the DPBP. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token); +int dpbp_disable(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); -/** - * dpbp_is_enabled() - Check if the DPBP is enabled. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @en: Returns '1' if object is enabled; '0' otherwise - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en); +int dpbp_is_enabled(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + int *en); -/** - * dpbp_reset() - Reset the DPBP, returns the object to initial state. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * - * Return: '0' on Success; Error code otherwise. - */ -int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token); +int dpbp_reset(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); /** - * dpbp_set_irq() - Set IRQ information for the DPBP to trigger an interrupt. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @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 + * struct dpbp_irq_cfg - IRQ configuration + * @addr: Address that must be written to signal a message-based interrupt + * @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. */ +struct dpbp_irq_cfg { + u64 addr; + u32 val; + int user_irq_id; +}; + int dpbp_set_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint64_t irq_addr, - uint32_t irq_val, - int user_irq_id); + u32 cmd_flags, + u16 token, + u8 irq_index, + struct dpbp_irq_cfg *irq_cfg); -/** - * dpbp_get_irq() - Get IRQ information from the DPBP. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @type: 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 dpbp_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, + u32 cmd_flags, + u16 token, + u8 irq_index, int *type, - uint64_t *irq_addr, - uint32_t *irq_val, - int *user_irq_id); + struct dpbp_irq_cfg *irq_cfg); -/** - * dpbp_set_irq_enable() - Set overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @en: Interrupt state - enable = 1, disable = 0 - * - * Allows GPP software to control when interrupts are generated. - * Each interrupt can have up to 32 causes. The enable/disable control's the - * overall interrupt state. if the interrupt is disabled no causes will cause - * an interrupt. - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t en); + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 en); -/** - * dpbp_get_irq_enable() - Get overall interrupt state - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @en: Returned interrupt state - enable = 1, disable = 0 - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint8_t *en); + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 *en); -/** - * dpbp_set_irq_mask() - Set interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @mask: Event mask to trigger interrupt; - * each bit: - * 0 = ignore event - * 1 = consider event for asserting IRQ - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t mask); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 mask); -/** - * dpbp_get_irq_mask() - Get interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @mask: Returned event mask to trigger interrupt - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *mask); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *mask); -/** - * dpbp_get_irq_status() - Get the current status of any pending interrupts. - * - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @status: Returned interrupts status - one bit per cause: - * 0 = no interrupt pending - * 1 = interrupt pending - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t *status); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *status); -/** - * dpbp_clear_irq_status() - Clear a pending interrupt's status - * - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @irq_index: The interrupt index to configure - * @status: Bits to clear (W1C) - one bit per cause: - * 0 = don't change - * 1 = clear status bit - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - uint32_t status); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 status); /** * struct dpbp_attr - Structure representing DPBP attributes @@ -306,23 +157,15 @@ struct dpbp_attr { * @minor: DPBP minor version */ struct { - uint16_t major; - uint16_t minor; + u16 major; + u16 minor; } version; - uint16_t bpid; + u16 bpid; }; -/** - * dpbp_get_attributes - Retrieve DPBP attributes. - * - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPBP object - * @attr: Returned object's attributes - * - * Return: '0' on Success; Error code otherwise. - */ int dpbp_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, struct dpbp_attr *attr); /** @} */ diff --git a/drivers/staging/fsl-mc/include/dpcon-cmd.h b/drivers/staging/fsl-mc/include/dpcon-cmd.h index c878d33bf..536b2ef13 100644 --- a/drivers/staging/fsl-mc/include/dpcon-cmd.h +++ b/drivers/staging/fsl-mc/include/dpcon-cmd.h @@ -1,40 +1,40 @@ /* Copyright 2013-2015 Freescale Semiconductor Inc. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the above-listed copyright holders nor the -* names of any contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* -* ALTERNATIVELY, this software may be distributed under the terms of the -* GNU General Public License ("GPL") as published by the Free Software -* Foundation, either version 2 of that License or (at your option) any -* later version. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*/ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_DPCON_CMD_H #define _FSL_DPCON_CMD_H /* DPCON Version */ #define DPCON_VER_MAJOR 2 -#define DPCON_VER_MINOR 0 +#define DPCON_VER_MINOR 1 /* Command IDs */ #define DPCON_CMDID_CLOSE 0x800 diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h index 1b052b830..e5cfd017f 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 8 #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 @@ -53,28 +53,17 @@ struct fsl_mc_io; * and/or bug fixes that have no impact on API */ struct mc_version { - uint32_t major; - uint32_t minor; - uint32_t revision; + u32 major; + u32 minor; + u32 revision; }; -/** - * mc_get_version() - Retrieves the Management Complex firmware - * version information - * @mc_io: Pointer to opaque I/O object - * @mc_ver_info: Returned version information structure - * - * Return: '0' on Success; Error code otherwise. - */ -int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info); +int mc_get_version(struct fsl_mc_io *mc_io, + u32 cmd_flags, + struct mc_version *mc_ver_info); -/** - * dpmng_get_container_id() - Get container ID associated with a given portal. - * @mc_io: Pointer to MC portal's I/O object - * @container_id: Requested container ID - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmng_get_container_id(struct fsl_mc_io *mc_io, int *container_id); +int dpmng_get_container_id(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int *container_id); #endif /* __FSL_DPMNG_H */ diff --git a/drivers/staging/fsl-mc/include/dprc.h b/drivers/staging/fsl-mc/include/dprc.h index f1862a78a..c3152f677 100644 --- a/drivers/staging/fsl-mc/include/dprc.h +++ b/drivers/staging/fsl-mc/include/dprc.h @@ -32,6 +32,8 @@ #ifndef _FSL_DPRC_H #define _FSL_DPRC_H +#include "mc-cmd.h" + /* Data Path Resource Container API * Contains DPRC API for managing and querying DPAA resources */ @@ -43,7 +45,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 @@ -52,29 +54,14 @@ struct fsl_mc_io; */ #define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0)) -/** - * dprc_open() - Open DPRC object for use - * @mc_io: Pointer to MC portal's I/O object - * @container_id: Container ID to open - * @token: Returned token of DPRC object - * - * Return: '0' on Success; Error code otherwise. - * - * @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, + u32 cmd_flags, + int container_id, + u16 *token); -/** - * dprc_close() - Close the control session of the object - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * - * After this function is called, no further operations are - * allowed on the object without opening a new control session. - * - * 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, + u32 cmd_flags, + u16 token); /** * Container general options @@ -115,6 +102,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,94 +112,49 @@ 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_' options + * @label: Object's label */ struct dprc_cfg { - uint16_t icid; + u16 icid; int portal_id; - uint64_t options; + u64 options; + char label[16]; }; -/** - * dprc_create_container() - Create child container - * @mc_io: Pointer to MC portal's I/O object - * @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 - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_create_container(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + 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. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @child_container_id: ID of the container to destroy - * - * This function terminates the child container, so following this call the - * child container ID becomes invalid. - * - * Notes: - * - All resources and objects of the destroyed container are returned to the - * parent container or destroyed if were created be the destroyed container. - * - This function destroy all the child containers of the specified - * container prior to destroying the container itself. - * - * warning: Only the parent container is allowed to destroy a child policy - * Container 0 can't be destroyed - * - * Return: '0' on Success; Error code otherwise. - * - */ int dprc_destroy_container(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id); -/** - * dprc_reset_container - Reset child container. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @child_container_id: ID of the container to reset - * - * In case a software context crashes or becomes non-responsive, the parent - * may wish to reset its resources container before the software context is - * restarted. - * - * This routine informs all objects assigned to the child container that the - * container is being reset, so they may perform any cleanup operations that are - * needed. All objects handles that were owned by the child container shall be - * closed. - * - * Note that such request may be submitted even if the child software context - * has not crashed, but the resulting object cleanup operations will not be - * aware of that. - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_reset_container(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id); /* IRQ */ +/* IRQ index */ +#define DPRC_IRQ_INDEX 0 + /* 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 @@ -225,147 +170,65 @@ int dprc_reset_container(struct fsl_mc_io *mc_io, #define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 /** - * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @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. + * struct dprc_irq_cfg - IRQ configuration + * @paddr: Address that must be written to signal a message-based interrupt + * @val: Value to write into irq_addr address + * @user_irq_id: A user defined number associated with this IRQ */ +struct dprc_irq_cfg { + u64 paddr; + u32 val; + int user_irq_id; +}; + 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, - int user_irq_id); + u32 cmd_flags, + u16 token, + u8 irq_index, + struct dprc_irq_cfg *irq_cfg); -/** - * dprc_get_irq() - Get IRQ information from the DPRC. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @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_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, + u32 cmd_flags, + u16 token, + u8 irq_index, int *type, - uint64_t *irq_addr, - uint32_t *irq_val, - int *user_irq_id); + struct dprc_irq_cfg *irq_cfg); -/** - * dprc_set_irq_enable() - Set overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @en: Interrupt state - enable = 1, disable = 0 - * - * Allows GPP software to control when interrupts are generated. - * Each interrupt can have up to 32 causes. The enable/disable control's the - * overall interrupt state. if the interrupt is disabled no causes will cause - * an interrupt. - * - * 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); + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 en); -/** - * dprc_get_irq_enable() - Get overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @en: Returned interrupt state - enable = 1, disable = 0 - * - * 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); + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 *en); -/** - * dprc_set_irq_mask() - Set interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @mask: event mask to trigger interrupt; - * each bit: - * 0 = ignore event - * 1 = consider event for asserting irq - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * 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); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 mask); -/** - * dprc_get_irq_mask() - Get interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @mask: Returned event mask to trigger interrupt - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * 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); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *mask); -/** - * dprc_get_irq_status() - Get the current status of any pending interrupts. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @status: Returned interrupts status - one bit per cause: - * 0 = no interrupt pending - * 1 = interrupt pending - * - * 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); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *status); -/** - * dprc_clear_irq_status() - Clear a pending interrupt's status - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @status: bits to clear (W1C) - one bit per cause: - * 0 = don't change - * 1 = clear status bit - * - * 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); + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 status); /** * struct dprc_attributes - Container attributes @@ -377,81 +240,38 @@ 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; }; -/** - * dprc_get_attributes() - Obtains container attributes - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @attributes Returned container attributes - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_attributes(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, struct dprc_attributes *attributes); -/** - * dprc_set_res_quota() - Set allocation policy for a specific resource/object - * type in a child container - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @child_container_id: ID of the child container - * @type: Resource/object type - * @quota: Sets the maximum number of resources of the selected type - * that the child container is allowed to allocate from its parent; - * when quota is set to -1, the policy is the same as container's - * general policy. - * - * Allocation policy determines whether or not a container may allocate - * resources from its parent. Each container has a 'global' allocation policy - * that is set when the container is created. - * - * This function sets allocation policy for a specific resource type. - * The default policy for all resource types matches the container's 'global' - * allocation policy. - * - * Return: '0' on Success; Error code otherwise. - * - * @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, + u32 cmd_flags, + u16 token, int child_container_id, char *type, - uint16_t quota); + u16 quota); -/** - * dprc_get_res_quota() - Gets the allocation policy of a specific - * resource/object type in a child container - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @child_container_id; ID of the child container - * @type: resource/object type - * @quota: Returnes the maximum number of resources of the selected type - * that the child container is allowed to allocate from the parent; - * when quota is set to -1, the policy is the same as container's - * general policy. - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_res_quota(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id, char *type, - uint16_t *quota); + u16 *quota); /* Resource request options */ @@ -492,106 +312,38 @@ 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; }; -/** - * dprc_assign() - Assigns objects or resource to a child container. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @container_id: ID of the child container - * @res_req: Describes the type and amount of resources to - * assign to the given container - * - * Assignment is usually done by a parent (this DPRC) to one of its child - * containers. - * - * According to the DPRC allocation policy, the assigned resources may be taken - * (allocated) from the container's ancestors, if not enough resources are - * available in the container itself. - * - * The type of assignment depends on the dprc_res_req options, as follows: - * - DPRC_RES_REQ_OPT_EXPLICIT: indicates that assigned resources should have - * the explicit base ID specified at the id_base_align field of res_req. - * - DPRC_RES_REQ_OPT_ALIGNED: indicates that the assigned resources should be - * aligned to the value given at id_base_align field of res_req. - * - DPRC_RES_REQ_OPT_PLUGGED: Relevant only for object assignment, - * and indicates that the object must be set to the plugged state. - * - * A container may use this function with its own ID in order to change a - * object state to plugged or unplugged. - * - * If IRQ information has been set in the child DPRC, it will signal an - * interrupt following every change in its object assignment. - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_assign(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int container_id, struct dprc_res_req *res_req); -/** - * dprc_unassign() - Un-assigns objects or resources from a child container - * and moves them into this (parent) DPRC. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @child_container_id: ID of the child container - * @res_req: Describes the type and amount of resources to un-assign from - * the child container - * - * Un-assignment of objects can succeed only if the object is not in the - * plugged or opened state. - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_unassign(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int child_container_id, struct dprc_res_req *res_req); -/** - * dprc_get_pool_count() - Get the number of dprc's pools - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @pool_count: Returned number of resource pools in the dprc - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_pool_count(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int *pool_count); -/** - * dprc_get_pool() - Get the type (string) of a certain dprc's pool - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @pool_index; Index of the pool to be queried (< pool_count) - * @type: The type of the pool - * - * The pool types retrieved one by one by incrementing - * pool_index up to (not including) the value of pool_count returned - * from dprc_get_pool_count(). dprc_get_pool_count() must - * be called prior to dprc_get_pool(). - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_pool(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int pool_index, char *type); -/** - * dprc_get_obj_count() - Obtains the number of objects in the DPRC - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @obj_count: Number of objects assigned to the DPRC - * - * 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, + u32 cmd_flags, + u16 token, + int *obj_count); /* Objects Attributes Flags */ @@ -610,50 +362,53 @@ 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]; }; -/** - * dprc_get_obj() - Get general information on an object - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @obj_index: Index of the object to be queried (< obj_count) - * @obj_desc: Returns the requested object descriptor - * - * The object descriptors are retrieved one by one by incrementing - * obj_index up to (not including) the value of obj_count returned - * from dprc_get_obj_count(). dprc_get_obj_count() must - * be called prior to dprc_get_obj(). - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_obj(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, int obj_index, struct dprc_obj_desc *obj_desc); -/** - * 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 - * @token: Token of DPRC object - * @type: pool type - * @res_count: Returned number of free resources of the given - * resource type that are assigned to this DPRC - * - * Return: '0' on Success; Error code otherwise. - */ +int dprc_get_obj_desc(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + struct dprc_obj_desc *obj_desc); + +int dprc_set_obj_irq(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + u8 irq_index, + struct dprc_irq_cfg *irq_cfg); + +int dprc_get_obj_irq(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + u8 irq_index, + int *type, + struct dprc_irq_cfg *irq_cfg); + int dprc_get_res_count(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, char *type, int *res_count); @@ -684,115 +439,98 @@ struct dprc_res_ids_range_desc { enum dprc_iter_status iter_status; }; -/** - * dprc_get_res_ids() - Obtains IDs of free resources in the container - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @type: pool type - * @range_desc: range descriptor - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_res_ids(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, char *type, struct dprc_res_ids_range_desc *range_desc); +/* Region flags */ +/* Cacheable - Indicates that region should be mapped as cacheable */ +#define DPRC_REGION_CACHEABLE 0x00000001 + /** - * 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. + * enum dprc_region_type - Region type + * @DPRC_REGION_TYPE_MC_PORTAL: MC portal region + * @DPRC_REGION_TYPE_QBMAN_PORTAL: Qbman portal region */ -int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, - uint16_t token, - int portal_id, - uint64_t *portal_addr); +enum dprc_region_type { + DPRC_REGION_TYPE_MC_PORTAL, + DPRC_REGION_TYPE_QBMAN_PORTAL +}; /** * 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) + * @flags: Region attributes + * @type: Portal region type */ struct dprc_region_desc { - uint64_t base_paddr; - uint32_t size; + u32 base_offset; + u32 size; + u32 flags; + enum dprc_region_type type; }; -/** - * dprc_get_obj_region() - Get region information for a specified object. - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @obj_type; Object type as returned in dprc_get_obj() - * @obj_id: Unique object instance as returned in dprc_get_obj() - * @region_index: The specific region to query - * @region_desc: Returns the requested region descriptor - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_get_obj_region(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, char *obj_type, int obj_id, - uint8_t region_index, + u8 region_index, struct dprc_region_desc *region_desc); +int dprc_set_obj_label(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + char *label); + /** * struct dprc_endpoint - Endpoint description for link connect/disconnect * operations * @type: Endpoint object type: NULL terminated string * @id: Endpoint object ID - * @interface_id: Interface ID; should be set for endpoints with multiple + * @if_id: Interface ID; should be set for endpoints with multiple * interfaces ("dpsw", "dpdmux"); for others, always set to 0 */ struct dprc_endpoint { char type[16]; int id; - int interface_id; + int if_id; }; /** - * dprc_connect() - Connect two endpoints to create a network link between them - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @endpoint1: Endpoint 1 configuration parameters - * @endpoint2: Endpoint 2 configuration parameters - * - * Return: '0' on Success; Error code otherwise. + * struct dprc_connection_cfg - Connection configuration. + * Used for virtual connections only + * @committed_rate: Committed rate (Mbits/s) + * @max_rate: Maximum rate (Mbits/s) */ +struct dprc_connection_cfg { + u32 committed_rate; + u32 max_rate; +}; + int dprc_connect(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, const struct dprc_endpoint *endpoint1, - const struct dprc_endpoint *endpoint2); + const struct dprc_endpoint *endpoint2, + const struct dprc_connection_cfg *cfg); -/** - * dprc_disconnect() - Disconnect one endpoint to remove its network connection - * @mc_io: Pointer to MC portal's I/O object - * @token: Token of DPRC object - * @endpoint: Endpoint configuration parameters - * - * Return: '0' on Success; Error code otherwise. - */ int dprc_disconnect(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + 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 -* @endpoint1 Endpoint 1 configuration parameters -* @endpoint2 Returned endpoint 2 configuration parameters -* @state: Returned link state: 1 - link is up, 0 - link is down -* -* Return: '0' on Success; -ENAVAIL if connection does not exist. -*/ int dprc_get_connection(struct fsl_mc_io *mc_io, - uint16_t token, + u32 cmd_flags, + u16 token, const struct dprc_endpoint *endpoint1, struct dprc_endpoint *endpoint2, int *state); diff --git a/drivers/staging/fsl-mc/include/mc-cmd.h b/drivers/staging/fsl-mc/include/mc-cmd.h index 32501e020..65277e3de 100644 --- a/drivers/staging/fsl-mc/include/mc-cmd.h +++ b/drivers/staging/fsl-mc/include/mc-cmd.h @@ -35,21 +35,21 @@ #define MC_CMD_NUM_OF_PARAMS 7 #define MAKE_UMASK64(_width) \ - ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1)) + ((u64)((_width) < 64 ? ((u64)1 << (_width)) - 1 : -1)) -static inline uint64_t mc_enc(int lsoffset, int width, uint64_t val) +static inline u64 mc_enc(int lsoffset, int width, u64 val) { - return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset); + return (u64)(((u64)val & MAKE_UMASK64(width)) << lsoffset); } -static inline uint64_t mc_dec(uint64_t val, int lsoffset, int width) +static inline u64 mc_dec(u64 val, int lsoffset, int width) { - return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width)); + return (u64)((val >> lsoffset) & MAKE_UMASK64(width)); } struct mc_command { - uint64_t header; - uint64_t params[MC_CMD_NUM_OF_PARAMS]; + u64 header; + u64 params[MC_CMD_NUM_OF_PARAMS]; }; enum mc_cmd_status { @@ -67,24 +67,41 @@ enum mc_cmd_status { MC_CMD_STATUS_INVALID_STATE = 0xC /* Invalid state */ }; +/* + * MC command flags + */ + +/* High priority flag */ +#define MC_CMD_FLAG_PRI 0x00008000 +/* Command completion flag */ +#define MC_CMD_FLAG_INTR_DIS 0x01000000 + +/* + * TODO Remove following two defines after completion of flib 8.0.0 + * integration + */ +#define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */ +#define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */ + #define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */ #define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */ #define MC_CMD_HDR_TOKEN_O 38 /* Token field offset */ #define MC_CMD_HDR_TOKEN_S 10 /* Token field size */ #define MC_CMD_HDR_STATUS_O 16 /* Status field offset */ #define MC_CMD_HDR_STATUS_S 8 /* Status field size*/ -#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */ -#define MC_CMD_HDR_PRI_S 1 /* Priority field size */ +#define MC_CMD_HDR_FLAGS_O 0 /* Flags field offset */ +#define MC_CMD_HDR_FLAGS_S 32 /* Flags field size*/ +#define MC_CMD_HDR_FLAGS_MASK 0xFF00FF00 /* Command flags mask */ #define MC_CMD_HDR_READ_STATUS(_hdr) \ ((enum mc_cmd_status)mc_dec((_hdr), \ MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S)) #define MC_CMD_HDR_READ_TOKEN(_hdr) \ - ((uint16_t)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S)) + ((u16)mc_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S)) -#define MC_CMD_PRI_LOW 0 /* Low Priority command indication */ -#define MC_CMD_PRI_HIGH 1 /* High Priority command indication */ +#define MC_CMD_HDR_READ_FLAGS(_hdr) \ + ((u32)mc_dec((_hdr), MC_CMD_HDR_FLAGS_O, MC_CMD_HDR_FLAGS_S)) #define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \ ((_ext)[_param] |= mc_enc((_offset), (_width), _arg)) @@ -95,15 +112,16 @@ enum mc_cmd_status { #define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \ (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width))) -static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, - uint8_t priority, - uint16_t token) +static inline u64 mc_encode_cmd_header(u16 cmd_id, + u32 cmd_flags, + u16 token) { - uint64_t hdr; + u64 hdr; hdr = mc_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id); + hdr |= mc_enc(MC_CMD_HDR_FLAGS_O, MC_CMD_HDR_FLAGS_S, + (cmd_flags & MC_CMD_HDR_FLAGS_MASK)); hdr |= mc_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token); - hdr |= mc_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority); hdr |= mc_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S, MC_CMD_STATUS_READY); diff --git a/drivers/staging/fsl-mc/include/mc-private.h b/drivers/staging/fsl-mc/include/mc-private.h index c045f49f2..c706f7786 100644 --- a/drivers/staging/fsl-mc/include/mc-private.h +++ b/drivers/staging/fsl-mc/include/mc-private.h @@ -29,25 +29,28 @@ /** * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device * @root_mc_bus_dev: MC object device representing the root DPRC - * @addr_translation_ranges: array of bus to system address translation ranges + * @num_translation_ranges: number of entries in addr_translation_ranges + * @translation_ranges: array of bus to system address translation ranges */ struct fsl_mc { struct fsl_mc_device *root_mc_bus_dev; - uint8_t num_translation_ranges; + u8 num_translation_ranges; struct fsl_mc_addr_translation_range *translation_ranges; }; /** * 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 dprc_region_type mc_region_type; + u64 start_mc_offset; + u64 end_mc_offset; phys_addr_t start_phys_addr; }; @@ -100,7 +103,7 @@ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev); int __init dprc_driver_init(void); -void __exit dprc_driver_exit(void); +void dprc_driver_exit(void); int __init fsl_mc_allocator_driver_init(void); diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h index cb3b5a296..c5038cc77 100644 --- a/drivers/staging/fsl-mc/include/mc-sys.h +++ b/drivers/staging/fsl-mc/include/mc-sys.h @@ -39,6 +39,13 @@ #include #include #include +#include +#include + +/** + * Bit masks for a MC I/O object (struct fsl_mc_io) flags + */ +#define FSL_MC_IO_ATOMIC_CONTEXT_PORTAL 0x0001 struct fsl_mc_resource; struct mc_command; @@ -50,27 +57,57 @@ struct mc_command; * @portal_size: MC command portal size in bytes * @portal_phys_addr: MC command portal physical address * @portal_virt_addr: MC command portal virtual address - * @resource: generic resource associated with the MC portal if - * the MC portal came from a resource pool, or NULL if the MC portal - * is permanently bound to a device (e.g., a DPRC) + * @dpmcp_dev: pointer to the DPMCP device associated with the MC portal. + * + * Fields are only meaningful if the FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is not + * set: + * @mutex: Mutex to serialize mc_send_command() calls that use the same MC + * portal, if the fsl_mc_io object was created with the + * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag off. mc_send_command() calls for this + * fsl_mc_io object must be made only from non-atomic context. + * + * Fields are only meaningful if the FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is + * set: + * @spinlock: Spinlock to serialize mc_send_command() calls that use the same MC + * portal, if the fsl_mc_io object was created with the + * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag on. mc_send_command() calls for this + * fsl_mc_io object can be made from atomic or non-atomic context. */ struct fsl_mc_io { struct device *dev; - uint32_t flags; - uint32_t portal_size; + u16 flags; + u16 portal_size; phys_addr_t portal_phys_addr; void __iomem *portal_virt_addr; - struct fsl_mc_resource *resource; + struct fsl_mc_device *dpmcp_dev; + union { + /* + * This field is only meaningful if the + * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is not set + */ + struct mutex mutex; /* serializes mc_send_command() */ + + /* + * This field is only meaningful if the + * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is set + */ + spinlock_t spinlock; /* serializes mc_send_command() */ + }; }; int __must_check fsl_create_mc_io(struct device *dev, phys_addr_t mc_portal_phys_addr, - uint32_t mc_portal_size, - struct fsl_mc_resource *resource, - uint32_t flags, struct fsl_mc_io **new_mc_io); + u32 mc_portal_size, + struct fsl_mc_device *dpmcp_dev, + u32 flags, struct fsl_mc_io **new_mc_io); void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); +int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io, + struct fsl_mc_device *dpmcp_dev); + +void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io); + int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd); #endif /* _FSL_MC_SYS_H */ diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h index fa02ef052..a933291e4 100644 --- a/drivers/staging/fsl-mc/include/mc.h +++ b/drivers/staging/fsl-mc/include/mc.h @@ -59,10 +59,10 @@ struct fsl_mc_driver { * a MC object device driver. The last entry of the table has vendor set to 0x0 */ struct fsl_mc_device_match_id { - uint16_t vendor; + u16 vendor; const char obj_type[16]; - uint32_t ver_major; - uint32_t ver_minor; + u32 ver_major; + u32 ver_minor; }; /** @@ -148,10 +148,10 @@ struct fsl_mc_resource { */ struct fsl_mc_device { struct device dev; - uint64_t dma_mask; - uint16_t flags; - uint16_t icid; - uint16_t mc_handle; + u64 dma_mask; + u16 flags; + u16 icid; + u16 mc_handle; struct fsl_mc_io *mc_io; struct dprc_obj_desc obj_desc; struct resource *regions; @@ -182,8 +182,10 @@ int __must_check __fsl_mc_driver_register(struct fsl_mc_driver *fsl_mc_driver, void fsl_mc_driver_unregister(struct fsl_mc_driver *driver); +bool fsl_mc_bus_exists(void); + int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, - uint16_t mc_io_flags, + u16 mc_io_flags, struct fsl_mc_io **new_mc_io); void fsl_mc_portal_free(struct fsl_mc_io *mc_io); -- cgit v1.2.3-54-g00ecf