All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 00/13] Introduce framework for SLIMbus device driver
@ 2017-11-15 14:10 ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, arnd-r2nGTMty4D4,
	Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Thanks for everyone who reviewed v6 patchset, here is v7 with
review comments addressed.

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.
SLIMbus uses Time-Division-Multiplexing to accommodate multiple data
channels, and control channel. Control channel has messages to do
device-enumeration, messages to send/receive control-data to/from
slimbus devices, messages for port/channel management, and messages to
do bandwidth allocation.
Framework is introduced to support  multiple instances of the bus
(1 controller per bus), and multiple slave devices per controller.
SPI and I2C frameworks, and comments from last time when I submitted
the patches were referred-to while working on this framework.

These patchsets introduce device-management, OF helpers, and messaging
APIs, controller driver for Qualcomm's slimbus controller, and
clock-pause feature for entering/exiting low-power mode for SLIMbus.
Framework patches to do channel, port and bandwidth
management are work-in-progress and will be sent out once these
initial patches are accepted.

These patchsets were tested on Qualcomm Snapdragon processor board
using the controller driver, and a test slave device.

v6: https://lwn.net/Articles/735693/

Changes from v6 to v7:
* Various improvements in commenting style and kerneldoc
 suggested by various reviewers.
* Removed usage of semaphores.
* Split patches into more reviewable sizes.
* Move buffer management into the controller driver.
* use IDR for TID transactions.
* use IDA for controller ids.
* Remove lot of redundant code.
* remove framer booted call for now, which can be added in future.
* Added slim_readb/writeb and slim_read/write apis for 
simplified value element interface. Inspired by Soundwire patches.
* Added slim device state so the the drivers which are 
probed after the device is announced, can get device state.
* Lots of code cleanup.
* move summary to .rst format.
* move from callbacks to completions for async reads.
* split slimbus.h into device and controller specific parts.

Sagar Dharia (9):
  Documentation: Add SLIMbus summary
  dt-bindings: Add SLIMbus bindings
  slimbus: Add SLIMbus bus type
  slimbus: core: Add slim controllers support
  slimbus: Add messaging APIs to slimbus framework
  slimbus: Add support for 'clock-pause' feature
  dt-bindings: Add qcom slimbus controller bindings
  slimbus: qcom: Add Qualcomm Slimbus controller driver
  slimbus: qcom: Add runtime-pm support using clock-pause

Srinivas Kandagatla (4):
  slimbus: core: add support to device tree helper
  regmap: add SLIMbus support
  slimbus: core: add common defines required for controllers
  MAINTAINERS: Add SLIMbus maintainer

 Documentation/devicetree/bindings/slimbus/bus.txt  |  50 ++
 .../devicetree/bindings/slimbus/slim-qcom-ctrl.txt |  43 ++
 Documentation/driver-api/slimbus/index.rst         |  15 +
 Documentation/driver-api/slimbus/summary.rst       | 108 +++
 MAINTAINERS                                        |   8 +
 drivers/Kconfig                                    |   2 +
 drivers/Makefile                                   |   1 +
 drivers/base/regmap/Kconfig                        |   4 +
 drivers/base/regmap/Makefile                       |   1 +
 drivers/base/regmap/regmap-slimbus.c               |  95 +++
 drivers/slimbus/Kconfig                            |  22 +
 drivers/slimbus/Makefile                           |   9 +
 drivers/slimbus/core.c                             | 500 +++++++++++++
 drivers/slimbus/messaging.c                        | 448 ++++++++++++
 drivers/slimbus/qcom-ctrl.c                        | 791 +++++++++++++++++++++
 drivers/slimbus/sched.c                            | 128 ++++
 drivers/slimbus/slimbus.h                          | 276 +++++++
 include/linux/mod_devicetable.h                    |  13 +
 include/linux/regmap.h                             |  18 +
 include/linux/slimbus.h                            | 167 +++++
 20 files changed, 2699 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt
 create mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
 create mode 100644 Documentation/driver-api/slimbus/index.rst
 create mode 100644 Documentation/driver-api/slimbus/summary.rst
 create mode 100644 drivers/base/regmap/regmap-slimbus.c
 create mode 100644 drivers/slimbus/Kconfig
 create mode 100644 drivers/slimbus/Makefile
 create mode 100644 drivers/slimbus/core.c
 create mode 100644 drivers/slimbus/messaging.c
 create mode 100644 drivers/slimbus/qcom-ctrl.c
 create mode 100644 drivers/slimbus/sched.c
 create mode 100644 drivers/slimbus/slimbus.h
 create mode 100644 include/linux/slimbus.h

-- 
2.15.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* [PATCH v7 00/13] Introduce framework for SLIMbus device driver
@ 2017-11-15 14:10 ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

Thanks for everyone who reviewed v6 patchset, here is v7 with
review comments addressed.

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.
SLIMbus uses Time-Division-Multiplexing to accommodate multiple data
channels, and control channel. Control channel has messages to do
device-enumeration, messages to send/receive control-data to/from
slimbus devices, messages for port/channel management, and messages to
do bandwidth allocation.
Framework is introduced to support  multiple instances of the bus
(1 controller per bus), and multiple slave devices per controller.
SPI and I2C frameworks, and comments from last time when I submitted
the patches were referred-to while working on this framework.

These patchsets introduce device-management, OF helpers, and messaging
APIs, controller driver for Qualcomm's slimbus controller, and
clock-pause feature for entering/exiting low-power mode for SLIMbus.
Framework patches to do channel, port and bandwidth
management are work-in-progress and will be sent out once these
initial patches are accepted.

These patchsets were tested on Qualcomm Snapdragon processor board
using the controller driver, and a test slave device.

v6: https://lwn.net/Articles/735693/

Changes from v6 to v7:
* Various improvements in commenting style and kerneldoc
 suggested by various reviewers.
* Removed usage of semaphores.
* Split patches into more reviewable sizes.
* Move buffer management into the controller driver.
* use IDR for TID transactions.
* use IDA for controller ids.
* Remove lot of redundant code.
* remove framer booted call for now, which can be added in future.
* Added slim_readb/writeb and slim_read/write apis for 
simplified value element interface. Inspired by Soundwire patches.
* Added slim device state so the the drivers which are 
probed after the device is announced, can get device state.
* Lots of code cleanup.
* move summary to .rst format.
* move from callbacks to completions for async reads.
* split slimbus.h into device and controller specific parts.

Sagar Dharia (9):
  Documentation: Add SLIMbus summary
  dt-bindings: Add SLIMbus bindings
  slimbus: Add SLIMbus bus type
  slimbus: core: Add slim controllers support
  slimbus: Add messaging APIs to slimbus framework
  slimbus: Add support for 'clock-pause' feature
  dt-bindings: Add qcom slimbus controller bindings
  slimbus: qcom: Add Qualcomm Slimbus controller driver
  slimbus: qcom: Add runtime-pm support using clock-pause

Srinivas Kandagatla (4):
  slimbus: core: add support to device tree helper
  regmap: add SLIMbus support
  slimbus: core: add common defines required for controllers
  MAINTAINERS: Add SLIMbus maintainer

 Documentation/devicetree/bindings/slimbus/bus.txt  |  50 ++
 .../devicetree/bindings/slimbus/slim-qcom-ctrl.txt |  43 ++
 Documentation/driver-api/slimbus/index.rst         |  15 +
 Documentation/driver-api/slimbus/summary.rst       | 108 +++
 MAINTAINERS                                        |   8 +
 drivers/Kconfig                                    |   2 +
 drivers/Makefile                                   |   1 +
 drivers/base/regmap/Kconfig                        |   4 +
 drivers/base/regmap/Makefile                       |   1 +
 drivers/base/regmap/regmap-slimbus.c               |  95 +++
 drivers/slimbus/Kconfig                            |  22 +
 drivers/slimbus/Makefile                           |   9 +
 drivers/slimbus/core.c                             | 500 +++++++++++++
 drivers/slimbus/messaging.c                        | 448 ++++++++++++
 drivers/slimbus/qcom-ctrl.c                        | 791 +++++++++++++++++++++
 drivers/slimbus/sched.c                            | 128 ++++
 drivers/slimbus/slimbus.h                          | 276 +++++++
 include/linux/mod_devicetable.h                    |  13 +
 include/linux/regmap.h                             |  18 +
 include/linux/slimbus.h                            | 167 +++++
 20 files changed, 2699 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt
 create mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
 create mode 100644 Documentation/driver-api/slimbus/index.rst
 create mode 100644 Documentation/driver-api/slimbus/summary.rst
 create mode 100644 drivers/base/regmap/regmap-slimbus.c
 create mode 100644 drivers/slimbus/Kconfig
 create mode 100644 drivers/slimbus/Makefile
 create mode 100644 drivers/slimbus/core.c
 create mode 100644 drivers/slimbus/messaging.c
 create mode 100644 drivers/slimbus/qcom-ctrl.c
 create mode 100644 drivers/slimbus/sched.c
 create mode 100644 drivers/slimbus/slimbus.h
 create mode 100644 include/linux/slimbus.h

-- 
2.15.0

^ permalink raw reply	[flat|nested] 78+ messages in thread

* [PATCH v7 01/13] Documentation: Add SLIMbus summary
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10   ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: mark.rutland, michael.opdenacker, poeschel, Srinivas Kandagatla,
	andreas.noever, arnd, vinod.koul, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

From: Sagar Dharia <sdharia@codeaurora.org>

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.

The summary of SLIMbus and API is documented in the 'summary' file.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 Documentation/driver-api/slimbus/index.rst   |  15 ++++
 Documentation/driver-api/slimbus/summary.rst | 108 +++++++++++++++++++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 Documentation/driver-api/slimbus/index.rst
 create mode 100644 Documentation/driver-api/slimbus/summary.rst

diff --git a/Documentation/driver-api/slimbus/index.rst b/Documentation/driver-api/slimbus/index.rst
new file mode 100644
index 000000000000..586f979659e6
--- /dev/null
+++ b/Documentation/driver-api/slimbus/index.rst
@@ -0,0 +1,15 @@
+=====================
+SLIMbus Documentation
+=====================
+
+.. toctree::
+   :maxdepth: 1
+
+   summary
+
+.. only::  subproject
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/driver-api/slimbus/summary.rst b/Documentation/driver-api/slimbus/summary.rst
new file mode 100644
index 000000000000..d379d1e6be06
--- /dev/null
+++ b/Documentation/driver-api/slimbus/summary.rst
@@ -0,0 +1,108 @@
+============================
+Linux kernel SLIMbus support
+============================
+
+Overview
+========
+
+What is SLIMbus?
+----------------
+SLIMbus (Serial Low Power Interchip Media Bus) is a specification developed by
+MIPI (Mobile Industry Processor Interface) alliance. The bus uses master/slave
+configuration, and is a 2-wire multi-drop implementation (clock, and data).
+
+Currently, SLIMbus is used to interface between application processors of SoCs
+(System-on-Chip) and peripheral components (typically codec).SLIMbus uses
+Time-Division-Multiplexing to accommodate multiple data channels, and
+a control channel.
+
+The control channel is used for various control functions such as bus
+management, configuration and status updates.These messages can be unicast (e.g.
+reading/writing device specific values), or multicast (e.g. data channel
+reconfiguration sequence is a broadcast message announced to all devices)
+
+A data channel is used for data-transfer between 2 Slimbus devices. Data
+channel uses dedicated ports on the device.
+
+Hardware description:
+---------------------
+Slimbus specification has different types of device classifications based on
+their capabilities.
+A manager device is responsible for enumeration, configuration, and dynamic
+channel allocation. Every bus has 1 active manager.
+
+A generic device is a device providing application functionality (e.g. codec).
+
+Framer device is responsible for clocking the bus, and transmitting frame-sync
+and framing information on the bus.
+
+Each SLIMbus component has an interface device for monitoring physical layer.
+
+Typically each SoC contains SLIMbus component having 1 manager, 1 framer device,
+1 generic device (for data channel support), and 1 interface device.
+External peripheral SLIMbus component usually has 1 generic device (for
+functionality/data channel support), and an associated interface device.
+The generic device's registers are mapped as 'value elements' so that they can
+be written/read using Slimbus control channel exchanging control/status type of
+information.
+In case there are multiple framer devices on the same bus, manager device is
+responsible to select the active-framer for clocking the bus.
+
+Per specification, Slimbus uses "clock gears" to do power management based on
+current frequency and bandwidth requirements. There are 10 clock gears and each
+gear changes the Slimbus frequency to be twice its previous gear.
+
+Each device has a 6-byte enumeration-address and the manager assigns every
+device with a 1-byte logical address after the devices report presence on the
+bus.
+
+Software description:
+---------------------
+There are 2 types of SLIMbus drivers:
+
+slim_controller represents a 'controller' for SLIMbus. This driver should
+implement duties needed by the SoC (manager device, associated
+interface device for monitoring the layers and reporting errors, default
+framer device).
+
+slim_device represents the 'generic device/component' for SLIMbus, and a
+slim_driver should implement driver for that slim_device.
+
+Device notifications to the driver:
+-----------------------------------
+Since SLIMbus devices have mechanisms for reporting their presence, the
+framework allows drivers to bind when corresponding devices report their
+presence on the bus.
+However, it is possible that the driver needs to be probed
+first so that it can enable corresponding SLIMbus device (e.g. power it up and/or
+take it out of reset). To support that behavior, the framework allows drivers
+to probe first as well  (e.g. using standard DeviceTree compatbility field).
+This creates the necessity for the driver to know when the device is functional
+(i.e. reported present). device_up callback is used for that reason when the
+device reports present and is assigned a logical address by the controller.
+
+Similarly, SLIMbus devices 'report absent' when they go down. A 'device_down'
+callback notifies the driver when the device reports absent and its logical
+address assignment is invalidated by the controller.
+
+Another notification "boot_device" is used to notify the slim_driver when
+controller resets the bus. This notification allows the driver to take necessary
+steps to boot the device so that it's functional after the bus has been reset.
+
+Clock-pause:
+------------
+SLIMbus mandates that a reconfiguration sequence (known as clock-pause) be
+broadcast to all active devices on the bus before the bus can enter low-power
+mode. Controller uses this sequence when it decides to enter low-power mode so
+that corresponding clocks and/or power-rails can be turned off to save power.
+Clock-pause is exited by waking up framer device (if controller driver initiates
+exiting low power mode), or by toggling the data line (if a slave device wants
+to initiate it).
+
+Messaging APIs:
+---------------
+The framework supports APIs to exchange control-information with a SLIMbus
+device. APIs can be synchronous or asynchronous.
+From controller's perspective, multiple buffers can be queued to/from
+hardware for sending/receiving data using slim_ctrl_buf circular buffer.
+The header file <linux/slimbus.h> has more documentation about messaging APIs.
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 01/13] Documentation: Add SLIMbus summary
@ 2017-11-15 14:10   ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.

The summary of SLIMbus and API is documented in the 'summary' file.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 Documentation/driver-api/slimbus/index.rst   |  15 ++++
 Documentation/driver-api/slimbus/summary.rst | 108 +++++++++++++++++++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 Documentation/driver-api/slimbus/index.rst
 create mode 100644 Documentation/driver-api/slimbus/summary.rst

diff --git a/Documentation/driver-api/slimbus/index.rst b/Documentation/driver-api/slimbus/index.rst
new file mode 100644
index 000000000000..586f979659e6
--- /dev/null
+++ b/Documentation/driver-api/slimbus/index.rst
@@ -0,0 +1,15 @@
+=====================
+SLIMbus Documentation
+=====================
+
+.. toctree::
+   :maxdepth: 1
+
+   summary
+
+.. only::  subproject
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/driver-api/slimbus/summary.rst b/Documentation/driver-api/slimbus/summary.rst
new file mode 100644
index 000000000000..d379d1e6be06
--- /dev/null
+++ b/Documentation/driver-api/slimbus/summary.rst
@@ -0,0 +1,108 @@
+============================
+Linux kernel SLIMbus support
+============================
+
+Overview
+========
+
+What is SLIMbus?
+----------------
+SLIMbus (Serial Low Power Interchip Media Bus) is a specification developed by
+MIPI (Mobile Industry Processor Interface) alliance. The bus uses master/slave
+configuration, and is a 2-wire multi-drop implementation (clock, and data).
+
+Currently, SLIMbus is used to interface between application processors of SoCs
+(System-on-Chip) and peripheral components (typically codec).SLIMbus uses
+Time-Division-Multiplexing to accommodate multiple data channels, and
+a control channel.
+
+The control channel is used for various control functions such as bus
+management, configuration and status updates.These messages can be unicast (e.g.
+reading/writing device specific values), or multicast (e.g. data channel
+reconfiguration sequence is a broadcast message announced to all devices)
+
+A data channel is used for data-transfer between 2 Slimbus devices. Data
+channel uses dedicated ports on the device.
+
+Hardware description:
+---------------------
+Slimbus specification has different types of device classifications based on
+their capabilities.
+A manager device is responsible for enumeration, configuration, and dynamic
+channel allocation. Every bus has 1 active manager.
+
+A generic device is a device providing application functionality (e.g. codec).
+
+Framer device is responsible for clocking the bus, and transmitting frame-sync
+and framing information on the bus.
+
+Each SLIMbus component has an interface device for monitoring physical layer.
+
+Typically each SoC contains SLIMbus component having 1 manager, 1 framer device,
+1 generic device (for data channel support), and 1 interface device.
+External peripheral SLIMbus component usually has 1 generic device (for
+functionality/data channel support), and an associated interface device.
+The generic device's registers are mapped as 'value elements' so that they can
+be written/read using Slimbus control channel exchanging control/status type of
+information.
+In case there are multiple framer devices on the same bus, manager device is
+responsible to select the active-framer for clocking the bus.
+
+Per specification, Slimbus uses "clock gears" to do power management based on
+current frequency and bandwidth requirements. There are 10 clock gears and each
+gear changes the Slimbus frequency to be twice its previous gear.
+
+Each device has a 6-byte enumeration-address and the manager assigns every
+device with a 1-byte logical address after the devices report presence on the
+bus.
+
+Software description:
+---------------------
+There are 2 types of SLIMbus drivers:
+
+slim_controller represents a 'controller' for SLIMbus. This driver should
+implement duties needed by the SoC (manager device, associated
+interface device for monitoring the layers and reporting errors, default
+framer device).
+
+slim_device represents the 'generic device/component' for SLIMbus, and a
+slim_driver should implement driver for that slim_device.
+
+Device notifications to the driver:
+-----------------------------------
+Since SLIMbus devices have mechanisms for reporting their presence, the
+framework allows drivers to bind when corresponding devices report their
+presence on the bus.
+However, it is possible that the driver needs to be probed
+first so that it can enable corresponding SLIMbus device (e.g. power it up and/or
+take it out of reset). To support that behavior, the framework allows drivers
+to probe first as well  (e.g. using standard DeviceTree compatbility field).
+This creates the necessity for the driver to know when the device is functional
+(i.e. reported present). device_up callback is used for that reason when the
+device reports present and is assigned a logical address by the controller.
+
+Similarly, SLIMbus devices 'report absent' when they go down. A 'device_down'
+callback notifies the driver when the device reports absent and its logical
+address assignment is invalidated by the controller.
+
+Another notification "boot_device" is used to notify the slim_driver when
+controller resets the bus. This notification allows the driver to take necessary
+steps to boot the device so that it's functional after the bus has been reset.
+
+Clock-pause:
+------------
+SLIMbus mandates that a reconfiguration sequence (known as clock-pause) be
+broadcast to all active devices on the bus before the bus can enter low-power
+mode. Controller uses this sequence when it decides to enter low-power mode so
+that corresponding clocks and/or power-rails can be turned off to save power.
+Clock-pause is exited by waking up framer device (if controller driver initiates
+exiting low power mode), or by toggling the data line (if a slave device wants
+to initiate it).
+
+Messaging APIs:
+---------------
+The framework supports APIs to exchange control-information with a SLIMbus
+device. APIs can be synchronous or asynchronous.
+From controller's perspective, multiple buffers can be queued to/from
+hardware for sending/receiving data using slim_ctrl_buf circular buffer.
+The header file <linux/slimbus.h> has more documentation about messaging APIs.
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10   ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: mark.rutland, michael.opdenacker, poeschel, Srinivas Kandagatla,
	andreas.noever, arnd, vinod.koul, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

From: Sagar Dharia <sdharia@codeaurora.org>

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.

This patch adds device tree bindings for the slimbus.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt

diff --git a/Documentation/devicetree/bindings/slimbus/bus.txt b/Documentation/devicetree/bindings/slimbus/bus.txt
new file mode 100644
index 000000000000..413b5076858e
--- /dev/null
+++ b/Documentation/devicetree/bindings/slimbus/bus.txt
@@ -0,0 +1,50 @@
+SLIM(Serial Low Power Interchip Media Bus) bus
+
+SLIMbus is a 2-wire bus, and is used to communicate with peripheral
+components like audio-codec.
+
+Required property for SLIMbus controller node:
+- compatible	- name of SLIMbus controller
+
+Child nodes:
+Every SLIMbus controller node can contain zero or more child nodes
+representing slave devices on the bus. Every SLIMbus slave device is
+uniquely determined by the enumeration address containing 4 fields:
+Manufacturer ID, Product code, Device index, and Instance value for
+the device.
+If child node is not present and it is instantiated after device
+discovery (slave device reporting itself present).
+
+In some cases it may be necessary to describe non-probeable device
+details such as non-standard ways of powering up a device. In
+such cases, child nodes for those devices will be present as
+slaves of the slimbus-controller, as detailed below.
+
+Required property for SLIMbus child node if it is present:
+- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
+		  Enumeration  Address.
+		  Device Index Uniquely identifies multiple Devices within
+		  a single Component.
+		  Instance ID Is for the cases where multiple Devices of the
+		  same type or Class are attached to the bus.
+
+- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
+	 	  Product Code, shall be in lower case hexadecimal with leading
+		  zeroes suppressed
+
+SLIMbus example for Qualcomm's slimbus manager component:
+
+	slim@28080000 {
+		compatible = "qcom,apq8064-slim", "qcom,slim";
+		reg = <0x28080000 0x2000>,
+		interrupts = <0 33 0>;
+		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
+		clock-names = "iface", "core";
+		#address-cells = <2>;
+		#size-cell = <0>;
+
+		codec: wcd9310@1,0{
+			compatible = "slim217,60";
+			reg = <1 0>;
+		};
+	};
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
@ 2017-11-15 14:10   ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.

This patch adds device tree bindings for the slimbus.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt

diff --git a/Documentation/devicetree/bindings/slimbus/bus.txt b/Documentation/devicetree/bindings/slimbus/bus.txt
new file mode 100644
index 000000000000..413b5076858e
--- /dev/null
+++ b/Documentation/devicetree/bindings/slimbus/bus.txt
@@ -0,0 +1,50 @@
+SLIM(Serial Low Power Interchip Media Bus) bus
+
+SLIMbus is a 2-wire bus, and is used to communicate with peripheral
+components like audio-codec.
+
+Required property for SLIMbus controller node:
+- compatible	- name of SLIMbus controller
+
+Child nodes:
+Every SLIMbus controller node can contain zero or more child nodes
+representing slave devices on the bus. Every SLIMbus slave device is
+uniquely determined by the enumeration address containing 4 fields:
+Manufacturer ID, Product code, Device index, and Instance value for
+the device.
+If child node is not present and it is instantiated after device
+discovery (slave device reporting itself present).
+
+In some cases it may be necessary to describe non-probeable device
+details such as non-standard ways of powering up a device. In
+such cases, child nodes for those devices will be present as
+slaves of the slimbus-controller, as detailed below.
+
+Required property for SLIMbus child node if it is present:
+- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
+		  Enumeration  Address.
+		  Device Index Uniquely identifies multiple Devices within
+		  a single Component.
+		  Instance ID Is for the cases where multiple Devices of the
+		  same type or Class are attached to the bus.
+
+- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
+	 	  Product Code, shall be in lower case hexadecimal with leading
+		  zeroes suppressed
+
+SLIMbus example for Qualcomm's slimbus manager component:
+
+	slim@28080000 {
+		compatible = "qcom,apq8064-slim", "qcom,slim";
+		reg = <0x28080000 0x2000>,
+		interrupts = <0 33 0>;
+		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
+		clock-names = "iface", "core";
+		#address-cells = <2>;
+		#size-cell = <0>;
+
+		codec: wcd9310@1,0{
+			compatible = "slim217,60";
+			reg = <1 0>;
+		};
+	};
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 03/13] slimbus: Add SLIMbus bus type
  2017-11-15 14:10 ` srinivas.kandagatla
                   ` (2 preceding siblings ...)
  (?)
@ 2017-11-15 14:10 ` srinivas.kandagatla
  2017-11-16 12:25     ` Mark Brown
  2017-11-16 13:18     ` [alsa-devel] " Vinod Koul
  -1 siblings, 2 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

SLIMbus (Serial Low Power Interchip Media Bus) is a specification
developed by MIPI (Mobile Industry Processor Interface) alliance.
SLIMbus is a 2-wire implementation, which is used to communicate with
peripheral components like audio-codec.
SLIMbus uses Time-Division-Multiplexing to accommodate multiple data
channels, and control channel. Control channel has messages to do
device-enumeration, messages to send/receive control-data to/from
slimbus devices, messages for port/channel management, and messages to
do bandwidth allocation.
The framework supports multiple instances of the bus (1 controller per
bus), and multiple slave devices per controller.

This patch adds support to basic silmbus core which includes support to
slimbus type, slimbus device registeration and some basic data structures.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/Kconfig                 |   2 +
 drivers/Makefile                |   1 +
 drivers/slimbus/Kconfig         |  16 +++++
 drivers/slimbus/Makefile        |   5 ++
 drivers/slimbus/core.c          | 122 +++++++++++++++++++++++++++++++++++++
 include/linux/mod_devicetable.h |  13 ++++
 include/linux/slimbus.h         | 129 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 288 insertions(+)
 create mode 100644 drivers/slimbus/Kconfig
 create mode 100644 drivers/slimbus/Makefile
 create mode 100644 drivers/slimbus/core.c
 create mode 100644 include/linux/slimbus.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 1d7af3c2ff27..dd921785e65c 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -209,4 +209,6 @@ source "drivers/tee/Kconfig"
 
 source "drivers/mux/Kconfig"
 
+source "drivers/slimbus/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index d242d3514d30..876c6624103c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_MTD)		+= mtd/
 obj-$(CONFIG_SPI)		+= spi/
 obj-$(CONFIG_SPMI)		+= spmi/
 obj-$(CONFIG_HSI)		+= hsi/
+obj-$(CONFIG_SLIMBUS)		+= slimbus/
 obj-y				+= net/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_FUSION)		+= message/
diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig
new file mode 100644
index 000000000000..9c7d3c61656a
--- /dev/null
+++ b/drivers/slimbus/Kconfig
@@ -0,0 +1,16 @@
+#
+# SLIMBUS driver configuration
+#
+menuconfig SLIMBUS
+	tristate "Slimbus support"
+	help
+	  Slimbus is standard interface between System-on-Chip and audio codec,
+	  and other peripheral components in typical embedded systems.
+
+	  If unsure, choose N.
+
+if SLIMBUS
+
+# SlIMbus controllers
+
+endif
diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
new file mode 100644
index 000000000000..50deace4e76d
--- /dev/null
+++ b/drivers/slimbus/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for kernel slimbus framework.
+#
+obj-$(CONFIG_SLIMBUS)			+= slimbus.o
+slimbus-y				:= core.o
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
new file mode 100644
index 000000000000..22edebf1a233
--- /dev/null
+++ b/drivers/slimbus/core.c
@@ -0,0 +1,122 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/slimbus.h>
+
+static const struct slim_device_id *slim_match(const struct slim_device_id *id,
+					       const struct slim_device *sbdev)
+{
+	while (id->manf_id != 0 || id->prod_code != 0) {
+		if (id->manf_id == sbdev->e_addr.manf_id &&
+		    id->prod_code == sbdev->e_addr.prod_code)
+			return id;
+		id++;
+	}
+	return NULL;
+}
+
+static int slim_device_match(struct device *dev, struct device_driver *drv)
+{
+	struct slim_device *sbdev = to_slim_device(dev);
+	struct slim_driver *sbdrv = to_slim_driver(drv);
+
+	return slim_match(sbdrv->id_table, sbdev) != NULL;
+}
+
+static int slim_device_probe(struct device *dev)
+{
+	struct slim_device	*sbdev;
+	struct slim_driver	*sbdrv;
+	int ret = 0;
+
+	sbdev = to_slim_device(dev);
+	sbdrv = to_slim_driver(dev->driver);
+
+	if (sbdrv->probe)
+		ret = sbdrv->probe(sbdev);
+
+	return ret;
+}
+
+static int slim_device_remove(struct device *dev)
+{
+	struct slim_device *sbdev = to_slim_device(dev);
+	struct slim_driver *sbdrv;
+
+	if (dev->driver) {
+		sbdrv = to_slim_driver(dev->driver);
+		if (sbdrv->remove)
+			sbdrv->remove(sbdev);
+	}
+
+	return 0;
+}
+
+struct bus_type slimbus_bus = {
+	.name		= "slimbus",
+	.match		= slim_device_match,
+	.probe		= slim_device_probe,
+	.remove		= slim_device_remove,
+};
+EXPORT_SYMBOL_GPL(slimbus_bus);
+
+/*
+ * __slim_driver_register() - Client driver registration with slimbus
+ *
+ * @drv:Client driver to be associated with client-device.
+ * @owner: owning module/driver
+ *
+ * This API will register the client driver with the slimbus
+ * It is called from the driver's module-init function.
+ */
+int __slim_driver_register(struct slim_driver *drv, struct module *owner)
+{
+	/* ID table is mandatory to match the devices to probe */
+	if (!drv->id_table)
+		return -EINVAL;
+
+	drv->driver.bus = &slimbus_bus;
+	drv->driver.owner = owner;
+
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(__slim_driver_register);
+
+/*
+ * slim_driver_unregister() - Undo effect of slim_driver_register
+ *
+ * @drv: Client driver to be unregistered
+ */
+void slim_driver_unregister(struct slim_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(slim_driver_unregister);
+
+static void __exit slimbus_exit(void)
+{
+	bus_unregister(&slimbus_bus);
+}
+module_exit(slimbus_exit);
+
+static int __init slimbus_init(void)
+{
+	return bus_register(&slimbus_bus);
+}
+postcore_initcall(slimbus_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SLIMbus core");
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 1c2e8d6b7274..7d6238863fc1 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -452,6 +452,19 @@ struct spi_device_id {
 	kernel_ulong_t driver_data;	/* Data private to the driver */
 };
 
+/* SLIMbus */
+
+#define SLIMBUS_NAME_SIZE	32
+#define SLIMBUS_MODULE_PREFIX	"slim:"
+
+struct slim_device_id {
+	__u16 manf_id, prod_code;
+	__u8 dev_index, instance;
+
+	/* Data private to the driver */
+	kernel_ulong_t driver_data;
+};
+
 #define SPMI_NAME_SIZE	32
 #define SPMI_MODULE_PREFIX "spmi:"
 
diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h
new file mode 100644
index 000000000000..057198216a65
--- /dev/null
+++ b/include/linux/slimbus.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 _LINUX_SLIMBUS_H
+#define _LINUX_SLIMBUS_H
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+
+/**
+ * Interfaces between SLIMbus manager drivers, SLIMbus client drivers, and
+ * SLIMbus infrastructure.
+ */
+
+extern struct bus_type slimbus_bus;
+
+/**
+ * struct slim_eaddr - Enumeration address for a slimbus device
+ * @manf_id: Manufacturer Id for the device
+ * @prod_code: Product code
+ * @dev_index: Device index
+ * @instance: Instance value
+ */
+struct slim_eaddr {
+	u16 manf_id;
+	u16 prod_code;
+	u8 dev_index;
+	u8 instance;
+};
+
+/**
+ * enum slim_device_status - slim device status
+ * @SLIM_DEVICE_STATUS_DOWN: Slim device is absent or not reported yet.
+ * @SLIM_DEVICE_STATUS_UP: Slim device is announced on the bus.
+ * @SLIM_DEVICE_STATUS_RESERVED: Reserved for future use.
+ */
+enum slim_device_status {
+	SLIM_DEVICE_STATUS_DOWN = 0,
+	SLIM_DEVICE_STATUS_UP,
+	SLIM_DEVICE_STATUS_RESERVED,
+};
+
+/**
+ * struct slim_device - Slim device handle.
+ * @dev: Driver model representation of the device.
+ * @name: Name of driver to use with this device.
+ * @e_addr: Enumeration address of this device.
+ * @driver: Device's driver. Pointer to access routines.
+ * @laddr: 1-byte Logical address of this device.
+ *
+ * This is the client/device handle returned when a slimbus
+ * device is registered with a controller.
+ * Pointer to this structure is used by client-driver as a handle.
+ */
+struct slim_device {
+	struct device		dev;
+	struct slim_eaddr	e_addr;
+	struct list_head node;
+	enum slim_device_status	status;
+	u8			laddr;
+	bool			is_laddr_valid;
+};
+
+#define to_slim_device(d) container_of(d, struct slim_device, dev)
+
+/**
+ * struct slim_driver - Slimbus 'generic device' (slave) device driver
+ *				(similar to 'spi_device' on SPI)
+ * @probe: Binds this driver to a slimbus device.
+ * @remove: Unbinds this driver from the slimbus device.
+ * @shutdown: Standard shutdown callback used during powerdown/halt.
+ * @device_status: This callback is called when
+ *	-The device reports present and gets a laddr assigned
+ *	-The device reports absent, or the bus goes down.
+ * @driver: Slimbus device drivers should initialize name and owner field of
+ *	    this structure
+ * @id_table: List of slimbus devices supported by this driver
+ */
+
+struct slim_driver {
+	int	(*probe)(struct slim_device *sl);
+	void	(*remove)(struct slim_device *sl);
+	void	(*shutdown)(struct slim_device *sl);
+	int	(*device_status)(struct slim_device *sl,
+				 enum slim_device_status s);
+	struct device_driver		driver;
+	const struct slim_device_id	*id_table;
+};
+#define to_slim_driver(d) container_of(d, struct slim_driver, driver)
+
+/*
+ * use a macro to avoid include chaining to get THIS_MODULE
+ */
+#define slim_driver_register(drv) \
+	__slim_driver_register(drv, THIS_MODULE)
+int __slim_driver_register(struct slim_driver *drv, struct module *owner);
+void slim_driver_unregister(struct slim_driver *drv);
+
+/**
+ * module_slim_driver() - Helper macro for registering a slimbus driver
+ * @__slimbus_driver: slimbus_driver struct
+ *
+ * Helper macro for slimbus drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_slim_driver(__slim_driver) \
+	module_driver(__slim_driver, slim_driver_register, \
+			slim_driver_unregister)
+
+static inline void *slim_get_devicedata(const struct slim_device *dev)
+{
+	return dev_get_drvdata(&dev->dev);
+}
+
+static inline void slim_set_devicedata(struct slim_device *dev, void *data)
+{
+	dev_set_drvdata(&dev->dev, data);
+}
+#endif /* _LINUX_SLIMBUS_H */
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-15 14:10 ` srinivas.kandagatla
                   ` (3 preceding siblings ...)
  (?)
@ 2017-11-15 14:10 ` srinivas.kandagatla
  2017-11-16 16:42     ` Vinod Koul
  -1 siblings, 1 reply; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

This patch adds support to slim controllers in the slim core,
including some utility functions invoked by the controller and
slim device drivers.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/core.c    | 312 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/slimbus/slimbus.h | 116 +++++++++++++++++
 include/linux/slimbus.h   |   7 ++
 3 files changed, 435 insertions(+)
 create mode 100644 drivers/slimbus/slimbus.h

diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index 22edebf1a233..d31a9c4fe7e9 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -14,7 +14,11 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/idr.h>
 #include <linux/slimbus.h>
+#include "slimbus.h"
+
+static DEFINE_IDA(ctrl_ida);
 
 static const struct slim_device_id *slim_match(const struct slim_device_id *id,
 					       const struct slim_device *sbdev)
@@ -106,6 +110,314 @@ void slim_driver_unregister(struct slim_driver *drv)
 }
 EXPORT_SYMBOL_GPL(slim_driver_unregister);
 
+static void slim_dev_release(struct device *dev)
+{
+	struct slim_device *sbdev = to_slim_device(dev);
+
+	put_device(sbdev->ctrl->dev);
+	kfree(sbdev);
+}
+
+static int slim_add_device(struct slim_controller *ctrl,
+			   struct slim_device *sbdev,
+			   struct device_node *node)
+{
+	sbdev->dev.bus = &slimbus_bus;
+	sbdev->dev.parent = ctrl->dev;
+	sbdev->dev.release = slim_dev_release;
+	sbdev->dev.driver = NULL;
+	sbdev->ctrl = ctrl;
+
+	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
+				  sbdev->e_addr.manf_id,
+				  sbdev->e_addr.prod_code,
+				  sbdev->e_addr.dev_index,
+				  sbdev->e_addr.instance);
+
+	get_device(ctrl->dev);
+
+	return device_register(&sbdev->dev);
+}
+
+static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
+					     struct slim_eaddr *eaddr,
+					     struct device_node *node)
+{
+	struct slim_device *sbdev;
+	int ret;
+
+	sbdev = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
+	if (!sbdev)
+		return NULL;
+
+	sbdev->e_addr = *eaddr;
+	ret = slim_add_device(ctrl, sbdev, node);
+	if (ret) {
+		kfree(sbdev);
+		return NULL;
+	}
+
+	return sbdev;
+}
+
+/*
+ * slim_register_controller() - Controller bring-up and registration.
+ *
+ * @ctrl: Controller to be registered.
+ *
+ * A controller is registered with the framework using this API.
+ * If devices on a controller were registered before controller,
+ * this will make sure that they get probed when controller is up
+ */
+int slim_register_controller(struct slim_controller *ctrl)
+{
+	int id;
+
+	id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
+	if (id < 0)
+		return id;
+
+	ctrl->id = id;
+
+	if (!ctrl->min_cg)
+		ctrl->min_cg = SLIM_MIN_CLK_GEAR;
+	if (!ctrl->max_cg)
+		ctrl->max_cg = SLIM_MAX_CLK_GEAR;
+
+	ida_init(&ctrl->laddr_ida);
+	idr_init(&ctrl->tid_idr);
+	mutex_init(&ctrl->lock);
+
+	dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n",
+		ctrl->name, ctrl->dev);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(slim_register_controller);
+
+/* slim_remove_device: Remove the effect of slim_add_device() */
+static void slim_remove_device(struct slim_device *sbdev)
+{
+	device_unregister(&sbdev->dev);
+}
+
+static int slim_ctrl_remove_device(struct device *dev, void *null)
+{
+	slim_remove_device(to_slim_device(dev));
+	return 0;
+}
+
+/**
+ * slim_unregister_controller() - Controller tear-down.
+ *
+ * @ctrl: Controller to tear-down.
+ */
+int slim_unregister_controller(struct slim_controller *ctrl)
+{
+	/* Remove all clients */
+	device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device);
+	ida_simple_remove(&ctrl_ida, ctrl->id);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(slim_unregister_controller);
+
+static void slim_device_update_status(struct slim_device *sbdev,
+				      enum slim_device_status status)
+{
+	struct slim_driver *sbdrv;
+
+	if (sbdev->status == status)
+		return;
+
+	sbdev->status = status;
+	if (!sbdev->dev.driver)
+		return;
+
+	sbdrv = to_slim_driver(sbdev->dev.driver);
+	if (sbdrv->device_status)
+		sbdrv->device_status(sbdev, sbdev->status);
+}
+
+/**
+ * slim_report_absent() - Controller calls this function when a device
+ *	reports absent, OR when the device cannot be communicated with
+ *
+ * @sbdev: Device that cannot be reached, or sent report absent
+ */
+void slim_report_absent(struct slim_device *sbdev)
+{
+	struct slim_controller *ctrl = sbdev->ctrl;
+
+	if (!ctrl)
+		return;
+
+	/* invalidate logical addresses */
+	mutex_lock(&ctrl->lock);
+	sbdev->is_laddr_valid = false;
+	mutex_unlock(&ctrl->lock);
+
+	ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr);
+	slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
+}
+EXPORT_SYMBOL_GPL(slim_report_absent);
+
+static bool slim_eaddr_equal(struct slim_eaddr *a, struct slim_eaddr *b)
+{
+	return (a->manf_id == b->manf_id &&
+		a->prod_code == b->prod_code &&
+		a->dev_index == b->dev_index &&
+		a->instance == b->instance);
+}
+
+static int slim_match_dev(struct device *dev, void *data)
+{
+	struct slim_eaddr *e_addr = data;
+	struct slim_device *sbdev = to_slim_device(dev);
+
+	return slim_eaddr_equal(&sbdev->e_addr, e_addr);
+}
+
+static struct slim_device *find_slim_device(struct slim_controller *ctrl,
+					    struct slim_eaddr *eaddr)
+{
+	struct slim_device *sbdev;
+	struct device *dev;
+
+	dev = device_find_child(ctrl->dev, eaddr, slim_match_dev);
+	if (dev) {
+		sbdev = to_slim_device(dev);
+		return sbdev;
+	}
+
+	return NULL;
+}
+
+/**
+ * slim_get_device() - get handle to a device.
+ *
+ * @ctrl: Controller on which this device will be added/queried
+ * @e_addr: Enumeration address of the device to be queried
+ *
+ * Return: pointer to a device if it has already reported. Creates a new
+ * device and returns pointer to it if the device has not yet enumerated.
+ */
+struct slim_device *slim_get_device(struct slim_controller *ctrl,
+				    struct slim_eaddr *e_addr)
+{
+	struct slim_device *sbdev;
+
+	sbdev = find_slim_device(ctrl, e_addr);
+	if (!sbdev) {
+		sbdev = slim_alloc_device(ctrl, e_addr, NULL);
+		if (!sbdev)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	return sbdev;
+}
+EXPORT_SYMBOL_GPL(slim_get_device);
+
+static int slim_device_alloc_laddr(struct slim_device *sbdev,
+				   u8 *laddr, bool report_present)
+{
+	struct slim_controller *ctrl = sbdev->ctrl;
+	int ret;
+
+	mutex_lock(&ctrl->lock);
+	if (ctrl->get_laddr) {
+		ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, laddr);
+		if (ret < 0)
+			goto err;
+	} else if (report_present) {
+		ret = ida_simple_get(&ctrl->laddr_ida,
+				     0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
+		if (ret < 0)
+			goto err;
+
+		*laddr = ret;
+	} else {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (ctrl->set_laddr) {
+		ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, *laddr);
+		if (ret) {
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	sbdev->laddr = *laddr;
+	sbdev->is_laddr_valid = true;
+
+	slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_UP);
+
+	dev_dbg(ctrl->dev, "setting slimbus l-addr:%x, ea:%x,%x,%x,%x\n",
+		*laddr, sbdev->e_addr.manf_id, sbdev->e_addr.prod_code,
+		sbdev->e_addr.dev_index, sbdev->e_addr.instance);
+
+err:
+	mutex_unlock(&ctrl->lock);
+	return ret;
+
+}
+
+/**
+ * slim_device_report_present() - Report enumerated device.
+ *
+ * @ctrl: Controller with which device is enumerated.
+ * @e_addr: Enumeration address of the device.
+ * @laddr: Return logical address (if valid flag is false)
+ *
+ * Called by controller in response to REPORT_PRESENT. Framework will assign
+ * a logical address to this enumeration address.
+ * Function returns -EXFULL to indicate that all logical addresses are already
+ * taken.
+ */
+int slim_device_report_present(struct slim_controller *ctrl,
+			       struct slim_eaddr *e_addr, u8 *laddr)
+{
+	struct slim_device *sbdev;
+	int ret;
+
+	sbdev = slim_get_device(ctrl, e_addr);
+	if (IS_ERR(sbdev))
+		return -ENODEV;
+
+	if (sbdev->is_laddr_valid) {
+		*laddr = sbdev->laddr;
+		return 0;
+	}
+
+	ret = slim_device_alloc_laddr(sbdev, laddr, true);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(slim_device_report_present);
+
+/**
+ * slim_get_logical_addr() - Return the logical address of a slimbus device.
+ *
+ * @sbdev: client handle requesting the address.
+ * @laddr: output buffer to store the address
+ *
+ * Can sleep, -EINVAL is returned in case of invalid parameters,
+ * and -ENXIO is returned if the device with this enumeration address
+ * is not found.
+ */
+int slim_get_logical_addr(struct slim_device *sbdev, u8 *laddr)
+{
+	if (sbdev->is_laddr_valid) {
+		*laddr =  sbdev->laddr;
+		return 0;
+	}
+
+	return slim_device_alloc_laddr(sbdev, laddr, false);
+}
+EXPORT_SYMBOL_GPL(slim_get_logical_addr);
+
 static void __exit slimbus_exit(void)
 {
 	bus_unregister(&slimbus_bus);
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
new file mode 100644
index 000000000000..b53319992ad4
--- /dev/null
+++ b/drivers/slimbus/slimbus.h
@@ -0,0 +1,116 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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_SLIMBUS_H
+#define _DRIVERS_SLIMBUS_H
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/slimbus.h>
+
+/* Standard values per SLIMbus spec needed by controllers and devices */
+#define SLIM_MAX_CLK_GEAR		10
+#define SLIM_MIN_CLK_GEAR		1
+
+/* Manager's logical address is set to 0xFF per spec */
+#define SLIM_LA_MANAGER 0xFF
+
+/**
+ * struct slim_framer - Represents Slimbus framer.
+ * Every controller may have multiple framers. There is 1 active framer device
+ * responsible for clocking the bus.
+ * Manager is responsible for framer hand-over.
+ * @dev: Driver model representation of the device.
+ * @e_addr: Enumeration address of the framer.
+ * @rootfreq: Root Frequency at which the framer can run. This is maximum
+ *	frequency ('clock gear 10') at which the bus can operate.
+ * @superfreq: Superframes per root frequency. Every frame is 6144 bits.
+ */
+struct slim_framer {
+	struct device		dev;
+	struct slim_eaddr	e_addr;
+	int			rootfreq;
+	int			superfreq;
+};
+
+#define to_slim_framer(d) container_of(d, struct slim_framer, dev)
+
+/**
+ * struct slim_controller  - Controls every instance of SLIMbus
+ *				(similar to 'master' on SPI)
+ * @dev: Device interface to this driver
+ * @id: Board-specific number identifier for this controller/bus
+ * @name: Name for this controller
+ * @min_cg: Minimum clock gear supported by this controller (default value: 1)
+ * @max_cg: Maximum clock gear supported by this controller (default value: 10)
+ * @clkgear: Current clock gear in which this bus is running
+ * @laddr_ida: logical address id allocator
+ * @a_framer: Active framer which is clocking the bus managed by this controller
+ * @lock: Mutex protecting controller data structures
+ * @addr: Logical address table
+ * @devices: Slim device list
+ * @tid_idr: tid id allocator
+ * @txn_lock: Lock to protect table of transactions
+ * @set_laddr: Setup logical address at laddr for the slave with elemental
+ *	address e_addr. Drivers implementing controller will be expected to
+ *	send unicast message to this device with its logical address.
+ * @get_laddr: It is possible that controller needs to set fixed logical
+ *	address table and get_laddr can be used in that case so that controller
+ *	can do this assignment. Use case is when the master is on the remote
+ *	processor side, who is resposible for allocating laddr.
+ *
+ *	'Manager device' is responsible for  device management, bandwidth
+ *	allocation, channel setup, and port associations per channel.
+ *	Device management means Logical address assignment/removal based on
+ *	enumeration (report-present, report-absent) of a device.
+ *	Bandwidth allocation is done dynamically by the manager based on active
+ *	channels on the bus, message-bandwidth requests made by slimbus devices.
+ *	Based on current bandwidth usage, manager chooses a frequency to run
+ *	the bus at (in steps of 'clock-gear', 1 through 10, each clock gear
+ *	representing twice the frequency than the previous gear).
+ *	Manager is also responsible for entering (and exiting) low-power-mode
+ *	(known as 'clock pause').
+ *	Manager can do handover of framer if there are multiple framers on the
+ *	bus and a certain usecase warrants using certain framer to avoid keeping
+ *	previous framer being powered-on.
+ *
+ *	Controller here performs duties of the manager device, and 'interface
+ *	device'. Interface device is responsible for monitoring the bus and
+ *	reporting information such as loss-of-synchronization, data
+ *	slot-collision.
+ */
+struct slim_controller {
+	struct device		*dev;
+	unsigned int		id;
+	char			name[SLIMBUS_NAME_SIZE];
+	int			min_cg;
+	int			max_cg;
+	int			clkgear;
+	struct ida		laddr_ida;
+	struct slim_framer	*a_framer;
+	struct mutex		lock;
+	struct list_head	devices;
+	struct idr		tid_idr;
+	spinlock_t		txn_lock;
+	int			(*set_laddr)(struct slim_controller *ctrl,
+					     struct slim_eaddr *ea, u8 laddr);
+	int			(*get_laddr)(struct slim_controller *ctrl,
+					     struct slim_eaddr *ea, u8 *laddr);
+};
+
+int slim_device_report_present(struct slim_controller *ctrl,
+			       struct slim_eaddr *e_addr, u8 *laddr);
+void slim_report_absent(struct slim_device *sbdev);
+int slim_register_controller(struct slim_controller *ctrl);
+int slim_unregister_controller(struct slim_controller *ctrl);
+
+#endif /* _LINUX_SLIMBUS_H */
diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h
index 057198216a65..ba3fdf1f5176 100644
--- a/include/linux/slimbus.h
+++ b/include/linux/slimbus.h
@@ -49,6 +49,8 @@ enum slim_device_status {
 	SLIM_DEVICE_STATUS_RESERVED,
 };
 
+struct slim_controller;
+
 /**
  * struct slim_device - Slim device handle.
  * @dev: Driver model representation of the device.
@@ -65,6 +67,7 @@ struct slim_device {
 	struct device		dev;
 	struct slim_eaddr	e_addr;
 	struct list_head node;
+	struct slim_controller	*ctrl;
 	enum slim_device_status	status;
 	u8			laddr;
 	bool			is_laddr_valid;
@@ -126,4 +129,8 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data)
 {
 	dev_set_drvdata(&dev->dev, data);
 }
+
+struct slim_device *slim_get_device(struct slim_controller *ctrl,
+				    struct slim_eaddr *e_addr);
+int slim_get_logical_addr(struct slim_device *sbdev, u8 *laddr);
 #endif /* _LINUX_SLIMBUS_H */
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 05/13] slimbus: core: add support to device tree helper
  2017-11-15 14:10 ` srinivas.kandagatla
                   ` (4 preceding siblings ...)
  (?)
@ 2017-11-15 14:10 ` srinivas.kandagatla
       [not found]   ` <20171115141043.29202-6-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  -1 siblings, 1 reply; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

This patch adds support to parse slim devices from device tree.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index d31a9c4fe7e9..f7b14961c7e3 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/idr.h>
+#include <linux/of.h>
 #include <linux/slimbus.h>
 #include "slimbus.h"
 
@@ -128,6 +129,9 @@ static int slim_add_device(struct slim_controller *ctrl,
 	sbdev->dev.driver = NULL;
 	sbdev->ctrl = ctrl;
 
+	if (node)
+		sbdev->dev.of_node = of_node_get(node);
+
 	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
 				  sbdev->e_addr.manf_id,
 				  sbdev->e_addr.prod_code,
@@ -160,6 +164,50 @@ static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
 	return sbdev;
 }
 
+static void of_register_slim_devices(struct slim_controller *ctrl)
+{
+	struct device *dev = ctrl->dev;
+	struct device_node *node;
+
+	if (!ctrl->dev->of_node)
+		return;
+
+	for_each_child_of_node(ctrl->dev->of_node, node) {
+		struct slim_device *sbdev;
+		struct slim_eaddr e_addr;
+		const char *compat = NULL;
+		int reg[2], ret;
+		int manf_id, prod_code;
+
+		compat = of_get_property(node, "compatible", NULL);
+		if (!compat)
+			continue;
+
+		ret = sscanf(compat, "slim%x,%x", &manf_id, &prod_code);
+		if (ret != 2) {
+			dev_err(dev, "Manf ID & Product code not found %s\n",
+				compat);
+			continue;
+		}
+
+		ret = of_property_read_u32_array(node, "reg", reg, 2);
+		if (ret) {
+			dev_err(dev, "Device and Instance id not found:%d\n",
+				ret);
+			continue;
+		}
+
+		e_addr.dev_index = reg[0];
+		e_addr.instance = reg[1];
+		e_addr.manf_id = manf_id;
+		e_addr.prod_code = prod_code;
+
+		sbdev = slim_alloc_device(ctrl, &e_addr, node);
+		if (!sbdev)
+			continue;
+	}
+}
+
 /*
  * slim_register_controller() - Controller bring-up and registration.
  *
@@ -191,6 +239,8 @@ int slim_register_controller(struct slim_controller *ctrl)
 	dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n",
 		ctrl->name, ctrl->dev);
 
+	of_register_slim_devices(ctrl);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(slim_register_controller);
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10     ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, arnd-r2nGTMty4D4,
	Srinivas Kandagatla

From: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

Slimbus devices use value-element, and information elements to
control device parameters (e.g. value element is used to represent
gain for codec, information element is used to represent interrupt
status for codec when codec interrupt fires).
Messaging APIs are used to set/get these value and information
elements. Slimbus specification uses 8-bit "transaction IDs" for
messages where a read-value is anticipated. Framework uses a table
of pointers to store those TIDs and responds back to the caller in
O(1).
Caller can do synchronous and asynchronous reads/writes.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/slimbus/Makefile    |   2 +-
 drivers/slimbus/messaging.c | 415 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/slimbus/slimbus.h   |  74 ++++++++
 include/linux/slimbus.h     |  31 ++++
 4 files changed, 521 insertions(+), 1 deletion(-)
 create mode 100644 drivers/slimbus/messaging.c

diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index 50deace4e76d..dfa049a382ef 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -2,4 +2,4 @@
 # Makefile for kernel slimbus framework.
 #
 obj-$(CONFIG_SLIMBUS)			+= slimbus.o
-slimbus-y				:= core.o
+slimbus-y				:= core.o messaging.o
diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c
new file mode 100644
index 000000000000..ba78c1bfe15d
--- /dev/null
+++ b/drivers/slimbus/messaging.c
@@ -0,0 +1,415 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/slab.h>
+#include "slimbus.h"
+
+/**
+ * slim_msg_response() - Deliver Message response received from a device to the
+ *			framework.
+ *
+ * @ctrl: Controller handle
+ * @reply: Reply received from the device
+ * @len: Length of the reply
+ * @tid: Transaction ID received with which framework can associate reply.
+ *
+ * Called by controller to inform framework about the response received.
+ * This helps in making the API asynchronous, and controller-driver doesn't need
+ * to manage 1 more table other than the one managed by framework mapping TID
+ * with buffers
+ */
+void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
+{
+	struct slim_msg_txn *txn;
+	struct slim_val_inf *msg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctrl->txn_lock, flags);
+	txn = idr_find(&ctrl->tid_idr, tid);
+	if (txn == NULL) {
+		spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+		return;
+	}
+
+	msg = txn->msg;
+	if (msg == NULL || msg->rbuf == NULL) {
+		dev_err(ctrl->dev, "Got response to invalid TID:%d, len:%d\n",
+				tid, len);
+		return;
+	}
+
+	idr_remove(&ctrl->tid_idr, tid);
+	spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+	memcpy(msg->rbuf, reply, len);
+	if (txn->comp)
+		complete(txn->comp);
+}
+EXPORT_SYMBOL_GPL(slim_msg_response);
+
+/**
+ * slim_do_transfer() - Process a slimbus-messaging transaction
+ *
+ * @ctrl: Controller handle
+ * @txn: Transaction to be sent over SLIMbus
+ *
+ * Called by controller to transmit messaging transactions not dealing with
+ * Interface/Value elements. (e.g. transmittting a message to assign logical
+ * address to a slave device
+ *
+ * Return: -ETIMEDOUT: If transmission of this message timed out
+ *	(e.g. due to bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by destination
+ *	device.
+ */
+int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
+{
+	DECLARE_COMPLETION_ONSTACK(done);
+	bool need_tid;
+	unsigned long flags;
+	int ret, tid, timeout;
+
+	need_tid = slim_tid_txn(txn->mt, txn->mc);
+
+	if (need_tid) {
+		spin_lock_irqsave(&ctrl->txn_lock, flags);
+		tid = idr_alloc(&ctrl->tid_idr, txn, 0,
+				SLIM_MAX_TIDS, GFP_KERNEL);
+		txn->tid = tid;
+
+		if (!txn->msg->comp)
+			txn->comp = &done;
+		else
+			txn->comp = txn->comp;
+
+		spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+		if (tid < 0)
+			return tid;
+	}
+
+	ret = ctrl->xfer_msg(ctrl, txn);
+
+	if (ret && need_tid && !txn->msg->comp) {
+		unsigned long ms = txn->rl + HZ;
+
+		timeout = wait_for_completion_timeout(txn->comp,
+						      msecs_to_jiffies(ms));
+		if (!timeout) {
+			ret = -ETIMEDOUT;
+			spin_lock_irqsave(&ctrl->txn_lock, flags);
+			idr_remove(&ctrl->tid_idr, tid);
+			spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+		}
+	}
+
+	if (ret)
+		dev_err(ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
+			txn->mt, txn->mc, txn->la, ret);
+
+	return ret;
+}
+
+static int slim_val_inf_sanity(struct slim_controller *ctrl,
+			       struct slim_val_inf *msg, u8 mc)
+{
+	if (!msg || msg->num_bytes > 16 ||
+	    (msg->start_offset + msg->num_bytes) > 0xC00)
+		goto reterr;
+	switch (mc) {
+	case SLIM_MSG_MC_REQUEST_VALUE:
+	case SLIM_MSG_MC_REQUEST_INFORMATION:
+		if (msg->rbuf != NULL)
+			return 0;
+		break;
+	case SLIM_MSG_MC_CHANGE_VALUE:
+	case SLIM_MSG_MC_CLEAR_INFORMATION:
+		if (msg->wbuf != NULL)
+			return 0;
+		break;
+	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
+	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
+		if (msg->rbuf != NULL && msg->wbuf != NULL)
+			return 0;
+		break;
+	default:
+		break;
+	}
+reterr:
+	dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n",
+		msg->start_offset, mc);
+	return -EINVAL;
+}
+
+static u16 slim_slicesize(int code)
+{
+	static const u8 sizetocode[16] = {
+		0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7
+	};
+
+	clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
+	return sizetocode[code - 1];
+}
+
+static int slim_xfer_msg(struct slim_controller *ctrl,
+			 struct slim_device *sbdev,
+			 struct slim_val_inf *msg, u8 mc)
+{
+	DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg);
+	struct slim_msg_txn *txn = &txn_stack;
+	int ret;
+	u16 sl;
+
+	ret = slim_val_inf_sanity(ctrl, msg, mc);
+	if (ret)
+		return ret;
+
+	sl = slim_slicesize(msg->num_bytes);
+
+	dev_dbg(ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n",
+		msg->start_offset, msg->num_bytes, mc, sl);
+
+	txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
+
+	switch (mc) {
+	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
+	case SLIM_MSG_MC_CHANGE_VALUE:
+	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
+	case SLIM_MSG_MC_CLEAR_INFORMATION:
+		txn->rl += msg->num_bytes;
+	default:
+		break;
+	}
+
+	if (slim_tid_txn(txn->mt, txn->mc))
+		txn->rl++;
+
+	return slim_do_transfer(ctrl, txn);
+}
+
+/**
+ * slim_request_val_element() - request value element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to read.
+ * context: can sleep
+ *
+ * Return: -EINVAL: Invalid parameters
+ *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
+ *	 bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by the device.
+ */
+int slim_request_val_element(struct slim_device *sb,
+				struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_VALUE);
+}
+EXPORT_SYMBOL_GPL(slim_request_val_element);
+
+/**
+ * slim_request_inf_element() - Request a info element
+ *
+ * @sb: client handle requesting elemental message reads.
+ * @msg: Input structure for start-offset, number of bytes to read
+ *	wbuf will contain information element(s) bit masks to be cleared.
+ *	rbuf will return what the information element value was
+ */
+int slim_request_inf_element(struct slim_device *sb,
+				struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_INFORMATION);
+}
+EXPORT_SYMBOL_GPL(slim_request_inf_element);
+
+/**
+ * slim_change_val_element: change a given value element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to write.
+ * context: can sleep
+ *
+ * Return:
+ *	-EINVAL: Invalid parameters
+ *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
+ *	 bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by the device.
+ */
+int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CHANGE_VALUE);
+}
+EXPORT_SYMBOL_GPL(slim_change_val_element);
+
+/**
+ * slim_clear_inf_element() - Clear info element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to read
+ *	wbuf will contain information element(s) bit masks to be cleared.
+ *	rbuf will return what the information element value was
+ */
+int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CLEAR_INFORMATION);
+}
+EXPORT_SYMBOL_GPL(slim_clear_inf_element);
+
+/**
+ * slim_request_val_element() - change and request a given value element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to write.
+ * context: can sleep
+ *
+ * Return:
+ *	-EINVAL: Invalid parameters
+ *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
+ *	 bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by the device.
+ */
+int slim_request_change_val_element(struct slim_device *sb,
+					struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE);
+}
+EXPORT_SYMBOL_GPL(slim_request_change_val_element);
+
+/**
+ * slim_request_clear_inf_element() - Clear and request info element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to read
+ *	wbuf will contain information element(s) bit masks to be cleared.
+ *	rbuf will return what the information element value was
+ */
+int slim_request_clear_inf_element(struct slim_device *sb,
+					struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg,
+					SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION);
+}
+EXPORT_SYMBOL_GPL(slim_request_clear_inf_element);
+
+static void slim_fill_msg(struct slim_val_inf *msg, u32 addr,
+			 size_t count, u8 *rbuf, u8 *wbuf)
+{
+	msg->start_offset = addr;
+	msg->num_bytes = count;
+	msg->rbuf = rbuf;
+	msg->wbuf = wbuf;
+}
+
+/**
+ * slim_read() - Read slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address of value element to read.
+ * @count: number of bytes to read. Maximum bytes allowed are 16.
+ * @val: will return what the value element value was
+ */
+int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
+{
+	struct slim_val_inf msg;
+	int ret;
+
+	slim_fill_msg(&msg, addr, count, val, NULL);
+
+	ret = slim_request_val_element(sdev, &msg);
+
+	return ret;
+
+}
+EXPORT_SYMBOL_GPL(slim_read);
+
+/**
+ * slim_readb() - Read byte from slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address in the value element to read.
+ *
+ * Return: byte value of value element.
+ */
+int slim_readb(struct slim_device *sdev, u32 addr)
+{
+	int ret;
+	u8 buf;
+
+	ret = slim_read(sdev, addr, 1, &buf);
+	if (ret < 0)
+		return ret;
+	else
+		return buf;
+}
+EXPORT_SYMBOL_GPL(slim_readb);
+
+/**
+ * slim_write() - Write slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address in the value element to write.
+ * @count: number of bytes to write. Maximum bytes allowed are 16.
+ * @val: value to write to value element
+ */
+int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
+{
+	struct slim_val_inf msg;
+	int ret;
+
+	slim_fill_msg(&msg, addr, count,  val, NULL);
+	ret = slim_change_val_element(sdev, &msg);
+
+	return ret;
+
+}
+EXPORT_SYMBOL_GPL(slim_write);
+
+/**
+ * slim_writeb() - Write byte to slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address of value element to write.
+ * @value: value to write to value element
+ */
+int slim_writeb(struct slim_device *sdev, u32 addr, u8 value)
+{
+	return slim_write(sdev, addr, 1, &value);
+}
+EXPORT_SYMBOL_GPL(slim_writeb);
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index b53319992ad4..f3ed5d4dbb0a 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -15,8 +15,31 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/completion.h>
 #include <linux/slimbus.h>
 
+/* SLIMbus message types. Related to interpretation of message code. */
+#define SLIM_MSG_MT_CORE			0x0
+
+
+/* Information Element management messages */
+#define SLIM_MSG_MC_REQUEST_INFORMATION          0x20
+#define SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION    0x21
+#define SLIM_MSG_MC_REPLY_INFORMATION            0x24
+#define SLIM_MSG_MC_CLEAR_INFORMATION            0x28
+#define SLIM_MSG_MC_REPORT_INFORMATION           0x29
+
+/* Value Element management messages */
+#define SLIM_MSG_MC_REQUEST_VALUE                0x60
+#define SLIM_MSG_MC_REQUEST_CHANGE_VALUE         0x61
+#define SLIM_MSG_MC_REPLY_VALUE                  0x64
+#define SLIM_MSG_MC_CHANGE_VALUE                 0x68
+
+/* Destination type Values */
+#define SLIM_MSG_DEST_LOGICALADDR	0
+#define SLIM_MSG_DEST_ENUMADDR		1
+#define	SLIM_MSG_DEST_BROADCAST		3
+
 /* Standard values per SLIMbus spec needed by controllers and devices */
 #define SLIM_MAX_CLK_GEAR		10
 #define SLIM_MIN_CLK_GEAR		1
@@ -24,6 +47,7 @@
 /* Manager's logical address is set to 0xFF per spec */
 #define SLIM_LA_MANAGER 0xFF
 
+#define SLIM_MAX_TIDS			256
 /**
  * struct slim_framer - Represents Slimbus framer.
  * Every controller may have multiple framers. There is 1 active framer device
@@ -44,6 +68,40 @@ struct slim_framer {
 
 #define to_slim_framer(d) container_of(d, struct slim_framer, dev)
 
+/**
+ * struct slim_msg_txn - Message to be sent by the controller.
+ *			This structure has packet header,
+ *			payload and buffer to be filled (if any)
+ * @rl: Header field. remaining length.
+ * @mt: Header field. Message type.
+ * @mc: Header field. LSB is message code for type mt.
+ * @dt: Header field. Destination type.
+ * @ec: Element code. Used for elemental access APIs.
+ * @len: Length of payload. (excludes ec)
+ * @tid: Transaction ID. Used for messages expecting response.
+ *	(relevant for message-codes involving read operation)
+ * @la: Logical address of the device this message is going to.
+ *	(Not used when destination type is broadcast.)
+ * @msg: Elemental access message to be read/written
+ * @comp: completion if read/write is synchronous, used internally
+ *	for tid based transactions.
+ */
+struct slim_msg_txn {
+	u8			rl;
+	u8			mt;
+	u8			mc;
+	u8			dt;
+	u16			ec;
+	u8			tid;
+	u8			la;
+	struct slim_val_inf	*msg;
+	struct	completion	*comp;
+};
+
+/* Frequently used message transaction structures */
+#define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \
+	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\
+					0, la, msg, }
 /**
  * struct slim_controller  - Controls every instance of SLIMbus
  *				(similar to 'master' on SPI)
@@ -60,6 +118,9 @@ struct slim_framer {
  * @devices: Slim device list
  * @tid_idr: tid id allocator
  * @txn_lock: Lock to protect table of transactions
+ * @xfer_msg: Transfer a message on this controller (this can be a broadcast
+ *	control/status message like data channel setup, or a unicast message
+ *	like value element read/write.
  * @set_laddr: Setup logical address at laddr for the slave with elemental
  *	address e_addr. Drivers implementing controller will be expected to
  *	send unicast message to this device with its logical address.
@@ -101,6 +162,8 @@ struct slim_controller {
 	struct list_head	devices;
 	struct idr		tid_idr;
 	spinlock_t		txn_lock;
+	int			(*xfer_msg)(struct slim_controller *ctrl,
+					    struct slim_msg_txn *tx);
 	int			(*set_laddr)(struct slim_controller *ctrl,
 					     struct slim_eaddr *ea, u8 laddr);
 	int			(*get_laddr)(struct slim_controller *ctrl,
@@ -112,5 +175,16 @@ int slim_device_report_present(struct slim_controller *ctrl,
 void slim_report_absent(struct slim_device *sbdev);
 int slim_register_controller(struct slim_controller *ctrl);
 int slim_unregister_controller(struct slim_controller *ctrl);
+void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l);
+int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn);
+
+static inline bool slim_tid_txn(u8 mt, u8 mc)
+{
+	return (mt == SLIM_MSG_MT_CORE &&
+		(mc == SLIM_MSG_MC_REQUEST_INFORMATION ||
+		 mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION ||
+		 mc == SLIM_MSG_MC_REQUEST_VALUE ||
+		 mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION));
+}
 
 #endif /* _LINUX_SLIMBUS_H */
diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h
index ba3fdf1f5176..42b2a8561a45 100644
--- a/include/linux/slimbus.h
+++ b/include/linux/slimbus.h
@@ -14,6 +14,7 @@
 #define _LINUX_SLIMBUS_H
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/completion.h>
 #include <linux/mod_devicetable.h>
 
 /**
@@ -100,6 +101,23 @@ struct slim_driver {
 };
 #define to_slim_driver(d) container_of(d, struct slim_driver, driver)
 
+/**
+ * struct slim_val_inf - Slimbus value or information element
+ * @start_offset: Specifies starting offset in information/value element map
+ * @num_bytes: upto 16. This ensures that the message will fit the slicesize
+ *		per slimbus spec
+ * @comp: completion for asynchronous operations, valid only if TID is
+ *	  required for transaction, like REQUEST operations.
+ *	  Rest of the transactions are synchronous anyway.
+ */
+struct slim_val_inf {
+	u16			start_offset;
+	u8			num_bytes;
+	u8			*rbuf;
+	const u8		*wbuf;
+	struct	completion	*comp;
+};
+
 /*
  * use a macro to avoid include chaining to get THIS_MODULE
  */
@@ -133,4 +151,17 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data)
 struct slim_device *slim_get_device(struct slim_controller *ctrl,
 				    struct slim_eaddr *e_addr);
 int slim_get_logical_addr(struct slim_device *sbdev, u8 *laddr);
+
+int slim_request_val_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_request_inf_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_request_change_val_element(struct slim_device *sb,
+				    struct slim_val_inf *msg);
+int slim_request_clear_inf_element(struct slim_device *sb,
+				   struct slim_val_inf *msg);
+int slim_readb(struct slim_device *sdev, u32 addr);
+int slim_writeb(struct slim_device *sdev, u32 addr, u8 value);
+int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val);
+int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val);
 #endif /* _LINUX_SLIMBUS_H */
-- 
2.15.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
@ 2017-11-15 14:10     ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

Slimbus devices use value-element, and information elements to
control device parameters (e.g. value element is used to represent
gain for codec, information element is used to represent interrupt
status for codec when codec interrupt fires).
Messaging APIs are used to set/get these value and information
elements. Slimbus specification uses 8-bit "transaction IDs" for
messages where a read-value is anticipated. Framework uses a table
of pointers to store those TIDs and responds back to the caller in
O(1).
Caller can do synchronous and asynchronous reads/writes.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/Makefile    |   2 +-
 drivers/slimbus/messaging.c | 415 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/slimbus/slimbus.h   |  74 ++++++++
 include/linux/slimbus.h     |  31 ++++
 4 files changed, 521 insertions(+), 1 deletion(-)
 create mode 100644 drivers/slimbus/messaging.c

diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index 50deace4e76d..dfa049a382ef 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -2,4 +2,4 @@
 # Makefile for kernel slimbus framework.
 #
 obj-$(CONFIG_SLIMBUS)			+= slimbus.o
-slimbus-y				:= core.o
+slimbus-y				:= core.o messaging.o
diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c
new file mode 100644
index 000000000000..ba78c1bfe15d
--- /dev/null
+++ b/drivers/slimbus/messaging.c
@@ -0,0 +1,415 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/slab.h>
+#include "slimbus.h"
+
+/**
+ * slim_msg_response() - Deliver Message response received from a device to the
+ *			framework.
+ *
+ * @ctrl: Controller handle
+ * @reply: Reply received from the device
+ * @len: Length of the reply
+ * @tid: Transaction ID received with which framework can associate reply.
+ *
+ * Called by controller to inform framework about the response received.
+ * This helps in making the API asynchronous, and controller-driver doesn't need
+ * to manage 1 more table other than the one managed by framework mapping TID
+ * with buffers
+ */
+void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
+{
+	struct slim_msg_txn *txn;
+	struct slim_val_inf *msg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctrl->txn_lock, flags);
+	txn = idr_find(&ctrl->tid_idr, tid);
+	if (txn == NULL) {
+		spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+		return;
+	}
+
+	msg = txn->msg;
+	if (msg == NULL || msg->rbuf == NULL) {
+		dev_err(ctrl->dev, "Got response to invalid TID:%d, len:%d\n",
+				tid, len);
+		return;
+	}
+
+	idr_remove(&ctrl->tid_idr, tid);
+	spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+	memcpy(msg->rbuf, reply, len);
+	if (txn->comp)
+		complete(txn->comp);
+}
+EXPORT_SYMBOL_GPL(slim_msg_response);
+
+/**
+ * slim_do_transfer() - Process a slimbus-messaging transaction
+ *
+ * @ctrl: Controller handle
+ * @txn: Transaction to be sent over SLIMbus
+ *
+ * Called by controller to transmit messaging transactions not dealing with
+ * Interface/Value elements. (e.g. transmittting a message to assign logical
+ * address to a slave device
+ *
+ * Return: -ETIMEDOUT: If transmission of this message timed out
+ *	(e.g. due to bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by destination
+ *	device.
+ */
+int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
+{
+	DECLARE_COMPLETION_ONSTACK(done);
+	bool need_tid;
+	unsigned long flags;
+	int ret, tid, timeout;
+
+	need_tid = slim_tid_txn(txn->mt, txn->mc);
+
+	if (need_tid) {
+		spin_lock_irqsave(&ctrl->txn_lock, flags);
+		tid = idr_alloc(&ctrl->tid_idr, txn, 0,
+				SLIM_MAX_TIDS, GFP_KERNEL);
+		txn->tid = tid;
+
+		if (!txn->msg->comp)
+			txn->comp = &done;
+		else
+			txn->comp = txn->comp;
+
+		spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+		if (tid < 0)
+			return tid;
+	}
+
+	ret = ctrl->xfer_msg(ctrl, txn);
+
+	if (ret && need_tid && !txn->msg->comp) {
+		unsigned long ms = txn->rl + HZ;
+
+		timeout = wait_for_completion_timeout(txn->comp,
+						      msecs_to_jiffies(ms));
+		if (!timeout) {
+			ret = -ETIMEDOUT;
+			spin_lock_irqsave(&ctrl->txn_lock, flags);
+			idr_remove(&ctrl->tid_idr, tid);
+			spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+		}
+	}
+
+	if (ret)
+		dev_err(ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
+			txn->mt, txn->mc, txn->la, ret);
+
+	return ret;
+}
+
+static int slim_val_inf_sanity(struct slim_controller *ctrl,
+			       struct slim_val_inf *msg, u8 mc)
+{
+	if (!msg || msg->num_bytes > 16 ||
+	    (msg->start_offset + msg->num_bytes) > 0xC00)
+		goto reterr;
+	switch (mc) {
+	case SLIM_MSG_MC_REQUEST_VALUE:
+	case SLIM_MSG_MC_REQUEST_INFORMATION:
+		if (msg->rbuf != NULL)
+			return 0;
+		break;
+	case SLIM_MSG_MC_CHANGE_VALUE:
+	case SLIM_MSG_MC_CLEAR_INFORMATION:
+		if (msg->wbuf != NULL)
+			return 0;
+		break;
+	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
+	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
+		if (msg->rbuf != NULL && msg->wbuf != NULL)
+			return 0;
+		break;
+	default:
+		break;
+	}
+reterr:
+	dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n",
+		msg->start_offset, mc);
+	return -EINVAL;
+}
+
+static u16 slim_slicesize(int code)
+{
+	static const u8 sizetocode[16] = {
+		0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7
+	};
+
+	clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
+	return sizetocode[code - 1];
+}
+
+static int slim_xfer_msg(struct slim_controller *ctrl,
+			 struct slim_device *sbdev,
+			 struct slim_val_inf *msg, u8 mc)
+{
+	DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg);
+	struct slim_msg_txn *txn = &txn_stack;
+	int ret;
+	u16 sl;
+
+	ret = slim_val_inf_sanity(ctrl, msg, mc);
+	if (ret)
+		return ret;
+
+	sl = slim_slicesize(msg->num_bytes);
+
+	dev_dbg(ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n",
+		msg->start_offset, msg->num_bytes, mc, sl);
+
+	txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
+
+	switch (mc) {
+	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
+	case SLIM_MSG_MC_CHANGE_VALUE:
+	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
+	case SLIM_MSG_MC_CLEAR_INFORMATION:
+		txn->rl += msg->num_bytes;
+	default:
+		break;
+	}
+
+	if (slim_tid_txn(txn->mt, txn->mc))
+		txn->rl++;
+
+	return slim_do_transfer(ctrl, txn);
+}
+
+/**
+ * slim_request_val_element() - request value element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to read.
+ * context: can sleep
+ *
+ * Return: -EINVAL: Invalid parameters
+ *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
+ *	 bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by the device.
+ */
+int slim_request_val_element(struct slim_device *sb,
+				struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_VALUE);
+}
+EXPORT_SYMBOL_GPL(slim_request_val_element);
+
+/**
+ * slim_request_inf_element() - Request a info element
+ *
+ * @sb: client handle requesting elemental message reads.
+ * @msg: Input structure for start-offset, number of bytes to read
+ *	wbuf will contain information element(s) bit masks to be cleared.
+ *	rbuf will return what the information element value was
+ */
+int slim_request_inf_element(struct slim_device *sb,
+				struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_INFORMATION);
+}
+EXPORT_SYMBOL_GPL(slim_request_inf_element);
+
+/**
+ * slim_change_val_element: change a given value element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to write.
+ * context: can sleep
+ *
+ * Return:
+ *	-EINVAL: Invalid parameters
+ *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
+ *	 bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by the device.
+ */
+int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CHANGE_VALUE);
+}
+EXPORT_SYMBOL_GPL(slim_change_val_element);
+
+/**
+ * slim_clear_inf_element() - Clear info element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to read
+ *	wbuf will contain information element(s) bit masks to be cleared.
+ *	rbuf will return what the information element value was
+ */
+int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CLEAR_INFORMATION);
+}
+EXPORT_SYMBOL_GPL(slim_clear_inf_element);
+
+/**
+ * slim_request_val_element() - change and request a given value element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to write.
+ * context: can sleep
+ *
+ * Return:
+ *	-EINVAL: Invalid parameters
+ *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
+ *	 bus lines not being clocked or driven by controller)
+ *	-ENOTCONN: If the transmitted message was not ACKed by the device.
+ */
+int slim_request_change_val_element(struct slim_device *sb,
+					struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE);
+}
+EXPORT_SYMBOL_GPL(slim_request_change_val_element);
+
+/**
+ * slim_request_clear_inf_element() - Clear and request info element
+ *
+ * @sb: client handle requesting elemental message reads, writes.
+ * @msg: Input structure for start-offset, number of bytes to read
+ *	wbuf will contain information element(s) bit masks to be cleared.
+ *	rbuf will return what the information element value was
+ */
+int slim_request_clear_inf_element(struct slim_device *sb,
+					struct slim_val_inf *msg)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+
+	if (!ctrl)
+		return -EINVAL;
+
+	return slim_xfer_msg(ctrl, sb, msg,
+					SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION);
+}
+EXPORT_SYMBOL_GPL(slim_request_clear_inf_element);
+
+static void slim_fill_msg(struct slim_val_inf *msg, u32 addr,
+			 size_t count, u8 *rbuf, u8 *wbuf)
+{
+	msg->start_offset = addr;
+	msg->num_bytes = count;
+	msg->rbuf = rbuf;
+	msg->wbuf = wbuf;
+}
+
+/**
+ * slim_read() - Read slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address of value element to read.
+ * @count: number of bytes to read. Maximum bytes allowed are 16.
+ * @val: will return what the value element value was
+ */
+int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
+{
+	struct slim_val_inf msg;
+	int ret;
+
+	slim_fill_msg(&msg, addr, count, val, NULL);
+
+	ret = slim_request_val_element(sdev, &msg);
+
+	return ret;
+
+}
+EXPORT_SYMBOL_GPL(slim_read);
+
+/**
+ * slim_readb() - Read byte from slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address in the value element to read.
+ *
+ * Return: byte value of value element.
+ */
+int slim_readb(struct slim_device *sdev, u32 addr)
+{
+	int ret;
+	u8 buf;
+
+	ret = slim_read(sdev, addr, 1, &buf);
+	if (ret < 0)
+		return ret;
+	else
+		return buf;
+}
+EXPORT_SYMBOL_GPL(slim_readb);
+
+/**
+ * slim_write() - Write slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address in the value element to write.
+ * @count: number of bytes to write. Maximum bytes allowed are 16.
+ * @val: value to write to value element
+ */
+int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
+{
+	struct slim_val_inf msg;
+	int ret;
+
+	slim_fill_msg(&msg, addr, count,  val, NULL);
+	ret = slim_change_val_element(sdev, &msg);
+
+	return ret;
+
+}
+EXPORT_SYMBOL_GPL(slim_write);
+
+/**
+ * slim_writeb() - Write byte to slimbus value element
+ *
+ * @sdev: client handle.
+ * @addr:  address of value element to write.
+ * @value: value to write to value element
+ */
+int slim_writeb(struct slim_device *sdev, u32 addr, u8 value)
+{
+	return slim_write(sdev, addr, 1, &value);
+}
+EXPORT_SYMBOL_GPL(slim_writeb);
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index b53319992ad4..f3ed5d4dbb0a 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -15,8 +15,31 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/completion.h>
 #include <linux/slimbus.h>
 
+/* SLIMbus message types. Related to interpretation of message code. */
+#define SLIM_MSG_MT_CORE			0x0
+
+
+/* Information Element management messages */
+#define SLIM_MSG_MC_REQUEST_INFORMATION          0x20
+#define SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION    0x21
+#define SLIM_MSG_MC_REPLY_INFORMATION            0x24
+#define SLIM_MSG_MC_CLEAR_INFORMATION            0x28
+#define SLIM_MSG_MC_REPORT_INFORMATION           0x29
+
+/* Value Element management messages */
+#define SLIM_MSG_MC_REQUEST_VALUE                0x60
+#define SLIM_MSG_MC_REQUEST_CHANGE_VALUE         0x61
+#define SLIM_MSG_MC_REPLY_VALUE                  0x64
+#define SLIM_MSG_MC_CHANGE_VALUE                 0x68
+
+/* Destination type Values */
+#define SLIM_MSG_DEST_LOGICALADDR	0
+#define SLIM_MSG_DEST_ENUMADDR		1
+#define	SLIM_MSG_DEST_BROADCAST		3
+
 /* Standard values per SLIMbus spec needed by controllers and devices */
 #define SLIM_MAX_CLK_GEAR		10
 #define SLIM_MIN_CLK_GEAR		1
@@ -24,6 +47,7 @@
 /* Manager's logical address is set to 0xFF per spec */
 #define SLIM_LA_MANAGER 0xFF
 
+#define SLIM_MAX_TIDS			256
 /**
  * struct slim_framer - Represents Slimbus framer.
  * Every controller may have multiple framers. There is 1 active framer device
@@ -44,6 +68,40 @@ struct slim_framer {
 
 #define to_slim_framer(d) container_of(d, struct slim_framer, dev)
 
+/**
+ * struct slim_msg_txn - Message to be sent by the controller.
+ *			This structure has packet header,
+ *			payload and buffer to be filled (if any)
+ * @rl: Header field. remaining length.
+ * @mt: Header field. Message type.
+ * @mc: Header field. LSB is message code for type mt.
+ * @dt: Header field. Destination type.
+ * @ec: Element code. Used for elemental access APIs.
+ * @len: Length of payload. (excludes ec)
+ * @tid: Transaction ID. Used for messages expecting response.
+ *	(relevant for message-codes involving read operation)
+ * @la: Logical address of the device this message is going to.
+ *	(Not used when destination type is broadcast.)
+ * @msg: Elemental access message to be read/written
+ * @comp: completion if read/write is synchronous, used internally
+ *	for tid based transactions.
+ */
+struct slim_msg_txn {
+	u8			rl;
+	u8			mt;
+	u8			mc;
+	u8			dt;
+	u16			ec;
+	u8			tid;
+	u8			la;
+	struct slim_val_inf	*msg;
+	struct	completion	*comp;
+};
+
+/* Frequently used message transaction structures */
+#define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \
+	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\
+					0, la, msg, }
 /**
  * struct slim_controller  - Controls every instance of SLIMbus
  *				(similar to 'master' on SPI)
@@ -60,6 +118,9 @@ struct slim_framer {
  * @devices: Slim device list
  * @tid_idr: tid id allocator
  * @txn_lock: Lock to protect table of transactions
+ * @xfer_msg: Transfer a message on this controller (this can be a broadcast
+ *	control/status message like data channel setup, or a unicast message
+ *	like value element read/write.
  * @set_laddr: Setup logical address at laddr for the slave with elemental
  *	address e_addr. Drivers implementing controller will be expected to
  *	send unicast message to this device with its logical address.
@@ -101,6 +162,8 @@ struct slim_controller {
 	struct list_head	devices;
 	struct idr		tid_idr;
 	spinlock_t		txn_lock;
+	int			(*xfer_msg)(struct slim_controller *ctrl,
+					    struct slim_msg_txn *tx);
 	int			(*set_laddr)(struct slim_controller *ctrl,
 					     struct slim_eaddr *ea, u8 laddr);
 	int			(*get_laddr)(struct slim_controller *ctrl,
@@ -112,5 +175,16 @@ int slim_device_report_present(struct slim_controller *ctrl,
 void slim_report_absent(struct slim_device *sbdev);
 int slim_register_controller(struct slim_controller *ctrl);
 int slim_unregister_controller(struct slim_controller *ctrl);
+void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l);
+int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn);
+
+static inline bool slim_tid_txn(u8 mt, u8 mc)
+{
+	return (mt == SLIM_MSG_MT_CORE &&
+		(mc == SLIM_MSG_MC_REQUEST_INFORMATION ||
+		 mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION ||
+		 mc == SLIM_MSG_MC_REQUEST_VALUE ||
+		 mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION));
+}
 
 #endif /* _LINUX_SLIMBUS_H */
diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h
index ba3fdf1f5176..42b2a8561a45 100644
--- a/include/linux/slimbus.h
+++ b/include/linux/slimbus.h
@@ -14,6 +14,7 @@
 #define _LINUX_SLIMBUS_H
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/completion.h>
 #include <linux/mod_devicetable.h>
 
 /**
@@ -100,6 +101,23 @@ struct slim_driver {
 };
 #define to_slim_driver(d) container_of(d, struct slim_driver, driver)
 
+/**
+ * struct slim_val_inf - Slimbus value or information element
+ * @start_offset: Specifies starting offset in information/value element map
+ * @num_bytes: upto 16. This ensures that the message will fit the slicesize
+ *		per slimbus spec
+ * @comp: completion for asynchronous operations, valid only if TID is
+ *	  required for transaction, like REQUEST operations.
+ *	  Rest of the transactions are synchronous anyway.
+ */
+struct slim_val_inf {
+	u16			start_offset;
+	u8			num_bytes;
+	u8			*rbuf;
+	const u8		*wbuf;
+	struct	completion	*comp;
+};
+
 /*
  * use a macro to avoid include chaining to get THIS_MODULE
  */
@@ -133,4 +151,17 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data)
 struct slim_device *slim_get_device(struct slim_controller *ctrl,
 				    struct slim_eaddr *e_addr);
 int slim_get_logical_addr(struct slim_device *sbdev, u8 *laddr);
+
+int slim_request_val_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_request_inf_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg);
+int slim_request_change_val_element(struct slim_device *sb,
+				    struct slim_val_inf *msg);
+int slim_request_clear_inf_element(struct slim_device *sb,
+				   struct slim_val_inf *msg);
+int slim_readb(struct slim_device *sdev, u32 addr);
+int slim_writeb(struct slim_device *sdev, u32 addr, u8 value);
+int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val);
+int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val);
 #endif /* _LINUX_SLIMBUS_H */
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10   ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: mark.rutland, michael.opdenacker, poeschel, Srinivas Kandagatla,
	andreas.noever, arnd, vinod.koul, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

From: Sagar Dharia <sdharia@codeaurora.org>

Per slimbus specification, a reconfiguration sequence known as
'clock pause' needs to be broadcast over the bus while entering low-
power mode. Clock-pause is initiated by the controller driver.
To exit clock-pause, controller typically wakes up the framer device.
Since wakeup precedure is controller-specific, framework calls it via
controller's function pointer to invoke it.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/Makefile    |   2 +-
 drivers/slimbus/core.c      |  16 ++++++
 drivers/slimbus/messaging.c |  35 +++++++++++-
 drivers/slimbus/sched.c     | 128 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/slimbus/slimbus.h   |  54 +++++++++++++++++++
 5 files changed, 233 insertions(+), 2 deletions(-)
 create mode 100644 drivers/slimbus/sched.c

diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index dfa049a382ef..043402eae5be 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -2,4 +2,4 @@
 # Makefile for kernel slimbus framework.
 #
 obj-$(CONFIG_SLIMBUS)			+= slimbus.o
-slimbus-y				:= core.o messaging.o
+slimbus-y				:= core.o messaging.o sched.o
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index f7b14961c7e3..fa0ae157d6b0 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <linux/slimbus.h>
 #include "slimbus.h"
 
@@ -235,6 +236,8 @@ int slim_register_controller(struct slim_controller *ctrl)
 	ida_init(&ctrl->laddr_ida);
 	idr_init(&ctrl->tid_idr);
 	mutex_init(&ctrl->lock);
+	mutex_init(&ctrl->sched.m_reconf);
+	init_completion(&ctrl->sched.pause_comp);
 
 	dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n",
 		ctrl->name, ctrl->dev);
@@ -266,6 +269,8 @@ int slim_unregister_controller(struct slim_controller *ctrl)
 {
 	/* Remove all clients */
 	device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device);
+	/* Enter Clock Pause */
+	slim_ctrl_clk_pause(ctrl, false, 0);
 	ida_simple_remove(&ctrl_ida, ctrl->id);
 
 	return 0;
@@ -432,6 +437,14 @@ int slim_device_report_present(struct slim_controller *ctrl,
 	struct slim_device *sbdev;
 	int ret;
 
+	ret = pm_runtime_get_sync(ctrl->dev);
+
+	if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
+		dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
+				    ctrl->sched.clk_state, ret);
+		goto slimbus_not_active;
+	}
+
 	sbdev = slim_get_device(ctrl, e_addr);
 	if (IS_ERR(sbdev))
 		return -ENODEV;
@@ -443,6 +456,9 @@ int slim_device_report_present(struct slim_controller *ctrl,
 
 	ret = slim_device_alloc_laddr(sbdev, laddr, true);
 
+slimbus_not_active:
+	pm_runtime_mark_last_busy(ctrl->dev);
+	pm_runtime_put_autosuspend(ctrl->dev);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(slim_device_report_present);
diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c
index ba78c1bfe15d..c11534eaf97b 100644
--- a/drivers/slimbus/messaging.c
+++ b/drivers/slimbus/messaging.c
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 #include "slimbus.h"
 
 /**
@@ -52,6 +53,10 @@ void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
 	memcpy(msg->rbuf, reply, len);
 	if (txn->comp)
 		complete(txn->comp);
+
+	/* Remove runtime-pm vote now that response was received for TID txn */
+	pm_runtime_mark_last_busy(ctrl->dev);
+	pm_runtime_put_autosuspend(ctrl->dev);
 }
 EXPORT_SYMBOL_GPL(slim_msg_response);
 
@@ -73,10 +78,29 @@ EXPORT_SYMBOL_GPL(slim_msg_response);
 int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
 {
 	DECLARE_COMPLETION_ONSTACK(done);
-	bool need_tid;
+	bool need_tid = false, clk_pause_msg = false;
 	unsigned long flags;
 	int ret, tid, timeout;
 
+	/*
+	 * do not vote for runtime-PM if the transactions are part of clock
+	 * pause sequence
+	 */
+	if (ctrl->sched.clk_state == SLIM_CLK_ENTERING_PAUSE &&
+		(txn->mt == SLIM_MSG_MT_CORE &&
+		 txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
+		 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
+		clk_pause_msg = true;
+
+	if (!clk_pause_msg) {
+		ret = pm_runtime_get_sync(ctrl->dev);
+		if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
+			dev_err(ctrl->dev, "ctrl wrong state:%d, ret:%d\n",
+				ctrl->sched.clk_state, ret);
+			goto slim_xfer_err;
+		}
+	}
+
 	need_tid = slim_tid_txn(txn->mt, txn->mc);
 
 	if (need_tid) {
@@ -115,6 +139,15 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
 		dev_err(ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
 			txn->mt, txn->mc, txn->la, ret);
 
+slim_xfer_err:
+	if (!clk_pause_msg && (!need_tid  || ret == -ETIMEDOUT)) {
+		/*
+		 * remove runtime-pm vote if this was TX only, or
+		 * if there was error during this transaction
+		 */
+		pm_runtime_mark_last_busy(ctrl->dev);
+		pm_runtime_mark_last_busy(ctrl->dev);
+	}
 	return ret;
 }
 
diff --git a/drivers/slimbus/sched.c b/drivers/slimbus/sched.c
new file mode 100644
index 000000000000..74300f1a6898
--- /dev/null
+++ b/drivers/slimbus/sched.c
@@ -0,0 +1,128 @@
+/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/errno.h>
+#include "slimbus.h"
+
+/**
+ * slim_ctrl_clk_pause() - Called by slimbus controller to enter/exit
+ *			   'clock pause'
+ * @ctrl: controller requesting bus to be paused or woken up
+ * @wakeup: Wakeup this controller from clock pause.
+ * @restart: Restart time value per spec used for clock pause. This value
+ *	isn't used when controller is to be woken up.
+ *
+ * Slimbus specification needs this sequence to turn-off clocks for the bus.
+ * The sequence involves sending 3 broadcast messages (reconfiguration
+ * sequence) to inform all devices on the bus.
+ * To exit clock-pause, controller typically wakes up active framer device.
+ * This API executes clock pause reconfiguration sequence if wakeup is false.
+ * If wakeup is true, controller's wakeup is called.
+ * For entering clock-pause, -EBUSY is returned if a message txn in pending.
+ */
+int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart)
+{
+	int i, ret = 0;
+	unsigned long flags;
+	struct slim_sched *sched = &ctrl->sched;
+	struct slim_val_inf msg = {0, 0, NULL, NULL};
+
+	DEFINE_SLIM_BCAST_TXN(txn, SLIM_MSG_MC_BEGIN_RECONFIGURATION,
+				3, SLIM_LA_MANAGER, &msg);
+
+	if (wakeup == false && restart > SLIM_CLK_UNSPECIFIED)
+		return -EINVAL;
+
+	mutex_lock(&sched->m_reconf);
+	if (wakeup) {
+		if (sched->clk_state == SLIM_CLK_ACTIVE) {
+			mutex_unlock(&sched->m_reconf);
+			return 0;
+		}
+
+		/*
+		 * Fine-tune calculation based on clock gear,
+		 * message-bandwidth after bandwidth management
+		 */
+		ret = wait_for_completion_timeout(&sched->pause_comp,
+				msecs_to_jiffies(100));
+		if (!ret) {
+			mutex_unlock(&sched->m_reconf);
+			pr_err("Previous clock pause did not finish");
+			return -ETIMEDOUT;
+		}
+		ret = 0;
+
+		/*
+		 * Slimbus framework will call controller wakeup
+		 * Controller should make sure that it sets active framer
+		 * out of clock pause
+		 */
+		if (sched->clk_state == SLIM_CLK_PAUSED && ctrl->wakeup)
+			ret = ctrl->wakeup(ctrl);
+		if (!ret)
+			sched->clk_state = SLIM_CLK_ACTIVE;
+		mutex_unlock(&sched->m_reconf);
+
+		return ret;
+	}
+
+	/* already paused */
+	if (ctrl->sched.clk_state == SLIM_CLK_PAUSED) {
+		mutex_unlock(&sched->m_reconf);
+		return 0;
+	}
+
+	spin_lock_irqsave(&ctrl->txn_lock, flags);
+	for (i = 0; i < SLIM_MAX_TIDS; i++) {
+		/* Pending response for a message */
+		if (idr_find(&ctrl->tid_idr, i)) {
+			spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+			mutex_unlock(&sched->m_reconf);
+			return -EBUSY;
+		}
+	}
+	spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+	sched->clk_state = SLIM_CLK_ENTERING_PAUSE;
+
+	/* clock pause sequence */
+	ret = slim_do_transfer(ctrl, &txn);
+	if (ret)
+		goto clk_pause_ret;
+
+	txn.mc = SLIM_MSG_MC_NEXT_PAUSE_CLOCK;
+	txn.rl = 4;
+	msg.num_bytes = 1;
+	msg.wbuf = &restart;
+	ret = slim_do_transfer(ctrl, &txn);
+	if (ret)
+		goto clk_pause_ret;
+
+	txn.mc = SLIM_MSG_MC_RECONFIGURE_NOW;
+	txn.rl = 3;
+	msg.num_bytes = 1;
+	msg.wbuf = NULL;
+	ret = slim_do_transfer(ctrl, &txn);
+
+clk_pause_ret:
+	if (ret) {
+		sched->clk_state = SLIM_CLK_ACTIVE;
+	} else {
+		sched->clk_state = SLIM_CLK_PAUSED;
+		complete(&sched->pause_comp);
+	}
+	mutex_unlock(&sched->m_reconf);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(slim_ctrl_clk_pause);
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index f3ed5d4dbb0a..4fe1892cbd4f 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -35,6 +35,16 @@
 #define SLIM_MSG_MC_REPLY_VALUE                  0x64
 #define SLIM_MSG_MC_CHANGE_VALUE                 0x68
 
+/* Clock pause Reconfiguration messages */
+#define SLIM_MSG_MC_BEGIN_RECONFIGURATION        0x40
+#define SLIM_MSG_MC_NEXT_PAUSE_CLOCK             0x4A
+#define SLIM_MSG_MC_RECONFIGURE_NOW              0x5F
+
+/* Clock pause values per slimbus spec */
+#define SLIM_CLK_FAST				0
+#define SLIM_CLK_CONST_PHASE			1
+#define SLIM_CLK_UNSPECIFIED			2
+
 /* Destination type Values */
 #define SLIM_MSG_DEST_LOGICALADDR	0
 #define SLIM_MSG_DEST_ENUMADDR		1
@@ -102,6 +112,43 @@ struct slim_msg_txn {
 #define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \
 	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\
 					0, la, msg, }
+
+#define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \
+	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\
+					0, la, msg, }
+/**
+ * enum slim_clk_state: Slimbus controller's clock state used internally for
+ *	maintaining current clock state.
+ * @SLIM_CLK_ACTIVE: Slimbus clock is active
+ * @SLIM_CLK_ENTERING_PAUSE: Slimbus clock pause sequence is being sent on the
+ *	bus. If this succeeds, state changes to SLIM_CLK_PAUSED. If the
+ *	transition fails, state changes back to SLIM_CLK_ACTIVE
+ * @SLIM_CLK_PAUSED: Slimbus controller clock has paused.
+ */
+enum slim_clk_state {
+	SLIM_CLK_ACTIVE,
+	SLIM_CLK_ENTERING_PAUSE,
+	SLIM_CLK_PAUSED,
+};
+
+/**
+ * struct slim_sched: Framework uses this structure internally for scheduling.
+ * @clk_state: Controller's clock state from enum slim_clk_state
+ * @pause_comp: Signals completion of clock pause sequence. This is useful when
+ *	client tries to call slimbus transaction when controller is entering
+ *	clock pause.
+ * @m_reconf: This mutex is held until current reconfiguration (data channel
+ *	scheduling, message bandwidth reservation) is done. Message APIs can
+ *	use the bus concurrently when this mutex is held since elemental access
+ *	messages can be sent on the bus when reconfiguration is in progress.
+ */
+struct slim_sched {
+	int			clkgear;
+	enum slim_clk_state	clk_state;
+	struct completion	pause_comp;
+	struct mutex		m_reconf;
+};
+
 /**
  * struct slim_controller  - Controls every instance of SLIMbus
  *				(similar to 'master' on SPI)
@@ -118,6 +165,7 @@ struct slim_msg_txn {
  * @devices: Slim device list
  * @tid_idr: tid id allocator
  * @txn_lock: Lock to protect table of transactions
+ * @sched: scheduler structure used by the controller
  * @xfer_msg: Transfer a message on this controller (this can be a broadcast
  *	control/status message like data channel setup, or a unicast message
  *	like value element read/write.
@@ -128,6 +176,9 @@ struct slim_msg_txn {
  *	address table and get_laddr can be used in that case so that controller
  *	can do this assignment. Use case is when the master is on the remote
  *	processor side, who is resposible for allocating laddr.
+ * @wakeup: This function pointer implements controller-specific procedure
+ *	to wake it up from clock-pause. Framework will call this to bring
+ *	the controller out of clock pause.
  *
  *	'Manager device' is responsible for  device management, bandwidth
  *	allocation, channel setup, and port associations per channel.
@@ -162,12 +213,14 @@ struct slim_controller {
 	struct list_head	devices;
 	struct idr		tid_idr;
 	spinlock_t		txn_lock;
+	struct slim_sched	sched;
 	int			(*xfer_msg)(struct slim_controller *ctrl,
 					    struct slim_msg_txn *tx);
 	int			(*set_laddr)(struct slim_controller *ctrl,
 					     struct slim_eaddr *ea, u8 laddr);
 	int			(*get_laddr)(struct slim_controller *ctrl,
 					     struct slim_eaddr *ea, u8 *laddr);
+	int			(*wakeup)(struct slim_controller *ctrl);
 };
 
 int slim_device_report_present(struct slim_controller *ctrl,
@@ -177,6 +230,7 @@ int slim_register_controller(struct slim_controller *ctrl);
 int slim_unregister_controller(struct slim_controller *ctrl);
 void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l);
 int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn);
+int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart);
 
 static inline bool slim_tid_txn(u8 mt, u8 mc)
 {
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature
@ 2017-11-15 14:10   ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

Per slimbus specification, a reconfiguration sequence known as
'clock pause' needs to be broadcast over the bus while entering low-
power mode. Clock-pause is initiated by the controller driver.
To exit clock-pause, controller typically wakes up the framer device.
Since wakeup precedure is controller-specific, framework calls it via
controller's function pointer to invoke it.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/Makefile    |   2 +-
 drivers/slimbus/core.c      |  16 ++++++
 drivers/slimbus/messaging.c |  35 +++++++++++-
 drivers/slimbus/sched.c     | 128 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/slimbus/slimbus.h   |  54 +++++++++++++++++++
 5 files changed, 233 insertions(+), 2 deletions(-)
 create mode 100644 drivers/slimbus/sched.c

diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index dfa049a382ef..043402eae5be 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -2,4 +2,4 @@
 # Makefile for kernel slimbus framework.
 #
 obj-$(CONFIG_SLIMBUS)			+= slimbus.o
-slimbus-y				:= core.o messaging.o
+slimbus-y				:= core.o messaging.o sched.o
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index f7b14961c7e3..fa0ae157d6b0 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <linux/slimbus.h>
 #include "slimbus.h"
 
@@ -235,6 +236,8 @@ int slim_register_controller(struct slim_controller *ctrl)
 	ida_init(&ctrl->laddr_ida);
 	idr_init(&ctrl->tid_idr);
 	mutex_init(&ctrl->lock);
+	mutex_init(&ctrl->sched.m_reconf);
+	init_completion(&ctrl->sched.pause_comp);
 
 	dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n",
 		ctrl->name, ctrl->dev);
@@ -266,6 +269,8 @@ int slim_unregister_controller(struct slim_controller *ctrl)
 {
 	/* Remove all clients */
 	device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device);
+	/* Enter Clock Pause */
+	slim_ctrl_clk_pause(ctrl, false, 0);
 	ida_simple_remove(&ctrl_ida, ctrl->id);
 
 	return 0;
@@ -432,6 +437,14 @@ int slim_device_report_present(struct slim_controller *ctrl,
 	struct slim_device *sbdev;
 	int ret;
 
+	ret = pm_runtime_get_sync(ctrl->dev);
+
+	if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
+		dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
+				    ctrl->sched.clk_state, ret);
+		goto slimbus_not_active;
+	}
+
 	sbdev = slim_get_device(ctrl, e_addr);
 	if (IS_ERR(sbdev))
 		return -ENODEV;
@@ -443,6 +456,9 @@ int slim_device_report_present(struct slim_controller *ctrl,
 
 	ret = slim_device_alloc_laddr(sbdev, laddr, true);
 
+slimbus_not_active:
+	pm_runtime_mark_last_busy(ctrl->dev);
+	pm_runtime_put_autosuspend(ctrl->dev);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(slim_device_report_present);
diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c
index ba78c1bfe15d..c11534eaf97b 100644
--- a/drivers/slimbus/messaging.c
+++ b/drivers/slimbus/messaging.c
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 #include "slimbus.h"
 
 /**
@@ -52,6 +53,10 @@ void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
 	memcpy(msg->rbuf, reply, len);
 	if (txn->comp)
 		complete(txn->comp);
+
+	/* Remove runtime-pm vote now that response was received for TID txn */
+	pm_runtime_mark_last_busy(ctrl->dev);
+	pm_runtime_put_autosuspend(ctrl->dev);
 }
 EXPORT_SYMBOL_GPL(slim_msg_response);
 
@@ -73,10 +78,29 @@ EXPORT_SYMBOL_GPL(slim_msg_response);
 int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
 {
 	DECLARE_COMPLETION_ONSTACK(done);
-	bool need_tid;
+	bool need_tid = false, clk_pause_msg = false;
 	unsigned long flags;
 	int ret, tid, timeout;
 
+	/*
+	 * do not vote for runtime-PM if the transactions are part of clock
+	 * pause sequence
+	 */
+	if (ctrl->sched.clk_state == SLIM_CLK_ENTERING_PAUSE &&
+		(txn->mt == SLIM_MSG_MT_CORE &&
+		 txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
+		 txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW))
+		clk_pause_msg = true;
+
+	if (!clk_pause_msg) {
+		ret = pm_runtime_get_sync(ctrl->dev);
+		if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
+			dev_err(ctrl->dev, "ctrl wrong state:%d, ret:%d\n",
+				ctrl->sched.clk_state, ret);
+			goto slim_xfer_err;
+		}
+	}
+
 	need_tid = slim_tid_txn(txn->mt, txn->mc);
 
 	if (need_tid) {
@@ -115,6 +139,15 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
 		dev_err(ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
 			txn->mt, txn->mc, txn->la, ret);
 
+slim_xfer_err:
+	if (!clk_pause_msg && (!need_tid  || ret == -ETIMEDOUT)) {
+		/*
+		 * remove runtime-pm vote if this was TX only, or
+		 * if there was error during this transaction
+		 */
+		pm_runtime_mark_last_busy(ctrl->dev);
+		pm_runtime_mark_last_busy(ctrl->dev);
+	}
 	return ret;
 }
 
diff --git a/drivers/slimbus/sched.c b/drivers/slimbus/sched.c
new file mode 100644
index 000000000000..74300f1a6898
--- /dev/null
+++ b/drivers/slimbus/sched.c
@@ -0,0 +1,128 @@
+/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/errno.h>
+#include "slimbus.h"
+
+/**
+ * slim_ctrl_clk_pause() - Called by slimbus controller to enter/exit
+ *			   'clock pause'
+ * @ctrl: controller requesting bus to be paused or woken up
+ * @wakeup: Wakeup this controller from clock pause.
+ * @restart: Restart time value per spec used for clock pause. This value
+ *	isn't used when controller is to be woken up.
+ *
+ * Slimbus specification needs this sequence to turn-off clocks for the bus.
+ * The sequence involves sending 3 broadcast messages (reconfiguration
+ * sequence) to inform all devices on the bus.
+ * To exit clock-pause, controller typically wakes up active framer device.
+ * This API executes clock pause reconfiguration sequence if wakeup is false.
+ * If wakeup is true, controller's wakeup is called.
+ * For entering clock-pause, -EBUSY is returned if a message txn in pending.
+ */
+int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart)
+{
+	int i, ret = 0;
+	unsigned long flags;
+	struct slim_sched *sched = &ctrl->sched;
+	struct slim_val_inf msg = {0, 0, NULL, NULL};
+
+	DEFINE_SLIM_BCAST_TXN(txn, SLIM_MSG_MC_BEGIN_RECONFIGURATION,
+				3, SLIM_LA_MANAGER, &msg);
+
+	if (wakeup == false && restart > SLIM_CLK_UNSPECIFIED)
+		return -EINVAL;
+
+	mutex_lock(&sched->m_reconf);
+	if (wakeup) {
+		if (sched->clk_state == SLIM_CLK_ACTIVE) {
+			mutex_unlock(&sched->m_reconf);
+			return 0;
+		}
+
+		/*
+		 * Fine-tune calculation based on clock gear,
+		 * message-bandwidth after bandwidth management
+		 */
+		ret = wait_for_completion_timeout(&sched->pause_comp,
+				msecs_to_jiffies(100));
+		if (!ret) {
+			mutex_unlock(&sched->m_reconf);
+			pr_err("Previous clock pause did not finish");
+			return -ETIMEDOUT;
+		}
+		ret = 0;
+
+		/*
+		 * Slimbus framework will call controller wakeup
+		 * Controller should make sure that it sets active framer
+		 * out of clock pause
+		 */
+		if (sched->clk_state == SLIM_CLK_PAUSED && ctrl->wakeup)
+			ret = ctrl->wakeup(ctrl);
+		if (!ret)
+			sched->clk_state = SLIM_CLK_ACTIVE;
+		mutex_unlock(&sched->m_reconf);
+
+		return ret;
+	}
+
+	/* already paused */
+	if (ctrl->sched.clk_state == SLIM_CLK_PAUSED) {
+		mutex_unlock(&sched->m_reconf);
+		return 0;
+	}
+
+	spin_lock_irqsave(&ctrl->txn_lock, flags);
+	for (i = 0; i < SLIM_MAX_TIDS; i++) {
+		/* Pending response for a message */
+		if (idr_find(&ctrl->tid_idr, i)) {
+			spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+			mutex_unlock(&sched->m_reconf);
+			return -EBUSY;
+		}
+	}
+	spin_unlock_irqrestore(&ctrl->txn_lock, flags);
+
+	sched->clk_state = SLIM_CLK_ENTERING_PAUSE;
+
+	/* clock pause sequence */
+	ret = slim_do_transfer(ctrl, &txn);
+	if (ret)
+		goto clk_pause_ret;
+
+	txn.mc = SLIM_MSG_MC_NEXT_PAUSE_CLOCK;
+	txn.rl = 4;
+	msg.num_bytes = 1;
+	msg.wbuf = &restart;
+	ret = slim_do_transfer(ctrl, &txn);
+	if (ret)
+		goto clk_pause_ret;
+
+	txn.mc = SLIM_MSG_MC_RECONFIGURE_NOW;
+	txn.rl = 3;
+	msg.num_bytes = 1;
+	msg.wbuf = NULL;
+	ret = slim_do_transfer(ctrl, &txn);
+
+clk_pause_ret:
+	if (ret) {
+		sched->clk_state = SLIM_CLK_ACTIVE;
+	} else {
+		sched->clk_state = SLIM_CLK_PAUSED;
+		complete(&sched->pause_comp);
+	}
+	mutex_unlock(&sched->m_reconf);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(slim_ctrl_clk_pause);
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index f3ed5d4dbb0a..4fe1892cbd4f 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -35,6 +35,16 @@
 #define SLIM_MSG_MC_REPLY_VALUE                  0x64
 #define SLIM_MSG_MC_CHANGE_VALUE                 0x68
 
+/* Clock pause Reconfiguration messages */
+#define SLIM_MSG_MC_BEGIN_RECONFIGURATION        0x40
+#define SLIM_MSG_MC_NEXT_PAUSE_CLOCK             0x4A
+#define SLIM_MSG_MC_RECONFIGURE_NOW              0x5F
+
+/* Clock pause values per slimbus spec */
+#define SLIM_CLK_FAST				0
+#define SLIM_CLK_CONST_PHASE			1
+#define SLIM_CLK_UNSPECIFIED			2
+
 /* Destination type Values */
 #define SLIM_MSG_DEST_LOGICALADDR	0
 #define SLIM_MSG_DEST_ENUMADDR		1
@@ -102,6 +112,43 @@ struct slim_msg_txn {
 #define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \
 	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\
 					0, la, msg, }
+
+#define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \
+	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\
+					0, la, msg, }
+/**
+ * enum slim_clk_state: Slimbus controller's clock state used internally for
+ *	maintaining current clock state.
+ * @SLIM_CLK_ACTIVE: Slimbus clock is active
+ * @SLIM_CLK_ENTERING_PAUSE: Slimbus clock pause sequence is being sent on the
+ *	bus. If this succeeds, state changes to SLIM_CLK_PAUSED. If the
+ *	transition fails, state changes back to SLIM_CLK_ACTIVE
+ * @SLIM_CLK_PAUSED: Slimbus controller clock has paused.
+ */
+enum slim_clk_state {
+	SLIM_CLK_ACTIVE,
+	SLIM_CLK_ENTERING_PAUSE,
+	SLIM_CLK_PAUSED,
+};
+
+/**
+ * struct slim_sched: Framework uses this structure internally for scheduling.
+ * @clk_state: Controller's clock state from enum slim_clk_state
+ * @pause_comp: Signals completion of clock pause sequence. This is useful when
+ *	client tries to call slimbus transaction when controller is entering
+ *	clock pause.
+ * @m_reconf: This mutex is held until current reconfiguration (data channel
+ *	scheduling, message bandwidth reservation) is done. Message APIs can
+ *	use the bus concurrently when this mutex is held since elemental access
+ *	messages can be sent on the bus when reconfiguration is in progress.
+ */
+struct slim_sched {
+	int			clkgear;
+	enum slim_clk_state	clk_state;
+	struct completion	pause_comp;
+	struct mutex		m_reconf;
+};
+
 /**
  * struct slim_controller  - Controls every instance of SLIMbus
  *				(similar to 'master' on SPI)
@@ -118,6 +165,7 @@ struct slim_msg_txn {
  * @devices: Slim device list
  * @tid_idr: tid id allocator
  * @txn_lock: Lock to protect table of transactions
+ * @sched: scheduler structure used by the controller
  * @xfer_msg: Transfer a message on this controller (this can be a broadcast
  *	control/status message like data channel setup, or a unicast message
  *	like value element read/write.
@@ -128,6 +176,9 @@ struct slim_msg_txn {
  *	address table and get_laddr can be used in that case so that controller
  *	can do this assignment. Use case is when the master is on the remote
  *	processor side, who is resposible for allocating laddr.
+ * @wakeup: This function pointer implements controller-specific procedure
+ *	to wake it up from clock-pause. Framework will call this to bring
+ *	the controller out of clock pause.
  *
  *	'Manager device' is responsible for  device management, bandwidth
  *	allocation, channel setup, and port associations per channel.
@@ -162,12 +213,14 @@ struct slim_controller {
 	struct list_head	devices;
 	struct idr		tid_idr;
 	spinlock_t		txn_lock;
+	struct slim_sched	sched;
 	int			(*xfer_msg)(struct slim_controller *ctrl,
 					    struct slim_msg_txn *tx);
 	int			(*set_laddr)(struct slim_controller *ctrl,
 					     struct slim_eaddr *ea, u8 laddr);
 	int			(*get_laddr)(struct slim_controller *ctrl,
 					     struct slim_eaddr *ea, u8 *laddr);
+	int			(*wakeup)(struct slim_controller *ctrl);
 };
 
 int slim_device_report_present(struct slim_controller *ctrl,
@@ -177,6 +230,7 @@ int slim_register_controller(struct slim_controller *ctrl);
 int slim_unregister_controller(struct slim_controller *ctrl);
 void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l);
 int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn);
+int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart);
 
 static inline bool slim_tid_txn(u8 mt, u8 mc)
 {
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 08/13] regmap: add SLIMbus support
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10   ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: mark.rutland, michael.opdenacker, poeschel, Srinivas Kandagatla,
	andreas.noever, arnd, vinod.koul, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

This patch adds support to read/write slimbus value elements.
Currently it only supports byte read/write. Adding this support in
regmap would give codec drivers more flexibility when there are more
than 2 control interfaces like slimbus, i2c.

Without this patch each codec driver has to directly call slimbus value
element apis, and this could would get messy once we want to add i2c
interface to it.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/base/regmap/Kconfig          |  4 ++
 drivers/base/regmap/Makefile         |  1 +
 drivers/base/regmap/regmap-slimbus.c | 95 ++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h               | 18 +++++++
 4 files changed, 118 insertions(+)
 create mode 100644 drivers/base/regmap/regmap-slimbus.c

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 0368fd7b3a41..344440768205 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -20,6 +20,10 @@ config REGMAP_I2C
 	tristate
 	depends on I2C
 
+config REGMAP_SLIMBUS
+	tristate
+	depends on SLIMBUS
+
 config REGMAP_SPI
 	tristate
 	depends on SPI
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index 0d298c446108..63dec9222892 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
 obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
+obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
 obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
 obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
diff --git a/drivers/base/regmap/regmap-slimbus.c b/drivers/base/regmap/regmap-slimbus.c
new file mode 100644
index 000000000000..bbccad3f8b3a
--- /dev/null
+++ b/drivers/base/regmap/regmap-slimbus.c
@@ -0,0 +1,95 @@
+/*
+ * Register map access API - slimbus support
+ *
+ * Copyright 2017 Linaro Inc
+ *
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+ *
+ * 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.
+ */
+
+#include <linux/regmap.h>
+#include <linux/slimbus.h>
+#include <linux/module.h>
+
+#include "internal.h"
+
+static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
+					unsigned int *val)
+{
+	struct slim_device *sdev = context;
+	int v;
+
+	if (!sdev)
+		return 0;
+
+	v = slim_readb(sdev, reg);
+
+	if (v < 0)
+		return v;
+
+	*val = v;
+
+	return 0;
+}
+
+static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
+					 unsigned int val)
+{
+	struct slim_device *sdev = context;
+
+	if (!sdev)
+		return 0;
+
+	return slim_writeb(sdev, reg, val);
+}
+
+static struct regmap_bus regmap_slimbus_bus = {
+	.reg_write = regmap_slimbus_byte_reg_write,
+	.reg_read = regmap_slimbus_byte_reg_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+	.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static const struct regmap_bus *regmap_get_slimbus(struct slim_device *slim,
+					const struct regmap_config *config)
+{
+	if (config->val_bits == 8 && config->reg_bits == 8)
+		return &regmap_slimbus_bus;
+
+	return ERR_PTR(-ENOTSUPP);
+}
+
+struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
+				     const struct regmap_config *config,
+				     struct lock_class_key *lock_key,
+				     const char *lock_name)
+{
+	const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
+
+	if (IS_ERR(bus))
+		return ERR_CAST(bus);
+
+	return __regmap_init(&slimbus->dev, bus, &slimbus->dev, config,
+			     lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__regmap_init_slimbus);
+
+struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus,
+					  const struct regmap_config *config,
+					  struct lock_class_key *lock_key,
+					  const char *lock_name)
+{
+	const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
+
+	if (IS_ERR(bus))
+		return ERR_CAST(bus);
+
+	return __devm_regmap_init(&slimbus->dev, bus, &slimbus, config,
+				  lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__devm_regmap_init_slimbus);
+
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 978abfbac617..49c8db1dd0ce 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -24,6 +24,7 @@ struct module;
 struct device;
 struct i2c_client;
 struct irq_domain;
+struct slim_device;
 struct spi_device;
 struct spmi_device;
 struct regmap;
@@ -449,6 +450,10 @@ struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
 				 const struct regmap_config *config,
 				 struct lock_class_key *lock_key,
 				 const char *lock_name);
+struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name);
 struct regmap *__regmap_init_spi(struct spi_device *dev,
 				 const struct regmap_config *config,
 				 struct lock_class_key *lock_key,
@@ -565,6 +570,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
 	__regmap_lockdep_wrapper(__regmap_init_i2c, #config,		\
 				i2c, config)
 
+/**
+ * regmap_init_slimbus() - Initialise register map
+ *
+ * @slimbus: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_slimbus(slimbus, config)				\
+	__regmap_lockdep_wrapper(__regmap_init_slimbus, #config,	\
+				slimbus, config)
+
 /**
  * regmap_init_spi() - Initialise register map
  *
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 08/13] regmap: add SLIMbus support
@ 2017-11-15 14:10   ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

This patch adds support to read/write slimbus value elements.
Currently it only supports byte read/write. Adding this support in
regmap would give codec drivers more flexibility when there are more
than 2 control interfaces like slimbus, i2c.

Without this patch each codec driver has to directly call slimbus value
element apis, and this could would get messy once we want to add i2c
interface to it.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/base/regmap/Kconfig          |  4 ++
 drivers/base/regmap/Makefile         |  1 +
 drivers/base/regmap/regmap-slimbus.c | 95 ++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h               | 18 +++++++
 4 files changed, 118 insertions(+)
 create mode 100644 drivers/base/regmap/regmap-slimbus.c

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 0368fd7b3a41..344440768205 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -20,6 +20,10 @@ config REGMAP_I2C
 	tristate
 	depends on I2C
 
+config REGMAP_SLIMBUS
+	tristate
+	depends on SLIMBUS
+
 config REGMAP_SPI
 	tristate
 	depends on SPI
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index 0d298c446108..63dec9222892 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
 obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
+obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
 obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
 obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
diff --git a/drivers/base/regmap/regmap-slimbus.c b/drivers/base/regmap/regmap-slimbus.c
new file mode 100644
index 000000000000..bbccad3f8b3a
--- /dev/null
+++ b/drivers/base/regmap/regmap-slimbus.c
@@ -0,0 +1,95 @@
+/*
+ * Register map access API - slimbus support
+ *
+ * Copyright 2017 Linaro Inc
+ *
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+ *
+ * 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.
+ */
+
+#include <linux/regmap.h>
+#include <linux/slimbus.h>
+#include <linux/module.h>
+
+#include "internal.h"
+
+static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
+					unsigned int *val)
+{
+	struct slim_device *sdev = context;
+	int v;
+
+	if (!sdev)
+		return 0;
+
+	v = slim_readb(sdev, reg);
+
+	if (v < 0)
+		return v;
+
+	*val = v;
+
+	return 0;
+}
+
+static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
+					 unsigned int val)
+{
+	struct slim_device *sdev = context;
+
+	if (!sdev)
+		return 0;
+
+	return slim_writeb(sdev, reg, val);
+}
+
+static struct regmap_bus regmap_slimbus_bus = {
+	.reg_write = regmap_slimbus_byte_reg_write,
+	.reg_read = regmap_slimbus_byte_reg_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+	.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static const struct regmap_bus *regmap_get_slimbus(struct slim_device *slim,
+					const struct regmap_config *config)
+{
+	if (config->val_bits == 8 && config->reg_bits == 8)
+		return &regmap_slimbus_bus;
+
+	return ERR_PTR(-ENOTSUPP);
+}
+
+struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
+				     const struct regmap_config *config,
+				     struct lock_class_key *lock_key,
+				     const char *lock_name)
+{
+	const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
+
+	if (IS_ERR(bus))
+		return ERR_CAST(bus);
+
+	return __regmap_init(&slimbus->dev, bus, &slimbus->dev, config,
+			     lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__regmap_init_slimbus);
+
+struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus,
+					  const struct regmap_config *config,
+					  struct lock_class_key *lock_key,
+					  const char *lock_name)
+{
+	const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
+
+	if (IS_ERR(bus))
+		return ERR_CAST(bus);
+
+	return __devm_regmap_init(&slimbus->dev, bus, &slimbus, config,
+				  lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__devm_regmap_init_slimbus);
+
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 978abfbac617..49c8db1dd0ce 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -24,6 +24,7 @@ struct module;
 struct device;
 struct i2c_client;
 struct irq_domain;
+struct slim_device;
 struct spi_device;
 struct spmi_device;
 struct regmap;
@@ -449,6 +450,10 @@ struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
 				 const struct regmap_config *config,
 				 struct lock_class_key *lock_key,
 				 const char *lock_name);
+struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name);
 struct regmap *__regmap_init_spi(struct spi_device *dev,
 				 const struct regmap_config *config,
 				 struct lock_class_key *lock_key,
@@ -565,6 +570,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
 	__regmap_lockdep_wrapper(__regmap_init_i2c, #config,		\
 				i2c, config)
 
+/**
+ * regmap_init_slimbus() - Initialise register map
+ *
+ * @slimbus: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_slimbus(slimbus, config)				\
+	__regmap_lockdep_wrapper(__regmap_init_slimbus, #config,	\
+				slimbus, config)
+
 /**
  * regmap_init_spi() - Initialise register map
  *
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 09/13] slimbus: core: add common defines required for controllers
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10   ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: mark.rutland, michael.opdenacker, poeschel, Srinivas Kandagatla,
	andreas.noever, arnd, vinod.koul, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

This patch adds some common constant defines which are required
for qcom slim controller driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/slimbus.h | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index 4fe1892cbd4f..e1fc6d23f374 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -18,9 +18,37 @@
 #include <linux/completion.h>
 #include <linux/slimbus.h>
 
+/* Standard values per SLIMbus spec needed by controllers and devices */
+#define SLIM_CL_PER_SUPERFRAME		6144
+#define SLIM_CL_PER_SUPERFRAME_DIV8	(SLIM_CL_PER_SUPERFRAME >> 3)
+
 /* SLIMbus message types. Related to interpretation of message code. */
 #define SLIM_MSG_MT_CORE			0x0
 
+/*
+ * SLIM Broadcast header format
+ * BYTE 0: MT[7:5] RL[4:0]
+ * BYTE 1: RSVD[7] MC[6:0]
+ * BYTE 2: RSVD[7:6] DT[5:4] PI[3:0]
+ */
+#define SLIM_MSG_MT_MASK	GENMASK(2, 0)
+#define SLIM_MSG_MT_SHIFT	5
+#define SLIM_MSG_RL_MASK	GENMASK(4, 0)
+#define SLIM_MSG_RL_SHIFT	0
+#define SLIM_MSG_MC_MASK	GENMASK(6, 0)
+#define SLIM_MSG_MC_SHIFT	0
+#define SLIM_MSG_DT_MASK	GENMASK(1, 0)
+#define SLIM_MSG_DT_SHIFT	4
+
+#define SLIM_HEADER_GET_MT(b)	((b >> SLIM_MSG_MT_SHIFT) & SLIM_MSG_MT_MASK)
+#define SLIM_HEADER_GET_RL(b)	((b >> SLIM_MSG_RL_SHIFT) & SLIM_MSG_RL_MASK)
+#define SLIM_HEADER_GET_MC(b)	((b >> SLIM_MSG_MC_SHIFT) & SLIM_MSG_MC_MASK)
+#define SLIM_HEADER_GET_DT(b)	((b >> SLIM_MSG_DT_SHIFT) & SLIM_MSG_DT_MASK)
+
+/* Device management messages used by this framework */
+#define SLIM_MSG_MC_REPORT_PRESENT               0x1
+#define SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS       0x2
+#define SLIM_MSG_MC_REPORT_ABSENT                0xF
 
 /* Information Element management messages */
 #define SLIM_MSG_MC_REQUEST_INFORMATION          0x20
@@ -116,6 +144,10 @@ struct slim_msg_txn {
 #define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \
 	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\
 					0, la, msg, }
+
+#define DEFINE_SLIM_EDEST_TXN(name, mc, rl, la, msg) \
+	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_ENUMADDR, 0,\
+					0, la, msg, }
 /**
  * enum slim_clk_state: Slimbus controller's clock state used internally for
  *	maintaining current clock state.
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 09/13] slimbus: core: add common defines required for controllers
@ 2017-11-15 14:10   ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

This patch adds some common constant defines which are required
for qcom slim controller driver.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/slimbus.h | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index 4fe1892cbd4f..e1fc6d23f374 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -18,9 +18,37 @@
 #include <linux/completion.h>
 #include <linux/slimbus.h>
 
+/* Standard values per SLIMbus spec needed by controllers and devices */
+#define SLIM_CL_PER_SUPERFRAME		6144
+#define SLIM_CL_PER_SUPERFRAME_DIV8	(SLIM_CL_PER_SUPERFRAME >> 3)
+
 /* SLIMbus message types. Related to interpretation of message code. */
 #define SLIM_MSG_MT_CORE			0x0
 
+/*
+ * SLIM Broadcast header format
+ * BYTE 0: MT[7:5] RL[4:0]
+ * BYTE 1: RSVD[7] MC[6:0]
+ * BYTE 2: RSVD[7:6] DT[5:4] PI[3:0]
+ */
+#define SLIM_MSG_MT_MASK	GENMASK(2, 0)
+#define SLIM_MSG_MT_SHIFT	5
+#define SLIM_MSG_RL_MASK	GENMASK(4, 0)
+#define SLIM_MSG_RL_SHIFT	0
+#define SLIM_MSG_MC_MASK	GENMASK(6, 0)
+#define SLIM_MSG_MC_SHIFT	0
+#define SLIM_MSG_DT_MASK	GENMASK(1, 0)
+#define SLIM_MSG_DT_SHIFT	4
+
+#define SLIM_HEADER_GET_MT(b)	((b >> SLIM_MSG_MT_SHIFT) & SLIM_MSG_MT_MASK)
+#define SLIM_HEADER_GET_RL(b)	((b >> SLIM_MSG_RL_SHIFT) & SLIM_MSG_RL_MASK)
+#define SLIM_HEADER_GET_MC(b)	((b >> SLIM_MSG_MC_SHIFT) & SLIM_MSG_MC_MASK)
+#define SLIM_HEADER_GET_DT(b)	((b >> SLIM_MSG_DT_SHIFT) & SLIM_MSG_DT_MASK)
+
+/* Device management messages used by this framework */
+#define SLIM_MSG_MC_REPORT_PRESENT               0x1
+#define SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS       0x2
+#define SLIM_MSG_MC_REPORT_ABSENT                0xF
 
 /* Information Element management messages */
 #define SLIM_MSG_MC_REQUEST_INFORMATION          0x20
@@ -116,6 +144,10 @@ struct slim_msg_txn {
 #define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \
 	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\
 					0, la, msg, }
+
+#define DEFINE_SLIM_EDEST_TXN(name, mc, rl, la, msg) \
+	struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_ENUMADDR, 0,\
+					0, la, msg, }
 /**
  * enum slim_clk_state: Slimbus controller's clock state used internally for
  *	maintaining current clock state.
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings
  2017-11-15 14:10 ` srinivas.kandagatla
                   ` (8 preceding siblings ...)
  (?)
@ 2017-11-15 14:10 ` srinivas.kandagatla
  2017-11-16  5:19     ` Rob Herring
  -1 siblings, 1 reply; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

This patch add device tree bindings for Qualcomm slimbus controller.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 .../devicetree/bindings/slimbus/slim-qcom-ctrl.txt | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt

diff --git a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
new file mode 100644
index 000000000000..e4d28910b2e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
@@ -0,0 +1,43 @@
+Qualcomm SLIMBUS controller
+This controller is used if applications processor driver controls slimbus
+master component.
+
+Required properties:
+
+ - #address-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt
+ - #size-cells	- refer to Documentation/devicetree/bindings/slimbus/bus.txt
+
+ - reg : Offset and length of the register region(s) for the device
+ - reg-names : Register region name(s) referenced in reg above
+	 Required register resource entries are:
+	 "ctrl": Physical address of controller register blocks
+ - compatible : should be "qcom,<SOC-NAME>-slim" for SOC specific compatible
+ 		followed by "qcom,slim" for fallback.
+ - interrupts : Interrupt number used by this controller
+ - clocks : Interface and core clocks used by this slimbus controller
+ - clock-names : Required clock-name entries are:
+	"iface_clk" : Interface clock for this controller
+	"core_clk" : Interrupt for controller core's BAM
+
+
+Optional property:
+ - reg entry for slew rate : If slew rate control register is provided, this
+	entry should be used.
+ - reg-name for slew rate: "slew"
+
+Example:
+
+	slim@28080000 {
+		compatible = "qcom,apq8064-slim", "qcom,slim";
+		reg = <0x28080000 0x2000>,
+		interrupts = <0 33 0>;
+		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
+		clock-names = "iface", "core";
+		#address-cells = <2>;
+		#size-cell = <0>;
+
+		codec: wcd9310@1,0{
+			compatible = "slim217,60";
+			reg = <1 0>;
+		};
+	};
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10     ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, arnd-r2nGTMty4D4,
	Srinivas Kandagatla

From: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

This controller driver programs manager, interface, and framer
devices for Qualcomm's slimbus HW block.
Manager component currently implements logical address setting,
and messaging interface.
Interface device reports bus synchronization information, and framer
device clocks the bus from the time it's woken up, until clock-pause
is executed by the manager device.

Signed-off-by: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/slimbus/Kconfig     |   6 +
 drivers/slimbus/Makefile    |   4 +
 drivers/slimbus/qcom-ctrl.c | 684 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 694 insertions(+)
 create mode 100644 drivers/slimbus/qcom-ctrl.c

diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig
index 9c7d3c61656a..9c8d59290634 100644
--- a/drivers/slimbus/Kconfig
+++ b/drivers/slimbus/Kconfig
@@ -12,5 +12,11 @@ menuconfig SLIMBUS
 if SLIMBUS
 
 # SlIMbus controllers
+config SLIM_QCOM_CTRL
+	tristate "Qualcomm Slimbus Manager Component"
+	depends on SLIMBUS
+	help
+	  Select driver if Qualcomm's Slimbus Manager Component is
+	  programmed using Linux kernel.
 
 endif
diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index 043402eae5be..9a70c7c70aae 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -3,3 +3,7 @@
 #
 obj-$(CONFIG_SLIMBUS)			+= slimbus.o
 slimbus-y				:= core.o messaging.o sched.o
+
+#Controllers
+obj-$(CONFIG_SLIM_QCOM_CTRL)		+= slim-qcom-ctrl.o
+slim-qcom-ctrl-y			:= qcom-ctrl.o
diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c
new file mode 100644
index 000000000000..25c1974f04ec
--- /dev/null
+++ b/drivers/slimbus/qcom-ctrl.c
@@ -0,0 +1,684 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/dma-mapping.h>
+#include "slimbus.h"
+
+/* Manager registers */
+#define	MGR_CFG		0x200
+#define	MGR_STATUS	0x204
+#define	MGR_INT_EN	0x210
+#define	MGR_INT_STAT	0x214
+#define	MGR_INT_CLR	0x218
+#define	MGR_TX_MSG	0x230
+#define	MGR_RX_MSG	0x270
+#define	MGR_IE_STAT	0x2F0
+#define	MGR_VE_STAT	0x300
+#define	MGR_CFG_ENABLE	1
+
+/* Framer registers */
+#define	FRM_CFG		0x400
+#define	FRM_STAT	0x404
+#define	FRM_INT_EN	0x410
+#define	FRM_INT_STAT	0x414
+#define	FRM_INT_CLR	0x418
+#define	FRM_WAKEUP	0x41C
+#define	FRM_CLKCTL_DONE	0x420
+#define	FRM_IE_STAT	0x430
+#define	FRM_VE_STAT	0x440
+
+/* Interface registers */
+#define	INTF_CFG	0x600
+#define	INTF_STAT	0x604
+#define	INTF_INT_EN	0x610
+#define	INTF_INT_STAT	0x614
+#define	INTF_INT_CLR	0x618
+#define	INTF_IE_STAT	0x630
+#define	INTF_VE_STAT	0x640
+
+/* Interrupt status bits */
+#define	MGR_INT_TX_NACKED_2	BIT(25)
+#define	MGR_INT_MSG_BUF_CONTE	BIT(26)
+#define	MGR_INT_RX_MSG_RCVD	BIT(30)
+#define	MGR_INT_TX_MSG_SENT	BIT(31)
+
+/* Framer config register settings */
+#define	FRM_ACTIVE	1
+#define	CLK_GEAR	7
+#define	ROOT_FREQ	11
+#define	REF_CLK_GEAR	15
+#define	INTR_WAKE	19
+
+#define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \
+		((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
+
+#define SLIM_ROOT_FREQ 24576000
+
+/* MAX message size over control channel */
+#define SLIM_MSGQ_BUF_LEN	40
+#define QCOM_TX_MSGS 2
+#define QCOM_RX_MSGS	8
+#define QCOM_BUF_ALLOC_RETRIES	10
+
+#define CFG_PORT(r, v) ((v) ? CFG_PORT_V2(r) : CFG_PORT_V1(r))
+
+/* V2 Component registers */
+#define CFG_PORT_V2(r) ((r ## _V2))
+#define	COMP_CFG_V2		4
+#define	COMP_TRUST_CFG_V2	0x3000
+
+/* V1 Component registers */
+#define CFG_PORT_V1(r) ((r ## _V1))
+#define	COMP_CFG_V1		0
+#define	COMP_TRUST_CFG_V1	0x14
+
+/* Resource group info for manager, and non-ported generic device-components */
+#define EE_MGR_RSC_GRP	(1 << 10)
+#define EE_NGD_2	(2 << 6)
+#define EE_NGD_1	0
+
+struct slim_ctrl_buf {
+	void		*base;
+	phys_addr_t	phy;
+	spinlock_t	lock;
+	int		head;
+	int		tail;
+	int		sl_sz;
+	int		n;
+};
+
+struct qcom_slim_ctrl {
+	struct slim_controller  ctrl;
+	struct slim_framer	framer;
+	struct device		*dev;
+	void __iomem		*base;
+	void __iomem		*slew_reg;
+
+	struct slim_ctrl_buf	rx;
+	struct slim_ctrl_buf	tx;
+
+	struct completion	**wr_comp;
+	int			irq;
+	struct workqueue_struct *rxwq;
+	struct work_struct	wd;
+	struct clk		*rclk;
+	struct clk		*hclk;
+};
+
+static void qcom_slim_queue_tx(struct qcom_slim_ctrl *ctrl, void *buf,
+			       u8 len, u32 tx_reg)
+{
+	int count = (len + 3) >> 2;
+
+	__iowrite32_copy(ctrl->base + tx_reg, buf, count);
+
+	/* Ensure Oder of subsequent writes */
+	mb();
+}
+
+static void *slim_alloc_rxbuf(struct qcom_slim_ctrl *ctrl)
+{
+	unsigned long flags;
+	int idx;
+
+	spin_lock_irqsave(&ctrl->rx.lock, flags);
+	if ((ctrl->rx.tail + 1) % ctrl->rx.n == ctrl->rx.head) {
+		spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+		dev_err(ctrl->dev, "RX QUEUE full!");
+		return NULL;
+	}
+	idx = ctrl->rx.tail;
+	ctrl->rx.tail = (ctrl->rx.tail + 1) % ctrl->rx.n;
+	spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+
+	return ctrl->rx.base + (idx * ctrl->rx.sl_sz);
+}
+
+void slim_ack_txn(struct qcom_slim_ctrl *ctrl, int err)
+{
+	struct completion *comp;
+	unsigned long flags;
+	int idx;
+
+	spin_lock_irqsave(&ctrl->tx.lock, flags);
+	idx = ctrl->tx.head;
+	ctrl->tx.head = (ctrl->tx.head + 1) % ctrl->tx.n;
+	spin_unlock_irqrestore(&ctrl->tx.lock, flags);
+
+	comp = ctrl->wr_comp[idx];
+	ctrl->wr_comp[idx] = NULL;
+
+	complete(comp);
+}
+
+static irqreturn_t qcom_slim_handle_tx_irq(struct qcom_slim_ctrl *ctrl,
+					   u32 stat)
+{
+	int err = 0;
+
+	if (stat & MGR_INT_TX_MSG_SENT)
+		writel_relaxed(MGR_INT_TX_MSG_SENT,
+			       ctrl->base + MGR_INT_CLR);
+
+	if (stat & MGR_INT_TX_NACKED_2) {
+		u32 mgr_stat = readl_relaxed(ctrl->base + MGR_STATUS);
+		u32 mgr_ie_stat = readl_relaxed(ctrl->base + MGR_IE_STAT);
+		u32 frm_stat = readl_relaxed(ctrl->base + FRM_STAT);
+		u32 frm_cfg = readl_relaxed(ctrl->base + FRM_CFG);
+		u32 frm_intr_stat = readl_relaxed(ctrl->base + FRM_INT_STAT);
+		u32 frm_ie_stat = readl_relaxed(ctrl->base + FRM_IE_STAT);
+		u32 intf_stat = readl_relaxed(ctrl->base + INTF_STAT);
+		u32 intf_intr_stat = readl_relaxed(ctrl->base + INTF_INT_STAT);
+		u32 intf_ie_stat = readl_relaxed(ctrl->base + INTF_IE_STAT);
+
+		writel_relaxed(MGR_INT_TX_NACKED_2, ctrl->base + MGR_INT_CLR);
+
+		dev_err(ctrl->dev, "TX Nack MGR:int:0x%x, stat:0x%x\n",
+			stat, mgr_stat);
+		dev_err(ctrl->dev, "TX Nack MGR:ie:0x%x\n", mgr_ie_stat);
+		dev_err(ctrl->dev, "TX Nack FRM:int:0x%x, stat:0x%x\n",
+			frm_intr_stat, frm_stat);
+		dev_err(ctrl->dev, "TX Nack FRM:cfg:0x%x, ie:0x%x\n",
+			frm_cfg, frm_ie_stat);
+		dev_err(ctrl->dev, "TX Nack INTF:intr:0x%x, stat:0x%x\n",
+			intf_intr_stat, intf_stat);
+		dev_err(ctrl->dev, "TX Nack INTF:ie:0x%x\n",
+			intf_ie_stat);
+		err = -ENOTCONN;
+	}
+
+	slim_ack_txn(ctrl, err);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qcom_slim_handle_rx_irq(struct qcom_slim_ctrl *ctrl,
+					   u32 stat)
+{
+	u32 *rx_buf, pkt[10];
+	bool q_rx = false;
+	u8 la, *buf, mc, mt, len, *b = (u8 *)&pkt[0];
+	u16 ele;
+
+	pkt[0] = readl_relaxed(ctrl->base + MGR_RX_MSG);
+	mt = SLIM_HEADER_GET_MT(b[0]);
+	len = SLIM_HEADER_GET_RL(b[0]);
+	mc = SLIM_HEADER_GET_MC(b[1]);
+
+	/*
+	 * this message cannot be handled by ISR, so
+	 * let work-queue handle it
+	 */
+	if (mt == SLIM_MSG_MT_CORE &&
+		mc == SLIM_MSG_MC_REPORT_PRESENT)
+		rx_buf = (u32 *)slim_alloc_rxbuf(ctrl);
+	else
+		rx_buf = pkt;
+
+	if (rx_buf == NULL) {
+		dev_err(ctrl->dev, "dropping RX:0x%x due to RX full\n",
+					pkt[0]);
+		goto rx_ret_irq;
+	}
+
+	rx_buf[0] = pkt[0];
+	__ioread32_copy(rx_buf + 1, ctrl->base + MGR_RX_MSG + 4,
+			DIV_ROUND_UP(len, 4));
+
+	switch (mc) {
+
+	case SLIM_MSG_MC_REPORT_PRESENT:
+		q_rx = true;
+		break;
+	case SLIM_MSG_MC_REPLY_INFORMATION:
+	case SLIM_MSG_MC_REPLY_VALUE:
+		slim_msg_response(&ctrl->ctrl, (u8 *)(rx_buf + 1),
+				  (u8)(*rx_buf >> 24), (len - 4));
+		break;
+	case SLIM_MSG_MC_REPORT_INFORMATION:
+		buf = (u8 *)rx_buf;
+		la = buf[2];
+		ele = (u16)buf[4] << 4;
+
+		ele |= ((buf[3] & 0xf0) >> 4);
+		/*
+		 * report information is most likely loss of
+		 * sync or collision detected in data slots
+		 */
+		dev_info(ctrl->dev, "LA:%d report inf ele:0x%x\n",
+			 la, ele);
+		break;
+	default:
+		dev_err(ctrl->dev, "unsupported MC,%x MT:%x\n",
+			mc, mt);
+		break;
+	}
+rx_ret_irq:
+	writel(MGR_INT_RX_MSG_RCVD, ctrl->base +
+		       MGR_INT_CLR);
+	if (q_rx)
+		queue_work(ctrl->rxwq, &ctrl->wd);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qcom_slim_interrupt(int irq, void *d)
+{
+	struct qcom_slim_ctrl *ctrl = d;
+	u32 stat = readl_relaxed(ctrl->base + MGR_INT_STAT);
+	int ret = IRQ_NONE;
+
+	if (stat & MGR_INT_TX_MSG_SENT || stat & MGR_INT_TX_NACKED_2)
+		ret = qcom_slim_handle_tx_irq(ctrl, stat);
+
+	if (stat & MGR_INT_RX_MSG_RCVD)
+		ret = qcom_slim_handle_rx_irq(ctrl, stat);
+
+	return ret;
+}
+
+void *slim_alloc_txbuf(struct qcom_slim_ctrl *ctrl, struct slim_msg_txn *txn,
+		       struct completion *done)
+{
+	unsigned long flags;
+	int idx;
+
+	spin_lock_irqsave(&ctrl->tx.lock, flags);
+	if (((ctrl->tx.head + 1) % ctrl->tx.n) == ctrl->tx.tail) {
+		spin_unlock_irqrestore(&ctrl->tx.lock, flags);
+		dev_err(ctrl->dev, "controller TX buf unavailable");
+		return NULL;
+	}
+	idx = ctrl->tx.tail;
+	ctrl->wr_comp[idx] = done;
+	ctrl->tx.tail = (ctrl->tx.tail + 1) % ctrl->tx.n;
+
+	spin_unlock_irqrestore(&ctrl->tx.lock, flags);
+
+	return ctrl->tx.base + (idx * ctrl->tx.sl_sz);
+}
+
+
+static int qcom_xfer_msg(struct slim_controller *sctrl,
+			 struct slim_msg_txn *txn)
+{
+	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
+	DECLARE_COMPLETION_ONSTACK(done);
+	void *pbuf = slim_alloc_txbuf(ctrl, txn, &done);
+	unsigned long ms = txn->rl + HZ;
+	u8 *puc;
+	int ret = 0, timeout, retries = QCOM_BUF_ALLOC_RETRIES;
+	u8 la = txn->la;
+	u32 *head;
+	/* HW expects length field to be excluded */
+	txn->rl--;
+
+	/* spin till buffer is made available */
+	if (!pbuf) {
+		while (retries--) {
+			usleep_range(10000, 15000);
+			pbuf = slim_alloc_txbuf(ctrl, txn, &done);
+			if (pbuf)
+				break;
+		}
+	}
+
+	if (!retries && !pbuf)
+		return -ENOMEM;
+
+	puc = (u8 *)pbuf;
+	head = (u32 *)pbuf;
+
+	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
+		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
+						la);
+	else
+		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
+						la);
+
+	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
+		puc += 3;
+	else
+		puc += 2;
+
+	if (txn->mt == SLIM_MSG_MT_CORE && slim_tid_txn(txn->mt, txn->mc))
+		*(puc++) = txn->tid;
+
+	if ((txn->mt == SLIM_MSG_MT_CORE) &&
+		((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
+		txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
+		(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
+		 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
+		*(puc++) = (txn->ec & 0xFF);
+		*(puc++) = (txn->ec >> 8) & 0xFF;
+	}
+
+	if (txn->msg && txn->msg->wbuf)
+		memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
+
+	qcom_slim_queue_tx(ctrl, head, txn->rl, MGR_TX_MSG);
+	timeout = wait_for_completion_timeout(&done, msecs_to_jiffies(ms));
+
+	if (!timeout) {
+		dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
+					txn->mt);
+		ret = -ETIMEDOUT;
+	}
+
+	return ret;
+
+}
+
+static int qcom_set_laddr(struct slim_controller *sctrl,
+				struct slim_eaddr *ead, u8 laddr)
+{
+	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
+	struct {
+		__be16 manf_id;
+		__be16 prod_code;
+		u8 dev_index;
+		u8 instance;
+		u8 laddr;
+	} __packed p;
+	struct slim_val_inf msg = {0};
+	DEFINE_SLIM_EDEST_TXN(txn, SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS,
+			      10, laddr, &msg);
+	int ret;
+
+	p.manf_id = cpu_to_be16(ead->manf_id);
+	p.prod_code = cpu_to_be16(ead->prod_code);
+	p.dev_index = ead->dev_index;
+	p.instance = ead->instance;
+	p.laddr = laddr;
+
+	msg.wbuf = (void *)&p;
+	msg.num_bytes = 7;
+	ret = slim_do_transfer(&ctrl->ctrl, &txn);
+
+	if (ret)
+		dev_err(ctrl->dev, "set LA:0x%x failed:ret:%d\n",
+				  laddr, ret);
+	return ret;
+}
+
+static int slim_get_current_rxbuf(struct qcom_slim_ctrl *ctrl, void *buf)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctrl->rx.lock, flags);
+	if (ctrl->rx.tail == ctrl->rx.head) {
+		spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+		return -ENODATA;
+	}
+	memcpy(buf, ctrl->rx.base + (ctrl->rx.head * ctrl->rx.sl_sz),
+				ctrl->rx.sl_sz);
+
+	ctrl->rx.head = (ctrl->rx.head + 1) % ctrl->rx.n;
+	spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+
+	return 0;
+}
+
+static void qcom_slim_rxwq(struct work_struct *work)
+{
+	u8 buf[SLIM_MSGQ_BUF_LEN];
+	u8 mc, mt, len;
+	int i, ret;
+	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
+						 wd);
+
+	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
+		len = SLIM_HEADER_GET_RL(buf[0]);
+		mt = SLIM_HEADER_GET_MT(buf[0]);
+		mc = SLIM_HEADER_GET_MC(buf[1]);
+		if (mt == SLIM_MSG_MT_CORE &&
+			mc == SLIM_MSG_MC_REPORT_PRESENT) {
+			u8 laddr;
+			struct slim_eaddr ea;
+			u8 e_addr[6];
+
+			for (i = 0; i < 6; i++)
+				e_addr[i] = buf[7-i];
+
+			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
+			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
+			ea.dev_index = e_addr[1];
+			ea.instance = e_addr[0];
+			ret = slim_device_report_present(&ctrl->ctrl,
+							 &ea, &laddr);
+			if (ret < 0)
+				dev_err(ctrl->dev, "assign laddr failed:%d\n",
+					ret);
+		} else {
+			dev_err(ctrl->dev, "unexpected message:mc:%x, mt:%x\n",
+				mc, mt);
+		}
+	}
+}
+
+static void qcom_slim_prg_slew(struct platform_device *pdev,
+				struct qcom_slim_ctrl *ctrl)
+{
+	struct resource	*slew_mem;
+
+	if (!ctrl->slew_reg) {
+		/* SLEW RATE register for this slimbus */
+		slew_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+				"slew");
+		ctrl->slew_reg = devm_ioremap(&pdev->dev, slew_mem->start,
+				resource_size(slew_mem));
+		if (!ctrl->slew_reg)
+			return;
+	}
+
+	writel_relaxed(1, ctrl->slew_reg);
+	/* Make sure slimbus-slew rate enabling goes through */
+	wmb();
+}
+
+static int qcom_slim_probe(struct platform_device *pdev)
+{
+	struct qcom_slim_ctrl *ctrl;
+	struct slim_controller *sctrl;
+	struct resource *slim_mem;
+	int ret, ver;
+
+	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl)
+		return -ENOMEM;
+
+	ctrl->hclk = devm_clk_get(&pdev->dev, "iface");
+	if (IS_ERR(ctrl->hclk))
+		return PTR_ERR(ctrl->hclk);
+
+	ctrl->rclk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(ctrl->rclk))
+		return PTR_ERR(ctrl->rclk);
+
+	ret = clk_set_rate(ctrl->rclk, SLIM_ROOT_FREQ);
+	if (ret) {
+		dev_err(&pdev->dev, "ref-clock set-rate failed:%d\n", ret);
+		return ret;
+	}
+
+	ctrl->irq = platform_get_irq(pdev, 0);
+	if (!ctrl->irq) {
+		dev_err(&pdev->dev, "no slimbus IRQ\n");
+		return -ENODEV;
+	}
+
+	sctrl = &ctrl->ctrl;
+	sctrl->dev = &pdev->dev;
+	ctrl->dev = &pdev->dev;
+	platform_set_drvdata(pdev, ctrl);
+	dev_set_drvdata(ctrl->dev, ctrl);
+
+	slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+	ctrl->base = devm_ioremap_resource(ctrl->dev, slim_mem);
+	if (!ctrl->base) {
+		dev_err(&pdev->dev, "IOremap failed\n");
+		return -ENOMEM;
+	}
+
+	sctrl->set_laddr = qcom_set_laddr;
+	sctrl->xfer_msg = qcom_xfer_msg;
+	ctrl->tx.n = QCOM_TX_MSGS;
+	ctrl->tx.sl_sz = SLIM_MSGQ_BUF_LEN;
+	ctrl->rx.n = QCOM_RX_MSGS;
+	ctrl->rx.sl_sz = SLIM_MSGQ_BUF_LEN;
+	ctrl->wr_comp = kzalloc(sizeof(struct completion *) * QCOM_TX_MSGS,
+				GFP_KERNEL);
+	if (!ctrl->wr_comp)
+		return -ENOMEM;
+
+	spin_lock_init(&ctrl->rx.lock);
+	spin_lock_init(&ctrl->tx.lock);
+	INIT_WORK(&ctrl->wd, qcom_slim_rxwq);
+	ctrl->rxwq = create_singlethread_workqueue("qcom_slim_rx");
+	if (!ctrl->rxwq) {
+		dev_err(ctrl->dev, "Failed to start Rx WQ\n");
+		return -ENOMEM;
+	}
+
+	ctrl->framer.rootfreq = SLIM_ROOT_FREQ / 8;
+	ctrl->framer.superfreq =
+		ctrl->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8;
+	sctrl->a_framer = &ctrl->framer;
+	sctrl->clkgear = SLIM_MAX_CLK_GEAR;
+
+	qcom_slim_prg_slew(pdev, ctrl);
+
+	ret = devm_request_irq(&pdev->dev, ctrl->irq, qcom_slim_interrupt,
+				IRQF_TRIGGER_HIGH, "qcom_slim_irq", ctrl);
+	if (ret) {
+		dev_err(&pdev->dev, "request IRQ failed\n");
+		goto err_request_irq_failed;
+	}
+
+	ret = clk_prepare_enable(ctrl->hclk);
+	if (ret)
+		goto err_hclk_enable_failed;
+
+	ret = clk_prepare_enable(ctrl->rclk);
+	if (ret)
+		goto err_rclk_enable_failed;
+
+	ctrl->tx.base = dmam_alloc_coherent(&pdev->dev,
+					   (ctrl->tx.sl_sz * ctrl->tx.n),
+					   &ctrl->tx.phy, GFP_KERNEL);
+	if (!ctrl->tx.base) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ctrl->rx.base = dmam_alloc_coherent(&pdev->dev,
+					   (ctrl->rx.sl_sz * ctrl->rx.n),
+					   &ctrl->rx.phy, GFP_KERNEL);
+	if (!ctrl->rx.base) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* Register with framework before enabling frame, clock */
+	ret = slim_register_controller(&ctrl->ctrl);
+	if (ret) {
+		dev_err(ctrl->dev, "error adding controller\n");
+		goto err;
+	}
+
+	ver = readl_relaxed(ctrl->base);
+	/* Version info in 16 MSbits */
+	ver >>= 16;
+	/* Component register initialization */
+	writel(1, ctrl->base + CFG_PORT(COMP_CFG, ver));
+	writel((EE_MGR_RSC_GRP | EE_NGD_2 | EE_NGD_1),
+				ctrl->base + CFG_PORT(COMP_TRUST_CFG, ver));
+
+	writel((MGR_INT_TX_NACKED_2 |
+			MGR_INT_MSG_BUF_CONTE | MGR_INT_RX_MSG_RCVD |
+			MGR_INT_TX_MSG_SENT), ctrl->base + MGR_INT_EN);
+	writel(1, ctrl->base + MGR_CFG);
+	/* Framer register initialization */
+	writel((1 << INTR_WAKE) | (0xA << REF_CLK_GEAR) |
+		(0xA << CLK_GEAR) | (1 << ROOT_FREQ) | (1 << FRM_ACTIVE) | 1,
+		ctrl->base + FRM_CFG);
+	writel(MGR_CFG_ENABLE, ctrl->base + MGR_CFG);
+	writel(1, ctrl->base + INTF_CFG);
+	writel(1, ctrl->base + CFG_PORT(COMP_CFG, ver));
+
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, QCOM_SLIM_AUTOSUSPEND);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	dev_dbg(ctrl->dev, "QCOM SB controller is up:ver:0x%x!\n", ver);
+	return 0;
+
+err:
+	clk_disable_unprepare(ctrl->rclk);
+err_rclk_enable_failed:
+	clk_disable_unprepare(ctrl->hclk);
+err_hclk_enable_failed:
+err_request_irq_failed:
+	destroy_workqueue(ctrl->rxwq);
+	return ret;
+}
+
+static int qcom_slim_remove(struct platform_device *pdev)
+{
+	struct qcom_slim_ctrl *ctrl = platform_get_drvdata(pdev);
+
+	disable_irq(ctrl->irq);
+	clk_disable_unprepare(ctrl->hclk);
+	clk_disable_unprepare(ctrl->rclk);
+	slim_unregister_controller(&ctrl->ctrl);
+	destroy_workqueue(ctrl->rxwq);
+	return 0;
+}
+
+static const struct dev_pm_ops qcom_slim_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(qcom_slim_suspend, qcom_slim_resume)
+	SET_RUNTIME_PM_OPS(
+			   qcom_slim_runtime_suspend,
+			   qcom_slim_runtime_resume,
+			   NULL
+	)
+};
+
+static const struct of_device_id qcom_slim_dt_match[] = {
+	{ .compatible = "qcom,slim", },
+	{ .compatible = "qcom,apq8064-slim", },
+	{}
+};
+
+static struct platform_driver qcom_slim_driver = {
+	.probe = qcom_slim_probe,
+	.remove = qcom_slim_remove,
+	.driver	= {
+		.name = "qcom_slim_ctrl",
+		.of_match_table = qcom_slim_dt_match,
+	},
+};
+module_platform_driver(qcom_slim_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm SLIMBus Controller");
-- 
2.15.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
@ 2017-11-15 14:10     ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

This controller driver programs manager, interface, and framer
devices for Qualcomm's slimbus HW block.
Manager component currently implements logical address setting,
and messaging interface.
Interface device reports bus synchronization information, and framer
device clocks the bus from the time it's woken up, until clock-pause
is executed by the manager device.

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/Kconfig     |   6 +
 drivers/slimbus/Makefile    |   4 +
 drivers/slimbus/qcom-ctrl.c | 684 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 694 insertions(+)
 create mode 100644 drivers/slimbus/qcom-ctrl.c

diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig
index 9c7d3c61656a..9c8d59290634 100644
--- a/drivers/slimbus/Kconfig
+++ b/drivers/slimbus/Kconfig
@@ -12,5 +12,11 @@ menuconfig SLIMBUS
 if SLIMBUS
 
 # SlIMbus controllers
+config SLIM_QCOM_CTRL
+	tristate "Qualcomm Slimbus Manager Component"
+	depends on SLIMBUS
+	help
+	  Select driver if Qualcomm's Slimbus Manager Component is
+	  programmed using Linux kernel.
 
 endif
diff --git a/drivers/slimbus/Makefile b/drivers/slimbus/Makefile
index 043402eae5be..9a70c7c70aae 100644
--- a/drivers/slimbus/Makefile
+++ b/drivers/slimbus/Makefile
@@ -3,3 +3,7 @@
 #
 obj-$(CONFIG_SLIMBUS)			+= slimbus.o
 slimbus-y				:= core.o messaging.o sched.o
+
+#Controllers
+obj-$(CONFIG_SLIM_QCOM_CTRL)		+= slim-qcom-ctrl.o
+slim-qcom-ctrl-y			:= qcom-ctrl.o
diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c
new file mode 100644
index 000000000000..25c1974f04ec
--- /dev/null
+++ b/drivers/slimbus/qcom-ctrl.c
@@ -0,0 +1,684 @@
+/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/dma-mapping.h>
+#include "slimbus.h"
+
+/* Manager registers */
+#define	MGR_CFG		0x200
+#define	MGR_STATUS	0x204
+#define	MGR_INT_EN	0x210
+#define	MGR_INT_STAT	0x214
+#define	MGR_INT_CLR	0x218
+#define	MGR_TX_MSG	0x230
+#define	MGR_RX_MSG	0x270
+#define	MGR_IE_STAT	0x2F0
+#define	MGR_VE_STAT	0x300
+#define	MGR_CFG_ENABLE	1
+
+/* Framer registers */
+#define	FRM_CFG		0x400
+#define	FRM_STAT	0x404
+#define	FRM_INT_EN	0x410
+#define	FRM_INT_STAT	0x414
+#define	FRM_INT_CLR	0x418
+#define	FRM_WAKEUP	0x41C
+#define	FRM_CLKCTL_DONE	0x420
+#define	FRM_IE_STAT	0x430
+#define	FRM_VE_STAT	0x440
+
+/* Interface registers */
+#define	INTF_CFG	0x600
+#define	INTF_STAT	0x604
+#define	INTF_INT_EN	0x610
+#define	INTF_INT_STAT	0x614
+#define	INTF_INT_CLR	0x618
+#define	INTF_IE_STAT	0x630
+#define	INTF_VE_STAT	0x640
+
+/* Interrupt status bits */
+#define	MGR_INT_TX_NACKED_2	BIT(25)
+#define	MGR_INT_MSG_BUF_CONTE	BIT(26)
+#define	MGR_INT_RX_MSG_RCVD	BIT(30)
+#define	MGR_INT_TX_MSG_SENT	BIT(31)
+
+/* Framer config register settings */
+#define	FRM_ACTIVE	1
+#define	CLK_GEAR	7
+#define	ROOT_FREQ	11
+#define	REF_CLK_GEAR	15
+#define	INTR_WAKE	19
+
+#define SLIM_MSG_ASM_FIRST_WORD(l, mt, mc, dt, ad) \
+		((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
+
+#define SLIM_ROOT_FREQ 24576000
+
+/* MAX message size over control channel */
+#define SLIM_MSGQ_BUF_LEN	40
+#define QCOM_TX_MSGS 2
+#define QCOM_RX_MSGS	8
+#define QCOM_BUF_ALLOC_RETRIES	10
+
+#define CFG_PORT(r, v) ((v) ? CFG_PORT_V2(r) : CFG_PORT_V1(r))
+
+/* V2 Component registers */
+#define CFG_PORT_V2(r) ((r ## _V2))
+#define	COMP_CFG_V2		4
+#define	COMP_TRUST_CFG_V2	0x3000
+
+/* V1 Component registers */
+#define CFG_PORT_V1(r) ((r ## _V1))
+#define	COMP_CFG_V1		0
+#define	COMP_TRUST_CFG_V1	0x14
+
+/* Resource group info for manager, and non-ported generic device-components */
+#define EE_MGR_RSC_GRP	(1 << 10)
+#define EE_NGD_2	(2 << 6)
+#define EE_NGD_1	0
+
+struct slim_ctrl_buf {
+	void		*base;
+	phys_addr_t	phy;
+	spinlock_t	lock;
+	int		head;
+	int		tail;
+	int		sl_sz;
+	int		n;
+};
+
+struct qcom_slim_ctrl {
+	struct slim_controller  ctrl;
+	struct slim_framer	framer;
+	struct device		*dev;
+	void __iomem		*base;
+	void __iomem		*slew_reg;
+
+	struct slim_ctrl_buf	rx;
+	struct slim_ctrl_buf	tx;
+
+	struct completion	**wr_comp;
+	int			irq;
+	struct workqueue_struct *rxwq;
+	struct work_struct	wd;
+	struct clk		*rclk;
+	struct clk		*hclk;
+};
+
+static void qcom_slim_queue_tx(struct qcom_slim_ctrl *ctrl, void *buf,
+			       u8 len, u32 tx_reg)
+{
+	int count = (len + 3) >> 2;
+
+	__iowrite32_copy(ctrl->base + tx_reg, buf, count);
+
+	/* Ensure Oder of subsequent writes */
+	mb();
+}
+
+static void *slim_alloc_rxbuf(struct qcom_slim_ctrl *ctrl)
+{
+	unsigned long flags;
+	int idx;
+
+	spin_lock_irqsave(&ctrl->rx.lock, flags);
+	if ((ctrl->rx.tail + 1) % ctrl->rx.n == ctrl->rx.head) {
+		spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+		dev_err(ctrl->dev, "RX QUEUE full!");
+		return NULL;
+	}
+	idx = ctrl->rx.tail;
+	ctrl->rx.tail = (ctrl->rx.tail + 1) % ctrl->rx.n;
+	spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+
+	return ctrl->rx.base + (idx * ctrl->rx.sl_sz);
+}
+
+void slim_ack_txn(struct qcom_slim_ctrl *ctrl, int err)
+{
+	struct completion *comp;
+	unsigned long flags;
+	int idx;
+
+	spin_lock_irqsave(&ctrl->tx.lock, flags);
+	idx = ctrl->tx.head;
+	ctrl->tx.head = (ctrl->tx.head + 1) % ctrl->tx.n;
+	spin_unlock_irqrestore(&ctrl->tx.lock, flags);
+
+	comp = ctrl->wr_comp[idx];
+	ctrl->wr_comp[idx] = NULL;
+
+	complete(comp);
+}
+
+static irqreturn_t qcom_slim_handle_tx_irq(struct qcom_slim_ctrl *ctrl,
+					   u32 stat)
+{
+	int err = 0;
+
+	if (stat & MGR_INT_TX_MSG_SENT)
+		writel_relaxed(MGR_INT_TX_MSG_SENT,
+			       ctrl->base + MGR_INT_CLR);
+
+	if (stat & MGR_INT_TX_NACKED_2) {
+		u32 mgr_stat = readl_relaxed(ctrl->base + MGR_STATUS);
+		u32 mgr_ie_stat = readl_relaxed(ctrl->base + MGR_IE_STAT);
+		u32 frm_stat = readl_relaxed(ctrl->base + FRM_STAT);
+		u32 frm_cfg = readl_relaxed(ctrl->base + FRM_CFG);
+		u32 frm_intr_stat = readl_relaxed(ctrl->base + FRM_INT_STAT);
+		u32 frm_ie_stat = readl_relaxed(ctrl->base + FRM_IE_STAT);
+		u32 intf_stat = readl_relaxed(ctrl->base + INTF_STAT);
+		u32 intf_intr_stat = readl_relaxed(ctrl->base + INTF_INT_STAT);
+		u32 intf_ie_stat = readl_relaxed(ctrl->base + INTF_IE_STAT);
+
+		writel_relaxed(MGR_INT_TX_NACKED_2, ctrl->base + MGR_INT_CLR);
+
+		dev_err(ctrl->dev, "TX Nack MGR:int:0x%x, stat:0x%x\n",
+			stat, mgr_stat);
+		dev_err(ctrl->dev, "TX Nack MGR:ie:0x%x\n", mgr_ie_stat);
+		dev_err(ctrl->dev, "TX Nack FRM:int:0x%x, stat:0x%x\n",
+			frm_intr_stat, frm_stat);
+		dev_err(ctrl->dev, "TX Nack FRM:cfg:0x%x, ie:0x%x\n",
+			frm_cfg, frm_ie_stat);
+		dev_err(ctrl->dev, "TX Nack INTF:intr:0x%x, stat:0x%x\n",
+			intf_intr_stat, intf_stat);
+		dev_err(ctrl->dev, "TX Nack INTF:ie:0x%x\n",
+			intf_ie_stat);
+		err = -ENOTCONN;
+	}
+
+	slim_ack_txn(ctrl, err);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qcom_slim_handle_rx_irq(struct qcom_slim_ctrl *ctrl,
+					   u32 stat)
+{
+	u32 *rx_buf, pkt[10];
+	bool q_rx = false;
+	u8 la, *buf, mc, mt, len, *b = (u8 *)&pkt[0];
+	u16 ele;
+
+	pkt[0] = readl_relaxed(ctrl->base + MGR_RX_MSG);
+	mt = SLIM_HEADER_GET_MT(b[0]);
+	len = SLIM_HEADER_GET_RL(b[0]);
+	mc = SLIM_HEADER_GET_MC(b[1]);
+
+	/*
+	 * this message cannot be handled by ISR, so
+	 * let work-queue handle it
+	 */
+	if (mt == SLIM_MSG_MT_CORE &&
+		mc == SLIM_MSG_MC_REPORT_PRESENT)
+		rx_buf = (u32 *)slim_alloc_rxbuf(ctrl);
+	else
+		rx_buf = pkt;
+
+	if (rx_buf == NULL) {
+		dev_err(ctrl->dev, "dropping RX:0x%x due to RX full\n",
+					pkt[0]);
+		goto rx_ret_irq;
+	}
+
+	rx_buf[0] = pkt[0];
+	__ioread32_copy(rx_buf + 1, ctrl->base + MGR_RX_MSG + 4,
+			DIV_ROUND_UP(len, 4));
+
+	switch (mc) {
+
+	case SLIM_MSG_MC_REPORT_PRESENT:
+		q_rx = true;
+		break;
+	case SLIM_MSG_MC_REPLY_INFORMATION:
+	case SLIM_MSG_MC_REPLY_VALUE:
+		slim_msg_response(&ctrl->ctrl, (u8 *)(rx_buf + 1),
+				  (u8)(*rx_buf >> 24), (len - 4));
+		break;
+	case SLIM_MSG_MC_REPORT_INFORMATION:
+		buf = (u8 *)rx_buf;
+		la = buf[2];
+		ele = (u16)buf[4] << 4;
+
+		ele |= ((buf[3] & 0xf0) >> 4);
+		/*
+		 * report information is most likely loss of
+		 * sync or collision detected in data slots
+		 */
+		dev_info(ctrl->dev, "LA:%d report inf ele:0x%x\n",
+			 la, ele);
+		break;
+	default:
+		dev_err(ctrl->dev, "unsupported MC,%x MT:%x\n",
+			mc, mt);
+		break;
+	}
+rx_ret_irq:
+	writel(MGR_INT_RX_MSG_RCVD, ctrl->base +
+		       MGR_INT_CLR);
+	if (q_rx)
+		queue_work(ctrl->rxwq, &ctrl->wd);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qcom_slim_interrupt(int irq, void *d)
+{
+	struct qcom_slim_ctrl *ctrl = d;
+	u32 stat = readl_relaxed(ctrl->base + MGR_INT_STAT);
+	int ret = IRQ_NONE;
+
+	if (stat & MGR_INT_TX_MSG_SENT || stat & MGR_INT_TX_NACKED_2)
+		ret = qcom_slim_handle_tx_irq(ctrl, stat);
+
+	if (stat & MGR_INT_RX_MSG_RCVD)
+		ret = qcom_slim_handle_rx_irq(ctrl, stat);
+
+	return ret;
+}
+
+void *slim_alloc_txbuf(struct qcom_slim_ctrl *ctrl, struct slim_msg_txn *txn,
+		       struct completion *done)
+{
+	unsigned long flags;
+	int idx;
+
+	spin_lock_irqsave(&ctrl->tx.lock, flags);
+	if (((ctrl->tx.head + 1) % ctrl->tx.n) == ctrl->tx.tail) {
+		spin_unlock_irqrestore(&ctrl->tx.lock, flags);
+		dev_err(ctrl->dev, "controller TX buf unavailable");
+		return NULL;
+	}
+	idx = ctrl->tx.tail;
+	ctrl->wr_comp[idx] = done;
+	ctrl->tx.tail = (ctrl->tx.tail + 1) % ctrl->tx.n;
+
+	spin_unlock_irqrestore(&ctrl->tx.lock, flags);
+
+	return ctrl->tx.base + (idx * ctrl->tx.sl_sz);
+}
+
+
+static int qcom_xfer_msg(struct slim_controller *sctrl,
+			 struct slim_msg_txn *txn)
+{
+	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
+	DECLARE_COMPLETION_ONSTACK(done);
+	void *pbuf = slim_alloc_txbuf(ctrl, txn, &done);
+	unsigned long ms = txn->rl + HZ;
+	u8 *puc;
+	int ret = 0, timeout, retries = QCOM_BUF_ALLOC_RETRIES;
+	u8 la = txn->la;
+	u32 *head;
+	/* HW expects length field to be excluded */
+	txn->rl--;
+
+	/* spin till buffer is made available */
+	if (!pbuf) {
+		while (retries--) {
+			usleep_range(10000, 15000);
+			pbuf = slim_alloc_txbuf(ctrl, txn, &done);
+			if (pbuf)
+				break;
+		}
+	}
+
+	if (!retries && !pbuf)
+		return -ENOMEM;
+
+	puc = (u8 *)pbuf;
+	head = (u32 *)pbuf;
+
+	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
+		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
+						la);
+	else
+		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
+						la);
+
+	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
+		puc += 3;
+	else
+		puc += 2;
+
+	if (txn->mt == SLIM_MSG_MT_CORE && slim_tid_txn(txn->mt, txn->mc))
+		*(puc++) = txn->tid;
+
+	if ((txn->mt == SLIM_MSG_MT_CORE) &&
+		((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
+		txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
+		(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
+		 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
+		*(puc++) = (txn->ec & 0xFF);
+		*(puc++) = (txn->ec >> 8) & 0xFF;
+	}
+
+	if (txn->msg && txn->msg->wbuf)
+		memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
+
+	qcom_slim_queue_tx(ctrl, head, txn->rl, MGR_TX_MSG);
+	timeout = wait_for_completion_timeout(&done, msecs_to_jiffies(ms));
+
+	if (!timeout) {
+		dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
+					txn->mt);
+		ret = -ETIMEDOUT;
+	}
+
+	return ret;
+
+}
+
+static int qcom_set_laddr(struct slim_controller *sctrl,
+				struct slim_eaddr *ead, u8 laddr)
+{
+	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
+	struct {
+		__be16 manf_id;
+		__be16 prod_code;
+		u8 dev_index;
+		u8 instance;
+		u8 laddr;
+	} __packed p;
+	struct slim_val_inf msg = {0};
+	DEFINE_SLIM_EDEST_TXN(txn, SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS,
+			      10, laddr, &msg);
+	int ret;
+
+	p.manf_id = cpu_to_be16(ead->manf_id);
+	p.prod_code = cpu_to_be16(ead->prod_code);
+	p.dev_index = ead->dev_index;
+	p.instance = ead->instance;
+	p.laddr = laddr;
+
+	msg.wbuf = (void *)&p;
+	msg.num_bytes = 7;
+	ret = slim_do_transfer(&ctrl->ctrl, &txn);
+
+	if (ret)
+		dev_err(ctrl->dev, "set LA:0x%x failed:ret:%d\n",
+				  laddr, ret);
+	return ret;
+}
+
+static int slim_get_current_rxbuf(struct qcom_slim_ctrl *ctrl, void *buf)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctrl->rx.lock, flags);
+	if (ctrl->rx.tail == ctrl->rx.head) {
+		spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+		return -ENODATA;
+	}
+	memcpy(buf, ctrl->rx.base + (ctrl->rx.head * ctrl->rx.sl_sz),
+				ctrl->rx.sl_sz);
+
+	ctrl->rx.head = (ctrl->rx.head + 1) % ctrl->rx.n;
+	spin_unlock_irqrestore(&ctrl->rx.lock, flags);
+
+	return 0;
+}
+
+static void qcom_slim_rxwq(struct work_struct *work)
+{
+	u8 buf[SLIM_MSGQ_BUF_LEN];
+	u8 mc, mt, len;
+	int i, ret;
+	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
+						 wd);
+
+	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
+		len = SLIM_HEADER_GET_RL(buf[0]);
+		mt = SLIM_HEADER_GET_MT(buf[0]);
+		mc = SLIM_HEADER_GET_MC(buf[1]);
+		if (mt == SLIM_MSG_MT_CORE &&
+			mc == SLIM_MSG_MC_REPORT_PRESENT) {
+			u8 laddr;
+			struct slim_eaddr ea;
+			u8 e_addr[6];
+
+			for (i = 0; i < 6; i++)
+				e_addr[i] = buf[7-i];
+
+			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
+			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
+			ea.dev_index = e_addr[1];
+			ea.instance = e_addr[0];
+			ret = slim_device_report_present(&ctrl->ctrl,
+							 &ea, &laddr);
+			if (ret < 0)
+				dev_err(ctrl->dev, "assign laddr failed:%d\n",
+					ret);
+		} else {
+			dev_err(ctrl->dev, "unexpected message:mc:%x, mt:%x\n",
+				mc, mt);
+		}
+	}
+}
+
+static void qcom_slim_prg_slew(struct platform_device *pdev,
+				struct qcom_slim_ctrl *ctrl)
+{
+	struct resource	*slew_mem;
+
+	if (!ctrl->slew_reg) {
+		/* SLEW RATE register for this slimbus */
+		slew_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+				"slew");
+		ctrl->slew_reg = devm_ioremap(&pdev->dev, slew_mem->start,
+				resource_size(slew_mem));
+		if (!ctrl->slew_reg)
+			return;
+	}
+
+	writel_relaxed(1, ctrl->slew_reg);
+	/* Make sure slimbus-slew rate enabling goes through */
+	wmb();
+}
+
+static int qcom_slim_probe(struct platform_device *pdev)
+{
+	struct qcom_slim_ctrl *ctrl;
+	struct slim_controller *sctrl;
+	struct resource *slim_mem;
+	int ret, ver;
+
+	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl)
+		return -ENOMEM;
+
+	ctrl->hclk = devm_clk_get(&pdev->dev, "iface");
+	if (IS_ERR(ctrl->hclk))
+		return PTR_ERR(ctrl->hclk);
+
+	ctrl->rclk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(ctrl->rclk))
+		return PTR_ERR(ctrl->rclk);
+
+	ret = clk_set_rate(ctrl->rclk, SLIM_ROOT_FREQ);
+	if (ret) {
+		dev_err(&pdev->dev, "ref-clock set-rate failed:%d\n", ret);
+		return ret;
+	}
+
+	ctrl->irq = platform_get_irq(pdev, 0);
+	if (!ctrl->irq) {
+		dev_err(&pdev->dev, "no slimbus IRQ\n");
+		return -ENODEV;
+	}
+
+	sctrl = &ctrl->ctrl;
+	sctrl->dev = &pdev->dev;
+	ctrl->dev = &pdev->dev;
+	platform_set_drvdata(pdev, ctrl);
+	dev_set_drvdata(ctrl->dev, ctrl);
+
+	slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+	ctrl->base = devm_ioremap_resource(ctrl->dev, slim_mem);
+	if (!ctrl->base) {
+		dev_err(&pdev->dev, "IOremap failed\n");
+		return -ENOMEM;
+	}
+
+	sctrl->set_laddr = qcom_set_laddr;
+	sctrl->xfer_msg = qcom_xfer_msg;
+	ctrl->tx.n = QCOM_TX_MSGS;
+	ctrl->tx.sl_sz = SLIM_MSGQ_BUF_LEN;
+	ctrl->rx.n = QCOM_RX_MSGS;
+	ctrl->rx.sl_sz = SLIM_MSGQ_BUF_LEN;
+	ctrl->wr_comp = kzalloc(sizeof(struct completion *) * QCOM_TX_MSGS,
+				GFP_KERNEL);
+	if (!ctrl->wr_comp)
+		return -ENOMEM;
+
+	spin_lock_init(&ctrl->rx.lock);
+	spin_lock_init(&ctrl->tx.lock);
+	INIT_WORK(&ctrl->wd, qcom_slim_rxwq);
+	ctrl->rxwq = create_singlethread_workqueue("qcom_slim_rx");
+	if (!ctrl->rxwq) {
+		dev_err(ctrl->dev, "Failed to start Rx WQ\n");
+		return -ENOMEM;
+	}
+
+	ctrl->framer.rootfreq = SLIM_ROOT_FREQ / 8;
+	ctrl->framer.superfreq =
+		ctrl->framer.rootfreq / SLIM_CL_PER_SUPERFRAME_DIV8;
+	sctrl->a_framer = &ctrl->framer;
+	sctrl->clkgear = SLIM_MAX_CLK_GEAR;
+
+	qcom_slim_prg_slew(pdev, ctrl);
+
+	ret = devm_request_irq(&pdev->dev, ctrl->irq, qcom_slim_interrupt,
+				IRQF_TRIGGER_HIGH, "qcom_slim_irq", ctrl);
+	if (ret) {
+		dev_err(&pdev->dev, "request IRQ failed\n");
+		goto err_request_irq_failed;
+	}
+
+	ret = clk_prepare_enable(ctrl->hclk);
+	if (ret)
+		goto err_hclk_enable_failed;
+
+	ret = clk_prepare_enable(ctrl->rclk);
+	if (ret)
+		goto err_rclk_enable_failed;
+
+	ctrl->tx.base = dmam_alloc_coherent(&pdev->dev,
+					   (ctrl->tx.sl_sz * ctrl->tx.n),
+					   &ctrl->tx.phy, GFP_KERNEL);
+	if (!ctrl->tx.base) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ctrl->rx.base = dmam_alloc_coherent(&pdev->dev,
+					   (ctrl->rx.sl_sz * ctrl->rx.n),
+					   &ctrl->rx.phy, GFP_KERNEL);
+	if (!ctrl->rx.base) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* Register with framework before enabling frame, clock */
+	ret = slim_register_controller(&ctrl->ctrl);
+	if (ret) {
+		dev_err(ctrl->dev, "error adding controller\n");
+		goto err;
+	}
+
+	ver = readl_relaxed(ctrl->base);
+	/* Version info in 16 MSbits */
+	ver >>= 16;
+	/* Component register initialization */
+	writel(1, ctrl->base + CFG_PORT(COMP_CFG, ver));
+	writel((EE_MGR_RSC_GRP | EE_NGD_2 | EE_NGD_1),
+				ctrl->base + CFG_PORT(COMP_TRUST_CFG, ver));
+
+	writel((MGR_INT_TX_NACKED_2 |
+			MGR_INT_MSG_BUF_CONTE | MGR_INT_RX_MSG_RCVD |
+			MGR_INT_TX_MSG_SENT), ctrl->base + MGR_INT_EN);
+	writel(1, ctrl->base + MGR_CFG);
+	/* Framer register initialization */
+	writel((1 << INTR_WAKE) | (0xA << REF_CLK_GEAR) |
+		(0xA << CLK_GEAR) | (1 << ROOT_FREQ) | (1 << FRM_ACTIVE) | 1,
+		ctrl->base + FRM_CFG);
+	writel(MGR_CFG_ENABLE, ctrl->base + MGR_CFG);
+	writel(1, ctrl->base + INTF_CFG);
+	writel(1, ctrl->base + CFG_PORT(COMP_CFG, ver));
+
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, QCOM_SLIM_AUTOSUSPEND);
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	dev_dbg(ctrl->dev, "QCOM SB controller is up:ver:0x%x!\n", ver);
+	return 0;
+
+err:
+	clk_disable_unprepare(ctrl->rclk);
+err_rclk_enable_failed:
+	clk_disable_unprepare(ctrl->hclk);
+err_hclk_enable_failed:
+err_request_irq_failed:
+	destroy_workqueue(ctrl->rxwq);
+	return ret;
+}
+
+static int qcom_slim_remove(struct platform_device *pdev)
+{
+	struct qcom_slim_ctrl *ctrl = platform_get_drvdata(pdev);
+
+	disable_irq(ctrl->irq);
+	clk_disable_unprepare(ctrl->hclk);
+	clk_disable_unprepare(ctrl->rclk);
+	slim_unregister_controller(&ctrl->ctrl);
+	destroy_workqueue(ctrl->rxwq);
+	return 0;
+}
+
+static const struct dev_pm_ops qcom_slim_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(qcom_slim_suspend, qcom_slim_resume)
+	SET_RUNTIME_PM_OPS(
+			   qcom_slim_runtime_suspend,
+			   qcom_slim_runtime_resume,
+			   NULL
+	)
+};
+
+static const struct of_device_id qcom_slim_dt_match[] = {
+	{ .compatible = "qcom,slim", },
+	{ .compatible = "qcom,apq8064-slim", },
+	{}
+};
+
+static struct platform_driver qcom_slim_driver = {
+	.probe = qcom_slim_probe,
+	.remove = qcom_slim_remove,
+	.driver	= {
+		.name = "qcom_slim_ctrl",
+		.of_match_table = qcom_slim_dt_match,
+	},
+};
+module_platform_driver(qcom_slim_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm SLIMBus Controller");
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 12/13] slimbus: qcom: Add runtime-pm support using clock-pause
  2017-11-15 14:10 ` srinivas.kandagatla
                   ` (10 preceding siblings ...)
  (?)
@ 2017-11-15 14:10 ` srinivas.kandagatla
  2017-11-23 10:17     ` Charles Keepax
  -1 siblings, 1 reply; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Sagar Dharia <sdharia@codeaurora.org>

Slimbus HW mandates that clock-pause sequence has to be executed
before disabling relevant interface and core clocks.
Runtime-PM's autosuspend feature is used here to enter/exit low
power mode for Qualcomm's Slimbus controller. Autosuspend feature
enables driver to avoid changing power-modes too frequently since
entering clock-pause is an expensive sequence

Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/slimbus/qcom-ctrl.c | 113 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 110 insertions(+), 3 deletions(-)

diff --git a/drivers/slimbus/qcom-ctrl.c b/drivers/slimbus/qcom-ctrl.c
index 25c1974f04ec..38340b104db4 100644
--- a/drivers/slimbus/qcom-ctrl.c
+++ b/drivers/slimbus/qcom-ctrl.c
@@ -20,6 +20,7 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
 #include "slimbus.h"
 
 /* Manager registers */
@@ -71,6 +72,7 @@
 		((l) | ((mt) << 5) | ((mc) << 8) | ((dt) << 15) | ((ad) << 16))
 
 #define SLIM_ROOT_FREQ 24576000
+#define QCOM_SLIM_AUTOSUSPEND 1000
 
 /* MAX message size over control channel */
 #define SLIM_MSGQ_BUF_LEN	40
@@ -295,6 +297,30 @@ static irqreturn_t qcom_slim_interrupt(int irq, void *d)
 	return ret;
 }
 
+static int qcom_clk_pause_wakeup(struct slim_controller *sctrl)
+{
+	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
+
+	clk_prepare_enable(ctrl->hclk);
+	clk_prepare_enable(ctrl->rclk);
+	enable_irq(ctrl->irq);
+
+	writel_relaxed(1, ctrl->base + FRM_WAKEUP);
+	/* Make sure framer wakeup write goes through before ISR fires */
+	mb();
+	/*
+	 * HW Workaround: Currently, slave is reporting lost-sync messages
+	 * after slimbus comes out of clock pause.
+	 * Transaction with slave fail before slave reports that message
+	 * Give some time for that report to come
+	 * Slimbus wakes up in clock gear 10 at 24.576MHz. With each superframe
+	 * being 250 usecs, we wait for 5-10 superframes here to ensure
+	 * we get the message
+	 */
+	usleep_range(1250, 2500);
+	return 0;
+}
+
 void *slim_alloc_txbuf(struct qcom_slim_ctrl *ctrl, struct slim_msg_txn *txn,
 		       struct completion *done)
 {
@@ -540,6 +566,7 @@ static int qcom_slim_probe(struct platform_device *pdev)
 
 	sctrl->set_laddr = qcom_set_laddr;
 	sctrl->xfer_msg = qcom_xfer_msg;
+	sctrl->wakeup =  qcom_clk_pause_wakeup;
 	ctrl->tx.n = QCOM_TX_MSGS;
 	ctrl->tx.sl_sz = SLIM_MSGQ_BUF_LEN;
 	ctrl->rx.n = QCOM_RX_MSGS;
@@ -647,14 +674,93 @@ static int qcom_slim_remove(struct platform_device *pdev)
 {
 	struct qcom_slim_ctrl *ctrl = platform_get_drvdata(pdev);
 
-	disable_irq(ctrl->irq);
-	clk_disable_unprepare(ctrl->hclk);
-	clk_disable_unprepare(ctrl->rclk);
+	pm_runtime_disable(&pdev->dev);
 	slim_unregister_controller(&ctrl->ctrl);
 	destroy_workqueue(ctrl->rxwq);
 	return 0;
 }
 
+/*
+ * If PM_RUNTIME is not defined, these 2 functions become helper
+ * functions to be called from system suspend/resume.
+ */
+#ifdef CONFIG_PM
+static int qcom_slim_runtime_suspend(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct qcom_slim_ctrl *ctrl = platform_get_drvdata(pdev);
+	int ret;
+
+	dev_dbg(device, "pm_runtime: suspending...\n");
+	ret = slim_ctrl_clk_pause(&ctrl->ctrl, false, SLIM_CLK_UNSPECIFIED);
+	if (ret) {
+		dev_err(device, "clk pause not entered:%d", ret);
+	} else {
+		disable_irq(ctrl->irq);
+		clk_disable_unprepare(ctrl->hclk);
+		clk_disable_unprepare(ctrl->rclk);
+	}
+	return ret;
+}
+
+static int qcom_slim_runtime_resume(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct qcom_slim_ctrl *ctrl = platform_get_drvdata(pdev);
+	int ret = 0;
+
+	dev_dbg(device, "pm_runtime: resuming...\n");
+	ret = slim_ctrl_clk_pause(&ctrl->ctrl, true, 0);
+	if (ret)
+		dev_err(device, "clk pause not exited:%d", ret);
+	return ret;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int qcom_slim_suspend(struct device *dev)
+{
+	int ret = 0;
+
+	if (!pm_runtime_enabled(dev) ||
+		(!pm_runtime_suspended(dev))) {
+		dev_dbg(dev, "system suspend");
+		ret = qcom_slim_runtime_suspend(dev);
+	}
+
+	/*
+	 * If the clock pause failed due to active channels, there is
+	 * a possibility that some audio stream is active during suspend.
+	 * (e.g. modem usecase during suspend)
+	 * We dont want to return suspend failure in that case so that
+	 * display and relevant components can still go to suspend.
+	 * If there is some other error, then it should prevent
+	 * system level suspend
+	 */
+	if (ret == -EISCONN)
+		ret = 0;
+
+	return ret;
+}
+
+static int qcom_slim_resume(struct device *dev)
+{
+	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
+		int ret;
+
+		dev_dbg(dev, "system resume");
+		ret = qcom_slim_runtime_resume(dev);
+		if (!ret) {
+			pm_runtime_mark_last_busy(dev);
+			pm_request_autosuspend(dev);
+		}
+		return ret;
+
+	}
+	return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
 static const struct dev_pm_ops qcom_slim_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(qcom_slim_suspend, qcom_slim_resume)
 	SET_RUNTIME_PM_OPS(
@@ -676,6 +782,7 @@ static struct platform_driver qcom_slim_driver = {
 	.driver	= {
 		.name = "qcom_slim_ctrl",
 		.of_match_table = qcom_slim_dt_match,
+		.pm = &qcom_slim_dev_pm_ops,
 	},
 };
 module_platform_driver(qcom_slim_driver);
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 13/13] MAINTAINERS: Add SLIMbus maintainer
  2017-11-15 14:10 ` srinivas.kandagatla
@ 2017-11-15 14:10     ` srinivas.kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
  Cc: sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, arnd-r2nGTMty4D4,
	Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Add myself as maintainer for slimbus.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Acked-by: Bjorn Andersson <bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a7995c737728..d4ff3d1f82f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12347,6 +12347,14 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:	include/linux/srcu.h
 F:	kernel/rcu/srcu.c
 
+SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus)
+M:	Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+L:	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw@public.gmane.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/slimbus/
+F:	Documentation/devicetree/bindings/slimbus/
+F:	include/linux/slimbus.h
+
 SMACK SECURITY MODULE
 M:	Casey Schaufler <casey-iSGtlc1asvQWG2LlvL+J4A@public.gmane.org>
 L:	linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
-- 
2.15.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v7 13/13] MAINTAINERS: Add SLIMbus maintainer
@ 2017-11-15 14:10     ` srinivas.kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: srinivas.kandagatla @ 2017-11-15 14:10 UTC (permalink / raw)
  To: gregkh, broonie, alsa-devel
  Cc: sdharia, bp, poeschel, treding, andreas.noever, alan,
	mathieu.poirier, daniel, jkosina, sharon.dvir1, joe, davem,
	james.hogan, michael.opdenacker, robh+dt, pawel.moll,
	mark.rutland, devicetree, linux-kernel, linux-arm-msm,
	vinod.koul, arnd, Srinivas Kandagatla

From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

Add myself as maintainer for slimbus.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a7995c737728..d4ff3d1f82f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12347,6 +12347,14 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:	include/linux/srcu.h
 F:	kernel/rcu/srcu.c
 
+SERIAL LOW-POWER INTER-CHIP MEDIA BUS (SLIMbus)
+M:	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/slimbus/
+F:	Documentation/devicetree/bindings/slimbus/
+F:	include/linux/slimbus.h
+
 SMACK SECURITY MODULE
 M:	Casey Schaufler <casey@schaufler-ca.com>
 L:	linux-security-module@vger.kernel.org
-- 
2.15.0

^ permalink raw reply related	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
  2017-11-15 14:10   ` srinivas.kandagatla
@ 2017-11-16  5:15     ` Rob Herring
  -1 siblings, 0 replies; 78+ messages in thread
From: Rob Herring @ 2017-11-16  5:15 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, treding, devicetree,
	james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1, broonie,
	sdharia, alan, bp, mathieu.poirier, gregkh, linux-kernel, daniel,
	jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> developed by MIPI (Mobile Industry Processor Interface) alliance.
> SLIMbus is a 2-wire implementation, which is used to communicate with
> peripheral components like audio-codec.
> 
> This patch adds device tree bindings for the slimbus.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>  Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
@ 2017-11-16  5:15     ` Rob Herring
  0 siblings, 0 replies; 78+ messages in thread
From: Rob Herring @ 2017-11-16  5:15 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> developed by MIPI (Mobile Industry Processor Interface) alliance.
> SLIMbus is a 2-wire implementation, which is used to communicate with
> peripheral components like audio-codec.
> 
> This patch adds device tree bindings for the slimbus.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>  Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings
  2017-11-15 14:10 ` [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings srinivas.kandagatla
@ 2017-11-16  5:19     ` Rob Herring
  0 siblings, 0 replies; 78+ messages in thread
From: Rob Herring @ 2017-11-16  5:19 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, treding, devicetree,
	james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1, broonie,
	sdharia, alan, bp, mathieu.poirier, gregkh, linux-kernel, daniel,
	jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:40PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> This patch add device tree bindings for Qualcomm slimbus controller.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>  .../devicetree/bindings/slimbus/slim-qcom-ctrl.txt | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
> 
> diff --git a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
> new file mode 100644
> index 000000000000..e4d28910b2e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
> @@ -0,0 +1,43 @@
> +Qualcomm SLIMBUS controller
> +This controller is used if applications processor driver controls slimbus
> +master component.
> +
> +Required properties:
> +
> + - #address-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt
> + - #size-cells	- refer to Documentation/devicetree/bindings/slimbus/bus.txt
> +
> + - reg : Offset and length of the register region(s) for the device
> + - reg-names : Register region name(s) referenced in reg above
> +	 Required register resource entries are:
> +	 "ctrl": Physical address of controller register blocks
> + - compatible : should be "qcom,<SOC-NAME>-slim" for SOC specific compatible
> + 		followed by "qcom,slim" for fallback.
> + - interrupts : Interrupt number used by this controller
> + - clocks : Interface and core clocks used by this slimbus controller
> + - clock-names : Required clock-name entries are:
> +	"iface_clk" : Interface clock for this controller
> +	"core_clk" : Interrupt for controller core's BAM
> +
> +
> +Optional property:
> + - reg entry for slew rate : If slew rate control register is provided, this
> +	entry should be used.
> + - reg-name for slew rate: "slew"

reg-names

I'd prefer it be explicit as to which compatibles do or don't have this 
register.

> +
> +Example:
> +
> +	slim@28080000 {
> +		compatible = "qcom,apq8064-slim", "qcom,slim";
> +		reg = <0x28080000 0x2000>,

error                                    ^

> +		interrupts = <0 33 0>;
> +		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
> +		clock-names = "iface", "core";
> +		#address-cells = <2>;
> +		#size-cell = <0>;
> +
> +		codec: wcd9310@1,0{

Use generic node names:

wcd9310: audio-codec@1,0

> +			compatible = "slim217,60";
> +			reg = <1 0>;
> +		};
> +	};
> -- 
> 2.15.0
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings
@ 2017-11-16  5:19     ` Rob Herring
  0 siblings, 0 replies; 78+ messages in thread
From: Rob Herring @ 2017-11-16  5:19 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 02:10:40PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> This patch add device tree bindings for Qualcomm slimbus controller.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>  .../devicetree/bindings/slimbus/slim-qcom-ctrl.txt | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
> 
> diff --git a/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
> new file mode 100644
> index 000000000000..e4d28910b2e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/slimbus/slim-qcom-ctrl.txt
> @@ -0,0 +1,43 @@
> +Qualcomm SLIMBUS controller
> +This controller is used if applications processor driver controls slimbus
> +master component.
> +
> +Required properties:
> +
> + - #address-cells - refer to Documentation/devicetree/bindings/slimbus/bus.txt
> + - #size-cells	- refer to Documentation/devicetree/bindings/slimbus/bus.txt
> +
> + - reg : Offset and length of the register region(s) for the device
> + - reg-names : Register region name(s) referenced in reg above
> +	 Required register resource entries are:
> +	 "ctrl": Physical address of controller register blocks
> + - compatible : should be "qcom,<SOC-NAME>-slim" for SOC specific compatible
> + 		followed by "qcom,slim" for fallback.
> + - interrupts : Interrupt number used by this controller
> + - clocks : Interface and core clocks used by this slimbus controller
> + - clock-names : Required clock-name entries are:
> +	"iface_clk" : Interface clock for this controller
> +	"core_clk" : Interrupt for controller core's BAM
> +
> +
> +Optional property:
> + - reg entry for slew rate : If slew rate control register is provided, this
> +	entry should be used.
> + - reg-name for slew rate: "slew"

reg-names

I'd prefer it be explicit as to which compatibles do or don't have this 
register.

> +
> +Example:
> +
> +	slim@28080000 {
> +		compatible = "qcom,apq8064-slim", "qcom,slim";
> +		reg = <0x28080000 0x2000>,

error                                    ^

> +		interrupts = <0 33 0>;
> +		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
> +		clock-names = "iface", "core";
> +		#address-cells = <2>;
> +		#size-cell = <0>;
> +
> +		codec: wcd9310@1,0{

Use generic node names:

wcd9310: audio-codec@1,0

> +			compatible = "slim217,60";
> +			reg = <1 0>;
> +		};
> +	};
> -- 
> 2.15.0
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings
  2017-11-16  5:19     ` Rob Herring
@ 2017-11-16  9:42       ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16  9:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, arnd-r2nGTMty4D4

Thanks for the review,

On 16/11/17 05:19, Rob Herring wrote:
>> +	entry should be used.
>> + - reg-name for slew rate: "slew"
> reg-names
> 
> I'd prefer it be explicit as to which compatibles do or don't have this
> register.
Makes sense, I will take this in before sending next version.
> 
>> +
>> +Example:
>> +
>> +	slim@28080000 {
>> +		compatible = "qcom,apq8064-slim", "qcom,slim";
>> +		reg = <0x28080000 0x2000>,
> error                                    ^
> 
thanks for spotting.. will fix this.
>> +		interrupts = <0 33 0>;
>> +		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
>> +		clock-names = "iface", "core";
>> +		#address-cells = <2>;
>> +		#size-cell = <0>;
>> +
>> +		codec: wcd9310@1,0{
> Use generic node names:
> 
> wcd9310: audio-codec@1,0
Yep, will do that.

thanks,
srini
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings
@ 2017-11-16  9:42       ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16  9:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

Thanks for the review,

On 16/11/17 05:19, Rob Herring wrote:
>> +	entry should be used.
>> + - reg-name for slew rate: "slew"
> reg-names
> 
> I'd prefer it be explicit as to which compatibles do or don't have this
> register.
Makes sense, I will take this in before sending next version.
> 
>> +
>> +Example:
>> +
>> +	slim@28080000 {
>> +		compatible = "qcom,apq8064-slim", "qcom,slim";
>> +		reg = <0x28080000 0x2000>,
> error                                    ^
> 
thanks for spotting.. will fix this.
>> +		interrupts = <0 33 0>;
>> +		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
>> +		clock-names = "iface", "core";
>> +		#address-cells = <2>;
>> +		#size-cell = <0>;
>> +
>> +		codec: wcd9310@1,0{
> Use generic node names:
> 
> wcd9310: audio-codec@1,0
Yep, will do that.

thanks,
srini
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 03/13] slimbus: Add SLIMbus bus type
  2017-11-15 14:10 ` [PATCH v7 03/13] slimbus: Add SLIMbus bus type srinivas.kandagatla
@ 2017-11-16 12:25     ` Mark Brown
  2017-11-16 13:18     ` [alsa-devel] " Vinod Koul
  1 sibling, 0 replies; 78+ messages in thread
From: Mark Brown @ 2017-11-16 12:25 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, gregkh, linux-kernel, daniel, jkosina,
	joe, davem


[-- Attachment #1.1: Type: text/plain, Size: 434 bytes --]

On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> developed by MIPI (Mobile Industry Processor Interface) alliance.
> SLIMbus is a 2-wire implementation, which is used to communicate with
> peripheral components like audio-codec.

Reviewed-by: Mark Brown <broonie@kernel.org>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 03/13] slimbus: Add SLIMbus bus type
@ 2017-11-16 12:25     ` Mark Brown
  0 siblings, 0 replies; 78+ messages in thread
From: Mark Brown @ 2017-11-16 12:25 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

[-- Attachment #1: Type: text/plain, Size: 434 bytes --]

On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> developed by MIPI (Mobile Industry Processor Interface) alliance.
> SLIMbus is a 2-wire implementation, which is used to communicate with
> peripheral components like audio-codec.

Reviewed-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
  2017-11-15 14:10   ` srinivas.kandagatla
  (?)
  (?)
@ 2017-11-16 13:09   ` Vinod Koul
  2017-11-16 13:40       ` Srinivas Kandagatla
  -1 siblings, 1 reply; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 13:09 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> developed by MIPI (Mobile Industry Processor Interface) alliance.
> SLIMbus is a 2-wire implementation, which is used to communicate with
> peripheral components like audio-codec.
> 
> This patch adds device tree bindings for the slimbus.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
>  Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt
> 
> diff --git a/Documentation/devicetree/bindings/slimbus/bus.txt b/Documentation/devicetree/bindings/slimbus/bus.txt
> new file mode 100644
> index 000000000000..413b5076858e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/slimbus/bus.txt
> @@ -0,0 +1,50 @@
> +SLIM(Serial Low Power Interchip Media Bus) bus
> +
> +SLIMbus is a 2-wire bus, and is used to communicate with peripheral
> +components like audio-codec.
> +
> +Required property for SLIMbus controller node:
> +- compatible	- name of SLIMbus controller
> +
> +Child nodes:
> +Every SLIMbus controller node can contain zero or more child nodes
> +representing slave devices on the bus. Every SLIMbus slave device is
> +uniquely determined by the enumeration address containing 4 fields:
> +Manufacturer ID, Product code, Device index, and Instance value for
> +the device.
> +If child node is not present and it is instantiated after device
> +discovery (slave device reporting itself present).

So you allow the devices to work even if the respective firmware description
is absent?

> +
> +In some cases it may be necessary to describe non-probeable device
> +details such as non-standard ways of powering up a device. In
> +such cases, child nodes for those devices will be present as
> +slaves of the slimbus-controller, as detailed below.
> +
> +Required property for SLIMbus child node if it is present:
> +- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
> +		  Enumeration  Address.
> +		  Device Index Uniquely identifies multiple Devices within
> +		  a single Component.
> +		  Instance ID Is for the cases where multiple Devices of the
> +		  same type or Class are attached to the bus.
> +
> +- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
> +	 	  Product Code, shall be in lower case hexadecimal with leading
> +		  zeroes suppressed
> +
> +SLIMbus example for Qualcomm's slimbus manager component:
> +
> +	slim@28080000 {
> +		compatible = "qcom,apq8064-slim", "qcom,slim";
> +		reg = <0x28080000 0x2000>,
> +		interrupts = <0 33 0>;
> +		clocks = <&lcc SLIMBUS_SRC>, <&lcc AUDIO_SLIMBUS_CLK>;
> +		clock-names = "iface", "core";
> +		#address-cells = <2>;
> +		#size-cell = <0>;
> +
> +		codec: wcd9310@1,0{
> +			compatible = "slim217,60";
> +			reg = <1 0>;
> +		};
> +	};

Pardon my ignorance as I am not very familiar with DT nodes, but where are
the Manufacturer ID, Product code, Device index, and Instance values here?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 03/13] slimbus: Add SLIMbus bus type
  2017-11-15 14:10 ` [PATCH v7 03/13] slimbus: Add SLIMbus bus type srinivas.kandagatla
@ 2017-11-16 13:18     ` Vinod Koul
  2017-11-16 13:18     ` [alsa-devel] " Vinod Koul
  1 sibling, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 13:18 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, treding, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	bp, mathieu.poirier, jkosina, linux-kernel, broonie, daniel,
	gregkh, joe, davem

On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:

> +menuconfig SLIMBUS
> +	tristate "Slimbus support"
> +	help
> +	  Slimbus is standard interface between System-on-Chip and audio codec,
> +	  and other peripheral components in typical embedded systems.
> +
> +	  If unsure, choose N.
> +
> +if SLIMBUS
> +
> +# SlIMbus controllers

Slimbus perhaps?

> +static int slim_device_match(struct device *dev, struct device_driver *drv)
> +{
> +	struct slim_device *sbdev = to_slim_device(dev);
> +	struct slim_driver *sbdrv = to_slim_driver(drv);
> +
> +	return slim_match(sbdrv->id_table, sbdev) != NULL;

return !!slim_match() ?

> +static int slim_device_probe(struct device *dev)
> +{
> +	struct slim_device	*sbdev;
> +	struct slim_driver	*sbdrv;
> +	int ret = 0;
> +
> +	sbdev = to_slim_device(dev);
> +	sbdrv = to_slim_driver(dev->driver);
> +
> +	if (sbdrv->probe)
> +		ret = sbdrv->probe(sbdev);

shouldn't probe be mandatory :)

> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 1c2e8d6b7274..7d6238863fc1 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -452,6 +452,19 @@ struct spi_device_id {
>  	kernel_ulong_t driver_data;	/* Data private to the driver */
>  };
>  
> +/* SLIMbus */
> +
> +#define SLIMBUS_NAME_SIZE	32
> +#define SLIMBUS_MODULE_PREFIX	"slim:"
> +
> +struct slim_device_id {
> +	__u16 manf_id, prod_code;
> +	__u8 dev_index, instance;
> +
> +	/* Data private to the driver */
> +	kernel_ulong_t driver_data;

As Takashi pointed out in SDW patches, this needs to be aligned.

> +};
> +

I was hoping to see changes to devicetable-offsets.c and file2alias.c as
well as that is required for module autoloading. I think that is required?

> +/**
> + * struct slim_device - Slim device handle.
> + * @dev: Driver model representation of the device.
> + * @name: Name of driver to use with this device.
> + * @e_addr: Enumeration address of this device.
> + * @driver: Device's driver. Pointer to access routines.
> + * @laddr: 1-byte Logical address of this device.
> + *
> + * This is the client/device handle returned when a slimbus
> + * device is registered with a controller.
> + * Pointer to this structure is used by client-driver as a handle.
> + */
> +struct slim_device {
> +	struct device		dev;
> +	struct slim_eaddr	e_addr;
> +	struct list_head node;

aligned with others please

> +/**
> + * struct slim_driver - Slimbus 'generic device' (slave) device driver
> + *				(similar to 'spi_device' on SPI)
> + * @probe: Binds this driver to a slimbus device.
> + * @remove: Unbinds this driver from the slimbus device.
> + * @shutdown: Standard shutdown callback used during powerdown/halt.
> + * @device_status: This callback is called when
> + *	-The device reports present and gets a laddr assigned
> + *	-The device reports absent, or the bus goes down.

space after - pls

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 03/13] slimbus: Add SLIMbus bus type
@ 2017-11-16 13:18     ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 13:18 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, mark.rutland, michael.opdenacker,
	poeschel, andreas.noever, arnd, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:

> +menuconfig SLIMBUS
> +	tristate "Slimbus support"
> +	help
> +	  Slimbus is standard interface between System-on-Chip and audio codec,
> +	  and other peripheral components in typical embedded systems.
> +
> +	  If unsure, choose N.
> +
> +if SLIMBUS
> +
> +# SlIMbus controllers

Slimbus perhaps?

> +static int slim_device_match(struct device *dev, struct device_driver *drv)
> +{
> +	struct slim_device *sbdev = to_slim_device(dev);
> +	struct slim_driver *sbdrv = to_slim_driver(drv);
> +
> +	return slim_match(sbdrv->id_table, sbdev) != NULL;

return !!slim_match() ?

> +static int slim_device_probe(struct device *dev)
> +{
> +	struct slim_device	*sbdev;
> +	struct slim_driver	*sbdrv;
> +	int ret = 0;
> +
> +	sbdev = to_slim_device(dev);
> +	sbdrv = to_slim_driver(dev->driver);
> +
> +	if (sbdrv->probe)
> +		ret = sbdrv->probe(sbdev);

shouldn't probe be mandatory :)

> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 1c2e8d6b7274..7d6238863fc1 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -452,6 +452,19 @@ struct spi_device_id {
>  	kernel_ulong_t driver_data;	/* Data private to the driver */
>  };
>  
> +/* SLIMbus */
> +
> +#define SLIMBUS_NAME_SIZE	32
> +#define SLIMBUS_MODULE_PREFIX	"slim:"
> +
> +struct slim_device_id {
> +	__u16 manf_id, prod_code;
> +	__u8 dev_index, instance;
> +
> +	/* Data private to the driver */
> +	kernel_ulong_t driver_data;

As Takashi pointed out in SDW patches, this needs to be aligned.

> +};
> +

I was hoping to see changes to devicetable-offsets.c and file2alias.c as
well as that is required for module autoloading. I think that is required?

> +/**
> + * struct slim_device - Slim device handle.
> + * @dev: Driver model representation of the device.
> + * @name: Name of driver to use with this device.
> + * @e_addr: Enumeration address of this device.
> + * @driver: Device's driver. Pointer to access routines.
> + * @laddr: 1-byte Logical address of this device.
> + *
> + * This is the client/device handle returned when a slimbus
> + * device is registered with a controller.
> + * Pointer to this structure is used by client-driver as a handle.
> + */
> +struct slim_device {
> +	struct device		dev;
> +	struct slim_eaddr	e_addr;
> +	struct list_head node;

aligned with others please

> +/**
> + * struct slim_driver - Slimbus 'generic device' (slave) device driver
> + *				(similar to 'spi_device' on SPI)
> + * @probe: Binds this driver to a slimbus device.
> + * @remove: Unbinds this driver from the slimbus device.
> + * @shutdown: Standard shutdown callback used during powerdown/halt.
> + * @device_status: This callback is called when
> + *	-The device reports present and gets a laddr assigned
> + *	-The device reports absent, or the bus goes down.

space after - pls

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 03/13] slimbus: Add SLIMbus bus type
  2017-11-16 13:18     ` [alsa-devel] " Vinod Koul
@ 2017-11-16 13:40       ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 13:40 UTC (permalink / raw)
  To: Vinod Koul
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, treding, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	bp, mathieu.poirier, jkosina, linux-kernel, broonie, daniel,
	gregkh, joe, davem

Thanks for the review.

On 16/11/17 13:18, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:
> 
>> +menuconfig SLIMBUS
>> +	tristate "Slimbus support"
>> +	help
>> +	  Slimbus is standard interface between System-on-Chip and audio codec,
>> +	  and other peripheral components in typical embedded systems.
>> +
>> +	  If unsure, choose N.
>> +
>> +if SLIMBUS
>> +
>> +# SlIMbus controllers
> 
> Slimbus perhaps?
> 
slimbus is specified as "SLIMbus" in the mipi specs, so I should 
probably stay with it and make it consistent across the patchset.


>> +static int slim_device_match(struct device *dev, struct device_driver *drv)
>> +{
>> +	struct slim_device *sbdev = to_slim_device(dev);
>> +	struct slim_driver *sbdrv = to_slim_driver(drv);
>> +
>> +	return slim_match(sbdrv->id_table, sbdev) != NULL;
> 
> return !!slim_match() ?
> 
>> +static int slim_device_probe(struct device *dev)
>> +{
>> +	struct slim_device	*sbdev;
>> +	struct slim_driver	*sbdrv;
>> +	int ret = 0;
>> +
>> +	sbdev = to_slim_device(dev);
>> +	sbdrv = to_slim_driver(dev->driver);
>> +
>> +	if (sbdrv->probe)
>> +		ret = sbdrv->probe(sbdev);
> 
> shouldn't probe be mandatory :)
Yep it is .. I will fix that..
> 
>> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
>> index 1c2e8d6b7274..7d6238863fc1 100644
>> --- a/include/linux/mod_devicetable.h
>> +++ b/include/linux/mod_devicetable.h
>> @@ -452,6 +452,19 @@ struct spi_device_id {
>>   	kernel_ulong_t driver_data;	/* Data private to the driver */
>>   };
>>   
>> +/* SLIMbus */
>> +
>> +#define SLIMBUS_NAME_SIZE	32
>> +#define SLIMBUS_MODULE_PREFIX	"slim:"
>> +
>> +struct slim_device_id {
>> +	__u16 manf_id, prod_code;
>> +	__u8 dev_index, instance;
>> +
>> +	/* Data private to the driver */
>> +	kernel_ulong_t driver_data;
> 
> As Takashi pointed out in SDW patches, this needs to be aligned.
> 
Okay, I will make sure that driver_data is aligned.

>> +};
>> +
> 
> I was hoping to see changes to devicetable-offsets.c and file2alias.c as
> well as that is required for module autoloading. I think that is required?
> 
>> +/**
>> + * struct slim_device - Slim device handle.
>> + * @dev: Driver model representation of the device.
>> + * @name: Name of driver to use with this device.
>> + * @e_addr: Enumeration address of this device.
>> + * @driver: Device's driver. Pointer to access routines.
>> + * @laddr: 1-byte Logical address of this device.
>> + *
>> + * This is the client/device handle returned when a slimbus
>> + * device is registered with a controller.
>> + * Pointer to this structure is used by client-driver as a handle.
>> + */
>> +struct slim_device {
>> +	struct device		dev;
>> +	struct slim_eaddr	e_addr;
>> +	struct list_head node;
> 
> aligned with others please
> 
Thanks for spotting, this looks like a leftover, There is no use of node 
in this structure so I will remove it in next version.

>> +/**
>> + * struct slim_driver - Slimbus 'generic device' (slave) device driver
>> + *				(similar to 'spi_device' on SPI)
>> + * @probe: Binds this driver to a slimbus device.
>> + * @remove: Unbinds this driver from the slimbus device.
>> + * @shutdown: Standard shutdown callback used during powerdown/halt.
>> + * @device_status: This callback is called when
>> + *	-The device reports present and gets a laddr assigned
>> + *	-The device reports absent, or the bus goes down.
> 
> space after - pls
Yep.. will do that.
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 03/13] slimbus: Add SLIMbus bus type
@ 2017-11-16 13:40       ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 13:40 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh, broonie, alsa-devel, mark.rutland, michael.opdenacker,
	poeschel, andreas.noever, arnd, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

Thanks for the review.

On 16/11/17 13:18, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:
> 
>> +menuconfig SLIMBUS
>> +	tristate "Slimbus support"
>> +	help
>> +	  Slimbus is standard interface between System-on-Chip and audio codec,
>> +	  and other peripheral components in typical embedded systems.
>> +
>> +	  If unsure, choose N.
>> +
>> +if SLIMBUS
>> +
>> +# SlIMbus controllers
> 
> Slimbus perhaps?
> 
slimbus is specified as "SLIMbus" in the mipi specs, so I should 
probably stay with it and make it consistent across the patchset.


>> +static int slim_device_match(struct device *dev, struct device_driver *drv)
>> +{
>> +	struct slim_device *sbdev = to_slim_device(dev);
>> +	struct slim_driver *sbdrv = to_slim_driver(drv);
>> +
>> +	return slim_match(sbdrv->id_table, sbdev) != NULL;
> 
> return !!slim_match() ?
> 
>> +static int slim_device_probe(struct device *dev)
>> +{
>> +	struct slim_device	*sbdev;
>> +	struct slim_driver	*sbdrv;
>> +	int ret = 0;
>> +
>> +	sbdev = to_slim_device(dev);
>> +	sbdrv = to_slim_driver(dev->driver);
>> +
>> +	if (sbdrv->probe)
>> +		ret = sbdrv->probe(sbdev);
> 
> shouldn't probe be mandatory :)
Yep it is .. I will fix that..
> 
>> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
>> index 1c2e8d6b7274..7d6238863fc1 100644
>> --- a/include/linux/mod_devicetable.h
>> +++ b/include/linux/mod_devicetable.h
>> @@ -452,6 +452,19 @@ struct spi_device_id {
>>   	kernel_ulong_t driver_data;	/* Data private to the driver */
>>   };
>>   
>> +/* SLIMbus */
>> +
>> +#define SLIMBUS_NAME_SIZE	32
>> +#define SLIMBUS_MODULE_PREFIX	"slim:"
>> +
>> +struct slim_device_id {
>> +	__u16 manf_id, prod_code;
>> +	__u8 dev_index, instance;
>> +
>> +	/* Data private to the driver */
>> +	kernel_ulong_t driver_data;
> 
> As Takashi pointed out in SDW patches, this needs to be aligned.
> 
Okay, I will make sure that driver_data is aligned.

>> +};
>> +
> 
> I was hoping to see changes to devicetable-offsets.c and file2alias.c as
> well as that is required for module autoloading. I think that is required?
> 
>> +/**
>> + * struct slim_device - Slim device handle.
>> + * @dev: Driver model representation of the device.
>> + * @name: Name of driver to use with this device.
>> + * @e_addr: Enumeration address of this device.
>> + * @driver: Device's driver. Pointer to access routines.
>> + * @laddr: 1-byte Logical address of this device.
>> + *
>> + * This is the client/device handle returned when a slimbus
>> + * device is registered with a controller.
>> + * Pointer to this structure is used by client-driver as a handle.
>> + */
>> +struct slim_device {
>> +	struct device		dev;
>> +	struct slim_eaddr	e_addr;
>> +	struct list_head node;
> 
> aligned with others please
> 
Thanks for spotting, this looks like a leftover, There is no use of node 
in this structure so I will remove it in next version.

>> +/**
>> + * struct slim_driver - Slimbus 'generic device' (slave) device driver
>> + *				(similar to 'spi_device' on SPI)
>> + * @probe: Binds this driver to a slimbus device.
>> + * @remove: Unbinds this driver from the slimbus device.
>> + * @shutdown: Standard shutdown callback used during powerdown/halt.
>> + * @device_status: This callback is called when
>> + *	-The device reports present and gets a laddr assigned
>> + *	-The device reports absent, or the bus goes down.
> 
> space after - pls
Yep.. will do that.
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
  2017-11-16 13:09   ` Vinod Koul
@ 2017-11-16 13:40       ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 13:40 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4

Thanks for the review comments.

On 16/11/17 13:09, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
>> From: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>
>> +
>> +Child nodes:
>> +Every SLIMbus controller node can contain zero or more child nodes
>> +representing slave devices on the bus. Every SLIMbus slave device is
>> +uniquely determined by the enumeration address containing 4 fields:
>> +Manufacturer ID, Product code, Device index, and Instance value for
>> +the device.
>> +If child node is not present and it is instantiated after device
>> +discovery (slave device reporting itself present).
> 
> So you allow the devices to work even if the respective firmware description
> is absent?
Yes, As SLIMbus itself itself is discoverable bus.

> 
>> +
>> +In some cases it may be necessary to describe non-probeable device
>> +details such as non-standard ways of powering up a device. In
>> +such cases, child nodes for those devices will be present as
>> +slaves of the slimbus-controller, as detailed below.
>> +
>> +Required property for SLIMbus child node if it is present:
>> +- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
>> +		  Enumeration  Address.
>> +		  Device Index Uniquely identifies multiple Devices within
>> +		  a single Component.
>> +		  Instance ID Is for the cases where multiple Devices of the
>> +		  same type or Class are attached to the bus.
>> +
>> +- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
>> +	 	  Product Code, shall be in lower case hexadecimal with leading
>> +		  zeroes suppressed
>> +

>> +		codec: wcd9310@1,0{
>> +			compatible = "slim217,60";
>> +			reg = <1 0>;
>> +		};
>> +	};
> 
> Pardon my ignorance as I am not very familiar with DT nodes, but where are
> the Manufacturer ID, Product code, Device index, and Instance values here?

Manfacturer ID and Product code is part of compatible string
Device index and Instance value are part of reg.

> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
@ 2017-11-16 13:40       ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 13:40 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

Thanks for the review comments.

On 16/11/17 13:09, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
>> From: Sagar Dharia <sdharia@codeaurora.org>
>
>> +
>> +Child nodes:
>> +Every SLIMbus controller node can contain zero or more child nodes
>> +representing slave devices on the bus. Every SLIMbus slave device is
>> +uniquely determined by the enumeration address containing 4 fields:
>> +Manufacturer ID, Product code, Device index, and Instance value for
>> +the device.
>> +If child node is not present and it is instantiated after device
>> +discovery (slave device reporting itself present).
> 
> So you allow the devices to work even if the respective firmware description
> is absent?
Yes, As SLIMbus itself itself is discoverable bus.

> 
>> +
>> +In some cases it may be necessary to describe non-probeable device
>> +details such as non-standard ways of powering up a device. In
>> +such cases, child nodes for those devices will be present as
>> +slaves of the slimbus-controller, as detailed below.
>> +
>> +Required property for SLIMbus child node if it is present:
>> +- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
>> +		  Enumeration  Address.
>> +		  Device Index Uniquely identifies multiple Devices within
>> +		  a single Component.
>> +		  Instance ID Is for the cases where multiple Devices of the
>> +		  same type or Class are attached to the bus.
>> +
>> +- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
>> +	 	  Product Code, shall be in lower case hexadecimal with leading
>> +		  zeroes suppressed
>> +

>> +		codec: wcd9310@1,0{
>> +			compatible = "slim217,60";
>> +			reg = <1 0>;
>> +		};
>> +	};
> 
> Pardon my ignorance as I am not very familiar with DT nodes, but where are
> the Manufacturer ID, Product code, Device index, and Instance values here?

Manfacturer ID and Product code is part of compatible string
Device index and Instance value are part of reg.

> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 03/13] slimbus: Add SLIMbus bus type
  2017-11-16 16:14           ` Vinod Koul
@ 2017-11-16 16:13             ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 16:13 UTC (permalink / raw)
  To: Vinod Koul
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, treding, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	bp, mathieu.poirier, jkosina, linux-kernel, broonie, daniel,
	gregkh, joe, davem



On 16/11/17 16:14, Vinod Koul wrote:
>>>> +static int slim_device_match(struct device *dev, struct device_driver *drv)
>>>> +{
>>>> +	struct slim_device *sbdev = to_slim_device(dev);
>>>> +	struct slim_driver *sbdrv = to_slim_driver(drv);
>>>> +
>>>> +	return slim_match(sbdrv->id_table, sbdev) != NULL;
>>> return !!slim_match() ?
> I guess you missed this one..
Opps, It makes sense I will change it.

> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 03/13] slimbus: Add SLIMbus bus type
@ 2017-11-16 16:13             ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 16:13 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh, broonie, alsa-devel, mark.rutland, michael.opdenacker,
	poeschel, andreas.noever, arnd, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem



On 16/11/17 16:14, Vinod Koul wrote:
>>>> +static int slim_device_match(struct device *dev, struct device_driver *drv)
>>>> +{
>>>> +	struct slim_device *sbdev = to_slim_device(dev);
>>>> +	struct slim_driver *sbdrv = to_slim_driver(drv);
>>>> +
>>>> +	return slim_match(sbdrv->id_table, sbdev) != NULL;
>>> return !!slim_match() ?
> I guess you missed this one..
Opps, It makes sense I will change it.

> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 03/13] slimbus: Add SLIMbus bus type
  2017-11-16 13:40       ` [alsa-devel] " Srinivas Kandagatla
@ 2017-11-16 16:14           ` Vinod Koul
  -1 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 16:14 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, mark.rutland-5wv7dgnIgG8,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w, arnd-r2nGTMty4D4,
	bp-l3A5Bk7waGM, devicetree-u79uwXL29TY76Z2rM5mHXA,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA, pawel.moll-5wv7dgnIgG8,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sdharia-sgV2jX0FEOL9JmXXK+q4OQ,
	alan-VuQAYsv1563Yd54FQh9/CA, treding-DDmLM1+adcrQT0dZR+AlfA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, jkosina-AlSwsSmVLrQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, daniel-/w4YWyX8dFk,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On Thu, Nov 16, 2017 at 01:40:05PM +0000, Srinivas Kandagatla wrote:
> On 16/11/17 13:18, Vinod Koul wrote:
> >On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
> >
> >>+menuconfig SLIMBUS
> >>+	tristate "Slimbus support"
> >>+	help
> >>+	  Slimbus is standard interface between System-on-Chip and audio codec,
> >>+	  and other peripheral components in typical embedded systems.
> >>+
> >>+	  If unsure, choose N.
> >>+
> >>+if SLIMBUS
> >>+
> >>+# SlIMbus controllers
> >
> >Slimbus perhaps?
> >
> slimbus is specified as "SLIMbus" in the mipi specs, so I should probably
> stay with it and make it consistent across the patchset.

Yeah this I though was a first use, so I though this was a typo. I think
Documentation should use the spec term (like SoundWire) and code should pick
anyone and just be consistent on it.

> >>+static int slim_device_match(struct device *dev, struct device_driver *drv)
> >>+{
> >>+	struct slim_device *sbdev = to_slim_device(dev);
> >>+	struct slim_driver *sbdrv = to_slim_driver(drv);
> >>+
> >>+	return slim_match(sbdrv->id_table, sbdev) != NULL;
> >
> >return !!slim_match() ?

I guess you missed this one..

> >>+struct slim_device_id {
> >>+	__u16 manf_id, prod_code;
> >>+	__u8 dev_index, instance;
> >>+
> >>+	/* Data private to the driver */
> >>+	kernel_ulong_t driver_data;
> >
> >As Takashi pointed out in SDW patches, this needs to be aligned.
> >
> Okay, I will make sure that driver_data is aligned.

You may want to look at comments and disucssion on the SoundWire patches

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 03/13] slimbus: Add SLIMbus bus type
@ 2017-11-16 16:14           ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 16:14 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: gregkh, broonie, alsa-devel, mark.rutland, michael.opdenacker,
	poeschel, andreas.noever, arnd, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

On Thu, Nov 16, 2017 at 01:40:05PM +0000, Srinivas Kandagatla wrote:
> On 16/11/17 13:18, Vinod Koul wrote:
> >On Wed, Nov 15, 2017 at 02:10:33PM +0000, srinivas.kandagatla@linaro.org wrote:
> >
> >>+menuconfig SLIMBUS
> >>+	tristate "Slimbus support"
> >>+	help
> >>+	  Slimbus is standard interface between System-on-Chip and audio codec,
> >>+	  and other peripheral components in typical embedded systems.
> >>+
> >>+	  If unsure, choose N.
> >>+
> >>+if SLIMBUS
> >>+
> >>+# SlIMbus controllers
> >
> >Slimbus perhaps?
> >
> slimbus is specified as "SLIMbus" in the mipi specs, so I should probably
> stay with it and make it consistent across the patchset.

Yeah this I though was a first use, so I though this was a typo. I think
Documentation should use the spec term (like SoundWire) and code should pick
anyone and just be consistent on it.

> >>+static int slim_device_match(struct device *dev, struct device_driver *drv)
> >>+{
> >>+	struct slim_device *sbdev = to_slim_device(dev);
> >>+	struct slim_driver *sbdrv = to_slim_driver(drv);
> >>+
> >>+	return slim_match(sbdrv->id_table, sbdev) != NULL;
> >
> >return !!slim_match() ?

I guess you missed this one..

> >>+struct slim_device_id {
> >>+	__u16 manf_id, prod_code;
> >>+	__u8 dev_index, instance;
> >>+
> >>+	/* Data private to the driver */
> >>+	kernel_ulong_t driver_data;
> >
> >As Takashi pointed out in SDW patches, this needs to be aligned.
> >
> Okay, I will make sure that driver_data is aligned.

You may want to look at comments and disucssion on the SoundWire patches

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-15 14:10 ` [PATCH v7 04/13] slimbus: core: Add slim controllers support srinivas.kandagatla
@ 2017-11-16 16:42     ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 16:42 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, treding, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	bp, mathieu.poirier, gregkh, linux-kernel, broonie, daniel,
	jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:34PM +0000, srinivas.kandagatla@linaro.org wrote:

> +static void slim_dev_release(struct device *dev)
> +{
> +	struct slim_device *sbdev = to_slim_device(dev);
> +
> +	put_device(sbdev->ctrl->dev);

which device would that be?

> +static int slim_add_device(struct slim_controller *ctrl,
> +			   struct slim_device *sbdev,
> +			   struct device_node *node)
> +{
> +	sbdev->dev.bus = &slimbus_bus;
> +	sbdev->dev.parent = ctrl->dev;
> +	sbdev->dev.release = slim_dev_release;
> +	sbdev->dev.driver = NULL;
> +	sbdev->ctrl = ctrl;
> +
> +	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
> +				  sbdev->e_addr.manf_id,
> +				  sbdev->e_addr.prod_code,
> +				  sbdev->e_addr.dev_index,
> +				  sbdev->e_addr.instance);
> +
> +	get_device(ctrl->dev);

is this controller device and you ensuring it doesnt go away while you have
slaves on it?

> +static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
> +					     struct slim_eaddr *eaddr,
> +					     struct device_node *node)
> +{
> +	struct slim_device *sbdev;
> +	int ret;
> +
> +	sbdev = kzalloc(sizeof(struct slim_device), GFP_KERNEL);

Usual kernel way of doing is kzalloc(*sbdev)

> +void slim_report_absent(struct slim_device *sbdev)
> +{
> +	struct slim_controller *ctrl = sbdev->ctrl;
> +
> +	if (!ctrl)
> +		return;
> +
> +	/* invalidate logical addresses */
> +	mutex_lock(&ctrl->lock);
> +	sbdev->is_laddr_valid = false;
> +	mutex_unlock(&ctrl->lock);
> +
> +	ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr);
> +	slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
> +}
> +EXPORT_SYMBOL_GPL(slim_report_absent);

Do you have APIs for report present too, if so why not add te status in
argument as you may have common handling

> +static int slim_device_alloc_laddr(struct slim_device *sbdev,
> +				   u8 *laddr, bool report_present)
> +{
> +	struct slim_controller *ctrl = sbdev->ctrl;
> +	int ret;
> +
> +	mutex_lock(&ctrl->lock);
> +	if (ctrl->get_laddr) {
> +		ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, laddr);
> +		if (ret < 0)
> +			goto err;
> +	} else if (report_present) {
> +		ret = ida_simple_get(&ctrl->laddr_ida,
> +				     0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
> +		if (ret < 0)
> +			goto err;
> +
> +		*laddr = ret;
> +	} else {
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (ctrl->set_laddr) {
> +		ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, *laddr);
> +		if (ret) {
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +	}
> +
> +	sbdev->laddr = *laddr;

if you have this in sbdev, then why have this as an arg also?

> +	sbdev->is_laddr_valid = true;

shouldn't non-zero value signify that?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
@ 2017-11-16 16:42     ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-16 16:42 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Wed, Nov 15, 2017 at 02:10:34PM +0000, srinivas.kandagatla@linaro.org wrote:

> +static void slim_dev_release(struct device *dev)
> +{
> +	struct slim_device *sbdev = to_slim_device(dev);
> +
> +	put_device(sbdev->ctrl->dev);

which device would that be?

> +static int slim_add_device(struct slim_controller *ctrl,
> +			   struct slim_device *sbdev,
> +			   struct device_node *node)
> +{
> +	sbdev->dev.bus = &slimbus_bus;
> +	sbdev->dev.parent = ctrl->dev;
> +	sbdev->dev.release = slim_dev_release;
> +	sbdev->dev.driver = NULL;
> +	sbdev->ctrl = ctrl;
> +
> +	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
> +				  sbdev->e_addr.manf_id,
> +				  sbdev->e_addr.prod_code,
> +				  sbdev->e_addr.dev_index,
> +				  sbdev->e_addr.instance);
> +
> +	get_device(ctrl->dev);

is this controller device and you ensuring it doesnt go away while you have
slaves on it?

> +static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
> +					     struct slim_eaddr *eaddr,
> +					     struct device_node *node)
> +{
> +	struct slim_device *sbdev;
> +	int ret;
> +
> +	sbdev = kzalloc(sizeof(struct slim_device), GFP_KERNEL);

Usual kernel way of doing is kzalloc(*sbdev)

> +void slim_report_absent(struct slim_device *sbdev)
> +{
> +	struct slim_controller *ctrl = sbdev->ctrl;
> +
> +	if (!ctrl)
> +		return;
> +
> +	/* invalidate logical addresses */
> +	mutex_lock(&ctrl->lock);
> +	sbdev->is_laddr_valid = false;
> +	mutex_unlock(&ctrl->lock);
> +
> +	ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr);
> +	slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
> +}
> +EXPORT_SYMBOL_GPL(slim_report_absent);

Do you have APIs for report present too, if so why not add te status in
argument as you may have common handling

> +static int slim_device_alloc_laddr(struct slim_device *sbdev,
> +				   u8 *laddr, bool report_present)
> +{
> +	struct slim_controller *ctrl = sbdev->ctrl;
> +	int ret;
> +
> +	mutex_lock(&ctrl->lock);
> +	if (ctrl->get_laddr) {
> +		ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, laddr);
> +		if (ret < 0)
> +			goto err;
> +	} else if (report_present) {
> +		ret = ida_simple_get(&ctrl->laddr_ida,
> +				     0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
> +		if (ret < 0)
> +			goto err;
> +
> +		*laddr = ret;
> +	} else {
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (ctrl->set_laddr) {
> +		ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, *laddr);
> +		if (ret) {
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +	}
> +
> +	sbdev->laddr = *laddr;

if you have this in sbdev, then why have this as an arg also?

> +	sbdev->is_laddr_valid = true;

shouldn't non-zero value signify that?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-16 16:42     ` Vinod Koul
@ 2017-11-16 17:29       ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 17:29 UTC (permalink / raw)
  To: Vinod Koul
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, treding, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	bp, mathieu.poirier, gregkh, linux-kernel, broonie, daniel,
	jkosina, joe, davem

thanks for the comments.


On 16/11/17 16:42, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:34PM +0000, srinivas.kandagatla@linaro.org wrote:
> 
>> +static void slim_dev_release(struct device *dev)
>> +{
>> +	struct slim_device *sbdev = to_slim_device(dev);
>> +
>> +	put_device(sbdev->ctrl->dev);
> 
> which device would that be?
This is controller device

> 
>> +static int slim_add_device(struct slim_controller *ctrl,
>> +			   struct slim_device *sbdev,
>> +			   struct device_node *node)
>> +{
>> +	sbdev->dev.bus = &slimbus_bus;
>> +	sbdev->dev.parent = ctrl->dev;
>> +	sbdev->dev.release = slim_dev_release;
>> +	sbdev->dev.driver = NULL;
>> +	sbdev->ctrl = ctrl;
>> +
>> +	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
>> +				  sbdev->e_addr.manf_id,
>> +				  sbdev->e_addr.prod_code,
>> +				  sbdev->e_addr.dev_index,
>> +				  sbdev->e_addr.instance);
>> +
>> +	get_device(ctrl->dev);
> 
> is this controller device and you ensuring it doesnt go away while you have
> slaves on it?

Yes.

> 
>> +static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
>> +					     struct slim_eaddr *eaddr,
>> +					     struct device_node *node)
>> +{
>> +	struct slim_device *sbdev;
>> +	int ret;
>> +
>> +	sbdev = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
> 
> Usual kernel way of doing is kzalloc(*sbdev)
> 
I agree will fix it in next version.

>> +void slim_report_absent(struct slim_device *sbdev)
>> +{
>> +	struct slim_controller *ctrl = sbdev->ctrl;
>> +
>> +	if (!ctrl)
>> +		return;
>> +
>> +	/* invalidate logical addresses */
>> +	mutex_lock(&ctrl->lock);
>> +	sbdev->is_laddr_valid = false;
>> +	mutex_unlock(&ctrl->lock);
>> +
>> +	ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr);
>> +	slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
>> +}
>> +EXPORT_SYMBOL_GPL(slim_report_absent);
> 
> Do you have APIs for report present too, if so why not add te status in
> argument as you may have common handling
Yes, We do  have api for reporting too, I will give it a try to combine 
both.

> 
>> +static int slim_device_alloc_laddr(struct slim_device *sbdev,
>> +				   u8 *laddr, bool report_present)
>> +{
>> +	struct slim_controller *ctrl = sbdev->ctrl;
>> +	int ret;
>> +
>> +	mutex_lock(&ctrl->lock);
>> +	if (ctrl->get_laddr) {
>> +		ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, laddr);
>> +		if (ret < 0)
>> +			goto err;
>> +	} else if (report_present) {
>> +		ret = ida_simple_get(&ctrl->laddr_ida,
>> +				     0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
>> +		if (ret < 0)
>> +			goto err;
>> +
>> +		*laddr = ret;
>> +	} else {
>> +		ret = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	if (ctrl->set_laddr) {
>> +		ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, *laddr);
>> +		if (ret) {
>> +			ret = -EINVAL;
>> +			goto err;
>> +		}
>> +	}
>> +
>> +	sbdev->laddr = *laddr;
> 
> if you have this in sbdev, then why have this as an arg also?
Yes makes sens, laddr argument in this function is redundant, it can be 
removed totally.
> 
>> +	sbdev->is_laddr_valid = true;
> 
> shouldn't non-zero value signify that?
0 is also a valid laddr.

> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
@ 2017-11-16 17:29       ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-16 17:29 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

thanks for the comments.


On 16/11/17 16:42, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:34PM +0000, srinivas.kandagatla@linaro.org wrote:
> 
>> +static void slim_dev_release(struct device *dev)
>> +{
>> +	struct slim_device *sbdev = to_slim_device(dev);
>> +
>> +	put_device(sbdev->ctrl->dev);
> 
> which device would that be?
This is controller device

> 
>> +static int slim_add_device(struct slim_controller *ctrl,
>> +			   struct slim_device *sbdev,
>> +			   struct device_node *node)
>> +{
>> +	sbdev->dev.bus = &slimbus_bus;
>> +	sbdev->dev.parent = ctrl->dev;
>> +	sbdev->dev.release = slim_dev_release;
>> +	sbdev->dev.driver = NULL;
>> +	sbdev->ctrl = ctrl;
>> +
>> +	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
>> +				  sbdev->e_addr.manf_id,
>> +				  sbdev->e_addr.prod_code,
>> +				  sbdev->e_addr.dev_index,
>> +				  sbdev->e_addr.instance);
>> +
>> +	get_device(ctrl->dev);
> 
> is this controller device and you ensuring it doesnt go away while you have
> slaves on it?

Yes.

> 
>> +static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
>> +					     struct slim_eaddr *eaddr,
>> +					     struct device_node *node)
>> +{
>> +	struct slim_device *sbdev;
>> +	int ret;
>> +
>> +	sbdev = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
> 
> Usual kernel way of doing is kzalloc(*sbdev)
> 
I agree will fix it in next version.

>> +void slim_report_absent(struct slim_device *sbdev)
>> +{
>> +	struct slim_controller *ctrl = sbdev->ctrl;
>> +
>> +	if (!ctrl)
>> +		return;
>> +
>> +	/* invalidate logical addresses */
>> +	mutex_lock(&ctrl->lock);
>> +	sbdev->is_laddr_valid = false;
>> +	mutex_unlock(&ctrl->lock);
>> +
>> +	ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr);
>> +	slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
>> +}
>> +EXPORT_SYMBOL_GPL(slim_report_absent);
> 
> Do you have APIs for report present too, if so why not add te status in
> argument as you may have common handling
Yes, We do  have api for reporting too, I will give it a try to combine 
both.

> 
>> +static int slim_device_alloc_laddr(struct slim_device *sbdev,
>> +				   u8 *laddr, bool report_present)
>> +{
>> +	struct slim_controller *ctrl = sbdev->ctrl;
>> +	int ret;
>> +
>> +	mutex_lock(&ctrl->lock);
>> +	if (ctrl->get_laddr) {
>> +		ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, laddr);
>> +		if (ret < 0)
>> +			goto err;
>> +	} else if (report_present) {
>> +		ret = ida_simple_get(&ctrl->laddr_ida,
>> +				     0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
>> +		if (ret < 0)
>> +			goto err;
>> +
>> +		*laddr = ret;
>> +	} else {
>> +		ret = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	if (ctrl->set_laddr) {
>> +		ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, *laddr);
>> +		if (ret) {
>> +			ret = -EINVAL;
>> +			goto err;
>> +		}
>> +	}
>> +
>> +	sbdev->laddr = *laddr;
> 
> if you have this in sbdev, then why have this as an arg also?
Yes makes sens, laddr argument in this function is redundant, it can be 
removed totally.
> 
>> +	sbdev->is_laddr_valid = true;
> 
> shouldn't non-zero value signify that?
0 is also a valid laddr.

> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
  2017-11-16 13:40       ` Srinivas Kandagatla
@ 2017-11-17  3:55           ` Vinod Koul
  -1 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  3:55 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4

On Thu, Nov 16, 2017 at 01:40:13PM +0000, Srinivas Kandagatla wrote:
> Thanks for the review comments.
> 
> On 16/11/17 13:09, Vinod Koul wrote:
> >On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
> >>From: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> >
> >>+
> >>+Child nodes:
> >>+Every SLIMbus controller node can contain zero or more child nodes
> >>+representing slave devices on the bus. Every SLIMbus slave device is
> >>+uniquely determined by the enumeration address containing 4 fields:
> >>+Manufacturer ID, Product code, Device index, and Instance value for
> >>+the device.
> >>+If child node is not present and it is instantiated after device
> >>+discovery (slave device reporting itself present).
> >
> >So you allow the devices to work even if the respective firmware description
> >is absent?
> Yes, As SLIMbus itself itself is discoverable bus.

Okay, in SDW we mandate description be present in respective firmwares so we
dont have this path. In theory this never works for you as driver cant load
without device being created and without driver load device is not powered
up so can't report...

> >>+In some cases it may be necessary to describe non-probeable device
> >>+details such as non-standard ways of powering up a device. In
> >>+such cases, child nodes for those devices will be present as
> >>+slaves of the slimbus-controller, as detailed below.
> >>+
> >>+Required property for SLIMbus child node if it is present:
> >>+- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
> >>+		  Enumeration  Address.
> >>+		  Device Index Uniquely identifies multiple Devices within
> >>+		  a single Component.
> >>+		  Instance ID Is for the cases where multiple Devices of the
> >>+		  same type or Class are attached to the bus.
> >>+
> >>+- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
> >>+	 	  Product Code, shall be in lower case hexadecimal with leading
> >>+		  zeroes suppressed
> >>+
> 
> >>+		codec: wcd9310@1,0{
> >>+			compatible = "slim217,60";
> >>+			reg = <1 0>;
> >>+		};
> >>+	};
> >
> >Pardon my ignorance as I am not very familiar with DT nodes, but where are
> >the Manufacturer ID, Product code, Device index, and Instance values here?
> 
> Manfacturer ID and Product code is part of compatible string
> Device index and Instance value are part of reg.

hmmm, wouldn't it be more helpful to have a field(s) for these which contain
these numbers rather than coded together in a word

compatible makes sense though

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
@ 2017-11-17  3:55           ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  3:55 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Thu, Nov 16, 2017 at 01:40:13PM +0000, Srinivas Kandagatla wrote:
> Thanks for the review comments.
> 
> On 16/11/17 13:09, Vinod Koul wrote:
> >On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
> >>From: Sagar Dharia <sdharia@codeaurora.org>
> >
> >>+
> >>+Child nodes:
> >>+Every SLIMbus controller node can contain zero or more child nodes
> >>+representing slave devices on the bus. Every SLIMbus slave device is
> >>+uniquely determined by the enumeration address containing 4 fields:
> >>+Manufacturer ID, Product code, Device index, and Instance value for
> >>+the device.
> >>+If child node is not present and it is instantiated after device
> >>+discovery (slave device reporting itself present).
> >
> >So you allow the devices to work even if the respective firmware description
> >is absent?
> Yes, As SLIMbus itself itself is discoverable bus.

Okay, in SDW we mandate description be present in respective firmwares so we
dont have this path. In theory this never works for you as driver cant load
without device being created and without driver load device is not powered
up so can't report...

> >>+In some cases it may be necessary to describe non-probeable device
> >>+details such as non-standard ways of powering up a device. In
> >>+such cases, child nodes for those devices will be present as
> >>+slaves of the slimbus-controller, as detailed below.
> >>+
> >>+Required property for SLIMbus child node if it is present:
> >>+- reg		- Should be ('Device index', 'Instance ID') from SLIMbus
> >>+		  Enumeration  Address.
> >>+		  Device Index Uniquely identifies multiple Devices within
> >>+		  a single Component.
> >>+		  Instance ID Is for the cases where multiple Devices of the
> >>+		  same type or Class are attached to the bus.
> >>+
> >>+- compatible	-"slimMID,PID". The textual representation of Manufacturer ID,
> >>+	 	  Product Code, shall be in lower case hexadecimal with leading
> >>+		  zeroes suppressed
> >>+
> 
> >>+		codec: wcd9310@1,0{
> >>+			compatible = "slim217,60";
> >>+			reg = <1 0>;
> >>+		};
> >>+	};
> >
> >Pardon my ignorance as I am not very familiar with DT nodes, but where are
> >the Manufacturer ID, Product code, Device index, and Instance values here?
> 
> Manfacturer ID and Product code is part of compatible string
> Device index and Instance value are part of reg.

hmmm, wouldn't it be more helpful to have a field(s) for these which contain
these numbers rather than coded together in a word

compatible makes sense though

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-16 17:29       ` Srinivas Kandagatla
  (?)
@ 2017-11-17  4:42       ` Vinod Koul
  2017-11-17  8:13         ` Greg KH
  -1 siblings, 1 reply; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  4:42 UTC (permalink / raw)
  To: Srinivas Kandagatla, gregkh
  Cc: broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Thu, Nov 16, 2017 at 05:29:35PM +0000, Srinivas Kandagatla wrote:
> thanks for the comments.
> 
> 
> On 16/11/17 16:42, Vinod Koul wrote:
> >On Wed, Nov 15, 2017 at 02:10:34PM +0000, srinivas.kandagatla@linaro.org wrote:
> >
> >>+static void slim_dev_release(struct device *dev)
> >>+{
> >>+	struct slim_device *sbdev = to_slim_device(dev);
> >>+
> >>+	put_device(sbdev->ctrl->dev);
> >
> >which device would that be?
> This is controller device
> 
> >
> >>+static int slim_add_device(struct slim_controller *ctrl,
> >>+			   struct slim_device *sbdev,
> >>+			   struct device_node *node)
> >>+{
> >>+	sbdev->dev.bus = &slimbus_bus;
> >>+	sbdev->dev.parent = ctrl->dev;
> >>+	sbdev->dev.release = slim_dev_release;
> >>+	sbdev->dev.driver = NULL;
> >>+	sbdev->ctrl = ctrl;
> >>+
> >>+	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
> >>+				  sbdev->e_addr.manf_id,
> >>+				  sbdev->e_addr.prod_code,
> >>+				  sbdev->e_addr.dev_index,
> >>+				  sbdev->e_addr.instance);
> >>+
> >>+	get_device(ctrl->dev);
> >
> >is this controller device and you ensuring it doesnt go away while you have
> >slaves on it?
> 
> Yes.

I thought since you are marking ctrl->dev as parent, the device core should
ensure that parent doesn't go off when you have child device?

Greg, is that understanding correct, if so we may not need these calls.

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 05/13] slimbus: core: add support to device tree helper
  2017-11-15 14:10 ` [PATCH v7 05/13] slimbus: core: add support to device tree helper srinivas.kandagatla
@ 2017-11-17  7:11       ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  7:11 UTC (permalink / raw)
  To: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, mark.rutland-5wv7dgnIgG8,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w, arnd-r2nGTMty4D4,
	bp-l3A5Bk7waGM, devicetree-u79uwXL29TY76Z2rM5mHXA,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA, pawel.moll-5wv7dgnIgG8,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sdharia-sgV2jX0FEOL9JmXXK+q4OQ,
	alan-VuQAYsv1563Yd54FQh9/CA, treding-DDmLM1+adcrQT0dZR+AlfA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, jkosina-AlSwsSmVLrQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, daniel-/w4YWyX8dFk,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q

On Wed, Nov 15, 2017 at 02:10:35PM +0000, srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
> +
> +	for_each_child_of_node(ctrl->dev->of_node, node) {
> +		struct slim_device *sbdev;
> +		struct slim_eaddr e_addr;
> +		const char *compat = NULL;
> +		int reg[2], ret;
> +		int manf_id, prod_code;
> +
> +		compat = of_get_property(node, "compatible", NULL);
> +		if (!compat)
> +			continue;
> +
> +		ret = sscanf(compat, "slim%x,%x", &manf_id, &prod_code);
> +		if (ret != 2) {
> +			dev_err(dev, "Manf ID & Product code not found %s\n",
> +				compat);
> +			continue;
> +		}

can we do xxx_property_read_u32() on compat and then use bit manupliations
to get ids rather than scanf.

> +
> +		ret = of_property_read_u32_array(node, "reg", reg, 2);

I typically prefer using device_property_read_u32() but then this is of_
code so I will leave this upto you...

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [alsa-devel] [PATCH v7 05/13] slimbus: core: add support to device tree helper
@ 2017-11-17  7:11       ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  7:11 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, mark.rutland, michael.opdenacker,
	poeschel, andreas.noever, arnd, bp, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	treding, mathieu.poirier, jkosina, linux-kernel, daniel, joe,
	davem

On Wed, Nov 15, 2017 at 02:10:35PM +0000, srinivas.kandagatla@linaro.org wrote:
> +
> +	for_each_child_of_node(ctrl->dev->of_node, node) {
> +		struct slim_device *sbdev;
> +		struct slim_eaddr e_addr;
> +		const char *compat = NULL;
> +		int reg[2], ret;
> +		int manf_id, prod_code;
> +
> +		compat = of_get_property(node, "compatible", NULL);
> +		if (!compat)
> +			continue;
> +
> +		ret = sscanf(compat, "slim%x,%x", &manf_id, &prod_code);
> +		if (ret != 2) {
> +			dev_err(dev, "Manf ID & Product code not found %s\n",
> +				compat);
> +			continue;
> +		}

can we do xxx_property_read_u32() on compat and then use bit manupliations
to get ids rather than scanf.

> +
> +		ret = of_property_read_u32_array(node, "reg", reg, 2);

I typically prefer using device_property_read_u32() but then this is of_
code so I will leave this upto you...

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
  2017-11-15 14:10     ` srinivas.kandagatla
@ 2017-11-17  7:48         ` Vinod Koul
  -1 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  7:48 UTC (permalink / raw)
  To: srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4

On Wed, Nov 15, 2017 at 02:10:36PM +0000, srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:

> +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
> +{
> +	struct slim_msg_txn *txn;
> +	struct slim_val_inf *msg;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&ctrl->txn_lock, flags);

Do you need this to be a _irqsave variant? What is the context of io
transfers in this case

> +/**
> + * slim_do_transfer() - Process a slimbus-messaging transaction
> + *
> + * @ctrl: Controller handle
> + * @txn: Transaction to be sent over SLIMbus
> + *
> + * Called by controller to transmit messaging transactions not dealing with
> + * Interface/Value elements. (e.g. transmittting a message to assign logical
> + * address to a slave device
> + *
> + * Return: -ETIMEDOUT: If transmission of this message timed out
> + *	(e.g. due to bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by destination
> + *	device.

I am preferring ENODATA in SDW for this case, as Slaves didnt respond or
ACK.

ENOTCONN is defined as /* Transport endpoint is not connected */ which is
not the case here, connected yes but not responded.

> +static int slim_val_inf_sanity(struct slim_controller *ctrl,
> +			       struct slim_val_inf *msg, u8 mc)
> +{
> +	if (!msg || msg->num_bytes > 16 ||
> +	    (msg->start_offset + msg->num_bytes) > 0xC00)
> +		goto reterr;
> +	switch (mc) {
> +	case SLIM_MSG_MC_REQUEST_VALUE:
> +	case SLIM_MSG_MC_REQUEST_INFORMATION:
> +		if (msg->rbuf != NULL)
> +			return 0;
> +		break;

empty line here and after each break make it look better

> +	case SLIM_MSG_MC_CHANGE_VALUE:
> +	case SLIM_MSG_MC_CLEAR_INFORMATION:
> +		if (msg->wbuf != NULL)
> +			return 0;
> +		break;
> +	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
> +	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
> +		if (msg->rbuf != NULL && msg->wbuf != NULL)
> +			return 0;
> +		break;
> +	default:
> +		break;

this seems superflous and we can just fall thru to error below.

> +	}
> +reterr:
> +	dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n",
> +		msg->start_offset, mc);
> +	return -EINVAL;

...

> +static int slim_xfer_msg(struct slim_controller *ctrl,
> +			 struct slim_device *sbdev,
> +			 struct slim_val_inf *msg, u8 mc)
> +{
> +	DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg);
> +	struct slim_msg_txn *txn = &txn_stack;
> +	int ret;
> +	u16 sl;
> +
> +	ret = slim_val_inf_sanity(ctrl, msg, mc);
> +	if (ret)
> +		return ret;
> +
> +	sl = slim_slicesize(msg->num_bytes);
> +
> +	dev_dbg(ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n",
> +		msg->start_offset, msg->num_bytes, mc, sl);

better to add tracing support for these debug prints

> +
> +	txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
> +
> +	switch (mc) {
> +	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
> +	case SLIM_MSG_MC_CHANGE_VALUE:
> +	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
> +	case SLIM_MSG_MC_CLEAR_INFORMATION:
> +		txn->rl += msg->num_bytes;
> +	default:
> +		break;
> +	}
> +
> +	if (slim_tid_txn(txn->mt, txn->mc))
> +		txn->rl++;
> +
> +	return slim_do_transfer(ctrl, txn);
> +}
> +
> +/**
> + * slim_request_val_element() - request value element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to read.
> + * context: can sleep
> + *
> + * Return: -EINVAL: Invalid parameters
> + *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
> + *	 bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by the device.
> + */
> +int slim_request_val_element(struct slim_device *sb,
> +				struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_val_element);
> +
> +/**
> + * slim_request_inf_element() - Request a info element
> + *
> + * @sb: client handle requesting elemental message reads.
> + * @msg: Input structure for start-offset, number of bytes to read
> + *	wbuf will contain information element(s) bit masks to be cleared.
> + *	rbuf will return what the information element value was
> + */
> +int slim_request_inf_element(struct slim_device *sb,
> +				struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_INFORMATION);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_inf_element);
> +
> +/**
> + * slim_change_val_element: change a given value element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to write.
> + * context: can sleep
> + *
> + * Return:
> + *	-EINVAL: Invalid parameters
> + *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
> + *	 bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by the device.
> + */
> +int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CHANGE_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_change_val_element);
> +
> +/**
> + * slim_clear_inf_element() - Clear info element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to read
> + *	wbuf will contain information element(s) bit masks to be cleared.
> + *	rbuf will return what the information element value was
> + */
> +int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CLEAR_INFORMATION);
> +}
> +EXPORT_SYMBOL_GPL(slim_clear_inf_element);
> +
> +/**
> + * slim_request_val_element() - change and request a given value element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to write.
> + * context: can sleep
> + *
> + * Return:
> + *	-EINVAL: Invalid parameters
> + *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
> + *	 bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by the device.
> + */
> +int slim_request_change_val_element(struct slim_device *sb,
> +					struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_change_val_element);

looking at this, does it really help to have different APIs for SLIM_MSG_XXX
why not slim_xfer_msg() be an exported one..

> +int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
> +{
> +	struct slim_val_inf msg;
> +	int ret;
> +
> +	slim_fill_msg(&msg, addr, count,  val, NULL);
> +	ret = slim_change_val_element(sdev, &msg);

return slim_change_val_element()

> +
> +	return ret;
> +
> +}

...

> +/* Destination type Values */
> +#define SLIM_MSG_DEST_LOGICALADDR	0
> +#define SLIM_MSG_DEST_ENUMADDR		1
> +#define	SLIM_MSG_DEST_BROADCAST		3
	^^^
why tab here
 

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
@ 2017-11-17  7:48         ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-17  7:48 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Wed, Nov 15, 2017 at 02:10:36PM +0000, srinivas.kandagatla@linaro.org wrote:

> +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
> +{
> +	struct slim_msg_txn *txn;
> +	struct slim_val_inf *msg;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&ctrl->txn_lock, flags);

Do you need this to be a _irqsave variant? What is the context of io
transfers in this case

> +/**
> + * slim_do_transfer() - Process a slimbus-messaging transaction
> + *
> + * @ctrl: Controller handle
> + * @txn: Transaction to be sent over SLIMbus
> + *
> + * Called by controller to transmit messaging transactions not dealing with
> + * Interface/Value elements. (e.g. transmittting a message to assign logical
> + * address to a slave device
> + *
> + * Return: -ETIMEDOUT: If transmission of this message timed out
> + *	(e.g. due to bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by destination
> + *	device.

I am preferring ENODATA in SDW for this case, as Slaves didnt respond or
ACK.

ENOTCONN is defined as /* Transport endpoint is not connected */ which is
not the case here, connected yes but not responded.

> +static int slim_val_inf_sanity(struct slim_controller *ctrl,
> +			       struct slim_val_inf *msg, u8 mc)
> +{
> +	if (!msg || msg->num_bytes > 16 ||
> +	    (msg->start_offset + msg->num_bytes) > 0xC00)
> +		goto reterr;
> +	switch (mc) {
> +	case SLIM_MSG_MC_REQUEST_VALUE:
> +	case SLIM_MSG_MC_REQUEST_INFORMATION:
> +		if (msg->rbuf != NULL)
> +			return 0;
> +		break;

empty line here and after each break make it look better

> +	case SLIM_MSG_MC_CHANGE_VALUE:
> +	case SLIM_MSG_MC_CLEAR_INFORMATION:
> +		if (msg->wbuf != NULL)
> +			return 0;
> +		break;
> +	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
> +	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
> +		if (msg->rbuf != NULL && msg->wbuf != NULL)
> +			return 0;
> +		break;
> +	default:
> +		break;

this seems superflous and we can just fall thru to error below.

> +	}
> +reterr:
> +	dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n",
> +		msg->start_offset, mc);
> +	return -EINVAL;

...

> +static int slim_xfer_msg(struct slim_controller *ctrl,
> +			 struct slim_device *sbdev,
> +			 struct slim_val_inf *msg, u8 mc)
> +{
> +	DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg);
> +	struct slim_msg_txn *txn = &txn_stack;
> +	int ret;
> +	u16 sl;
> +
> +	ret = slim_val_inf_sanity(ctrl, msg, mc);
> +	if (ret)
> +		return ret;
> +
> +	sl = slim_slicesize(msg->num_bytes);
> +
> +	dev_dbg(ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n",
> +		msg->start_offset, msg->num_bytes, mc, sl);

better to add tracing support for these debug prints

> +
> +	txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
> +
> +	switch (mc) {
> +	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
> +	case SLIM_MSG_MC_CHANGE_VALUE:
> +	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
> +	case SLIM_MSG_MC_CLEAR_INFORMATION:
> +		txn->rl += msg->num_bytes;
> +	default:
> +		break;
> +	}
> +
> +	if (slim_tid_txn(txn->mt, txn->mc))
> +		txn->rl++;
> +
> +	return slim_do_transfer(ctrl, txn);
> +}
> +
> +/**
> + * slim_request_val_element() - request value element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to read.
> + * context: can sleep
> + *
> + * Return: -EINVAL: Invalid parameters
> + *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
> + *	 bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by the device.
> + */
> +int slim_request_val_element(struct slim_device *sb,
> +				struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_val_element);
> +
> +/**
> + * slim_request_inf_element() - Request a info element
> + *
> + * @sb: client handle requesting elemental message reads.
> + * @msg: Input structure for start-offset, number of bytes to read
> + *	wbuf will contain information element(s) bit masks to be cleared.
> + *	rbuf will return what the information element value was
> + */
> +int slim_request_inf_element(struct slim_device *sb,
> +				struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_INFORMATION);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_inf_element);
> +
> +/**
> + * slim_change_val_element: change a given value element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to write.
> + * context: can sleep
> + *
> + * Return:
> + *	-EINVAL: Invalid parameters
> + *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
> + *	 bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by the device.
> + */
> +int slim_change_val_element(struct slim_device *sb, struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CHANGE_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_change_val_element);
> +
> +/**
> + * slim_clear_inf_element() - Clear info element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to read
> + *	wbuf will contain information element(s) bit masks to be cleared.
> + *	rbuf will return what the information element value was
> + */
> +int slim_clear_inf_element(struct slim_device *sb, struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_CLEAR_INFORMATION);
> +}
> +EXPORT_SYMBOL_GPL(slim_clear_inf_element);
> +
> +/**
> + * slim_request_val_element() - change and request a given value element
> + *
> + * @sb: client handle requesting elemental message reads, writes.
> + * @msg: Input structure for start-offset, number of bytes to write.
> + * context: can sleep
> + *
> + * Return:
> + *	-EINVAL: Invalid parameters
> + *	-ETIMEDOUT: If transmission of this message timed out (e.g. due to
> + *	 bus lines not being clocked or driven by controller)
> + *	-ENOTCONN: If the transmitted message was not ACKed by the device.
> + */
> +int slim_request_change_val_element(struct slim_device *sb,
> +					struct slim_val_inf *msg)
> +{
> +	struct slim_controller *ctrl = sb->ctrl;
> +
> +	if (!ctrl)
> +		return -EINVAL;
> +
> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_change_val_element);

looking at this, does it really help to have different APIs for SLIM_MSG_XXX
why not slim_xfer_msg() be an exported one..

> +int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
> +{
> +	struct slim_val_inf msg;
> +	int ret;
> +
> +	slim_fill_msg(&msg, addr, count,  val, NULL);
> +	ret = slim_change_val_element(sdev, &msg);

return slim_change_val_element()

> +
> +	return ret;
> +
> +}

...

> +/* Destination type Values */
> +#define SLIM_MSG_DEST_LOGICALADDR	0
> +#define SLIM_MSG_DEST_ENUMADDR		1
> +#define	SLIM_MSG_DEST_BROADCAST		3
	^^^
why tab here
 

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-17  4:42       ` Vinod Koul
@ 2017-11-17  8:13         ` Greg KH
  2017-11-20  6:47           ` Srinivas Kandagatla
  0 siblings, 1 reply; 78+ messages in thread
From: Greg KH @ 2017-11-17  8:13 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Srinivas Kandagatla, broonie, alsa-devel, sdharia, bp, poeschel,
	treding, andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Fri, Nov 17, 2017 at 10:12:22AM +0530, Vinod Koul wrote:
> On Thu, Nov 16, 2017 at 05:29:35PM +0000, Srinivas Kandagatla wrote:
> > thanks for the comments.
> > 
> > 
> > On 16/11/17 16:42, Vinod Koul wrote:
> > >On Wed, Nov 15, 2017 at 02:10:34PM +0000, srinivas.kandagatla@linaro.org wrote:
> > >
> > >>+static void slim_dev_release(struct device *dev)
> > >>+{
> > >>+	struct slim_device *sbdev = to_slim_device(dev);
> > >>+
> > >>+	put_device(sbdev->ctrl->dev);
> > >
> > >which device would that be?
> > This is controller device
> > 
> > >
> > >>+static int slim_add_device(struct slim_controller *ctrl,
> > >>+			   struct slim_device *sbdev,
> > >>+			   struct device_node *node)
> > >>+{
> > >>+	sbdev->dev.bus = &slimbus_bus;
> > >>+	sbdev->dev.parent = ctrl->dev;
> > >>+	sbdev->dev.release = slim_dev_release;
> > >>+	sbdev->dev.driver = NULL;
> > >>+	sbdev->ctrl = ctrl;
> > >>+
> > >>+	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
> > >>+				  sbdev->e_addr.manf_id,
> > >>+				  sbdev->e_addr.prod_code,
> > >>+				  sbdev->e_addr.dev_index,
> > >>+				  sbdev->e_addr.instance);
> > >>+
> > >>+	get_device(ctrl->dev);
> > >
> > >is this controller device and you ensuring it doesnt go away while you have
> > >slaves on it?
> > 
> > Yes.
> 
> I thought since you are marking ctrl->dev as parent, the device core should
> ensure that parent doesn't go off when you have child device?
> 
> Greg, is that understanding correct, if so we may not need these calls.

That understanding should be correct, as the reference count is
incremented on the parent when a child is added.

It would be trivial for this to be tested, and yes, I am pretty sure you
don't need this call.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
  2017-11-17  7:48         ` Vinod Koul
  (?)
@ 2017-11-20  6:47         ` Srinivas Kandagatla
  2017-11-27  5:56           ` Vinod Koul
  -1 siblings, 1 reply; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-20  6:47 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

thanks for the comments,

On 17/11/17 07:48, Vinod Koul wrote:
> On Wed, Nov 15, 2017 at 02:10:36PM +0000, srinivas.kandagatla@linaro.org wrote:
> 
>> +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
>> +{
>> +	struct slim_msg_txn *txn;
>> +	struct slim_val_inf *msg;
>> +	unsigned long flags;
>> +
>> +	spin_lock_irqsave(&ctrl->txn_lock, flags);
> 
> Do you need this to be a _irqsave variant? What is the context of io
> transfers in this case
Yes, On Qcom controller driver it is called in Interrupt context, but it 
depends on caller (controller driver) which could be in process context too.

> 
>> +/**
>> + * slim_do_transfer() - Process a slimbus-messaging transaction
>> + *
>> + * @ctrl: Controller handle
>> + * @txn: Transaction to be sent over SLIMbus
>> + *
>> + * Called by controller to transmit messaging transactions not dealing with
>> + * Interface/Value elements. (e.g. transmittting a message to assign logical
>> + * address to a slave device
>> + *
>> + * Return: -ETIMEDOUT: If transmission of this message timed out
>> + *	(e.g. due to bus lines not being clocked or driven by controller)
>> + *	-ENOTCONN: If the transmitted message was not ACKed by destination
>> + *	device.
> 
> I am preferring ENODATA in SDW for this case, as Slaves didnt respond or
> ACK.
Isn't that a timeout error then.

ENODATA is for "No data available", reporting ENODATA would be misleading.

> 
> ENOTCONN is defined as /* Transport endpoint is not connected */ which is
> not the case here, connected yes but not responded.

Code as it is would not return this, so i will be deleting ENOTCONN from 
kernel doc.

> 
>> +static int slim_val_inf_sanity(struct slim_controller *ctrl,
>> +			       struct slim_val_inf *msg, u8 mc)
>> +{
>> +	if (!msg || msg->num_bytes > 16 ||
>> +	    (msg->start_offset + msg->num_bytes) > 0xC00)
>> +		goto reterr;
>> +	switch (mc) {
>> +	case SLIM_MSG_MC_REQUEST_VALUE:
>> +	case SLIM_MSG_MC_REQUEST_INFORMATION:
>> +		if (msg->rbuf != NULL)
>> +			return 0;
>> +		break;
> 
> empty line here and after each break make it look better
Yep, will remove this in next version.
> 
>> +	case SLIM_MSG_MC_CHANGE_VALUE:
>> +	case SLIM_MSG_MC_CLEAR_INFORMATION:
>> +		if (msg->wbuf != NULL)
>> +			return 0;
>> +		break;
>> +	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
>> +	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
>> +		if (msg->rbuf != NULL && msg->wbuf != NULL)
>> +			return 0;
>> +		break;
>> +	default:
>> +		break;
> 
> this seems superflous and we can just fall thru to error below.
> 
Agree..
will fix it in next version.
>> +	}
>> +reterr:
>> +	dev_err(ctrl->dev, "Sanity check failed:msg:offset:0x%x, mc:%d\n",
>> +		msg->start_offset, mc);
>> +	return -EINVAL;
> 
> ...
> 
>> +static int slim_xfer_msg(struct slim_controller *ctrl,
>> +			 struct slim_device *sbdev,
>> +			 struct slim_val_inf *msg, u8 mc)
>> +{
>> +	DEFINE_SLIM_LDEST_TXN(txn_stack, mc, 6, sbdev->laddr, msg);
>> +	struct slim_msg_txn *txn = &txn_stack;
>> +	int ret;
>> +	u16 sl;
>> +
>> +	ret = slim_val_inf_sanity(ctrl, msg, mc);
>> +	if (ret)
>> +		return ret;
>> +
>> +	sl = slim_slicesize(msg->num_bytes);
>> +
>> +	dev_dbg(ctrl->dev, "SB xfer msg:os:%x, len:%d, MC:%x, sl:%x\n",
>> +		msg->start_offset, msg->num_bytes, mc, sl);
> 
> better to add tracing support for these debug prints
> 
Will explore tracing side of it..
>> +
>> +	txn->ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
>> +
>> +	switch (mc) {
>> +	case SLIM_MSG_MC_REQUEST_CHANGE_VALUE:
>> +	case SLIM_MSG_MC_CHANGE_VALUE:
>> +	case SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION:
>> +int slim_request_change_val_element(struct slim_device *sb,
>> +					struct slim_val_inf *msg)
>> +{
>> +	struct slim_controller *ctrl = sb->ctrl;
>> +
>> +	if (!ctrl)
>> +		return -EINVAL;
>> +
>> +	return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_CHANGE_VALUE);
>> +}
>> +EXPORT_SYMBOL_GPL(slim_request_change_val_element);
> 
> looking at this, does it really help to have different APIs for SLIM_MSG_XXX
> why not slim_xfer_msg() be an exported one..

I did think about this cleanup, and it makes sense.

I will have a go at removing this and just leaving slim_readb/writeb() 
slim_read/write() and slim_xfer_msg() API's in next version.

We can discuss to add this in future incase its required.


> 
>> +int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val)
>> +{
>> +	struct slim_val_inf msg;
>> +	int ret;
>> +
>> +	slim_fill_msg(&msg, addr, count,  val, NULL);
>> +	ret = slim_change_val_element(sdev, &msg);
> 
> return slim_change_val_element()
Makes sense.

> 
>> +
>> +	return ret;
>> +
>> +}
> 
> ...
> 
>> +/* Destination type Values */
>> +#define SLIM_MSG_DEST_LOGICALADDR	0
>> +#define SLIM_MSG_DEST_ENUMADDR		1
>> +#define	SLIM_MSG_DEST_BROADCAST		3
> 	^^^
> why tab here
Will fix it in next version.
>   
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-17  8:13         ` Greg KH
@ 2017-11-20  6:47           ` Srinivas Kandagatla
       [not found]             ` <64797182-9244-e6e7-8044-dbc404cdda7c-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-20  6:47 UTC (permalink / raw)
  To: Greg KH, Vinod Koul
  Cc: broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd



On 17/11/17 08:13, Greg KH wrote:
> On Fri, Nov 17, 2017 at 10:12:22AM +0530, Vinod Koul wrote:
>> On Thu, Nov 16, 2017 at 05:29:35PM +0000, Srinivas Kandagatla wrote:
>>> thanks for the comments.
>>>
>>>
>>> On 16/11/17 16:42, Vinod Koul wrote:
>>>> On Wed, Nov 15, 2017 at 02:10:34PM +0000,srinivas.kandagatla@linaro.org  wrote:
>>>>
>>>>> +static void slim_dev_release(struct device *dev)
>>>>> +{
>>>>> +	struct slim_device *sbdev = to_slim_device(dev);
>>>>> +
>>>>> +	put_device(sbdev->ctrl->dev);
>>>> which device would that be?
>>> This is controller device
>>>
>>>>> +static int slim_add_device(struct slim_controller *ctrl,
>>>>> +			   struct slim_device *sbdev,
>>>>> +			   struct device_node *node)
>>>>> +{
>>>>> +	sbdev->dev.bus = &slimbus_bus;
>>>>> +	sbdev->dev.parent = ctrl->dev;
>>>>> +	sbdev->dev.release = slim_dev_release;
>>>>> +	sbdev->dev.driver = NULL;
>>>>> +	sbdev->ctrl = ctrl;
>>>>> +
>>>>> +	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
>>>>> +				  sbdev->e_addr.manf_id,
>>>>> +				  sbdev->e_addr.prod_code,
>>>>> +				  sbdev->e_addr.dev_index,
>>>>> +				  sbdev->e_addr.instance);
>>>>> +
>>>>> +	get_device(ctrl->dev);
>>>> is this controller device and you ensuring it doesnt go away while you have
>>>> slaves on it?
>>> Yes.
>> I thought since you are marking ctrl->dev as parent, the device core should
>> ensure that parent doesn't go off when you have child device?
>>
>> Greg, is that understanding correct, if so we may not need these calls.
> That understanding should be correct, as the reference count is
> incremented on the parent when a child is added.
> 
> It would be trivial for this to be tested, and yes, I am pretty sure you
> don't need this call.
> 

Thanks for suggestion, I will remove this in next version.


thanks,
srini

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature
  2017-11-15 14:10   ` srinivas.kandagatla
@ 2017-11-23  7:28     ` Charles Keepax
  -1 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23  7:28 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, treding, devicetree,
	james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt,
	sdharia, alan, bp, mathieu.poirier, gregkh, linux-kernel,
	broonie, daniel, jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:37PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> Per slimbus specification, a reconfiguration sequence known as
> 'clock pause' needs to be broadcast over the bus while entering low-
> power mode. Clock-pause is initiated by the controller driver.
> To exit clock-pause, controller typically wakes up the framer device.
> Since wakeup precedure is controller-specific, framework calls it via
> controller's function pointer to invoke it.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +/**
> + * struct slim_sched: Framework uses this structure internally for scheduling.

Missing kernel doc for clkgear here.

> + * @clk_state: Controller's clock state from enum slim_clk_state
> + * @pause_comp: Signals completion of clock pause sequence. This is useful when
> + *	client tries to call slimbus transaction when controller is entering
> + *	clock pause.
> + * @m_reconf: This mutex is held until current reconfiguration (data channel
> + *	scheduling, message bandwidth reservation) is done. Message APIs can
> + *	use the bus concurrently when this mutex is held since elemental access
> + *	messages can be sent on the bus when reconfiguration is in progress.
> + */
> +struct slim_sched {
> +	int			clkgear;
> +	enum slim_clk_state	clk_state;
> +	struct completion	pause_comp;
> +	struct mutex		m_reconf;
> +};

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature
@ 2017-11-23  7:28     ` Charles Keepax
  0 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23  7:28 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 02:10:37PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> Per slimbus specification, a reconfiguration sequence known as
> 'clock pause' needs to be broadcast over the bus while entering low-
> power mode. Clock-pause is initiated by the controller driver.
> To exit clock-pause, controller typically wakes up the framer device.
> Since wakeup precedure is controller-specific, framework calls it via
> controller's function pointer to invoke it.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +/**
> + * struct slim_sched: Framework uses this structure internally for scheduling.

Missing kernel doc for clkgear here.

> + * @clk_state: Controller's clock state from enum slim_clk_state
> + * @pause_comp: Signals completion of clock pause sequence. This is useful when
> + *	client tries to call slimbus transaction when controller is entering
> + *	clock pause.
> + * @m_reconf: This mutex is held until current reconfiguration (data channel
> + *	scheduling, message bandwidth reservation) is done. Message APIs can
> + *	use the bus concurrently when this mutex is held since elemental access
> + *	messages can be sent on the bus when reconfiguration is in progress.
> + */
> +struct slim_sched {
> +	int			clkgear;
> +	enum slim_clk_state	clk_state;
> +	struct completion	pause_comp;
> +	struct mutex		m_reconf;
> +};

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
  2017-11-16  5:15     ` Rob Herring
@ 2017-11-23  7:41       ` Charles Keepax
  -1 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23  7:41 UTC (permalink / raw)
  To: Rob Herring
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	srinivas.kandagatla, andreas.noever, arnd, vinod.koul, treding,
	devicetree, james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1,
	broonie, sdharia, alan, bp, mathieu.poirier, gregkh,
	linux-kernel, daniel, jkosina, joe, davem

On Wed, Nov 15, 2017 at 11:15:00PM -0600, Rob Herring wrote:
> On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
> > From: Sagar Dharia <sdharia@codeaurora.org>
> > 
> > SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> > developed by MIPI (Mobile Industry Processor Interface) alliance.
> > SLIMbus is a 2-wire implementation, which is used to communicate with
> > peripheral components like audio-codec.
> > 
> > This patch adds device tree bindings for the slimbus.
> > 
> > Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
> >  1 file changed, 50 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt
> 
> Reviewed-by: Rob Herring <robh@kernel.org>

I still have some reservations about the putting the MID and PID
in the compatible sting, are we sure this is what we want to do?
As has been discussed previous the discoverability of SLIMbus
is really theoretical since you really always need to bind a
driver to power on the device, since power is not part of the bus
itself.

Many devices (ours included) will support SLIMbus and other
interfaces, this means we will need a different compatible
string between SLIMbus and I2C/SPI, which feels a little
icky.  Additionally it does make the compatible strings really
unreadable and which is a little annoying when looking at device
trees as you can't easily see what things are.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings
@ 2017-11-23  7:41       ` Charles Keepax
  0 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23  7:41 UTC (permalink / raw)
  To: Rob Herring
  Cc: srinivas.kandagatla, gregkh, broonie, alsa-devel, sdharia, bp,
	poeschel, treding, andreas.noever, alan, mathieu.poirier, daniel,
	jkosina, sharon.dvir1, joe, davem, james.hogan,
	michael.opdenacker, pawel.moll, mark.rutland, devicetree,
	linux-kernel, linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 11:15:00PM -0600, Rob Herring wrote:
> On Wed, Nov 15, 2017 at 02:10:32PM +0000, srinivas.kandagatla@linaro.org wrote:
> > From: Sagar Dharia <sdharia@codeaurora.org>
> > 
> > SLIMbus (Serial Low Power Interchip Media Bus) is a specification
> > developed by MIPI (Mobile Industry Processor Interface) alliance.
> > SLIMbus is a 2-wire implementation, which is used to communicate with
> > peripheral components like audio-codec.
> > 
> > This patch adds device tree bindings for the slimbus.
> > 
> > Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/slimbus/bus.txt | 50 +++++++++++++++++++++++
> >  1 file changed, 50 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/slimbus/bus.txt
> 
> Reviewed-by: Rob Herring <robh@kernel.org>

I still have some reservations about the putting the MID and PID
in the compatible sting, are we sure this is what we want to do?
As has been discussed previous the discoverability of SLIMbus
is really theoretical since you really always need to bind a
driver to power on the device, since power is not part of the bus
itself.

Many devices (ours included) will support SLIMbus and other
interfaces, this means we will need a different compatible
string between SLIMbus and I2C/SPI, which feels a little
icky.  Additionally it does make the compatible strings really
unreadable and which is a little annoying when looking at device
trees as you can't easily see what things are.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 08/13] regmap: add SLIMbus support
  2017-11-15 14:10   ` srinivas.kandagatla
@ 2017-11-23  7:49     ` Charles Keepax
  -1 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23  7:49 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, treding, devicetree,
	james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt,
	sdharia, alan, bp, mathieu.poirier, gregkh, linux-kernel,
	broonie, daniel, jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:38PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> 
> This patch adds support to read/write slimbus value elements.
> Currently it only supports byte read/write. Adding this support in
> regmap would give codec drivers more flexibility when there are more
> than 2 control interfaces like slimbus, i2c.
> 
> Without this patch each codec driver has to directly call slimbus value
> element apis, and this could would get messy once we want to add i2c
> interface to it.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +
> +static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
> +					unsigned int *val)
> +{
> +	struct slim_device *sdev = context;
> +	int v;
> +
> +	if (!sdev)
> +		return 0;

Is there a specific reason we are checking the context here? The
other regmap buses don't both and whilst I don't mind checking
shouldn't we return an error if we don't have a context rather
than pretending to succeed?

> +
> +	v = slim_readb(sdev, reg);
> +
> +	if (v < 0)
> +		return v;
> +
> +	*val = v;
> +
> +	return 0;
> +}
> +
> +static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
> +					 unsigned int val)
> +{
> +	struct slim_device *sdev = context;
> +
> +	if (!sdev)
> +		return 0;

ditto.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 08/13] regmap: add SLIMbus support
@ 2017-11-23  7:49     ` Charles Keepax
  0 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23  7:49 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 02:10:38PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> 
> This patch adds support to read/write slimbus value elements.
> Currently it only supports byte read/write. Adding this support in
> regmap would give codec drivers more flexibility when there are more
> than 2 control interfaces like slimbus, i2c.
> 
> Without this patch each codec driver has to directly call slimbus value
> element apis, and this could would get messy once we want to add i2c
> interface to it.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +
> +static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
> +					unsigned int *val)
> +{
> +	struct slim_device *sdev = context;
> +	int v;
> +
> +	if (!sdev)
> +		return 0;

Is there a specific reason we are checking the context here? The
other regmap buses don't both and whilst I don't mind checking
shouldn't we return an error if we don't have a context rather
than pretending to succeed?

> +
> +	v = slim_readb(sdev, reg);
> +
> +	if (v < 0)
> +		return v;
> +
> +	*val = v;
> +
> +	return 0;
> +}
> +
> +static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
> +					 unsigned int val)
> +{
> +	struct slim_device *sdev = context;
> +
> +	if (!sdev)
> +		return 0;

ditto.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
  2017-11-15 14:10     ` srinivas.kandagatla
@ 2017-11-23 10:07       ` Charles Keepax
  -1 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23 10:07 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, treding, devicetree,
	james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt,
	sdharia, alan, bp, mathieu.poirier, gregkh, linux-kernel,
	broonie, daniel, jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:41PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> This controller driver programs manager, interface, and framer
> devices for Qualcomm's slimbus HW block.
> Manager component currently implements logical address setting,
> and messaging interface.
> Interface device reports bus synchronization information, and framer
> device clocks the bus from the time it's woken up, until clock-pause
> is executed by the manager device.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +
> +static irqreturn_t qcom_slim_handle_rx_irq(struct qcom_slim_ctrl *ctrl,
> +					   u32 stat)
> +{
> +	u32 *rx_buf, pkt[10];
> +	bool q_rx = false;
> +	u8 la, *buf, mc, mt, len, *b = (u8 *)&pkt[0];
> +	u16 ele;
> +

This function feels pretty funky, we basically have rx_buf, pkt,
b and buf all of which basically point to the same thing. Can we
simplify it a little?

> +	pkt[0] = readl_relaxed(ctrl->base + MGR_RX_MSG);
> +	mt = SLIM_HEADER_GET_MT(b[0]);
> +	len = SLIM_HEADER_GET_RL(b[0]);
> +	mc = SLIM_HEADER_GET_MC(b[1]);
> +
> +	/*
> +	 * this message cannot be handled by ISR, so
> +	 * let work-queue handle it
> +	 */
> +	if (mt == SLIM_MSG_MT_CORE &&
> +		mc == SLIM_MSG_MC_REPORT_PRESENT)
> +		rx_buf = (u32 *)slim_alloc_rxbuf(ctrl);
> +	else
> +		rx_buf = pkt;
> +
> +	if (rx_buf == NULL) {
> +		dev_err(ctrl->dev, "dropping RX:0x%x due to RX full\n",
> +					pkt[0]);
> +		goto rx_ret_irq;
> +	}
> +
> +	rx_buf[0] = pkt[0];

This is the only time that rx_buf is used without being cast to a
u8* would there be any milage in combining b and buf, and getting
rid of rx_buf?

> +	__ioread32_copy(rx_buf + 1, ctrl->base + MGR_RX_MSG + 4,
> +			DIV_ROUND_UP(len, 4));
> +
> +	switch (mc) {
> +
> +	case SLIM_MSG_MC_REPORT_PRESENT:
> +		q_rx = true;
> +		break;
> +	case SLIM_MSG_MC_REPLY_INFORMATION:
> +	case SLIM_MSG_MC_REPLY_VALUE:
> +		slim_msg_response(&ctrl->ctrl, (u8 *)(rx_buf + 1),
> +				  (u8)(*rx_buf >> 24), (len - 4));
> +		break;
> +	case SLIM_MSG_MC_REPORT_INFORMATION:
> +		buf = (u8 *)rx_buf;
> +		la = buf[2];
> +		ele = (u16)buf[4] << 4;
> +
> +		ele |= ((buf[3] & 0xf0) >> 4);
> +		/*
> +		 * report information is most likely loss of
> +		 * sync or collision detected in data slots
> +		 */
> +		dev_info(ctrl->dev, "LA:%d report inf ele:0x%x\n",
> +			 la, ele);
> +		break;
> +	default:
> +		dev_err(ctrl->dev, "unsupported MC,%x MT:%x\n",
> +			mc, mt);
> +		break;
> +	}
> +rx_ret_irq:
> +	writel(MGR_INT_RX_MSG_RCVD, ctrl->base +
> +		       MGR_INT_CLR);
> +	if (q_rx)
> +		queue_work(ctrl->rxwq, &ctrl->wd);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int qcom_xfer_msg(struct slim_controller *sctrl,
> +			 struct slim_msg_txn *txn)
> +{
> +	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
> +	DECLARE_COMPLETION_ONSTACK(done);
> +	void *pbuf = slim_alloc_txbuf(ctrl, txn, &done);
> +	unsigned long ms = txn->rl + HZ;
> +	u8 *puc;
> +	int ret = 0, timeout, retries = QCOM_BUF_ALLOC_RETRIES;
> +	u8 la = txn->la;
> +	u32 *head;
> +	/* HW expects length field to be excluded */
> +	txn->rl--;
> +
> +	/* spin till buffer is made available */
> +	if (!pbuf) {
> +		while (retries--) {
> +			usleep_range(10000, 15000);
> +			pbuf = slim_alloc_txbuf(ctrl, txn, &done);
> +			if (pbuf)
> +				break;
> +		}
> +	}
> +
> +	if (!retries && !pbuf)
> +		return -ENOMEM;
> +
> +	puc = (u8 *)pbuf;
> +	head = (u32 *)pbuf;
> +
> +	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
> +		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
> +						la);
> +	else
> +		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
> +						la);
> +
> +	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
> +		puc += 3;
> +	else
> +		puc += 2;

Combine these two if statements, makes it much clearer the actions
are related.

> +
> +	if (txn->mt == SLIM_MSG_MT_CORE && slim_tid_txn(txn->mt, txn->mc))

slim_tid_txn checks for SLIM_MSG_MT_CORE so the check here should
be redundant.

> +		*(puc++) = txn->tid;
> +
> +	if ((txn->mt == SLIM_MSG_MT_CORE) &&
> +		((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
> +		txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
> +		(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
> +		 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
> +		*(puc++) = (txn->ec & 0xFF);
> +		*(puc++) = (txn->ec >> 8) & 0xFF;
> +	}

As you already have slim_tid_txn, would it be worth adding
something like slim_ec_txn? To state if an element code is
required, feels like other controls will probably want to do a
similar thing and would make the code a little more readable
here.

> +
> +	if (txn->msg && txn->msg->wbuf)
> +		memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
> +
> +	qcom_slim_queue_tx(ctrl, head, txn->rl, MGR_TX_MSG);
> +	timeout = wait_for_completion_timeout(&done, msecs_to_jiffies(ms));
> +
> +	if (!timeout) {
> +		dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
> +					txn->mt);
> +		ret = -ETIMEDOUT;
> +	}
> +
> +	return ret;
> +
> +}
> +
> +static void qcom_slim_rxwq(struct work_struct *work)
> +{
> +	u8 buf[SLIM_MSGQ_BUF_LEN];
> +	u8 mc, mt, len;
> +	int i, ret;
> +	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
> +						 wd);
> +
> +	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
> +		len = SLIM_HEADER_GET_RL(buf[0]);
> +		mt = SLIM_HEADER_GET_MT(buf[0]);
> +		mc = SLIM_HEADER_GET_MC(buf[1]);
> +		if (mt == SLIM_MSG_MT_CORE &&
> +			mc == SLIM_MSG_MC_REPORT_PRESENT) {
> +			u8 laddr;
> +			struct slim_eaddr ea;
> +			u8 e_addr[6];
> +
> +			for (i = 0; i < 6; i++)
> +				e_addr[i] = buf[7-i];
> +
> +			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
> +			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
> +			ea.dev_index = e_addr[1];
> +			ea.instance = e_addr[0];

If we are just bitshifting this out of the bytes does it really
make it much more clear to reverse the byte order first? Feels
like you might as well shift it out of buf directly.

Also we didn't bother to reverse the bytes for the element code
above, so feels more consistent.

> +			ret = slim_device_report_present(&ctrl->ctrl,
> +							 &ea, &laddr);
> +			if (ret < 0)
> +				dev_err(ctrl->dev, "assign laddr failed:%d\n",
> +					ret);
> +		} else {
> +			dev_err(ctrl->dev, "unexpected message:mc:%x, mt:%x\n",
> +				mc, mt);
> +		}
> +	}
> +}

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
@ 2017-11-23 10:07       ` Charles Keepax
  0 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23 10:07 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 02:10:41PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> This controller driver programs manager, interface, and framer
> devices for Qualcomm's slimbus HW block.
> Manager component currently implements logical address setting,
> and messaging interface.
> Interface device reports bus synchronization information, and framer
> device clocks the bus from the time it's woken up, until clock-pause
> is executed by the manager device.
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +
> +static irqreturn_t qcom_slim_handle_rx_irq(struct qcom_slim_ctrl *ctrl,
> +					   u32 stat)
> +{
> +	u32 *rx_buf, pkt[10];
> +	bool q_rx = false;
> +	u8 la, *buf, mc, mt, len, *b = (u8 *)&pkt[0];
> +	u16 ele;
> +

This function feels pretty funky, we basically have rx_buf, pkt,
b and buf all of which basically point to the same thing. Can we
simplify it a little?

> +	pkt[0] = readl_relaxed(ctrl->base + MGR_RX_MSG);
> +	mt = SLIM_HEADER_GET_MT(b[0]);
> +	len = SLIM_HEADER_GET_RL(b[0]);
> +	mc = SLIM_HEADER_GET_MC(b[1]);
> +
> +	/*
> +	 * this message cannot be handled by ISR, so
> +	 * let work-queue handle it
> +	 */
> +	if (mt == SLIM_MSG_MT_CORE &&
> +		mc == SLIM_MSG_MC_REPORT_PRESENT)
> +		rx_buf = (u32 *)slim_alloc_rxbuf(ctrl);
> +	else
> +		rx_buf = pkt;
> +
> +	if (rx_buf == NULL) {
> +		dev_err(ctrl->dev, "dropping RX:0x%x due to RX full\n",
> +					pkt[0]);
> +		goto rx_ret_irq;
> +	}
> +
> +	rx_buf[0] = pkt[0];

This is the only time that rx_buf is used without being cast to a
u8* would there be any milage in combining b and buf, and getting
rid of rx_buf?

> +	__ioread32_copy(rx_buf + 1, ctrl->base + MGR_RX_MSG + 4,
> +			DIV_ROUND_UP(len, 4));
> +
> +	switch (mc) {
> +
> +	case SLIM_MSG_MC_REPORT_PRESENT:
> +		q_rx = true;
> +		break;
> +	case SLIM_MSG_MC_REPLY_INFORMATION:
> +	case SLIM_MSG_MC_REPLY_VALUE:
> +		slim_msg_response(&ctrl->ctrl, (u8 *)(rx_buf + 1),
> +				  (u8)(*rx_buf >> 24), (len - 4));
> +		break;
> +	case SLIM_MSG_MC_REPORT_INFORMATION:
> +		buf = (u8 *)rx_buf;
> +		la = buf[2];
> +		ele = (u16)buf[4] << 4;
> +
> +		ele |= ((buf[3] & 0xf0) >> 4);
> +		/*
> +		 * report information is most likely loss of
> +		 * sync or collision detected in data slots
> +		 */
> +		dev_info(ctrl->dev, "LA:%d report inf ele:0x%x\n",
> +			 la, ele);
> +		break;
> +	default:
> +		dev_err(ctrl->dev, "unsupported MC,%x MT:%x\n",
> +			mc, mt);
> +		break;
> +	}
> +rx_ret_irq:
> +	writel(MGR_INT_RX_MSG_RCVD, ctrl->base +
> +		       MGR_INT_CLR);
> +	if (q_rx)
> +		queue_work(ctrl->rxwq, &ctrl->wd);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int qcom_xfer_msg(struct slim_controller *sctrl,
> +			 struct slim_msg_txn *txn)
> +{
> +	struct qcom_slim_ctrl *ctrl = dev_get_drvdata(sctrl->dev);
> +	DECLARE_COMPLETION_ONSTACK(done);
> +	void *pbuf = slim_alloc_txbuf(ctrl, txn, &done);
> +	unsigned long ms = txn->rl + HZ;
> +	u8 *puc;
> +	int ret = 0, timeout, retries = QCOM_BUF_ALLOC_RETRIES;
> +	u8 la = txn->la;
> +	u32 *head;
> +	/* HW expects length field to be excluded */
> +	txn->rl--;
> +
> +	/* spin till buffer is made available */
> +	if (!pbuf) {
> +		while (retries--) {
> +			usleep_range(10000, 15000);
> +			pbuf = slim_alloc_txbuf(ctrl, txn, &done);
> +			if (pbuf)
> +				break;
> +		}
> +	}
> +
> +	if (!retries && !pbuf)
> +		return -ENOMEM;
> +
> +	puc = (u8 *)pbuf;
> +	head = (u32 *)pbuf;
> +
> +	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
> +		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
> +						la);
> +	else
> +		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
> +						la);
> +
> +	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
> +		puc += 3;
> +	else
> +		puc += 2;

Combine these two if statements, makes it much clearer the actions
are related.

> +
> +	if (txn->mt == SLIM_MSG_MT_CORE && slim_tid_txn(txn->mt, txn->mc))

slim_tid_txn checks for SLIM_MSG_MT_CORE so the check here should
be redundant.

> +		*(puc++) = txn->tid;
> +
> +	if ((txn->mt == SLIM_MSG_MT_CORE) &&
> +		((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
> +		txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
> +		(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
> +		 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
> +		*(puc++) = (txn->ec & 0xFF);
> +		*(puc++) = (txn->ec >> 8) & 0xFF;
> +	}

As you already have slim_tid_txn, would it be worth adding
something like slim_ec_txn? To state if an element code is
required, feels like other controls will probably want to do a
similar thing and would make the code a little more readable
here.

> +
> +	if (txn->msg && txn->msg->wbuf)
> +		memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
> +
> +	qcom_slim_queue_tx(ctrl, head, txn->rl, MGR_TX_MSG);
> +	timeout = wait_for_completion_timeout(&done, msecs_to_jiffies(ms));
> +
> +	if (!timeout) {
> +		dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
> +					txn->mt);
> +		ret = -ETIMEDOUT;
> +	}
> +
> +	return ret;
> +
> +}
> +
> +static void qcom_slim_rxwq(struct work_struct *work)
> +{
> +	u8 buf[SLIM_MSGQ_BUF_LEN];
> +	u8 mc, mt, len;
> +	int i, ret;
> +	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
> +						 wd);
> +
> +	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
> +		len = SLIM_HEADER_GET_RL(buf[0]);
> +		mt = SLIM_HEADER_GET_MT(buf[0]);
> +		mc = SLIM_HEADER_GET_MC(buf[1]);
> +		if (mt == SLIM_MSG_MT_CORE &&
> +			mc == SLIM_MSG_MC_REPORT_PRESENT) {
> +			u8 laddr;
> +			struct slim_eaddr ea;
> +			u8 e_addr[6];
> +
> +			for (i = 0; i < 6; i++)
> +				e_addr[i] = buf[7-i];
> +
> +			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
> +			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
> +			ea.dev_index = e_addr[1];
> +			ea.instance = e_addr[0];

If we are just bitshifting this out of the bytes does it really
make it much more clear to reverse the byte order first? Feels
like you might as well shift it out of buf directly.

Also we didn't bother to reverse the bytes for the element code
above, so feels more consistent.

> +			ret = slim_device_report_present(&ctrl->ctrl,
> +							 &ea, &laddr);
> +			if (ret < 0)
> +				dev_err(ctrl->dev, "assign laddr failed:%d\n",
> +					ret);
> +		} else {
> +			dev_err(ctrl->dev, "unexpected message:mc:%x, mt:%x\n",
> +				mc, mt);
> +		}
> +	}
> +}

Thanks,
Charles

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 12/13] slimbus: qcom: Add runtime-pm support using clock-pause
  2017-11-15 14:10 ` [PATCH v7 12/13] slimbus: qcom: Add runtime-pm support using clock-pause srinivas.kandagatla
@ 2017-11-23 10:17     ` Charles Keepax
  0 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23 10:17 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, vinod.koul, treding, devicetree,
	james.hogan, pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt,
	sdharia, alan, bp, mathieu.poirier, gregkh, linux-kernel,
	broonie, daniel, jkosina, joe, davem

On Wed, Nov 15, 2017 at 02:10:42PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> Slimbus HW mandates that clock-pause sequence has to be executed
> before disabling relevant interface and core clocks.
> Runtime-PM's autosuspend feature is used here to enter/exit low
> power mode for Qualcomm's Slimbus controller. Autosuspend feature
> enables driver to avoid changing power-modes too frequently since
> entering clock-pause is an expensive sequence
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int qcom_slim_suspend(struct device *dev)
> +{
> +	int ret = 0;
> +
> +	if (!pm_runtime_enabled(dev) ||
> +		(!pm_runtime_suspended(dev))) {
> +		dev_dbg(dev, "system suspend");
> +		ret = qcom_slim_runtime_suspend(dev);
> +	}
> +
> +	/*
> +	 * If the clock pause failed due to active channels, there is
> +	 * a possibility that some audio stream is active during suspend.
> +	 * (e.g. modem usecase during suspend)
> +	 * We dont want to return suspend failure in that case so that
> +	 * display and relevant components can still go to suspend.
> +	 * If there is some other error, then it should prevent
> +	 * system level suspend
> +	 */
> +	if (ret == -EISCONN)
> +		ret = 0;

Who actually returns the EISCONN for this to catch? Or will that
be added to slim_ctrl_clk_pause once support for the audio
channels is added?

Thanks,
Charles

> +
> +	return ret;
> +}

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 12/13] slimbus: qcom: Add runtime-pm support using clock-pause
@ 2017-11-23 10:17     ` Charles Keepax
  0 siblings, 0 replies; 78+ messages in thread
From: Charles Keepax @ 2017-11-23 10:17 UTC (permalink / raw)
  To: srinivas.kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

On Wed, Nov 15, 2017 at 02:10:42PM +0000, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
> 
> Slimbus HW mandates that clock-pause sequence has to be executed
> before disabling relevant interface and core clocks.
> Runtime-PM's autosuspend feature is used here to enter/exit low
> power mode for Qualcomm's Slimbus controller. Autosuspend feature
> enables driver to avoid changing power-modes too frequently since
> entering clock-pause is an expensive sequence
> 
> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> ---
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int qcom_slim_suspend(struct device *dev)
> +{
> +	int ret = 0;
> +
> +	if (!pm_runtime_enabled(dev) ||
> +		(!pm_runtime_suspended(dev))) {
> +		dev_dbg(dev, "system suspend");
> +		ret = qcom_slim_runtime_suspend(dev);
> +	}
> +
> +	/*
> +	 * If the clock pause failed due to active channels, there is
> +	 * a possibility that some audio stream is active during suspend.
> +	 * (e.g. modem usecase during suspend)
> +	 * We dont want to return suspend failure in that case so that
> +	 * display and relevant components can still go to suspend.
> +	 * If there is some other error, then it should prevent
> +	 * system level suspend
> +	 */
> +	if (ret == -EISCONN)
> +		ret = 0;

Who actually returns the EISCONN for this to catch? Or will that
be added to slim_ctrl_clk_pause once support for the audio
channels is added?

Thanks,
Charles

> +
> +	return ret;
> +}

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
  2017-11-23 10:07       ` Charles Keepax
  (?)
@ 2017-11-23 16:42       ` Jonathan Neuschäfer
  2017-11-24 14:40         ` Srinivas Kandagatla
  -1 siblings, 1 reply; 78+ messages in thread
From: Jonathan Neuschäfer @ 2017-11-23 16:42 UTC (permalink / raw)
  To: srinivas.kandagatla, Charles Keepax
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

[-- Attachment #1: Type: text/plain, Size: 2682 bytes --]

Hello Srinivas and Charles,

On Thu, Nov 23, 2017 at 10:07:03AM +0000, Charles Keepax wrote:
> On Wed, Nov 15, 2017 at 02:10:41PM +0000, srinivas.kandagatla@linaro.org wrote:
> > From: Sagar Dharia <sdharia@codeaurora.org>
> > 
> > This controller driver programs manager, interface, and framer
> > devices for Qualcomm's slimbus HW block.
> > Manager component currently implements logical address setting,
> > and messaging interface.
> > Interface device reports bus synchronization information, and framer
> > device clocks the bus from the time it's woken up, until clock-pause
> > is executed by the manager device.
> > 
> > Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
> > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> > ---
[...]
> > +static void qcom_slim_rxwq(struct work_struct *work)
> > +{
> > +	u8 buf[SLIM_MSGQ_BUF_LEN];
> > +	u8 mc, mt, len;
> > +	int i, ret;
> > +	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
> > +						 wd);
> > +
> > +	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
> > +		len = SLIM_HEADER_GET_RL(buf[0]);
> > +		mt = SLIM_HEADER_GET_MT(buf[0]);
> > +		mc = SLIM_HEADER_GET_MC(buf[1]);
> > +		if (mt == SLIM_MSG_MT_CORE &&
> > +			mc == SLIM_MSG_MC_REPORT_PRESENT) {
> > +			u8 laddr;
> > +			struct slim_eaddr ea;
> > +			u8 e_addr[6];
> > +
> > +			for (i = 0; i < 6; i++)
> > +				e_addr[i] = buf[7-i];
> > +
> > +			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
> > +			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
> > +			ea.dev_index = e_addr[1];
> > +			ea.instance = e_addr[0];
> 
> If we are just bitshifting this out of the bytes does it really
> make it much more clear to reverse the byte order first? Feels
> like you might as well shift it out of buf directly.

In any case, there is a predefined function to make this code a little
nicer in <asm/byteorder.h>:

	le16_to_cpu(x):  Converts the 16-bit little endian value x to
	                 CPU-endian
	le16_to_cpup(p): Converts the 16-bit little endian value pointed
	                 to by p to CPU-endian

If you use le16_to_cpup, you need to cast your pointer to __le16 *:

	ea.manf_id = le16_to_cpup((__le16 *)&e_addr[4]);

Like Charles, I don't quite see the point of the for loop that fills
e_addr. I guess it did effectively a byteswap, so the original code,
that assumed little-endian, could simply dereference a u16 *. This does
not make a lot of sense anymore, once you use properly (CPU-)endian-
independent code. (Of course, you'll need to replace le16 with be16 if
you drop that loop.)


Thanks,
Jonathan Neuschäfer

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature
  2017-11-23  7:28     ` Charles Keepax
@ 2017-11-24 14:39         ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-24 14:39 UTC (permalink / raw)
  To: Charles Keepax
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w, arnd-r2nGTMty4D4

Thanks for the Review,

On 23/11/17 07:28, Charles Keepax wrote:
> On Wed, Nov 15, 2017 at 02:10:37PM +0000, srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org wrote:
>> From: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>>
>> Per slimbus specification, a reconfiguration sequence known as
>> 'clock pause' needs to be broadcast over the bus while entering low-
>> power mode. Clock-pause is initiated by the controller driver.
>> To exit clock-pause, controller typically wakes up the framer device.
>> Since wakeup precedure is controller-specific, framework calls it via
>> controller's function pointer to invoke it.
>>
>> Signed-off-by: Sagar Dharia <sdharia-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
>> +/**
>> + * struct slim_sched: Framework uses this structure internally for scheduling.
> 
> Missing kernel doc for clkgear here.
Will add that in next version.

> 
>> + * @clk_state: Controller's clock state from enum slim_clk_state
>> + * @pause_comp: Signals completion of clock pause sequence. This is useful when
>> + *	client tries to call slimbus transaction when controller is entering
>> + *	clock pause.
>> + * @m_reconf: This mutex is held until current reconfiguration (data channel
>> + *	scheduling, message bandwidth reservation) is done. Message APIs can
>> + *	use the bus concurrently when this mutex is held since elemental access
>> + *	messages can be sent on the bus when reconfiguration is in progress.
>> + */
>> +struct slim_sched {
>> +	int			clkgear;
>> +	enum slim_clk_state	clk_state;
>> +	struct completion	pause_comp;
>> +	struct mutex		m_reconf;
>> +};
> 
> Thanks,
> Charles
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature
@ 2017-11-24 14:39         ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-24 14:39 UTC (permalink / raw)
  To: Charles Keepax
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

Thanks for the Review,

On 23/11/17 07:28, Charles Keepax wrote:
> On Wed, Nov 15, 2017 at 02:10:37PM +0000, srinivas.kandagatla@linaro.org wrote:
>> From: Sagar Dharia <sdharia@codeaurora.org>
>>
>> Per slimbus specification, a reconfiguration sequence known as
>> 'clock pause' needs to be broadcast over the bus while entering low-
>> power mode. Clock-pause is initiated by the controller driver.
>> To exit clock-pause, controller typically wakes up the framer device.
>> Since wakeup precedure is controller-specific, framework calls it via
>> controller's function pointer to invoke it.
>>
>> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> ---
>> +/**
>> + * struct slim_sched: Framework uses this structure internally for scheduling.
> 
> Missing kernel doc for clkgear here.
Will add that in next version.

> 
>> + * @clk_state: Controller's clock state from enum slim_clk_state
>> + * @pause_comp: Signals completion of clock pause sequence. This is useful when
>> + *	client tries to call slimbus transaction when controller is entering
>> + *	clock pause.
>> + * @m_reconf: This mutex is held until current reconfiguration (data channel
>> + *	scheduling, message bandwidth reservation) is done. Message APIs can
>> + *	use the bus concurrently when this mutex is held since elemental access
>> + *	messages can be sent on the bus when reconfiguration is in progress.
>> + */
>> +struct slim_sched {
>> +	int			clkgear;
>> +	enum slim_clk_state	clk_state;
>> +	struct completion	pause_comp;
>> +	struct mutex		m_reconf;
>> +};
> 
> Thanks,
> Charles
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 08/13] regmap: add SLIMbus support
  2017-11-23  7:49     ` Charles Keepax
  (?)
@ 2017-11-24 14:39     ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-24 14:39 UTC (permalink / raw)
  To: alsa-devel

Thanks for the Review,

On 23/11/17 07:49, Charles Keepax wrote:
> On Wed, Nov 15, 2017 at 02:10:38PM +0000, srinivas.kandagatla@linaro.org wrote:
>> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>>
>> This patch adds support to read/write slimbus value elements.
>> Currently it only supports byte read/write. Adding this support in
>> regmap would give codec drivers more flexibility when there are more
>> than 2 control interfaces like slimbus, i2c.
>>
>> Without this patch each codec driver has to directly call slimbus value
>> element apis, and this could would get messy once we want to add i2c
>> interface to it.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> ---
>> +
>> +static int regmap_slimbus_byte_reg_read(void *context, unsigned int reg,
>> +					unsigned int *val)
>> +{
>> +	struct slim_device *sdev = context;
>> +	int v;
>> +
>> +	if (!sdev)
>> +		return 0;
> 
> Is there a specific reason we are checking the context here? The
> other regmap buses don't both and whilst I don't mind checking
> shouldn't we return an error if we don't have a context rather
> than pretending to succeed?
looks like over done here, I will fix it in next version.

> 
>> +
>> +	v = slim_readb(sdev, reg);
>> +
>> +	if (v < 0)
>> +		return v;
>> +
>> +	*val = v;
>> +
>> +	return 0;
>> +}
>> +
>> +static int regmap_slimbus_byte_reg_write(void *context, unsigned int reg,
>> +					 unsigned int val)
>> +{
>> +	struct slim_device *sdev = context;
>> +
>> +	if (!sdev)
>> +		return 0;
> 
> ditto.
> 
> Thanks,
> Charles
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 12/13] slimbus: qcom: Add runtime-pm support using clock-pause
  2017-11-23 10:17     ` Charles Keepax
  (?)
@ 2017-11-24 14:39     ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-24 14:39 UTC (permalink / raw)
  To: Charles Keepax
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

Thanks for the review,

On 23/11/17 10:17, Charles Keepax wrote:
> On Wed, Nov 15, 2017 at 02:10:42PM +0000, srinivas.kandagatla@linaro.org wrote:
>> From: Sagar Dharia <sdharia@codeaurora.org>
>>
>> Slimbus HW mandates that clock-pause sequence has to be executed
>> before disabling relevant interface and core clocks.
>> Runtime-PM's autosuspend feature is used here to enter/exit low
>> power mode for Qualcomm's Slimbus controller. Autosuspend feature
>> enables driver to avoid changing power-modes too frequently since
>> entering clock-pause is an expensive sequence
>>
>> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> ---
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int qcom_slim_suspend(struct device *dev)
>> +{
>> +	int ret = 0;
>> +
>> +	if (!pm_runtime_enabled(dev) ||
>> +		(!pm_runtime_suspended(dev))) {
>> +		dev_dbg(dev, "system suspend");
>> +		ret = qcom_slim_runtime_suspend(dev);
>> +	}
>> +
>> +	/*
>> +	 * If the clock pause failed due to active channels, there is
>> +	 * a possibility that some audio stream is active during suspend.
>> +	 * (e.g. modem usecase during suspend)
>> +	 * We dont want to return suspend failure in that case so that
>> +	 * display and relevant components can still go to suspend.
>> +	 * If there is some other error, then it should prevent
>> +	 * system level suspend
>> +	 */
>> +	if (ret == -EISCONN)
>> +		ret = 0;
> 
> Who actually returns the EISCONN for this to catch? Or will that
> be added to slim_ctrl_clk_pause once support for the audio
> channels is added?

This looks like a leftover code, I will remove it in next version and we 
can add it once related code is added.



> 
> Thanks,
> Charles
> 
>> +
>> +	return ret;
>> +}

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
  2017-11-23 10:07       ` Charles Keepax
  (?)
  (?)
@ 2017-11-24 14:39       ` Srinivas Kandagatla
  -1 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-24 14:39 UTC (permalink / raw)
  To: Charles Keepax
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

Thanks for your review,

On 23/11/17 10:07, Charles Keepax wrote:
>> +static irqreturn_t qcom_slim_handle_rx_irq(struct qcom_slim_ctrl *ctrl,
>> +					   u32 stat)
>> +{
>> +	u32 *rx_buf, pkt[10];
>> +	bool q_rx = false;
>> +	u8 la, *buf, mc, mt, len, *b = (u8 *)&pkt[0];
>> +	u16 ele;
>> +
> 
> This function feels pretty funky, we basically have rx_buf, pkt,
> b and buf all of which basically point to the same thing. Can we
> simplify it a little?
I will give that a try before I send next version.
> 
>> +	pkt[0] = readl_relaxed(ctrl->base + MGR_RX_MSG);
>> +	mt = SLIM_HEADER_GET_MT(b[0]);
>> +	len = SLIM_HEADER_GET_RL(b[0]);
>> +	mc = SLIM_HEADER_GET_MC(b[1]);
>> +
>> +	/*
...

>> +
>> +	puc = (u8 *)pbuf;
>> +	head = (u32 *)pbuf;
>> +
>> +	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
>> +		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 0,
>> +						la);
>> +	else
>> +		*head = SLIM_MSG_ASM_FIRST_WORD(txn->rl, txn->mt, txn->mc, 1,
>> +						la);
>> +
>> +	if (txn->dt == SLIM_MSG_DEST_LOGICALADDR)
>> +		puc += 3;
>> +	else
>> +		puc += 2;
> 
> Combine these two if statements, makes it much clearer the actions
> are related.
I agree!!

> 
>> +
>> +	if (txn->mt == SLIM_MSG_MT_CORE && slim_tid_txn(txn->mt, txn->mc))
> 
> slim_tid_txn checks for SLIM_MSG_MT_CORE so the check here should
> be redundant.
> 
Yep, will remove this in next version.

>> +		*(puc++) = txn->tid;
>> +
>> +	if ((txn->mt == SLIM_MSG_MT_CORE) &&
>> +		((txn->mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
>> +		txn->mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
>> +		(txn->mc >= SLIM_MSG_MC_REQUEST_VALUE &&
>> +		 txn->mc <= SLIM_MSG_MC_CHANGE_VALUE))) {
>> +		*(puc++) = (txn->ec & 0xFF);
>> +		*(puc++) = (txn->ec >> 8) & 0xFF;
>> +	}
> 
> As you already have slim_tid_txn, would it be worth adding
> something like slim_ec_txn? 
I will give it a go and see how it looks like..

To state if an element code is
> required, feels like other controls will probably want to do a
> similar thing and would make the code a little more readable
> here.
> 
>> +
>> +	if (txn->msg && txn->msg->wbuf)
>> +		memcpy(puc, txn->msg->wbuf, txn->msg->num_bytes);
>> +
>> +	qcom_slim_queue_tx(ctrl, head, txn->rl, MGR_TX_MSG);
>> +	timeout = wait_for_completion_timeout(&done, msecs_to_jiffies(ms));
>> +
>> +	if (!timeout) {
>> +		dev_err(ctrl->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
>> +					txn->mt);
>> +		ret = -ETIMEDOUT;
>> +	}
>> +
>> +	return ret;
>> +
>> +}
>> +
>> +static void qcom_slim_rxwq(struct work_struct *work)
>> +{
>> +	u8 buf[SLIM_MSGQ_BUF_LEN];
>> +	u8 mc, mt, len;
>> +	int i, ret;
>> +	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
>> +						 wd);
>> +
>> +	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
>> +		len = SLIM_HEADER_GET_RL(buf[0]);
>> +		mt = SLIM_HEADER_GET_MT(buf[0]);
>> +		mc = SLIM_HEADER_GET_MC(buf[1]);
>> +		if (mt == SLIM_MSG_MT_CORE &&
>> +			mc == SLIM_MSG_MC_REPORT_PRESENT) {
>> +			u8 laddr;
>> +			struct slim_eaddr ea;
>> +			u8 e_addr[6];
>> +
>> +			for (i = 0; i < 6; i++)
>> +				e_addr[i] = buf[7-i];
>> +
>> +			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
>> +			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
>> +			ea.dev_index = e_addr[1];
>> +			ea.instance = e_addr[0];
> 
> If we are just bitshifting this out of the bytes does it really
> make it much more clear to reverse the byte order first? Feels
> like you might as well shift it out of buf directly.
> 
> Also we didn't bother to reverse the bytes for the element code
> above, so feels more consistent.
I will try Jonathan Neuschäfer Suggestion to simplify this area of code.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver
  2017-11-23 16:42       ` Jonathan Neuschäfer
@ 2017-11-24 14:40         ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-24 14:40 UTC (permalink / raw)
  To: Jonathan Neuschäfer, Charles Keepax
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, vinod.koul, arnd

Thanks for your review,

On 23/11/17 16:42, Jonathan Neuschäfer wrote:
> Hello Srinivas and Charles,
> 
> On Thu, Nov 23, 2017 at 10:07:03AM +0000, Charles Keepax wrote:
>> On Wed, Nov 15, 2017 at 02:10:41PM +0000, srinivas.kandagatla@linaro.org wrote:
>>> From: Sagar Dharia <sdharia@codeaurora.org>
>>>
>>> This controller driver programs manager, interface, and framer
>>> devices for Qualcomm's slimbus HW block.
>>> Manager component currently implements logical address setting,
>>> and messaging interface.
>>> Interface device reports bus synchronization information, and framer
>>> device clocks the bus from the time it's woken up, until clock-pause
>>> is executed by the manager device.
>>>
>>> Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>>> ---
> [...]
>>> +static void qcom_slim_rxwq(struct work_struct *work)
>>> +{
>>> +	u8 buf[SLIM_MSGQ_BUF_LEN];
>>> +	u8 mc, mt, len;
>>> +	int i, ret;
>>> +	struct qcom_slim_ctrl *ctrl = container_of(work, struct qcom_slim_ctrl,
>>> +						 wd);
>>> +
>>> +	while ((slim_get_current_rxbuf(ctrl, buf)) != -ENODATA) {
>>> +		len = SLIM_HEADER_GET_RL(buf[0]);
>>> +		mt = SLIM_HEADER_GET_MT(buf[0]);
>>> +		mc = SLIM_HEADER_GET_MC(buf[1]);
>>> +		if (mt == SLIM_MSG_MT_CORE &&
>>> +			mc == SLIM_MSG_MC_REPORT_PRESENT) {
>>> +			u8 laddr;
>>> +			struct slim_eaddr ea;
>>> +			u8 e_addr[6];
>>> +
>>> +			for (i = 0; i < 6; i++)
>>> +				e_addr[i] = buf[7-i];
>>> +
>>> +			ea.manf_id = (u16)(e_addr[5] << 8) | e_addr[4];
>>> +			ea.prod_code = (u16)(e_addr[3] << 8) | e_addr[2];
>>> +			ea.dev_index = e_addr[1];
>>> +			ea.instance = e_addr[0];
>>
>> If we are just bitshifting this out of the bytes does it really
>> make it much more clear to reverse the byte order first? Feels
>> like you might as well shift it out of buf directly.
> 
> In any case, there is a predefined function to make this code a little
> nicer in <asm/byteorder.h>:
> 
> 	le16_to_cpu(x):  Converts the 16-bit little endian value x to
> 	                 CPU-endian
> 	le16_to_cpup(p): Converts the 16-bit little endian value pointed
> 	                 to by p to CPU-endian
> 
> If you use le16_to_cpup, you need to cast your pointer to __le16 *:
> 
> 	ea.manf_id = le16_to_cpup((__le16 *)&e_addr[4]);
> 
It Looks like I can make use of these apis here, I will give this a go 
to cleanup this part of the code.

thanks,
srini

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
  2017-11-20  6:47           ` Srinivas Kandagatla
@ 2017-11-27  5:52                 ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-27  5:52 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg KH, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	sdharia-sgV2jX0FEOL9JmXXK+q4OQ, bp-l3A5Bk7waGM,
	poeschel-Xtl8qvBWbHwb1SvskN2V4Q, treding-DDmLM1+adcrQT0dZR+AlfA,
	andreas.noever-Re5JQEeQqe8AvxtiuMwx3w,
	alan-VuQAYsv1563Yd54FQh9/CA,
	mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A, daniel-/w4YWyX8dFk,
	jkosina-AlSwsSmVLrQ, sharon.dvir1-MQgwKvJRKlGYZoqfULhbRA,
	joe-6d6DIl74uiNBDgjK7y7TUQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
	james.hogan-1AXoQHu6uovQT0dZR+AlfA,
	michael.opdenacker-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4

On Mon, Nov 20, 2017 at 06:47:58AM +0000, Srinivas Kandagatla wrote:
> >>>thanks for the comments.
> >>>
> >>>
> >>>On 16/11/17 16:42, Vinod Koul wrote:
> >>>>On Wed, Nov 15, 2017 at 02:10:34PM +0000,srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org  wrote:
> >>>>
> >>>>>+static void slim_dev_release(struct device *dev)
> >>>>>+{
> >>>>>+	struct slim_device *sbdev = to_slim_device(dev);
> >>>>>+
> >>>>>+	put_device(sbdev->ctrl->dev);
> >>>>which device would that be?
> >>>This is controller device
> >>>
> >>>>>+static int slim_add_device(struct slim_controller *ctrl,
> >>>>>+			   struct slim_device *sbdev,
> >>>>>+			   struct device_node *node)
> >>>>>+{
> >>>>>+	sbdev->dev.bus = &slimbus_bus;
> >>>>>+	sbdev->dev.parent = ctrl->dev;
> >>>>>+	sbdev->dev.release = slim_dev_release;
> >>>>>+	sbdev->dev.driver = NULL;
> >>>>>+	sbdev->ctrl = ctrl;
> >>>>>+
> >>>>>+	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
> >>>>>+				  sbdev->e_addr.manf_id,
> >>>>>+				  sbdev->e_addr.prod_code,
> >>>>>+				  sbdev->e_addr.dev_index,
> >>>>>+				  sbdev->e_addr.instance);
> >>>>>+
> >>>>>+	get_device(ctrl->dev);
> >>>>is this controller device and you ensuring it doesnt go away while you have
> >>>>slaves on it?
> >>>Yes.
> >>I thought since you are marking ctrl->dev as parent, the device core should
> >>ensure that parent doesn't go off when you have child device?
> >>
> >>Greg, is that understanding correct, if so we may not need these calls.
> >That understanding should be correct, as the reference count is
> >incremented on the parent when a child is added.
> >
> >It would be trivial for this to be tested, and yes, I am pretty sure you
> >don't need this call.
> 
> Thanks for suggestion, I will remove this in next version.

I think it might be helpful to test the assumption as Greg noted :)

-- 
~Vinod
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 04/13] slimbus: core: Add slim controllers support
@ 2017-11-27  5:52                 ` Vinod Koul
  0 siblings, 0 replies; 78+ messages in thread
From: Vinod Koul @ 2017-11-27  5:52 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg KH, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Mon, Nov 20, 2017 at 06:47:58AM +0000, Srinivas Kandagatla wrote:
> >>>thanks for the comments.
> >>>
> >>>
> >>>On 16/11/17 16:42, Vinod Koul wrote:
> >>>>On Wed, Nov 15, 2017 at 02:10:34PM +0000,srinivas.kandagatla@linaro.org  wrote:
> >>>>
> >>>>>+static void slim_dev_release(struct device *dev)
> >>>>>+{
> >>>>>+	struct slim_device *sbdev = to_slim_device(dev);
> >>>>>+
> >>>>>+	put_device(sbdev->ctrl->dev);
> >>>>which device would that be?
> >>>This is controller device
> >>>
> >>>>>+static int slim_add_device(struct slim_controller *ctrl,
> >>>>>+			   struct slim_device *sbdev,
> >>>>>+			   struct device_node *node)
> >>>>>+{
> >>>>>+	sbdev->dev.bus = &slimbus_bus;
> >>>>>+	sbdev->dev.parent = ctrl->dev;
> >>>>>+	sbdev->dev.release = slim_dev_release;
> >>>>>+	sbdev->dev.driver = NULL;
> >>>>>+	sbdev->ctrl = ctrl;
> >>>>>+
> >>>>>+	dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
> >>>>>+				  sbdev->e_addr.manf_id,
> >>>>>+				  sbdev->e_addr.prod_code,
> >>>>>+				  sbdev->e_addr.dev_index,
> >>>>>+				  sbdev->e_addr.instance);
> >>>>>+
> >>>>>+	get_device(ctrl->dev);
> >>>>is this controller device and you ensuring it doesnt go away while you have
> >>>>slaves on it?
> >>>Yes.
> >>I thought since you are marking ctrl->dev as parent, the device core should
> >>ensure that parent doesn't go off when you have child device?
> >>
> >>Greg, is that understanding correct, if so we may not need these calls.
> >That understanding should be correct, as the reference count is
> >incremented on the parent when a child is added.
> >
> >It would be trivial for this to be tested, and yes, I am pretty sure you
> >don't need this call.
> 
> Thanks for suggestion, I will remove this in next version.

I think it might be helpful to test the assumption as Greg noted :)

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
  2017-11-20  6:47         ` Srinivas Kandagatla
@ 2017-11-27  5:56           ` Vinod Koul
  2017-11-28  7:18               ` Srinivas Kandagatla
  0 siblings, 1 reply; 78+ messages in thread
From: Vinod Koul @ 2017-11-27  5:56 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd

On Mon, Nov 20, 2017 at 06:47:52AM +0000, Srinivas Kandagatla wrote:

> >>+ *	-ENOTCONN: If the transmitted message was not ACKed by destination
> >>+ *	device.
> >
> >I am preferring ENODATA in SDW for this case, as Slaves didnt respond or
> >ACK.
> Isn't that a timeout error then.
> 
> ENODATA is for "No data available", reporting ENODATA would be misleading.

Do you get a explict NACK or no response for this

> 
> >
> >ENOTCONN is defined as /* Transport endpoint is not connected */ which is
> >not the case here, connected yes but not responded.
> 
> Code as it is would not return this, so i will be deleting ENOTCONN from
> kernel doc.

ok

-- 
~Vinod

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
  2017-11-27  5:56           ` Vinod Koul
@ 2017-11-28  7:18               ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-28  7:18 UTC (permalink / raw)
  To: Vinod Koul
  Cc: mark.rutland, alsa-devel, michael.opdenacker, poeschel,
	andreas.noever, arnd, treding, devicetree, james.hogan,
	pawel.moll, linux-arm-msm, sharon.dvir1, robh+dt, sdharia, alan,
	bp, mathieu.poirier, gregkh, linux-kernel, broonie, daniel,
	jkosina, joe, davem



On 27/11/17 05:56, Vinod Koul wrote:
> On Mon, Nov 20, 2017 at 06:47:52AM +0000, Srinivas Kandagatla wrote:
> 
>>>> + *	-ENOTCONN: If the transmitted message was not ACKed by destination
>>>> + *	device.
>>>
>>> I am preferring ENODATA in SDW for this case, as Slaves didnt respond or
>>> ACK.
>> Isn't that a timeout error then.
>>
>> ENODATA is for "No data available", reporting ENODATA would be misleading.
> 
> Do you get a explict NACK or no response for this

There is no response for the request, currently code waits for it arrive 
and then timesout on completion.

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework
@ 2017-11-28  7:18               ` Srinivas Kandagatla
  0 siblings, 0 replies; 78+ messages in thread
From: Srinivas Kandagatla @ 2017-11-28  7:18 UTC (permalink / raw)
  To: Vinod Koul
  Cc: gregkh, broonie, alsa-devel, sdharia, bp, poeschel, treding,
	andreas.noever, alan, mathieu.poirier, daniel, jkosina,
	sharon.dvir1, joe, davem, james.hogan, michael.opdenacker,
	robh+dt, pawel.moll, mark.rutland, devicetree, linux-kernel,
	linux-arm-msm, arnd



On 27/11/17 05:56, Vinod Koul wrote:
> On Mon, Nov 20, 2017 at 06:47:52AM +0000, Srinivas Kandagatla wrote:
> 
>>>> + *	-ENOTCONN: If the transmitted message was not ACKed by destination
>>>> + *	device.
>>>
>>> I am preferring ENODATA in SDW for this case, as Slaves didnt respond or
>>> ACK.
>> Isn't that a timeout error then.
>>
>> ENODATA is for "No data available", reporting ENODATA would be misleading.
> 
> Do you get a explict NACK or no response for this

There is no response for the request, currently code waits for it arrive 
and then timesout on completion.

^ permalink raw reply	[flat|nested] 78+ messages in thread

end of thread, other threads:[~2017-11-28  7:18 UTC | newest]

Thread overview: 78+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-15 14:10 [PATCH v7 00/13] Introduce framework for SLIMbus device driver srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-11-15 14:10 ` srinivas.kandagatla
2017-11-15 14:10 ` [PATCH v7 01/13] Documentation: Add SLIMbus summary srinivas.kandagatla
2017-11-15 14:10   ` srinivas.kandagatla
2017-11-15 14:10 ` [PATCH v7 02/13] dt-bindings: Add SLIMbus bindings srinivas.kandagatla
2017-11-15 14:10   ` srinivas.kandagatla
2017-11-16  5:15   ` Rob Herring
2017-11-16  5:15     ` Rob Herring
2017-11-23  7:41     ` Charles Keepax
2017-11-23  7:41       ` Charles Keepax
2017-11-16 13:09   ` Vinod Koul
2017-11-16 13:40     ` Srinivas Kandagatla
2017-11-16 13:40       ` Srinivas Kandagatla
     [not found]       ` <a32232fc-3995-60f6-878e-76aaed4c52d6-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-17  3:55         ` Vinod Koul
2017-11-17  3:55           ` Vinod Koul
2017-11-15 14:10 ` [PATCH v7 03/13] slimbus: Add SLIMbus bus type srinivas.kandagatla
2017-11-16 12:25   ` Mark Brown
2017-11-16 12:25     ` Mark Brown
2017-11-16 13:18   ` Vinod Koul
2017-11-16 13:18     ` [alsa-devel] " Vinod Koul
2017-11-16 13:40     ` Srinivas Kandagatla
2017-11-16 13:40       ` [alsa-devel] " Srinivas Kandagatla
     [not found]       ` <e2fa6b56-965d-74e7-af2f-77baf0f50901-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-16 16:14         ` Vinod Koul
2017-11-16 16:14           ` Vinod Koul
2017-11-16 16:13           ` Srinivas Kandagatla
2017-11-16 16:13             ` [alsa-devel] " Srinivas Kandagatla
2017-11-15 14:10 ` [PATCH v7 04/13] slimbus: core: Add slim controllers support srinivas.kandagatla
2017-11-16 16:42   ` Vinod Koul
2017-11-16 16:42     ` Vinod Koul
2017-11-16 17:29     ` Srinivas Kandagatla
2017-11-16 17:29       ` Srinivas Kandagatla
2017-11-17  4:42       ` Vinod Koul
2017-11-17  8:13         ` Greg KH
2017-11-20  6:47           ` Srinivas Kandagatla
     [not found]             ` <64797182-9244-e6e7-8044-dbc404cdda7c-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-27  5:52               ` Vinod Koul
2017-11-27  5:52                 ` Vinod Koul
2017-11-15 14:10 ` [PATCH v7 05/13] slimbus: core: add support to device tree helper srinivas.kandagatla
     [not found]   ` <20171115141043.29202-6-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-17  7:11     ` [alsa-devel] " Vinod Koul
2017-11-17  7:11       ` Vinod Koul
2017-11-15 14:10 ` [PATCH v7 07/13] slimbus: Add support for 'clock-pause' feature srinivas.kandagatla
2017-11-15 14:10   ` srinivas.kandagatla
2017-11-23  7:28   ` Charles Keepax
2017-11-23  7:28     ` Charles Keepax
     [not found]     ` <20171123072800.z2pkmelom374zr63-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2017-11-24 14:39       ` Srinivas Kandagatla
2017-11-24 14:39         ` Srinivas Kandagatla
2017-11-15 14:10 ` [PATCH v7 08/13] regmap: add SLIMbus support srinivas.kandagatla
2017-11-15 14:10   ` srinivas.kandagatla
2017-11-23  7:49   ` Charles Keepax
2017-11-23  7:49     ` Charles Keepax
2017-11-24 14:39     ` Srinivas Kandagatla
2017-11-15 14:10 ` [PATCH v7 09/13] slimbus: core: add common defines required for controllers srinivas.kandagatla
2017-11-15 14:10   ` srinivas.kandagatla
2017-11-15 14:10 ` [PATCH v7 10/13] dt-bindings: Add qcom slimbus controller bindings srinivas.kandagatla
2017-11-16  5:19   ` Rob Herring
2017-11-16  5:19     ` Rob Herring
2017-11-16  9:42     ` Srinivas Kandagatla
2017-11-16  9:42       ` Srinivas Kandagatla
     [not found] ` <20171115141043.29202-1-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-15 14:10   ` [PATCH v7 06/13] slimbus: Add messaging APIs to slimbus framework srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-11-15 14:10     ` srinivas.kandagatla
     [not found]     ` <20171115141043.29202-7-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-17  7:48       ` Vinod Koul
2017-11-17  7:48         ` Vinod Koul
2017-11-20  6:47         ` Srinivas Kandagatla
2017-11-27  5:56           ` Vinod Koul
2017-11-28  7:18             ` Srinivas Kandagatla
2017-11-28  7:18               ` Srinivas Kandagatla
2017-11-15 14:10   ` [PATCH v7 11/13] slimbus: qcom: Add Qualcomm Slimbus controller driver srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-11-15 14:10     ` srinivas.kandagatla
2017-11-23 10:07     ` Charles Keepax
2017-11-23 10:07       ` Charles Keepax
2017-11-23 16:42       ` Jonathan Neuschäfer
2017-11-24 14:40         ` Srinivas Kandagatla
2017-11-24 14:39       ` Srinivas Kandagatla
2017-11-15 14:10   ` [PATCH v7 13/13] MAINTAINERS: Add SLIMbus maintainer srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-11-15 14:10     ` srinivas.kandagatla
2017-11-15 14:10 ` [PATCH v7 12/13] slimbus: qcom: Add runtime-pm support using clock-pause srinivas.kandagatla
2017-11-23 10:17   ` Charles Keepax
2017-11-23 10:17     ` Charles Keepax
2017-11-24 14:39     ` Srinivas Kandagatla

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.