Commit 0505d00c authored by Roy Pledge's avatar Roy Pledge Committed by Li Yang

soc/fsl/qbman: Cleanup buffer pools if BMan was initialized prior to bootup

Clean the BMan buffer pools if the device had been initialized
previously.  This will ensure a consistent state if the kernel
was soft restarted (kexec for example)
Signed-off-by: default avatarRoy Pledge <roy.pledge@nxp.com>
Signed-off-by: default avatarLi Yang <leoyang.li@nxp.com>
parent 97777078
...@@ -635,30 +635,31 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits) ...@@ -635,30 +635,31 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits)
return 0; return 0;
} }
static int bm_shutdown_pool(u32 bpid) int bm_shutdown_pool(u32 bpid)
{ {
int err = 0;
struct bm_mc_command *bm_cmd; struct bm_mc_command *bm_cmd;
union bm_mc_result *bm_res; union bm_mc_result *bm_res;
struct bman_portal *p = get_affine_portal();
while (1) { while (1) {
struct bman_portal *p = get_affine_portal();
/* Acquire buffers until empty */ /* Acquire buffers until empty */
bm_cmd = bm_mc_start(&p->p); bm_cmd = bm_mc_start(&p->p);
bm_cmd->bpid = bpid; bm_cmd->bpid = bpid;
bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | 1); bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | 1);
if (!bm_mc_result_timeout(&p->p, &bm_res)) { if (!bm_mc_result_timeout(&p->p, &bm_res)) {
put_affine_portal();
pr_crit("BMan Acquire Command timedout\n"); pr_crit("BMan Acquire Command timedout\n");
return -ETIMEDOUT; err = -ETIMEDOUT;
goto done;
} }
if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) { if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
put_affine_portal();
/* Pool is empty */ /* Pool is empty */
return 0; goto done;
} }
put_affine_portal();
} }
done:
put_affine_portal();
return 0; return 0;
} }
......
...@@ -195,6 +195,16 @@ int bman_is_probed(void) ...@@ -195,6 +195,16 @@ int bman_is_probed(void)
} }
EXPORT_SYMBOL_GPL(bman_is_probed); EXPORT_SYMBOL_GPL(bman_is_probed);
int bman_requires_cleanup(void)
{
return __bman_requires_cleanup;
}
void bman_done_cleanup(void)
{
__bman_requires_cleanup = 0;
}
static int fsl_bman_probe(struct platform_device *pdev) static int fsl_bman_probe(struct platform_device *pdev)
{ {
int ret, err_irq; int ret, err_irq;
......
...@@ -100,7 +100,7 @@ static int bman_portal_probe(struct platform_device *pdev) ...@@ -100,7 +100,7 @@ static int bman_portal_probe(struct platform_device *pdev)
struct device_node *node = dev->of_node; struct device_node *node = dev->of_node;
struct bm_portal_config *pcfg; struct bm_portal_config *pcfg;
struct resource *addr_phys[2]; struct resource *addr_phys[2];
int irq, cpu, err; int irq, cpu, err, i;
err = bman_is_probed(); err = bman_is_probed();
if (!err) if (!err)
...@@ -176,6 +176,22 @@ static int bman_portal_probe(struct platform_device *pdev) ...@@ -176,6 +176,22 @@ static int bman_portal_probe(struct platform_device *pdev)
if (!cpu_online(cpu)) if (!cpu_online(cpu))
bman_offline_cpu(cpu); bman_offline_cpu(cpu);
if (__bman_portals_probed == 1 && bman_requires_cleanup()) {
/*
* BMan wasn't reset prior to boot (Kexec for example)
* Empty all the buffer pools so they are in reset state
*/
for (i = 0; i < BM_POOL_MAX; i++) {
err = bm_shutdown_pool(i);
if (err) {
dev_err(dev, "Failed to shutdown bpool %d\n",
i);
goto err_portal_init;
}
}
bman_done_cleanup();
}
return 0; return 0;
err_portal_init: err_portal_init:
......
...@@ -76,3 +76,8 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits); ...@@ -76,3 +76,8 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits);
const struct bm_portal_config * const struct bm_portal_config *
bman_get_bm_portal_config(const struct bman_portal *portal); bman_get_bm_portal_config(const struct bman_portal *portal);
int bman_requires_cleanup(void);
void bman_done_cleanup(void);
int bm_shutdown_pool(u32 bpid);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment