summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/fsl_qbman/bman_driver.c25
-rw-r--r--drivers/staging/fsl_qbman/bman_private.h1
-rw-r--r--drivers/staging/fsl_qbman/fsl_usdpaa.c10
-rw-r--r--drivers/staging/fsl_qbman/qman_driver.c27
-rw-r--r--drivers/staging/fsl_qbman/qman_private.h2
-rw-r--r--include/linux/fsl_usdpaa.h12
6 files changed, 72 insertions, 5 deletions
diff --git a/drivers/staging/fsl_qbman/bman_driver.c b/drivers/staging/fsl_qbman/bman_driver.c
index 06b77ed..27a5b0f 100644
--- a/drivers/staging/fsl_qbman/bman_driver.c
+++ b/drivers/staging/fsl_qbman/bman_driver.c
@@ -198,11 +198,34 @@ static struct bm_portal_config *get_pcfg(struct list_head *list)
return pcfg;
}
+static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
+ uint32_t idx)
+{
+ struct bm_portal_config *pcfg;
+ if (list_empty(list))
+ return NULL;
+ list_for_each_entry(pcfg, list, list) {
+ if (pcfg->public_cfg.index == idx) {
+ list_del(&pcfg->list);
+ return pcfg;
+ }
+ }
+ return NULL;
+}
+
struct bm_portal_config *bm_get_unused_portal(void)
{
+ return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
+}
+
+struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
+{
struct bm_portal_config *ret;
spin_lock(&unused_pcfgs_lock);
- ret = get_pcfg(&unused_pcfgs);
+ if (idx == QBMAN_ANY_PORTAL_IDX)
+ ret = get_pcfg(&unused_pcfgs);
+ else
+ ret = get_pcfg_idx(&unused_pcfgs, idx);
spin_unlock(&unused_pcfgs_lock);
return ret;
}
diff --git a/drivers/staging/fsl_qbman/bman_private.h b/drivers/staging/fsl_qbman/bman_private.h
index 53aa21b..2df9857 100644
--- a/drivers/staging/fsl_qbman/bman_private.h
+++ b/drivers/staging/fsl_qbman/bman_private.h
@@ -80,6 +80,7 @@ const struct bm_portal_config *bman_destroy_affine_portal(void);
/* Hooks from fsl_usdpaa.c to bman_driver.c */
struct bm_portal_config *bm_get_unused_portal(void);
+struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
void bm_put_unused_portal(struct bm_portal_config *pcfg);
void bm_set_liodns(struct bm_portal_config *pcfg);
diff --git a/drivers/staging/fsl_qbman/fsl_usdpaa.c b/drivers/staging/fsl_qbman/fsl_usdpaa.c
index 0167b7b..aebbc15 100644
--- a/drivers/staging/fsl_qbman/fsl_usdpaa.c
+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
@@ -1047,7 +1047,8 @@ static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
return -ENOMEM;
memcpy(&mapping->user, arg, sizeof(mapping->user));
if (mapping->user.type == usdpaa_portal_qman) {
- mapping->qportal = qm_get_unused_portal();
+ mapping->qportal =
+ qm_get_unused_portal_idx(mapping->user.index);
if (!mapping->qportal) {
ret = -ENODEV;
goto err_get_portal;
@@ -1055,13 +1056,16 @@ static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
mapping->phys = &mapping->qportal->addr_phys[0];
mapping->user.channel = mapping->qportal->public_cfg.channel;
mapping->user.pools = mapping->qportal->public_cfg.pools;
+ mapping->user.index = mapping->qportal->public_cfg.index;
} else if (mapping->user.type == usdpaa_portal_bman) {
- mapping->bportal = bm_get_unused_portal();
+ mapping->bportal =
+ bm_get_unused_portal_idx(mapping->user.index);
if (!mapping->bportal) {
ret = -ENODEV;
goto err_get_portal;
}
mapping->phys = &mapping->bportal->addr_phys[0];
+ mapping->user.index = mapping->bportal->public_cfg.index;
} else {
ret = -EINVAL;
goto err_copy_from_user;
@@ -1255,11 +1259,13 @@ static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
if (copy_from_user(&input, a, sizeof(input)))
return -EFAULT;
converted.type = input.type;
+ converted.index = input.index;
ret = ioctl_portal_map(fp, ctx, &converted);
input.addr.cinh = ptr_to_compat(converted.addr.cinh);
input.addr.cena = ptr_to_compat(converted.addr.cena);
input.channel = converted.channel;
input.pools = converted.pools;
+ input.index = converted.index;
if (copy_to_user(a, &input, sizeof(input)))
return -EFAULT;
return ret;
diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c
index 875c0df..b2f60d7 100644
--- a/drivers/staging/fsl_qbman/qman_driver.c
+++ b/drivers/staging/fsl_qbman/qman_driver.c
@@ -454,6 +454,21 @@ static struct qm_portal_config *get_pcfg(struct list_head *list)
return pcfg;
}
+static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
+{
+ struct qm_portal_config *pcfg;
+ if (list_empty(list))
+ return NULL;
+ list_for_each_entry(pcfg, list, list) {
+ if (pcfg->public_cfg.index == idx) {
+ list_del(&pcfg->list);
+ return pcfg;
+ }
+ }
+ return NULL;
+}
+
+
static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
{
int ret;
@@ -530,11 +545,14 @@ _iommu_domain_free:
iommu_domain_free(pcfg->iommu_domain);
}
-struct qm_portal_config *qm_get_unused_portal(void)
+struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
{
struct qm_portal_config *ret;
spin_lock(&unused_pcfgs_lock);
- ret = get_pcfg(&unused_pcfgs);
+ if (idx == QBMAN_ANY_PORTAL_IDX)
+ ret = get_pcfg(&unused_pcfgs);
+ else
+ ret = get_pcfg_idx(&unused_pcfgs, idx);
spin_unlock(&unused_pcfgs_lock);
/* Bind stashing LIODNs to the CPU we are currently executing on, and
* set the portal to use the stashing request queue corresonding to the
@@ -549,6 +567,11 @@ struct qm_portal_config *qm_get_unused_portal(void)
return ret;
}
+struct qm_portal_config *qm_get_unused_portal()
+{
+ return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
+}
+
void qm_put_unused_portal(struct qm_portal_config *pcfg)
{
spin_lock(&unused_pcfgs_lock);
diff --git a/drivers/staging/fsl_qbman/qman_private.h b/drivers/staging/fsl_qbman/qman_private.h
index 6179943..a701006 100644
--- a/drivers/staging/fsl_qbman/qman_private.h
+++ b/drivers/staging/fsl_qbman/qman_private.h
@@ -218,6 +218,8 @@ void qman_destroy_portal(struct qman_portal *qm);
/* Hooks from fsl_usdpaa.c to qman_driver.c */
struct qm_portal_config *qm_get_unused_portal(void);
+struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
+
void qm_put_unused_portal(struct qm_portal_config *pcfg);
void qm_set_liodns(struct qm_portal_config *pcfg);
diff --git a/include/linux/fsl_usdpaa.h b/include/linux/fsl_usdpaa.h
index de017a6..fbf9480 100644
--- a/include/linux/fsl_usdpaa.h
+++ b/include/linux/fsl_usdpaa.h
@@ -165,9 +165,17 @@ enum usdpaa_portal_type {
usdpaa_portal_bman,
};
+#define QBMAN_ANY_PORTAL_IDX 0xffffffff
+
struct usdpaa_ioctl_portal_map {
/* Input parameter, is a qman or bman portal required. */
+
enum usdpaa_portal_type type;
+ /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
+ for don't care. The portal index will be populated by the
+ driver when the ioctl() successfully completes */
+ uint32_t index;
+
/* Return value if the map succeeds, this gives the mapped
* cache-inhibited (cinh) and cache-enabled (cena) addresses. */
struct usdpaa_portal_map {
@@ -183,6 +191,10 @@ struct usdpaa_ioctl_portal_map {
struct compat_usdpaa_ioctl_portal_map {
/* Input parameter, is a qman or bman portal required. */
enum usdpaa_portal_type type;
+ /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
+ for don't care. The portal index will be populated by the
+ driver when the ioctl() successfully completes */
+ uint32_t index;
/* Return value if the map succeeds, this gives the mapped
* cache-inhibited (cinh) and cache-enabled (cena) addresses. */
struct usdpaa_portal_map_compat {