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: Roy Pledge <roy.pledge@nxp.com> Signed-off-by: Li Yang <leoyang.li@nxp.com>
This commit is contained in:
Родитель
97777078d6
Коммит
0505d00c8d
|
@ -635,30 +635,31 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bm_shutdown_pool(u32 bpid)
|
||||
int bm_shutdown_pool(u32 bpid)
|
||||
{
|
||||
int err = 0;
|
||||
struct bm_mc_command *bm_cmd;
|
||||
union bm_mc_result *bm_res;
|
||||
|
||||
|
||||
struct bman_portal *p = get_affine_portal();
|
||||
while (1) {
|
||||
struct bman_portal *p = get_affine_portal();
|
||||
/* Acquire buffers until empty */
|
||||
bm_cmd = bm_mc_start(&p->p);
|
||||
bm_cmd->bpid = bpid;
|
||||
bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | 1);
|
||||
if (!bm_mc_result_timeout(&p->p, &bm_res)) {
|
||||
put_affine_portal();
|
||||
pr_crit("BMan Acquire Command timedout\n");
|
||||
return -ETIMEDOUT;
|
||||
err = -ETIMEDOUT;
|
||||
goto done;
|
||||
}
|
||||
if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
|
||||
put_affine_portal();
|
||||
/* Pool is empty */
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
put_affine_portal();
|
||||
}
|
||||
|
||||
done:
|
||||
put_affine_portal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -195,6 +195,16 @@ int bman_is_probed(void)
|
|||
}
|
||||
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)
|
||||
{
|
||||
int ret, err_irq;
|
||||
|
|
|
@ -100,7 +100,7 @@ static int bman_portal_probe(struct platform_device *pdev)
|
|||
struct device_node *node = dev->of_node;
|
||||
struct bm_portal_config *pcfg;
|
||||
struct resource *addr_phys[2];
|
||||
int irq, cpu, err;
|
||||
int irq, cpu, err, i;
|
||||
|
||||
err = bman_is_probed();
|
||||
if (!err)
|
||||
|
@ -176,6 +176,22 @@ static int bman_portal_probe(struct platform_device *pdev)
|
|||
if (!cpu_online(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;
|
||||
|
||||
err_portal_init:
|
||||
|
|
|
@ -76,3 +76,8 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits);
|
|||
|
||||
const struct bm_portal_config *
|
||||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче