aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mic
diff options
context:
space:
mode:
authorSudeep Dutt <sudeep.dutt@intel.com>2015-04-29 08:32:31 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-24 15:13:36 -0400
commitb55f0359c19bae3be8fbda1281c071bc72c0dd55 (patch)
tree9fddaf660670d4c50d9504c8093cc942f59c8574 /drivers/misc/mic
parent5ec4ca6adb6abcd4479fa8d4e657748da0043f15 (diff)
misc: mic: SCIF Peer Bus
The SCIF peer bus is used to register and unregister SCIF peer devices internally by the SCIF driver to signify the addition and removal of peer nodes respectively from the SCIF network. This simplifies remote node handling within SCIF and will also be used to support device probe/remove for SCIF client drivers (e.g. netdev over SCIF) Reviewed-by: Nikhil Rao <nikhil.rao@intel.com> Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mic')
-rw-r--r--drivers/misc/mic/scif/scif_peer_bus.c124
-rw-r--r--drivers/misc/mic/scif/scif_peer_bus.h65
2 files changed, 189 insertions, 0 deletions
diff --git a/drivers/misc/mic/scif/scif_peer_bus.c b/drivers/misc/mic/scif/scif_peer_bus.c
new file mode 100644
index 000000000000..589ae9ad2501
--- /dev/null
+++ b/drivers/misc/mic/scif/scif_peer_bus.c
@@ -0,0 +1,124 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2014 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * Intel SCIF driver.
16 */
17#include "scif_main.h"
18#include "../bus/scif_bus.h"
19#include "scif_peer_bus.h"
20
21static inline struct scif_peer_dev *
22dev_to_scif_peer(struct device *dev)
23{
24 return container_of(dev, struct scif_peer_dev, dev);
25}
26
27static inline struct scif_peer_driver *
28drv_to_scif_peer(struct device_driver *drv)
29{
30 return container_of(drv, struct scif_peer_driver, driver);
31}
32
33static int scif_peer_dev_match(struct device *dv, struct device_driver *dr)
34{
35 return !strncmp(dev_name(dv), dr->name, 4);
36}
37
38static int scif_peer_dev_probe(struct device *d)
39{
40 struct scif_peer_dev *dev = dev_to_scif_peer(d);
41 struct scif_peer_driver *drv = drv_to_scif_peer(dev->dev.driver);
42
43 return drv->probe(dev);
44}
45
46static int scif_peer_dev_remove(struct device *d)
47{
48 struct scif_peer_dev *dev = dev_to_scif_peer(d);
49 struct scif_peer_driver *drv = drv_to_scif_peer(dev->dev.driver);
50
51 drv->remove(dev);
52 return 0;
53}
54
55static struct bus_type scif_peer_bus = {
56 .name = "scif_peer_bus",
57 .match = scif_peer_dev_match,
58 .probe = scif_peer_dev_probe,
59 .remove = scif_peer_dev_remove,
60};
61
62int scif_peer_register_driver(struct scif_peer_driver *driver)
63{
64 driver->driver.bus = &scif_peer_bus;
65 return driver_register(&driver->driver);
66}
67
68void scif_peer_unregister_driver(struct scif_peer_driver *driver)
69{
70 driver_unregister(&driver->driver);
71}
72
73static void scif_peer_release_dev(struct device *d)
74{
75 struct scif_peer_dev *sdev = dev_to_scif_peer(d);
76 struct scif_dev *scifdev = &scif_dev[sdev->dnode];
77
78 scif_cleanup_scifdev(scifdev);
79 kfree(sdev);
80}
81
82struct scif_peer_dev *
83scif_peer_register_device(struct scif_dev *scifdev)
84{
85 int ret;
86 struct scif_peer_dev *spdev;
87
88 spdev = kzalloc(sizeof(*spdev), GFP_KERNEL);
89 if (!spdev)
90 return ERR_PTR(-ENOMEM);
91
92 spdev->dev.parent = scifdev->sdev->dev.parent;
93 spdev->dev.release = scif_peer_release_dev;
94 spdev->dnode = scifdev->node;
95 spdev->dev.bus = &scif_peer_bus;
96
97 dev_set_name(&spdev->dev, "scif_peer-dev%u", spdev->dnode);
98 /*
99 * device_register() causes the bus infrastructure to look for a
100 * matching driver.
101 */
102 ret = device_register(&spdev->dev);
103 if (ret)
104 goto free_spdev;
105 return spdev;
106free_spdev:
107 kfree(spdev);
108 return ERR_PTR(ret);
109}
110
111void scif_peer_unregister_device(struct scif_peer_dev *sdev)
112{
113 device_unregister(&sdev->dev);
114}
115
116int scif_peer_bus_init(void)
117{
118 return bus_register(&scif_peer_bus);
119}
120
121void scif_peer_bus_exit(void)
122{
123 bus_unregister(&scif_peer_bus);
124}
diff --git a/drivers/misc/mic/scif/scif_peer_bus.h b/drivers/misc/mic/scif/scif_peer_bus.h
new file mode 100644
index 000000000000..33f0dbb30152
--- /dev/null
+++ b/drivers/misc/mic/scif/scif_peer_bus.h
@@ -0,0 +1,65 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2014 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * Intel SCIF driver.
16 */
17#ifndef _SCIF_PEER_BUS_H_
18#define _SCIF_PEER_BUS_H_
19
20#include <linux/device.h>
21#include <linux/mic_common.h>
22
23/*
24 * Peer devices show up as PCIe devices for the mgmt node but not the cards.
25 * The mgmt node discovers all the cards on the PCIe bus and informs the other
26 * cards about their peers. Upon notification of a peer a node adds a peer
27 * device to the peer bus to maintain symmetry in the way devices are
28 * discovered across all nodes in the SCIF network.
29 */
30/**
31 * scif_peer_dev - representation of a peer SCIF device
32 * @dev: underlying device
33 * @dnode - The destination node which this device will communicate with.
34 */
35struct scif_peer_dev {
36 struct device dev;
37 u8 dnode;
38};
39
40/**
41 * scif_peer_driver - operations for a scif_peer I/O driver
42 * @driver: underlying device driver (populate name and owner).
43 * @id_table: the ids serviced by this driver.
44 * @probe: the function to call when a device is found. Returns 0 or -errno.
45 * @remove: the function to call when a device is removed.
46 */
47struct scif_peer_driver {
48 struct device_driver driver;
49 const struct scif_peer_dev_id *id_table;
50
51 int (*probe)(struct scif_peer_dev *dev);
52 void (*remove)(struct scif_peer_dev *dev);
53};
54
55struct scif_dev;
56
57int scif_peer_register_driver(struct scif_peer_driver *driver);
58void scif_peer_unregister_driver(struct scif_peer_driver *driver);
59
60struct scif_peer_dev *scif_peer_register_device(struct scif_dev *sdev);
61void scif_peer_unregister_device(struct scif_peer_dev *sdev);
62
63int scif_peer_bus_init(void);
64void scif_peer_bus_exit(void);
65#endif /* _SCIF_PEER_BUS_H */