[PATCH linux dev-4.7 v2 1/7] drivers/fsi: Add hub master scan detect

Christopher Bostic cbostic at linux.vnet.ibm.com
Wed Feb 22 08:50:26 AEDT 2017


On detect of hub master engine in config space set up a master
device and register it with the core.

Signed-off-by: Christopher Bostic <cbostic at linux.vnet.ibm.com>

---

Changes in V2:

- Refactor structures for hub master. Previously hub master engine
  was considered a slave engine.
---
 drivers/fsi/fsi-core.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index d63a892..646bb43 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -43,6 +43,11 @@
 
 #define FSI_IPOLL_PERIOD		msecs_to_jiffies(fsi_ipoll_period_ms)
 
+#define	FSI_ENGID_HUB_MASTER		0x1c
+#define	FSI_ENGID_HUB_LINK		0x1d
+#define	FSI_HUB_LINK_OFFSET		0x80000
+#define	FSI_HUB_MASTER_MAX_LINKS	8
+
 static const int engine_page_size = 0x400;
 static struct task_struct *master_ipoll;
 static unsigned int fsi_ipoll_period_ms = 100;
@@ -58,6 +63,14 @@ struct fsi_slave {
 	uint8_t			id;
 };
 
+struct fsi_master_hub {
+	struct fsi_master	master;
+	struct fsi_slave	*slave;
+	uint32_t		control_regs;	/* slave-relative addr regs */
+	uint32_t		base;		/* slave-relative addr of */
+						/* master address space */
+};
+
 #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev)
 
 static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr,
@@ -203,12 +216,18 @@ static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
 			slave->id, addr, val, size);
 }
 
+static int hub_master_init(struct fsi_master_hub *hub)
+{
+	return 0;
+}
+
 static int fsi_slave_scan(struct fsi_slave *slave)
 {
 	uint32_t engine_addr;
 	uint32_t conf;
 	int rc, i;
 	uint8_t si1s_bit = 1;
+	struct fsi_master_hub *hub;
 
 	INIT_LIST_HEAD(&slave->my_engines);
 
@@ -252,7 +271,31 @@ static int fsi_slave_scan(struct fsi_slave *slave)
 		 * Unused address areas are marked by a zero type value; this
 		 * skips the defined address areas
 		 */
-		if (type != 0 && slots != 0) {
+		if (type != 0) {
+
+			if (type == FSI_ENGID_HUB_MASTER) {
+				hub = kzalloc(sizeof(*hub), GFP_KERNEL);
+				if (!hub)
+					return -ENOMEM;
+
+				hub->base = FSI_HUB_LINK_OFFSET;
+				hub->control_regs = engine_addr;
+				hub->slave = slave;
+				rc = hub_master_init(hub);
+
+				continue;
+			}
+			if (type == FSI_ENGID_HUB_LINK) {
+				if (!hub)
+					continue;
+
+				hub->master.n_links++;
+				if (hub->master.n_links ==
+						(FSI_HUB_MASTER_MAX_LINKS * 2))
+					rc = fsi_master_register(&hub->master);
+
+				continue;
+			}
 
 			/* create device */
 			dev = fsi_create_device(slave);
@@ -597,7 +640,7 @@ DEVICE_ATTR(fsi_ipoll_period, S_IRUGO | S_IWUSR, fsi_ipoll_period_show,
 
 int fsi_master_register(struct fsi_master *master)
 {
-	if (!master || !master->dev)
+	if (!master)
 		return -EINVAL;
 
 	master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL);
-- 
1.8.2.2



More information about the openbmc mailing list