drivers/fsi: Implement slave initialisation
Implement fsi_slave_init: if we can read a chip ID, create fsi_slave devices and register with the driver core. Includes changes from Christopher Bostic <cbostic@linux.vnet.ibm.com>. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com> Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>hifive-unleashed-5.1
parent
2609528211
commit
2b545cd8e1
|
@ -6,6 +6,7 @@ menu "FSI support"
|
||||||
|
|
||||||
config FSI
|
config FSI
|
||||||
tristate "FSI support"
|
tristate "FSI support"
|
||||||
|
select CRC4
|
||||||
---help---
|
---help---
|
||||||
FSI - the FRU Support Interface - is a simple bus for low-level
|
FSI - the FRU Support Interface - is a simple bus for low-level
|
||||||
access to POWER-based hardware.
|
access to POWER-based hardware.
|
||||||
|
|
|
@ -13,13 +13,17 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/crc4.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/fsi.h>
|
#include <linux/fsi.h>
|
||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include "fsi-master.h"
|
#include "fsi-master.h"
|
||||||
|
|
||||||
|
#define FSI_SLAVE_SIZE_23b 0x800000
|
||||||
|
|
||||||
static DEFINE_IDA(master_ida);
|
static DEFINE_IDA(master_ida);
|
||||||
|
|
||||||
struct fsi_slave {
|
struct fsi_slave {
|
||||||
|
@ -90,11 +94,70 @@ static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
|
||||||
addr, val, size);
|
addr, val, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fsi_slave_release(struct device *dev)
|
||||||
|
{
|
||||||
|
struct fsi_slave *slave = to_fsi_slave(dev);
|
||||||
|
|
||||||
|
kfree(slave);
|
||||||
|
}
|
||||||
|
|
||||||
static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
|
static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
|
||||||
{
|
{
|
||||||
/* todo: initialise slave device, perform engine scan */
|
struct fsi_slave *slave;
|
||||||
|
uint32_t chip_id;
|
||||||
|
uint8_t crc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
return -ENODEV;
|
/* Currently, we only support single slaves on a link, and use the
|
||||||
|
* full 23-bit address range
|
||||||
|
*/
|
||||||
|
if (id != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rc = fsi_master_read(master, link, id, 0, &chip_id, sizeof(chip_id));
|
||||||
|
if (rc) {
|
||||||
|
dev_dbg(&master->dev, "can't read slave %02x:%02x %d\n",
|
||||||
|
link, id, rc);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
chip_id = be32_to_cpu(chip_id);
|
||||||
|
|
||||||
|
crc = crc4(0, chip_id, 32);
|
||||||
|
if (crc) {
|
||||||
|
dev_warn(&master->dev, "slave %02x:%02x invalid chip id CRC!\n",
|
||||||
|
link, id);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",
|
||||||
|
chip_id, master->idx, link, id);
|
||||||
|
|
||||||
|
/* We can communicate with a slave; create the slave device and
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
slave = kzalloc(sizeof(*slave), GFP_KERNEL);
|
||||||
|
if (!slave)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
slave->master = master;
|
||||||
|
slave->dev.parent = &master->dev;
|
||||||
|
slave->dev.release = fsi_slave_release;
|
||||||
|
slave->link = link;
|
||||||
|
slave->id = id;
|
||||||
|
slave->size = FSI_SLAVE_SIZE_23b;
|
||||||
|
|
||||||
|
dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
|
||||||
|
rc = device_register(&slave->dev);
|
||||||
|
if (rc < 0) {
|
||||||
|
dev_warn(&master->dev, "failed to create slave device: %d\n",
|
||||||
|
rc);
|
||||||
|
put_device(&slave->dev);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* todo: perform engine scan */
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FSI master support */
|
/* FSI master support */
|
||||||
|
|
Loading…
Reference in New Issue