@@ -50,6 +50,7 @@ static const int engine_page_size = 0x400;
#define FSI_SMODE 0x0 /* R/W: Mode register */
#define FSI_SISC 0x8 /* R/W: Interrupt condition */
#define FSI_SSTAT 0x14 /* R : Slave status */
+#define FSI_SLBUS 0x30 /* W : LBUS Ownership */
#define FSI_LLMODE 0x100 /* R/W: Link layer mode register */
/*
@@ -66,6 +67,11 @@ static const int engine_page_size = 0x400;
#define FSI_SMODE_LBCRR_SHIFT 8 /* Clk ratio shift */
#define FSI_SMODE_LBCRR_MASK 0xf /* Clk ratio mask */
+/*
+ * SLBUS fields
+ */
+#define FSI_SLBUS_FORCE 0x80000000 /* Force LBUS ownership */
+
/*
* LLMODE fields
*/
@@ -981,7 +987,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
uint32_t cfam_id;
struct fsi_slave *slave;
uint8_t crc;
- __be32 data, llmode;
+ __be32 data, llmode, slbus;
int rc;
/* Currently, we only support single slaves on a link, and use the
@@ -1052,6 +1058,20 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
}
+ /*
+ * The FSI specification requires that the master claim ownership of
+ * bus before accessing the CFAM address space. This driver doesn't yet
+ * support more complex multi-master situations, so just force
+ * ownership of the bus now.
+ */
+ slbus = cpu_to_be32(FSI_SLBUS_FORCE);
+ rc = fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SLBUS,
+ &slbus, sizeof(slbus));
+ if (rc)
+ dev_warn(&master->dev,
+ "can't set slbus on slave:%02x:%02x %d\n", link, id,
+ rc);
+
rc = fsi_slave_set_smode(slave);
if (rc) {
dev_warn(&master->dev,
The FSI specification indicates that a slave will prevent access to the CFAM address space for a master without local bus ownership. Therefore, force local bus ownership when initializing the slave. Signed-off-by: Eddie James <eajames@linux.ibm.com> --- drivers/fsi/fsi-core.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)