summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorMadalin Bucur <madalin.bucur@freescale.com>2015-01-15 10:32:38 (GMT)
committerMadalin Bucur <madalin.bucur@freescale.com>2015-02-25 16:27:05 (GMT)
commit350e0ecf99128144bd11c48fc2267007371701f1 (patch)
treeef2e7f8951be05a6f38594a543daaf344caea33f /drivers/staging
parent7bc67b0e3d1346d641aa5ff36540cce264d10265 (diff)
downloadlinux-fsl-qoriq-350e0ecf99128144bd11c48fc2267007371701f1.tar.xz
fsl_qman: add qman_delete_cgr_safe()
Add qman_delete_cgr_safe() that can be called from any CPU. This in turn schedules qman_delete_cgr() on the proper CPU. Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com> Change-Id: I762e83108533a4e537a534e90073df26a6b7b09c Reviewed-on: http://git.am.freescale.net:8181/28532 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Marian Cristian Rotariu <marian.rotariu@freescale.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/fsl_qbman/qman_high.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c
index 374ebf6..c3a341c 100644
--- a/drivers/staging/fsl_qbman/qman_high.c
+++ b/drivers/staging/fsl_qbman/qman_high.c
@@ -2556,6 +2556,8 @@ EXPORT_SYMBOL(qman_modify_cgr);
QM_CHANNEL_SWPORTAL0))
#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
+static u8 qman_cgr_cpus[__CGR_NUM];
+
int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
struct qm_mcc_initcgr *opts)
{
@@ -2572,7 +2574,10 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
if (cgr->cgrid >= __CGR_NUM)
return -EINVAL;
+ preempt_disable();
p = get_affine_portal();
+ qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
+ preempt_enable();
memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
cgr->chan = p->config->public_cfg.channel;
@@ -2715,6 +2720,47 @@ put_portal:
}
EXPORT_SYMBOL(qman_delete_cgr);
+struct cgr_comp {
+ struct qman_cgr *cgr;
+ struct completion completion;
+};
+
+static int qman_delete_cgr_thread(void *p)
+{
+ struct cgr_comp *cgr_comp = (struct cgr_comp *)p;
+ int res;
+
+ res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr);
+ complete(&cgr_comp->completion);
+
+ return res;
+}
+
+void qman_delete_cgr_safe(struct qman_cgr *cgr)
+{
+ struct task_struct *thread;
+ struct cgr_comp cgr_comp;
+
+ preempt_disable();
+ if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
+ init_completion(&cgr_comp.completion);
+ cgr_comp.cgr = cgr;
+ thread = kthread_create(qman_delete_cgr_thread, &cgr_comp,
+ "cgr_del");
+
+ if (likely(!IS_ERR(thread))) {
+ kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]);
+ wake_up_process(thread);
+ wait_for_completion(&cgr_comp.completion);
+ preempt_enable();
+ return;
+ }
+ }
+ qman_delete_cgr(cgr);
+ preempt_enable();
+}
+EXPORT_SYMBOL(qman_delete_cgr_safe);
+
int qm_get_clock(u64 *clock_hz)
{
if (!qman_clk) {