summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/nhi.c
diff options
context:
space:
mode:
authorAndreas Noever <andreas.noever@gmail.com>2014-06-03 22:04:00 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-19 14:07:07 -0700
commitd6cc51cd1a4aed1d9e2dd66d643d729acb4be560 (patch)
treea193e0c2807cf18e11c770392c71e51bafbe378a /drivers/thunderbolt/nhi.c
parentf25bf6fcb1a83a149bc8b5285d33b48cbd47c7d7 (diff)
thunderbolt: Setup control channel
Add struct tb which will contain our view of the thunderbolt bus. For now it just contains a pointer to the control channel and a workqueue for hotplug events. Add thunderbolt_alloc_and_start() and thunderbolt_shutdown_and_free() which are responsible for setup and teardown of struct tb. Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/thunderbolt/nhi.c')
-rw-r--r--drivers/thunderbolt/nhi.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index 11070ff2cec7..d2b9ce857818 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -16,6 +16,7 @@
#include "nhi.h"
#include "nhi_regs.h"
+#include "tb.h"
#define RING_TYPE(ring) ((ring)->is_tx ? "TX ring" : "RX ring")
@@ -517,6 +518,7 @@ static void nhi_shutdown(struct tb_nhi *nhi)
static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct tb_nhi *nhi;
+ struct tb *tb;
int res;
res = pcim_enable_device(pdev);
@@ -575,14 +577,26 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* magic value - clock related? */
iowrite32(3906250 / 10000, nhi->iobase + 0x38c00);
- pci_set_drvdata(pdev, nhi);
+ dev_info(&nhi->pdev->dev, "NHI initialized, starting thunderbolt\n");
+ tb = thunderbolt_alloc_and_start(nhi);
+ if (!tb) {
+ /*
+ * At this point the RX/TX rings might already have been
+ * activated. Do a proper shutdown.
+ */
+ nhi_shutdown(nhi);
+ return -EIO;
+ }
+ pci_set_drvdata(pdev, tb);
return 0;
}
static void nhi_remove(struct pci_dev *pdev)
{
- struct tb_nhi *nhi = pci_get_drvdata(pdev);
+ struct tb *tb = pci_get_drvdata(pdev);
+ struct tb_nhi *nhi = tb->nhi;
+ thunderbolt_shutdown_and_free(tb);
nhi_shutdown(nhi);
}