Since signatures of flib functions have changed, we had to change all the corresponding calls in the MC bus driver Signed-off-by: J. German Rivera <German.Rivera@xxxxxxxxxxxxx> --- drivers/staging/fsl-mc/bus/dpbp.c | 232 ++++++++------ drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 81 +---- drivers/staging/fsl-mc/bus/dpmcp.c | 123 +++++--- drivers/staging/fsl-mc/bus/dpmcp.h | 123 +++++--- drivers/staging/fsl-mc/bus/dpmng.c | 14 +- drivers/staging/fsl-mc/bus/dprc-cmd.h | 7 +- drivers/staging/fsl-mc/bus/dprc-driver.c | 61 +++- drivers/staging/fsl-mc/bus/dprc.c | 464 +++++++++++++++++++++++----- drivers/staging/fsl-mc/bus/mc-allocator.c | 122 ++++---- drivers/staging/fsl-mc/bus/mc-bus.c | 72 +++-- drivers/staging/fsl-mc/bus/mc-sys.c | 188 +++++++++-- drivers/staging/fsl-mc/include/dpbp-cmd.h | 147 +++++++-- drivers/staging/fsl-mc/include/dpbp.h | 91 ++++-- drivers/staging/fsl-mc/include/dpcon-cmd.h | 159 ++++++++-- drivers/staging/fsl-mc/include/dpmng.h | 14 +- drivers/staging/fsl-mc/include/dprc.h | 313 +++++++++++++++---- drivers/staging/fsl-mc/include/mc-cmd.h | 28 +- drivers/staging/fsl-mc/include/mc-private.h | 17 +- drivers/staging/fsl-mc/include/mc-sys.h | 51 ++- 19 files changed, 1661 insertions(+), 646 deletions(-) diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c index d99ab6d..6857a67 100644 --- a/drivers/staging/fsl-mc/bus/dpbp.c +++ b/drivers/staging/fsl-mc/bus/dpbp.c @@ -1,48 +1,52 @@ -/* Copyright 2013-2014 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. -*/ +/* 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. + */ #include "../include/mc-sys.h" #include "../include/mc-cmd.h" #include "../include/dpbp.h" #include "../include/dpbp-cmd.h" -int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) +int dpbp_open(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + int dpbp_id, + uint16_t *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.params[0] |= mc_enc(0, 32, dpbp_id); + cmd_flags, + 0); + DPBP_CMD_OPEN(cmd, dpbp_id); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -54,22 +58,23 @@ int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token) return err; } -EXPORT_SYMBOL(dpbp_open); -int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token) +int dpbp_close(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpbp_close); int dpbp_create(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, const struct dpbp_cfg *cfg, uint16_t *token) { @@ -80,7 +85,8 @@ 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,50 +99,59 @@ int dpbp_create(struct fsl_mc_io *mc_io, return 0; } -int dpbp_destroy(struct fsl_mc_io *mc_io, uint16_t token) +int dpbp_destroy(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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) +int dpbp_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpbp_enable); -int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token) +int dpbp_disable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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) +int dpbp_is_enabled(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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*/ @@ -145,59 +160,61 @@ int dpbp_is_enabled(struct fsl_mc_io *mc_io, uint16_t token, int *en) return err; /* retrieve response parameters */ - *en = (int)mc_dec(cmd.params[0], 0, 1); + DPBP_RSP_IS_ENABLED(cmd, *en); return 0; } -int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token) +int dpbp_reset(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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); } -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) +int dpbp_set_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t 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.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_flags, + token); + + DPBP_CMD_SET_IRQ(cmd, irq_index, irq_cfg); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -int dpbp_get_irq(struct fsl_mc_io *mc_io, - uint16_t token, - uint8_t irq_index, - int *type, - uint64_t *irq_paddr, - uint32_t *irq_val, - int *user_irq_id) +int dpbp_get_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + uint8_t irq_index, + int *type, + 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.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_GET_IRQ(cmd, irq_index); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -205,14 +222,13 @@ 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); - *type = (int)mc_dec(cmd.params[2], 32, 32); + DPBP_RSP_GET_IRQ(cmd, *type, irq_cfg); + return 0; } int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t en) @@ -221,15 +237,17 @@ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(0, 8, en); - cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_SET_IRQ_ENABLE(cmd, irq_index, en); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t *en) @@ -239,8 +257,10 @@ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_ENABLE, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_GET_IRQ_ENABLE(cmd, irq_index); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -248,11 +268,13 @@ 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); + DPBP_RSP_GET_IRQ_ENABLE(cmd, *en); + return 0; } int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t mask) @@ -261,15 +283,17 @@ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_IRQ_MASK, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(0, 32, mask); - cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_SET_IRQ_MASK(cmd, irq_index, mask); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *mask) @@ -279,8 +303,10 @@ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_MASK, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_GET_IRQ_MASK(cmd, irq_index); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -288,11 +314,13 @@ 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); + DPBP_RSP_GET_IRQ_MASK(cmd, *mask); + return 0; } int dpbp_get_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *status) @@ -302,8 +330,10 @@ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_GET_IRQ_STATUS(cmd, irq_index); /* send command to mc*/ err = mc_send_command(mc_io, &cmd); @@ -311,11 +341,13 @@ 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); + DPBP_RSP_GET_IRQ_STATUS(cmd, *status); + return 0; } int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t status) @@ -324,15 +356,17 @@ int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, /* prepare command */ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLEAR_IRQ_STATUS, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(0, 32, status); - cmd.params[0] |= mc_enc(32, 8, irq_index); + cmd_flags, + token); + + DPBP_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } int dpbp_get_attributes(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, struct dpbp_attr *attr) { @@ -341,7 +375,8 @@ 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 +384,7 @@ 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->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); + DPBP_RSP_GET_ATTRIBUTES(cmd, attr); + 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 57f326b..a87e9f8 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 6b9da5b..ee63380 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.c +++ b/drivers/staging/fsl-mc/bus/dpmcp.c @@ -34,14 +34,18 @@ #include "dpmcp.h" #include "dpmcp-cmd.h" -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) { 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,12 +59,15 @@ 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) +int dpmcp_close(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token) { struct mc_command cmd = { 0 }; /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, MC_CMD_PRI_HIGH, + cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLOSE, + cmd_flags, token); /* send command to mc*/ @@ -68,15 +75,17 @@ int dpmcp_close(struct fsl_mc_io *mc_io, uint16_t token) } int dpmcp_create(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, const struct dpmcp_cfg *cfg, - uint16_t *token) + uint16_t *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 +99,71 @@ int dpmcp_create(struct fsl_mc_io *mc_io, return 0; } -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) { 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) +int dpmcp_reset(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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); } 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) + uint8_t 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); } 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) + uint8_t 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 +172,25 @@ 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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + irq_cfg->paddr = (uint64_t)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; } 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) + uint8_t irq_index, + uint8_t 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); @@ -182,16 +199,18 @@ int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, } 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) + uint8_t irq_index, + uint8_t *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*/ @@ -205,15 +224,17 @@ int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, } 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) + uint8_t irq_index, + uint32_t 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); @@ -222,16 +243,18 @@ int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, } 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) + uint8_t irq_index, + uint32_t *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*/ @@ -245,16 +268,18 @@ int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, } 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) + uint8_t irq_index, + uint32_t *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*/ @@ -268,15 +293,17 @@ int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, } 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) + uint8_t irq_index, + uint32_t 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); @@ -285,15 +312,17 @@ int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io, } int dpmcp_get_attributes(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, - struct dpmcp_attr *attr) + 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); diff --git a/drivers/staging/fsl-mc/bus/dpmcp.h b/drivers/staging/fsl-mc/bus/dpmcp.h index 5e7c219..164684f 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.h +++ b/drivers/staging/fsl-mc/bus/dpmcp.h @@ -41,6 +41,7 @@ struct fsl_mc_io; /** * 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 * @@ -54,7 +55,10 @@ struct fsl_mc_io; * * 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) @@ -62,6 +66,7 @@ int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, 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 @@ -69,12 +74,14 @@ int dpmcp_open(struct fsl_mc_io *mc_io, int dpmcp_id, uint16_t *token); * * 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 + * from pool */ struct dpmcp_cfg { int portal_id; @@ -83,6 +90,7 @@ struct dpmcp_cfg { /** * 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 * @@ -101,81 +109,91 @@ struct dpmcp_cfg { * 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); + 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, 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 + * @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, 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 */ -/* @} */ + +/** + * 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 + */ +struct dpmcp_irq_cfg { + uint64_t paddr; + uint32_t val; + int user_irq_id; +}; /** * 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_addr: Address that must be written to - * signal a message-based interrupt - * @irq_val: Value to write into irq_addr address - * @user_irq_id: A user defined number associated with this IRQ + * @irq_cfg: IRQ configuration * * Return: '0' on Success; Error code otherwise. */ 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); + uint8_t irq_index, + 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 + * @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_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 + * 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, + 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); + uint8_t irq_index, + int *type, + struct dpmcp_irq_cfg *irq_cfg); /** * 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 @@ -188,13 +206,15 @@ int dpmcp_get_irq(struct fsl_mc_io *mc_io, * 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); + 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 + * @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 @@ -202,13 +222,15 @@ int dpmcp_set_irq_enable(struct fsl_mc_io *mc_io, * 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); + uint8_t irq_index, + uint8_t *en); /** * 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; @@ -221,14 +243,16 @@ int dpmcp_get_irq_enable(struct fsl_mc_io *mc_io, * * Return: '0' on Success; Error code otherwise. */ -int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, +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); + uint8_t irq_index, + uint32_t mask); /** * 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 @@ -238,15 +262,17 @@ int dpmcp_set_irq_mask(struct fsl_mc_io *mc_io, * * Return: '0' on Success; Error code otherwise. */ -int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, +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); + 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 + * @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: @@ -256,14 +282,16 @@ int dpmcp_get_irq_mask(struct fsl_mc_io *mc_io, * 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); + 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 + * @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: @@ -273,9 +301,10 @@ int dpmcp_get_irq_status(struct fsl_mc_io *mc_io, * 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); + uint8_t irq_index, + uint32_t status); /** * struct dpmcp_attr - Structure representing DPMCP attributes @@ -299,13 +328,15 @@ struct dpmcp_attr { * 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, + uint32_t cmd_flags, uint16_t token, - struct dpmcp_attr *attr); + struct dpmcp_attr *attr); #endif /* __FSL_DPMCP_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmng.c b/drivers/staging/fsl-mc/bus/dpmng.c index 58328e8..1aeca05 100644 --- a/drivers/staging/fsl-mc/bus/dpmng.c +++ b/drivers/staging/fsl-mc/bus/dpmng.c @@ -34,14 +34,17 @@ #include "../include/dpmng.h" #include "dpmng-cmd.h" -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, + uint32_t 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 +59,17 @@ 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) +int dpmng_get_container_id(struct fsl_mc_io *mc_io, + uint32_t 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 0920248..6552c20 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 35c06cf..f87714f 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -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,8 +290,19 @@ 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); + + /* + * -ENXIO means object index was invalid. + * This is caused when the DPRC was changed at + * the MC during the scan. In this case, + * abort the current scan. + */ + if (error == -ENXIO) + return error; + if (error < 0) { dev_err(&mc_bus_dev->dev, "dprc_get_obj(i=%d) failed: %d\n", @@ -357,6 +369,7 @@ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) return 0; error: + device_for_each_child(&mc_bus_dev->dev, NULL, __fsl_mc_device_remove); dprc_cleanup_all_resource_pools(mc_bus_dev); return error; } @@ -377,14 +390,28 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) int error; size_t region_size; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); + bool mc_io_created = false; + bool dev_root_set = false; if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) return -EINVAL; - if (!mc_dev->mc_io) { + if (mc_dev->mc_io) { + /* + * This is the root DPRC + */ + if (WARN_ON(fsl_mc_bus_type.dev_root)) + return -EINVAL; + + fsl_mc_bus_type.dev_root = &mc_dev->dev; + dev_root_set = true; + } else { /* - * This is a child DPRC: + * This is a child DPRC */ + if (WARN_ON(!fsl_mc_bus_type.dev_root)) + return -EINVAL; + if (WARN_ON(mc_dev->obj_desc.region_count == 0)) return -EINVAL; @@ -397,19 +424,29 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) NULL, 0, &mc_dev->mc_io); if (error < 0) return error; + + mc_io_created = true; } - error = dprc_open(mc_dev->mc_io, mc_dev->obj_desc.id, + 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); goto error_cleanup_mc_io; } + error = dprc_get_attributes(mc_dev->mc_io, 0, mc_dev->mc_handle, + &mc_bus->dprc_attr); + if (error < 0) { + dev_err(&mc_dev->dev, "dprc_get_attributes() failed: %d\n", + error); + goto error_cleanup_open; + } + mutex_init(&mc_bus->scan_mutex); /* - * Discover MC objects in DPRC object: + * Discover MC objects in the DPRC object: */ error = dprc_scan_container(mc_dev); if (error < 0) @@ -419,10 +456,17 @@ 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); + if (mc_io_created) { + fsl_destroy_mc_io(mc_dev->mc_io); + mc_dev->mc_io = NULL; + } + + if (dev_root_set) + fsl_mc_bus_type.dev_root = NULL; + return error; } @@ -447,10 +491,13 @@ 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); + if (&mc_dev->dev == fsl_mc_bus_type.dev_root) + fsl_mc_bus_type.dev_root = NULL; + dev_info(&mc_dev->dev, "DPRC device unbound from driver"); return 0; } diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c index 19b26e6..a1cdafd 100644 --- a/drivers/staging/fsl-mc/bus/dprc.c +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -34,13 +34,16 @@ #include "../include/dprc.h" #include "dprc-cmd.h" -int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) +int dprc_open(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + int container_id, + uint16_t *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 +59,14 @@ int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token) } EXPORT_SYMBOL(dprc_open); -int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) +int dprc_close(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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*/ @@ -70,10 +75,11 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token) EXPORT_SYMBOL(dprc_close); int dprc_create_container(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, struct dprc_cfg *cfg, int *child_container_id, - uint64_t *child_portal_paddr) + uint64_t *child_portal_offset) { struct mc_command cmd = { 0 }; int err; @@ -82,9 +88,26 @@ 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,12 +116,14 @@ 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; } +EXPORT_SYMBOL(dprc_create_container); int dprc_destroy_container(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id) { @@ -106,14 +131,17 @@ int dprc_destroy_container(struct fsl_mc_io *mc_io, /* 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); } +EXPORT_SYMBOL(dprc_destroy_container); int dprc_reset_container(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id) { @@ -121,27 +149,28 @@ int dprc_reset_container(struct fsl_mc_io *mc_io, /* 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); } +EXPORT_SYMBOL(dprc_reset_container); int dprc_get_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t 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,37 +180,39 @@ 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; } +EXPORT_SYMBOL(dprc_get_irq); int dprc_set_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, - uint64_t irq_paddr, - uint32_t irq_val, - int user_irq_id) + 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); } +EXPORT_SYMBOL(dprc_set_irq); int dprc_get_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t *en) @@ -191,7 +222,8 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, /* 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*/ @@ -204,8 +236,10 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_irq_enable); int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t en) @@ -214,15 +248,18 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, /* 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); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_set_irq_enable); int dprc_get_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *mask) @@ -232,7 +269,8 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, /* 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*/ @@ -245,8 +283,10 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_irq_mask); int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t mask) @@ -255,15 +295,18 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, /* 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); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_set_irq_mask); int dprc_get_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *status) @@ -273,7 +316,8 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, /* 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*/ @@ -286,8 +330,10 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_irq_status); int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t status) @@ -296,15 +342,18 @@ int dprc_clear_irq_status(struct fsl_mc_io *mc_io, /* 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); /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_clear_irq_status); int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, struct dprc_attributes *attr) { @@ -313,7 +362,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*/ @@ -331,8 +380,10 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_attributes); int dprc_set_res_quota(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id, char *type, @@ -342,7 +393,8 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, /* 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]); @@ -365,8 +417,10 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_set_res_quota); int dprc_get_res_quota(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id, char *type, @@ -377,7 +431,8 @@ int dprc_get_res_quota(struct fsl_mc_io *mc_io, /* 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]); @@ -406,8 +461,10 @@ int dprc_get_res_quota(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_res_quota); int dprc_assign(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int container_id, struct dprc_res_req *res_req) @@ -416,7 +473,8 @@ 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); @@ -441,8 +499,10 @@ int dprc_assign(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_assign); int dprc_unassign(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id, struct dprc_res_req *res_req) @@ -451,7 +511,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); @@ -477,8 +537,10 @@ int dprc_unassign(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_unassign); int dprc_get_pool_count(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int *pool_count) { @@ -487,7 +549,8 @@ 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); @@ -499,8 +562,10 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_pool_count); int dprc_get_pool(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int pool_index, char *type) @@ -510,7 +575,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); @@ -539,15 +604,20 @@ int dprc_get_pool(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_pool); -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, + uint32_t cmd_flags, + uint16_t 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); @@ -562,6 +632,7 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count) EXPORT_SYMBOL(dprc_get_obj_count); int dprc_get_obj(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int obj_index, struct dprc_obj_desc *obj_desc) @@ -571,7 +642,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,12 +675,201 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, obj_desc->type[13] = mc_dec(cmd.params[4], 40, 8); obj_desc->type[14] = mc_dec(cmd.params[4], 48, 8); obj_desc->type[15] = '\0'; - + obj_desc->label[0] = mc_dec(cmd.params[5], 0, 8); + obj_desc->label[1] = mc_dec(cmd.params[5], 8, 8); + obj_desc->label[2] = mc_dec(cmd.params[5], 16, 8); + obj_desc->label[3] = mc_dec(cmd.params[5], 24, 8); + obj_desc->label[4] = mc_dec(cmd.params[5], 32, 8); + obj_desc->label[5] = mc_dec(cmd.params[5], 40, 8); + obj_desc->label[6] = mc_dec(cmd.params[5], 48, 8); + obj_desc->label[7] = mc_dec(cmd.params[5], 56, 8); + obj_desc->label[8] = mc_dec(cmd.params[6], 0, 8); + obj_desc->label[9] = mc_dec(cmd.params[6], 8, 8); + obj_desc->label[10] = mc_dec(cmd.params[6], 16, 8); + obj_desc->label[11] = mc_dec(cmd.params[6], 24, 8); + obj_desc->label[12] = mc_dec(cmd.params[6], 32, 8); + obj_desc->label[13] = mc_dec(cmd.params[6], 40, 8); + obj_desc->label[14] = mc_dec(cmd.params[6], 48, 8); + obj_desc->label[15] = '\0'; return 0; } EXPORT_SYMBOL(dprc_get_obj); +int dprc_get_obj_desc(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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 = (uint16_t)mc_dec(cmd.params[1], 0, 16); + obj_desc->vendor = (uint8_t)mc_dec(cmd.params[1], 16, 8); + obj_desc->region_count = (uint8_t)mc_dec(cmd.params[1], 24, 8); + obj_desc->state = (uint32_t)mc_dec(cmd.params[1], 32, 32); + obj_desc->ver_major = (uint16_t)mc_dec(cmd.params[2], 0, 16); + obj_desc->ver_minor = (uint16_t)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); + +int dprc_set_obj_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t 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); + +int dprc_get_obj_irq(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t 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 = (uint32_t)mc_dec(cmd.params[0], 0, 32); + irq_cfg->paddr = (uint64_t)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); + int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, char *type, int *res_count) @@ -621,7 +881,8 @@ 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]); @@ -652,6 +913,7 @@ int dprc_get_res_count(struct fsl_mc_io *mc_io, EXPORT_SYMBOL(dprc_get_res_count); int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, char *type, struct dprc_res_ids_range_desc *range_desc) @@ -661,7 +923,8 @@ 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,32 +959,8 @@ int dprc_get_res_ids(struct fsl_mc_io *mc_io, } EXPORT_SYMBOL(dprc_get_res_ids); -int dprc_get_portal_paddr(struct fsl_mc_io *mc_io, - uint16_t token, - int portal_id, - uint64_t *portal_addr) -{ - struct mc_command cmd = { 0 }; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_PORTAL_PADDR, - MC_CMD_PRI_LOW, token); - cmd.params[0] |= mc_enc(0, 32, portal_id); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - *portal_addr = mc_dec(cmd.params[1], 0, 64); - - return 0; -} -EXPORT_SYMBOL(dprc_get_portal_paddr); - int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, char *obj_type, int obj_id, @@ -733,7 +972,8 @@ 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 +999,83 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, return err; /* retrieve response parameters */ - region_desc->base_paddr = mc_dec(cmd.params[1], 0, 64); + region_desc->base_offset = mc_dec(cmd.params[1], 0, 64); region_desc->size = mc_dec(cmd.params[2], 0, 32); return 0; } EXPORT_SYMBOL(dprc_get_obj_region); +int dprc_set_obj_label(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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); + int dprc_connect(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t 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 +1092,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]); @@ -817,8 +1114,10 @@ int dprc_connect(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_connect); int dprc_disconnect(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, const struct dprc_endpoint *endpoint) { @@ -826,10 +1125,10 @@ int dprc_disconnect(struct fsl_mc_io *mc_io, /* 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]); @@ -850,22 +1149,24 @@ int dprc_disconnect(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } +EXPORT_SYMBOL(dprc_disconnect); int dprc_get_connection(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, - const struct dprc_endpoint *endpoint1, - struct dprc_endpoint *endpoint2, - int *state) + 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 +1191,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); @@ -911,3 +1212,4 @@ int dprc_get_connection(struct fsl_mc_io *mc_io, return 0; } +EXPORT_SYMBOL(dprc_get_connection); diff --git a/drivers/staging/fsl-mc/bus/mc-allocator.c b/drivers/staging/fsl-mc/bus/mc-allocator.c index e36235d..60fb3d5 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); @@ -284,12 +284,17 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_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; - if (mc_dev->flags & FSL_MC_IS_DPRC) { + if (!mc_dev) { + if (WARN_ON(!fsl_mc_bus_type.dev_root)) + return error; + + mc_bus_dev = to_fsl_mc_device(fsl_mc_bus_type.dev_root); + } else if (mc_dev->flags & FSL_MC_IS_DPRC) { mc_bus_dev = mc_dev; } else { if (WARN_ON(mc_dev->dev.parent->bus != &fsl_mc_bus_type)) @@ -304,23 +309,24 @@ 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 || + strcmp(dpmcp_dev->obj_desc.type, "dpmcp") != 0)) 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 +348,26 @@ 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(strcmp(dpmcp_dev->obj_desc.type, "dpmcp") != 0)) return; - if (WARN_ON(!resource->data)) + if (WARN_ON(dpmcp_dev->mc_io != mc_io)) + return; + + 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 +383,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; - - if (WARN_ON(resource->type != FSL_MC_POOL_DPMCP)) - return -EINVAL; + struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; - if (WARN_ON(!mc_dev)) + if (WARN_ON(!dpmcp_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); - if (error < 0) { - dev_err(&mc_dev->dev, "dpmcp_reset() failed: %d\n", error); - return error; - } - - error = dpmcp_close(mc_io, token); + error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle); 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; } @@ -491,16 +494,31 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev) goto error; 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; - error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, mc_dev); - if (error < 0) - goto error; + /* + * If mc_dev is the DPMCP object for the parent DPRC's built-in + * portal, we don't add this DPMCP to the DPMCP object pool, + * but instead allocate it directly to the parent DPRC (mc_bus_dev): + */ + if (strcmp(mc_dev->obj_desc.type, "dpmcp") == 0 && + mc_dev->obj_desc.id == mc_bus->dprc_attr.portal_id) { + error = fsl_mc_io_set_dpmcp(mc_bus_dev->mc_io, mc_dev); + if (error < 0) + goto error; + } else { + error = object_type_to_pool_type(mc_dev->obj_desc.type, + &pool_type); + if (error < 0) + goto error; + + error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, + mc_dev); + if (error < 0) + goto error; + } - dev_info(&mc_dev->dev, - "Allocatable MC object device bound to fsl_mc_allocator driver"); + dev_dbg(&mc_dev->dev, + "Allocatable MC object device bound to fsl_mc_allocator driver"); return 0; error: @@ -513,20 +531,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 766a659..749036b 100644 --- a/drivers/staging/fsl-mc/bus/mc-bus.c +++ b/drivers/staging/fsl-mc/bus/mc-bus.c @@ -39,18 +39,18 @@ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv) bool major_version_mismatch = false; bool minor_version_mismatch = false; - if (WARN_ON(!fsl_mc_bus_type.dev_root)) - goto out; - if (!mc_drv->match_id_table) goto out; /* * If the object is not 'plugged' don't match. * Only exception is the root DPRC, which is a special case. + * + * NOTE: Only when this function is invoked for the root DPRC, + * mc_dev->mc_io is not NULL */ if ((mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED) == 0 && - &mc_dev->dev != fsl_mc_bus_type.dev_root) + !mc_dev->mc_io) goto out; /* @@ -213,14 +213,14 @@ static int get_dprc_icid(struct fsl_mc_io *mc_io, 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,11 +230,12 @@ 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(enum dprc_region_type mc_region_type, + uint64_t mc_offset, phys_addr_t *phys_addr) { int i; struct fsl_mc *mc = dev_get_drvdata(fsl_mc_bus_type.dev_root->parent); @@ -243,7 +244,7 @@ static int translate_mc_addr(uint64_t mc_addr, phys_addr_t *phys_addr) /* * Do identity mapping: */ - *phys_addr = mc_addr; + *phys_addr = mc_offset; return 0; } @@ -251,10 +252,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 +272,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 +298,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 +308,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_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; } @@ -386,9 +406,6 @@ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc, } mc_io2 = mc_io; - - if (!fsl_mc_bus_type.dev_root) - fsl_mc_bus_type.dev_root = &mc_dev->dev; } error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid); @@ -473,7 +490,8 @@ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev) if (&mc_dev->dev == fsl_mc_bus_type.dev_root) fsl_mc_bus_type.dev_root = NULL; - } + } else + WARN_ON(mc_dev->mc_io != NULL); if (mc_bus) devm_kfree(mc_dev->dev.parent, mc_bus); @@ -574,12 +592,14 @@ static int get_mc_addr_translation_ranges(struct device *dev, for (i = 0; i < *num_ranges; ++i) { struct fsl_mc_addr_translation_range *range = &(*ranges)[i]; - range->start_mc_addr = of_read_number(cell, mc_addr_cells); + range->mc_region_type = of_read_number(cell, 1); + range->start_mc_offset = of_read_number(cell + 1, + mc_addr_cells - 1); cell += mc_addr_cells; range->start_phys_addr = of_read_number(cell, paddr_cells); cell += paddr_cells; - range->end_mc_addr = range->start_mc_addr + - of_read_number(cell, mc_size_cells); + range->end_mc_offset = range->start_mc_offset + + of_read_number(cell, mc_size_cells); cell += mc_size_cells; } @@ -630,7 +650,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 +681,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 +693,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); @@ -713,6 +734,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 5737f59..dc3aedb 100644 --- a/drivers/staging/fsl-mc/bus/mc-sys.c +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -34,15 +34,16 @@ #include "../include/mc-sys.h" #include "../include/mc-cmd.h" +#include "../include/mc.h" #include <linux/delay.h> #include <linux/slab.h> #include <linux/ioport.h> #include <linux/device.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 @@ -70,9 +71,10 @@ 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, + struct fsl_mc_device *dpmcp_dev, uint32_t 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 +87,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 +114,19 @@ 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,39 @@ 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) +{ + 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; + + 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) +{ + 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; + + 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[] = { @@ -223,26 +278,13 @@ static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem * return status; } -/** - * Sends an 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. - * - * NOTE: This function cannot be invoked from from atomic contexts. - */ -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,17 +313,103 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) } } - 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, - (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header), - (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header), - mc_status_to_string(status), - (unsigned int)status); - - return mc_status_to_error(status); + *mc_status = status; + return 0; +} + +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, + (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header), + (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header), + mc_status_to_string(status), + (unsigned int)status); + + error = mc_status_to_error(status); + goto common_exit; + } + + 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 1fd70a21..be80c03 100644 --- a/drivers/staging/fsl-mc/include/dpbp-cmd.h +++ b/drivers/staging/fsl-mc/include/dpbp-cmd.h @@ -1,40 +1,40 @@ -/* Copyright 2013-2014 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. -*/ +/* 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. + */ #ifndef _FSL_DPBP_CMD_H #define _FSL_DPBP_CMD_H /* DPBP Version */ #define DPBP_VER_MAJOR 2 -#define DPBP_VER_MINOR 0 +#define DPBP_VER_MINOR 1 /* Command IDs */ #define DPBP_CMDID_CLOSE 0x800 @@ -57,4 +57,87 @@ #define DPBP_CMDID_GET_IRQ_STATUS 0x016 #define DPBP_CMDID_CLEAR_IRQ_STATUS 0x017 +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_CMD_OPEN(cmd, dpbp_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_RSP_IS_ENABLED(cmd, en) \ + MC_RSP_OP(cmd, 0, 0, 1, int, en) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr); \ + MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->user_irq_id); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_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 DPBP_RSP_GET_IRQ(cmd, type, irq_cfg) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val); \ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr); \ + MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->user_irq_id); \ + MC_RSP_OP(cmd, 2, 32, 32, int, type); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_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 DPBP_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 DPBP_RSP_GET_IRQ_ENABLE(cmd, en) \ + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_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 DPBP_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 DPBP_RSP_GET_IRQ_MASK(cmd, mask) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_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 DPBP_RSP_GET_IRQ_STATUS(cmd, status) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status) + +/* cmd, param, offset, width, type, arg_name */ +#define DPBP_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 DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \ + 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_DPBP_CMD_H */ diff --git a/drivers/staging/fsl-mc/include/dpbp.h b/drivers/staging/fsl-mc/include/dpbp.h index 5f3c8e7..5d16bb1 100644 --- a/drivers/staging/fsl-mc/include/dpbp.h +++ b/drivers/staging/fsl-mc/include/dpbp.h @@ -41,6 +41,7 @@ struct fsl_mc_io; /** * 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 * @@ -54,11 +55,15 @@ struct fsl_mc_io; * * 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, + uint32_t cmd_flags, + int dpbp_id, + 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 @@ -66,10 +71,12 @@ int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token); * * 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, + uint32_t cmd_flags, + uint16_t token); /** - * struct dpbp_cfg() - Structure representing DPBP configuration + * struct dpbp_cfg - Structure representing DPBP configuration * @options: place holder */ struct dpbp_cfg { @@ -79,6 +86,7 @@ struct dpbp_cfg { /** * 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 * @@ -97,99 +105,123 @@ struct dpbp_cfg { * Return: '0' on Success; Error code otherwise. */ int dpbp_create(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, const struct dpbp_cfg *cfg, 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, uint16_t token); +int dpbp_destroy(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + 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, uint16_t token); +int dpbp_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + 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, uint16_t token); +int dpbp_disable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); /** * 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, uint16_t token, int *en); +int dpbp_is_enabled(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + int *en); /** * 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, uint16_t token); +int dpbp_reset(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); + +/** + * 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 + */ +struct dpbp_irq_cfg { + uint64_t addr; + uint32_t val; + int user_irq_id; +}; /** * 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_addr: Address that must be written to - * signal a message-based interrupt - * @irq_val: Value to write into irq_addr address - * @user_irq_id: A user defined number associated with this IRQ + * @irq_cfg: IRQ configuration * * Return: '0' on Success; Error code otherwise. */ int dpbp_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 dpbp_irq_cfg *irq_cfg); /** * 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_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 + * 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, + 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 dpbp_irq_cfg *irq_cfg); /** * 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 @@ -202,6 +234,7 @@ int dpbp_get_irq(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t en); @@ -209,6 +242,7 @@ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, /** * 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 @@ -216,6 +250,7 @@ int dpbp_set_irq_enable(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t *en); @@ -223,6 +258,7 @@ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, /** * 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; @@ -236,6 +272,7 @@ int dpbp_get_irq_enable(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t mask); @@ -243,6 +280,7 @@ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, /** * 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 @@ -253,6 +291,7 @@ int dpbp_set_irq_mask(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *mask); @@ -261,6 +300,7 @@ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, * 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: @@ -270,6 +310,7 @@ int dpbp_get_irq_mask(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *status); @@ -278,6 +319,7 @@ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, * 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: @@ -287,6 +329,7 @@ int dpbp_get_irq_status(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dpbp_clear_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t status); @@ -316,12 +359,14 @@ struct dpbp_attr { * 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, + uint32_t cmd_flags, uint16_t 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 c878d33..0c1fc63 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 @@ -59,4 +59,101 @@ #define DPCON_CMDID_SET_NOTIFICATION 0x100 +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_CMD_OPEN(cmd, dpcon_id) \ + MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_CMD_CREATE(cmd, cfg) \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_priorities) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_RSP_IS_ENABLED(cmd, en) \ + MC_RSP_OP(cmd, 0, 0, 1, int, en) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\ + MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\ + MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->user_irq_id); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_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 DPCON_RSP_GET_IRQ(cmd, type, irq_cfg) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val);\ + MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\ + MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->user_irq_id); \ + MC_RSP_OP(cmd, 2, 32, 32, int, type);\ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_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 DPCON_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 DPCON_RSP_GET_IRQ_ENABLE(cmd, en) \ + MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_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 DPCON_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 DPCON_RSP_GET_IRQ_MASK(cmd, mask) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_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 DPCON_RSP_GET_IRQ_STATUS(cmd, status) \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_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 DPCON_RSP_GET_ATTR(cmd, attr) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\ + MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_ch_id);\ + MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\ + 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) + +/* cmd, param, offset, width, type, arg_name */ +#define DPCON_CMD_SET_NOTIFICATION(cmd, cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dpio_id);\ + MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->priority);\ + MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx);\ +} while (0) + #endif /* _FSL_DPCON_CMD_H */ diff --git a/drivers/staging/fsl-mc/include/dpmng.h b/drivers/staging/fsl-mc/include/dpmng.h index 1b052b8..4a0996c 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 @@ -62,19 +62,25 @@ struct mc_version { * 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, struct mc_version *mc_ver_info); +int mc_get_version(struct fsl_mc_io *mc_io, + uint32_t 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 + * @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, int *container_id); +int dpmng_get_container_id(struct fsl_mc_io *mc_io, + uint32_t 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 f1862a7..253ef7d 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 */ @@ -55,6 +57,7 @@ struct fsl_mc_io; /** * 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 * @@ -62,11 +65,15 @@ struct fsl_mc_io; * * @warning Required before any operation on the object. */ -int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); +int dprc_open(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + int container_id, + 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 @@ -74,7 +81,9 @@ int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token); * * Return: '0' on Success; Error code otherwise. */ -int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); +int dprc_close(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token); /** * Container general options @@ -99,7 +108,7 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); /* Object initialization allowed - software context associated with this * container is allowed to invoke object initialization operations. */ -#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 +#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004 /* Topology change allowed - software context associated with this * container is allowed to invoke topology operations, such as attach/detach @@ -115,6 +124,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,33 +134,37 @@ int dprc_close(struct fsl_mc_io *mc_io, uint16_t token); * @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free * portal ID is allocated by the DPRC * @options: Combination of 'DPRC_CFG_OPT_<X>' options + * @label: Object's label */ struct dprc_cfg { - uint16_t icid; - int portal_id; - uint64_t options; + uint16_t icid; + int portal_id; + uint64_t options; + char label[16]; }; /** * 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_paddr: Returned base physical address of the - * child portal + * @child_portal_offset: Returned child portal offset from MC portal base * * Return: '0' on Success; Error code otherwise. */ int dprc_create_container(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, struct dprc_cfg *cfg, int *child_container_id, - uint64_t *child_portal_paddr); + uint64_t *child_portal_offset); /** * 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 * @@ -168,12 +184,14 @@ int dprc_create_container(struct fsl_mc_io *mc_io, * */ int dprc_destroy_container(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id); /** * 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 * @@ -192,25 +210,33 @@ int dprc_destroy_container(struct fsl_mc_io *mc_io, * * Return: '0' on Success; Error code otherwise. */ -int dprc_reset_container(struct fsl_mc_io *mc_io, - uint16_t token, - int child_container_id); +int dprc_reset_container(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t 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,49 +251,56 @@ int dprc_reset_container(struct fsl_mc_io *mc_io, #define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 /** + * 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 { + uint64_t paddr; + uint32_t val; + int user_irq_id; +}; + +/** * 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_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 + * @irq_cfg: IRQ configuration * * Return: '0' on Success; Error code otherwise. */ int dprc_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 dprc_irq_cfg *irq_cfg); /** * 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: 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 + * @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, + 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 dprc_irq_cfg *irq_cfg); /** * 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 @@ -280,6 +313,7 @@ int dprc_get_irq(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t en); @@ -287,6 +321,7 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, /** * 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 @@ -294,6 +329,7 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint8_t *en); @@ -301,6 +337,7 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, /** * 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; @@ -314,6 +351,7 @@ int dprc_get_irq_enable(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t mask); @@ -321,6 +359,7 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, /** * 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 @@ -331,6 +370,7 @@ int dprc_set_irq_mask(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *mask); @@ -338,6 +378,7 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, /** * 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: @@ -347,6 +388,7 @@ int dprc_get_irq_mask(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t *status); @@ -354,6 +396,7 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, /** * 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: @@ -363,6 +406,7 @@ int dprc_get_irq_status(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, uint8_t irq_index, uint32_t status); @@ -394,12 +438,14 @@ struct dprc_attributes { /** * 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 + * @attributes: Returned container attributes * * Return: '0' on Success; Error code otherwise. */ int dprc_get_attributes(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, struct dprc_attributes *attributes); @@ -407,6 +453,7 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, * 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 @@ -428,6 +475,7 @@ int dprc_get_attributes(struct fsl_mc_io *mc_io, * @warning Only the parent container is allowed to change a child policy. */ int dprc_set_res_quota(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id, char *type, @@ -437,8 +485,9 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, * 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 + * @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; @@ -448,6 +497,7 @@ int dprc_set_res_quota(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_res_quota(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id, char *type, @@ -500,6 +550,7 @@ struct dprc_res_req { /** * 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 @@ -529,6 +580,7 @@ struct dprc_res_req { * Return: '0' on Success; Error code otherwise. */ int dprc_assign(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int container_id, struct dprc_res_req *res_req); @@ -537,6 +589,7 @@ int dprc_assign(struct fsl_mc_io *mc_io, * 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 @@ -548,12 +601,14 @@ int dprc_assign(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_unassign(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int child_container_id, struct dprc_res_req *res_req); /** * 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 @@ -561,14 +616,16 @@ int dprc_unassign(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_pool_count(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t 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 + * @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) + * @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 @@ -579,6 +636,7 @@ int dprc_get_pool_count(struct fsl_mc_io *mc_io, * Return: '0' on Success; Error code otherwise. */ int dprc_get_pool(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int pool_index, char *type); @@ -586,12 +644,16 @@ int dprc_get_pool(struct fsl_mc_io *mc_io, /** * 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, uint16_t token, int *obj_count); +int dprc_get_obj_count(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + int *obj_count); /* Objects Attributes Flags */ @@ -610,6 +672,7 @@ 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]; @@ -620,11 +683,13 @@ struct dprc_obj_desc { uint8_t irq_count; uint8_t region_count; uint32_t state; + char label[16]; }; /** * 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 @@ -637,14 +702,79 @@ struct dprc_obj_desc { * Return: '0' on Success; Error code otherwise. */ int dprc_get_obj(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, int obj_index, struct dprc_obj_desc *obj_desc); /** + * 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, + uint32_t cmd_flags, + uint16_t token, + char *obj_type, + int obj_id, + struct dprc_obj_desc *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, + uint32_t cmd_flags, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t irq_index, + struct dprc_irq_cfg *irq_cfg); + +/** + * 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, + uint32_t cmd_flags, + uint16_t token, + char *obj_type, + int obj_id, + uint8_t irq_index, + int *type, + struct dprc_irq_cfg *irq_cfg); + +/** * 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 @@ -652,7 +782,8 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, * * Return: '0' on Success; Error code otherwise. */ -int dprc_get_res_count(struct fsl_mc_io *mc_io, +int dprc_get_res_count(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, char *type, int *res_count); @@ -687,6 +818,7 @@ struct dprc_res_ids_range_desc { /** * 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 @@ -694,39 +826,48 @@ struct dprc_res_ids_range_desc { * Return: '0' on Success; Error code otherwise. */ int dprc_get_res_ids(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t 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; + uint32_t base_offset; + uint32_t size; + uint32_t 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 + * @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_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 @@ -734,6 +875,7 @@ struct dprc_region_desc { * Return: '0' on Success; Error code otherwise. */ int dprc_get_obj_region(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, uint16_t token, char *obj_type, int obj_id, @@ -741,57 +883,102 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, struct dprc_region_desc *region_desc); /** + * 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, + uint32_t cmd_flags, + uint16_t 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; +}; + +/** + * 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 { + uint32_t committed_rate; + uint32_t max_rate; }; /** * 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, - const struct dprc_endpoint *endpoint1, - const struct dprc_endpoint *endpoint2); +int dprc_connect(struct fsl_mc_io *mc_io, + uint32_t cmd_flags, + uint16_t token, + const struct dprc_endpoint *endpoint1, + 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 + * @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, + uint32_t cmd_flags, uint16_t 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 +* @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, + uint32_t cmd_flags, uint16_t token, const struct dprc_endpoint *endpoint1, struct dprc_endpoint *endpoint2, diff --git a/drivers/staging/fsl-mc/include/mc-cmd.h b/drivers/staging/fsl-mc/include/mc-cmd.h index 32501e0..57fefd2 100644 --- a/drivers/staging/fsl-mc/include/mc-cmd.h +++ b/drivers/staging/fsl-mc/include/mc-cmd.h @@ -67,14 +67,29 @@ 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), \ @@ -83,8 +98,8 @@ enum mc_cmd_status { #define MC_CMD_HDR_READ_TOKEN(_hdr) \ ((uint16_t)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) \ + ((uint32_t)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)) @@ -96,14 +111,15 @@ enum mc_cmd_status { (_arg = (_type)mc_dec(_cmd.params[_param], (_offset), (_width))) static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, - uint8_t priority, + uint32_t cmd_flags, uint16_t token) { uint64_t 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 c045f49..03809d2 100644 --- a/drivers/staging/fsl-mc/include/mc-private.h +++ b/drivers/staging/fsl-mc/include/mc-private.h @@ -29,7 +29,8 @@ /** * 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; @@ -40,14 +41,16 @@ struct fsl_mc { /** * 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; + uint64_t start_mc_offset; + uint64_t end_mc_offset; phys_addr_t start_phys_addr; }; @@ -77,11 +80,13 @@ struct fsl_mc_resource_pool { * for this MC bus. These resources represent allocatable entities * from the physical DPRC. * @scan_mutex: Serializes bus scanning + * @dprc_attr: DPRC attributes */ struct fsl_mc_bus { struct fsl_mc_device mc_dev; struct fsl_mc_resource_pool resource_pools[FSL_MC_NUM_POOL_TYPES]; struct mutex scan_mutex; /* serializes bus scanning */ + struct dprc_attributes dprc_attr; }; #define to_fsl_mc_bus(_mc_dev) \ diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h index cb3b5a2..f2a9214 100644 --- a/drivers/staging/fsl-mc/include/mc-sys.h +++ b/drivers/staging/fsl-mc/include/mc-sys.h @@ -39,6 +39,13 @@ #include <linux/errno.h> #include <linux/io.h> #include <linux/dma-mapping.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> + +/** + * 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; + uint16_t flags; + uint16_t 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, + struct fsl_mc_device *dpmcp_dev, uint32_t 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 */ -- 2.3.3 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel