Commit af22527e authored by Scott Branden's avatar Scott Branden Committed by Greg Kroah-Hartman

misc: bcm-vk: add triggers when host panic or reboots to notify card

Pass down an interrupt to card in case of panic or reboot so
that card can take appropriate action to perform a clean reset.
Uses kernel notifier block either directly (register on panic list),
or implicitly (add shutdown method for PCI device).
Co-developed-by: default avatarDesmond Yan <desmond.yan@broadcom.com>
Acked-by: default avatarOlof Johansson <olof@lixom.net>
Signed-off-by: default avatarDesmond Yan <desmond.yan@broadcom.com>
Signed-off-by: default avatarScott Branden <scott.branden@broadcom.com>
Link: https://lore.kernel.org/r/20210120175827.14820-6-scott.branden@broadcom.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bfc53e01
......@@ -223,6 +223,8 @@ struct bcm_vk {
unsigned long wq_offload[1]; /* various flags on wq requested */
void *tdma_vaddr; /* test dma segment virtual addr */
dma_addr_t tdma_addr; /* test dma segment bus addr */
struct notifier_block panic_nb;
};
/* wq offload work items bits definitions */
......
......@@ -635,6 +635,16 @@ static int bcm_vk_trigger_reset(struct bcm_vk *vk)
return 0;
}
static int bcm_vk_on_panic(struct notifier_block *nb,
unsigned long e, void *p)
{
struct bcm_vk *vk = container_of(nb, struct bcm_vk, panic_nb);
bcm_to_v_reset_doorbell(vk, VK_BAR0_RESET_DB_HARD);
return 0;
}
static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err;
......@@ -748,6 +758,15 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* sync other info */
bcm_vk_sync_card_info(vk);
/* register for panic notifier */
vk->panic_nb.notifier_call = bcm_vk_on_panic;
err = atomic_notifier_chain_register(&panic_notifier_list,
&vk->panic_nb);
if (err) {
dev_err(dev, "Fail to register panic notifier\n");
goto err_destroy_workqueue;
}
/*
* lets trigger an auto download. We don't want to do it serially here
* because at probing time, it is not supposed to block for a long time.
......@@ -756,7 +775,7 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (auto_load) {
if ((boot_status & BOOT_STATE_MASK) == BROM_RUNNING) {
if (bcm_vk_trigger_autoload(vk))
goto err_destroy_workqueue;
goto err_unregister_panic_notifier;
} else {
dev_err(dev,
"Auto-load skipped - BROM not in proper state (0x%x)\n",
......@@ -768,6 +787,10 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
err_unregister_panic_notifier:
atomic_notifier_chain_unregister(&panic_notifier_list,
&vk->panic_nb);
err_destroy_workqueue:
destroy_workqueue(vk->wq_thread);
......@@ -818,6 +841,10 @@ static void bcm_vk_remove(struct pci_dev *pdev)
bcm_vk_trigger_reset(vk);
usleep_range(BCM_VK_UCODE_BOOT_US, BCM_VK_UCODE_BOOT_MAX_US);
/* unregister panic notifier */
atomic_notifier_chain_unregister(&panic_notifier_list,
&vk->panic_nb);
if (vk->tdma_vaddr)
dma_free_coherent(&pdev->dev, nr_scratch_pages * PAGE_SIZE,
vk->tdma_vaddr, vk->tdma_addr);
......
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