[PATCH v3 00/18] FSI device driver introduction
From: Christopher BosticIntroduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v3: - Patch set contained an invalid 18/18 test patch not meant for community review, corrected. Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all compatible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interface for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 +
[PATCH v3 00/18] FSI device driver introduction
From: Christopher Bostic Introduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v3: - Patch set contained an invalid 18/18 test patch not meant for community review, corrected. Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all compatible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interface for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig
[PATCH v3 00/18] FSI device driver introduction
From: Chris BosticIntroduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v3: - Patch set contained an invalid 18/18 test patch not meant for community review, corrected. Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all comptible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interfac for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig
[PATCH v3 00/18] FSI device driver introduction
From: Chris Bostic Introduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v3: - Patch set contained an invalid 18/18 test patch not meant for community review, corrected. Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all comptible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interfac for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig
[PATCH v3 02/18] drivers/fsi: Add device & driver definitions
From: Jeremy KerrAdd structs for fsi devices & drivers, and struct device conversion functions. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- include/linux/fsi.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/include/linux/fsi.h b/include/linux/fsi.h index 47aa181..f73886a 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -17,6 +17,17 @@ #include +struct fsi_device { + struct device dev; +}; + +struct fsi_driver { + struct device_driver drv; +}; + +#define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) +#define to_fsi_drv(drvp) container_of(drvp, struct fsi_driver, drv) + extern struct bus_type fsi_bus_type; #endif /* LINUX_FSI_H */ -- 1.8.2.2
[PATCH v3 02/18] drivers/fsi: Add device & driver definitions
From: Jeremy Kerr Add structs for fsi devices & drivers, and struct device conversion functions. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- include/linux/fsi.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/include/linux/fsi.h b/include/linux/fsi.h index 47aa181..f73886a 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -17,6 +17,17 @@ #include +struct fsi_device { + struct device dev; +}; + +struct fsi_driver { + struct device_driver drv; +}; + +#define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) +#define to_fsi_drv(drvp) container_of(drvp, struct fsi_driver, drv) + extern struct bus_type fsi_bus_type; #endif /* LINUX_FSI_H */ -- 1.8.2.2
[PATCH v3 00/18] FSI device driver introduction
From: Chris BosticIntroduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v3: - Patch set contained an invalid 18/18 test patch not meant for community review, corrected. Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all comptible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interfac for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig
[PATCH v3 00/18] FSI device driver introduction
From: Chris Bostic Introduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v3: - Patch set contained an invalid 18/18 test patch not meant for community review, corrected. Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all comptible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interfac for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig
[PATCH v2 18/18] insert build break
From: Chris BosticSigned-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 28b82d1..db09836 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -42,6 +42,7 @@ static DEFINE_IDA(master_ida); + struct fsi_slave { struct device dev; struct fsi_master *master; -- 1.8.2.2
[PATCH v2 18/18] insert build break
From: Chris Bostic Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 28b82d1..db09836 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -42,6 +42,7 @@ static DEFINE_IDA(master_ida); + struct fsi_slave { struct device dev; struct fsi_master *master; -- 1.8.2.2
[PATCH v2 17/18] drivers/fsi: Add GPIO based FSI master
From: Chris BosticImplement a FSI master using GPIO. Will generate FSI protocol for read and write commands to particular addresses. Sends master command and waits for and decodes a slave response. Includes Jeremy Kerr's original GPIO master base commit. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Merge fsi_master_gpio_init() into probe. - Remove scan sysfs file creation since its now created in the core. - Set pin initial output values at time of requesting the pins from the gpio driver. - Assign value to master->master.dev at probe time. - Use the get_optional gpio driver interface for all optional pins. --- drivers/fsi/Kconfig | 11 + drivers/fsi/Makefile | 1 + drivers/fsi/fsi-master-gpio.c | 530 ++ 3 files changed, 542 insertions(+) create mode 100644 drivers/fsi/fsi-master-gpio.c diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig index 04c1a0e..9cf8345 100644 --- a/drivers/fsi/Kconfig +++ b/drivers/fsi/Kconfig @@ -9,4 +9,15 @@ config FSI ---help--- FSI - the FRU Support Interface - is a simple bus for low-level access to POWER-based hardware. + +if FSI + +config FSI_MASTER_GPIO + tristate "GPIO-based FSI master" + depends on FSI && GPIOLIB + ---help--- + This option enables a FSI master driver using GPIO lines. + +endif + endmenu diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile index db0e5e7..ed28ac0 100644 --- a/drivers/fsi/Makefile +++ b/drivers/fsi/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_FSI) += fsi-core.o +obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c new file mode 100644 index 000..b549d0b --- /dev/null +++ b/drivers/fsi/fsi-master-gpio.c @@ -0,0 +1,530 @@ +/* + * FSI GPIO based master driver + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A FSI master controller, using a simple GPIO bit-banging interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsi-master.h" + +#defineFSI_GPIO_STD_DLY1 /* Standard pin delay in nS */ +#defineFSI_ECHO_DELAY_CLOCKS 16 /* Number clocks for echo delay */ +#defineFSI_PRE_BREAK_CLOCKS50 /* Number clocks to prep for break */ +#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue break */ +#defineFSI_POST_BREAK_CLOCKS 16000 /* Number clocks to set up cfam */ +#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */ +#defineFSI_GPIO_STD_DELAY 10 /* Standard GPIO delay in nS */ + /* todo: adjust down as low as */ + /* possible or eliminate */ +#defineFSI_GPIO_CMD_DPOLL 0x002AULL +#defineFSI_GPIO_CMD_DPOLL_SIZE 9 +#defineFSI_GPIO_DPOLL_CLOCKS 100 /* < 21 will cause slave to hang */ +#defineFSI_GPIO_CMD_DEFAULT0x2000ULL +#defineFSI_GPIO_CMD_WRITE 0 +#defineFSI_GPIO_CMD_READ 0x0400ULL +#defineFSI_GPIO_CMD_SLAVE_MASK 0xC000ULL +#defineFSI_GPIO_CMD_ADDR_SHIFT 37 +#defineFSI_GPIO_CMD_ADDR_MASK 0x001F +#defineFSI_GPIO_CMD_SLV_SHIFT 62 +#defineFSI_GPIO_CMD_SIZE_160x0010ULL +#defineFSI_GPIO_CMD_SIZE_320x0030ULL +#defineFSI_GPIO_CMD_DT32_SHIFT 4 +#defineFSI_GPIO_CMD_DT16_SHIFT 20 +#defineFSI_GPIO_CMD_DT8_SHIFT 28 +#defineFSI_GPIO_CMD_DFLT_LEN 28 +#defineFSI_GPIO_CMD_CRC_SHIFT 60 + +/* Bus errors */ +#defineFSI_GPIO_ERR_BUSY 1 /* Slave stuck in busy state */ +#defineFSI_GPIO_RESP_ERRA 2 /* Any (misc) Error */ +#defineFSI_GPIO_RESP_ERRC 3 /* Slave reports master CRC error */ +#defineFSI_GPIO_MTOE 4 /* Master time out error */ +#defineFSI_GPIO_CRC_INVAL 5 /* Master reports slave CRC error */ + +/* Normal slave responses */ +#defineFSI_GPIO_RESP_BUSY 1 +#defineFSI_GPIO_RESP_ACK 0 +#defineFSI_GPIO_RESP_ACKD 4 + +#defineFSI_GPIO_MAX_BUSY 100 +#defineFSI_GPIO_MTOE_COUNT 1000 +#defineFSI_GPIO_DRAIN_BITS 20
[PATCH v2 16/18] drivers/fsi: Document FSI master sysfs files in ABI
From: Chris BosticAdd info for sysfs scan file in Documentaiton ABI/testing Signed-off-by: Chris Bostic --- Documentation/ABI/testing/sysfs-bus-fsi | 6 ++ 1 file changed, 6 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-fsi diff --git a/Documentation/ABI/testing/sysfs-bus-fsi b/Documentation/ABI/testing/sysfs-bus-fsi new file mode 100644 index 000..dfcbc1b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-fsi @@ -0,0 +1,6 @@ +What: /sys/bus/platform/devices/fsi-master/scan +KernelVersion: 4.9 +Contact:cbos...@us.ibm.com +Description: +Initiates a FSI master scan for all connected +slave devices on its links. -- 1.8.2.2
[PATCH v2 17/18] drivers/fsi: Add GPIO based FSI master
From: Chris Bostic Implement a FSI master using GPIO. Will generate FSI protocol for read and write commands to particular addresses. Sends master command and waits for and decodes a slave response. Includes Jeremy Kerr's original GPIO master base commit. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Merge fsi_master_gpio_init() into probe. - Remove scan sysfs file creation since its now created in the core. - Set pin initial output values at time of requesting the pins from the gpio driver. - Assign value to master->master.dev at probe time. - Use the get_optional gpio driver interface for all optional pins. --- drivers/fsi/Kconfig | 11 + drivers/fsi/Makefile | 1 + drivers/fsi/fsi-master-gpio.c | 530 ++ 3 files changed, 542 insertions(+) create mode 100644 drivers/fsi/fsi-master-gpio.c diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig index 04c1a0e..9cf8345 100644 --- a/drivers/fsi/Kconfig +++ b/drivers/fsi/Kconfig @@ -9,4 +9,15 @@ config FSI ---help--- FSI - the FRU Support Interface - is a simple bus for low-level access to POWER-based hardware. + +if FSI + +config FSI_MASTER_GPIO + tristate "GPIO-based FSI master" + depends on FSI && GPIOLIB + ---help--- + This option enables a FSI master driver using GPIO lines. + +endif + endmenu diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile index db0e5e7..ed28ac0 100644 --- a/drivers/fsi/Makefile +++ b/drivers/fsi/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_FSI) += fsi-core.o +obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c new file mode 100644 index 000..b549d0b --- /dev/null +++ b/drivers/fsi/fsi-master-gpio.c @@ -0,0 +1,530 @@ +/* + * FSI GPIO based master driver + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * A FSI master controller, using a simple GPIO bit-banging interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsi-master.h" + +#defineFSI_GPIO_STD_DLY1 /* Standard pin delay in nS */ +#defineFSI_ECHO_DELAY_CLOCKS 16 /* Number clocks for echo delay */ +#defineFSI_PRE_BREAK_CLOCKS50 /* Number clocks to prep for break */ +#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue break */ +#defineFSI_POST_BREAK_CLOCKS 16000 /* Number clocks to set up cfam */ +#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */ +#defineFSI_GPIO_STD_DELAY 10 /* Standard GPIO delay in nS */ + /* todo: adjust down as low as */ + /* possible or eliminate */ +#defineFSI_GPIO_CMD_DPOLL 0x002AULL +#defineFSI_GPIO_CMD_DPOLL_SIZE 9 +#defineFSI_GPIO_DPOLL_CLOCKS 100 /* < 21 will cause slave to hang */ +#defineFSI_GPIO_CMD_DEFAULT0x2000ULL +#defineFSI_GPIO_CMD_WRITE 0 +#defineFSI_GPIO_CMD_READ 0x0400ULL +#defineFSI_GPIO_CMD_SLAVE_MASK 0xC000ULL +#defineFSI_GPIO_CMD_ADDR_SHIFT 37 +#defineFSI_GPIO_CMD_ADDR_MASK 0x001F +#defineFSI_GPIO_CMD_SLV_SHIFT 62 +#defineFSI_GPIO_CMD_SIZE_160x0010ULL +#defineFSI_GPIO_CMD_SIZE_320x0030ULL +#defineFSI_GPIO_CMD_DT32_SHIFT 4 +#defineFSI_GPIO_CMD_DT16_SHIFT 20 +#defineFSI_GPIO_CMD_DT8_SHIFT 28 +#defineFSI_GPIO_CMD_DFLT_LEN 28 +#defineFSI_GPIO_CMD_CRC_SHIFT 60 + +/* Bus errors */ +#defineFSI_GPIO_ERR_BUSY 1 /* Slave stuck in busy state */ +#defineFSI_GPIO_RESP_ERRA 2 /* Any (misc) Error */ +#defineFSI_GPIO_RESP_ERRC 3 /* Slave reports master CRC error */ +#defineFSI_GPIO_MTOE 4 /* Master time out error */ +#defineFSI_GPIO_CRC_INVAL 5 /* Master reports slave CRC error */ + +/* Normal slave responses */ +#defineFSI_GPIO_RESP_BUSY 1 +#defineFSI_GPIO_RESP_ACK 0 +#defineFSI_GPIO_RESP_ACKD 4 + +#defineFSI_GPIO_MAX_BUSY 100 +#defineFSI_GPIO_MTOE_COUNT 1000 +#defineFSI_GPIO_DRAIN_BITS 20 +#defineFSI_GPIO_CRC_SIZE 4 +#define
[PATCH v2 16/18] drivers/fsi: Document FSI master sysfs files in ABI
From: Chris Bostic Add info for sysfs scan file in Documentaiton ABI/testing Signed-off-by: Chris Bostic --- Documentation/ABI/testing/sysfs-bus-fsi | 6 ++ 1 file changed, 6 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-fsi diff --git a/Documentation/ABI/testing/sysfs-bus-fsi b/Documentation/ABI/testing/sysfs-bus-fsi new file mode 100644 index 000..dfcbc1b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-fsi @@ -0,0 +1,6 @@ +What: /sys/bus/platform/devices/fsi-master/scan +KernelVersion: 4.9 +Contact:cbos...@us.ibm.com +Description: +Initiates a FSI master scan for all connected +slave devices on its links. -- 1.8.2.2
[PATCH v2 15/18] drivers/fsi: Add documentation for GPIO based FSI master
From: Chris BosticDefine the device tree bindings for the GPIO master type. Signed-off-by: Chris Bostic --- V2 - Break out this documentation update from the code implementing The GPIO master function. - Move the documentation to an earlier patch than the code implementing the function. - Document all 'compatible' strings used in the series. - Write binding document in terms of hardware, not software. - Elaborate on what a GPIO based FSI master is versus a non GPIO based master. - Give a more detailed description of what each pin in the GPIO FSI master is to be used for. - Re-order compatible strings in example so that most specific comes first. - Indicate the proper order each pin should be initialized. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example list items individually. --- .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 ++ 1 file changed, 71 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt diff --git a/Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt b/Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt new file mode 100644 index 000..5d589bf --- /dev/null +++ b/Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt @@ -0,0 +1,71 @@ +Device-tree bindings for FSI master implemented with GPIO +- + +Typically a FSI master is defined in hardware with output control +lines designated for Enable, Data, Clock, etc.. In the case of +a 'GPIO FSI master', however, it may be the case that there is no +such master defined in hardware and must be implemented in standard +GPIO to interact with its slaves. In this 'virtual' FSI master +case the GPIO pins representing clk and data are directly +connected to the slaves. + +The GPIO FSI master node +- +This node describes a FSI master implmented with GPIO. +Required property: + compatible = "ibm,fsi-master-gpio" + +The standard FSI master node + +This node describes a FSI master implmemented fully in hardware +with dedicated input/output pins required for its function (i.e. +not using generic GPIO pins). +Required property: + compatible = "ibm,fsi-master" + + +GPIO FSI master property/pin descriptions +-- +clk - The master controlled clock line that indicates to the + slave when to read in or send out new data - required. +data - The serial data line containing information to be sent or + received by the master. This line is bi-directional. During + command phase the master controls the line and when a response + is required the slave takes control - required. +enable - Controls power state of data line - optional. +trans - Voltage translator control. In some applications the data line + must have its signal levels altered by a translator. If this is + necessary then control of signal direction is managed via this + line - optional. +mux - Multiplexor control. This activates/deactivates the data line + in cases where it is one of many possible selections via mux - + optional. + +Required properties: + - compatible = "ibm,fsi-master-gpio"; + - clk-gpios; + - data-gpios; + +Optional properties: + - enable-gpios; + - trans-gpios; + - mux-gpios; + +Order of property activation: +1. clk +2. data +3. trans +4. enable +5. mux + + +Example: + +fsi-master { + compatible = "ibm,fsi-master-gpio", "ibm,fsi-master"; + clk-gpios = < 0>, < 6>; + data-gpios = < 1>, < 7>; + enable-gpios = < 2>, < 8>; + trans-gpios = < 3>, < 9>; + mux-gpios = < 4>, < 10>; +} -- 1.8.2.2
[PATCH v2 15/18] drivers/fsi: Add documentation for GPIO based FSI master
From: Chris Bostic Define the device tree bindings for the GPIO master type. Signed-off-by: Chris Bostic --- V2 - Break out this documentation update from the code implementing The GPIO master function. - Move the documentation to an earlier patch than the code implementing the function. - Document all 'compatible' strings used in the series. - Write binding document in terms of hardware, not software. - Elaborate on what a GPIO based FSI master is versus a non GPIO based master. - Give a more detailed description of what each pin in the GPIO FSI master is to be used for. - Re-order compatible strings in example so that most specific comes first. - Indicate the proper order each pin should be initialized. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example list items individually. --- .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 ++ 1 file changed, 71 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt diff --git a/Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt b/Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt new file mode 100644 index 000..5d589bf --- /dev/null +++ b/Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt @@ -0,0 +1,71 @@ +Device-tree bindings for FSI master implemented with GPIO +- + +Typically a FSI master is defined in hardware with output control +lines designated for Enable, Data, Clock, etc.. In the case of +a 'GPIO FSI master', however, it may be the case that there is no +such master defined in hardware and must be implemented in standard +GPIO to interact with its slaves. In this 'virtual' FSI master +case the GPIO pins representing clk and data are directly +connected to the slaves. + +The GPIO FSI master node +- +This node describes a FSI master implmented with GPIO. +Required property: + compatible = "ibm,fsi-master-gpio" + +The standard FSI master node + +This node describes a FSI master implmemented fully in hardware +with dedicated input/output pins required for its function (i.e. +not using generic GPIO pins). +Required property: + compatible = "ibm,fsi-master" + + +GPIO FSI master property/pin descriptions +-- +clk - The master controlled clock line that indicates to the + slave when to read in or send out new data - required. +data - The serial data line containing information to be sent or + received by the master. This line is bi-directional. During + command phase the master controls the line and when a response + is required the slave takes control - required. +enable - Controls power state of data line - optional. +trans - Voltage translator control. In some applications the data line + must have its signal levels altered by a translator. If this is + necessary then control of signal direction is managed via this + line - optional. +mux - Multiplexor control. This activates/deactivates the data line + in cases where it is one of many possible selections via mux - + optional. + +Required properties: + - compatible = "ibm,fsi-master-gpio"; + - clk-gpios; + - data-gpios; + +Optional properties: + - enable-gpios; + - trans-gpios; + - mux-gpios; + +Order of property activation: +1. clk +2. data +3. trans +4. enable +5. mux + + +Example: + +fsi-master { + compatible = "ibm,fsi-master-gpio", "ibm,fsi-master"; + clk-gpios = < 0>, < 6>; + data-gpios = < 1>, < 7>; + enable-gpios = < 2>, < 8>; + trans-gpios = < 3>, < 9>; + mux-gpios = < 4>, < 10>; +} -- 1.8.2.2
[PATCH v2 14/18] drivers/fsi: Add FSI bus documentation
From: Chris BosticAdd details on the basic functions of the FSI serial bus. Signed-off-by: Chris Bostic --- Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi.txt diff --git a/Documentation/devicetree/bindings/fsi/fsi.txt b/Documentation/devicetree/bindings/fsi/fsi.txt new file mode 100644 index 000..7fa2394 --- /dev/null +++ b/Documentation/devicetree/bindings/fsi/fsi.txt @@ -0,0 +1,54 @@ +FSI: Flexible Support processor Interface + +FSI is a two line serial bus capable of running at speeds up to 166 MHz. +The lines consist of a clock responsible for synchronizing the target device +(slave) with the master which is responsible for all transactions on the bus. +The master owns the clock line and is the only side allowed to change its +state. The second line, SDA, is a data line that conveys information to/from +the slave who samples based on the clock line. The data line is +bi-directional. + +The master initiates communication by sending a command to the slave and +depending on the type of command will allow the slave to control the bus +to return requested data. All commands are CRC protected. The slave upon +receipt of a command will determine if the CRC is correct and discard +the data if noise has corrupted the line. In the same manner the master +will verify the CRC received from the slave. + +Types of commands: +Read 32 bit: Read a 32 bit word from a specified address on the slave. +Read 16 bit: Read a 16 bit 'half word' from a specified address on the slave. +read 8 bit: Read a byte from a specified address on the slave. +Write 32,16,8 bit: Write to a specified address on the slave with the provided + data. +BREAK: Initialize the slave's logic to receive commands. +TERM: Terminate the slave's error lockout to resume communications + after an error on the bus is detected. +D-POLL:Poll the slave to determine when it is no longer buy processing + a previous command. +I-POLL:Interrupt signal check. Master queries slave to see if any + interrupts are asserting. + +High fanout capability: +FSI buses can be chained together in 'hub' configurations to expand the +available communications channels and thus allow connetion to more slaves. + + +Typical implementation + + FSI master - slave with local FSI master (hub) --- downstream slave + + +Each two line combination of a clock and data line is collectively referred +to as a 'FSI link'. Depending on hardware the primary FSI master may support +up to 64 links. Hub FSI masters can support at most 8 links. Total number +of supported slaves can grow exponentially depending on how many hubs are +placed in the path. Presently only two hubs in the chain are allowed but +in the future this may be expanded. + +The slave hardware logic responsible for decoding FSI master commands is +contained in a CFAM (Common Field replaceable unit Access Macro). Up to +4 slaves or CFAMs can be connected on each FSI link. CFAMs in addition +to the slave logic (or engine) can contain other functions that allow access +via FSI. Common additional functionality includes I2C masters, GPIO +controllers, UARTs, etc... -- 1.8.2.2
[PATCH v2 14/18] drivers/fsi: Add FSI bus documentation
From: Chris Bostic Add details on the basic functions of the FSI serial bus. Signed-off-by: Chris Bostic --- Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi.txt diff --git a/Documentation/devicetree/bindings/fsi/fsi.txt b/Documentation/devicetree/bindings/fsi/fsi.txt new file mode 100644 index 000..7fa2394 --- /dev/null +++ b/Documentation/devicetree/bindings/fsi/fsi.txt @@ -0,0 +1,54 @@ +FSI: Flexible Support processor Interface + +FSI is a two line serial bus capable of running at speeds up to 166 MHz. +The lines consist of a clock responsible for synchronizing the target device +(slave) with the master which is responsible for all transactions on the bus. +The master owns the clock line and is the only side allowed to change its +state. The second line, SDA, is a data line that conveys information to/from +the slave who samples based on the clock line. The data line is +bi-directional. + +The master initiates communication by sending a command to the slave and +depending on the type of command will allow the slave to control the bus +to return requested data. All commands are CRC protected. The slave upon +receipt of a command will determine if the CRC is correct and discard +the data if noise has corrupted the line. In the same manner the master +will verify the CRC received from the slave. + +Types of commands: +Read 32 bit: Read a 32 bit word from a specified address on the slave. +Read 16 bit: Read a 16 bit 'half word' from a specified address on the slave. +read 8 bit: Read a byte from a specified address on the slave. +Write 32,16,8 bit: Write to a specified address on the slave with the provided + data. +BREAK: Initialize the slave's logic to receive commands. +TERM: Terminate the slave's error lockout to resume communications + after an error on the bus is detected. +D-POLL:Poll the slave to determine when it is no longer buy processing + a previous command. +I-POLL:Interrupt signal check. Master queries slave to see if any + interrupts are asserting. + +High fanout capability: +FSI buses can be chained together in 'hub' configurations to expand the +available communications channels and thus allow connetion to more slaves. + + +Typical implementation + + FSI master - slave with local FSI master (hub) --- downstream slave + + +Each two line combination of a clock and data line is collectively referred +to as a 'FSI link'. Depending on hardware the primary FSI master may support +up to 64 links. Hub FSI masters can support at most 8 links. Total number +of supported slaves can grow exponentially depending on how many hubs are +placed in the path. Presently only two hubs in the chain are allowed but +in the future this may be expanded. + +The slave hardware logic responsible for decoding FSI master commands is +contained in a CFAM (Common Field replaceable unit Access Macro). Up to +4 slaves or CFAMs can be connected on each FSI link. CFAMs in addition +to the slave logic (or engine) can contain other functions that allow access +via FSI. Common additional functionality includes I2C masters, GPIO +controllers, UARTs, etc... -- 1.8.2.2
[PATCH v2 11/18] drivers/fsi: Set up links for slave communication
From: Chris BosticEnable each link and send a break command in preparation for scanning each link for slaves. Signed-off-by: Chris Bostic Signed-off-by: Jeremy Kerr --- drivers/fsi/fsi-core.c | 38 -- drivers/fsi/fsi-master.h | 2 ++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3119aa1..b2c9274 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -271,14 +271,48 @@ static int fsi_slave_init(struct fsi_master *master, /* FSI master support */ +static int fsi_master_link_enable(struct fsi_master *master, int link) +{ + if (master->link_enable) + return master->link_enable(master, link); + + return 0; +} + +/* + * Issue a break command on this link + */ +static int fsi_master_break(struct fsi_master *master, int link) +{ + if (master->send_break) + return master->send_break(master, link); + + return 0; +} + static int fsi_master_scan(struct fsi_master *master) { - int link, slave_id; + int link, slave_id, rc; + + for (link = 0; link < master->n_links; link++) { + rc = fsi_master_link_enable(master, link); + if (rc) { + dev_dbg(master->dev, + "enable link:%d failed with:%d\n", link, rc); + continue; + } + rc = fsi_master_break(master, link); + if (rc) { + dev_dbg(master->dev, + "Break to link:%d failed with:%d\n", link, rc); + continue; + } - for (link = 0; link < master->n_links; link++) for (slave_id = 0; slave_id < FSI_N_SLAVES; slave_id++) fsi_slave_init(master, link, slave_id); + } + return 0; } diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h index e75a810..94a0671 100644 --- a/drivers/fsi/fsi-master.h +++ b/drivers/fsi/fsi-master.h @@ -29,6 +29,8 @@ struct fsi_master { int (*write)(struct fsi_master *, int link, uint8_t slave, uint32_t addr, const void *val, size_t size); + int (*send_break)(struct fsi_master *, int link); + int (*link_enable)(struct fsi_master *, int link); }; extern int fsi_master_register(struct fsi_master *master); -- 1.8.2.2
[PATCH v2 13/18] drivers/fsi: Remove all scanned devices during master unregister
From: Chris BosticMaster will remove all previously scanned devices during an unregister operation. This will be necessary should any master attempt to register more than once. Signed-off-by: Chris Bostic --- V2 - Remove list heads and explicit master device list management int the fsi master and fsi slave structs. Instead utilize the device_for_each_child method already available. --- drivers/fsi/fsi-core.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index af7965f..28b82d1 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -428,12 +428,26 @@ int fsi_master_register(struct fsi_master *master) } EXPORT_SYMBOL_GPL(fsi_master_register); +static int fsi_slave_device_remove(struct device *dev, void *data) +{ + put_device(dev); + return 0; +} + +static int fsi_master_slave_remove(struct device *dev, void *data) +{ + device_for_each_child(dev, NULL, fsi_slave_device_remove); + device_unregister(dev); + return 0; +} + void fsi_master_unregister(struct fsi_master *master) { if (!master || !master->dev) return; ida_simple_remove(_ida, master->idx); + device_for_each_child(master->dev, NULL, fsi_master_slave_remove); put_device(master->dev); } EXPORT_SYMBOL_GPL(fsi_master_unregister); -- 1.8.2.2
[PATCH v2 11/18] drivers/fsi: Set up links for slave communication
From: Chris Bostic Enable each link and send a break command in preparation for scanning each link for slaves. Signed-off-by: Chris Bostic Signed-off-by: Jeremy Kerr --- drivers/fsi/fsi-core.c | 38 -- drivers/fsi/fsi-master.h | 2 ++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3119aa1..b2c9274 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -271,14 +271,48 @@ static int fsi_slave_init(struct fsi_master *master, /* FSI master support */ +static int fsi_master_link_enable(struct fsi_master *master, int link) +{ + if (master->link_enable) + return master->link_enable(master, link); + + return 0; +} + +/* + * Issue a break command on this link + */ +static int fsi_master_break(struct fsi_master *master, int link) +{ + if (master->send_break) + return master->send_break(master, link); + + return 0; +} + static int fsi_master_scan(struct fsi_master *master) { - int link, slave_id; + int link, slave_id, rc; + + for (link = 0; link < master->n_links; link++) { + rc = fsi_master_link_enable(master, link); + if (rc) { + dev_dbg(master->dev, + "enable link:%d failed with:%d\n", link, rc); + continue; + } + rc = fsi_master_break(master, link); + if (rc) { + dev_dbg(master->dev, + "Break to link:%d failed with:%d\n", link, rc); + continue; + } - for (link = 0; link < master->n_links; link++) for (slave_id = 0; slave_id < FSI_N_SLAVES; slave_id++) fsi_slave_init(master, link, slave_id); + } + return 0; } diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h index e75a810..94a0671 100644 --- a/drivers/fsi/fsi-master.h +++ b/drivers/fsi/fsi-master.h @@ -29,6 +29,8 @@ struct fsi_master { int (*write)(struct fsi_master *, int link, uint8_t slave, uint32_t addr, const void *val, size_t size); + int (*send_break)(struct fsi_master *, int link); + int (*link_enable)(struct fsi_master *, int link); }; extern int fsi_master_register(struct fsi_master *master); -- 1.8.2.2
[PATCH v2 13/18] drivers/fsi: Remove all scanned devices during master unregister
From: Chris Bostic Master will remove all previously scanned devices during an unregister operation. This will be necessary should any master attempt to register more than once. Signed-off-by: Chris Bostic --- V2 - Remove list heads and explicit master device list management int the fsi master and fsi slave structs. Instead utilize the device_for_each_child method already available. --- drivers/fsi/fsi-core.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index af7965f..28b82d1 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -428,12 +428,26 @@ int fsi_master_register(struct fsi_master *master) } EXPORT_SYMBOL_GPL(fsi_master_register); +static int fsi_slave_device_remove(struct device *dev, void *data) +{ + put_device(dev); + return 0; +} + +static int fsi_master_slave_remove(struct device *dev, void *data) +{ + device_for_each_child(dev, NULL, fsi_slave_device_remove); + device_unregister(dev); + return 0; +} + void fsi_master_unregister(struct fsi_master *master) { if (!master || !master->dev) return; ida_simple_remove(_ida, master->idx); + device_for_each_child(master->dev, NULL, fsi_master_slave_remove); put_device(master->dev); } EXPORT_SYMBOL_GPL(fsi_master_unregister); -- 1.8.2.2
[PATCH v2 12/18] drivers/fsi: Set slave SMODE to init communication
From: Chris BosticSet CFAM to appropriate ID so that the controlling master can manage link memory ranges. Add slave engine register definitions. Signed-off-by: Chris Bostic Signed-off-by: Jeremy Kerr --- drivers/fsi/fsi-core.c | 90 +- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index b2c9274..af7965f 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -36,6 +36,7 @@ #define FSI_SLAVE_CONF_DATA_BITS 28 #define FSI_PEEK_BASE 0x410 +#defineFSI_SLAVE_BASE 0x800 static const int engine_page_size = 0x400; @@ -55,8 +56,26 @@ static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, const void *val, size_t size); -/* FSI endpoint-device support */ +/* + * FSI slave engine control register offsets + */ +#defineFSI_SMODE 0x0 /* R/W: Mode register */ + +/* + * SMODE fields + */ +#defineFSI_SMODE_WSC 0x8000 /* Warm start done */ +#defineFSI_SMODE_ECRC 0x2000 /* Hw CRC check */ +#defineFSI_SMODE_SID_SHIFT 24 /* ID shift */ +#defineFSI_SMODE_SID_MASK 3 /* ID Mask */ +#defineFSI_SMODE_ED_SHIFT 20 /* Echo delay shift */ +#defineFSI_SMODE_ED_MASK 0xf /* Echo delay mask */ +#defineFSI_SMODE_SD_SHIFT 16 /* Send delay shift */ +#defineFSI_SMODE_SD_MASK 0xf /* Send delay mask */ +#defineFSI_SMODE_LBCRR_SHIFT 8 /* Clk ratio shift */ +#defineFSI_SMODE_LBCRR_MASK0xf /* Clk ratio mask */ +/* FSI endpoint-device support */ int fsi_device_read(struct fsi_device *dev, uint32_t addr, void *val, size_t size) { @@ -114,6 +133,30 @@ static struct fsi_device *fsi_create_device(struct fsi_slave *slave) /* FSI slave support */ +/* Encode slave local bus echo delay */ +static inline uint32_t fsi_smode_echodly(int x) +{ + return (x & FSI_SMODE_ED_MASK) << FSI_SMODE_ED_SHIFT; +} + +/* Encode slave local bus send delay */ +static inline uint32_t fsi_smode_senddly(int x) +{ + return (x & FSI_SMODE_SD_MASK) << FSI_SMODE_SD_SHIFT; +} + +/* Encode slave local bus clock rate ratio */ +static inline uint32_t fsi_smode_lbcrr(int x) +{ + return (x & FSI_SMODE_LBCRR_MASK) << FSI_SMODE_LBCRR_SHIFT; +} + +/* Encode slave ID */ +static inline uint32_t fsi_smode_sid(int x) +{ + return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT; +} + static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, void *val, size_t size) { @@ -221,6 +264,22 @@ static void fsi_slave_release(struct device *dev) kfree(slave); } +static uint32_t set_smode_defaults(struct fsi_master *master) +{ + return FSI_SMODE_WSC | FSI_SMODE_ECRC + | fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf) + | fsi_smode_lbcrr(1); +} + +static int fsi_slave_set_smode(struct fsi_master *master, int link, int id) +{ + uint32_t smode = set_smode_defaults(master); + + smode |= fsi_smode_sid(id); + return master->write(master, link, 3, FSI_SLAVE_BASE + FSI_SMODE, + , sizeof(smode)); +} + static int fsi_slave_init(struct fsi_master *master, int link, uint8_t slave_id) { @@ -229,6 +288,21 @@ static int fsi_slave_init(struct fsi_master *master, int rc; uint8_t crc; + /* +* todo: Due to CFAM hardware issues related to BREAK commands we're +* limited to only one CFAM per link. Once issues are resolved this +* restriction can be removed. +*/ + if (slave_id > 0) + return 0; + + rc = fsi_slave_set_smode(master, link, slave_id); + if (rc) { + dev_warn(master->dev, "can't set smode on slave:%02x:%02x %d\n", + link, slave_id, rc); + return -ENODEV; + } + rc = master->read(master, link, slave_id, 0, _id, sizeof(chip_id)); if (rc) { dev_warn(master->dev, "can't read slave %02x:%02x: %d\n", @@ -293,6 +367,7 @@ static int fsi_master_break(struct fsi_master *master, int link) static int fsi_master_scan(struct fsi_master *master) { int link, slave_id, rc; + uint32_t smode; for (link = 0; link < master->n_links; link++) { rc = fsi_master_link_enable(master, link); @@ -308,6 +383,19 @@ static int fsi_master_scan(struct fsi_master *master) continue; } + /* +* Verify can read slave at default ID location. If fails +
[PATCH v2 12/18] drivers/fsi: Set slave SMODE to init communication
From: Chris Bostic Set CFAM to appropriate ID so that the controlling master can manage link memory ranges. Add slave engine register definitions. Signed-off-by: Chris Bostic Signed-off-by: Jeremy Kerr --- drivers/fsi/fsi-core.c | 90 +- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index b2c9274..af7965f 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -36,6 +36,7 @@ #define FSI_SLAVE_CONF_DATA_BITS 28 #define FSI_PEEK_BASE 0x410 +#defineFSI_SLAVE_BASE 0x800 static const int engine_page_size = 0x400; @@ -55,8 +56,26 @@ static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, const void *val, size_t size); -/* FSI endpoint-device support */ +/* + * FSI slave engine control register offsets + */ +#defineFSI_SMODE 0x0 /* R/W: Mode register */ + +/* + * SMODE fields + */ +#defineFSI_SMODE_WSC 0x8000 /* Warm start done */ +#defineFSI_SMODE_ECRC 0x2000 /* Hw CRC check */ +#defineFSI_SMODE_SID_SHIFT 24 /* ID shift */ +#defineFSI_SMODE_SID_MASK 3 /* ID Mask */ +#defineFSI_SMODE_ED_SHIFT 20 /* Echo delay shift */ +#defineFSI_SMODE_ED_MASK 0xf /* Echo delay mask */ +#defineFSI_SMODE_SD_SHIFT 16 /* Send delay shift */ +#defineFSI_SMODE_SD_MASK 0xf /* Send delay mask */ +#defineFSI_SMODE_LBCRR_SHIFT 8 /* Clk ratio shift */ +#defineFSI_SMODE_LBCRR_MASK0xf /* Clk ratio mask */ +/* FSI endpoint-device support */ int fsi_device_read(struct fsi_device *dev, uint32_t addr, void *val, size_t size) { @@ -114,6 +133,30 @@ static struct fsi_device *fsi_create_device(struct fsi_slave *slave) /* FSI slave support */ +/* Encode slave local bus echo delay */ +static inline uint32_t fsi_smode_echodly(int x) +{ + return (x & FSI_SMODE_ED_MASK) << FSI_SMODE_ED_SHIFT; +} + +/* Encode slave local bus send delay */ +static inline uint32_t fsi_smode_senddly(int x) +{ + return (x & FSI_SMODE_SD_MASK) << FSI_SMODE_SD_SHIFT; +} + +/* Encode slave local bus clock rate ratio */ +static inline uint32_t fsi_smode_lbcrr(int x) +{ + return (x & FSI_SMODE_LBCRR_MASK) << FSI_SMODE_LBCRR_SHIFT; +} + +/* Encode slave ID */ +static inline uint32_t fsi_smode_sid(int x) +{ + return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT; +} + static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, void *val, size_t size) { @@ -221,6 +264,22 @@ static void fsi_slave_release(struct device *dev) kfree(slave); } +static uint32_t set_smode_defaults(struct fsi_master *master) +{ + return FSI_SMODE_WSC | FSI_SMODE_ECRC + | fsi_smode_echodly(0xf) | fsi_smode_senddly(0xf) + | fsi_smode_lbcrr(1); +} + +static int fsi_slave_set_smode(struct fsi_master *master, int link, int id) +{ + uint32_t smode = set_smode_defaults(master); + + smode |= fsi_smode_sid(id); + return master->write(master, link, 3, FSI_SLAVE_BASE + FSI_SMODE, + , sizeof(smode)); +} + static int fsi_slave_init(struct fsi_master *master, int link, uint8_t slave_id) { @@ -229,6 +288,21 @@ static int fsi_slave_init(struct fsi_master *master, int rc; uint8_t crc; + /* +* todo: Due to CFAM hardware issues related to BREAK commands we're +* limited to only one CFAM per link. Once issues are resolved this +* restriction can be removed. +*/ + if (slave_id > 0) + return 0; + + rc = fsi_slave_set_smode(master, link, slave_id); + if (rc) { + dev_warn(master->dev, "can't set smode on slave:%02x:%02x %d\n", + link, slave_id, rc); + return -ENODEV; + } + rc = master->read(master, link, slave_id, 0, _id, sizeof(chip_id)); if (rc) { dev_warn(master->dev, "can't read slave %02x:%02x: %d\n", @@ -293,6 +367,7 @@ static int fsi_master_break(struct fsi_master *master, int link) static int fsi_master_scan(struct fsi_master *master) { int link, slave_id, rc; + uint32_t smode; for (link = 0; link < master->n_links; link++) { rc = fsi_master_link_enable(master, link); @@ -308,6 +383,19 @@ static int fsi_master_scan(struct fsi_master *master) continue; } + /* +* Verify can read slave at default ID location. If fails +* there must be nothing on other end of link +
[PATCH v2 10/18] drivers/fsi: Add device read/write/peek functions
From: Jeremy KerrThis change introduces the fsi device API: simple read, write and peek accessors for the devices' address spaces. Includes contributions from Chris Bostic Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Clean up white space. --- drivers/fsi/fsi-core.c | 47 +++ include/linux/fsi.h| 6 ++ 2 files changed, 53 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index f7ef993..3119aa1 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -35,6 +35,8 @@ #define FSI_SLAVE_CONF_CRC_MASK0x000f #define FSI_SLAVE_CONF_DATA_BITS 28 +#define FSI_PEEK_BASE 0x410 + static const int engine_page_size = 0x400; static DEFINE_IDA(master_ida); @@ -48,8 +50,46 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) +static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, + void *val, size_t size); +static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, + const void *val, size_t size); + /* FSI endpoint-device support */ +int fsi_device_read(struct fsi_device *dev, uint32_t addr, void *val, + size_t size) +{ + if (addr > dev->size) + return -EINVAL; + + if (addr + size > dev->size) + return -EINVAL; + + return fsi_slave_read(dev->slave, dev->addr + addr, val, size); +} +EXPORT_SYMBOL_GPL(fsi_device_read); + +int fsi_device_write(struct fsi_device *dev, uint32_t addr, const void *val, + size_t size) +{ + if (addr > dev->size) + return -EINVAL; + + if (addr + size > dev->size) + return -EINVAL; + + return fsi_slave_write(dev->slave, dev->addr + addr, val, size); +} +EXPORT_SYMBOL_GPL(fsi_device_write); + +int fsi_device_peek(struct fsi_device *dev, void *val) +{ + uint32_t addr = FSI_PEEK_BASE + ((dev->unit - 2) * sizeof(uint32_t)); + + return fsi_slave_read(dev->slave, addr, val, sizeof(uint32_t)); +} + static void fsi_device_release(struct device *_device) { struct fsi_device *device = to_fsi_dev(_device); @@ -81,6 +121,13 @@ static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, slave->id, addr, val, size); } +static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, + const void *val, size_t size) +{ + return slave->master->write(slave->master, slave->link, + slave->id, addr, val, size); +} + static int fsi_slave_scan(struct fsi_slave *slave) { uint32_t engine_addr; diff --git a/include/linux/fsi.h b/include/linux/fsi.h index efa55ba..273945d 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -27,6 +27,12 @@ struct fsi_device { uint32_tsize; }; +extern int fsi_device_read(struct fsi_device *dev, uint32_t addr, + void *val, size_t size); +extern int fsi_device_write(struct fsi_device *dev, uint32_t addr, + const void *val, size_t size); +extern int fsi_device_peek(struct fsi_device *dev, void *val); + struct fsi_device_id { u8 engine_type; u8 version; -- 1.8.2.2
[PATCH v2 10/18] drivers/fsi: Add device read/write/peek functions
From: Jeremy Kerr This change introduces the fsi device API: simple read, write and peek accessors for the devices' address spaces. Includes contributions from Chris Bostic Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Clean up white space. --- drivers/fsi/fsi-core.c | 47 +++ include/linux/fsi.h| 6 ++ 2 files changed, 53 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index f7ef993..3119aa1 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -35,6 +35,8 @@ #define FSI_SLAVE_CONF_CRC_MASK0x000f #define FSI_SLAVE_CONF_DATA_BITS 28 +#define FSI_PEEK_BASE 0x410 + static const int engine_page_size = 0x400; static DEFINE_IDA(master_ida); @@ -48,8 +50,46 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) +static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, + void *val, size_t size); +static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, + const void *val, size_t size); + /* FSI endpoint-device support */ +int fsi_device_read(struct fsi_device *dev, uint32_t addr, void *val, + size_t size) +{ + if (addr > dev->size) + return -EINVAL; + + if (addr + size > dev->size) + return -EINVAL; + + return fsi_slave_read(dev->slave, dev->addr + addr, val, size); +} +EXPORT_SYMBOL_GPL(fsi_device_read); + +int fsi_device_write(struct fsi_device *dev, uint32_t addr, const void *val, + size_t size) +{ + if (addr > dev->size) + return -EINVAL; + + if (addr + size > dev->size) + return -EINVAL; + + return fsi_slave_write(dev->slave, dev->addr + addr, val, size); +} +EXPORT_SYMBOL_GPL(fsi_device_write); + +int fsi_device_peek(struct fsi_device *dev, void *val) +{ + uint32_t addr = FSI_PEEK_BASE + ((dev->unit - 2) * sizeof(uint32_t)); + + return fsi_slave_read(dev->slave, addr, val, sizeof(uint32_t)); +} + static void fsi_device_release(struct device *_device) { struct fsi_device *device = to_fsi_dev(_device); @@ -81,6 +121,13 @@ static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, slave->id, addr, val, size); } +static int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, + const void *val, size_t size) +{ + return slave->master->write(slave->master, slave->link, + slave->id, addr, val, size); +} + static int fsi_slave_scan(struct fsi_slave *slave) { uint32_t engine_addr; diff --git a/include/linux/fsi.h b/include/linux/fsi.h index efa55ba..273945d 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -27,6 +27,12 @@ struct fsi_device { uint32_tsize; }; +extern int fsi_device_read(struct fsi_device *dev, uint32_t addr, + void *val, size_t size); +extern int fsi_device_write(struct fsi_device *dev, uint32_t addr, + const void *val, size_t size); +extern int fsi_device_peek(struct fsi_device *dev, void *val); + struct fsi_device_id { u8 engine_type; u8 version; -- 1.8.2.2
[PATCH v2 09/18] drivers/fsi: scan slaves & register devices
From: Jeremy KerrNow that we have fsi_slave devices, scan each for endpoints, and register them on the fsi bus. Includes contributions from Chris Bostic Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 136 +++-- include/linux/fsi.h| 4 ++ 2 files changed, 136 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 931bcba..f7ef993 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -23,9 +23,19 @@ #include "fsi-master.h" #define FSI_N_SLAVES 4 -#define FSI_SLAVE_CONF_CRC_SHIFT4 -#define FSI_SLAVE_CONF_CRC_MASK 0x000f -#define FSI_SLAVE_CONF_DATA_BITS28 + +#define FSI_SLAVE_CONF_NEXT_MASK 0x8000 +#define FSI_SLAVE_CONF_SLOTS_MASK 0x00ff +#define FSI_SLAVE_CONF_SLOTS_SHIFT 16 +#define FSI_SLAVE_CONF_VERSION_MASK0xf000 +#define FSI_SLAVE_CONF_VERSION_SHIFT 12 +#define FSI_SLAVE_CONF_TYPE_MASK 0x0ff0 +#define FSI_SLAVE_CONF_TYPE_SHIFT 4 +#define FSI_SLAVE_CONF_CRC_SHIFT 4 +#define FSI_SLAVE_CONF_CRC_MASK0x000f +#define FSI_SLAVE_CONF_DATA_BITS 28 + +static const int engine_page_size = 0x400; static DEFINE_IDA(master_ida); @@ -38,8 +48,125 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) +/* FSI endpoint-device support */ + +static void fsi_device_release(struct device *_device) +{ + struct fsi_device *device = to_fsi_dev(_device); + + kfree(device); +} + +static struct fsi_device *fsi_create_device(struct fsi_slave *slave) +{ + struct fsi_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->dev.parent = >dev; + dev->dev.bus = _bus_type; + dev->dev.release = fsi_device_release; + + return dev; +} + /* FSI slave support */ +static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, + void *val, size_t size) +{ + return slave->master->read(slave->master, slave->link, + slave->id, addr, val, size); +} + +static int fsi_slave_scan(struct fsi_slave *slave) +{ + uint32_t engine_addr; + uint32_t conf; + int rc, i; + + /* +* scan engines +* +* We keep the peek mode and slave engines for the core; so start +* at the third slot in the configuration table. We also need to +* skip the chip ID entry at the start of the address space. +*/ + engine_addr = engine_page_size * 3; + for (i = 2; i < engine_page_size / sizeof(uint32_t); i++) { + uint8_t slots, version, type, crc; + struct fsi_device *dev; + + rc = fsi_slave_read(slave, (i + 1) * sizeof(conf), + , sizeof(conf)); + if (rc) { + dev_warn(>dev, + "error reading slave registers\n"); + return -1; + } + + crc = crc_fsi(0, conf >> FSI_SLAVE_CONF_CRC_SHIFT, + FSI_SLAVE_CONF_DATA_BITS); + if (crc != (conf & FSI_SLAVE_CONF_CRC_MASK)) { + dev_warn(>dev, + "crc error in slave register at 0x%04x\n", + i); + return -1; + } + + slots = (conf & FSI_SLAVE_CONF_SLOTS_MASK) + >> FSI_SLAVE_CONF_SLOTS_SHIFT; + version = (conf & FSI_SLAVE_CONF_VERSION_MASK) + >> FSI_SLAVE_CONF_VERSION_SHIFT; + type = (conf & FSI_SLAVE_CONF_TYPE_MASK) + >> FSI_SLAVE_CONF_TYPE_SHIFT; + + /* +* Unused address areas are marked by a zero type value; this +* skips the defined address areas +*/ + if (type != 0) { + + /* create device */ + dev = fsi_create_device(slave); + if (!dev) + return -ENOMEM; + + dev->slave = slave; + dev->engine_type = type; + dev->version = version; + dev->unit = i; + dev->addr = engine_addr; + dev->size = slots * engine_page_size; + + dev_info(>dev, + "engine[%i]: type %x, version %x, addr %x size %x\n", + dev->unit, dev->engine_type, version, + dev->addr, dev->size); + + device_initialize(>dev); + dev_set_name(>dev, "%02x:%02x:%02x:%02x", +
[PATCH v2 09/18] drivers/fsi: scan slaves & register devices
From: Jeremy Kerr Now that we have fsi_slave devices, scan each for endpoints, and register them on the fsi bus. Includes contributions from Chris Bostic Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 136 +++-- include/linux/fsi.h| 4 ++ 2 files changed, 136 insertions(+), 4 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 931bcba..f7ef993 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -23,9 +23,19 @@ #include "fsi-master.h" #define FSI_N_SLAVES 4 -#define FSI_SLAVE_CONF_CRC_SHIFT4 -#define FSI_SLAVE_CONF_CRC_MASK 0x000f -#define FSI_SLAVE_CONF_DATA_BITS28 + +#define FSI_SLAVE_CONF_NEXT_MASK 0x8000 +#define FSI_SLAVE_CONF_SLOTS_MASK 0x00ff +#define FSI_SLAVE_CONF_SLOTS_SHIFT 16 +#define FSI_SLAVE_CONF_VERSION_MASK0xf000 +#define FSI_SLAVE_CONF_VERSION_SHIFT 12 +#define FSI_SLAVE_CONF_TYPE_MASK 0x0ff0 +#define FSI_SLAVE_CONF_TYPE_SHIFT 4 +#define FSI_SLAVE_CONF_CRC_SHIFT 4 +#define FSI_SLAVE_CONF_CRC_MASK0x000f +#define FSI_SLAVE_CONF_DATA_BITS 28 + +static const int engine_page_size = 0x400; static DEFINE_IDA(master_ida); @@ -38,8 +48,125 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) +/* FSI endpoint-device support */ + +static void fsi_device_release(struct device *_device) +{ + struct fsi_device *device = to_fsi_dev(_device); + + kfree(device); +} + +static struct fsi_device *fsi_create_device(struct fsi_slave *slave) +{ + struct fsi_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->dev.parent = >dev; + dev->dev.bus = _bus_type; + dev->dev.release = fsi_device_release; + + return dev; +} + /* FSI slave support */ +static int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, + void *val, size_t size) +{ + return slave->master->read(slave->master, slave->link, + slave->id, addr, val, size); +} + +static int fsi_slave_scan(struct fsi_slave *slave) +{ + uint32_t engine_addr; + uint32_t conf; + int rc, i; + + /* +* scan engines +* +* We keep the peek mode and slave engines for the core; so start +* at the third slot in the configuration table. We also need to +* skip the chip ID entry at the start of the address space. +*/ + engine_addr = engine_page_size * 3; + for (i = 2; i < engine_page_size / sizeof(uint32_t); i++) { + uint8_t slots, version, type, crc; + struct fsi_device *dev; + + rc = fsi_slave_read(slave, (i + 1) * sizeof(conf), + , sizeof(conf)); + if (rc) { + dev_warn(>dev, + "error reading slave registers\n"); + return -1; + } + + crc = crc_fsi(0, conf >> FSI_SLAVE_CONF_CRC_SHIFT, + FSI_SLAVE_CONF_DATA_BITS); + if (crc != (conf & FSI_SLAVE_CONF_CRC_MASK)) { + dev_warn(>dev, + "crc error in slave register at 0x%04x\n", + i); + return -1; + } + + slots = (conf & FSI_SLAVE_CONF_SLOTS_MASK) + >> FSI_SLAVE_CONF_SLOTS_SHIFT; + version = (conf & FSI_SLAVE_CONF_VERSION_MASK) + >> FSI_SLAVE_CONF_VERSION_SHIFT; + type = (conf & FSI_SLAVE_CONF_TYPE_MASK) + >> FSI_SLAVE_CONF_TYPE_SHIFT; + + /* +* Unused address areas are marked by a zero type value; this +* skips the defined address areas +*/ + if (type != 0) { + + /* create device */ + dev = fsi_create_device(slave); + if (!dev) + return -ENOMEM; + + dev->slave = slave; + dev->engine_type = type; + dev->version = version; + dev->unit = i; + dev->addr = engine_addr; + dev->size = slots * engine_page_size; + + dev_info(>dev, + "engine[%i]: type %x, version %x, addr %x size %x\n", + dev->unit, dev->engine_type, version, + dev->addr, dev->size); + + device_initialize(>dev); + dev_set_name(>dev, "%02x:%02x:%02x:%02x", + slave->master->idx, slave->link, +
[PATCH v2 08/18] drivers/fsi: Implement slave initialisation
From: Jeremy KerrCreate fsi_slave devices during the master scan. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 56 -- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 5f9f7a9..931bcba 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -17,10 +17,15 @@ #include #include #include +#include +#include #include "fsi-master.h" #define FSI_N_SLAVES 4 +#define FSI_SLAVE_CONF_CRC_SHIFT4 +#define FSI_SLAVE_CONF_CRC_MASK 0x000f +#define FSI_SLAVE_CONF_DATA_BITS28 static DEFINE_IDA(master_ida); @@ -34,12 +39,59 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) /* FSI slave support */ + +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 slave_id) { - /* todo: initialise slave device, perform engine scan */ + struct fsi_slave *slave; + uint32_t chip_id; + int rc; + uint8_t crc; + + rc = master->read(master, link, slave_id, 0, _id, sizeof(chip_id)); + if (rc) { + dev_warn(master->dev, "can't read slave %02x:%02x: %d\n", + link, slave_id, rc); + return -ENODEV; + } + crc = crc_fsi(0, chip_id >> FSI_SLAVE_CONF_CRC_SHIFT, + FSI_SLAVE_CONF_DATA_BITS); + if (crc != (chip_id & FSI_SLAVE_CONF_CRC_MASK)) { + dev_warn(master->dev, "slave %02x:%02x invalid chip id CRC!\n", + link, slave_id); + return -EIO; + } + + pr_debug("fsi: found chip %08x at %02x:%02x:%02x\n", + master->idx, chip_id, link, slave_id); + + /* we can communicate with a slave; create devices and scan */ + slave = kzalloc(sizeof(*slave), GFP_KERNEL); + if (!slave) + return -ENOMEM; + + slave->master = master; + slave->id = slave_id; + slave->dev.parent = master->dev; + slave->dev.release = fsi_slave_release; + + dev_set_name(>dev, "slave@%02x:%02x", link, slave_id); + rc = device_register(>dev); + if (rc < 0) { + dev_warn(master->dev, "failed to create slave device: %d\n", + rc); + put_device(>dev); + return rc; + } - return -ENODEV; + return rc; } /* FSI master support */ -- 1.8.2.2
[PATCH v2 08/18] drivers/fsi: Implement slave initialisation
From: Jeremy Kerr Create fsi_slave devices during the master scan. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 56 -- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 5f9f7a9..931bcba 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -17,10 +17,15 @@ #include #include #include +#include +#include #include "fsi-master.h" #define FSI_N_SLAVES 4 +#define FSI_SLAVE_CONF_CRC_SHIFT4 +#define FSI_SLAVE_CONF_CRC_MASK 0x000f +#define FSI_SLAVE_CONF_DATA_BITS28 static DEFINE_IDA(master_ida); @@ -34,12 +39,59 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) /* FSI slave support */ + +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 slave_id) { - /* todo: initialise slave device, perform engine scan */ + struct fsi_slave *slave; + uint32_t chip_id; + int rc; + uint8_t crc; + + rc = master->read(master, link, slave_id, 0, _id, sizeof(chip_id)); + if (rc) { + dev_warn(master->dev, "can't read slave %02x:%02x: %d\n", + link, slave_id, rc); + return -ENODEV; + } + crc = crc_fsi(0, chip_id >> FSI_SLAVE_CONF_CRC_SHIFT, + FSI_SLAVE_CONF_DATA_BITS); + if (crc != (chip_id & FSI_SLAVE_CONF_CRC_MASK)) { + dev_warn(master->dev, "slave %02x:%02x invalid chip id CRC!\n", + link, slave_id); + return -EIO; + } + + pr_debug("fsi: found chip %08x at %02x:%02x:%02x\n", + master->idx, chip_id, link, slave_id); + + /* we can communicate with a slave; create devices and scan */ + slave = kzalloc(sizeof(*slave), GFP_KERNEL); + if (!slave) + return -ENOMEM; + + slave->master = master; + slave->id = slave_id; + slave->dev.parent = master->dev; + slave->dev.release = fsi_slave_release; + + dev_set_name(>dev, "slave@%02x:%02x", link, slave_id); + rc = device_register(>dev); + if (rc < 0) { + dev_warn(master->dev, "failed to create slave device: %d\n", + rc); + put_device(>dev); + return rc; + } - return -ENODEV; + return rc; } /* FSI master support */ -- 1.8.2.2
[PATCH v2 07/18] drivers/fsi: Kick off master scan via sysfs
From: Chris BosticMove master scan from automatic kick off early in kernel power up to a scan file that can be invoked at any particular time based on needs of a given platform. Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3160c1c..5f9f7a9 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -53,8 +53,19 @@ static int fsi_master_scan(struct fsi_master *master) fsi_slave_init(master, link, slave_id); return 0; +} + +static ssize_t store_scan(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct fsi_master *master = dev_get_drvdata(dev); + fsi_master_scan(master); + return count; } +static DEVICE_ATTR(scan, 0200, NULL, store_scan); int fsi_master_register(struct fsi_master *master) { @@ -63,8 +74,8 @@ int fsi_master_register(struct fsi_master *master) master->idx = ida_simple_get(_ida, 0, 0, GFP_KERNEL); get_device(master->dev); - fsi_master_scan(master); - return 0; + dev_set_drvdata(master->dev, master); + return device_create_file(master->dev, _attr_scan); } EXPORT_SYMBOL_GPL(fsi_master_register); -- 1.8.2.2
[PATCH v2 07/18] drivers/fsi: Kick off master scan via sysfs
From: Chris Bostic Move master scan from automatic kick off early in kernel power up to a scan file that can be invoked at any particular time based on needs of a given platform. Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3160c1c..5f9f7a9 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -53,8 +53,19 @@ static int fsi_master_scan(struct fsi_master *master) fsi_slave_init(master, link, slave_id); return 0; +} + +static ssize_t store_scan(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct fsi_master *master = dev_get_drvdata(dev); + fsi_master_scan(master); + return count; } +static DEVICE_ATTR(scan, 0200, NULL, store_scan); int fsi_master_register(struct fsi_master *master) { @@ -63,8 +74,8 @@ int fsi_master_register(struct fsi_master *master) master->idx = ida_simple_get(_ida, 0, 0, GFP_KERNEL); get_device(master->dev); - fsi_master_scan(master); - return 0; + dev_set_drvdata(master->dev, master); + return device_create_file(master->dev, _attr_scan); } EXPORT_SYMBOL_GPL(fsi_master_register); -- 1.8.2.2
[PATCH v2 06/18] drivers/fsi: Add FSI crc calculators to library
From: Jeremy KerrAdd some helpers for the crc checks for the slave configuration table. This works 4-bits-at-a-time, using a simple table approach. We will need this in the FSI core code, as well as any master implementations that need to calculate CRCs in software. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Move crc utilities out of the FSI core and move into linux/lib. --- include/linux/crc-fsi.h | 29 + lib/Makefile| 1 + lib/crc-fsi.c | 39 +++ 3 files changed, 69 insertions(+) create mode 100644 include/linux/crc-fsi.h create mode 100644 lib/crc-fsi.c diff --git a/include/linux/crc-fsi.h b/include/linux/crc-fsi.h new file mode 100644 index 000..e96d2f0 --- /dev/null +++ b/include/linux/crc-fsi.h @@ -0,0 +1,29 @@ +/* + * FSI CRC calculator + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Implements the standard FSI CRC: + * + * Width 1 - 32 + * Poly 0x0017 (x^4 + x^2 + x^1 + x^0) + */ + +#ifndef CRC_FSI_H +#define CRC_FSI_H + +#include + +uint8_t crc_fsi(uint8_t c, uint64_t x, int bits); + +#endif /* CRC_FSI_H */ diff --git a/lib/Makefile b/lib/Makefile index 50144a3..c840628 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -230,3 +230,4 @@ obj-$(CONFIG_UBSAN) += ubsan.o UBSAN_SANITIZE_ubsan.o := n obj-$(CONFIG_SBITMAP) += sbitmap.o +obj-$(CONFIG_FSI) += crc-fsi.o diff --git a/lib/crc-fsi.c b/lib/crc-fsi.c new file mode 100644 index 000..55cfe9d --- /dev/null +++ b/lib/crc-fsi.c @@ -0,0 +1,39 @@ +/* + * FSI CRC calculator + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +/* crc helpers */ +static const uint8_t crc_fsi_tab[] = { + 0x0, 0x7, 0xe, 0x9, 0xb, 0xc, 0x5, 0x2, + 0x1, 0x6, 0xf, 0x8, 0xa, 0xd, 0x4, 0x3, +}; + +uint8_t crc_fsi(uint8_t c, uint64_t x, int bits) +{ + int i; + + /* Align to 4-bits */ + bits = (bits + 3) & ~0x3; + + /* Calculate crc4 over four-bit nibbles, starting at the MSbit */ + for (i = bits; i >= 0; i -= 4) + c = crc_fsi_tab[c ^ ((x >> i) & 0xf)]; + + return c; +} +EXPORT_SYMBOL_GPL(crc_fsi); -- 1.8.2.2
[PATCH v2 06/18] drivers/fsi: Add FSI crc calculators to library
From: Jeremy Kerr Add some helpers for the crc checks for the slave configuration table. This works 4-bits-at-a-time, using a simple table approach. We will need this in the FSI core code, as well as any master implementations that need to calculate CRCs in software. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Move crc utilities out of the FSI core and move into linux/lib. --- include/linux/crc-fsi.h | 29 + lib/Makefile| 1 + lib/crc-fsi.c | 39 +++ 3 files changed, 69 insertions(+) create mode 100644 include/linux/crc-fsi.h create mode 100644 lib/crc-fsi.c diff --git a/include/linux/crc-fsi.h b/include/linux/crc-fsi.h new file mode 100644 index 000..e96d2f0 --- /dev/null +++ b/include/linux/crc-fsi.h @@ -0,0 +1,29 @@ +/* + * FSI CRC calculator + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * Implements the standard FSI CRC: + * + * Width 1 - 32 + * Poly 0x0017 (x^4 + x^2 + x^1 + x^0) + */ + +#ifndef CRC_FSI_H +#define CRC_FSI_H + +#include + +uint8_t crc_fsi(uint8_t c, uint64_t x, int bits); + +#endif /* CRC_FSI_H */ diff --git a/lib/Makefile b/lib/Makefile index 50144a3..c840628 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -230,3 +230,4 @@ obj-$(CONFIG_UBSAN) += ubsan.o UBSAN_SANITIZE_ubsan.o := n obj-$(CONFIG_SBITMAP) += sbitmap.o +obj-$(CONFIG_FSI) += crc-fsi.o diff --git a/lib/crc-fsi.c b/lib/crc-fsi.c new file mode 100644 index 000..55cfe9d --- /dev/null +++ b/lib/crc-fsi.c @@ -0,0 +1,39 @@ +/* + * FSI CRC calculator + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +/* crc helpers */ +static const uint8_t crc_fsi_tab[] = { + 0x0, 0x7, 0xe, 0x9, 0xb, 0xc, 0x5, 0x2, + 0x1, 0x6, 0xf, 0x8, 0xa, 0xd, 0x4, 0x3, +}; + +uint8_t crc_fsi(uint8_t c, uint64_t x, int bits) +{ + int i; + + /* Align to 4-bits */ + bits = (bits + 3) & ~0x3; + + /* Calculate crc4 over four-bit nibbles, starting at the MSbit */ + for (i = bits; i >= 0; i -= 4) + c = crc_fsi_tab[c ^ ((x >> i) & 0xf)]; + + return c; +} +EXPORT_SYMBOL_GPL(crc_fsi); -- 1.8.2.2
[PATCH v2 05/18] drivers/fsi: Add empty master scan
From: Jeremy KerrWhen a new fsi master is added, we will need to scan its links, and slaves attached to those links. This change introduces a little shell to iterate the links, which we will populate with the actual slave scan in a later change. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 78d9c558..3160c1c 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -20,6 +20,8 @@ #include "fsi-master.h" +#define FSI_N_SLAVES 4 + static DEFINE_IDA(master_ida); struct fsi_slave { @@ -31,8 +33,29 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) +/* FSI slave support */ +static int fsi_slave_init(struct fsi_master *master, + int link, uint8_t slave_id) +{ + /* todo: initialise slave device, perform engine scan */ + + return -ENODEV; +} + /* FSI master support */ +static int fsi_master_scan(struct fsi_master *master) +{ + int link, slave_id; + + for (link = 0; link < master->n_links; link++) + for (slave_id = 0; slave_id < FSI_N_SLAVES; slave_id++) + fsi_slave_init(master, link, slave_id); + + return 0; + +} + int fsi_master_register(struct fsi_master *master) { if (!master || !master->dev) @@ -40,6 +63,7 @@ int fsi_master_register(struct fsi_master *master) master->idx = ida_simple_get(_ida, 0, 0, GFP_KERNEL); get_device(master->dev); + fsi_master_scan(master); return 0; } EXPORT_SYMBOL_GPL(fsi_master_register); -- 1.8.2.2
[PATCH v2 05/18] drivers/fsi: Add empty master scan
From: Jeremy Kerr When a new fsi master is added, we will need to scan its links, and slaves attached to those links. This change introduces a little shell to iterate the links, which we will populate with the actual slave scan in a later change. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 78d9c558..3160c1c 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -20,6 +20,8 @@ #include "fsi-master.h" +#define FSI_N_SLAVES 4 + static DEFINE_IDA(master_ida); struct fsi_slave { @@ -31,8 +33,29 @@ struct fsi_slave { #define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) +/* FSI slave support */ +static int fsi_slave_init(struct fsi_master *master, + int link, uint8_t slave_id) +{ + /* todo: initialise slave device, perform engine scan */ + + return -ENODEV; +} + /* FSI master support */ +static int fsi_master_scan(struct fsi_master *master) +{ + int link, slave_id; + + for (link = 0; link < master->n_links; link++) + for (slave_id = 0; slave_id < FSI_N_SLAVES; slave_id++) + fsi_slave_init(master, link, slave_id); + + return 0; + +} + int fsi_master_register(struct fsi_master *master) { if (!master || !master->dev) @@ -40,6 +63,7 @@ int fsi_master_register(struct fsi_master *master) master->idx = ida_simple_get(_ida, 0, 0, GFP_KERNEL); get_device(master->dev); + fsi_master_scan(master); return 0; } EXPORT_SYMBOL_GPL(fsi_master_register); -- 1.8.2.2
[PATCH v2 04/18] drivers/fsi: Add slave definition
From: Jeremy KerrAdd the initial fsi slave device, which is private to the core code. This will be a child of the master, and parent to endpoint devices. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index c7469fe..78d9c558 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -22,6 +22,15 @@ static DEFINE_IDA(master_ida); +struct fsi_slave { + struct device dev; + struct fsi_master *master; + int link; + uint8_t id; +}; + +#define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) + /* FSI master support */ int fsi_master_register(struct fsi_master *master) -- 1.8.2.2
[PATCH v2 04/18] drivers/fsi: Add slave definition
From: Jeremy Kerr Add the initial fsi slave device, which is private to the core code. This will be a child of the master, and parent to endpoint devices. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index c7469fe..78d9c558 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -22,6 +22,15 @@ static DEFINE_IDA(master_ida); +struct fsi_slave { + struct device dev; + struct fsi_master *master; + int link; + uint8_t id; +}; + +#define to_fsi_slave(d) container_of(d, struct fsi_slave, dev) + /* FSI master support */ int fsi_master_register(struct fsi_master *master) -- 1.8.2.2
[PATCH v2 03/18] drivers/fsi: Add fsi master definition
From: Jeremy KerrSigned-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Change atomic global keeping track of master number to ida simple interface. - Add valid pointer checks on entry to register and unregister. --- drivers/fsi/fsi-core.c | 28 drivers/fsi/fsi-master.h | 37 + 2 files changed, 65 insertions(+) create mode 100644 drivers/fsi/fsi-master.h diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3d55bd5..c7469fe 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -16,6 +16,34 @@ #include #include #include +#include + +#include "fsi-master.h" + +static DEFINE_IDA(master_ida); + +/* FSI master support */ + +int fsi_master_register(struct fsi_master *master) +{ + if (!master || !master->dev) + return -EINVAL; + + master->idx = ida_simple_get(_ida, 0, 0, GFP_KERNEL); + get_device(master->dev); + return 0; +} +EXPORT_SYMBOL_GPL(fsi_master_register); + +void fsi_master_unregister(struct fsi_master *master) +{ + if (!master || !master->dev) + return; + + ida_simple_remove(_ida, master->idx); + put_device(master->dev); +} +EXPORT_SYMBOL_GPL(fsi_master_unregister); /* FSI core & Linux bus type definitions */ diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h new file mode 100644 index 000..e75a810 --- /dev/null +++ b/drivers/fsi/fsi-master.h @@ -0,0 +1,37 @@ +/* + * FSI master definitions. These comprise the core <--> master interface, + * to allow the core to interact with the (hardware-specific) masters. + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef DRIVERS_FSI_MASTER_H +#define DRIVERS_FSI_MASTER_H + +#include + +struct fsi_master { + struct device *dev; + int idx; + int n_links; + int (*read)(struct fsi_master *, int link, + uint8_t slave, uint32_t addr, + void *val, size_t size); + int (*write)(struct fsi_master *, int link, + uint8_t slave, uint32_t addr, + const void *val, size_t size); +}; + +extern int fsi_master_register(struct fsi_master *master); +extern void fsi_master_unregister(struct fsi_master *master); + +#endif /* DRIVERS_FSI_MASTER_H */ -- 1.8.2.2
[PATCH v2 03/18] drivers/fsi: Add fsi master definition
From: Jeremy Kerr Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- V2 - Change atomic global keeping track of master number to ida simple interface. - Add valid pointer checks on entry to register and unregister. --- drivers/fsi/fsi-core.c | 28 drivers/fsi/fsi-master.h | 37 + 2 files changed, 65 insertions(+) create mode 100644 drivers/fsi/fsi-master.h diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3d55bd5..c7469fe 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -16,6 +16,34 @@ #include #include #include +#include + +#include "fsi-master.h" + +static DEFINE_IDA(master_ida); + +/* FSI master support */ + +int fsi_master_register(struct fsi_master *master) +{ + if (!master || !master->dev) + return -EINVAL; + + master->idx = ida_simple_get(_ida, 0, 0, GFP_KERNEL); + get_device(master->dev); + return 0; +} +EXPORT_SYMBOL_GPL(fsi_master_register); + +void fsi_master_unregister(struct fsi_master *master) +{ + if (!master || !master->dev) + return; + + ida_simple_remove(_ida, master->idx); + put_device(master->dev); +} +EXPORT_SYMBOL_GPL(fsi_master_unregister); /* FSI core & Linux bus type definitions */ diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h new file mode 100644 index 000..e75a810 --- /dev/null +++ b/drivers/fsi/fsi-master.h @@ -0,0 +1,37 @@ +/* + * FSI master definitions. These comprise the core <--> master interface, + * to allow the core to interact with the (hardware-specific) masters. + * + * Copyright (C) IBM Corporation 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef DRIVERS_FSI_MASTER_H +#define DRIVERS_FSI_MASTER_H + +#include + +struct fsi_master { + struct device *dev; + int idx; + int n_links; + int (*read)(struct fsi_master *, int link, + uint8_t slave, uint32_t addr, + void *val, size_t size); + int (*write)(struct fsi_master *, int link, + uint8_t slave, uint32_t addr, + const void *val, size_t size); +}; + +extern int fsi_master_register(struct fsi_master *master); +extern void fsi_master_unregister(struct fsi_master *master); + +#endif /* DRIVERS_FSI_MASTER_H */ -- 1.8.2.2
[PATCH v2 02/18] drivers/fsi: add driver to device matches
From: Jeremy KerrDriver bind to devices based on the engine types & (optional) versions. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 21 + include/linux/fsi.h| 21 +++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3e45306..3d55bd5 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -19,8 +19,29 @@ /* FSI core & Linux bus type definitions */ +static int fsi_bus_match(struct device *dev, struct device_driver *drv) +{ + struct fsi_device *fsi_dev = to_fsi_dev(dev); + struct fsi_driver *fsi_drv = to_fsi_drv(drv); + const struct fsi_device_id *id; + + if (!fsi_drv->id_table) + return 0; + + for (id = fsi_drv->id_table; id->engine_type; id++) { + if (id->engine_type != fsi_dev->engine_type) + continue; + if (id->version == FSI_VERSION_ANY || + id->version == fsi_dev->version) + return 1; + } + + return 0; +} + struct bus_type fsi_bus_type = { .name = "fsi", + .match = fsi_bus_match, }; EXPORT_SYMBOL_GPL(fsi_bus_type); diff --git a/include/linux/fsi.h b/include/linux/fsi.h index f73886a..273cbf6 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -18,11 +18,28 @@ #include struct fsi_device { - struct device dev; + struct device dev; + u8 engine_type; + u8 version; }; +struct fsi_device_id { + u8 engine_type; + u8 version; +}; + +#define FSI_VERSION_ANY0 + +#define FSI_DEVICE(t) \ + .engine_type = (t), .version = FSI_VERSION_ANY, + +#define FSI_DEVICE_VERSIONED(t, v) \ + .engine_type = (t), .version = (v), + + struct fsi_driver { - struct device_driver drv; + struct device_driverdrv; + const struct fsi_device_id *id_table; }; #define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) -- 1.8.2.2
[PATCH v2 02/18] drivers/fsi: add driver to device matches
From: Jeremy Kerr Driver bind to devices based on the engine types & (optional) versions. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- drivers/fsi/fsi-core.c | 21 + include/linux/fsi.h| 21 +++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 3e45306..3d55bd5 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -19,8 +19,29 @@ /* FSI core & Linux bus type definitions */ +static int fsi_bus_match(struct device *dev, struct device_driver *drv) +{ + struct fsi_device *fsi_dev = to_fsi_dev(dev); + struct fsi_driver *fsi_drv = to_fsi_drv(drv); + const struct fsi_device_id *id; + + if (!fsi_drv->id_table) + return 0; + + for (id = fsi_drv->id_table; id->engine_type; id++) { + if (id->engine_type != fsi_dev->engine_type) + continue; + if (id->version == FSI_VERSION_ANY || + id->version == fsi_dev->version) + return 1; + } + + return 0; +} + struct bus_type fsi_bus_type = { .name = "fsi", + .match = fsi_bus_match, }; EXPORT_SYMBOL_GPL(fsi_bus_type); diff --git a/include/linux/fsi.h b/include/linux/fsi.h index f73886a..273cbf6 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -18,11 +18,28 @@ #include struct fsi_device { - struct device dev; + struct device dev; + u8 engine_type; + u8 version; }; +struct fsi_device_id { + u8 engine_type; + u8 version; +}; + +#define FSI_VERSION_ANY0 + +#define FSI_DEVICE(t) \ + .engine_type = (t), .version = FSI_VERSION_ANY, + +#define FSI_DEVICE_VERSIONED(t, v) \ + .engine_type = (t), .version = (v), + + struct fsi_driver { - struct device_driver drv; + struct device_driverdrv; + const struct fsi_device_id *id_table; }; #define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) -- 1.8.2.2
[PATCH v2 01/18] drivers/fsi: Add device & driver definitions
From: Jeremy KerrAdd structs for fsi devices & drivers, and struct device conversion functions. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- include/linux/fsi.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/include/linux/fsi.h b/include/linux/fsi.h index 47aa181..f73886a 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -17,6 +17,17 @@ #include +struct fsi_device { + struct device dev; +}; + +struct fsi_driver { + struct device_driver drv; +}; + +#define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) +#define to_fsi_drv(drvp) container_of(drvp, struct fsi_driver, drv) + extern struct bus_type fsi_bus_type; #endif /* LINUX_FSI_H */ -- 1.8.2.2
[PATCH v2 01/18] drivers/fsi: Add device & driver definitions
From: Jeremy Kerr Add structs for fsi devices & drivers, and struct device conversion functions. Signed-off-by: Jeremy Kerr Signed-off-by: Chris Bostic --- include/linux/fsi.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/include/linux/fsi.h b/include/linux/fsi.h index 47aa181..f73886a 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -17,6 +17,17 @@ #include +struct fsi_device { + struct device dev; +}; + +struct fsi_driver { + struct device_driver drv; +}; + +#define to_fsi_dev(devp) container_of(devp, struct fsi_device, dev) +#define to_fsi_drv(drvp) container_of(drvp, struct fsi_driver, drv) + extern struct bus_type fsi_bus_type; #endif /* LINUX_FSI_H */ -- 1.8.2.2
[PATCH v2 00/18] FSI device driver introduction
From: Chris BosticIntroduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all comptible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interfac for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig| 23 + drivers/fsi/Makefile | 3 + drivers/fsi/fsi-core.c
[PATCH v2 00/18] FSI device driver introduction
From: Chris Bostic Introduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (8): drivers/fsi: Kick off master scan via sysfs drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Remove all scanned devices during master unregister drivers/fsi: Add FSI bus documentation drivers/fsi: Add documentation for GPIO based FSI master drivers/fsi: Document FSI master sysfs files in ABI drivers/fsi: Add GPIO based FSI master Jeremy Kerr (10): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add FSI crc calculators to library drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions Changes for v2: - Change from atomic global for master number to ida simple interface. - Add valid pointer checks on register and unregister utils. - Move CRC calculation utilities out of driver to lib path. - Clean up white space issues. - Remove added list management of master devices and use instead the device_for_each_child method available in the bus. - Add new patch to document FSI bus functionality. - Add new patch documenting FSI gpio master. - Rearrage patch set to have documentation earlier than code implementing it. - Document all comptible strings used in device tree bindings. - Elaborate documentation definition of FSI GPIO master. - Describe in more detail what each GPIO FSI master pin is for. - Re-order compatible strings in example binding so that most specific device comes first. - Indicate proper activation order of all FSI GPIO master pins. - Fix an unmatched '>' bracket in the example for binding. - Bracket each element of the example bindings individually. - Add new patch documenting sysfs-bus-fsi attributes. - Merge FSI GPIO master init into probe function. - Set pin initial values at time of pin request. - Assign value of master->master.dev at probe time. - Use get_optional interfac for all optional GPIO pins. Documentation/ABI/testing/sysfs-bus-fsi| 6 + .../devicetree/bindings/fsi/fsi-master-gpio.txt| 71 +++ Documentation/devicetree/bindings/fsi/fsi.txt | 54 +++ drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig| 23 + drivers/fsi/Makefile | 3 + drivers/fsi/fsi-core.c
[PATCH 00/16] FSI device driver introduction
From: Chris BosticIntroduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (5): drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Add master unscan drivers/fsi: Add documentation for GPIO bindings drivers/fsi: Add GPIO based FSI master Jeremy Kerr (11): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add fake master driver drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add crc4 helpers drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions .../devicetree/bindings/fsi/fsi-master-gpio.txt| 21 + drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig| 29 ++ drivers/fsi/Makefile | 4 + drivers/fsi/fsi-core.c | 514 +++ drivers/fsi/fsi-master-fake.c | 95 drivers/fsi/fsi-master-gpio.c | 552 + drivers/fsi/fsi-master.h | 62 +++ include/linux/fsi.h| 60 +++ 10 files changed, 1340 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt create mode 100644 drivers/fsi/Kconfig create mode 100644 drivers/fsi/Makefile create mode 100644 drivers/fsi/fsi-core.c create mode 100644 drivers/fsi/fsi-master-fake.c create mode 100644 drivers/fsi/fsi-master-gpio.c create mode 100644 drivers/fsi/fsi-master.h create mode 100644 include/linux/fsi.h -- 1.8.2.2
[PATCH 00/16] FSI device driver introduction
From: Chris Bostic Introduction of the IBM 'Flexible Support Interface' (FSI) bus device driver. FSI is a high fan out serial bus consisting of a clock and a serial data line capable of running at speeds up to 166 MHz. This set provides the basic framework to add FSI extensions to the Linux bus and device models. Master specific implementations are defined to utilize the core FSI function. In Linux, we have a core FSI "bus type", along with drivers for FSI masters and engines. The FSI master drivers expose a read/write interface to the bus address space. The master drivers are under drivers/fsi/fsi-master-*.c. The core handles probing and discovery of slaves and slave engines, using those read/write interfaces. It is responsible for creating the endpoint Linux devices corresponding to the discovered engines on each slave. Slave engines are identified by an 'engine' type, and an optional version. Engine, a.k.a. client, drivers are matched and bound to these engines during discovery. This patch set does not include extended FSI function such as: * Hub master support * Cascaded master support * Application layer hot plug notification * Application layer FSI bus status interface Common FSI terminology: * Master Controller of the FSI bus. Only the master is allowed to control the clock line and is the initiator of all transactions on a bus. * Slave The receiver or target of a master initiated transaction. The slave cannot initiate communications on a bus and must respond to any master requests for data. * CFAM Stands for Common Field replaceable unit Access Macro. A CFAM is an ASIC residing in any device requiring FSI communications. CFAMs consist of an array of hardware 'engines' used for various purposes. I2C masters, UARTs, General Purpose IO hardware are common types of these engines. * Configuration Space / Table A table contained at the beginning of each CFAM address space. This table lists information such as the CFAM's ID, which engine types and versions it has available, as well as its addressing range. * FSI Engine driver A device driver that registers with the FSI core so that it can access devices it owns on an FSI bus. Chris Bostic (5): drivers/fsi: Set up links for slave communication drivers/fsi: Set slave SMODE to init communication drivers/fsi: Add master unscan drivers/fsi: Add documentation for GPIO bindings drivers/fsi: Add GPIO based FSI master Jeremy Kerr (11): drivers/fsi: Add empty fsi bus definitions drivers/fsi: Add device & driver definitions drivers/fsi: add driver to device matches drivers/fsi: Add fsi master definition drivers/fsi: Add fake master driver drivers/fsi: Add slave definition drivers/fsi: Add empty master scan drivers/fsi: Add crc4 helpers drivers/fsi: Implement slave initialisation drivers/fsi: scan slaves & register devices drivers/fsi: Add device read/write/peek functions .../devicetree/bindings/fsi/fsi-master-gpio.txt| 21 + drivers/Kconfig| 2 + drivers/Makefile | 1 + drivers/fsi/Kconfig| 29 ++ drivers/fsi/Makefile | 4 + drivers/fsi/fsi-core.c | 514 +++ drivers/fsi/fsi-master-fake.c | 95 drivers/fsi/fsi-master-gpio.c | 552 + drivers/fsi/fsi-master.h | 62 +++ include/linux/fsi.h| 60 +++ 10 files changed, 1340 insertions(+) create mode 100644 Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt create mode 100644 drivers/fsi/Kconfig create mode 100644 drivers/fsi/Makefile create mode 100644 drivers/fsi/fsi-core.c create mode 100644 drivers/fsi/fsi-master-fake.c create mode 100644 drivers/fsi/fsi-master-gpio.c create mode 100644 drivers/fsi/fsi-master.h create mode 100644 include/linux/fsi.h -- 1.8.2.2