All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] soundwire: Add a new SoundWire subsystem
@ 2017-10-19  3:03 ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

So today we celebrate Diwali, the festival of lights in this part of
the world. On this occasion I would like to add a new Linux subsystem.

This patch series adds a new SoundWire subsystem which implements a
new MIPI bus protocol 'SoundWire'.

The SoundWire protocol is a robust, scalable, low complexity, low
power, low latency, two-pin (clock and data) multi-drop bus that
allows for the transfer of multiple audio streams and embedded
control/commands.  SoundWire provides synchronization capabilities and
supports both PCM and PDM, multichannel data, isochronous and
asynchronous modes.

This series adds SoundWire Bus, IO transfers, DisCo (Discovery and
Configuration) sysfs interface, regmap and Documentation summary

This patch series is also available on
git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git
topic/patch_v1

This is first version of the patch which incorporates lots of changes
based on the RFC series posted last year
https://lkml.org/lkml/2016/10/21/395


Sanyog Kale (4):
  Documentation: Add SoundWire summary
  soundwire: Add SoundWire MIPI defined registers
  soundwire: Add Slave status handling helpers
  soundwire: cdns: Add sdw_master_ops and IO transfer support

Vinod Koul (10):
  soundwire: Add SoundWire bus type
  soundwire: Add Master registration
  soundwire: Add MIPI DisCo property helpers
  soundwire: Add IO transfer
  regmap: Add SoundWire bus support
  soundwire: Add slave status handling
  soundwire: Add sysfs for SoundWire DisCo properties
  soundwire: cdns: Add cadence module
  soundwire: intel: Add Intel Master driver
  soundwire: intel: Add Intel init module

 Documentation/soundwire/summary.txt     | 192 +++++++
 drivers/Kconfig                         |   2 +
 drivers/Makefile                        |   1 +
 drivers/base/regmap/Kconfig             |   4 +
 drivers/base/regmap/Makefile            |   1 +
 drivers/base/regmap/regmap-sdw.c        | 146 +++++
 drivers/soundwire/Kconfig               |  37 ++
 drivers/soundwire/Makefile              |  18 +
 drivers/soundwire/bus.c                 | 983 ++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h                 | 119 ++++
 drivers/soundwire/bus_type.c            | 245 ++++++++
 drivers/soundwire/cadence_master.c      | 793 ++++++++++++++++++++++++++
 drivers/soundwire/cadence_master.h      |  94 +++
 drivers/soundwire/intel.c               | 395 +++++++++++++
 drivers/soundwire/intel.h               |  70 +++
 drivers/soundwire/intel_init.c          | 230 ++++++++
 drivers/soundwire/mipi_disco.c          | 421 ++++++++++++++
 drivers/soundwire/slave.c               | 173 ++++++
 drivers/soundwire/sysfs.c               | 396 +++++++++++++
 include/linux/mod_devicetable.h         |   7 +
 include/linux/regmap.h                  |  37 ++
 include/linux/soundwire/sdw.h           | 564 ++++++++++++++++++
 include/linux/soundwire/sdw_intel.h     |  72 +++
 include/linux/soundwire/sdw_registers.h | 238 ++++++++
 scripts/mod/devicetable-offsets.c       |   5 +
 scripts/mod/file2alias.c                |  16 +
 26 files changed, 5259 insertions(+)
 create mode 100644 Documentation/soundwire/summary.txt
 create mode 100644 drivers/base/regmap/regmap-sdw.c
 create mode 100644 drivers/soundwire/Kconfig
 create mode 100644 drivers/soundwire/Makefile
 create mode 100644 drivers/soundwire/bus.c
 create mode 100644 drivers/soundwire/bus.h
 create mode 100644 drivers/soundwire/bus_type.c
 create mode 100644 drivers/soundwire/cadence_master.c
 create mode 100644 drivers/soundwire/cadence_master.h
 create mode 100644 drivers/soundwire/intel.c
 create mode 100644 drivers/soundwire/intel.h
 create mode 100644 drivers/soundwire/intel_init.c
 create mode 100644 drivers/soundwire/mipi_disco.c
 create mode 100644 drivers/soundwire/slave.c
 create mode 100644 drivers/soundwire/sysfs.c
 create mode 100644 include/linux/soundwire/sdw.h
 create mode 100644 include/linux/soundwire/sdw_intel.h
 create mode 100644 include/linux/soundwire/sdw_registers.h

-- 
2.7.4

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

* [PATCH 00/14] soundwire: Add a new SoundWire subsystem
@ 2017-10-19  3:03 ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

So today we celebrate Diwali, the festival of lights in this part of
the world. On this occasion I would like to add a new Linux subsystem.

This patch series adds a new SoundWire subsystem which implements a
new MIPI bus protocol 'SoundWire'.

The SoundWire protocol is a robust, scalable, low complexity, low
power, low latency, two-pin (clock and data) multi-drop bus that
allows for the transfer of multiple audio streams and embedded
control/commands.  SoundWire provides synchronization capabilities and
supports both PCM and PDM, multichannel data, isochronous and
asynchronous modes.

This series adds SoundWire Bus, IO transfers, DisCo (Discovery and
Configuration) sysfs interface, regmap and Documentation summary

This patch series is also available on
git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git
topic/patch_v1

This is first version of the patch which incorporates lots of changes
based on the RFC series posted last year
https://lkml.org/lkml/2016/10/21/395


Sanyog Kale (4):
  Documentation: Add SoundWire summary
  soundwire: Add SoundWire MIPI defined registers
  soundwire: Add Slave status handling helpers
  soundwire: cdns: Add sdw_master_ops and IO transfer support

Vinod Koul (10):
  soundwire: Add SoundWire bus type
  soundwire: Add Master registration
  soundwire: Add MIPI DisCo property helpers
  soundwire: Add IO transfer
  regmap: Add SoundWire bus support
  soundwire: Add slave status handling
  soundwire: Add sysfs for SoundWire DisCo properties
  soundwire: cdns: Add cadence module
  soundwire: intel: Add Intel Master driver
  soundwire: intel: Add Intel init module

 Documentation/soundwire/summary.txt     | 192 +++++++
 drivers/Kconfig                         |   2 +
 drivers/Makefile                        |   1 +
 drivers/base/regmap/Kconfig             |   4 +
 drivers/base/regmap/Makefile            |   1 +
 drivers/base/regmap/regmap-sdw.c        | 146 +++++
 drivers/soundwire/Kconfig               |  37 ++
 drivers/soundwire/Makefile              |  18 +
 drivers/soundwire/bus.c                 | 983 ++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h                 | 119 ++++
 drivers/soundwire/bus_type.c            | 245 ++++++++
 drivers/soundwire/cadence_master.c      | 793 ++++++++++++++++++++++++++
 drivers/soundwire/cadence_master.h      |  94 +++
 drivers/soundwire/intel.c               | 395 +++++++++++++
 drivers/soundwire/intel.h               |  70 +++
 drivers/soundwire/intel_init.c          | 230 ++++++++
 drivers/soundwire/mipi_disco.c          | 421 ++++++++++++++
 drivers/soundwire/slave.c               | 173 ++++++
 drivers/soundwire/sysfs.c               | 396 +++++++++++++
 include/linux/mod_devicetable.h         |   7 +
 include/linux/regmap.h                  |  37 ++
 include/linux/soundwire/sdw.h           | 564 ++++++++++++++++++
 include/linux/soundwire/sdw_intel.h     |  72 +++
 include/linux/soundwire/sdw_registers.h | 238 ++++++++
 scripts/mod/devicetable-offsets.c       |   5 +
 scripts/mod/file2alias.c                |  16 +
 26 files changed, 5259 insertions(+)
 create mode 100644 Documentation/soundwire/summary.txt
 create mode 100644 drivers/base/regmap/regmap-sdw.c
 create mode 100644 drivers/soundwire/Kconfig
 create mode 100644 drivers/soundwire/Makefile
 create mode 100644 drivers/soundwire/bus.c
 create mode 100644 drivers/soundwire/bus.h
 create mode 100644 drivers/soundwire/bus_type.c
 create mode 100644 drivers/soundwire/cadence_master.c
 create mode 100644 drivers/soundwire/cadence_master.h
 create mode 100644 drivers/soundwire/intel.c
 create mode 100644 drivers/soundwire/intel.h
 create mode 100644 drivers/soundwire/intel_init.c
 create mode 100644 drivers/soundwire/mipi_disco.c
 create mode 100644 drivers/soundwire/slave.c
 create mode 100644 drivers/soundwire/sysfs.c
 create mode 100644 include/linux/soundwire/sdw.h
 create mode 100644 include/linux/soundwire/sdw_intel.h
 create mode 100644 include/linux/soundwire/sdw_registers.h

-- 
2.7.4

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

* [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-19  3:03 ` Vinod Koul
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-19  3:33     ` Randy Dunlap
                     ` (2 more replies)
  -1 siblings, 3 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

From: Sanyog Kale <sanyog.r.kale@intel.com>

SoundWire is a new Linux bus which implements a new MIPI bus protocol
'SoundWire'. The summary of SoundWire bus and registration APIs is
documented in the 'summary' file.

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
 1 file changed, 192 insertions(+)
 create mode 100644 Documentation/soundwire/summary.txt

diff --git a/Documentation/soundwire/summary.txt b/Documentation/soundwire/summary.txt
new file mode 100644
index 000000000000..15b78e6e3347
--- /dev/null
+++ b/Documentation/soundwire/summary.txt
@@ -0,0 +1,192 @@
+SoundWire
+===========
+
+SoundWire is a new interface ratified in 2015 by the MIPI Alliance.
+SoundWire is used for transporting data typically related to audio
+functions. SoundWire interface is optimized to integrate audio devices in
+mobile or mobile inspired systems.
+
+SoundWire is a 2-Pin multi-drop interface with data and clock line. It
+facilitates development of low cost, efficient, high performance systems.
+Broad level key features of SoundWire interface include:
+  1. Transporting all of payload data channels, control information, and setup
+  commands over a single two-pin interface.
+  2. Lower clock frequency, and hence lower power consumption, by use of DDR
+  (Dual Data Rate) data transmission.
+  3. Clock scaling and optional multiple data lanes to give wide flexibility
+  in data rate to match system requirements.
+  4. Device status monitoring, including interrupt-style alerts to the Master.
+
+The SoundWire protocol supports up to eleven Slave interfaces. All the
+interfaces share the common Bus containing data and clock line. Each of the
+Slaves can support up to 14 Data Ports. 13 Data Ports are dedicated to audio
+transport. Data Port0 is dedicated to transport of Bulk control information,
+each of the audio Data Ports (1..14) can support up to 8 Channels in
+transmit or receiving mode (typically fixed direction but configurable
+direction is enabled by the specification).  Bandwidth restrictions to
+~19.2..24.576Mbits/s don't however allow for 11*13*8 channels to be
+transmitted simultaneously.
+
+Below figure shows an example of connectivity between a SoundWire Master and
+two Slave devices.
+
++---------------+                                       +---------------+
+|               |                       Clock Signal    |               |
+|    Master     |-------+-------------------------------|    Slave      |
+|   Interface   |       |               Data Signal     |  Interface 1  |
+|               |-------|-------+-----------------------|               |
++---------------+       |       |                       +---------------+
+                        |       |
+                        |       |
+                        |       |
+                     +--+-------+--+
+                     |             |
+                     |   Slave     |
+                     | Interface 2 |
+                     |             |
+                     +-------------+
+
+Terminology
+=============
+
+The MIPI SoundWire specification uses the term 'device' to refer to a Master
+or Slave interface, which of course can be confusing. In this summary and
+code we use the term interface only to refer to the hardware. We follow the
+Linux device model by mapping each Slave interface connected on the bus as a
+device managed by a specific driver. The Linux SoundWire subsystem provides
+a framework to implement a SoundWire Slave driver with an API allowing
+3rd-party vendors to enable implementation-defined functionality while
+common setup/configuration tasks are handled by the bus.
+
+Bus:
+Implements SoundWire Linux Bus which handles the SoundWire protocol.
+It programs all the MIPI defined Slave registers. It represents a SoundWire
+Master. There can be multiple instances of Bus maybe present in a system.
+
+Slave:
+Registers as SoundWire Slave device (Linux Device). Multiple Slave devices
+can register to a Bus instance.
+
+Slave driver:
+Driver controlling the Slave device. MIPI-specified registers are controlled
+directly by the Bus (and transmitted through the Master driver/interface).
+Any implementation-defined Slave register is controlled by Slave driver. In
+practice, it is expected that the Slave driver relies on regmap and does not
+request direct register access.
+
+Programming interfaces (SoundWire Master interface Driver)
+==========================================================
+
+SoundWire Bus supports programming interfaces for the SoundWire Master
+implementation and SoundWire Slave devices. All the code uses the "sdw"
+prefix commonly used by SoC designers and 3rd party vendors.
+
+Each of the SoundWire Master interfaces needs to be registered to the Bus.
+Bus implements API to read standard Master MIPI properties and also provides
+callback in Master ops for Master driver to implement own functions that
+provides capabilities information. DT support is not implemented at this
+time but should be trivial to add since capabilities are enabled with the
+device_property_ API.
+
+The Master interface along with the Master interface capabilities are
+registered based on board file, DT or ACPI.
+
+Following is the Bus API to register the SoundWire Bus.
+
+int sdw_add_bus_master(struct sdw_bus *bus)
+{
+        if (!bus->dev)
+                return -ENODEV;
+
+        mutex_init(&bus->lock);
+        INIT_LIST_HEAD(&bus->slaves);
+
+	/* Check ACPI for Slave devices */
+        sdw_acpi_find_slaves(bus);
+
+	/* Check DT for Slave devices */
+	sdw_of_find_slaves(bus);
+
+        return 0;
+}
+
+This will initialize sdw_bus object for Master device. "sdw_master_ops" and
+"sdw_master_port_ops" callback functions are provided to the Bus.
+
+"sdw_master_ops" is used by Bus to control the Bus in the hardware specific
+way. It includes Bus control functions such as sending the SoundWire
+read/write messages on Bus, setting up clock frequency & Stream
+Synchronization Point (SSP). The "sdw_master_ops" structure abstracts the
+hardware details of the Master from the Bus.
+
+"sdw_master_port_ops" is used by Bus to setup the Port parameters of the
+Master interface Port. Master interface Port register map is not defined by
+MIPI specification, so Bus calls the "sdw_master_port_ops" callback
+function to do Port operations like "Port Prepare", "Port Transport params
+set", "Port enable and disable". The implementation of the Master driver can
+then perform hardware-specific configurations.
+
+Programming interfaces (SoundWire Slave Driver)
+===============================================
+
+The MIPI specification requires each Slave interface to expose a unique
+48-bit identifier, stored in 6 read only dev_id registers. This dev_id
+identifier contains vendor and part information, as well as a field enabling
+to differentiate between identical components. An additional class field is
+currently unused. Slave driver is written for the specific 48-bit
+identifier, Bus enumerates the Slave device based on the 48-bit identifier.
+Slave device and driver match is done based on this 48-bit identifier. Probe
+of the Slave driver is called by Bus on successful match between device and
+driver id. A parent/child relationship is enforced between Slave and Master
+devices (the logical representation is aligned with the physical
+connectivity).
+
+The information on Master/Slave dependencies is stored in platform data,
+board-file, ACPI or DT. The MIPI Software specification defines an
+additional link_id parameters for controllers that have multiple Master
+interfaces. The dev_id registers are only unique in the scope of a link, and
+the link_id unique in the scope of a controller. Both dev_id and link_id are
+not necessarily unique at the system level but the parent/child information
+is used to avoid ambiguity.
+
+static const struct sdw_device_id slave_id[] = {
+        SDW_SLAVE_ENTRY(0x025d, 0x700, 0),
+        {},
+};
+MODULE_DEVICE_TABLE(sdw, slave_id);
+
+static struct sdw_driver slave_sdw_driver = {
+        .driver = {
+                   .name = "slave_xxx",
+                   .pm = &slave_runtime_pm,
+                   },
+	.probe = slave_sdw_probe,
+	.remove = slave_sdw_remove,
+	.ops = &slave_slave_ops,
+	.id_table = slave_id,
+};
+
+
+For capabilities, Bus implements API to read standard Slave MIPI properties
+and also provides callback in Slave ops for Slave driver to implement own
+function that provides capabilities information. Bus needs to know a set of
+Slave capabilities to program Slave registers and to control the Bus
+reconfigurations.
+
+Future enhancements to be done:
+===============================
+1. Bulk Register Access (BRA) transfers.
+2. Multiple data lane support.
+
+Links:
+=====
+
+SoundWire MIPI specification 1.1 is available at:
+https://members.mipi.org/wg/All-Members/document/70290
+
+SoundWire MIPI DisCo (Discovery and Configuration) specification is
+available at:
+https://www.mipi.org/specifications/mipi-disco-soundwire
+
+(publicly accessible with registration or directly accessible to MIPI
+members)
-- 
2.7.4

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

* [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  3:03 ` Vinod Koul
  (?)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-19  7:40   ` Takashi Iwai
                     ` (4 more replies)
  -1 siblings, 5 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

This adds the base SoundWire bus type, bus and driver registration.
along with changes to module device table for new SoundWire
device type.

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/Kconfig                   |   2 +
 drivers/Makefile                  |   1 +
 drivers/soundwire/Kconfig         |  22 ++++
 drivers/soundwire/Makefile        |   7 ++
 drivers/soundwire/bus.h           |  62 +++++++++++
 drivers/soundwire/bus_type.c      | 229 ++++++++++++++++++++++++++++++++++++++
 include/linux/mod_devicetable.h   |   7 ++
 include/linux/soundwire/sdw.h     | 170 ++++++++++++++++++++++++++++
 scripts/mod/devicetable-offsets.c |   5 +
 scripts/mod/file2alias.c          |  16 +++
 10 files changed, 521 insertions(+)
 create mode 100644 drivers/soundwire/Kconfig
 create mode 100644 drivers/soundwire/Makefile
 create mode 100644 drivers/soundwire/bus.h
 create mode 100644 drivers/soundwire/bus_type.c
 create mode 100644 include/linux/soundwire/sdw.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 505c676fa9c7..61b6e245c052 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -152,6 +152,8 @@ source "drivers/remoteproc/Kconfig"
 
 source "drivers/rpmsg/Kconfig"
 
+source "drivers/soundwire/Kconfig"
+
 source "drivers/soc/Kconfig"
 
 source "drivers/devfreq/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index d90fdc413648..39c032f8abf3 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -154,6 +154,7 @@ obj-$(CONFIG_MAILBOX)		+= mailbox/
 obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/
 obj-$(CONFIG_REMOTEPROC)	+= remoteproc/
 obj-$(CONFIG_RPMSG)		+= rpmsg/
+obj-$(CONFIG_SOUNDWIRE)		+= soundwire/
 
 # Virtualization drivers
 obj-$(CONFIG_VIRT_DRIVERS)	+= virt/
diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig
new file mode 100644
index 000000000000..35792728c0aa
--- /dev/null
+++ b/drivers/soundwire/Kconfig
@@ -0,0 +1,22 @@
+#
+# SoundWire subsystem configuration
+#
+
+menuconfig SOUNDWIRE
+	bool "SoundWire support"
+	---help---
+	  SoundWire is a 2-Pin interface with data and clock line ratified
+	  by the MIPI Alliance. SoundWire is used for transporting data
+	  typically related to audio functions. SoundWire interface is
+	  optimized to integrate audio devices in mobile or mobile inspired
+	  systems
+
+if SOUNDWIRE
+
+comment "SoundWire Devices"
+
+config SOUNDWIRE_BUS
+	tristate
+	default SOUNDWIRE
+
+endif
diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
new file mode 100644
index 000000000000..d1281def7662
--- /dev/null
+++ b/drivers/soundwire/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for soundwire core
+#
+
+#Bus Objs
+soundwire-bus-objs := bus_type.o
+obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
new file mode 100644
index 000000000000..2683c6798b95
--- /dev/null
+++ b/drivers/soundwire/bus.h
@@ -0,0 +1,62 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __SDW_BUS_H
+#define __SDW_BUS_H
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/acpi.h>
+#include <linux/soundwire/sdw.h>
+
+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
+
+#endif /* __SDW_BUS_H */
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
new file mode 100644
index 000000000000..a14d1de80afa
--- /dev/null
+++ b/drivers/soundwire/bus_type.c
@@ -0,0 +1,229 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+/**
+ * sdw_get_device_id: find the matching SoundWire device id
+ *
+ * @slave: SoundWire Slave device
+ * @drv: SoundWire Slave Driver
+ *
+ * The match is done by comparing the mfg_id and part_id from the
+ * struct sdw_device_id. class_id is unused, as it is a placeholder
+ * in MIPI Spec.
+ */
+static const struct sdw_device_id *
+sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
+{
+	const struct sdw_device_id *id = drv->id_table;
+
+	while (id && id->mfg_id) {
+		if (slave->id.mfg_id == id->mfg_id &&
+				slave->id.part_id == id->part_id) {
+			return id;
+		}
+		id++;
+	}
+
+	return NULL;
+}
+
+static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
+
+	return !!sdw_get_device_id(slave, drv);
+}
+
+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
+{
+	/* modalias is sdw:m<mfg_id>p<part_id> */
+
+	return snprintf(buf, size, "sdw:m%04Xp%04X\n",
+			slave->id.mfg_id, slave->id.part_id);
+}
+
+static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	char modalias[32];
+
+	sdw_slave_modalias(slave, modalias, sizeof(modalias));
+
+	if (add_uevent_var(env, "MODALIAS=%s", modalias))
+		return -ENOMEM;
+
+	return 0;
+}
+
+struct bus_type sdw_bus_type = {
+	.name = "soundwire",
+	.match = sdw_bus_match,
+	.uevent = sdw_uevent,
+};
+EXPORT_SYMBOL(sdw_bus_type);
+
+static int sdw_drv_probe(struct device *dev)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
+	const struct sdw_device_id *id;
+	int ret;
+
+	id = sdw_get_device_id(slave, drv);
+	if (!id)
+		return -ENODEV;
+
+	/*
+	 * attach to power domain but don't turn on (last arg)
+	 */
+	ret = dev_pm_domain_attach(dev, false);
+	if (ret) {
+		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
+		return ret;
+	}
+
+	ret = drv->probe(slave, id);
+	if (ret) {
+		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int sdw_drv_remove(struct device *dev)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
+
+	if (drv->remove)
+		drv->remove(slave);
+
+	dev_pm_domain_detach(dev, false);
+
+	return 0;
+}
+
+static void sdw_drv_shutdown(struct device *dev)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
+
+	if (drv->shutdown)
+		drv->shutdown(slave);
+}
+
+/**
+ * __sdw_register_driver - register a SoundWire Slave driver
+ *
+ * @drv: driver to register
+ * @owner: owning module/driver
+ *
+ * Return: zero on success, else a negative error code.
+ */
+int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
+{
+	drv->driver.bus = &sdw_bus_type;
+
+	if (!drv->probe) {
+		pr_err("driver %s didn't provide SDW probe routine\n",
+							drv->name);
+		return -EINVAL;
+	}
+
+	drv->driver.owner = owner;
+	drv->driver.probe = sdw_drv_probe;
+
+	if (drv->remove)
+		drv->driver.remove = sdw_drv_remove;
+
+	if (drv->shutdown)
+		drv->driver.shutdown = sdw_drv_shutdown;
+
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(__sdw_register_driver);
+
+/*
+ * sdw_unregister_driver: unregisters the SoundWire Slave driver
+ *
+ * @drv: driver to unregister
+ */
+void sdw_unregister_driver(struct sdw_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(sdw_unregister_driver);
+
+static int __init sdw_bus_init(void)
+{
+	return bus_register(&sdw_bus_type);
+}
+
+static void __exit sdw_bus_exit(void)
+{
+	bus_unregister(&sdw_bus_type);
+}
+
+postcore_initcall(sdw_bus_init);
+module_exit(sdw_bus_exit);
+
+MODULE_DESCRIPTION("SoundWire bus");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 694cebb50f72..e2a9dcd52afc 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -228,6 +228,13 @@ struct hda_device_id {
 	unsigned long driver_data;
 };
 
+struct sdw_device_id {
+	__u16 mfg_id;
+	__u16 part_id;
+	__u8 class_id;
+	kernel_ulong_t driver_data;
+};
+
 /*
  * Struct used for matching a device
  */
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
new file mode 100644
index 000000000000..2b089463104d
--- /dev/null
+++ b/include/linux/soundwire/sdw.h
@@ -0,0 +1,170 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __SOUNDWIRE_H
+#define __SOUNDWIRE_H
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+struct sdw_bus;
+struct sdw_slave;
+
+#define SDW_MAX_DEVICES			11
+
+/**
+ * enum sdw_slave_status: Slave status
+ *
+ * @SDW_SLAVE_UNATTACHED: Slave is not attached with the bus.
+ * @SDW_SLAVE_ATTACHED: Slave is attached with bus.
+ * @SDW_SLAVE_ALERT: Some alert condition on the Slave
+ * @SDW_SLAVE_RESERVED: Reserved for future use
+ */
+enum sdw_slave_status {
+	SDW_SLAVE_UNATTACHED = 0,
+	SDW_SLAVE_ATTACHED = 1,
+	SDW_SLAVE_ALERT = 2,
+	SDW_SLAVE_RESERVED = 3,
+};
+
+/*
+ * SDW Slave Structures and APIs
+ */
+
+/**
+ * struct sdw_slave_id: Slave ID
+ *
+ * @mfg_id: MIPI Manufacturer ID
+ * @part_id: Device Part ID
+ * @class_id: MIPI Class ID ,unused now.
+ * Currently a placeholder in MIPI SoundWire Spec
+ * @unique_id: Device unique ID
+ * @sdw_version: SDW version implemented
+ *
+ * The order of the IDs here does not follow the DisCo spec definitions
+ */
+struct sdw_slave_id {
+	__u16 mfg_id;
+	__u16 part_id;
+	__u8 class_id;
+	__u8 unique_id:4;
+	__u8 sdw_version:4;
+};
+
+/**
+ * struct sdw_slave: SoundWire Slave
+ *
+ * @id: MIPI device ID
+ * @dev: Linux device
+ * @status: Status reported by the Slave
+ * @bus: Bus handle
+ * @node: node for bus list
+ * @dev_num: Device Number assigned by Bus
+ */
+struct sdw_slave {
+	struct sdw_slave_id id;
+	struct device dev;
+	enum sdw_slave_status status;
+	struct sdw_bus *bus;
+	struct list_head node;
+	u16 dev_num;
+};
+
+#define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
+
+extern struct bus_type sdw_bus_type;
+
+struct sdw_driver {
+	const char *name;
+
+	int (*probe)(struct sdw_slave *sdw,
+			const struct sdw_device_id *id);
+	int (*remove)(struct sdw_slave *sdw);
+	void (*shutdown)(struct sdw_slave *sdw);
+
+	const struct sdw_device_id *id_table;
+	const struct sdw_slave_ops *ops;
+
+	struct device_driver driver;
+};
+
+#define SDW_SLAVE_ENTRY(_mfg_id, _part_id, _drv_data) \
+	{ .mfg_id = (_mfg_id), .part_id = (_part_id), \
+	  .driver_data = (unsigned long)(_drv_data) }
+
+#define drv_to_sdw_driver(_drv) container_of(_drv, struct sdw_driver, driver)
+
+#define sdw_register_driver(drv) \
+	__sdw_register_driver(drv, THIS_MODULE)
+
+int __sdw_register_driver(struct sdw_driver *drv, struct module *);
+void sdw_unregister_driver(struct sdw_driver *drv);
+
+/*
+ * SDW master structures and APIs
+ */
+
+/**
+ * struct sdw_bus: SoundWire bus
+ *
+ * @dev: Master linux device
+ * @link_id: Link id number, can be 0 to N, unique for each Master
+ * @slaves: list of Slaves on this bus
+ * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
+ * @bus_lock: bus lock
+ */
+struct sdw_bus {
+	struct device *dev;
+	unsigned int link_id;
+	struct list_head slaves;
+	bool assigned[SDW_MAX_DEVICES + 1];
+	struct mutex bus_lock;
+};
+
+#endif /* __SOUNDWIRE_H */
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index e4d90e50f6fe..5c79292d81cf 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -202,6 +202,11 @@ int main(void)
 	DEVID_FIELD(hda_device_id, rev_id);
 	DEVID_FIELD(hda_device_id, api_version);
 
+	DEVID(sdw_device_id);
+	DEVID_FIELD(sdw_device_id, mfg_id);
+	DEVID_FIELD(sdw_device_id, part_id);
+	DEVID_FIELD(sdw_device_id, class_id);
+
 	DEVID(fsl_mc_device_id);
 	DEVID_FIELD(fsl_mc_device_id, vendor);
 	DEVID_FIELD(fsl_mc_device_id, obj_type);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 29d6699d5a06..3f1706d59fb9 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1289,6 +1289,22 @@ static int do_hda_entry(const char *filename, void *symval, char *alias)
 }
 ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry);
 
+/* Looks like: sdw:mNpN */
+static int do_sdw_entry(const char *filename, void *symval, char *alias)
+{
+	DEF_FIELD(symval, sdw_device_id, mfg_id);
+	DEF_FIELD(symval, sdw_device_id, part_id);
+	DEF_FIELD(symval, sdw_device_id, class_id);
+
+	strcpy(alias, "sdw:");
+	ADD(alias, "m", mfg_id != 0, mfg_id);
+	ADD(alias, "p", part_id != 0, part_id);
+
+	add_wildcard(alias);
+	return 1;
+}
+ADD_TO_DEVTABLE("sdw", sdw_device_id, do_sdw_entry);
+
 /* Looks like: fsl-mc:vNdN */
 static int do_fsl_mc_entry(const char *filename, void *symval,
 			   char *alias)
-- 
2.7.4

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

* [PATCH 03/14] soundwire: Add Master registration
  2017-10-19  3:03 ` Vinod Koul
@ 2017-10-19  3:03   ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

A Master registers with SoundWire bus and scans the firmware provided
for device description. In this patch we scan the ACPI namespaces and
create the SoundWire Slave devices based on the ACPI description

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Makefile    |   2 +-
 drivers/soundwire/bus.c       | 150 ++++++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h       |  20 +++++
 drivers/soundwire/slave.c     | 172 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/soundwire/sdw.h |   3 +
 5 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soundwire/bus.c
 create mode 100644 drivers/soundwire/slave.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index d1281def7662..c875e434f8b3 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -3,5 +3,5 @@
 #
 
 #Bus Objs
-soundwire-bus-objs := bus_type.o
+soundwire-bus-objs := bus_type.o bus.o slave.o
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
new file mode 100644
index 000000000000..57250f38a8d4
--- /dev/null
+++ b/drivers/soundwire/bus.c
@@ -0,0 +1,150 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pm_runtime.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+/**
+ * sdw_add_bus_master: add a bus Master instance
+ *
+ * @bus: bus instance
+ *
+ * Initializes the bus instance, read properties and create child
+ * devices.
+ */
+int sdw_add_bus_master(struct sdw_bus *bus)
+{
+	int ret;
+
+	if (!bus->dev) {
+		pr_err("SoundWire bus has no device");
+		return -ENODEV;
+	}
+
+	mutex_init(&bus->bus_lock);
+	INIT_LIST_HEAD(&bus->slaves);
+
+	/*
+	 * SDW is an enumerable bus, but devices can be powered off. So,
+	 * they won't be able to report as present.
+	 *
+	 * Create Slave devices based on Slaves described in
+	 * the respective firmware (ACPI/DT)
+	 */
+
+	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
+		ret = sdw_acpi_find_slaves(bus);
+	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
+		ret = sdw_of_find_slaves(bus);
+	else
+		ret = -ENOTSUPP; /* No ACPI/DT so error out */
+
+	if (ret) {
+		dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_add_bus_master);
+
+static int sdw_delete_slave(struct device *dev, void *data)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	struct sdw_bus *bus = slave->bus;
+
+	mutex_lock(&bus->bus_lock);
+	if (!list_empty(&bus->slaves))
+		list_del(&slave->node);
+	mutex_unlock(&bus->bus_lock);
+
+	device_unregister(dev);
+	return 0;
+}
+
+void sdw_delete_bus_master(struct sdw_bus *bus)
+{
+	device_for_each_child(bus->dev, NULL, sdw_delete_slave);
+}
+EXPORT_SYMBOL(sdw_delete_bus_master);
+
+void sdw_extract_slave_id(struct sdw_bus *bus,
+			unsigned long long addr, struct sdw_slave_id *id)
+{
+	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
+
+	/*
+	 * Spec definition
+	 *   Register		Bit	Contents
+	 *   DevId_0 [7:4]	47:44	sdw_version
+	 *   DevId_0 [3:0]	43:40	unique_id
+	 *   DevId_1		39:32	mfg_id [15:8]
+	 *   DevId_2		31:24	mfg_id [7:0]
+	 *   DevId_3		23:16	part_id [15:8]
+	 *   DevId_4		15:08	part_id [7:0]
+	 *   DevId_5		07:00	class_id
+	 */
+	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
+	id->unique_id = (addr >> 40) & GENMASK(3, 0);
+	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
+	id->part_id = (addr >> 8) & GENMASK(15, 0);
+	id->class_id = addr & GENMASK(7, 0);
+
+	dev_info(bus->dev,
+		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
+				id->class_id, id->part_id, id->mfg_id,
+				id->unique_id, id->sdw_version);
+
+}
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index 2683c6798b95..f61bc9f59445 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -57,6 +57,26 @@
 #include <linux/acpi.h>
 #include <linux/soundwire/sdw.h>
 
+#if IS_ENABLED(CONFIG_ACPI)
+int sdw_acpi_find_slaves(struct sdw_bus *bus);
+#else
+static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+#if IS_ENABLED(CONFIG_OF)
+int sdw_of_find_slaves(struct sdw_bus *bus);
+#else
+static inline int sdw_of_find_slaves(struct sdw_bus *bus)
+{
+	return -ENOTSUPP;
+}
+#endif
+
 int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
+void sdw_extract_slave_id(struct sdw_bus *bus,
+			unsigned long long addr, struct sdw_slave_id *id);
 
 #endif /* __SDW_BUS_H */
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
new file mode 100644
index 000000000000..ee8e0e848f64
--- /dev/null
+++ b/drivers/soundwire/slave.c
@@ -0,0 +1,172 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+static void sdw_slave_release(struct device *dev)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+
+	kfree(slave);
+}
+
+static int sdw_slave_add(struct sdw_bus *bus,
+		struct sdw_slave_id *id, struct fwnode_handle *fwnode)
+{
+	struct sdw_slave *slave;
+	char name[32];
+	int ret;
+
+	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
+	if (!slave)
+		return -ENOMEM;
+
+	/* Initialize data structure */
+	memcpy(&slave->id, id, sizeof(*id));
+
+	/* name shall be sdw:link:mfg:part:class:unique */
+	snprintf(name, sizeof(name), "sdw:%x:%x:%x:%x:%x",
+			bus->link_id, id->mfg_id, id->part_id,
+			id->class_id, id->unique_id);
+
+	slave->dev.parent = bus->dev;
+	slave->dev.fwnode = fwnode;
+	dev_set_name(&slave->dev, "%s", name);
+	slave->dev.release = sdw_slave_release;
+	slave->dev.bus = &sdw_bus_type;
+	slave->bus = bus;
+	slave->status = SDW_SLAVE_UNATTACHED;
+	slave->dev_num = 0;
+
+	mutex_lock(&bus->bus_lock);
+	list_add_tail(&slave->node, &bus->slaves);
+	mutex_unlock(&bus->bus_lock);
+
+	ret = device_register(&slave->dev);
+	if (ret) {
+		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
+
+		/*
+		 * On err, don't free but drop ref as this will be freed
+		 * when release method is invoked.
+		 */
+		put_device(&slave->dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_ACPI)
+/*
+ * sdw_acpi_find_slaves: Find Slave devices in Master ACPI node
+ *
+ * @bus: SDW bus instance
+ *
+ * Scans Master ACPI node for SDW child Slave devices and registers it.
+ */
+int sdw_acpi_find_slaves(struct sdw_bus *bus)
+{
+	struct acpi_device *adev, *parent;
+
+	parent = ACPI_COMPANION(bus->dev);
+	if (!parent) {
+		dev_err(bus->dev, "Can't find parent for acpi bind\n");
+		return -ENODEV;
+	}
+
+	list_for_each_entry(adev, &parent->children, node) {
+		unsigned long long addr;
+		struct sdw_slave_id id;
+		unsigned int link_id;
+		acpi_status status;
+
+		status = acpi_evaluate_integer(adev->handle,
+					METHOD_NAME__ADR, NULL, &addr);
+
+		if (ACPI_FAILURE(status)) {
+			dev_err(bus->dev, "_ADR resolution failed: %x\n",
+							status);
+			return status;
+		}
+
+		/* Extract link id from ADR, it is from 48 to 51 bits */
+		link_id = (addr >> 48) & GENMASK(3, 0);
+
+		/* Check for link_id match */
+		if (link_id != bus->link_id)
+			continue;
+
+		sdw_extract_slave_id(bus, addr, &id);
+
+		/*
+		 * don't error check for sdw_slave_add as we want to continue
+		 * adding Slaves
+		 */
+		sdw_slave_add(bus, &id, acpi_fwnode_handle(adev));
+	}
+
+	return 0;
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_OF)
+int sdw_of_find_slaves(struct sdw_bus *bus)
+{
+	/* placeholder now, fill on OF support */
+	return -ENOTSUPP;
+}
+#endif
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 2b089463104d..deb5ba6c63c2 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -167,4 +167,7 @@ struct sdw_bus {
 	struct mutex bus_lock;
 };
 
+int sdw_add_bus_master(struct sdw_bus *bus);
+void sdw_delete_bus_master(struct sdw_bus *bus);
+
 #endif /* __SOUNDWIRE_H */
-- 
2.7.4

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

* [PATCH 03/14] soundwire: Add Master registration
@ 2017-10-19  3:03   ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

A Master registers with SoundWire bus and scans the firmware provided
for device description. In this patch we scan the ACPI namespaces and
create the SoundWire Slave devices based on the ACPI description

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Makefile    |   2 +-
 drivers/soundwire/bus.c       | 150 ++++++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h       |  20 +++++
 drivers/soundwire/slave.c     | 172 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/soundwire/sdw.h |   3 +
 5 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soundwire/bus.c
 create mode 100644 drivers/soundwire/slave.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index d1281def7662..c875e434f8b3 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -3,5 +3,5 @@
 #
 
 #Bus Objs
-soundwire-bus-objs := bus_type.o
+soundwire-bus-objs := bus_type.o bus.o slave.o
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
new file mode 100644
index 000000000000..57250f38a8d4
--- /dev/null
+++ b/drivers/soundwire/bus.c
@@ -0,0 +1,150 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pm_runtime.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+/**
+ * sdw_add_bus_master: add a bus Master instance
+ *
+ * @bus: bus instance
+ *
+ * Initializes the bus instance, read properties and create child
+ * devices.
+ */
+int sdw_add_bus_master(struct sdw_bus *bus)
+{
+	int ret;
+
+	if (!bus->dev) {
+		pr_err("SoundWire bus has no device");
+		return -ENODEV;
+	}
+
+	mutex_init(&bus->bus_lock);
+	INIT_LIST_HEAD(&bus->slaves);
+
+	/*
+	 * SDW is an enumerable bus, but devices can be powered off. So,
+	 * they won't be able to report as present.
+	 *
+	 * Create Slave devices based on Slaves described in
+	 * the respective firmware (ACPI/DT)
+	 */
+
+	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
+		ret = sdw_acpi_find_slaves(bus);
+	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
+		ret = sdw_of_find_slaves(bus);
+	else
+		ret = -ENOTSUPP; /* No ACPI/DT so error out */
+
+	if (ret) {
+		dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_add_bus_master);
+
+static int sdw_delete_slave(struct device *dev, void *data)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	struct sdw_bus *bus = slave->bus;
+
+	mutex_lock(&bus->bus_lock);
+	if (!list_empty(&bus->slaves))
+		list_del(&slave->node);
+	mutex_unlock(&bus->bus_lock);
+
+	device_unregister(dev);
+	return 0;
+}
+
+void sdw_delete_bus_master(struct sdw_bus *bus)
+{
+	device_for_each_child(bus->dev, NULL, sdw_delete_slave);
+}
+EXPORT_SYMBOL(sdw_delete_bus_master);
+
+void sdw_extract_slave_id(struct sdw_bus *bus,
+			unsigned long long addr, struct sdw_slave_id *id)
+{
+	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
+
+	/*
+	 * Spec definition
+	 *   Register		Bit	Contents
+	 *   DevId_0 [7:4]	47:44	sdw_version
+	 *   DevId_0 [3:0]	43:40	unique_id
+	 *   DevId_1		39:32	mfg_id [15:8]
+	 *   DevId_2		31:24	mfg_id [7:0]
+	 *   DevId_3		23:16	part_id [15:8]
+	 *   DevId_4		15:08	part_id [7:0]
+	 *   DevId_5		07:00	class_id
+	 */
+	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
+	id->unique_id = (addr >> 40) & GENMASK(3, 0);
+	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
+	id->part_id = (addr >> 8) & GENMASK(15, 0);
+	id->class_id = addr & GENMASK(7, 0);
+
+	dev_info(bus->dev,
+		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
+				id->class_id, id->part_id, id->mfg_id,
+				id->unique_id, id->sdw_version);
+
+}
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index 2683c6798b95..f61bc9f59445 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -57,6 +57,26 @@
 #include <linux/acpi.h>
 #include <linux/soundwire/sdw.h>
 
+#if IS_ENABLED(CONFIG_ACPI)
+int sdw_acpi_find_slaves(struct sdw_bus *bus);
+#else
+static inline int sdw_acpi_find_slaves(struct sdw_bus *bus)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+#if IS_ENABLED(CONFIG_OF)
+int sdw_of_find_slaves(struct sdw_bus *bus);
+#else
+static inline int sdw_of_find_slaves(struct sdw_bus *bus)
+{
+	return -ENOTSUPP;
+}
+#endif
+
 int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
+void sdw_extract_slave_id(struct sdw_bus *bus,
+			unsigned long long addr, struct sdw_slave_id *id);
 
 #endif /* __SDW_BUS_H */
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
new file mode 100644
index 000000000000..ee8e0e848f64
--- /dev/null
+++ b/drivers/soundwire/slave.c
@@ -0,0 +1,172 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+static void sdw_slave_release(struct device *dev)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+
+	kfree(slave);
+}
+
+static int sdw_slave_add(struct sdw_bus *bus,
+		struct sdw_slave_id *id, struct fwnode_handle *fwnode)
+{
+	struct sdw_slave *slave;
+	char name[32];
+	int ret;
+
+	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
+	if (!slave)
+		return -ENOMEM;
+
+	/* Initialize data structure */
+	memcpy(&slave->id, id, sizeof(*id));
+
+	/* name shall be sdw:link:mfg:part:class:unique */
+	snprintf(name, sizeof(name), "sdw:%x:%x:%x:%x:%x",
+			bus->link_id, id->mfg_id, id->part_id,
+			id->class_id, id->unique_id);
+
+	slave->dev.parent = bus->dev;
+	slave->dev.fwnode = fwnode;
+	dev_set_name(&slave->dev, "%s", name);
+	slave->dev.release = sdw_slave_release;
+	slave->dev.bus = &sdw_bus_type;
+	slave->bus = bus;
+	slave->status = SDW_SLAVE_UNATTACHED;
+	slave->dev_num = 0;
+
+	mutex_lock(&bus->bus_lock);
+	list_add_tail(&slave->node, &bus->slaves);
+	mutex_unlock(&bus->bus_lock);
+
+	ret = device_register(&slave->dev);
+	if (ret) {
+		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
+
+		/*
+		 * On err, don't free but drop ref as this will be freed
+		 * when release method is invoked.
+		 */
+		put_device(&slave->dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_ACPI)
+/*
+ * sdw_acpi_find_slaves: Find Slave devices in Master ACPI node
+ *
+ * @bus: SDW bus instance
+ *
+ * Scans Master ACPI node for SDW child Slave devices and registers it.
+ */
+int sdw_acpi_find_slaves(struct sdw_bus *bus)
+{
+	struct acpi_device *adev, *parent;
+
+	parent = ACPI_COMPANION(bus->dev);
+	if (!parent) {
+		dev_err(bus->dev, "Can't find parent for acpi bind\n");
+		return -ENODEV;
+	}
+
+	list_for_each_entry(adev, &parent->children, node) {
+		unsigned long long addr;
+		struct sdw_slave_id id;
+		unsigned int link_id;
+		acpi_status status;
+
+		status = acpi_evaluate_integer(adev->handle,
+					METHOD_NAME__ADR, NULL, &addr);
+
+		if (ACPI_FAILURE(status)) {
+			dev_err(bus->dev, "_ADR resolution failed: %x\n",
+							status);
+			return status;
+		}
+
+		/* Extract link id from ADR, it is from 48 to 51 bits */
+		link_id = (addr >> 48) & GENMASK(3, 0);
+
+		/* Check for link_id match */
+		if (link_id != bus->link_id)
+			continue;
+
+		sdw_extract_slave_id(bus, addr, &id);
+
+		/*
+		 * don't error check for sdw_slave_add as we want to continue
+		 * adding Slaves
+		 */
+		sdw_slave_add(bus, &id, acpi_fwnode_handle(adev));
+	}
+
+	return 0;
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_OF)
+int sdw_of_find_slaves(struct sdw_bus *bus)
+{
+	/* placeholder now, fill on OF support */
+	return -ENOTSUPP;
+}
+#endif
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 2b089463104d..deb5ba6c63c2 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -167,4 +167,7 @@ struct sdw_bus {
 	struct mutex bus_lock;
 };
 
+int sdw_add_bus_master(struct sdw_bus *bus);
+void sdw_delete_bus_master(struct sdw_bus *bus);
+
 #endif /* __SOUNDWIRE_H */
-- 
2.7.4

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

* [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
  2017-10-19  3:03 ` Vinod Koul
                   ` (3 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-19  9:02   ` [alsa-devel] " Takashi Iwai
  2017-10-21  9:20     ` Mark Brown
  -1 siblings, 2 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

MIPI Discovery And Configuration (DisCo) Specification for SoundWire
specifies properties to be implemented for SoundWire Masters and
Slaves. The DisCo spec doesn't mandate these properties. However,
SDW bus cannot work without knowing these values.

The bus helper functions read the Master and Slave properties.
Implementers of Master or Slave drivers can use any of the below
three mechanisms:
   a) Use these APIs here as .read_prop() callback for Master
   and Slave
   b) Implement own methods and set those as .read_prop(), but invoke
   APIs in this file for generic read and override the values with
   platform specific data
   c) Implement ones own methods which do not use anything provided
   here

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Makefile     |   2 +-
 drivers/soundwire/bus.c        |   8 +
 drivers/soundwire/bus_type.c   |  16 ++
 drivers/soundwire/mipi_disco.c | 421 +++++++++++++++++++++++++++++++++++++++++
 include/linux/soundwire/sdw.h  | 286 ++++++++++++++++++++++++++++
 5 files changed, 732 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soundwire/mipi_disco.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index c875e434f8b3..bcde0d26524c 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -3,5 +3,5 @@
 #
 
 #Bus Objs
-soundwire-bus-objs := bus_type.o bus.o slave.o
+soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 57250f38a8d4..5b13d96b67b8 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -76,6 +76,14 @@ int sdw_add_bus_master(struct sdw_bus *bus)
 	mutex_init(&bus->bus_lock);
 	INIT_LIST_HEAD(&bus->slaves);
 
+	if (bus->ops->read_prop) {
+		ret = bus->ops->read_prop(bus);
+		if (ret < 0) {
+			dev_err(bus->dev, "Bus read properties failed:%d", ret);
+			return ret;
+		}
+	}
+
 	/*
 	 * SDW is an enumerable bus, but devices can be powered off. So,
 	 * they won't be able to report as present.
diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
index a14d1de80afa..baad4ad3be44 100644
--- a/drivers/soundwire/bus_type.c
+++ b/drivers/soundwire/bus_type.c
@@ -139,12 +139,28 @@ static int sdw_drv_probe(struct device *dev)
 		return ret;
 	}
 
+	slave->ops = drv->ops;
+
 	ret = drv->probe(slave, id);
 	if (ret) {
 		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
 		return ret;
 	}
 
+	/* device is probed so let's read the properties now */
+	if (slave->ops && slave->ops->read_prop)
+		slave->ops->read_prop(slave);
+
+	/*
+	 * Check for valid clk_stop_timeout, use DisCo worst case value of
+	 * 300ms
+	 */
+	if (slave->prop.clk_stop_timeout == 0)
+		slave->prop.clk_stop_timeout = 300;
+
+	slave->bus->clk_stop_timeout = max_t(u32, slave->bus->clk_stop_timeout,
+					slave->prop.clk_stop_timeout);
+
 	return 0;
 }
 
diff --git a/drivers/soundwire/mipi_disco.c b/drivers/soundwire/mipi_disco.c
new file mode 100644
index 000000000000..2eef2fe6f855
--- /dev/null
+++ b/drivers/soundwire/mipi_disco.c
@@ -0,0 +1,421 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * MIPI Discovery And Configuration (DisCo) Specification for SoundWire
+ * specifies properties to be implemented for SoundWire Masters and Slaves.
+ * The DisCo spec doesn't mandate these properties. However, SDW bus cannot
+ * work without knowing these values.
+ *
+ * The helper functions read the Master and Slave properties. Implementers
+ * of Master or Slave drivers can use any of the below three mechanisms:
+ *    a) Use these APIs here as .read_prop() callback for Master and Slave
+ *    b) Implement own methods and set those as .read_prop(), but invoke
+ *    APIs in this file for generic read and override the values with
+ *    platform specific data
+ *    c) Implement ones own methods which do not use anything provided
+ *    here
+ */
+
+#include <linux/property.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+/**
+ * sdw_master_read_prop: Read Master properties
+ *
+ * @bus: SDW bus instance
+ */
+int sdw_master_read_prop(struct sdw_bus *bus)
+{
+	struct sdw_master_prop *prop = &bus->prop;
+	struct fwnode_handle *link;
+	unsigned int count = 0;
+	char name[32];
+	int nval, i;
+
+	device_property_read_u32(bus->dev,
+			"mipi-sdw-sw-interface-revision", &prop->revision);
+	device_property_read_u32(bus->dev, "mipi-sdw-master-count", &count);
+
+	/* Find link handle */
+	snprintf(name, sizeof(name),
+			"mipi-sdw-link-%d-subproperties", bus->link_id);
+
+	link = device_get_named_child_node(bus->dev, name);
+	if (!link) {
+		dev_err(bus->dev, "Link node %s not found\n", name);
+		return -EIO;
+	}
+
+	if (fwnode_property_read_bool(link,
+			"mipi-sdw-clock-stop-mode0-supported") == true)
+		prop->clk_stop_mode = SDW_CLK_STOP_MODE0;
+
+	if (fwnode_property_read_bool(link,
+			"mipi-sdw-clock-stop-mode1-supported") == true)
+		prop->clk_stop_mode |= SDW_CLK_STOP_MODE1;
+
+	fwnode_property_read_u32(link,
+			"mipi-sdw-max-clock-frequency", &prop->max_freq);
+
+	nval = fwnode_property_read_u32_array(link,
+			"mipi-sdw-clock-frequencies-supported", NULL, 0);
+	if (nval > 0)
+		prop->num_freq = nval;
+
+	if (prop->num_freq) {
+		prop->freq = devm_kcalloc(bus->dev, nval,
+					sizeof(*prop->freq), GFP_KERNEL);
+		if (!prop->freq)
+			return -ENOMEM;
+
+		fwnode_property_read_u32_array(link,
+				"mipi-sdw-clock-frequencies-supported",
+				prop->freq, nval);
+
+		/*
+		 * Check the frequencies supported. If FW doesn't provide max
+		 * freq, then populate here by checking values.
+		 */
+		if (!prop->max_freq) {
+			prop->max_freq = prop->freq[0];
+			for (i = 1; i < prop->num_freq; i++) {
+				if (prop->freq[i] > prop->max_freq)
+					prop->max_freq = prop->freq[i];
+			}
+		}
+	}
+
+	nval = fwnode_property_read_u32_array(link,
+			"mipi-sdw-supported-clock-gears", NULL, 0);
+	if (nval > 0)
+		prop->num_clk_gears = nval;
+
+	if (prop->num_clk_gears) {
+		prop->clk_gears = devm_kcalloc(bus->dev, nval,
+				sizeof(*prop->clk_gears), GFP_KERNEL);
+		if (!prop->clk_gears)
+			return -ENOMEM;
+
+		fwnode_property_read_u32_array(link,
+				"mipi-sdw-supported-clock-gears",
+				prop->clk_gears, nval);
+	}
+
+	fwnode_property_read_u32(link, "mipi-sdw-default-frame-rate",
+				&prop->default_frame_rate);
+	fwnode_property_read_u32(link, "mipi-sdw-default-frame-row-size",
+				&prop->default_row);
+	fwnode_property_read_u32(link, "mipi-sdw-default-frame-col-size",
+				&prop->default_col);
+	prop->dynamic_frame =  fwnode_property_read_bool(link,
+				"mipi-sdw-dynamic-frame-shape");
+	fwnode_property_read_u32(link, "mipi-sdw-command-error-threshold",
+				&prop->err_threshold);
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_master_read_prop);
+
+int sdw_slave_read_dpn(struct sdw_slave *slave,
+		struct sdw_dpn_prop *dpn, int count, int ports, char *type)
+{
+	struct fwnode_handle *node;
+	u32 bit, i = 0, nval;
+	unsigned long addr;
+	char name[40];
+
+	addr = ports;
+	/* valid ports are 1 to 14 so apply mask */
+	addr &= GENMASK(14, 1);
+
+	for_each_set_bit(bit, &addr, 32) {
+		snprintf(name, sizeof(name),
+			"mipi-sdw-dp-%d-%s-subproperties", bit, type);
+
+		dpn[i].num = bit;
+
+		node = device_get_named_child_node(&slave->dev, name);
+		if (!node) {
+			dev_err(&slave->dev, "%s dpN not found\n", name);
+			return -EIO;
+		}
+
+		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
+						&dpn[i].max_word);
+		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
+						&dpn[i].min_word);
+
+		nval = fwnode_property_read_u32_array(node,
+				"mipi-sdw-port-wordlength-configs", NULL, 0);
+		if (nval > 0)
+			dpn[i].num_words = nval;
+
+		if (dpn[i].num_words) {
+			dpn[i].words = devm_kcalloc(&slave->dev, nval,
+				sizeof(*dpn[i].words), GFP_KERNEL);
+			if (!dpn[i].words)
+				return -ENOMEM;
+
+			fwnode_property_read_u32_array(node,
+					"mipi-sdw-port-wordlength-configs",
+					&dpn[i].num_words, nval);
+		}
+
+		fwnode_property_read_u32(node, "mipi-sdw-data-port-type",
+				&dpn[i].type);
+		fwnode_property_read_u32(node,
+				"mipi-sdw-max-grouping-supported",
+				&dpn[i].max_grouping);
+		dpn[i].simple_ch_prep_sm = fwnode_property_read_bool(node,
+				"mipi-sdw-simplified-channelprepare-sm");
+		fwnode_property_read_u32(node,
+				"mipi-sdw-port-channelprepare-timeout",
+				&dpn[i].ch_prep_timeout);
+		fwnode_property_read_u32(node,
+				"mipi-sdw-imp-def-dpn-interrupts-supported",
+				&dpn[i].device_interrupts);
+		fwnode_property_read_u32(node, "mipi-sdw-min-channel-number",
+				&dpn[i].min_ch);
+		fwnode_property_read_u32(node, "mipi-sdw-max-channel-number",
+				&dpn[i].max_ch);
+
+		nval = fwnode_property_read_u32_array(node,
+				"mipi-sdw-channel-number-list", NULL, 0);
+		if (nval > 0)
+			dpn[i].num_ch = nval;
+
+		if (dpn[i].num_ch) {
+			dpn[i].ch = devm_kcalloc(&slave->dev, nval,
+					sizeof(*dpn[i].ch), GFP_KERNEL);
+			if (!dpn[i].ch)
+				return -ENOMEM;
+
+			fwnode_property_read_u32_array(node,
+					"mipi-sdw-channel-number-list",
+					dpn[i].ch, nval);
+		}
+
+		nval = fwnode_property_read_u32_array(node,
+				"mipi-sdw-channel-combination-list", NULL, 0);
+		if (nval > 0)
+			dpn[i].num_ch_combinations = nval;
+
+		if (dpn[i].num_ch_combinations) {
+			dpn[i].ch_combinations = devm_kcalloc(&slave->dev,
+					nval, sizeof(*dpn[i].ch_combinations),
+					GFP_KERNEL);
+			if (!dpn[i].ch_combinations)
+				return -ENOMEM;
+
+			fwnode_property_read_u32_array(node,
+					"mipi-sdw-channel-combination-list",
+					dpn[i].ch_combinations, nval);
+		}
+
+		fwnode_property_read_u32(node,
+				"mipi-sdw-modes-supported", &dpn[i].modes);
+		fwnode_property_read_u32(node, "mipi-sdw-max-async-buffer",
+				&dpn[i].max_async_buffer);
+		dpn[i].block_pack_mode = fwnode_property_read_bool(node,
+				"mipi-sdw-block-packing-mode");
+
+		fwnode_property_read_u32(node, "mipi-sdw-port-encoding-type",
+				&dpn[i].port_encoding);
+
+		/* TODO: Read audio mode */
+
+		i++;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_slave_read_dpn);
+
+/**
+ * sdw_slave_read_prop: Read Slave properties
+ *
+ * @slave: SDW Slave
+ */
+int sdw_slave_read_prop(struct sdw_slave *slave)
+{
+	struct sdw_slave_prop *prop = &slave->prop;
+	struct device *dev = &slave->dev;
+	struct fwnode_handle *port;
+	int num_of_ports, nval, i;
+
+	device_property_read_u32(dev, "mipi-sdw-sw-interface-revision",
+				&prop->mipi_revision);
+
+	prop->wake_capable = device_property_read_bool(dev,
+				"mipi-sdw-wake-up-unavailable");
+	prop->wake_capable = !prop->wake_capable;
+
+	prop->test_mode_capable = device_property_read_bool(dev,
+				"mipi-sdw-test-mode-supported");
+
+	prop->clk_stop_mode1 = false;
+	if (device_property_read_bool(dev,
+				"mipi-sdw-clock-stop-mode1-supported"))
+		prop->clk_stop_mode1 = true;
+
+	prop->simple_clk_stop_capable = device_property_read_bool(dev,
+			"mipi-sdw-simplified-clockstopprepare-sm-supported");
+
+	device_property_read_u32(dev, "mipi-sdw-clockstopprepare-timeout",
+			&prop->clk_stop_timeout);
+	device_property_read_u32(dev, "mipi-sdw-slave-channelprepare-timeout",
+			&prop->ch_prep_timeout);
+	device_property_read_u32(dev,
+			"mipi-sdw-clockstopprepare-hard-reset-behavior",
+			&prop->reset_behave);
+
+	prop->high_PHY_capable = device_property_read_bool(dev,
+			"mipi-sdw-highPHY-capable");
+	prop->paging_support = device_property_read_bool(dev,
+			"mipi-sdw-paging-support");
+	prop->bank_delay_support = device_property_read_bool(dev,
+			"mipi-sdw-bank-delay-support");
+	device_property_read_u32(dev,
+			"mipi-sdw-port15-read-behavior", &prop->p15_behave);
+	device_property_read_u32(dev, "mipi-sdw-master-count",
+				&prop->master_count);
+
+	device_property_read_u32(dev, "mipi-sdw-source-port-list",
+				&prop->source_ports);
+	device_property_read_u32(dev, "mipi-sdw-sink-port-list",
+				&prop->sink_ports);
+
+	/* Read dp0 properties */
+	port = device_get_named_child_node(dev, "mipi-sdw-dp-0-subproperties");
+	if (!port) {
+		dev_err(dev, "DP0 node not found!!\n");
+		return -EIO;
+	}
+
+	prop->dp0_prop = devm_kzalloc(&slave->dev,
+			sizeof(*prop->dp0_prop), GFP_KERNEL);
+	if (!prop->dp0_prop)
+		return -ENOMEM;
+
+	fwnode_property_read_u32(port, "mipi-sdw-port-max-wordlength",
+			&prop->dp0_prop->max_word);
+	fwnode_property_read_u32(port, "mipi-sdw-port-min-wordlength",
+			&prop->dp0_prop->min_word);
+	nval = fwnode_property_read_u32_array(port,
+			"mipi-sdw-port-wordlength-configs", NULL, 0);
+	if (nval > 0)
+		prop->dp0_prop->num_words = nval;
+
+	if (prop->dp0_prop->num_words) {
+		prop->dp0_prop->words = devm_kcalloc(&slave->dev, nval,
+				sizeof(*prop->dp0_prop->words), GFP_KERNEL);
+		if (!prop->dp0_prop->words)
+			return -ENOMEM;
+
+		fwnode_property_read_u32_array(port,
+				"mipi-sdw-port-wordlength-configs",
+				prop->dp0_prop->words, nval);
+	}
+
+	prop->dp0_prop->flow_controlled = fwnode_property_read_bool(port,
+			"mipi-sdw-bra-flow-controlled");
+
+	prop->dp0_prop->simple_ch_prep_sm = fwnode_property_read_bool(port,
+			"mipi-sdw-simplified-channel-prepare-sm");
+
+	prop->dp0_prop->device_interrupts = fwnode_property_read_bool(port,
+			"mipi-sdw-imp-def-dp0-interrupts-supported");
+
+	/*
+	 * Based on each DPn port, get source and sink dpn properties.
+	 * Also, some ports can operate as both source or sink.
+	 */
+
+	/* Allocate memory for set bits in port lists */
+	nval = hweight32(prop->source_ports);
+	num_of_ports += nval;
+	prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
+				sizeof(*prop->src_dpn_prop), GFP_KERNEL);
+	if (!prop->src_dpn_prop)
+		return -ENOMEM;
+
+	/* Read dpn properties for source port(s) */
+	sdw_slave_read_dpn(slave, prop->src_dpn_prop, nval,
+			prop->source_ports, "source");
+
+	nval = hweight32(prop->sink_ports);
+	num_of_ports += nval;
+	prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
+				sizeof(*prop->sink_dpn_prop), GFP_KERNEL);
+	if (!prop->sink_dpn_prop)
+		return -ENOMEM;
+
+	/* Read dpn properties for sink port(s) */
+	sdw_slave_read_dpn(slave, prop->sink_dpn_prop, nval,
+			prop->sink_ports, "sink");
+
+	/* some ports are bidirectional so check total ports by ORing */
+	nval = prop->source_ports | prop->sink_ports;
+	num_of_ports = hweight32(nval) + 1; /* add 1 for DP0 */
+
+	/* Allocate port_ready based on num_of_ports */
+	slave->port_ready = devm_kcalloc(&slave->dev, num_of_ports,
+				sizeof(*slave->port_ready), GFP_KERNEL);
+	if (!slave->port_ready)
+		return -ENOMEM;
+
+	/* Initialize completion */
+	for (i = 0; i < num_of_ports; i++)
+		init_completion(&slave->port_ready[i]);
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_slave_read_prop);
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index deb5ba6c63c2..9c52b0bc561a 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -74,6 +74,262 @@ enum sdw_slave_status {
 };
 
 /*
+ * SDW properties, defined in MIPI DisCo spec v1.0
+ */
+enum sdw_clk_stop_reset_behave {
+	SDW_CLK_STOP_KEEP_STATUS = 1,
+};
+
+/**
+ * enum sdw_p15_behave: Slave Port 15 behaviour when the Master attempts a
+ * read
+ *
+ * @SDW_P15_READ_IGNORED: Read is ignored
+ * @SDW_P15_CMD_OK: Command is ok
+ */
+enum sdw_p15_behave {
+	SDW_P15_READ_IGNORED = 0,
+	SDW_P15_CMD_OK = 1,
+};
+
+/**
+ * enum sdw_dpn_type: Data port types
+ *
+ * @SDW_DPN_FULL: Full Data Port is supported
+ * @SDW_DPN_SIMPLE: Simplified Data Port as defined in spec.
+ * DPN_SampleCtrl2, DPN_OffsetCtrl2, DPN_HCtrl and DPN_BlockCtrl3
+ * are not implemented.
+ * @SDW_DPN_REDUCED: Reduced Data Port as defined in spec.
+ * DPN_SampleCtrl2, DPN_HCtrl are not implemented.
+ */
+enum sdw_dpn_type {
+	SDW_DPN_FULL = 0,
+	SDW_DPN_SIMPLE = 1,
+	SDW_DPN_REDUCED = 2,
+};
+
+/**
+ * enum sdw_clk_stop_mode: Clock Stop modes
+ *
+ * @SDW_CLK_STOP_MODE_0: Slave can continue operation seamlessly on clock
+ * restart
+ * @SDW_CLK_STOP_MODE_1: Slave may have entered a deeper power-saving mode,
+ * not capable of continuing operation seamlessly when the clock restarts
+ */
+enum sdw_clk_stop_mode {
+	SDW_CLK_STOP_MODE0 = 1,
+	SDW_CLK_STOP_MODE1 = 2,
+};
+
+/**
+ * struct sdw_dp0_prop: DP0 properties
+ *
+ * @max_word: Maximum number of bits in a Payload Channel Sample, 1 to 64
+ * (inclusive)
+ * @min_word: Minimum number of bits in a Payload Channel Sample, 1 to 64
+ * (inclusive)
+ * @num_words: number of wordlengths supported
+ * @words: wordlengths supported
+ * @flow_controlled: Slave implementation results in an OK_NotReady
+ * response
+ * @simple_ch_prep_sm: If channel prepare sequence is required
+ * @device_interrupts: If implementation-defined interrupts are supported
+ *
+ * The wordlengths are specified by Spec as max, min AND number of
+ * discrete values, implementation can define based on the wordlengths they
+ * support
+ */
+struct sdw_dp0_prop {
+	u32 max_word;
+	u32 min_word;
+	u32 num_words;
+	u32 *words;
+	bool flow_controlled;
+	bool simple_ch_prep_sm;
+	bool device_interrupts;
+};
+
+/**
+ * struct sdw_dpn_audio_mode: Audio mode properties for DPn
+ *
+ * @bus_min_freq: Minimum bus frequency, in Hz
+ * @bus_max_freq: Maximum bus frequency, in Hz
+ * @bus_num_freq: Number of discrete frequencies supported
+ * @bus_freq: Discrete bus frequencies, in Hz
+ * @bus_min_freq: Minimum sampling frequency, in Hz
+ * @bus_max_freq: Maximum sampling bus frequency, in Hz
+ * @bus_num_freq: Number of discrete sampling frequency supported
+ * @bus_freq: Discrete sampling frequencies, in Hz
+ * @prep_ch_behave: Specifies the dependencies between Channel Prepare
+ * sequence and bus clock configuration
+ * If 0, Channel Prepare can happen at any Bus clock rate
+ * If 1, Channel Prepare sequence shall happen only after Bus clock is
+ * changed to a frequency supported by this mode or compatible modes
+ * described by the next field
+ * @glitchless: Bitmap describing possible glitchless transitions from this
+ * Audio Mode to other Audio Modes
+ */
+struct sdw_dpn_audio_mode {
+	u32 bus_min_freq;
+	u32 bus_max_freq;
+	u32 bus_num_freq;
+	u32 *bus_freq;
+	u32 max_freq;
+	u32 min_freq;
+	u32 num_freq;
+	u32 *freq;
+	u32 prep_ch_behave;
+	u32 glitchless;
+};
+
+/**
+ * struct sdw_dpn_prop: Data Port DPn properties
+ *
+ * @num: port number
+ * @max_word: Maximum number of bits in a Payload Channel Sample, 1 to 64
+ * (inclusive)
+ * @min_word: Minimum number of bits in a Payload Channel Sample, 1 to 64
+ * (inclusive)
+ * @num_words: Number of discrete supported wordlengths
+ * @words: Discrete supported wordlength
+ * @type: Data port type. Full, Simplified or Reduced
+ * @max_grouping: Maximum number of samples that can be grouped together for
+ * a full data port
+ * @simple_ch_prep_sm: If the port supports simplified channel prepare state
+ * machine
+ * @ch_prep_timeout: Port-specific timeout value, in milliseconds
+ * @device_interrupts: If set, each bit corresponds to support for
+ * implementation-defined interrupts
+ * @max_ch: Maximum channels supported
+ * @min_ch: Minimum channels supported
+ * @num_ch: Number of discrete channels supported
+ * @ch: Discrete channels supported
+ * @num_ch_combinations: Number of channel combinations supported
+ * @ch_combinations: Channel combinations supported
+ * @modes: SDW mode supported
+ * @max_async_buffer: Number of samples that this port can buffer in
+ * asynchronous modes
+ * @block_pack_mode: Type of block port mode supported
+ * @port_encoding: Payload Channel Sample encoding schemes supported
+ * @audio_modes: Audio modes supported
+ */
+struct sdw_dpn_prop {
+	u32 num;
+	u32 max_word;
+	u32 min_word;
+	u32 num_words;
+	u32 *words;
+	enum sdw_dpn_type type;
+	u32 max_grouping;
+	bool simple_ch_prep_sm;
+	u32 ch_prep_timeout;
+	u32 device_interrupts;
+	u32 max_ch;
+	u32 min_ch;
+	u32 num_ch;
+	u32 *ch;
+	u32 num_ch_combinations;
+	u32 *ch_combinations;
+	u32 modes;
+	u32 max_async_buffer;
+	bool block_pack_mode;
+	u32 port_encoding;
+	struct sdw_dpn_audio_mode *audio_modes;
+};
+
+/**
+ * struct sdw_slave_prop: SoundWire Slave properties
+ *
+ * @mipi_revision: Spec version of the implementation
+ * @wake_capable: Wake-up events are supported
+ * @test_mode_capable: If test mode is supported
+ * @clk_stop_mode1: Clock-Stop Mode 1 is supported
+ * @simple_clk_stop_capable: Simple clock mode is supported
+ * @clk_stop_timeout: Worst-case latency of the Clock Stop Prepare State
+ * Machine transitions, in milliseconds
+ * @ch_prep_timeout: Worst-case latency of the Channel Prepare State Machine
+ * transitions, in milliseconds
+ * @reset_behave: Slave keeps the status of the SlaveStopClockPrepare
+ * state machine (P=1 SCSP_SM) after exit from clock-stop mode1
+ * @high_PHY_capable: Slave is HighPHY capable
+ * @paging_support: Slave implements paging registers SCP_AddrPage1 and
+ * SCP_AddrPage2
+ * @bank_delay_support: Slave implements bank delay/bridge support registers
+ * SCP_BankDelay and SCP_NextFrame
+ * @p15_behave: Slave behavior when the Master attempts a read to the Port15
+ * alias
+ * @lane_control_support:
+ * @master_count: Number of Masters present on this Slave
+ * @source_ports: Bitmap identifying source ports
+ * @sink_ports: Bitmap identifying sink ports
+ * @dp0_prop: Data Port 0 properties
+ * @src_dpn_prop: Source Data Port N properties
+ * @sink_dpn_prop: Sink Data Port N properties
+ */
+struct sdw_slave_prop {
+	u32 mipi_revision;
+	bool wake_capable;
+	bool test_mode_capable;
+	bool clk_stop_mode1;
+	bool simple_clk_stop_capable;
+	u32 clk_stop_timeout;
+	u32 ch_prep_timeout;
+	enum sdw_clk_stop_reset_behave reset_behave;
+	bool high_PHY_capable;
+	bool paging_support;
+	bool bank_delay_support;
+	enum sdw_p15_behave p15_behave;
+	bool lane_control_support;
+	u32 master_count;
+	u32 source_ports;
+	u32 sink_ports;
+	struct sdw_dp0_prop *dp0_prop;
+	struct sdw_dpn_prop *src_dpn_prop;
+	struct sdw_dpn_prop *sink_dpn_prop;
+};
+
+/**
+ * struct sdw_master_prop: Master properties
+ *
+ * @revision: MIPI spec version of the implementation
+ * @master_count:
+ * @clk_stop_mode: Clock Stop mode supported
+ * @max_freq: Maximum Bus clock frequency, in Hz
+ * @num_clk_gears: Number of clock gears supported
+ * @clk_gears: Clock gears supported
+ * @num_freq: Number of clock frequencies supported, in Hz
+ * @freq: Clock frequencies supported, in Hz
+ * @default_frame_rate: Controller default Frame rate, in Hz
+ * @default_row: Number of rows
+ * @default_col: Number of columns
+ * @dynamic_frame: Dynamic frame supported
+ * @err_threshold: Number of times that software may retry sending a single
+ * command
+ * @dpn_prop: Data Port N properties
+ */
+struct sdw_master_prop {
+	u32 revision;
+	u32 master_count;
+	enum sdw_clk_stop_mode clk_stop_mode;
+	u32 max_freq;
+	u32 num_clk_gears;
+	u32 *clk_gears;
+	u32 num_freq;
+	u32 *freq;
+	u32 default_frame_rate;
+	u32 default_row;
+	u32 default_col;
+	bool dynamic_frame;
+	u32 err_threshold;
+	struct sdw_dpn_prop *dpn_prop;
+};
+
+int sdw_master_read_prop(struct sdw_bus *bus);
+int sdw_slave_read_prop(struct sdw_slave *slave);
+int sdw_slave_read_dpn(struct sdw_slave *slave,
+		struct sdw_dpn_prop *dpn, int count, int ports, char *type);
+
+/*
  * SDW Slave Structures and APIs
  */
 
@@ -98,13 +354,25 @@ struct sdw_slave_id {
 };
 
 /**
+ * struct sdw_slave_ops: Slave driver callback ops
+ *
+ * @read_prop: Read Slave properties
+ */
+struct sdw_slave_ops {
+	int (*read_prop)(struct sdw_slave *sdw);
+};
+
+/**
  * struct sdw_slave: SoundWire Slave
  *
  * @id: MIPI device ID
  * @dev: Linux device
  * @status: Status reported by the Slave
  * @bus: Bus handle
+ * @ops: Slave callback ops
+ * @prop: Slave properties
  * @node: node for bus list
+ * @port_ready: Port ready completion flag for each Slave port
  * @dev_num: Device Number assigned by Bus
  */
 struct sdw_slave {
@@ -112,7 +380,10 @@ struct sdw_slave {
 	struct device dev;
 	enum sdw_slave_status status;
 	struct sdw_bus *bus;
+	const struct sdw_slave_ops *ops;
+	struct sdw_slave_prop prop;
 	struct list_head node;
+	struct completion *port_ready;
 	u16 dev_num;
 };
 
@@ -151,6 +422,15 @@ void sdw_unregister_driver(struct sdw_driver *drv);
  */
 
 /**
+ * struct sdw_master_ops: Master driver ops
+ *
+ * @read_prop: Read Master properties
+ */
+struct sdw_master_ops {
+	int (*read_prop)(struct sdw_bus *bus);
+};
+
+/**
  * struct sdw_bus: SoundWire bus
  *
  * @dev: Master linux device
@@ -158,6 +438,9 @@ void sdw_unregister_driver(struct sdw_driver *drv);
  * @slaves: list of Slaves on this bus
  * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
  * @bus_lock: bus lock
+ * @ops: Master callback ops
+ * @prop: Master properties
+ * @clk_stop_timeout: Clock stop timeout computed
  */
 struct sdw_bus {
 	struct device *dev;
@@ -165,6 +448,9 @@ struct sdw_bus {
 	struct list_head slaves;
 	bool assigned[SDW_MAX_DEVICES + 1];
 	struct mutex bus_lock;
+	const struct sdw_master_ops *ops;
+	struct sdw_master_prop prop;
+	unsigned int clk_stop_timeout;
 };
 
 int sdw_add_bus_master(struct sdw_bus *bus);
-- 
2.7.4

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

* [PATCH 05/14] soundwire: Add SoundWire MIPI defined registers
  2017-10-19  3:03 ` Vinod Koul
                   ` (4 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

From: Sanyog Kale <sanyog.r.kale@intel.com>

MIPI SoundWire spec defines standard SoundWire registers mandatory for
SoundWire Slave devices, so add them.

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 include/linux/soundwire/sdw.h           |   1 +
 include/linux/soundwire/sdw_registers.h | 238 ++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+)
 create mode 100644 include/linux/soundwire/sdw_registers.h

diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 9c52b0bc561a..a5bb5e9bc50a 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -52,6 +52,7 @@
 
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
+#include <linux/soundwire/sdw_registers.h>
 
 struct sdw_bus;
 struct sdw_slave;
diff --git a/include/linux/soundwire/sdw_registers.h b/include/linux/soundwire/sdw_registers.h
new file mode 100644
index 000000000000..9324d56f6fc8
--- /dev/null
+++ b/include/linux/soundwire/sdw_registers.h
@@ -0,0 +1,238 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __SDW_REGISTERS_H
+#define __SDW_REGISTERS_H
+
+/*
+ * typically we define register and shifts but if one observes carefully,
+ * the shift can be generated from MASKS using few bit primitaives like ffs
+ * etc, so we use that and avoid defining shifts
+ */
+#define SDW_REG_SHIFT(n)			(ffs(n) - 1)
+
+/*
+ * SDW registers as defined by MIPI 1.1 Spec
+ */
+#define SDW_REGADDR				GENMASK(14, 0)
+#define SDW_SCP_ADDRPAGE1_MASK			GENMASK(22, 15)
+#define SDW_SCP_ADDRPAGE2_MASK			GENMASK(30, 23)
+
+#define SDW_MAX_REG_ADDR			65536
+
+#define SDW_DPN_SIZE				0x100
+#define SDW_BANK1_OFFSET			0x10
+
+/*
+ * DP0 Interrupt register & bits
+ *
+ * Spec treats Status (RO) and Clear (WC) as separate but they are same
+ * address, so treat as same register with WC.
+ */
+
+/* both INT and STATUS register are same */
+#define SDW_DP0_INT				0x0
+#define SDW_DP0_INTMASK				0x1
+#define SDW_DP0_PORTCTRL			0x2
+#define SDW_DP0_BLOCKCTRL1			0x3
+#define SDW_DP0_PREPARESTATUS			0x4
+#define SDW_DP0_PREPARECTRL			0x5
+
+#define SDW_DP0_INT_TEST_FAIL			BIT(0)
+#define SDW_DP0_INT_PORT_READY			BIT(1)
+#define SDW_DP0_INT_BRA_FAILURE			BIT(2)
+#define SDW_DP0_INT_IMPDEF1			BIT(5)
+#define SDW_DP0_INT_IMPDEF2			BIT(6)
+#define SDW_DP0_INT_IMPDEF3			BIT(7)
+
+#define SDW_DP0_PORTCTRL_DATAMODE		GENMASK(3, 2)
+#define SDW_DP0_PORTCTRL_NXTINVBANK		BIT(4)
+#define SDW_DP0_PORTCTRL_BPT_PAYLD		GENMASK(7, 6)
+
+#define SDW_DP0_CHANNELEN			0x20
+#define SDW_DP0_SAMPLECTRL1			0x22
+#define SDW_DP0_SAMPLECTRL2			0x23
+#define SDW_DP0_OFFSETCTRL1			0x24
+#define SDW_DP0_OFFSETCTRL2			0x25
+#define SDW_DP0_HCTRL				0x26
+#define SDW_DP0_LANECTRL			0x28
+
+/* Both INT and STATUS register are same */
+#define SDW_SCP_INT1				0x40
+#define SDW_SCP_INTMASK1			0x41
+
+#define SDW_SCP_INT1_PARITY			BIT(0)
+#define SDW_SCP_INT1_BUS_CLASH			BIT(1)
+#define SDW_SCP_INT1_IMPL_DEF			BIT(2)
+#define SDW_SCP_INT1_SCP2_CASCADE		BIT(7)
+#define SDW_SCP_INT1_PORT0_3			GENMASK(6, 3)
+
+#define SDW_SCP_INTSTAT2			0x42
+#define SDW_SCP_INTSTAT2_SCP3_CASCADE		BIT(7)
+#define SDW_SCP_INTSTAT2_PORT4_10		GENMASK(6, 0)
+
+
+#define SDW_SCP_INTSTAT3			0x43
+#define SDW_SCP_INTSTAT3_PORT11_14		GENMASK(3, 0)
+
+/* Number of interrupt status registers */
+#define SDW_NUM_INT_STAT_REGISTERS		3
+
+/* Number of interrupt clear registers */
+#define SDW_NUM_INT_CLEAR_REGISTERS		1
+
+#define SDW_SCP_CTRL				0x44
+#define SDW_SCP_CTRL_CLK_STP_NOW		BIT(1)
+#define SDW_SCP_CTRL_FORCE_RESET		BIT(7)
+
+#define SDW_SCP_STAT				0x44
+#define SDW_SCP_STAT_CLK_STP_NF			BIT(0)
+#define SDW_SCP_STAT_HPHY_NOK			BIT(5)
+#define SDW_SCP_STAT_CURR_BANK			BIT(6)
+
+#define SDW_SCP_SYSTEMCTRL			0x45
+#define SDW_SCP_SYSTEMCTRL_CLK_STP_PREP		BIT(0)
+#define SDW_SCP_SYSTEMCTRL_CLK_STP_MODE		BIT(2)
+#define SDW_SCP_SYSTEMCTRL_WAKE_UP_EN		BIT(3)
+#define SDW_SCP_SYSTEMCTRL_HIGH_PHY		BIT(4)
+
+#define SDW_SCP_SYSTEMCTRL_CLK_STP_MODE0	0
+#define SDW_SCP_SYSTEMCTRL_CLK_STP_MODE1	BIT(2)
+
+#define SDW_SCP_DEVNUMBER			0x46
+#define SDW_SCP_HIGH_PHY_CHECK			0x47
+#define SDW_SCP_ADDRPAGE1			0x48
+#define SDW_SCP_ADDRPAGE2			0x49
+#define SDW_SCP_KEEPEREN			0x4A
+#define SDW_SCP_BANKDELAY			0x4B
+#define SDW_SCP_TESTMODE			0x4F
+#define SDW_SCP_DEVID_0				0x50
+#define SDW_SCP_DEVID_1				0x51
+#define SDW_SCP_DEVID_2				0x52
+#define SDW_SCP_DEVID_3				0x53
+#define SDW_SCP_DEVID_4				0x54
+#define SDW_SCP_DEVID_5				0x55
+
+/* Banked Registers */
+#define SDW_SCP_FRAMECTRL_B0			0x60
+#define SDW_SCP_FRAMECTRL_B1			(0x60 + SDW_BANK1_OFFSET)
+#define SDW_SCP_NEXTFRAME_B0			0x61
+#define SDW_SCP_NEXTFRAME_B1			(0x61 + SDW_BANK1_OFFSET)
+
+/* Both INT and STATUS register is same */
+#define SDW_DPN_INT(n)				(0x0 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_INTMASK(n)			(0x1 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_PORTCTRL(n)			(0x2 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_BLOCKCTRL1(n)			(0x3 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_PREPARESTATUS(n)		(0x4 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_PREPARECTRL(n)			(0x5 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_INT_TEST_FAIL			BIT(0)
+#define SDW_DPN_INT_PORT_READY			BIT(1)
+#define SDW_DPN_INT_IMPDEF1			BIT(5)
+#define SDW_DPN_INT_IMPDEF2			BIT(6)
+#define SDW_DPN_INT_IMPDEF3			BIT(7)
+
+#define SDW_DPN_PORTCTRL_FLOWMODE		GENMASK(1, 0)
+#define SDW_DPN_PORTCTRL_DATAMODE		GENMASK(3, 2)
+#define SDW_DPN_PORTCTRL_NXTINVBANK		BIT(4)
+
+#define SDW_DPN_BLOCKCTRL1_WDLEN		GENMASK(5, 0)
+
+#define SDW_DPN_PREPARECTRL_CH_PREP		GENMASK(7, 0)
+
+#define SDW_DPN_CHANNELEN_B0(n)			(0x20 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_CHANNELEN_B1(n)			(0x30 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_BLOCKCTRL2_B0(n)		(0x21 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_BLOCKCTRL2_B1(n)		(0x31 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_SAMPLECTRL1_B0(n)		(0x22 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_SAMPLECTRL1_B1(n)		(0x32 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_SAMPLECTRL2_B0(n)		(0x23 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_SAMPLECTRL2_B1(n)		(0x33 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_OFFSETCTRL1_B0(n)		(0x24 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_OFFSETCTRL1_B1(n)		(0x34 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_OFFSETCTRL2_B0(n)		(0x25 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_OFFSETCTRL2_B1(n)		(0x35 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_HCTRL_B0(n)			(0x26 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_HCTRL_B1(n)			(0x36 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_BLOCKCTRL3_B0(n)		(0x27 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_BLOCKCTRL3_B1(n)		(0x37 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_LANECTRL_B0(n)			(0x28 + SDW_DPN_SIZE * (n))
+#define SDW_DPN_LANECTRL_B1(n)			(0x38 + SDW_DPN_SIZE * (n))
+
+#define SDW_DPN_SAMPLECTRL_LOW			GENMASK(7, 0)
+#define SDW_DPN_SAMPLECTRL_HIGH			GENMASK(15, 8)
+
+#define SDW_DPN_HCTRL_HSTART			GENMASK(7, 4)
+#define SDW_DPN_HCTRL_HSTOP			GENMASK(3, 0)
+
+#define SDW_NUM_CASC_PORT_INTSTAT1		4
+#define SDW_CASC_PORT_START_INTSTAT1		0
+#define SDW_CASC_PORT_MASK_INTSTAT1		0x8
+#define SDW_CASC_PORT_REG_OFFSET_INTSTAT1	0x0
+
+#define SDW_NUM_CASC_PORT_INTSTAT2		7
+#define SDW_CASC_PORT_START_INTSTAT2		4
+#define SDW_CASC_PORT_MASK_INTSTAT2		1
+#define SDW_CASC_PORT_REG_OFFSET_INTSTAT2	1
+
+#define SDW_NUM_CASC_PORT_INTSTAT3		4
+#define SDW_CASC_PORT_START_INTSTAT3		11
+#define SDW_CASC_PORT_MASK_INTSTAT3		1
+#define SDW_CASC_PORT_REG_OFFSET_INTSTAT3	2
+
+#endif /* __SDW_REGISTERS_H */
-- 
2.7.4

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

* [PATCH 06/14] soundwire: Add IO transfer
  2017-10-19  3:03 ` Vinod Koul
@ 2017-10-19  3:03   ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

SoundWire bus supports read and write register(s) for SoundWire
Slave device. sdw_read() and sdw_write() APIs are provided for single
register read/write. sdw_nread() and sdw_nwrite() for operations on
contiguous register read/write.

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/bus.c       | 265 ++++++++++++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h       |  33 ++++++
 include/linux/soundwire/sdw.h |  67 +++++++++++
 3 files changed, 365 insertions(+)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 5b13d96b67b8..9ac22eab11bb 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -73,6 +73,12 @@ int sdw_add_bus_master(struct sdw_bus *bus)
 		return -ENODEV;
 	}
 
+	if (!bus->ops) {
+		dev_err(bus->dev, "SoundWire Bus ops are not set");
+		return -EINVAL;
+	}
+
+	mutex_init(&bus->msg_lock);
 	mutex_init(&bus->bus_lock);
 	INIT_LIST_HEAD(&bus->slaves);
 
@@ -128,6 +134,265 @@ void sdw_delete_bus_master(struct sdw_bus *bus)
 }
 EXPORT_SYMBOL(sdw_delete_bus_master);
 
+/*
+ * SDW IO Calls
+ */
+
+static bool sdw_get_page(struct sdw_slave *slave, struct sdw_msg *msg)
+{
+	bool page = false, paging_support = false;
+
+	if (slave && slave->prop.paging_support)
+		paging_support = true;
+
+	/*
+	 * Programme SCP page addr for:
+	 * 1. addr_page1 and addr_page2 contains non-zero values.
+	 * 2. Paging supported by Slave.
+	 */
+	switch (msg->dev_num) {
+	case SDW_ENUM_DEV_NUM:
+	case SDW_BROADCAST_DEV_NUM:
+		break;
+
+	default:
+		if (paging_support && ((msg->addr_page1) || (msg->addr_page2)))
+			page = true;
+	}
+
+	return page;
+}
+
+static inline int find_error_code(unsigned int sdw_ret)
+{
+	switch (sdw_ret) {
+	case SDW_CMD_OK:
+		return 0;
+
+	case SDW_CMD_IGNORED:
+		return -ENODATA;
+
+	case SDW_CMD_TIMEOUT:
+		return -ETIMEDOUT;
+	}
+
+	return -EIO;
+}
+
+static inline int do_transfer(struct sdw_bus *bus,
+			struct sdw_msg *msg, bool page)
+{
+	int retry = bus->prop.err_threshold;
+	int ret, i;
+
+	for (ret = 0, i = 0; i <= retry; i++) {
+		ret = bus->ops->xfer_msg(bus, msg, page);
+		ret = find_error_code(ret);
+		/* if cmd is ok or ignored return */
+		if (ret == 0 || ret == -ENODATA)
+			return ret;
+	}
+
+	return ret;
+}
+
+static inline int do_transfer_defer(struct sdw_bus *bus,
+			struct sdw_msg *msg, bool page,
+			struct sdw_defer *defer)
+{
+	int retry = bus->prop.err_threshold;
+	int ret, i;
+
+	defer->msg = msg;
+	defer->length = msg->len;
+
+	for (ret = 0, i = 0; i <= retry; i++) {
+
+		ret = bus->ops->xfer_msg_defer(bus, msg, page, defer);
+		ret = find_error_code(ret);
+		/* if cmd is ok or ignored return */
+		if (ret == 0 || ret == -ENODATA)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int sdw_reset_page(struct sdw_bus *bus, u16 dev_num)
+{
+	int retry = bus->prop.err_threshold;
+	int ret, i;
+
+	for (ret = 0, i = 0; i <= retry; i++) {
+		ret = bus->ops->reset_page_addr(bus, dev_num);
+		ret = find_error_code(ret);
+		/* if cmd is ok or ignored return */
+		if (ret == 0 || ret == -ENODATA)
+			return ret;
+	}
+
+	return ret;
+}
+
+/**
+ * sdw_transfer: Synchronous transfer message to a SDW Slave device
+ *
+ * @bus: SDW bus
+ * @slave: SDW Slave
+ * @msg: SDW message to be xfered
+ */
+int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
+					struct sdw_msg *msg)
+{
+	bool page;
+	int ret;
+
+	mutex_lock(&bus->msg_lock);
+
+	page = sdw_get_page(slave, msg);
+
+	ret = do_transfer(bus, msg, page);
+	if (ret != 0 && ret != -ENODATA) {
+		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
+				msg->dev_num, ret);
+		goto error;
+	}
+
+	if (page)
+		ret = sdw_reset_page(bus, msg->dev_num);
+
+error:
+	mutex_unlock(&bus->msg_lock);
+
+	return ret;
+}
+
+/**
+ * sdw_transfer_defer: Asynchronously transfer message to a SDW Slave device
+ *
+ * @bus: SDW bus
+ * @slave: SDW Slave
+ * @msg: SDW message to be xfered
+ * @defer: Defer block for signal completion
+ *
+ * Caller needs to hold the msg_lock lock while calling this
+ */
+int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_slave *slave,
+			struct sdw_msg *msg, struct sdw_defer *defer)
+{
+	bool page;
+	int ret;
+
+	if (!bus->ops->xfer_msg_defer)
+		return -ENOTSUPP;
+
+	page = sdw_get_page(slave, msg);
+
+	ret = do_transfer_defer(bus, msg, page, defer);
+	if (ret != 0 && ret != -ENODATA)
+		goto error;
+
+	if (page)
+		ret = sdw_reset_page(bus, msg->dev_num);
+
+error:
+	return ret;
+}
+
+static inline int sdw_fill_msg(struct sdw_msg *msg, u16 addr,
+				size_t count, u16 dev_num, u8 flags, u8 *buf)
+{
+	msg->addr = (addr >> SDW_REG_SHIFT(SDW_REGADDR));
+	msg->len = count;
+	msg->dev_num = dev_num;
+	msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
+	msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
+	msg->flags = flags;
+	msg->buf = buf;
+	msg->ssp_sync = false;
+
+	return 0;
+}
+
+/**
+ * sdw_nread: Read "n" contiguous SDW Slave registers
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ * @count: length
+ * @val: Buffer for values to be read
+ */
+int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+{
+	struct sdw_msg msg;
+	int ret;
+
+	pm_runtime_get_sync(slave->bus->dev);
+
+	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_READ, val);
+	ret = sdw_transfer(slave->bus, slave, &msg);
+	pm_runtime_put(slave->bus->dev);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdw_nread);
+
+/**
+ * sdw_nwrite: Write "n" contiguous SDW Slave registers
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ * @count: length
+ * @val: Buffer for values to be read
+ */
+int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+{
+	struct sdw_msg msg;
+	int ret;
+
+	pm_runtime_get_sync(slave->bus->dev);
+
+	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_WRITE, val);
+	ret = sdw_transfer(slave->bus, slave, &msg);
+	pm_runtime_put(slave->bus->dev);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdw_nwrite);
+
+/**
+ * sdw_read: Read a SDW Slave register
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ */
+int sdw_read(struct sdw_slave *slave, u32 addr)
+{
+	u8 buf;
+	int ret;
+
+	ret = sdw_nread(slave, addr, 1, &buf);
+	if (ret < 0)
+		return ret;
+	else
+		return buf;
+}
+EXPORT_SYMBOL(sdw_read);
+
+/**
+ * sdw_write: Write a SDW Slave register
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ * @value: Register value
+ */
+int sdw_write(struct sdw_slave *slave, u32 addr, u8 value)
+{
+	return sdw_nwrite(slave, addr, 1, &value);
+
+}
+EXPORT_SYMBOL(sdw_write);
+
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			unsigned long long addr, struct sdw_slave_id *id)
 {
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index f61bc9f59445..bd3b7d230076 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -79,4 +79,37 @@ int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			unsigned long long addr, struct sdw_slave_id *id);
 
+enum {
+	SDW_MSG_FLAG_READ = 0,
+	SDW_MSG_FLAG_WRITE,
+};
+
+/**
+ * struct sdw_msg: Message structure
+ *
+ * @addr: Register address accessed in the Slave
+ * @len: number of messages
+ * @dev_num: Slave device number
+ * @addr_page1: SCP address page 1 Slave register
+ * @addr_page2: SCP address page 2 Slave register
+ * @flags: transfer flags, indicate if xfer is read or write
+ * @buf: message data buffer
+ * @ssp_sync: Send message at SSP (Stream Synchronization Point)
+ */
+struct sdw_msg {
+	u16 addr;
+	u16 len;
+	u16 dev_num;
+	u8 addr_page1;
+	u8 addr_page2;
+	u8 flags;
+	u8 *buf;
+	bool ssp_sync;
+};
+
+int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
+			struct sdw_msg *msg);
+int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_slave *slave,
+			struct sdw_msg *msg, struct sdw_defer *defer);
+
 #endif /* __SDW_BUS_H */
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index a5bb5e9bc50a..af94c0a29024 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -57,6 +57,14 @@
 struct sdw_bus;
 struct sdw_slave;
 
+/* SDW spec defines and enums, as defined by MIPI 1.1. Spec */
+
+/* SDW Broadcast addr */
+#define SDW_BROADCAST_DEV_NUM		15
+
+/* SDW Enumeration Device Number */
+#define SDW_ENUM_DEV_NUM		0
+
 #define SDW_MAX_DEVICES			11
 
 /**
@@ -74,6 +82,28 @@ enum sdw_slave_status {
 	SDW_SLAVE_RESERVED = 3,
 };
 
+/**
+ * enum sdw_command_response: Command response as defined by SDW spec
+ *
+ * @SDW_CMD_OK: cmd was successful
+ * @SDW_CMD_IGNORED: cmd was ignored
+ * @SDW_CMD_FAIL: cmd was NACKed
+ * @SDW_CMD_TIMEOUT: cmd timedout
+ * @SDW_CMD_FAIL_OTHER: cmd failed due to other reason than above
+ *
+ * NOTE: The enum is different than actual Spec as response in the Spec is
+ * combination of ACK/NAK bits
+ *
+ * SDW_CMD_TIMEOUT/FAIL_OTHER is defined for SW use, not in spec
+ */
+enum sdw_command_response {
+	SDW_CMD_OK = 0,
+	SDW_CMD_IGNORED = 1,
+	SDW_CMD_FAIL = 2,
+	SDW_CMD_TIMEOUT = 4,
+	SDW_CMD_FAIL_OTHER = 8,
+};
+
 /*
  * SDW properties, defined in MIPI DisCo spec v1.0
  */
@@ -422,13 +452,39 @@ void sdw_unregister_driver(struct sdw_driver *drv);
  * SDW master structures and APIs
  */
 
+struct sdw_msg;
+
+/**
+ * struct sdw_defer: SDW deffered message
+ *
+ * @length: message length
+ * @complete: message completion
+ * @msg: SDW message
+ */
+struct sdw_defer {
+	int length;
+	struct completion complete;
+	struct sdw_msg *msg;
+};
+
 /**
  * struct sdw_master_ops: Master driver ops
  *
  * @read_prop: Read Master properties
+ * @xfer_msg: Transfer message callback
+ * @xfer_msg_defer: Defer version of transfer message callback
+ * @reset_page_addr: Reset the SCP page address registers
  */
 struct sdw_master_ops {
 	int (*read_prop)(struct sdw_bus *bus);
+
+	enum sdw_command_response (*xfer_msg)
+			(struct sdw_bus *bus, struct sdw_msg *msg, int page);
+	enum sdw_command_response (*xfer_msg_defer)
+			(struct sdw_bus *bus, struct sdw_msg *msg,
+			int page, struct sdw_defer *defer);
+	enum sdw_command_response (*reset_page_addr)
+			(struct sdw_bus *bus, unsigned int dev_num);
 };
 
 /**
@@ -439,8 +495,10 @@ struct sdw_master_ops {
  * @slaves: list of Slaves on this bus
  * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
  * @bus_lock: bus lock
+ * @msg_lock: message lock
  * @ops: Master callback ops
  * @prop: Master properties
+ * @defer_msg: Defer message
  * @clk_stop_timeout: Clock stop timeout computed
  */
 struct sdw_bus {
@@ -449,12 +507,21 @@ struct sdw_bus {
 	struct list_head slaves;
 	bool assigned[SDW_MAX_DEVICES + 1];
 	struct mutex bus_lock;
+	struct mutex msg_lock;
 	const struct sdw_master_ops *ops;
 	struct sdw_master_prop prop;
+	struct sdw_defer defer_msg;
 	unsigned int clk_stop_timeout;
 };
 
 int sdw_add_bus_master(struct sdw_bus *bus);
 void sdw_delete_bus_master(struct sdw_bus *bus);
 
+/* messaging and data APIs */
+
+int sdw_read(struct sdw_slave *slave, u32 addr);
+int sdw_write(struct sdw_slave *slave, u32 addr, u8 value);
+int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
+int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
+
 #endif /* __SOUNDWIRE_H */
-- 
2.7.4

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

* [PATCH 06/14] soundwire: Add IO transfer
@ 2017-10-19  3:03   ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

SoundWire bus supports read and write register(s) for SoundWire
Slave device. sdw_read() and sdw_write() APIs are provided for single
register read/write. sdw_nread() and sdw_nwrite() for operations on
contiguous register read/write.

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/bus.c       | 265 ++++++++++++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h       |  33 ++++++
 include/linux/soundwire/sdw.h |  67 +++++++++++
 3 files changed, 365 insertions(+)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 5b13d96b67b8..9ac22eab11bb 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -73,6 +73,12 @@ int sdw_add_bus_master(struct sdw_bus *bus)
 		return -ENODEV;
 	}
 
+	if (!bus->ops) {
+		dev_err(bus->dev, "SoundWire Bus ops are not set");
+		return -EINVAL;
+	}
+
+	mutex_init(&bus->msg_lock);
 	mutex_init(&bus->bus_lock);
 	INIT_LIST_HEAD(&bus->slaves);
 
@@ -128,6 +134,265 @@ void sdw_delete_bus_master(struct sdw_bus *bus)
 }
 EXPORT_SYMBOL(sdw_delete_bus_master);
 
+/*
+ * SDW IO Calls
+ */
+
+static bool sdw_get_page(struct sdw_slave *slave, struct sdw_msg *msg)
+{
+	bool page = false, paging_support = false;
+
+	if (slave && slave->prop.paging_support)
+		paging_support = true;
+
+	/*
+	 * Programme SCP page addr for:
+	 * 1. addr_page1 and addr_page2 contains non-zero values.
+	 * 2. Paging supported by Slave.
+	 */
+	switch (msg->dev_num) {
+	case SDW_ENUM_DEV_NUM:
+	case SDW_BROADCAST_DEV_NUM:
+		break;
+
+	default:
+		if (paging_support && ((msg->addr_page1) || (msg->addr_page2)))
+			page = true;
+	}
+
+	return page;
+}
+
+static inline int find_error_code(unsigned int sdw_ret)
+{
+	switch (sdw_ret) {
+	case SDW_CMD_OK:
+		return 0;
+
+	case SDW_CMD_IGNORED:
+		return -ENODATA;
+
+	case SDW_CMD_TIMEOUT:
+		return -ETIMEDOUT;
+	}
+
+	return -EIO;
+}
+
+static inline int do_transfer(struct sdw_bus *bus,
+			struct sdw_msg *msg, bool page)
+{
+	int retry = bus->prop.err_threshold;
+	int ret, i;
+
+	for (ret = 0, i = 0; i <= retry; i++) {
+		ret = bus->ops->xfer_msg(bus, msg, page);
+		ret = find_error_code(ret);
+		/* if cmd is ok or ignored return */
+		if (ret == 0 || ret == -ENODATA)
+			return ret;
+	}
+
+	return ret;
+}
+
+static inline int do_transfer_defer(struct sdw_bus *bus,
+			struct sdw_msg *msg, bool page,
+			struct sdw_defer *defer)
+{
+	int retry = bus->prop.err_threshold;
+	int ret, i;
+
+	defer->msg = msg;
+	defer->length = msg->len;
+
+	for (ret = 0, i = 0; i <= retry; i++) {
+
+		ret = bus->ops->xfer_msg_defer(bus, msg, page, defer);
+		ret = find_error_code(ret);
+		/* if cmd is ok or ignored return */
+		if (ret == 0 || ret == -ENODATA)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int sdw_reset_page(struct sdw_bus *bus, u16 dev_num)
+{
+	int retry = bus->prop.err_threshold;
+	int ret, i;
+
+	for (ret = 0, i = 0; i <= retry; i++) {
+		ret = bus->ops->reset_page_addr(bus, dev_num);
+		ret = find_error_code(ret);
+		/* if cmd is ok or ignored return */
+		if (ret == 0 || ret == -ENODATA)
+			return ret;
+	}
+
+	return ret;
+}
+
+/**
+ * sdw_transfer: Synchronous transfer message to a SDW Slave device
+ *
+ * @bus: SDW bus
+ * @slave: SDW Slave
+ * @msg: SDW message to be xfered
+ */
+int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
+					struct sdw_msg *msg)
+{
+	bool page;
+	int ret;
+
+	mutex_lock(&bus->msg_lock);
+
+	page = sdw_get_page(slave, msg);
+
+	ret = do_transfer(bus, msg, page);
+	if (ret != 0 && ret != -ENODATA) {
+		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
+				msg->dev_num, ret);
+		goto error;
+	}
+
+	if (page)
+		ret = sdw_reset_page(bus, msg->dev_num);
+
+error:
+	mutex_unlock(&bus->msg_lock);
+
+	return ret;
+}
+
+/**
+ * sdw_transfer_defer: Asynchronously transfer message to a SDW Slave device
+ *
+ * @bus: SDW bus
+ * @slave: SDW Slave
+ * @msg: SDW message to be xfered
+ * @defer: Defer block for signal completion
+ *
+ * Caller needs to hold the msg_lock lock while calling this
+ */
+int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_slave *slave,
+			struct sdw_msg *msg, struct sdw_defer *defer)
+{
+	bool page;
+	int ret;
+
+	if (!bus->ops->xfer_msg_defer)
+		return -ENOTSUPP;
+
+	page = sdw_get_page(slave, msg);
+
+	ret = do_transfer_defer(bus, msg, page, defer);
+	if (ret != 0 && ret != -ENODATA)
+		goto error;
+
+	if (page)
+		ret = sdw_reset_page(bus, msg->dev_num);
+
+error:
+	return ret;
+}
+
+static inline int sdw_fill_msg(struct sdw_msg *msg, u16 addr,
+				size_t count, u16 dev_num, u8 flags, u8 *buf)
+{
+	msg->addr = (addr >> SDW_REG_SHIFT(SDW_REGADDR));
+	msg->len = count;
+	msg->dev_num = dev_num;
+	msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
+	msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
+	msg->flags = flags;
+	msg->buf = buf;
+	msg->ssp_sync = false;
+
+	return 0;
+}
+
+/**
+ * sdw_nread: Read "n" contiguous SDW Slave registers
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ * @count: length
+ * @val: Buffer for values to be read
+ */
+int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+{
+	struct sdw_msg msg;
+	int ret;
+
+	pm_runtime_get_sync(slave->bus->dev);
+
+	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_READ, val);
+	ret = sdw_transfer(slave->bus, slave, &msg);
+	pm_runtime_put(slave->bus->dev);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdw_nread);
+
+/**
+ * sdw_nwrite: Write "n" contiguous SDW Slave registers
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ * @count: length
+ * @val: Buffer for values to be read
+ */
+int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
+{
+	struct sdw_msg msg;
+	int ret;
+
+	pm_runtime_get_sync(slave->bus->dev);
+
+	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_WRITE, val);
+	ret = sdw_transfer(slave->bus, slave, &msg);
+	pm_runtime_put(slave->bus->dev);
+
+	return ret;
+}
+EXPORT_SYMBOL(sdw_nwrite);
+
+/**
+ * sdw_read: Read a SDW Slave register
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ */
+int sdw_read(struct sdw_slave *slave, u32 addr)
+{
+	u8 buf;
+	int ret;
+
+	ret = sdw_nread(slave, addr, 1, &buf);
+	if (ret < 0)
+		return ret;
+	else
+		return buf;
+}
+EXPORT_SYMBOL(sdw_read);
+
+/**
+ * sdw_write: Write a SDW Slave register
+ *
+ * @slave: SDW Slave
+ * @addr: Register address
+ * @value: Register value
+ */
+int sdw_write(struct sdw_slave *slave, u32 addr, u8 value)
+{
+	return sdw_nwrite(slave, addr, 1, &value);
+
+}
+EXPORT_SYMBOL(sdw_write);
+
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			unsigned long long addr, struct sdw_slave_id *id)
 {
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index f61bc9f59445..bd3b7d230076 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -79,4 +79,37 @@ int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			unsigned long long addr, struct sdw_slave_id *id);
 
+enum {
+	SDW_MSG_FLAG_READ = 0,
+	SDW_MSG_FLAG_WRITE,
+};
+
+/**
+ * struct sdw_msg: Message structure
+ *
+ * @addr: Register address accessed in the Slave
+ * @len: number of messages
+ * @dev_num: Slave device number
+ * @addr_page1: SCP address page 1 Slave register
+ * @addr_page2: SCP address page 2 Slave register
+ * @flags: transfer flags, indicate if xfer is read or write
+ * @buf: message data buffer
+ * @ssp_sync: Send message at SSP (Stream Synchronization Point)
+ */
+struct sdw_msg {
+	u16 addr;
+	u16 len;
+	u16 dev_num;
+	u8 addr_page1;
+	u8 addr_page2;
+	u8 flags;
+	u8 *buf;
+	bool ssp_sync;
+};
+
+int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
+			struct sdw_msg *msg);
+int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_slave *slave,
+			struct sdw_msg *msg, struct sdw_defer *defer);
+
 #endif /* __SDW_BUS_H */
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index a5bb5e9bc50a..af94c0a29024 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -57,6 +57,14 @@
 struct sdw_bus;
 struct sdw_slave;
 
+/* SDW spec defines and enums, as defined by MIPI 1.1. Spec */
+
+/* SDW Broadcast addr */
+#define SDW_BROADCAST_DEV_NUM		15
+
+/* SDW Enumeration Device Number */
+#define SDW_ENUM_DEV_NUM		0
+
 #define SDW_MAX_DEVICES			11
 
 /**
@@ -74,6 +82,28 @@ enum sdw_slave_status {
 	SDW_SLAVE_RESERVED = 3,
 };
 
+/**
+ * enum sdw_command_response: Command response as defined by SDW spec
+ *
+ * @SDW_CMD_OK: cmd was successful
+ * @SDW_CMD_IGNORED: cmd was ignored
+ * @SDW_CMD_FAIL: cmd was NACKed
+ * @SDW_CMD_TIMEOUT: cmd timedout
+ * @SDW_CMD_FAIL_OTHER: cmd failed due to other reason than above
+ *
+ * NOTE: The enum is different than actual Spec as response in the Spec is
+ * combination of ACK/NAK bits
+ *
+ * SDW_CMD_TIMEOUT/FAIL_OTHER is defined for SW use, not in spec
+ */
+enum sdw_command_response {
+	SDW_CMD_OK = 0,
+	SDW_CMD_IGNORED = 1,
+	SDW_CMD_FAIL = 2,
+	SDW_CMD_TIMEOUT = 4,
+	SDW_CMD_FAIL_OTHER = 8,
+};
+
 /*
  * SDW properties, defined in MIPI DisCo spec v1.0
  */
@@ -422,13 +452,39 @@ void sdw_unregister_driver(struct sdw_driver *drv);
  * SDW master structures and APIs
  */
 
+struct sdw_msg;
+
+/**
+ * struct sdw_defer: SDW deffered message
+ *
+ * @length: message length
+ * @complete: message completion
+ * @msg: SDW message
+ */
+struct sdw_defer {
+	int length;
+	struct completion complete;
+	struct sdw_msg *msg;
+};
+
 /**
  * struct sdw_master_ops: Master driver ops
  *
  * @read_prop: Read Master properties
+ * @xfer_msg: Transfer message callback
+ * @xfer_msg_defer: Defer version of transfer message callback
+ * @reset_page_addr: Reset the SCP page address registers
  */
 struct sdw_master_ops {
 	int (*read_prop)(struct sdw_bus *bus);
+
+	enum sdw_command_response (*xfer_msg)
+			(struct sdw_bus *bus, struct sdw_msg *msg, int page);
+	enum sdw_command_response (*xfer_msg_defer)
+			(struct sdw_bus *bus, struct sdw_msg *msg,
+			int page, struct sdw_defer *defer);
+	enum sdw_command_response (*reset_page_addr)
+			(struct sdw_bus *bus, unsigned int dev_num);
 };
 
 /**
@@ -439,8 +495,10 @@ struct sdw_master_ops {
  * @slaves: list of Slaves on this bus
  * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
  * @bus_lock: bus lock
+ * @msg_lock: message lock
  * @ops: Master callback ops
  * @prop: Master properties
+ * @defer_msg: Defer message
  * @clk_stop_timeout: Clock stop timeout computed
  */
 struct sdw_bus {
@@ -449,12 +507,21 @@ struct sdw_bus {
 	struct list_head slaves;
 	bool assigned[SDW_MAX_DEVICES + 1];
 	struct mutex bus_lock;
+	struct mutex msg_lock;
 	const struct sdw_master_ops *ops;
 	struct sdw_master_prop prop;
+	struct sdw_defer defer_msg;
 	unsigned int clk_stop_timeout;
 };
 
 int sdw_add_bus_master(struct sdw_bus *bus);
 void sdw_delete_bus_master(struct sdw_bus *bus);
 
+/* messaging and data APIs */
+
+int sdw_read(struct sdw_slave *slave, u32 addr);
+int sdw_write(struct sdw_slave *slave, u32 addr, u8 value);
+int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
+int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
+
 #endif /* __SOUNDWIRE_H */
-- 
2.7.4

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

* [PATCH 07/14] regmap: Add SoundWire bus support
  2017-10-19  3:03 ` Vinod Koul
                   ` (6 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-21  9:34     ` Mark Brown
  -1 siblings, 1 reply; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

SoundWire bus provides sdw_read() and sdw_write() APIs for Slave
devices to program the registers. Provide support in regmap for
SoundWire bus.

Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/base/regmap/Kconfig      |   4 ++
 drivers/base/regmap/Makefile     |   1 +
 drivers/base/regmap/regmap-sdw.c | 146 +++++++++++++++++++++++++++++++++++++++
 drivers/soundwire/Kconfig        |   1 +
 include/linux/regmap.h           |  37 ++++++++++
 5 files changed, 189 insertions(+)
 create mode 100644 drivers/base/regmap/regmap-sdw.c

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index 073c0b77e5b3..d0310fbaa8e7 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -36,3 +36,7 @@ config REGMAP_MMIO
 
 config REGMAP_IRQ
 	bool
+
+config REGMAP_SOUNDWIRE
+	tristate
+	depends on SOUNDWIRE_BUS
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index 0cf4abc8fbf1..13004c979881 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
 obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
 obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o
 obj-$(CONFIG_REGMAP_W1) += regmap-w1.o
+obj-$(CONFIG_REGMAP_SOUNDWIRE) += regmap-sdw.o
diff --git a/drivers/base/regmap/regmap-sdw.c b/drivers/base/regmap/regmap-sdw.c
new file mode 100644
index 000000000000..37983d7c9ceb
--- /dev/null
+++ b/drivers/base/regmap/regmap-sdw.c
@@ -0,0 +1,146 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_registers.h>
+#include "internal.h"
+
+static int regmap_sdw_write(void *context, unsigned int reg, unsigned int val)
+{
+	struct device *dev = context;
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+
+	/* Check for Slave */
+	if (!slave)
+		return 0;
+
+	return sdw_write(slave, reg, val);
+}
+
+static int regmap_sdw_read(void *context, unsigned int reg, unsigned int *val)
+{
+	struct device *dev = context;
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+	int read;
+
+	/* Check for Slave */
+	if (!slave)
+		return 0;
+
+	read = sdw_read(slave, reg);
+	if (read < 0)
+		return read;
+
+	*val = read;
+	return 0;
+}
+
+static struct regmap_bus regmap_sdw = {
+	.reg_read = regmap_sdw_read,
+	.reg_write = regmap_sdw_write,
+	.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
+	.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static int regmap_sdw_config_check(const struct regmap_config *config)
+{
+	/* All register are 8-bits wide as per MIPI Soundwire 1.0 Spec */
+	if (config->val_bits != 8)
+		return -ENOTSUPP;
+
+	/* Registers are 32 bits wide */
+	if (config->reg_bits != 32)
+		return -ENOTSUPP;
+
+	/* SoundWire register address are contiguous */
+	if (config->reg_stride != 0)
+		return -ENOTSUPP;
+
+	if (config->pad_bits != 0)
+		return -ENOTSUPP;
+
+	return 0;
+}
+
+struct regmap *__regmap_init_sdw(struct sdw_slave *sdw,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name)
+{
+	int ret;
+
+	ret = regmap_sdw_config_check(config);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return __regmap_init(&sdw->dev, &regmap_sdw,
+			&sdw->dev, config, lock_key, lock_name);
+}
+EXPORT_SYMBOL(__regmap_init_sdw);
+
+struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw,
+				      const struct regmap_config *config,
+				      struct lock_class_key *lock_key,
+				      const char *lock_name)
+{
+	int ret;
+
+	ret = regmap_sdw_config_check(config);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return __devm_regmap_init(&sdw->dev, &regmap_sdw,
+			&sdw->dev, config, lock_key, lock_name);
+}
+EXPORT_SYMBOL(__devm_regmap_init_sdw);
+
+MODULE_DESCRIPTION("Regmap SoundWire Module");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig
index 35792728c0aa..d63295015331 100644
--- a/drivers/soundwire/Kconfig
+++ b/drivers/soundwire/Kconfig
@@ -18,5 +18,6 @@ comment "SoundWire Devices"
 config SOUNDWIRE_BUS
 	tristate
 	default SOUNDWIRE
+	select REGMAP_SOUNDWIRE
 
 endif
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 978abfbac617..d5eecf2e9697 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -30,6 +30,7 @@ struct regmap;
 struct regmap_range_cfg;
 struct regmap_field;
 struct snd_ac97;
+struct sdw_slave;
 
 /* An enum of all the supported cache types */
 enum regcache_type {
@@ -474,6 +475,10 @@ struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97,
 				  const struct regmap_config *config,
 				  struct lock_class_key *lock_key,
 				  const char *lock_name);
+struct regmap *__regmap_init_sdw(struct sdw_slave *sdw,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name);
 
 struct regmap *__devm_regmap_init(struct device *dev,
 				  const struct regmap_bus *bus,
@@ -511,6 +516,10 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97,
 				       const struct regmap_config *config,
 				       struct lock_class_key *lock_key,
 				       const char *lock_name);
+struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name);
 
 /*
  * Wrapper for regmap_init macros to include a unique lockdep key and name
@@ -660,6 +669,20 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
 bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
 
 /**
+ * regmap_init_sdw(): Initialise register map
+ *
+ * @sdw: 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_sdw(sdw, config)					\
+	__regmap_lockdep_wrapper(__regmap_init_sdw, #config,		\
+				sdw, config)
+
+
+/**
  * devm_regmap_init() - Initialise managed register map
  *
  * @dev: Device that will be interacted with
@@ -789,6 +812,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
 	__regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config,	\
 				ac97, config)
 
+/**
+ * devm_regmap_init_sdw(): Initialise managed register map
+ *
+ * @sdw: 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.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_sdw(sdw, config)				\
+	__regmap_lockdep_wrapper(__devm_regmap_init_sdw, #config,	\
+				sdw, config)
+
 void regmap_exit(struct regmap *map);
 int regmap_reinit_cache(struct regmap *map,
 			const struct regmap_config *config);
-- 
2.7.4

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

* [PATCH 08/14] soundwire: Add Slave status handling helpers
  2017-10-19  3:03 ` Vinod Koul
                   ` (7 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-19 13:44   ` [alsa-devel] " Takashi Iwai
  -1 siblings, 1 reply; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

From: Sanyog Kale <sanyog.r.kale@intel.com>

SoundWire Slaves report status to bus. Add helpers to handle
the status changes.

Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/bus.c       | 211 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/soundwire/sdw.h |   1 +
 2 files changed, 212 insertions(+)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 9ac22eab11bb..f206e78d4b68 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -393,6 +393,95 @@ int sdw_write(struct sdw_slave *slave, u32 addr, u8 value)
 }
 EXPORT_SYMBOL(sdw_write);
 
+/*
+ * SDW alert handling
+ */
+static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
+{
+	struct sdw_slave *slave;
+
+	list_for_each_entry(slave, &bus->slaves, node) {
+		if (slave->dev_num == i)
+			return slave;
+	}
+
+	return NULL;
+}
+
+static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
+{
+
+	if ((slave->id.unique_id != id.unique_id) ||
+			(slave->id.mfg_id != id.mfg_id) ||
+			(slave->id.part_id != id.part_id) ||
+			(slave->id.class_id != id.class_id))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int sdw_get_device_num(struct sdw_slave *slave)
+{
+	bool assigned = false;
+	int i;
+
+	mutex_lock(&slave->bus->bus_lock);
+	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
+		if (slave->bus->assigned[i] == true)
+			continue;
+
+		slave->bus->assigned[i] = true;
+		assigned = true;
+
+		/*
+		 * Do not update dev_num in Slave data structure here,
+		 * Update once program dev_num is successful
+		 */
+		break;
+	}
+
+	mutex_unlock(&slave->bus->bus_lock);
+	if (assigned)
+		return i;
+	else
+		return -ENODEV;
+}
+
+static int sdw_assign_device_num(struct sdw_slave *slave)
+{
+	int ret, dev_num;
+
+	/* check first if device number is assigned, if so reuse that */
+	if (!slave->dev_num) {
+		dev_num = sdw_get_device_num(slave);
+		if (dev_num < 0) {
+			dev_err(slave->bus->dev, "Get dev_num failed: %d",
+								dev_num);
+			return dev_num;
+		}
+	} else {
+		dev_info(slave->bus->dev,
+				"Slave already registered dev_num:%d",
+				slave->dev_num);
+
+		/* Clear the slave->dev_num to transfer message on device 0 */
+		dev_num = slave->dev_num;
+		slave->dev_num = 0;
+
+	}
+
+	ret = sdw_write(slave, SDW_SCP_DEVNUMBER, dev_num);
+	if (ret < 0) {
+		dev_err(&slave->dev, "Program device_num failed: %d", ret);
+		return ret;
+	}
+
+	/* After xfer of msg, restore dev_num */
+	slave->dev_num = dev_num;
+
+	return 0;
+}
+
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			unsigned long long addr, struct sdw_slave_id *id)
 {
@@ -421,3 +510,125 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
 				id->unique_id, id->sdw_version);
 
 }
+
+static int sdw_program_device_num(struct sdw_bus *bus)
+{
+	u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
+	unsigned long long addr;
+	struct sdw_slave *slave;
+	struct sdw_slave_id id;
+	struct sdw_msg msg;
+	bool found = false;
+	int ret;
+
+	/* No Slave, so use raw xfer api */
+	sdw_fill_msg(&msg, SDW_SCP_DEVID_0, SDW_NUM_DEV_ID_REGISTERS,
+					0, SDW_MSG_FLAG_READ, buf);
+
+	do {
+		ret = sdw_transfer(bus, NULL, &msg);
+		if (ret == -ENODATA)
+			break;
+		if (ret < 0) {
+			dev_err(bus->dev, "DEVID read fail:%d\n", ret);
+			break;
+		}
+
+		/*
+		 * Construct the addr and extract. Cast the higher shift
+		 * bits to avoid truncation due to size limit.
+		 */
+		addr = buf[5] | (buf[4] << 8) | (buf[3] << 16) |
+			(buf[2] << 24) | ((unsigned long long)buf[1] << 32) |
+			((unsigned long long)buf[0] << 40);
+
+		sdw_extract_slave_id(bus, addr, &id);
+
+		/* Now compare with entries */
+		list_for_each_entry(slave, &bus->slaves, node) {
+			if (sdw_compare_devid(slave, id) == 0) {
+				found = true;
+
+				/*
+				 * Assign a new dev_num to this Slave and
+				 * not mark it present. It will be marked
+				 * present after it reports ATTACHED on new
+				 * dev_num
+				 */
+				ret = sdw_assign_device_num(slave);
+				if (ret) {
+					dev_err(slave->bus->dev,
+						"Assign dev_num failed:%d",
+						ret);
+					return ret;
+				}
+
+				break;
+			}
+		}
+
+		if (found == false) {
+			/* TODO: Park this device in Group 13 */
+			dev_err(bus->dev, "Slave Entry not found");
+		}
+
+	} while (ret == 0);
+
+	return 0;
+}
+
+static void sdw_modify_slave_status(struct sdw_slave *slave,
+				enum sdw_slave_status status)
+{
+	mutex_lock(&slave->bus->bus_lock);
+	slave->status = status;
+	mutex_unlock(&slave->bus->bus_lock);
+}
+
+static int sdw_initialize_slave(struct sdw_slave *slave)
+{
+	struct sdw_slave_prop *prop = &slave->prop;
+	int val, ret;
+
+	val = sdw_read(slave, SDW_SCP_INTMASK1);
+	if (val < 0) {
+		dev_err(slave->bus->dev,
+				"SDW_SCP_INTMASK1 read failed:%d", val);
+		return val;
+	}
+
+	/* Set bus clash and parity interrupt mask */
+	val |= SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
+
+	/* Enable SCP interrupts */
+	ret = sdw_write(slave, SDW_SCP_INTMASK1, val);
+	if (ret < 0) {
+		dev_err(slave->bus->dev,
+				"SDW_SCP_INTMASK1 write failed:%d", val);
+		return ret;
+	}
+
+	/* No need to continue if DP0 is not present */
+	if (!slave->prop.dp0_prop)
+		return 0;
+
+	/* Enable DP0 interrupts */
+	val = sdw_read(slave, SDW_DP0_INTMASK);
+	if (val < 0) {
+		dev_err(slave->bus->dev,
+				"SDW_DP0_INTMASK read failed:%d", val);
+		return val;
+	}
+
+	val |= prop->dp0_prop->device_interrupts;
+	val |= SDW_DP0_INT_PORT_READY | SDW_DP0_INT_BRA_FAILURE;
+
+	ret = sdw_write(slave, SDW_DP0_INTMASK, val);
+	if (ret < 0) {
+		dev_err(slave->bus->dev,
+				"SDW_DP0_INTMASK write failed:%d", val);
+		return ret;
+	}
+
+	return 0;
+}
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index af94c0a29024..c25315bc5331 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -65,6 +65,7 @@ struct sdw_slave;
 /* SDW Enumeration Device Number */
 #define SDW_ENUM_DEV_NUM		0
 
+#define SDW_NUM_DEV_ID_REGISTERS	6
 #define SDW_MAX_DEVICES			11
 
 /**
-- 
2.7.4

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

* [PATCH 09/14] soundwire: Add slave status handling
  2017-10-19  3:03 ` Vinod Koul
                   ` (8 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

Add status handling API sdw_handle_slave_status() to handle
Slave status changes.

Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/bus.c       | 344 ++++++++++++++++++++++++++++++++++++++++++
 drivers/soundwire/bus.h       |   2 +
 include/linux/soundwire/sdw.h |  21 +++
 3 files changed, 367 insertions(+)

diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index f206e78d4b68..6c4f41b64744 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -632,3 +632,347 @@ static int sdw_initialize_slave(struct sdw_slave *slave)
 
 	return 0;
 }
+
+static int sdw_handle_dp0_interrupt(struct sdw_slave *slave, u8 *slave_status)
+{
+	u8 clear = 0, impl_int_mask;
+	int status, ret, count = 0;
+
+	status = sdw_read(slave, SDW_DP0_INT);
+	if (status < 0) {
+		dev_err(slave->bus->dev,
+				"SDW_DP0_INT read failed:%d", status);
+		return status;
+	}
+
+	do {
+
+		if (status & SDW_DP0_INT_TEST_FAIL) {
+			dev_err(&slave->dev, "Test fail for port 0");
+			clear |= SDW_DP0_INT_TEST_FAIL;
+		}
+
+		/*
+		 * Assumption: PORT_READY interrupt will be received only for
+		 * ports implementing Channel Prepare state machine (CP_SM)
+		 */
+
+		if (status & SDW_DP0_INT_PORT_READY) {
+			complete(&slave->port_ready[0]);
+			clear |= SDW_DP0_INT_PORT_READY;
+		}
+
+		if (status & SDW_DP0_INT_BRA_FAILURE) {
+			dev_err(&slave->dev, "BRA failed");
+			clear |= SDW_DP0_INT_BRA_FAILURE;
+		}
+
+		impl_int_mask = SDW_DP0_INT_IMPDEF1 |
+			SDW_DP0_INT_IMPDEF2 | SDW_DP0_INT_IMPDEF3;
+
+		if (status & impl_int_mask) {
+			clear |= impl_int_mask;
+			*slave_status = clear;
+		}
+
+		/* clear the interrupt */
+		ret = sdw_write(slave, SDW_DP0_INT, clear);
+		if (ret < 0) {
+			dev_err(slave->bus->dev,
+				"SDW_DP0_INT write failed:%d", ret);
+			return ret;
+		}
+
+		/* Read DP0 interrupt again */
+		status = sdw_read(slave, SDW_DP0_INT);
+		if (status < 0) {
+			dev_err(slave->bus->dev,
+				"SDW_DP0_INT read failed:%d", status);
+			return status;
+		}
+
+		count++;
+
+		/* we can get alerts while processing so keep retrying */
+	} while (status != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
+
+	if (count == SDW_READ_INTR_CLEAR_RETRY)
+		dev_warn(slave->bus->dev, "Reached MAX_RETRY on DP0 read");
+
+	return ret;
+}
+
+static int sdw_handle_port_interrupt(struct sdw_slave *slave,
+		int port, u8 *slave_status)
+{
+	u8 clear = 0, impl_int_mask;
+	int status, ret, count = 0;
+	u32 addr;
+
+	if (port == 0)
+		return sdw_handle_dp0_interrupt(slave, slave_status);
+
+	addr = SDW_DPN_INT(port);
+	status = sdw_read(slave, addr);
+	if (status < 0) {
+		dev_err(slave->bus->dev,
+				"SDW_DPN_INT read failed:%d", status);
+
+		return status;
+	}
+
+	do {
+
+		if (status & SDW_DPN_INT_TEST_FAIL) {
+			dev_err(&slave->dev, "Test fail for port:%d", port);
+			clear |= SDW_DPN_INT_TEST_FAIL;
+		}
+
+		/*
+		 * Assumption: PORT_READY interrupt will be received only
+		 * for ports implementing CP_SM.
+		 */
+		if (status & SDW_DPN_INT_PORT_READY) {
+			complete(&slave->port_ready[port]);
+			clear |= SDW_DPN_INT_PORT_READY;
+		}
+
+		impl_int_mask = SDW_DPN_INT_IMPDEF1 |
+			SDW_DPN_INT_IMPDEF2 | SDW_DPN_INT_IMPDEF3;
+
+
+		if (status & impl_int_mask) {
+			clear |= impl_int_mask;
+			*slave_status = clear;
+		}
+
+		/* clear the interrupt */
+		ret = sdw_write(slave, addr, clear);
+		if (ret < 0) {
+			dev_err(slave->bus->dev,
+					"SDW_DPN_INT write failed:%d", ret);
+			return ret;
+		}
+
+		/* Read DPN interrupt again */
+		status = sdw_read(slave, addr);
+		if (status < 0) {
+			dev_err(slave->bus->dev,
+					"SDW_DPN_INT read failed:%d", status);
+			return status;
+		}
+
+		count++;
+
+		/* we can get alerts while processing so keep retrying */
+	} while (status != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
+
+	if (count == SDW_READ_INTR_CLEAR_RETRY)
+		dev_warn(slave->bus->dev, "Reached MAX_RETRY on port read");
+
+	return ret;
+}
+
+static int sdw_handle_slave_alerts(struct sdw_slave *slave)
+{
+	u8 clear = 0, bit, port_status[15];
+	int port_num, stat, ret, count = 0;
+	unsigned long port;
+	u8 buf[3];
+
+	sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);
+
+	/* Read Instat 1, Instat 2 and Instat 3 registers */
+	ret = sdw_nread(slave, SDW_SCP_INT1, 3, buf);
+	if (ret < 0) {
+		dev_err(slave->bus->dev,
+					"SDW_SCP_INT1 read failed:%d", ret);
+		return ret;
+	}
+
+	do {
+		/*
+		 * Check parity, bus clash and Slave (impl defined)
+		 * interrupt
+		 */
+		if (buf[0] & SDW_SCP_INT1_PARITY) {
+			dev_err(&slave->dev, "Parity error detected");
+			clear |= SDW_SCP_INT1_PARITY;
+		}
+
+		if (buf[0] & SDW_SCP_INT1_BUS_CLASH) {
+			dev_err(&slave->dev, "Bus clash error detected");
+			clear |= SDW_SCP_INT1_BUS_CLASH;
+		}
+
+		/*
+		 * When bus clash or parity errors are detected, such errors
+		 * are unlikely to be recoverable errors.
+		 * TODO: In such scenario, reset bus. Make this configurable
+		 * via sysfs property with bus reset being the default.
+		 */
+		if (buf[0] & SDW_SCP_INT1_IMPL_DEF) {
+			dev_dbg(&slave->dev, "Slave impl defined interrupt\n");
+			clear |= SDW_SCP_INT1_IMPL_DEF;
+		}
+
+		/* Check port 0 - 4 interrupts */
+		port = buf[0] & SDW_SCP_INT1_PORT0_3;
+
+		/* To get port number corresponding to bits, shift it */
+		port = port >> SDW_REG_SHIFT(SDW_SCP_INT1_PORT0_3);
+		for_each_set_bit(bit, &port, 8) {
+			sdw_handle_port_interrupt(slave, bit,
+						&port_status[bit]);
+
+		}
+
+		/* Check if cascade 2 interrupt is present */
+		if (buf[0] & SDW_SCP_INT1_SCP2_CASCADE) {
+			port = buf[1] & SDW_SCP_INTSTAT2_PORT4_10;
+			for_each_set_bit(bit, &port, 8) {
+				/* scp2 ports start from 4 */
+				port_num = bit + 3;
+				sdw_handle_port_interrupt(slave,
+						port_num,
+						&port_status[port_num]);
+			}
+		}
+
+		/* now check last cascade */
+		if (buf[1] & SDW_SCP_INTSTAT2_SCP3_CASCADE) {
+			port = buf[2] & SDW_SCP_INTSTAT3_PORT11_14;
+			for_each_set_bit(bit, &port, 8) {
+				/* scp3 ports start from 11 */
+				port_num = bit + 10;
+				sdw_handle_port_interrupt(slave,
+						port_num,
+						&port_status[port_num]);
+			}
+		}
+
+		/* Update the Slave driver */
+		if ((slave->ops) && (slave->ops->interrupt_callback)) {
+			struct sdw_slave_intr_status slave_intr;
+
+			slave_intr.control_port = clear;
+			memcpy(slave_intr.port, &port_status,
+						sizeof(slave_intr.port));
+
+			slave->ops->interrupt_callback(slave, &slave_intr);
+		}
+
+		/* Ack interrupt */
+		ret = sdw_write(slave, SDW_SCP_INT1, clear);
+		if (ret < 0) {
+			dev_err(slave->bus->dev,
+					"SDW_SCP_INT1 write failed:%d", ret);
+			return ret;
+		}
+
+		/*
+		 * Read status again to ensure no new interrupts arrived
+		 * while servicing interrupts
+		 */
+		ret = sdw_nread(slave, SDW_SCP_INT1, 3, buf);
+		if (ret < 0) {
+			dev_err(slave->bus->dev,
+					"SDW_SCP_INT1 read failed:%d", ret);
+			return ret;
+		}
+
+		/* Make sure no interrupts are pending */
+		stat = buf[0] || buf[1] || buf[2];
+
+		/*
+		 * Exit loop if Slave is continuously in ALERT state even
+		 * after servicing the interrupt multiple times.
+		 */
+		count++;
+
+		/* we can get alerts while processing so keep retrying */
+	} while (stat != 0 && count < SDW_READ_INTR_CLEAR_RETRY);
+
+	if (count == SDW_READ_INTR_CLEAR_RETRY)
+		dev_warn(slave->bus->dev, "Reached MAX_RETRY on alert read");
+
+	return ret;
+}
+
+static int sdw_update_slave_status(struct sdw_slave *slave,
+				enum sdw_slave_status status)
+{
+	if ((slave->ops) && (slave->ops->update_status))
+		return slave->ops->update_status(slave, status);
+
+	return 0;
+}
+
+/**
+ * sdw_handle_slave_status: Handle Slave status
+ *
+ * @bus: SDW bus instance
+ * @status: Status for all Slave(s)
+ */
+int sdw_handle_slave_status(struct sdw_bus *bus,
+			enum sdw_slave_status status[])
+{
+	struct sdw_slave *slave;
+	int i, ret = 0;
+
+	if (status[0] == SDW_SLAVE_ATTACHED) {
+		ret = sdw_program_device_num(bus);
+		if (ret)
+			dev_err(bus->dev, "Slave attach failed: %d", ret);
+	}
+
+	/* Continue to check other slave statuses */
+	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
+		if (bus->assigned[i] == false)
+			continue;
+
+		slave = sdw_get_slave(bus, i);
+		if (!slave)
+			continue;
+
+		switch (status[i]) {
+		case SDW_SLAVE_UNATTACHED:
+			if (slave->status == SDW_SLAVE_UNATTACHED)
+				break;
+
+			sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
+			break;
+
+		case SDW_SLAVE_ALERT:
+			ret = sdw_handle_slave_alerts(slave);
+			if (ret)
+				dev_err(bus->dev,
+					"Slave %d alert handling failed: %d",
+					i, ret);
+			break;
+
+		case SDW_SLAVE_ATTACHED:
+			if (slave->status == SDW_SLAVE_ATTACHED)
+				break;
+
+			sdw_initialize_slave(slave);
+			sdw_modify_slave_status(slave, SDW_SLAVE_ATTACHED);
+
+			break;
+
+		default:
+			dev_err(bus->dev, "Invalid slave %d status:%d",
+							i, status[i]);
+			break;
+		}
+
+		ret = sdw_update_slave_status(slave, status[i]);
+		if (ret)
+			dev_err(slave->bus->dev,
+				"Update Slave status failed:%d", ret);
+
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(sdw_handle_slave_status);
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index bd3b7d230076..2e9f84209879 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -107,6 +107,8 @@ struct sdw_msg {
 	bool ssp_sync;
 };
 
+#define SDW_READ_INTR_CLEAR_RETRY	10
+
 int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
 			struct sdw_msg *msg);
 int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_slave *slave,
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index c25315bc5331..38c806cae2bf 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -386,12 +386,30 @@ struct sdw_slave_id {
 };
 
 /**
+ * struct sdw_slave_intr_status: Slave interrupt status
+ *
+ * @control_port: control port status
+ * @port: data port status
+ */
+struct sdw_slave_intr_status {
+	u8 control_port;
+	u8 port[14];
+};
+
+/**
  * struct sdw_slave_ops: Slave driver callback ops
  *
  * @read_prop: Read Slave properties
+ * @interrupt_callback: Device interrupt notification (invoked in thread
+ * context)
+ * @update_status: Update Slave status
  */
 struct sdw_slave_ops {
 	int (*read_prop)(struct sdw_slave *sdw);
+	int (*interrupt_callback)(struct sdw_slave *slave,
+			struct sdw_slave_intr_status *status);
+	int (*update_status)(struct sdw_slave *slave,
+			enum sdw_slave_status status);
 };
 
 /**
@@ -449,6 +467,9 @@ struct sdw_driver {
 int __sdw_register_driver(struct sdw_driver *drv, struct module *);
 void sdw_unregister_driver(struct sdw_driver *drv);
 
+int sdw_handle_slave_status(struct sdw_bus *bus,
+			enum sdw_slave_status status[]);
+
 /*
  * SDW master structures and APIs
  */
-- 
2.7.4

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

* [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
  2017-10-19  3:03 ` Vinod Koul
                   ` (9 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-21  9:42     ` Mark Brown
  2017-11-09 21:14   ` Srinivas Kandagatla
  -1 siblings, 2 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

It helps to read the properties for understanding and debug
SoundWire systems, so add sysfs files for SoundWire DisCo
properties.

TODO: Add ABI files for sysfs

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Makefile    |   2 +-
 drivers/soundwire/bus.c       |   5 +
 drivers/soundwire/bus.h       |   2 +
 drivers/soundwire/slave.c     |   1 +
 drivers/soundwire/sysfs.c     | 396 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/soundwire/sdw.h |  15 ++
 6 files changed, 420 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soundwire/sysfs.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index bcde0d26524c..67dc7b546258 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -3,5 +3,5 @@
 #
 
 #Bus Objs
-soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o
+soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o sysfs.o
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
index 6c4f41b64744..e3d7aea18892 100644
--- a/drivers/soundwire/bus.c
+++ b/drivers/soundwire/bus.c
@@ -90,6 +90,8 @@ int sdw_add_bus_master(struct sdw_bus *bus)
 		}
 	}
 
+	sdw_sysfs_bus_init(bus);
+
 	/*
 	 * SDW is an enumerable bus, but devices can be powered off. So,
 	 * they won't be able to report as present.
@@ -119,6 +121,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
 	struct sdw_slave *slave = dev_to_sdw_dev(dev);
 	struct sdw_bus *bus = slave->bus;
 
+	sdw_sysfs_slave_exit(slave);
+
 	mutex_lock(&bus->bus_lock);
 	if (!list_empty(&bus->slaves))
 		list_del(&slave->node);
@@ -130,6 +134,7 @@ static int sdw_delete_slave(struct device *dev, void *data)
 
 void sdw_delete_bus_master(struct sdw_bus *bus)
 {
+	sdw_sysfs_bus_init(bus);
 	device_for_each_child(bus->dev, NULL, sdw_delete_slave);
 }
 EXPORT_SYMBOL(sdw_delete_bus_master);
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
index 2e9f84209879..2c1f64415a5b 100644
--- a/drivers/soundwire/bus.h
+++ b/drivers/soundwire/bus.h
@@ -79,6 +79,8 @@ int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
 void sdw_extract_slave_id(struct sdw_bus *bus,
 			unsigned long long addr, struct sdw_slave_id *id);
 
+extern const struct attribute_group *sdw_slave_dev_attr_groups[];
+
 enum {
 	SDW_MSG_FLAG_READ = 0,
 	SDW_MSG_FLAG_WRITE,
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
index ee8e0e848f64..1b4e7f1b66e1 100644
--- a/drivers/soundwire/slave.c
+++ b/drivers/soundwire/slave.c
@@ -85,6 +85,7 @@ static int sdw_slave_add(struct sdw_bus *bus,
 	slave->dev.fwnode = fwnode;
 	dev_set_name(&slave->dev, "%s", name);
 	slave->dev.release = sdw_slave_release;
+	slave->dev.groups = sdw_slave_dev_attr_groups;
 	slave->dev.bus = &sdw_bus_type;
 	slave->bus = bus;
 	slave->status = SDW_SLAVE_UNATTACHED;
diff --git a/drivers/soundwire/sysfs.c b/drivers/soundwire/sysfs.c
new file mode 100644
index 000000000000..29e2f1db08ec
--- /dev/null
+++ b/drivers/soundwire/sysfs.c
@@ -0,0 +1,396 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+
+/*
+ * The sysfs for properties reflects the MIPI description as given
+ * in the MIPI DisCo spec
+ *
+ * Base file is:
+ *		properties
+ *		|---- interface-revision
+ *		|---- master-count
+ *		|---- link-N
+ *		      |---- clock-stop-modes
+ *		      |---- max-clock-frequency
+ *		      |---- clock-frequencies
+ *		      |---- default-frame-rows
+ *		      |---- default-frame-cols
+ *		      |---- dynamic-frame-shape
+ *		      |---- command-error-threshold
+ */
+
+struct sdw_master_sysfs {
+	struct kobject kobj;
+	struct sdw_bus *bus;
+};
+
+struct sdw_prop_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf);
+};
+
+static ssize_t sdw_prop_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct sdw_prop_attribute *prop_attr =
+		container_of(attr, struct sdw_prop_attribute, attr);
+	struct sdw_master_sysfs *master =
+		container_of(kobj, struct sdw_master_sysfs, kobj);
+
+	if (!prop_attr->show)
+		return -EIO;
+
+	return prop_attr->show(master->bus, prop_attr, buf);
+}
+
+static const struct sysfs_ops sdw_prop_sysfs_ops = {
+	.show	= sdw_prop_attr_show,
+};
+
+static void prop_release(struct kobject *kobj)
+{
+	struct sdw_master_sysfs *master =
+		container_of(kobj, struct sdw_master_sysfs, kobj);
+
+	kfree(master);
+}
+
+static struct kobj_type sdw_master_prop_ktype = {
+	.release	= prop_release,
+	.sysfs_ops	= &sdw_prop_sysfs_ops,
+};
+
+
+#define MASTER_ATTR(_name) \
+	struct sdw_prop_attribute master_attr_##_name = __ATTR_RO(_name)
+
+static ssize_t revision_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.revision);
+}
+
+static ssize_t count_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.master_count);
+}
+
+static ssize_t clock_stop_modes_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.clk_stop_mode);
+}
+
+static ssize_t max_clock_frequency_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.max_freq);
+}
+
+static ssize_t clock_frequencies_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	ssize_t size = 0;
+	int i;
+
+	for (i = 0; i < bus->prop.num_freq; i++)
+		size += sprintf(buf + size, "%8d\n", bus->prop.freq[i]);
+
+	return size;
+}
+
+static ssize_t clock_gears_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	ssize_t size = 0;
+	int i;
+
+	for (i = 0; i < bus->prop.num_clk_gears; i++)
+		size += sprintf(buf + size, "%8d\n", bus->prop.clk_gears[i]);
+
+	return size;
+}
+
+static ssize_t default_frame_rows_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.default_row);
+}
+
+static ssize_t default_frame_cols_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.default_col);
+}
+
+static ssize_t dynamic_frame_shape_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.dynamic_frame);
+}
+
+static ssize_t command_error_threshold_show(struct sdw_bus *bus,
+			struct sdw_prop_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%08x\n", bus->prop.err_threshold);
+}
+
+static MASTER_ATTR(revision);
+static MASTER_ATTR(count);
+static MASTER_ATTR(clock_stop_modes);
+static MASTER_ATTR(max_clock_frequency);
+static MASTER_ATTR(clock_frequencies);
+static MASTER_ATTR(clock_gears);
+static MASTER_ATTR(default_frame_rows);
+static MASTER_ATTR(default_frame_cols);
+static MASTER_ATTR(dynamic_frame_shape);
+static MASTER_ATTR(command_error_threshold);
+
+static struct attribute *master_node_attrs[] = {
+	&master_attr_revision.attr,
+	&master_attr_count.attr,
+	&master_attr_clock_stop_modes.attr,
+	&master_attr_max_clock_frequency.attr,
+	&master_attr_clock_frequencies.attr,
+	&master_attr_clock_gears.attr,
+	&master_attr_default_frame_rows.attr,
+	&master_attr_default_frame_cols.attr,
+	&master_attr_dynamic_frame_shape.attr,
+	&master_attr_command_error_threshold.attr,
+	NULL,
+};
+
+static const struct attribute_group sdw_master_node_group = {
+	.attrs = master_node_attrs,
+};
+
+int sdw_sysfs_bus_init(struct sdw_bus *bus)
+{
+	struct kset *sdw_bus_kset;
+	struct sdw_master_sysfs *master;
+	int err;
+
+	if (bus->sysfs) {
+		dev_err(bus->dev, "SDW sysfs is already initialized\n");
+		return -EIO;
+	}
+
+	sdw_bus_kset = bus_get_kset(&sdw_bus_type);
+
+	master = bus->sysfs = kzalloc(sizeof(*master), GFP_KERNEL);
+	if (!master)
+		return -ENOMEM;
+
+	err = kobject_init_and_add(&master->kobj,
+			&sdw_master_prop_ktype, &sdw_bus_kset->kobj,
+			"mipi-properties-link%d", bus->link_id);
+	if (err < 0)
+		return err;
+
+	master->bus = bus;
+
+	err = sysfs_create_group(&master->kobj, &sdw_master_node_group);
+	if (err < 0) {
+		kobject_put(&master->kobj);
+		return err;
+	}
+
+	kobject_uevent(&master->kobj, KOBJ_CHANGE);
+	return 0;
+}
+
+void sdw_sysfs_bus_exit(struct sdw_bus *bus)
+{
+	struct sdw_master_sysfs *master = bus->sysfs;
+
+	if (!master)
+		return;
+
+	kobject_put(&master->kobj);
+	bus->sysfs = NULL;
+}
+
+/*
+ * Slave sysfs
+ */
+
+/*
+ * The sysfs for Slave reflects the MIPI description as given
+ * in the MIPI DisCo spec
+ *
+ * Base file is device
+ *	|---- mipi_revision
+ *	|---- wake_capable
+ *	|---- test_mode_capable
+ *	|---- simple_clk_stop_capable
+ *	|---- clk_stop_timeout
+ *	|---- ch_prep_timeout
+ *	|---- reset_behave
+ *	|---- high_PHY_capable
+ *	|---- paging_support
+ *	|---- bank_delay_support
+ *	|---- p15_behave
+ *	|---- master_count
+ *	|---- source_ports
+ *	|---- sink_ports
+ *	|---- dp0
+ *		|---- max_word
+ *		|---- min_word
+ *		|---- words
+ *		|---- flow_controlled
+ *		|---- simple_ch_prep_sm
+ *		|---- device_interrupts
+ *	|---- dpN
+ *		|---- max_word
+ *		|---- min_word
+ *		|---- words
+ *		|---- type
+ *		|---- max_grouping
+ *		|---- simple_ch_prep_sm
+ *		|---- ch_prep_timeout
+ *		|---- device_interrupts
+ *		|---- max_ch
+ *		|---- min_ch
+ *		|---- ch
+ *		|---- ch_combinations
+ *		|---- modes
+ *		|---- max_async_buffer
+ *		|---- block_pack_mode
+ *		|---- port_encoding
+ *		|---- bus_min_freq
+ *		|---- bus_max_freq
+ *		|---- bus_freq
+ *		|---- max_freq
+ *		|---- min_freq
+ *		|---- freq
+ *		|---- prep_ch_behave
+ *		|---- glitchless
+ *
+ */
+struct sdw_slave_sysfs {
+	struct sdw_slave *slave;
+};
+
+#define SLAVE_ATTR(type)					\
+static ssize_t type##_show(struct device *dev,			\
+		struct device_attribute *attr, char *buf)	\
+{								\
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);		\
+	return sprintf(buf, "0x%x\n", slave->prop.type);	\
+}								\
+static DEVICE_ATTR_RO(type)
+
+SLAVE_ATTR(mipi_revision);
+SLAVE_ATTR(wake_capable);
+SLAVE_ATTR(test_mode_capable);
+SLAVE_ATTR(clk_stop_mode1);
+SLAVE_ATTR(simple_clk_stop_capable);
+SLAVE_ATTR(clk_stop_timeout);
+SLAVE_ATTR(ch_prep_timeout);
+SLAVE_ATTR(reset_behave);
+SLAVE_ATTR(high_PHY_capable);
+SLAVE_ATTR(paging_support);
+SLAVE_ATTR(bank_delay_support);
+SLAVE_ATTR(p15_behave);
+SLAVE_ATTR(master_count);
+SLAVE_ATTR(source_ports);
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
+
+	return sdw_slave_modalias(slave, buf, 256);
+}
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *slave_dev_attrs[] = {
+	&dev_attr_mipi_revision.attr,
+	&dev_attr_wake_capable.attr,
+	&dev_attr_test_mode_capable.attr,
+	&dev_attr_clk_stop_mode1.attr,
+	&dev_attr_simple_clk_stop_capable.attr,
+	&dev_attr_clk_stop_timeout.attr,
+	&dev_attr_ch_prep_timeout.attr,
+	&dev_attr_reset_behave.attr,
+	&dev_attr_high_PHY_capable.attr,
+	&dev_attr_paging_support.attr,
+	&dev_attr_bank_delay_support.attr,
+	&dev_attr_p15_behave.attr,
+	&dev_attr_master_count.attr,
+	&dev_attr_source_ports.attr,
+	&dev_attr_modalias.attr,
+	NULL,
+};
+
+static struct attribute_group sdw_slave_dev_attr_group = {
+	.attrs	= slave_dev_attrs,
+};
+
+const struct attribute_group *sdw_slave_dev_attr_groups[] = {
+	&sdw_slave_dev_attr_group,
+	NULL
+};
+
+int sdw_sysfs_slave_init(struct sdw_slave *slave)
+{
+	/* TODO: Initialize dp0 and dpn kobject and attribute */
+	return 0;
+}
+
+void sdw_sysfs_slave_exit(struct sdw_slave *slave)
+{
+}
diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
index 38c806cae2bf..299e15894860 100644
--- a/include/linux/soundwire/sdw.h
+++ b/include/linux/soundwire/sdw.h
@@ -362,6 +362,17 @@ int sdw_slave_read_dpn(struct sdw_slave *slave,
 		struct sdw_dpn_prop *dpn, int count, int ports, char *type);
 
 /*
+ * SDW sysfs APIs
+ */
+struct sdw_slave_sysfs;
+struct sdw_master_sysfs;
+
+int sdw_sysfs_bus_init(struct sdw_bus *bus);
+void sdw_sysfs_bus_exit(struct sdw_bus *bus);
+int sdw_sysfs_slave_init(struct sdw_slave *slave);
+void sdw_sysfs_slave_exit(struct sdw_slave *slave);
+
+/*
  * SDW Slave Structures and APIs
  */
 
@@ -421,6 +432,7 @@ struct sdw_slave_ops {
  * @bus: Bus handle
  * @ops: Slave callback ops
  * @prop: Slave properties
+ * @sysfs: Sysfs interface
  * @node: node for bus list
  * @port_ready: Port ready completion flag for each Slave port
  * @dev_num: Device Number assigned by Bus
@@ -432,6 +444,7 @@ struct sdw_slave {
 	struct sdw_bus *bus;
 	const struct sdw_slave_ops *ops;
 	struct sdw_slave_prop prop;
+	struct sdw_slave_sysfs *sysfs;
 	struct list_head node;
 	struct completion *port_ready;
 	u16 dev_num;
@@ -520,6 +533,7 @@ struct sdw_master_ops {
  * @msg_lock: message lock
  * @ops: Master callback ops
  * @prop: Master properties
+ * @sysfs: Bus sysfs
  * @defer_msg: Defer message
  * @clk_stop_timeout: Clock stop timeout computed
  */
@@ -532,6 +546,7 @@ struct sdw_bus {
 	struct mutex msg_lock;
 	const struct sdw_master_ops *ops;
 	struct sdw_master_prop prop;
+	struct sdw_master_sysfs *sysfs;
 	struct sdw_defer defer_msg;
 	unsigned int clk_stop_timeout;
 };
-- 
2.7.4

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

* [PATCH 11/14] soundwire: cdns: Add cadence module
  2017-10-19  3:03 ` Vinod Koul
                   ` (10 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  2017-10-21  9:52     ` Mark Brown
  -1 siblings, 1 reply; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

Cadence IP implements SoundWire Master. Add base cadence module
initialization and interrupt handling

Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Kconfig          |   3 +
 drivers/soundwire/Makefile         |   4 +
 drivers/soundwire/cadence_master.c | 470 +++++++++++++++++++++++++++++++++++++
 drivers/soundwire/cadence_master.h |  80 +++++++
 4 files changed, 557 insertions(+)
 create mode 100644 drivers/soundwire/cadence_master.c
 create mode 100644 drivers/soundwire/cadence_master.h

diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig
index d63295015331..677789cf4745 100644
--- a/drivers/soundwire/Kconfig
+++ b/drivers/soundwire/Kconfig
@@ -20,4 +20,7 @@ config SOUNDWIRE_BUS
 	default SOUNDWIRE
 	select REGMAP_SOUNDWIRE
 
+config SOUNDWIRE_CADENCE
+	tristate
+
 endif
diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index 67dc7b546258..f9a1ce3a860e 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -5,3 +5,7 @@
 #Bus Objs
 soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o sysfs.o
 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
+
+#Cadence Objs
+soundwire-cadence-objs := cadence_master.o
+obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
new file mode 100644
index 000000000000..fc287cca9579
--- /dev/null
+++ b/drivers/soundwire/cadence_master.c
@@ -0,0 +1,470 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * Cadence SoundWire Master module
+ * Used by Master driver
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/soundwire/sdw.h>
+#include "bus.h"
+#include "cadence_master.h"
+
+#define CDNS_MCP_CONFIG				0x0
+
+#define CDNS_MCP_CONFIG_MCMD_RETRY		GENMASK(27, 24)
+#define CDNS_MCP_CONFIG_MPREQ_DELAY		GENMASK(20, 16)
+#define CDNS_MCP_CONFIG_MMASTER			BIT(7)
+#define CDNS_MCP_CONFIG_BUS_REL			BIT(6)
+#define CDNS_MCP_CONFIG_SNIFFER			BIT(5)
+#define CDNS_MCP_CONFIG_SSPMOD			BIT(4)
+#define CDNS_MCP_CONFIG_CMD			BIT(3)
+#define CDNS_MCP_CONFIG_OP			GENMASK(2, 0)
+#define CDNS_MCP_CONFIG_OP_NORMAL		0
+
+#define CDNS_MCP_CONTROL			0x4
+
+#define CDNS_MCP_CONTROL_RST_DELAY		GENMASK(10, 8)
+#define CDNS_MCP_CONTROL_CMD_RST		BIT(7)
+#define CDNS_MCP_CONTROL_SOFT_RST		BIT(6)
+#define CDNS_MCP_CONTROL_SW_RST			BIT(5)
+#define CDNS_MCP_CONTROL_HW_RST			BIT(4)
+#define CDNS_MCP_CONTROL_CLK_PAUSE		BIT(3)
+#define CDNS_MCP_CONTROL_CLK_STOP_CLR		BIT(2)
+#define CDNS_MCP_CONTROL_CMD_ACCEPT		BIT(1)
+#define CDNS_MCP_CONTROL_BLOCK_WAKEUP		BIT(0)
+
+
+#define CDNS_MCP_CMDCTRL			0x8
+#define CDNS_MCP_SSPSTAT			0xC
+#define CDNS_MCP_FRAME_SHAPE			0x10
+#define CDNS_MCP_FRAME_SHAPE_INIT		0x14
+
+#define CDNS_MCP_CONFIG_UPDATE			0x18
+#define CDNS_MCP_CONFIG_UPDATE_BIT		BIT(0)
+
+#define CDNS_MCP_PHYCTRL			0x1C
+#define CDNS_MCP_SSP_CTRL0			0x20
+#define CDNS_MCP_SSP_CTRL1			0x28
+#define CDNS_MCP_CLK_CTRL0			0x30
+#define CDNS_MCP_CLK_CTRL1			0x38
+
+#define CDNS_MCP_STAT				0x40
+
+#define CDNS_MCP_STAT_ACTIVE_BANK		BIT(20)
+#define CDNS_MCP_STAT_CLK_STOP			BIT(16)
+
+#define CDNS_MCP_INTSTAT			0x44
+#define CDNS_MCP_INTMASK			0x48
+
+#define CDNS_MCP_INT_IRQ			BIT(31)
+#define CDNS_MCP_INT_WAKEUP			BIT(16)
+#define CDNS_MCP_INT_SLAVE_RSVD			BIT(15)
+#define CDNS_MCP_INT_SLAVE_ALERT		BIT(14)
+#define CDNS_MCP_INT_SLAVE_ATTACH		BIT(13)
+#define CDNS_MCP_INT_SLAVE_NATTACH		BIT(12)
+#define CDNS_MCP_INT_SLAVE_MASK			GENMASK(15, 12)
+#define CDNS_MCP_INT_DPINT			BIT(11)
+#define CDNS_MCP_INT_CTRL_CLASH			BIT(10)
+#define CDNS_MCP_INT_DATA_CLASH			BIT(9)
+#define CDNS_MCP_INT_CMD_ERR			BIT(7)
+#define CDNS_MCP_INT_RX_WL			BIT(2)
+#define CDNS_MCP_INT_TXE			BIT(1)
+
+#define CDNS_MCP_INTSET				0x4C
+
+#define CDNS_SDW_SLAVE_STAT			0x50
+#define CDNS_MCP_SLAVE_STAT_MASK		BIT(1, 0)
+
+#define CDNS_MCP_SLAVE_INTSTAT0			0x54
+#define CDNS_MCP_SLAVE_INTSTAT1			0x58
+#define CDNS_MCP_SLAVE_INTSTAT_NPRESENT		BIT(0)
+#define CDNS_MCP_SLAVE_INTSTAT_ATTACHED		BIT(1)
+#define CDNS_MCP_SLAVE_INTSTAT_ALERT		BIT(2)
+#define CDNS_MCP_SLAVE_INTSTAT_RESERVED		BIT(3)
+#define CDNS_MCP_SLAVE_STATUS_BITS		GENMASK(3, 0)
+#define CDNS_MCP_SLAVE_STATUS_NUM		4
+
+#define CDNS_MCP_SLAVE_INTMASK0			0x5C
+#define CDNS_MCP_SLAVE_INTMASK1			0x60
+
+#define CDNS_MCP_SLAVE_INTMASK0_MASK		GENMASK(30, 0)
+#define CDNS_MCP_SLAVE_INTMASK1_MASK		GENMASK(16, 0)
+
+#define CDNS_MCP_PORT_INTSTAT			0x64
+#define CDNS_MCP_PDI_STAT			0x6C
+
+#define CDNS_MCP_FIFOLEVEL			0x78
+#define CDNS_MCP_FIFOSTAT			0x7C
+#define CDNS_MCP_RX_FIFO_AVAIL			GENMASK(5, 0)
+
+#define CDNS_MCP_CMD_BASE			0x80
+#define CDNS_MCP_RESP_BASE			0x80
+#define CDNS_MCP_CMD_LEN			0x20
+#define CDNS_MCP_CMD_WORD_LEN			0x4
+
+#define CDNS_MCP_CMD_SSP_TAG			BIT(31)
+#define CDNS_MCP_CMD_COMMAND			GENMASK(30, 28)
+#define CDNS_MCP_CMD_DEV_ADDR			GENMASK(27, 24)
+#define CDNS_MCP_CMD_REG_ADDR_H			GENMASK(23, 16)
+#define CDNS_MCP_CMD_REG_ADDR_L			GENMASK(15, 8)
+#define CDNS_MCP_CMD_REG_DATA			GENMASK(7, 0)
+
+#define CDNS_MCP_CMD_READ			2
+#define CDNS_MCP_CMD_WRITE			3
+
+#define CDNS_MCP_RESP_RDATA			GENMASK(15, 8)
+#define CDNS_MCP_RESP_ACK			BIT(0)
+#define CDNS_MCP_RESP_NACK			BIT(1)
+
+#define CDNS_DP_SIZE				128
+
+#define CDNS_DPN_B0_CONFIG(n)			(0x100 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B0_CH_EN(n)			(0x104 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B0_SAMPLE_CTRL(n)		(0x108 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B0_OFFSET_CTRL(n)		(0x10C + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B0_HCTRL(n)			(0x110 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B0_ASYNC_CTRL(n)		(0x114 + CDNS_DP_SIZE * (n))
+
+#define CDNS_DPN_B1_CONFIG(n)			(0x118 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B1_CH_EN(n)			(0x11C + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B1_SAMPLE_CTRL(n)		(0x120 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B1_OFFSET_CTRL(n)		(0x124 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B1_HCTRL(n)			(0x128 + CDNS_DP_SIZE * (n))
+#define CDNS_DPN_B1_ASYNC_CTRL(n)		(0x12C + CDNS_DP_SIZE * (n))
+
+#define CDNS_DPN_CONFIG_BPM			BIT(18)
+#define CDNS_DPN_CONFIG_BGC			GENMASK(17, 16)
+#define CDNS_DPN_CONFIG_WL			GENMASK(12, 8)
+#define CDNS_DPN_CONFIG_PORT_DAT		GENMASK(3, 2)
+#define CDNS_DPN_CONFIG_PORT_FLOW		GENMASK(1, 0)
+
+#define CDNS_DPN_SAMPLE_CTRL_SI			GENMASK(15, 0)
+
+#define CDNS_DPN_OFFSET_CTRL_1			GENMASK(7, 0)
+#define CDNS_DPN_OFFSET_CTRL_2			GENMASK(15, 8)
+
+#define CDNS_DPN_HCTRL_HSTOP			GENMASK(3, 0)
+#define CDNS_DPN_HCTRL_HSTART			GENMASK(7, 4)
+#define CDNS_DPN_HCTRL_LCTRL			GENMASK(10, 8)
+
+#define CDNS_PORTCTRL				0x130
+#define CDNS_PORTCTRL_DIRN			BIT(7)
+#define CDNS_PORTCTRL_BANK_INVERT		BIT(8)
+
+#define CDNS_PORT_OFFSET			0x80
+
+#define CDNS_PDI_CONFIG(n)			(0x1100 + (n) * 16)
+
+#define CDNS_PDI_CONFIG_SOFT_RESET		BIT(24)
+#define CDNS_PDI_CONFIG_CHANNEL			GENMASK(15, 8)
+#define CDNS_PDI_CONFIG_PORT			GENMASK(4, 0)
+
+/* Driver defaults */
+
+#define CDNS_DEFAULT_CLK_DIVIDER		0
+#define CDNS_DEFAULT_FRAME_SHAPE		0x30
+#define CDNS_DEFAULT_SSP_INTERVAL		0x18
+#define CDNS_TX_TIMEOUT				2000
+
+#define CDNS_PCM_PDI_OFFSET			0x2
+#define CDNS_PDM_PDI_OFFSET			0x6
+
+#define CDNS_SCP_RX_FIFOLEVEL			0x2
+
+/*
+ * register accessor helpers
+ */
+static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
+{
+	return readl(cdns->registers + offset);
+}
+
+static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
+{
+	writel(value, cdns->registers + offset);
+}
+
+static inline void cdns_updatel(struct sdw_cdns *cdns,
+				int offset, u32 mask, u32 val)
+{
+	u32 tmp;
+
+	tmp = cdns_readl(cdns, offset);
+	tmp = (tmp & ~mask) | val;
+	cdns_writel(cdns, offset, tmp);
+}
+
+static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
+{
+	int timeout = 10;
+	u32 reg_read;
+
+	writel(value, cdns->registers + offset);
+
+	/* Wait for bit to be self cleared */
+	do {
+		reg_read = readl(cdns->registers + offset);
+		if ((reg_read & value) == 0)
+			return 0;
+
+		timeout--;
+		usleep_range(1, 50);
+	} while (timeout != 0);
+
+	return -EIO;
+}
+
+/*
+ * IRQ handling
+ */
+
+static int cdns_update_slave_status(struct sdw_cdns *cdns,
+					u32 slave0, u32 slave1)
+{
+	enum sdw_slave_status status[SDW_MAX_DEVICES];
+	bool is_slave = false;
+	u64 slave, mask;
+	int i, set_status;
+
+	/* combine the two status */
+	slave = ((u64)slave1 << 32) | slave0;
+	memset(status, 0, sizeof(status));
+
+	for (i = 0; i <= SDW_MAX_DEVICES; i++) {
+		mask = (slave >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
+				CDNS_MCP_SLAVE_STATUS_BITS;
+		if (!mask)
+			continue;
+
+		is_slave = true;
+		set_status = 0;
+
+		if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
+			status[i] = SDW_SLAVE_RESERVED;
+			dev_err(cdns->dev,
+				"Slave %d reports RESERVED status", i);
+			set_status++;
+		}
+
+		if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
+			status[i] = SDW_SLAVE_ATTACHED;
+			set_status++;
+		}
+
+		if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
+			status[i] = SDW_SLAVE_ALERT;
+			set_status++;
+		}
+
+		if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
+			status[i] = SDW_SLAVE_UNATTACHED;
+			set_status++;
+		}
+
+		/* first check if Slave reported multiple status */
+		if (set_status > 1) {
+			dev_warn(cdns->dev,
+					"Slave reported multiple Status: %d\n",
+					status[i]);
+			/*
+			 * TODO: we need to reread the status here by
+			 * issuing a PING cmd, now clear this status
+			 */
+			status[i] = 0;
+		}
+	}
+
+	if (is_slave)
+		return sdw_handle_slave_status(&cdns->bus, status);
+
+	return 0;
+}
+
+irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
+{
+	struct sdw_cdns *cdns = dev_id;
+	u32 int_status;
+	int ret = IRQ_HANDLED;
+
+	/* Check if the link is up */
+	if (!cdns->link_up)
+		return IRQ_NONE;
+
+	int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
+
+	if (!(int_status & CDNS_MCP_INT_IRQ))
+		return IRQ_NONE;
+
+	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
+
+		/* Slave is driving bit slot during control word */
+		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
+		int_status |= CDNS_MCP_INT_CTRL_CLASH;
+	}
+
+	if (int_status & CDNS_MCP_INT_DATA_CLASH) {
+		/*
+		 * Multiple slaves trying to drive bit slot, or issue with
+		 * ownership of data bits or Slave gone bonkers
+		 */
+		dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
+		int_status |= CDNS_MCP_INT_DATA_CLASH;
+	}
+
+	if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
+		/* Mask the Slave interrupt and wake thread */
+		cdns_updatel(cdns, CDNS_MCP_INTMASK,
+				CDNS_MCP_INT_SLAVE_MASK, 0);
+
+		int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
+	return ret;
+}
+EXPORT_SYMBOL(sdw_cdns_irq);
+
+irqreturn_t sdw_cdns_thread(int irq, void *dev_id)
+{
+	struct sdw_cdns *cdns = dev_id;
+	u32 slave0, slave1;
+
+	dev_dbg(cdns->dev, "Slave status change\n");
+
+	slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
+	slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
+
+	cdns_update_slave_status(cdns, slave0, slave1);
+	cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
+	cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
+
+	/* clear and unmask Slave interrupt now */
+	cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
+	cdns_updatel(cdns, CDNS_MCP_INTMASK,
+			CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
+
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(sdw_cdns_thread);
+
+/*
+ * init routines
+ */
+
+/**
+ * sdw_cdns_init: Cadence initialization
+ *
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_init(struct sdw_cdns *cdns)
+{
+	u32 val;
+	int ret;
+
+	/* Exit clock stop */
+	ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
+			CDNS_MCP_CONTROL_CLK_STOP_CLR);
+	if (ret < 0) {
+		dev_err(cdns->dev, "Couldn't exit from clock stop\n");
+		return ret;
+	}
+
+	/* Set clock divider */
+	val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
+	val |= CDNS_DEFAULT_CLK_DIVIDER;
+	cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
+
+	/* Set the default frame shape */
+	cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE);
+
+	/* Set SSP interval to default value */
+	cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
+	cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
+
+	/* Set cmd accept mode */
+	cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
+					CDNS_MCP_CONTROL_CMD_ACCEPT);
+
+	/* Configure mcp config */
+	val = cdns_readl(cdns, CDNS_MCP_CONFIG);
+
+	/* Set Max cmd retry to 15 */
+	val |= CDNS_MCP_CONFIG_MCMD_RETRY;
+
+	/* Set frame delay between PREQ and ping frame to 15 frames */
+	val |= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY);
+
+	/* Disable auto bus release */
+	val &= ~CDNS_MCP_CONFIG_BUS_REL;
+
+	/* Disable sniffer mode */
+	val &= ~CDNS_MCP_CONFIG_SNIFFER;
+
+	/* Set cmd mode for Tx and Rx cmds */
+	val &= ~CDNS_MCP_CONFIG_CMD;
+
+	/* Set operation to normal */
+	val &= ~CDNS_MCP_CONFIG_OP;
+	val |= CDNS_MCP_CONFIG_OP_NORMAL;
+
+	cdns_writel(cdns, CDNS_MCP_CONFIG, val);
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_cdns_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("Cadence Soundwire Library");
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
new file mode 100644
index 000000000000..9fafd74bc13b
--- /dev/null
+++ b/drivers/soundwire/cadence_master.h
@@ -0,0 +1,80 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __SDW_CADENCE_H
+#define __SDW_CADENCE_H
+
+/**
+ * struct sdw_cdns: Cadence driver context
+ *
+ * @dev: Linux device
+ * @bus: Bus handle
+ * @instance: instance number
+ * @registers: Cadence registers
+ * @link_up: Link status
+ */
+struct sdw_cdns {
+	struct device *dev;
+	struct sdw_bus bus;
+	unsigned int instance;
+
+	void __iomem *registers;
+
+	bool link_up;
+};
+
+#define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
+
+/* Exported symbols */
+
+irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
+irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
+
+int sdw_cdns_init(struct sdw_cdns *cdns);
+
+#endif /* __SDW_CADENCE_H */
-- 
2.7.4

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

* [PATCH 12/14] soundwire: cdns: Add sdw_master_ops and IO transfer support
  2017-10-19  3:03 ` Vinod Koul
                   ` (11 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

From: Sanyog Kale <sanyog.r.kale@intel.com>

Implement sdw_master_ops with support for xfer_msg, xfer_msg_defer and
reset_page_addr. Since Cadence module doesn't know the systems it will be
used, set the read_prop to the bus helper.

Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/cadence_master.c | 323 +++++++++++++++++++++++++++++++++++++
 drivers/soundwire/cadence_master.h |  14 ++
 2 files changed, 337 insertions(+)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index fc287cca9579..638f4f8165d7 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -267,9 +267,262 @@ static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
 }
 
 /*
+ * IO Calls
+ */
+static enum sdw_command_response cdns_fill_msg_resp(
+			struct sdw_cdns *cdns,
+			struct sdw_msg *msg, int count, int offset)
+{
+	int nack = 0, no_ack = 0;
+	int i;
+
+	/* check message response */
+	for (i = 0; i < count; i++) {
+		if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
+			no_ack = 1;
+			dev_dbg(cdns->dev, "Msg Ack not received\n");
+			if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
+				nack = 1;
+				dev_err(cdns->dev, "Msg NACK received\n");
+			}
+		}
+	}
+
+	if (nack) {
+		dev_err(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
+		return SDW_CMD_FAIL;
+	} else if (no_ack) {
+		dev_dbg(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
+		return SDW_CMD_IGNORED;
+	}
+
+	/* fill response */
+	for (i = 0; i < count; i++)
+		msg->buf[i + offset] = cdns->response_buf[i] >>
+				SDW_REG_SHIFT(CDNS_MCP_RESP_RDATA);
+
+	return SDW_CMD_OK;
+}
+
+static enum sdw_command_response
+_cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
+				int offset, int count, bool defer)
+{
+	unsigned long time;
+	u32 base, i, data;
+	u16 addr;
+
+	/* Program the watermark level for RX FIFO */
+	if (cdns->msg_count != count) {
+		cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
+		cdns->msg_count = count;
+	}
+
+	base = CDNS_MCP_CMD_BASE;
+	addr = msg->addr;
+
+	for (i = 0; i < count; i++) {
+		data = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
+		data |= cmd << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
+		data |= addr++  << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
+
+		if (msg->flags == SDW_MSG_FLAG_WRITE)
+			data |= msg->buf[i + offset];
+
+		data |= msg->ssp_sync << SDW_REG_SHIFT(CDNS_MCP_CMD_SSP_TAG);
+		cdns_writel(cdns, base, data);
+		base += CDNS_MCP_CMD_WORD_LEN;
+	}
+
+	if (defer)
+		return SDW_CMD_OK;
+
+	/* wait for timeout or response */
+	time = wait_for_completion_timeout(&cdns->tx_complete,
+				msecs_to_jiffies(CDNS_TX_TIMEOUT));
+	if (!time) {
+		dev_err(cdns->dev, "IO transfer timed out\n");
+		msg->len = 0;
+		return SDW_CMD_TIMEOUT;
+	}
+
+	return cdns_fill_msg_resp(cdns, msg, count, offset);
+}
+
+static enum sdw_command_response cdns_program_scp_addr(
+			struct sdw_cdns *cdns, struct sdw_msg *msg)
+{
+	int nack = 0, no_ack = 0;
+	unsigned long time;
+	u32 data[2], base;
+	int i;
+
+	/* Program the watermark level for RX FIFO */
+	if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
+		cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
+		cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
+	}
+
+	data[0] = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
+	data[0] |= 0x3 << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
+	data[1] = data[0];
+
+	data[0] |= SDW_SCP_ADDRPAGE1 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
+	data[1] |= SDW_SCP_ADDRPAGE2 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
+
+	data[0] |= msg->addr_page1;
+	data[1] |= msg->addr_page2;
+
+	base = CDNS_MCP_CMD_BASE;
+	cdns_writel(cdns, base, data[0]);
+	base += CDNS_MCP_CMD_WORD_LEN;
+	cdns_writel(cdns, base, data[1]);
+
+	time = wait_for_completion_timeout(&cdns->tx_complete,
+				msecs_to_jiffies(CDNS_TX_TIMEOUT));
+	if (!time) {
+		dev_err(cdns->dev, "SCP Msg trf timed out\n");
+		msg->len = 0;
+		return SDW_CMD_TIMEOUT;
+	}
+
+	/* check response the writes */
+	for (i = 0; i < 2; i++) {
+		if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
+			no_ack = 1;
+			dev_err(cdns->dev, "Program SCP Ack not received");
+			if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
+				nack = 1;
+				dev_err(cdns->dev, "Program SCP NACK received");
+			}
+		}
+	}
+
+	/* For NACK, NO ack, don't return err if we are in Broadcast mode */
+	if (nack) {
+		dev_err(cdns->dev,
+			"SCP_addrpage NACKed for Slave %d", msg->dev_num);
+		return SDW_CMD_FAIL;
+	} else if (no_ack) {
+		dev_dbg(cdns->dev,
+			"SCP_addrpage ignored for Slave %d", msg->dev_num);
+		return SDW_CMD_IGNORED;
+	}
+
+	return SDW_CMD_OK;
+}
+
+static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg,
+						int page, int *cmd)
+{
+	int ret;
+
+	if (page) {
+		ret = cdns_program_scp_addr(cdns, msg);
+		if (ret) {
+			msg->len = 0;
+			return ret;
+		}
+	}
+
+	switch (msg->flags) {
+	case SDW_MSG_FLAG_READ:
+		*cmd = CDNS_MCP_CMD_READ;
+		break;
+
+	case SDW_MSG_FLAG_WRITE:
+		*cmd = CDNS_MCP_CMD_WRITE;
+		break;
+
+	default:
+		dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum sdw_command_response
+cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg, int page)
+{
+	struct sdw_cdns *cdns = bus_to_cdns(bus);
+	int cmd = 0, ret, i;
+
+	ret = cdns_prep_msg(cdns, msg, page, &cmd);
+	if (ret)
+		return SDW_CMD_FAIL_OTHER;
+
+	for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
+		ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
+				CDNS_MCP_CMD_LEN, false);
+		if (ret < 0)
+			goto exit;
+	}
+
+	if (!(msg->len % CDNS_MCP_CMD_LEN))
+		goto exit;
+
+	ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
+			msg->len % CDNS_MCP_CMD_LEN, false);
+
+exit:
+	return ret;
+}
+
+static enum sdw_command_response
+cdns_xfer_msg_defer(struct sdw_bus *bus, struct sdw_msg *msg,
+				int page, struct sdw_defer *defer)
+{
+	struct sdw_cdns *cdns = bus_to_cdns(bus);
+	int cmd = 0, ret;
+
+	/* for defer only 1 message is supported */
+	if (msg->len > 1)
+		return -ENOTSUPP;
+
+	ret = cdns_prep_msg(cdns, msg, page, &cmd);
+	if (ret)
+		return SDW_CMD_FAIL_OTHER;
+
+	cdns->defer = defer;
+	cdns->defer->length = msg->len;
+
+	return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
+}
+
+static enum sdw_command_response
+cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
+{
+	struct sdw_cdns *cdns = bus_to_cdns(bus);
+	struct sdw_msg msg;
+
+	/* Create dummy message with valid device number */
+	memset(&msg, 0, sizeof(msg));
+	msg.dev_num = dev_num;
+
+	return cdns_program_scp_addr(cdns, &msg);
+}
+
+/*
  * IRQ handling
  */
 
+static void cdns_read_response(struct sdw_cdns *cdns)
+{
+	u32 num_resp, cmd_base;
+	int i;
+
+	num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
+	num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
+
+	cmd_base = CDNS_MCP_CMD_BASE;
+
+	for (i = 0; i < num_resp; i++) {
+		cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
+		cmd_base += CDNS_MCP_CMD_WORD_LEN;
+	}
+}
+
 static int cdns_update_slave_status(struct sdw_cdns *cdns,
 					u32 slave0, u32 slave1)
 {
@@ -347,6 +600,18 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
 	if (!(int_status & CDNS_MCP_INT_IRQ))
 		return IRQ_NONE;
 
+	if (int_status & CDNS_MCP_INT_RX_WL) {
+		cdns_read_response(cdns);
+
+		if (cdns->defer) {
+			cdns_fill_msg_resp(cdns, cdns->defer->msg,
+					cdns->defer->length, 0);
+			complete(&cdns->defer->complete);
+			cdns->defer = NULL;
+		} else
+			complete(&cdns->tx_complete);
+	}
+
 	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
 
 		/* Slave is driving bit slot during control word */
@@ -403,6 +668,43 @@ EXPORT_SYMBOL(sdw_cdns_thread);
 /*
  * init routines
  */
+static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
+{
+	u32 mask;
+
+	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
+				CDNS_MCP_SLAVE_INTMASK0_MASK);
+	cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
+				CDNS_MCP_SLAVE_INTMASK1_MASK);
+
+	mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
+		CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH |
+		CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
+		CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT;
+
+	cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
+
+	return 0;
+}
+
+/**
+ * sdw_cdns_enable_interrupt: Enable SDW interrupts and update config
+ *
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
+{
+	int ret;
+
+	_cdns_enable_interrupt(cdns);
+	ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
+			CDNS_MCP_CONFIG_UPDATE_BIT);
+	if (ret < 0)
+		dev_err(cdns->dev, "Config update timedout");
+
+	return ret;
+}
+EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
 
 /**
  * sdw_cdns_init: Cadence initialization
@@ -466,5 +768,26 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 }
 EXPORT_SYMBOL(sdw_cdns_init);
 
+struct sdw_master_ops sdw_cdns_master_ops = {
+	.read_prop = sdw_master_read_prop,
+	.xfer_msg = cdns_xfer_msg,
+	.xfer_msg_defer = cdns_xfer_msg_defer,
+	.reset_page_addr = cdns_reset_page_addr,
+};
+EXPORT_SYMBOL(sdw_cdns_master_ops);
+
+/**
+ * sdw_cdns_probe: Cadence probe routine
+ *
+ * @cdns: Cadence instance
+ */
+int sdw_cdns_probe(struct sdw_cdns *cdns)
+{
+	init_completion(&cdns->tx_complete);
+
+	return 0;
+}
+EXPORT_SYMBOL(sdw_cdns_probe);
+
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_DESCRIPTION("Cadence Soundwire Library");
diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h
index 9fafd74bc13b..15c6cb0e11cd 100644
--- a/drivers/soundwire/cadence_master.h
+++ b/drivers/soundwire/cadence_master.h
@@ -55,26 +55,40 @@
  * @dev: Linux device
  * @bus: Bus handle
  * @instance: instance number
+ * @response_buf: SoundWire response buffer
+ * @tx_complete: Tx completion
+ * @defer: Defer pointer
  * @registers: Cadence registers
  * @link_up: Link status
+ * @msg_count: Messages sent on bus
  */
 struct sdw_cdns {
 	struct device *dev;
 	struct sdw_bus bus;
 	unsigned int instance;
 
+	u32 response_buf[0x80];
+	struct completion tx_complete;
+	struct sdw_defer *defer;
+
 	void __iomem *registers;
 
 	bool link_up;
+	unsigned int msg_count;
 };
 
 #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
 
 /* Exported symbols */
 
+int sdw_cdns_probe(struct sdw_cdns *cdns);
+extern struct sdw_master_ops sdw_cdns_master_ops;
+
 irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
 irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
 
 int sdw_cdns_init(struct sdw_cdns *cdns);
+int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns);
+
 
 #endif /* __SDW_CADENCE_H */
-- 
2.7.4

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

* [PATCH 13/14] soundwire: intel: Add Intel Master driver
  2017-10-19  3:03 ` Vinod Koul
                   ` (12 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

Some Intel platforms have SoundWire Master, so add Intel SoundWire
Master driver which uses Cadence module. This patch adds probe and
initialization routines for Intel Master driver.

Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Kconfig           |  11 +
 drivers/soundwire/Makefile          |   4 +
 drivers/soundwire/intel.c           | 395 ++++++++++++++++++++++++++++++++++++
 drivers/soundwire/intel.h           |  70 +++++++
 include/linux/soundwire/sdw_intel.h |  69 +++++++
 5 files changed, 549 insertions(+)
 create mode 100644 drivers/soundwire/intel.c
 create mode 100644 drivers/soundwire/intel.h
 create mode 100644 include/linux/soundwire/sdw_intel.h

diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig
index 677789cf4745..8ce6b9ebaded 100644
--- a/drivers/soundwire/Kconfig
+++ b/drivers/soundwire/Kconfig
@@ -23,4 +23,15 @@ config SOUNDWIRE_BUS
 config SOUNDWIRE_CADENCE
 	tristate
 
+config SOUNDWIRE_INTEL
+	tristate "Intel SoundWire Master driver"
+	select SOUNDWIRE_CADENCE
+	select SOUNDWIRE_BUS
+	depends on X86 && ACPI
+	---help---
+	  SoundWire Intel Master driver.
+	  If you have an Intel platform which has a SoundWire Master then
+	  enable this config option to get the SoundWire support for that
+	  device.
+
 endif
diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index f9a1ce3a860e..0813b2c74426 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -9,3 +9,7 @@ obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
 #Cadence Objs
 soundwire-cadence-objs := cadence_master.o
 obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o
+
+#Intel driver
+soundwire-intel-objs :=	intel.o
+obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o
diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
new file mode 100644
index 000000000000..c92847dad5cd
--- /dev/null
+++ b/drivers/soundwire/intel.c
@@ -0,0 +1,395 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * Soundwire Intel Master Driver
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_intel.h>
+#include "cadence_master.h"
+#include "intel.h"
+
+/* Intel SHIM Registers Definition */
+#define SDW_SHIM_LCAP			0x0
+#define SDW_SHIM_LCTL			0x4
+#define SDW_SHIM_IPPTR			0x8
+#define SDW_SHIM_SYNC			0xC
+
+#define SDW_SHIM_CTLSCAP(x)		(0x010 + 0x60 * x)
+#define SDW_SHIM_CTLS0CM(x)		(0x012 + 0x60 * x)
+#define SDW_SHIM_CTLS1CM(x)		(0x014 + 0x60 * x)
+#define SDW_SHIM_CTLS2CM(x)		(0x016 + 0x60 * x)
+#define SDW_SHIM_CTLS3CM(x)		(0x018 + 0x60 * x)
+#define SDW_SHIM_PCMSCAP(x)		(0x020 + 0x60 * x)
+
+#define SDW_SHIM_PCMSYCHM(x, y)		(0x022 + (0x60 * x) + (0x2 * y))
+#define SDW_SHIM_PCMSYCHC(x, y)		(0x042 + (0x60 * x) + (0x2 * y))
+#define SDW_SHIM_PDMSCAP(x)		(0x062 + 0x60 * x)
+#define SDW_SHIM_IOCTL(x)		(0x06C + 0x60 * x)
+#define SDW_SHIM_CTMCTL(x)		(0x06E + 0x60 * x)
+
+#define SDW_SHIM_WAKEEN			0x190
+#define SDW_SHIM_WAKESTS		0x192
+
+#define SDW_SHIM_LCTL_SPA		BIT(0)
+#define SDW_SHIM_LCTL_CPA		BIT(8)
+
+#define SDW_SHIM_SYNC_SYNCPRD_VAL	0x176F
+#define SDW_SHIM_SYNC_SYNCPRD		GENMASK(14, 0)
+#define SDW_SHIM_SYNC_SYNCCPU		BIT(15)
+#define SDW_SHIM_SYNC_CMDSYNC_MASK	GENMASK(19, 16)
+#define SDW_SHIM_SYNC_CMDSYNC		BIT(16)
+#define SDW_SHIM_SYNC_SYNCGO		BIT(24)
+
+#define SDW_SHIM_PCMSCAP_ISS		GENMASK(3, 0)
+#define SDW_SHIM_PCMSCAP_OSS		GENMASK(7, 4)
+#define SDW_SHIM_PCMSCAP_BSS		GENMASK(12, 8)
+
+#define SDW_SHIM_PCMSYCM_LCHN		GENMASK(3, 0)
+#define SDW_SHIM_PCMSYCM_HCHN		GENMASK(7, 4)
+#define SDW_SHIM_PCMSYCM_STREAM		GENMASK(13, 8)
+#define SDW_SHIM_PCMSYCM_DIR		BIT(15)
+
+#define SDW_SHIM_PDMSCAP_ISS		GENMASK(3, 0)
+#define SDW_SHIM_PDMSCAP_OSS		GENMASK(7, 4)
+#define SDW_SHIM_PDMSCAP_BSS		GENMASK(12, 8)
+#define SDW_SHIM_PDMSCAP_CPSS		GENMASK(15, 13)
+
+#define SDW_SHIM_IOCTL_MIF		BIT(0)
+#define SDW_SHIM_IOCTL_CO		BIT(1)
+#define SDW_SHIM_IOCTL_COE		BIT(2)
+#define SDW_SHIM_IOCTL_DO		BIT(3)
+#define SDW_SHIM_IOCTL_DOE		BIT(4)
+#define SDW_SHIM_IOCTL_BKE		BIT(5)
+#define SDW_SHIM_IOCTL_WPDD		BIT(6)
+#define SDW_SHIM_IOCTL_CIBD		BIT(8)
+#define SDW_SHIM_IOCTL_DIBD		BIT(9)
+
+#define SDW_SHIM_CTMCTL_DACTQE		BIT(0)
+#define SDW_SHIM_CTMCTL_DODS		BIT(1)
+#define SDW_SHIM_CTMCTL_DOAIS		GENMASK(4, 3)
+
+#define SDW_SHIM_WAKEEN_ENABLE		BIT(0)
+#define SDW_SHIM_WAKESTS_STATUS		BIT(0)
+
+/* Intel ALH Register definitions */
+#define SDW_ALH_STRMZCFG(x)		(0x000 + (0x4 * x))
+
+#define SDW_ALH_STRMZCFG_DMAT_VAL	0x3
+#define SDW_ALH_STRMZCFG_DMAT		GENMASK(7, 0)
+#define SDW_ALH_STRMZCFG_CHN		GENMASK(19, 16)
+
+struct sdw_intel {
+	struct sdw_cdns cdns;
+	int instance;
+	struct sdw_intel_link_res *res;
+};
+
+#define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
+
+/*
+ * Read, write helpers for HW registers
+ */
+static inline int sdw_readl(void __iomem *base, int offset)
+{
+	return readl(base + offset);
+}
+
+static inline void sdw_writel(void __iomem *base, int offset, int value)
+{
+	writel(value, base + offset);
+}
+
+static inline u16 sdw_readw(void __iomem *base, int offset)
+{
+	return readw(base + offset);
+}
+
+static inline void sdw_writew(void __iomem *base, int offset, u16 value)
+{
+	writew(value, base + offset);
+}
+
+static int sdw_clear_bit(void __iomem *base, int offset, u32 value, u32 mask)
+{
+	int timeout = 10;
+	u32 reg_read;
+
+	writel(value, base + offset);
+	do {
+		reg_read = readl(base + offset);
+		if (!(reg_read & mask))
+			return 0;
+
+		timeout--;
+		usleep_range(1, 50);
+
+	} while (timeout != 0);
+
+	return -EAGAIN;
+}
+
+static int sdw_set_bit(void __iomem *base, int offset, u32 value, u32 mask)
+{
+	int timeout = 10;
+	u32 reg_read;
+
+	writel(value, base + offset);
+	do {
+		reg_read = readl(base + offset);
+		if (reg_read & mask)
+			return 0;
+
+		timeout--;
+		usleep_range(1, 50);
+
+	} while (timeout != 0);
+
+	return -EAGAIN;
+}
+
+/*
+ * shim ops
+ */
+
+static int intel_link_power_up(struct sdw_intel *sdw)
+{
+	unsigned int link_id = sdw->instance;
+	void __iomem *shim = sdw->res->shim;
+	int spa_mask, cpa_mask;
+	int link_control, ret;
+
+	/* Link power up sequence */
+	link_control = sdw_readl(shim, SDW_SHIM_LCTL);
+	spa_mask = (SDW_SHIM_LCTL_SPA << link_id);
+	cpa_mask = (SDW_SHIM_LCTL_SPA << link_id);
+	link_control |=  spa_mask;
+
+	ret = sdw_set_bit(shim, SDW_SHIM_LCTL, link_control, cpa_mask);
+	if (ret < 0)
+		return ret;
+
+	sdw->cdns.link_up = true;
+	return 0;
+}
+
+static int intel_shim_init(struct sdw_intel *sdw)
+{
+	void __iomem *shim = sdw->res->shim;
+	unsigned int link_id = sdw->instance;
+	int sync_reg, ret;
+	u16 ioctl = 0, act = 0;
+
+	/* Initialize Shim */
+	ioctl |= SDW_SHIM_IOCTL_BKE;
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl |= SDW_SHIM_IOCTL_WPDD;
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl |= SDW_SHIM_IOCTL_DO;
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl |= SDW_SHIM_IOCTL_DOE;
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	/* Switch to MIP from Glue logic */
+	ioctl = sdw_readw(shim,  SDW_SHIM_IOCTL(link_id));
+
+	ioctl &= ~(SDW_SHIM_IOCTL_DOE);
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl &= ~(SDW_SHIM_IOCTL_DO);
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl |= (SDW_SHIM_IOCTL_MIF);
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	ioctl &= ~(SDW_SHIM_IOCTL_BKE);
+	ioctl &= ~(SDW_SHIM_IOCTL_COE);
+
+	sdw_writew(shim, SDW_SHIM_IOCTL(link_id), ioctl);
+
+	act |= 0x1 << SDW_REG_SHIFT(SDW_SHIM_CTMCTL_DOAIS);
+	act |= SDW_SHIM_CTMCTL_DACTQE;
+	act |= SDW_SHIM_CTMCTL_DODS;
+	sdw_writew(shim, SDW_SHIM_CTMCTL(link_id), act);
+
+	/* Now set SyncPRD period */
+	sync_reg = sdw_readl(shim, SDW_SHIM_SYNC);
+	sync_reg |= (SDW_SHIM_SYNC_SYNCPRD_VAL <<
+			SDW_REG_SHIFT(SDW_SHIM_SYNC_SYNCPRD));
+
+	/* Set SyncCPU bit */
+	sync_reg |= SDW_SHIM_SYNC_SYNCCPU;
+	ret = sdw_clear_bit(shim, SDW_SHIM_SYNC, sync_reg,
+				SDW_SHIM_SYNC_SYNCCPU);
+	if (ret < 0)
+		dev_err(sdw->cdns.dev, "Failed to set sync period: %d", ret);
+
+	return ret;
+}
+
+static int intel_prop_read(struct sdw_bus *bus)
+{
+	/* Initialize with default handler to read all DisCo properties */
+	sdw_master_read_prop(bus);
+
+	/* BIOS is not giving some values correctly. So, lets override them */
+	bus->prop.num_freq = 1;
+	bus->prop.freq = devm_kcalloc(bus->dev, sizeof(*bus->prop.freq),
+					bus->prop.num_freq, GFP_KERNEL);
+	if (!bus->prop.freq)
+		return -ENOMEM;
+
+	bus->prop.freq[0] = bus->prop.max_freq;
+	bus->prop.err_threshold = 5;
+
+	return 0;
+}
+
+/*
+ * probe and init
+ */
+static int intel_probe(struct platform_device *pdev)
+{
+	struct sdw_intel *sdw;
+	int ret;
+
+	sdw = devm_kzalloc(&pdev->dev, sizeof(*sdw), GFP_KERNEL);
+	if (!sdw)
+		return -ENOMEM;
+
+	sdw->instance = pdev->id;
+	sdw->res = dev_get_platdata(&pdev->dev);
+	sdw->cdns.dev = &pdev->dev;
+	sdw->cdns.registers = sdw->res->registers;
+	sdw->cdns.instance = sdw->instance;
+	sdw->cdns.msg_count = 0;
+	sdw->cdns.bus.dev = &pdev->dev;
+	sdw->cdns.bus.link_id = pdev->id;
+
+	sdw_cdns_probe(&sdw->cdns);
+
+	/* Set property read ops */
+	sdw_cdns_master_ops.read_prop = intel_prop_read;
+	sdw->cdns.bus.ops = &sdw_cdns_master_ops;
+
+	platform_set_drvdata(pdev, sdw);
+
+	ret = sdw_add_bus_master(&sdw->cdns.bus);
+	if (ret) {
+		dev_err(&pdev->dev, "sdw_add_bus_master fail: %d\n", ret);
+		goto err_master_reg;
+	}
+
+	/* Initialize shim and controller */
+	intel_link_power_up(sdw);
+	intel_shim_init(sdw);
+
+	ret = sdw_cdns_init(&sdw->cdns);
+	if (ret)
+		goto err_init;
+
+	sdw_cdns_enable_interrupt(&sdw->cdns);
+	if (ret)
+		goto err_init;
+
+	/* Acquire IRQ */
+	ret = request_threaded_irq(sdw->res->irq, sdw_cdns_irq,
+			sdw_cdns_thread, IRQF_SHARED, KBUILD_MODNAME,
+			&sdw->cdns);
+	if (ret < 0) {
+		dev_err(sdw->cdns.dev, "unable to grab IRQ %d, disabling device\n",
+				sdw->res->irq);
+		goto err_init;
+	}
+
+	return 0;
+
+err_init:
+	sdw_delete_bus_master(&sdw->cdns.bus);
+err_master_reg:
+	return ret;
+}
+
+static int intel_remove(struct platform_device *pdev)
+{
+	struct sdw_intel *sdw;
+
+	sdw = platform_get_drvdata(pdev);
+
+	free_irq(sdw->res->irq, sdw);
+	sdw_delete_bus_master(&sdw->cdns.bus);
+
+	return 0;
+}
+
+static struct platform_driver sdw_intel_drv = {
+	.probe = intel_probe,
+	.remove = intel_remove,
+	.driver = {
+		.name = "int-sdw",
+
+	},
+};
+
+module_platform_driver(sdw_intel_drv);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:int-sdw");
+MODULE_DESCRIPTION("Intel Soundwire Master Driver");
diff --git a/drivers/soundwire/intel.h b/drivers/soundwire/intel.h
new file mode 100644
index 000000000000..ba1310c1b282
--- /dev/null
+++ b/drivers/soundwire/intel.h
@@ -0,0 +1,70 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __SDW_INTEL_LOCAL_H
+#define __SDW_INTEL_LOCAL_H
+
+/**
+ * struct sdw_intel_res: Soundwire link resources
+ *
+ * @registers: Link IO registers base
+ * @shim: Audio shim pointer
+ * @alh: ALH (Audio Link Hub) pointer
+ * @irq: Interrupt line
+ *
+ * This is set as pdata for each link instance.
+ */
+struct sdw_intel_link_res {
+	void __iomem *registers;
+	void __iomem *shim;
+	void __iomem *alh;
+	int irq;
+};
+
+#endif /* __SDW_INTEL_LOCAL_H */
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
new file mode 100644
index 000000000000..ef4a3b437877
--- /dev/null
+++ b/include/linux/soundwire/sdw_intel.h
@@ -0,0 +1,69 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SDW_INTEL_H
+#define __SDW_INTEL_H
+
+#include <linux/acpi.h>
+
+/**
+ * struct sdw_intel_res: Soundwire Intel resource structure
+ *
+ * @mmio_base: mmio base of SoundWire registers
+ * @irq: interrupt number
+ * @handle: ACPI parent handle
+ * @parent: parent device
+ */
+struct sdw_intel_res {
+	void __iomem *mmio_base;
+	int irq;
+	acpi_handle handle;
+	struct device *parent;
+};
+
+#endif
-- 
2.7.4

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

* [PATCH 14/14] soundwire: intel: Add Intel init module
  2017-10-19  3:03 ` Vinod Koul
                   ` (13 preceding siblings ...)
  (?)
@ 2017-10-19  3:03 ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  3:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

The SoundWire Master is implemented as part of Audio controller in
Intel platforms. Add a init module which creates SoundWire Master
platform devices based on the links supported in the hardware.

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
 drivers/soundwire/Makefile          |   3 +
 drivers/soundwire/intel_init.c      | 230 ++++++++++++++++++++++++++++++++++++
 include/linux/soundwire/sdw_intel.h |   3 +
 3 files changed, 236 insertions(+)
 create mode 100644 drivers/soundwire/intel_init.c

diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile
index 0813b2c74426..94272c965d6c 100644
--- a/drivers/soundwire/Makefile
+++ b/drivers/soundwire/Makefile
@@ -13,3 +13,6 @@ obj-$(CONFIG_SOUNDWIRE_CADENCE) += soundwire-cadence.o
 #Intel driver
 soundwire-intel-objs :=	intel.o
 obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel.o
+
+soundwire-intel-init-objs := intel_init.o
+obj-$(CONFIG_SOUNDWIRE_INTEL) += soundwire-intel-init.o
diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c
new file mode 100644
index 000000000000..188cb2052842
--- /dev/null
+++ b/drivers/soundwire/intel_init.c
@@ -0,0 +1,230 @@
+/*
+ *  This file is provided under a dual BSD/GPLv2 license.  When using or
+ *  redistributing this file, you may do so under either license.
+ *
+ *  GPL LICENSE SUMMARY
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of version 2 of the GNU General Public License 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.
+ *
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015-17 Intel Corporation.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Intel Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * SDW Intel Init Routines
+ *
+ * Initializes and creates SDW devices based on ACPI and Hardware values
+ */
+
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/soundwire/sdw_intel.h>
+#include "intel.h"
+
+#define SDW_MAX_LINKS		4
+#define SDW_SHIM_LCAP		0x0
+#define SDW_SHIM_BASE		0x2C000
+#define SDW_ALH_BASE		0x2C800
+#define SDW_LINK_BASE		0x30000
+#define SDW_LINK_SIZE		0x10000
+
+struct sdw_link_data {
+	struct sdw_intel_link_res res;
+	struct platform_device *pdev;
+};
+
+struct sdw_intel_ctx {
+	int count;
+	struct sdw_link_data *links;
+};
+
+static int sdw_intel_cleanup_pdev(struct sdw_intel_ctx *ctx)
+{
+	struct sdw_link_data *link = ctx->links;
+	int i;
+
+	if (!link)
+		return 0;
+
+	for (i = 0; i < ctx->count; i++) {
+		if (link->pdev)
+			platform_device_unregister(link->pdev);
+		link++;
+	}
+
+	kfree(ctx->links);
+	ctx->links = NULL;
+
+	return 0;
+}
+
+static struct sdw_intel_ctx
+*sdw_intel_add_controller(struct sdw_intel_res *res)
+{
+	struct platform_device_info pdevinfo;
+	struct platform_device *pdev;
+	struct sdw_link_data *link;
+	struct sdw_intel_ctx *ctx;
+	struct acpi_device *adev;
+	int ret, i;
+	u8 count;
+	u32 caps;
+
+	if (acpi_bus_get_device(res->handle, &adev))
+		return NULL;
+
+	/* Found controller, find links supported */
+	count = 0;
+	ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
+				  "mipi-sdw-master-count", &count, 1);
+
+	/* Don't fail on error, continue and use hw value */
+	if (ret) {
+		dev_err(&adev->dev,
+			"Failed to read mipi-sdw-master-count: %d\n", ret);
+		count = SDW_MAX_LINKS;
+	}
+
+	/* Check SNDWLCAP.LCOUNT */
+	caps = ioread32(res->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
+
+	/* Check HW supported vs property value and use min of two */
+	count = min_t(u8, caps, count);
+
+	/* Check count is within bounds */
+	if (count > SDW_MAX_LINKS) {
+		dev_err(&adev->dev, "Link count %d exceeds max %d\n",
+						count, SDW_MAX_LINKS);
+		return NULL;
+	}
+
+	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return NULL;
+
+	ctx->count = count;
+	ctx->links = kcalloc(ctx->count, sizeof(*ctx->links), GFP_KERNEL);
+	if (!ctx->links)
+		goto link_err;
+
+	link = ctx->links;
+
+	/* Create SDW Master devices */
+	for (i = 0; i < count; i++) {
+
+		link->res.irq = res->irq;
+		link->res.registers = res->mmio_base + SDW_LINK_BASE
+					+ (SDW_LINK_SIZE * i);
+		link->res.shim = res->mmio_base + SDW_SHIM_BASE;
+		link->res.alh = res->mmio_base + SDW_ALH_BASE;
+
+		memset(&pdevinfo, 0, sizeof(pdevinfo));
+
+		pdevinfo.parent = res->parent;
+		pdevinfo.name = "int-sdw";
+		pdevinfo.id = i;
+		pdevinfo.fwnode = acpi_fwnode_handle(adev);
+		pdevinfo.data = &link->res;
+		pdevinfo.size_data = sizeof(link->res);
+
+		pdev = platform_device_register_full(&pdevinfo);
+		if (IS_ERR(pdev)) {
+			dev_err(&adev->dev,
+				"platform device creation failed: %ld\n",
+				PTR_ERR(pdev));
+			goto pdev_err;
+		}
+
+		link->pdev = pdev;
+		link++;
+	}
+
+	return ctx;
+
+pdev_err:
+	sdw_intel_cleanup_pdev(ctx);
+link_err:
+	kfree(ctx);
+	return NULL;
+}
+
+static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
+					void *cdata, void **return_value)
+{
+	struct sdw_intel_res *res = cdata;
+	struct acpi_device *adev;
+
+	if (acpi_bus_get_device(handle, &adev)) {
+		dev_err(&adev->dev, "Couldn't find ACPI handle\n");
+		return AE_NOT_FOUND;
+	}
+
+	res->handle = handle;
+	return AE_OK;
+}
+
+void *sdw_intel_init(acpi_handle *parent_handle, struct sdw_intel_res *res)
+{
+	acpi_status status;
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
+					parent_handle, 1,
+					sdw_intel_acpi_cb,
+					NULL, res, NULL);
+	if (ACPI_FAILURE(status))
+		return NULL;
+
+	return sdw_intel_add_controller(res);
+}
+EXPORT_SYMBOL(sdw_intel_init);
+
+void sdw_intel_exit(void *arg)
+{
+	struct sdw_intel_ctx *ctx = arg;
+
+	sdw_intel_cleanup_pdev(ctx);
+	kfree(ctx);
+}
+EXPORT_SYMBOL(sdw_intel_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("Intel Soundwire Init Library");
diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
index ef4a3b437877..af3563ac80ce 100644
--- a/include/linux/soundwire/sdw_intel.h
+++ b/include/linux/soundwire/sdw_intel.h
@@ -66,4 +66,7 @@ struct sdw_intel_res {
 	struct device *parent;
 };
 
+void *sdw_intel_init(acpi_handle *parent_handle, struct sdw_intel_res *res);
+void sdw_intel_exit(void *arg);
+
 #endif
-- 
2.7.4

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-19  3:03 ` [PATCH 01/14] Documentation: Add SoundWire summary Vinod Koul
@ 2017-10-19  3:33     ` Randy Dunlap
  2017-10-20 10:39     ` Greg Kroah-Hartman
  2017-10-21  8:57     ` Mark Brown
  2 siblings, 0 replies; 139+ messages in thread
From: Randy Dunlap @ 2017-10-19  3:33 UTC (permalink / raw)
  To: Vinod Koul, Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On 10/18/17 20:03, Vinod Koul wrote:
> From: Sanyog Kale <sanyog.r.kale@intel.com>
> 
> SoundWire is a new Linux bus which implements a new MIPI bus protocol
> 'SoundWire'. The summary of SoundWire bus and registration APIs is
> documented in the 'summary' file.
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 192 insertions(+)
>  create mode 100644 Documentation/soundwire/summary.txt
> 
> diff --git a/Documentation/soundwire/summary.txt b/Documentation/soundwire/summary.txt
> new file mode 100644
> index 000000000000..15b78e6e3347
> --- /dev/null
> +++ b/Documentation/soundwire/summary.txt
> @@ -0,0 +1,192 @@
> +SoundWire
> +===========
> +
> +SoundWire is a new interface ratified in 2015 by the MIPI Alliance.
> +SoundWire is used for transporting data typically related to audio
> +functions. SoundWire interface is optimized to integrate audio devices in
> +mobile or mobile inspired systems.
> +
> +SoundWire is a 2-Pin multi-drop interface with data and clock line. It

                  2-pin

> +facilitates development of low cost, efficient, high performance systems.
> +Broad level key features of SoundWire interface include:
> +  1. Transporting all of payload data channels, control information, and setup
> +  commands over a single two-pin interface.
> +  2. Lower clock frequency, and hence lower power consumption, by use of DDR
> +  (Dual Data Rate) data transmission.
> +  3. Clock scaling and optional multiple data lanes to give wide flexibility
> +  in data rate to match system requirements.
> +  4. Device status monitoring, including interrupt-style alerts to the Master.
> +
> +The SoundWire protocol supports up to eleven Slave interfaces. All the
> +interfaces share the common Bus containing data and clock line. Each of the
> +Slaves can support up to 14 Data Ports. 13 Data Ports are dedicated to audio
> +transport. Data Port0 is dedicated to transport of Bulk control information,
> +each of the audio Data Ports (1..14) can support up to 8 Channels in

                                (1..13) ??

> +transmit or receiving mode (typically fixed direction but configurable
> +direction is enabled by the specification).  Bandwidth restrictions to
> +~19.2..24.576Mbits/s don't however allow for 11*13*8 channels to be
> +transmitted simultaneously.
> +
> +Below figure shows an example of connectivity between a SoundWire Master and
> +two Slave devices.
> +
> ++---------------+                                       +---------------+
> +|               |                       Clock Signal    |               |
> +|    Master     |-------+-------------------------------|    Slave      |
> +|   Interface   |       |               Data Signal     |  Interface 1  |
> +|               |-------|-------+-----------------------|               |
> ++---------------+       |       |                       +---------------+
> +                        |       |
> +                        |       |
> +                        |       |
> +                     +--+-------+--+
> +                     |             |
> +                     |   Slave     |
> +                     | Interface 2 |
> +                     |             |
> +                     +-------------+
> +
> +Terminology
> +=============
> +
> +The MIPI SoundWire specification uses the term 'device' to refer to a Master
> +or Slave interface, which of course can be confusing. In this summary and
> +code we use the term interface only to refer to the hardware. We follow the
> +Linux device model by mapping each Slave interface connected on the bus as a
> +device managed by a specific driver. The Linux SoundWire subsystem provides
> +a framework to implement a SoundWire Slave driver with an API allowing
> +3rd-party vendors to enable implementation-defined functionality while
> +common setup/configuration tasks are handled by the bus.
> +
> +Bus:
> +Implements SoundWire Linux Bus which handles the SoundWire protocol.
> +It programs all the MIPI defined Slave registers. It represents a SoundWire

                       MIPI-defined

> +Master. There can be multiple instances of Bus maybe present in a system.

eh?
           Multiple instances of Bus may be present in a system.

> +
> +Slave:
> +Registers as SoundWire Slave device (Linux Device). Multiple Slave devices
> +can register to a Bus instance.
> +
> +Slave driver:
> +Driver controlling the Slave device. MIPI-specified registers are controlled
> +directly by the Bus (and transmitted through the Master driver/interface).
> +Any implementation-defined Slave register is controlled by Slave driver. In
> +practice, it is expected that the Slave driver relies on regmap and does not
> +request direct register access.
> +
> +Programming interfaces (SoundWire Master interface Driver)
> +==========================================================
> +
> +SoundWire Bus supports programming interfaces for the SoundWire Master
> +implementation and SoundWire Slave devices. All the code uses the "sdw"
> +prefix commonly used by SoC designers and 3rd party vendors.
> +
> +Each of the SoundWire Master interfaces needs to be registered to the Bus.
> +Bus implements API to read standard Master MIPI properties and also provides
> +callback in Master ops for Master driver to implement own functions that
> +provides capabilities information. DT support is not implemented at this
> +time but should be trivial to add since capabilities are enabled with the
> +device_property_ API.
> +
> +The Master interface along with the Master interface capabilities are
> +registered based on board file, DT or ACPI.
> +
> +Following is the Bus API to register the SoundWire Bus.
> +
> +int sdw_add_bus_master(struct sdw_bus *bus)
> +{
> +        if (!bus->dev)
> +                return -ENODEV;
> +
> +        mutex_init(&bus->lock);
> +        INIT_LIST_HEAD(&bus->slaves);
> +
> +	/* Check ACPI for Slave devices */
> +        sdw_acpi_find_slaves(bus);
> +
> +	/* Check DT for Slave devices */
> +	sdw_of_find_slaves(bus);

Please use same indentation as sdw_acpi_find_slaves().

> +
> +        return 0;
> +}
> +
> +This will initialize sdw_bus object for Master device. "sdw_master_ops" and
> +"sdw_master_port_ops" callback functions are provided to the Bus.
> +
> +"sdw_master_ops" is used by Bus to control the Bus in the hardware specific
> +way. It includes Bus control functions such as sending the SoundWire
> +read/write messages on Bus, setting up clock frequency & Stream
> +Synchronization Point (SSP). The "sdw_master_ops" structure abstracts the
> +hardware details of the Master from the Bus.
> +
> +"sdw_master_port_ops" is used by Bus to setup the Port parameters of the
> +Master interface Port. Master interface Port register map is not defined by
> +MIPI specification, so Bus calls the "sdw_master_port_ops" callback
> +function to do Port operations like "Port Prepare", "Port Transport params
> +set", "Port enable and disable". The implementation of the Master driver can
> +then perform hardware-specific configurations.
> +
> +Programming interfaces (SoundWire Slave Driver)
> +===============================================
> +
> +The MIPI specification requires each Slave interface to expose a unique
> +48-bit identifier, stored in 6 read only dev_id registers. This dev_id

                                  read-only

> +identifier contains vendor and part information, as well as a field enabling
> +to differentiate between identical components. An additional class field is
> +currently unused. Slave driver is written for the specific 48-bit
> +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> +Slave device and driver match is done based on this 48-bit identifier. Probe
> +of the Slave driver is called by Bus on successful match between device and
> +driver id. A parent/child relationship is enforced between Slave and Master

maybe reverse this order.............                         Master and Slave

to be in the "parent/child" order?  Unless I have them backwards?

> +devices (the logical representation is aligned with the physical
> +connectivity).
> +
> +The information on Master/Slave dependencies is stored in platform data,
> +board-file, ACPI or DT. The MIPI Software specification defines an

                                                      drop:        an

> +additional link_id parameters for controllers that have multiple Master
> +interfaces. The dev_id registers are only unique in the scope of a link, and
> +the link_id unique in the scope of a controller. Both dev_id and link_id are
> +not necessarily unique at the system level but the parent/child information
> +is used to avoid ambiguity.
> +
> +static const struct sdw_device_id slave_id[] = {
> +        SDW_SLAVE_ENTRY(0x025d, 0x700, 0),
> +        {},
> +};
> +MODULE_DEVICE_TABLE(sdw, slave_id);
> +
> +static struct sdw_driver slave_sdw_driver = {
> +        .driver = {
> +                   .name = "slave_xxx",
> +                   .pm = &slave_runtime_pm,
> +                   },
> +	.probe = slave_sdw_probe,
> +	.remove = slave_sdw_remove,
> +	.ops = &slave_slave_ops,
> +	.id_table = slave_id,
> +};
> +
> +
> +For capabilities, Bus implements API to read standard Slave MIPI properties
> +and also provides callback in Slave ops for Slave driver to implement own
> +function that provides capabilities information. Bus needs to know a set of
> +Slave capabilities to program Slave registers and to control the Bus
> +reconfigurations.
> +
> +Future enhancements to be done:
> +===============================
> +1. Bulk Register Access (BRA) transfers.
> +2. Multiple data lane support.
> +
> +Links:
> +=====
> +
> +SoundWire MIPI specification 1.1 is available at:
> +https://members.mipi.org/wg/All-Members/document/70290
> +
> +SoundWire MIPI DisCo (Discovery and Configuration) specification is
> +available at:
> +https://www.mipi.org/specifications/mipi-disco-soundwire
> +
> +(publicly accessible with registration or directly accessible to MIPI
> +members)
> 


-- 
~Randy

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-19  3:33     ` Randy Dunlap
  0 siblings, 0 replies; 139+ messages in thread
From: Randy Dunlap @ 2017-10-19  3:33 UTC (permalink / raw)
  To: Vinod Koul, Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On 10/18/17 20:03, Vinod Koul wrote:
> From: Sanyog Kale <sanyog.r.kale@intel.com>
> 
> SoundWire is a new Linux bus which implements a new MIPI bus protocol
> 'SoundWire'. The summary of SoundWire bus and registration APIs is
> documented in the 'summary' file.
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 192 insertions(+)
>  create mode 100644 Documentation/soundwire/summary.txt
> 
> diff --git a/Documentation/soundwire/summary.txt b/Documentation/soundwire/summary.txt
> new file mode 100644
> index 000000000000..15b78e6e3347
> --- /dev/null
> +++ b/Documentation/soundwire/summary.txt
> @@ -0,0 +1,192 @@
> +SoundWire
> +===========
> +
> +SoundWire is a new interface ratified in 2015 by the MIPI Alliance.
> +SoundWire is used for transporting data typically related to audio
> +functions. SoundWire interface is optimized to integrate audio devices in
> +mobile or mobile inspired systems.
> +
> +SoundWire is a 2-Pin multi-drop interface with data and clock line. It

                  2-pin

> +facilitates development of low cost, efficient, high performance systems.
> +Broad level key features of SoundWire interface include:
> +  1. Transporting all of payload data channels, control information, and setup
> +  commands over a single two-pin interface.
> +  2. Lower clock frequency, and hence lower power consumption, by use of DDR
> +  (Dual Data Rate) data transmission.
> +  3. Clock scaling and optional multiple data lanes to give wide flexibility
> +  in data rate to match system requirements.
> +  4. Device status monitoring, including interrupt-style alerts to the Master.
> +
> +The SoundWire protocol supports up to eleven Slave interfaces. All the
> +interfaces share the common Bus containing data and clock line. Each of the
> +Slaves can support up to 14 Data Ports. 13 Data Ports are dedicated to audio
> +transport. Data Port0 is dedicated to transport of Bulk control information,
> +each of the audio Data Ports (1..14) can support up to 8 Channels in

                                (1..13) ??

> +transmit or receiving mode (typically fixed direction but configurable
> +direction is enabled by the specification).  Bandwidth restrictions to
> +~19.2..24.576Mbits/s don't however allow for 11*13*8 channels to be
> +transmitted simultaneously.
> +
> +Below figure shows an example of connectivity between a SoundWire Master and
> +two Slave devices.
> +
> ++---------------+                                       +---------------+
> +|               |                       Clock Signal    |               |
> +|    Master     |-------+-------------------------------|    Slave      |
> +|   Interface   |       |               Data Signal     |  Interface 1  |
> +|               |-------|-------+-----------------------|               |
> ++---------------+       |       |                       +---------------+
> +                        |       |
> +                        |       |
> +                        |       |
> +                     +--+-------+--+
> +                     |             |
> +                     |   Slave     |
> +                     | Interface 2 |
> +                     |             |
> +                     +-------------+
> +
> +Terminology
> +=============
> +
> +The MIPI SoundWire specification uses the term 'device' to refer to a Master
> +or Slave interface, which of course can be confusing. In this summary and
> +code we use the term interface only to refer to the hardware. We follow the
> +Linux device model by mapping each Slave interface connected on the bus as a
> +device managed by a specific driver. The Linux SoundWire subsystem provides
> +a framework to implement a SoundWire Slave driver with an API allowing
> +3rd-party vendors to enable implementation-defined functionality while
> +common setup/configuration tasks are handled by the bus.
> +
> +Bus:
> +Implements SoundWire Linux Bus which handles the SoundWire protocol.
> +It programs all the MIPI defined Slave registers. It represents a SoundWire

                       MIPI-defined

> +Master. There can be multiple instances of Bus maybe present in a system.

eh?
           Multiple instances of Bus may be present in a system.

> +
> +Slave:
> +Registers as SoundWire Slave device (Linux Device). Multiple Slave devices
> +can register to a Bus instance.
> +
> +Slave driver:
> +Driver controlling the Slave device. MIPI-specified registers are controlled
> +directly by the Bus (and transmitted through the Master driver/interface).
> +Any implementation-defined Slave register is controlled by Slave driver. In
> +practice, it is expected that the Slave driver relies on regmap and does not
> +request direct register access.
> +
> +Programming interfaces (SoundWire Master interface Driver)
> +==========================================================
> +
> +SoundWire Bus supports programming interfaces for the SoundWire Master
> +implementation and SoundWire Slave devices. All the code uses the "sdw"
> +prefix commonly used by SoC designers and 3rd party vendors.
> +
> +Each of the SoundWire Master interfaces needs to be registered to the Bus.
> +Bus implements API to read standard Master MIPI properties and also provides
> +callback in Master ops for Master driver to implement own functions that
> +provides capabilities information. DT support is not implemented at this
> +time but should be trivial to add since capabilities are enabled with the
> +device_property_ API.
> +
> +The Master interface along with the Master interface capabilities are
> +registered based on board file, DT or ACPI.
> +
> +Following is the Bus API to register the SoundWire Bus.
> +
> +int sdw_add_bus_master(struct sdw_bus *bus)
> +{
> +        if (!bus->dev)
> +                return -ENODEV;
> +
> +        mutex_init(&bus->lock);
> +        INIT_LIST_HEAD(&bus->slaves);
> +
> +	/* Check ACPI for Slave devices */
> +        sdw_acpi_find_slaves(bus);
> +
> +	/* Check DT for Slave devices */
> +	sdw_of_find_slaves(bus);

Please use same indentation as sdw_acpi_find_slaves().

> +
> +        return 0;
> +}
> +
> +This will initialize sdw_bus object for Master device. "sdw_master_ops" and
> +"sdw_master_port_ops" callback functions are provided to the Bus.
> +
> +"sdw_master_ops" is used by Bus to control the Bus in the hardware specific
> +way. It includes Bus control functions such as sending the SoundWire
> +read/write messages on Bus, setting up clock frequency & Stream
> +Synchronization Point (SSP). The "sdw_master_ops" structure abstracts the
> +hardware details of the Master from the Bus.
> +
> +"sdw_master_port_ops" is used by Bus to setup the Port parameters of the
> +Master interface Port. Master interface Port register map is not defined by
> +MIPI specification, so Bus calls the "sdw_master_port_ops" callback
> +function to do Port operations like "Port Prepare", "Port Transport params
> +set", "Port enable and disable". The implementation of the Master driver can
> +then perform hardware-specific configurations.
> +
> +Programming interfaces (SoundWire Slave Driver)
> +===============================================
> +
> +The MIPI specification requires each Slave interface to expose a unique
> +48-bit identifier, stored in 6 read only dev_id registers. This dev_id

                                  read-only

> +identifier contains vendor and part information, as well as a field enabling
> +to differentiate between identical components. An additional class field is
> +currently unused. Slave driver is written for the specific 48-bit
> +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> +Slave device and driver match is done based on this 48-bit identifier. Probe
> +of the Slave driver is called by Bus on successful match between device and
> +driver id. A parent/child relationship is enforced between Slave and Master

maybe reverse this order.............                         Master and Slave

to be in the "parent/child" order?  Unless I have them backwards?

> +devices (the logical representation is aligned with the physical
> +connectivity).
> +
> +The information on Master/Slave dependencies is stored in platform data,
> +board-file, ACPI or DT. The MIPI Software specification defines an

                                                      drop:        an

> +additional link_id parameters for controllers that have multiple Master
> +interfaces. The dev_id registers are only unique in the scope of a link, and
> +the link_id unique in the scope of a controller. Both dev_id and link_id are
> +not necessarily unique at the system level but the parent/child information
> +is used to avoid ambiguity.
> +
> +static const struct sdw_device_id slave_id[] = {
> +        SDW_SLAVE_ENTRY(0x025d, 0x700, 0),
> +        {},
> +};
> +MODULE_DEVICE_TABLE(sdw, slave_id);
> +
> +static struct sdw_driver slave_sdw_driver = {
> +        .driver = {
> +                   .name = "slave_xxx",
> +                   .pm = &slave_runtime_pm,
> +                   },
> +	.probe = slave_sdw_probe,
> +	.remove = slave_sdw_remove,
> +	.ops = &slave_slave_ops,
> +	.id_table = slave_id,
> +};
> +
> +
> +For capabilities, Bus implements API to read standard Slave MIPI properties
> +and also provides callback in Slave ops for Slave driver to implement own
> +function that provides capabilities information. Bus needs to know a set of
> +Slave capabilities to program Slave registers and to control the Bus
> +reconfigurations.
> +
> +Future enhancements to be done:
> +===============================
> +1. Bulk Register Access (BRA) transfers.
> +2. Multiple data lane support.
> +
> +Links:
> +=====
> +
> +SoundWire MIPI specification 1.1 is available at:
> +https://members.mipi.org/wg/All-Members/document/70290
> +
> +SoundWire MIPI DisCo (Discovery and Configuration) specification is
> +available at:
> +https://www.mipi.org/specifications/mipi-disco-soundwire
> +
> +(publicly accessible with registration or directly accessible to MIPI
> +members)
> 


-- 
~Randy

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-19  3:33     ` Randy Dunlap
@ 2017-10-19  4:44       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  4:44 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, srinivas.kandagatla, plai, Sudheer Papothi


Thanks for the quick review Randy,

On Wed, Oct 18, 2017 at 08:33:08PM -0700, Randy Dunlap wrote:
> On 10/18/17 20:03, Vinod Koul wrote:

> > +SoundWire is a new interface ratified in 2015 by the MIPI Alliance.
> > +SoundWire is used for transporting data typically related to audio
> > +functions. SoundWire interface is optimized to integrate audio devices in
> > +mobile or mobile inspired systems.
> > +
> > +SoundWire is a 2-Pin multi-drop interface with data and clock line. It
> 
>                   2-pin

ok

> > +The SoundWire protocol supports up to eleven Slave interfaces. All the
> > +interfaces share the common Bus containing data and clock line. Each of the
> > +Slaves can support up to 14 Data Ports. 13 Data Ports are dedicated to audio
> > +transport. Data Port0 is dedicated to transport of Bulk control information,
> > +each of the audio Data Ports (1..14) can support up to 8 Channels in
> 
>                                 (1..13) ??

nope. 1 to 14, both inclusive, thats why 14 Data Ports

> > +Bus:
> > +Implements SoundWire Linux Bus which handles the SoundWire protocol.
> > +It programs all the MIPI defined Slave registers. It represents a SoundWire
> 
>                        MIPI-defined
> 
> > +Master. There can be multiple instances of Bus maybe present in a system.
> 
> eh?
>            Multiple instances of Bus may be present in a system.

sounds better

> > +int sdw_add_bus_master(struct sdw_bus *bus)
> > +{
> > +        if (!bus->dev)
> > +                return -ENODEV;
> > +
> > +        mutex_init(&bus->lock);
> > +        INIT_LIST_HEAD(&bus->slaves);
> > +
> > +	/* Check ACPI for Slave devices */
> > +        sdw_acpi_find_slaves(bus);
> > +
> > +	/* Check DT for Slave devices */
> > +	sdw_of_find_slaves(bus);
> 
> Please use same indentation as sdw_acpi_find_slaves().

ah not sure why it came like this, thanks for pointing out

> > +The MIPI specification requires each Slave interface to expose a unique
> > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> 
>                                   read-only

right

> > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> > +Slave device and driver match is done based on this 48-bit identifier. Probe
> > +of the Slave driver is called by Bus on successful match between device and
> > +driver id. A parent/child relationship is enforced between Slave and Master
> 
> maybe reverse this order.............                         Master and Slave
> 
> to be in the "parent/child" order?  Unless I have them backwards?

right, will update this

> > +devices (the logical representation is aligned with the physical
> > +connectivity).
> > +
> > +The information on Master/Slave dependencies is stored in platform data,
> > +board-file, ACPI or DT. The MIPI Software specification defines an
> 

ok

-- 
~Vinod

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-19  4:44       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-19  4:44 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


Thanks for the quick review Randy,

On Wed, Oct 18, 2017 at 08:33:08PM -0700, Randy Dunlap wrote:
> On 10/18/17 20:03, Vinod Koul wrote:

> > +SoundWire is a new interface ratified in 2015 by the MIPI Alliance.
> > +SoundWire is used for transporting data typically related to audio
> > +functions. SoundWire interface is optimized to integrate audio devices in
> > +mobile or mobile inspired systems.
> > +
> > +SoundWire is a 2-Pin multi-drop interface with data and clock line. It
> 
>                   2-pin

ok

> > +The SoundWire protocol supports up to eleven Slave interfaces. All the
> > +interfaces share the common Bus containing data and clock line. Each of the
> > +Slaves can support up to 14 Data Ports. 13 Data Ports are dedicated to audio
> > +transport. Data Port0 is dedicated to transport of Bulk control information,
> > +each of the audio Data Ports (1..14) can support up to 8 Channels in
> 
>                                 (1..13) ??

nope. 1 to 14, both inclusive, thats why 14 Data Ports

> > +Bus:
> > +Implements SoundWire Linux Bus which handles the SoundWire protocol.
> > +It programs all the MIPI defined Slave registers. It represents a SoundWire
> 
>                        MIPI-defined
> 
> > +Master. There can be multiple instances of Bus maybe present in a system.
> 
> eh?
>            Multiple instances of Bus may be present in a system.

sounds better

> > +int sdw_add_bus_master(struct sdw_bus *bus)
> > +{
> > +        if (!bus->dev)
> > +                return -ENODEV;
> > +
> > +        mutex_init(&bus->lock);
> > +        INIT_LIST_HEAD(&bus->slaves);
> > +
> > +	/* Check ACPI for Slave devices */
> > +        sdw_acpi_find_slaves(bus);
> > +
> > +	/* Check DT for Slave devices */
> > +	sdw_of_find_slaves(bus);
> 
> Please use same indentation as sdw_acpi_find_slaves().

ah not sure why it came like this, thanks for pointing out

> > +The MIPI specification requires each Slave interface to expose a unique
> > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> 
>                                   read-only

right

> > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> > +Slave device and driver match is done based on this 48-bit identifier. Probe
> > +of the Slave driver is called by Bus on successful match between device and
> > +driver id. A parent/child relationship is enforced between Slave and Master
> 
> maybe reverse this order.............                         Master and Slave
> 
> to be in the "parent/child" order?  Unless I have them backwards?

right, will update this

> > +devices (the logical representation is aligned with the physical
> > +connectivity).
> > +
> > +The information on Master/Slave dependencies is stored in platform data,
> > +board-file, ACPI or DT. The MIPI Software specification defines an
> 

ok

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  3:03 ` [PATCH 02/14] soundwire: Add SoundWire bus type Vinod Koul
@ 2017-10-19  7:40   ` Takashi Iwai
  2017-10-19  8:32       ` Takashi Iwai
  2017-10-20  5:11       ` Vinod Koul
  2017-10-20 10:41     ` Greg Kroah-Hartman
                     ` (3 subsequent siblings)
  4 siblings, 2 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  7:40 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, 19 Oct 2017 05:03:18 +0200,
Vinod Koul wrote:
> 
> --- /dev/null
> +++ b/drivers/soundwire/Kconfig
> @@ -0,0 +1,22 @@
> +#
> +# SoundWire subsystem configuration
> +#
> +
> +menuconfig SOUNDWIRE
> +	bool "SoundWire support"
> +	---help---
> +	  SoundWire is a 2-Pin interface with data and clock line ratified
> +	  by the MIPI Alliance. SoundWire is used for transporting data
> +	  typically related to audio functions. SoundWire interface is
> +	  optimized to integrate audio devices in mobile or mobile inspired
> +	  systems
> +
> +if SOUNDWIRE
> +
> +comment "SoundWire Devices"
> +
> +config SOUNDWIRE_BUS
> +	tristate
> +	default SOUNDWIRE
> +

Does it make sense to be tristate?
Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
Y or N.  If it's Y and others select M, it'll be still Y.


> --- /dev/null
> +++ b/drivers/soundwire/bus_type.c
> +/**
> + * sdw_get_device_id: find the matching SoundWire device id
> + *
> + * @slave: SoundWire Slave device
> + * @drv: SoundWire Slave Driver

Inconsistent upper/lower letters in these two lines.

> + * The match is done by comparing the mfg_id and part_id from the
> + * struct sdw_device_id. class_id is unused, as it is a placeholder
> + * in MIPI Spec.
> + */
> +static const struct sdw_device_id *
> +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> +{
> +	const struct sdw_device_id *id = drv->id_table;
> +
> +	while (id && id->mfg_id) {
> +		if (slave->id.mfg_id == id->mfg_id &&
> +				slave->id.part_id == id->part_id) {

Please indentation properly.

> +			return id;
> +		}

Superfluous braces for a single-line.

> +		id++;
> +	}
> +
> +	return NULL;
> +}
> +
> +static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> +
> +	return !!sdw_get_device_id(slave, drv);
> +}
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)

I'd put const to slave argument, as it won't be modified.

> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -228,6 +228,13 @@ struct hda_device_id {
>  	unsigned long driver_data;
>  };
>  
> +struct sdw_device_id {
> +	__u16 mfg_id;
> +	__u16 part_id;
> +	__u8 class_id;
> +	kernel_ulong_t driver_data;

Better to think of alignment.


> --- /dev/null
> +++ b/include/linux/soundwire/sdw.h
....
> +/**
> + * struct sdw_bus: SoundWire bus
> + *
> + * @dev: Master linux device
> + * @link_id: Link id number, can be 0 to N, unique for each Master
> + * @slaves: list of Slaves on this bus
> + * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
> + * @bus_lock: bus lock
> + */
> +struct sdw_bus {
> +	struct device *dev;
> +	unsigned int link_id;
> +	struct list_head slaves;
> +	bool assigned[SDW_MAX_DEVICES + 1];

Why not a bitmap?


thanks,

Takashi

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

* Re: [alsa-devel] [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  7:40   ` Takashi Iwai
@ 2017-10-19  8:32       ` Takashi Iwai
  2017-10-20  5:11       ` Vinod Koul
  1 sibling, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  8:32 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, patches.audio,
	Greg Kroah-Hartman, plai, LKML, Pierre, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, 19 Oct 2017 09:40:06 +0200,
Takashi Iwai wrote:
> 
> On Thu, 19 Oct 2017 05:03:18 +0200,
> Vinod Koul wrote:
> > 
> > --- /dev/null
> > +++ b/drivers/soundwire/Kconfig
> > @@ -0,0 +1,22 @@
> > +#
> > +# SoundWire subsystem configuration
> > +#
> > +
> > +menuconfig SOUNDWIRE
> > +	bool "SoundWire support"
> > +	---help---
> > +	  SoundWire is a 2-Pin interface with data and clock line ratified
> > +	  by the MIPI Alliance. SoundWire is used for transporting data
> > +	  typically related to audio functions. SoundWire interface is
> > +	  optimized to integrate audio devices in mobile or mobile inspired
> > +	  systems
> > +
> > +if SOUNDWIRE
> > +
> > +comment "SoundWire Devices"
> > +
> > +config SOUNDWIRE_BUS
> > +	tristate
> > +	default SOUNDWIRE
> > +
> 
> Does it make sense to be tristate?
> Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> Y or N.  If it's Y and others select M, it'll be still Y.

I found a later patch selecting SOUNDWIRE_BUS.  So just drop this
"default" line, and always let others selecting the bus.


Takashi

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-19  8:32       ` Takashi Iwai
  0 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  8:32 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Thu, 19 Oct 2017 09:40:06 +0200,
Takashi Iwai wrote:
> 
> On Thu, 19 Oct 2017 05:03:18 +0200,
> Vinod Koul wrote:
> > 
> > --- /dev/null
> > +++ b/drivers/soundwire/Kconfig
> > @@ -0,0 +1,22 @@
> > +#
> > +# SoundWire subsystem configuration
> > +#
> > +
> > +menuconfig SOUNDWIRE
> > +	bool "SoundWire support"
> > +	---help---
> > +	  SoundWire is a 2-Pin interface with data and clock line ratified
> > +	  by the MIPI Alliance. SoundWire is used for transporting data
> > +	  typically related to audio functions. SoundWire interface is
> > +	  optimized to integrate audio devices in mobile or mobile inspired
> > +	  systems
> > +
> > +if SOUNDWIRE
> > +
> > +comment "SoundWire Devices"
> > +
> > +config SOUNDWIRE_BUS
> > +	tristate
> > +	default SOUNDWIRE
> > +
> 
> Does it make sense to be tristate?
> Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> Y or N.  If it's Y and others select M, it'll be still Y.

I found a later patch selecting SOUNDWIRE_BUS.  So just drop this
"default" line, and always let others selecting the bus.


Takashi

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

* Re: [alsa-devel] [PATCH 03/14] soundwire: Add Master registration
  2017-10-19  3:03   ` Vinod Koul
@ 2017-10-19  8:54     ` Takashi Iwai
  -1 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  8:54 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, 19 Oct 2017 05:03:19 +0200,
Vinod Koul wrote:
> 
> +/**
> + * sdw_add_bus_master: add a bus Master instance
> + *
> + * @bus: bus instance
> + *
> + * Initializes the bus instance, read properties and create child
> + * devices.
> + */
> +int sdw_add_bus_master(struct sdw_bus *bus)
> +{
> +	int ret;
> +
> +	if (!bus->dev) {
> +		pr_err("SoundWire bus has no device");
> +		return -ENODEV;
> +	}
> +
> +	mutex_init(&bus->bus_lock);
> +	INIT_LIST_HEAD(&bus->slaves);
> +
> +	/*
> +	 * SDW is an enumerable bus, but devices can be powered off. So,
> +	 * they won't be able to report as present.
> +	 *
> +	 * Create Slave devices based on Slaves described in
> +	 * the respective firmware (ACPI/DT)
> +	 */
> +
> +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> +		ret = sdw_acpi_find_slaves(bus);
> +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)

The bus->dev NULL check is already done at the beginning of the
function, so here are superfluous.


> +static int sdw_delete_slave(struct device *dev, void *data)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_bus *bus = slave->bus;
> +
> +	mutex_lock(&bus->bus_lock);
> +	if (!list_empty(&bus->slaves))
> +		list_del(&slave->node);

You can perform list_del_init() without empty check.

> +void sdw_extract_slave_id(struct sdw_bus *bus,
> +			unsigned long long addr, struct sdw_slave_id *id)

Use u64 instead.

> +{
> +	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
> +
> +	/*
> +	 * Spec definition
> +	 *   Register		Bit	Contents
> +	 *   DevId_0 [7:4]	47:44	sdw_version
> +	 *   DevId_0 [3:0]	43:40	unique_id
> +	 *   DevId_1		39:32	mfg_id [15:8]
> +	 *   DevId_2		31:24	mfg_id [7:0]
> +	 *   DevId_3		23:16	part_id [15:8]
> +	 *   DevId_4		15:08	part_id [7:0]
> +	 *   DevId_5		07:00	class_id
> +	 */
> +	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
> +	id->unique_id = (addr >> 40) & GENMASK(3, 0);
> +	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
> +	id->part_id = (addr >> 8) & GENMASK(15, 0);
> +	id->class_id = addr & GENMASK(7, 0);
> +
> +	dev_info(bus->dev,
> +		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
> +				id->class_id, id->part_id, id->mfg_id,
> +				id->unique_id, id->sdw_version);
> +

Do we want to print a message always at each invocation?

> +static int sdw_slave_add(struct sdw_bus *bus,
> +		struct sdw_slave_id *id, struct fwnode_handle *fwnode)
> +{
> +	struct sdw_slave *slave;
> +	char name[32];
> +	int ret;
> +
> +	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
> +	if (!slave)
> +		return -ENOMEM;
> +
> +	/* Initialize data structure */
> +	memcpy(&slave->id, id, sizeof(*id));
> +
> +	/* name shall be sdw:link:mfg:part:class:unique */
> +	snprintf(name, sizeof(name), "sdw:%x:%x:%x:%x:%x",
> +			bus->link_id, id->mfg_id, id->part_id,
> +			id->class_id, id->unique_id);

You can set the name directly via dev_set_name().  It's printf format,
after all.

> +	slave->dev.parent = bus->dev;
> +	slave->dev.fwnode = fwnode;
> +	dev_set_name(&slave->dev, "%s", name);
> +	slave->dev.release = sdw_slave_release;
> +	slave->dev.bus = &sdw_bus_type;
> +	slave->bus = bus;
> +	slave->status = SDW_SLAVE_UNATTACHED;
> +	slave->dev_num = 0;
> +
> +	mutex_lock(&bus->bus_lock);
> +	list_add_tail(&slave->node, &bus->slaves);
> +	mutex_unlock(&bus->bus_lock);
> +
> +	ret = device_register(&slave->dev);
> +	if (ret) {
> +		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
> +
> +		/*
> +		 * On err, don't free but drop ref as this will be freed
> +		 * when release method is invoked.
> +		 */
> +		put_device(&slave->dev);

Wouldn't it leave a stale link to bus?


thanks,

Takashi

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

* Re: [PATCH 03/14] soundwire: Add Master registration
@ 2017-10-19  8:54     ` Takashi Iwai
  0 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  8:54 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Thu, 19 Oct 2017 05:03:19 +0200,
Vinod Koul wrote:
> 
> +/**
> + * sdw_add_bus_master: add a bus Master instance
> + *
> + * @bus: bus instance
> + *
> + * Initializes the bus instance, read properties and create child
> + * devices.
> + */
> +int sdw_add_bus_master(struct sdw_bus *bus)
> +{
> +	int ret;
> +
> +	if (!bus->dev) {
> +		pr_err("SoundWire bus has no device");
> +		return -ENODEV;
> +	}
> +
> +	mutex_init(&bus->bus_lock);
> +	INIT_LIST_HEAD(&bus->slaves);
> +
> +	/*
> +	 * SDW is an enumerable bus, but devices can be powered off. So,
> +	 * they won't be able to report as present.
> +	 *
> +	 * Create Slave devices based on Slaves described in
> +	 * the respective firmware (ACPI/DT)
> +	 */
> +
> +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> +		ret = sdw_acpi_find_slaves(bus);
> +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)

The bus->dev NULL check is already done at the beginning of the
function, so here are superfluous.


> +static int sdw_delete_slave(struct device *dev, void *data)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_bus *bus = slave->bus;
> +
> +	mutex_lock(&bus->bus_lock);
> +	if (!list_empty(&bus->slaves))
> +		list_del(&slave->node);

You can perform list_del_init() without empty check.

> +void sdw_extract_slave_id(struct sdw_bus *bus,
> +			unsigned long long addr, struct sdw_slave_id *id)

Use u64 instead.

> +{
> +	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
> +
> +	/*
> +	 * Spec definition
> +	 *   Register		Bit	Contents
> +	 *   DevId_0 [7:4]	47:44	sdw_version
> +	 *   DevId_0 [3:0]	43:40	unique_id
> +	 *   DevId_1		39:32	mfg_id [15:8]
> +	 *   DevId_2		31:24	mfg_id [7:0]
> +	 *   DevId_3		23:16	part_id [15:8]
> +	 *   DevId_4		15:08	part_id [7:0]
> +	 *   DevId_5		07:00	class_id
> +	 */
> +	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
> +	id->unique_id = (addr >> 40) & GENMASK(3, 0);
> +	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
> +	id->part_id = (addr >> 8) & GENMASK(15, 0);
> +	id->class_id = addr & GENMASK(7, 0);
> +
> +	dev_info(bus->dev,
> +		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
> +				id->class_id, id->part_id, id->mfg_id,
> +				id->unique_id, id->sdw_version);
> +

Do we want to print a message always at each invocation?

> +static int sdw_slave_add(struct sdw_bus *bus,
> +		struct sdw_slave_id *id, struct fwnode_handle *fwnode)
> +{
> +	struct sdw_slave *slave;
> +	char name[32];
> +	int ret;
> +
> +	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
> +	if (!slave)
> +		return -ENOMEM;
> +
> +	/* Initialize data structure */
> +	memcpy(&slave->id, id, sizeof(*id));
> +
> +	/* name shall be sdw:link:mfg:part:class:unique */
> +	snprintf(name, sizeof(name), "sdw:%x:%x:%x:%x:%x",
> +			bus->link_id, id->mfg_id, id->part_id,
> +			id->class_id, id->unique_id);

You can set the name directly via dev_set_name().  It's printf format,
after all.

> +	slave->dev.parent = bus->dev;
> +	slave->dev.fwnode = fwnode;
> +	dev_set_name(&slave->dev, "%s", name);
> +	slave->dev.release = sdw_slave_release;
> +	slave->dev.bus = &sdw_bus_type;
> +	slave->bus = bus;
> +	slave->status = SDW_SLAVE_UNATTACHED;
> +	slave->dev_num = 0;
> +
> +	mutex_lock(&bus->bus_lock);
> +	list_add_tail(&slave->node, &bus->slaves);
> +	mutex_unlock(&bus->bus_lock);
> +
> +	ret = device_register(&slave->dev);
> +	if (ret) {
> +		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
> +
> +		/*
> +		 * On err, don't free but drop ref as this will be freed
> +		 * when release method is invoked.
> +		 */
> +		put_device(&slave->dev);

Wouldn't it leave a stale link to bus?


thanks,

Takashi

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

* Re: [alsa-devel] [PATCH 04/14] soundwire: Add MIPI DisCo property      helpers
  2017-10-19  3:03 ` [PATCH 04/14] soundwire: Add MIPI DisCo property helpers Vinod Koul
@ 2017-10-19  9:02   ` Takashi Iwai
  2017-10-20  5:25     ` Vinod Koul
  2017-10-21  9:20     ` Mark Brown
  1 sibling, 1 reply; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  9:02 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, 19 Oct 2017 05:03:20 +0200,
Vinod Koul wrote:
> 
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> index a14d1de80afa..baad4ad3be44 100644
> --- a/drivers/soundwire/bus_type.c
> +++ b/drivers/soundwire/bus_type.c
> @@ -139,12 +139,28 @@ static int sdw_drv_probe(struct device *dev)
>  		return ret;
>  	}
>  
> +	slave->ops = drv->ops;
> +
>  	ret = drv->probe(slave, id);
>  	if (ret) {
>  		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
>  		return ret;
>  	}
>  
> +	/* device is probed so let's read the properties now */
> +	if (slave->ops && slave->ops->read_prop)
> +		slave->ops->read_prop(slave);
> +
> +	/*
> +	 * Check for valid clk_stop_timeout, use DisCo worst case value of
> +	 * 300ms
> +	 */
> +	if (slave->prop.clk_stop_timeout == 0)
> +		slave->prop.clk_stop_timeout = 300;
> +
> +	slave->bus->clk_stop_timeout = max_t(u32, slave->bus->clk_stop_timeout,
> +					slave->prop.clk_stop_timeout);

Isn't it racy?
Also what happens after removing a driver?  The clk_stop_timeout is
kept high?


> +
> +int sdw_slave_read_dpn(struct sdw_slave *slave,
> +		struct sdw_dpn_prop *dpn, int count, int ports, char *type)

Missing comment for a public API function.


thanks,

Takashi

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

* Re: [alsa-devel] [PATCH 06/14] soundwire: Add IO transfer
  2017-10-19  3:03   ` Vinod Koul
  (?)
@ 2017-10-19  9:13   ` Takashi Iwai
  2017-10-20  5:30       ` Vinod Koul
  -1 siblings, 1 reply; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19  9:13 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, 19 Oct 2017 05:03:22 +0200,
Vinod Koul wrote:
> 
> +static inline int find_error_code(unsigned int sdw_ret)
> +{
> +	switch (sdw_ret) {
> +	case SDW_CMD_OK:
> +		return 0;
> +
> +	case SDW_CMD_IGNORED:
> +		return -ENODATA;
> +
> +	case SDW_CMD_TIMEOUT:
> +		return -ETIMEDOUT;
> +	}
> +
> +	return -EIO;
> +}
> +
> +static inline int do_transfer(struct sdw_bus *bus,
> +			struct sdw_msg *msg, bool page)
> +{
> +	int retry = bus->prop.err_threshold;
> +	int ret, i;
> +
> +	for (ret = 0, i = 0; i <= retry; i++) {

Initializing ret here is a bit messy.  Better to do it outside.

> +		ret = bus->ops->xfer_msg(bus, msg, page);
> +		ret = find_error_code(ret);
> +		/* if cmd is ok or ignored return */
> +		if (ret == 0 || ret == -ENODATA)
> +			return ret;

Hmm, it's not good to use the same variable for representing two
different things.  Either drop the substitution to ret for
bus->ops->xfer_msg() call, or use another variable to make clear which
one is for SDW_CMD_* and which one is for -EXXX.  The former should be
basically an enum.


> +/**
> + * sdw_transfer: Synchronous transfer message to a SDW Slave device
> + *
> + * @bus: SDW bus
> + * @slave: SDW Slave
> + * @msg: SDW message to be xfered
> + */
> +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> +					struct sdw_msg *msg)
> +{
> +	bool page;
> +	int ret;
> +
> +	mutex_lock(&bus->msg_lock);
> +
> +	page = sdw_get_page(slave, msg);
> +
> +	ret = do_transfer(bus, msg, page);
> +	if (ret != 0 && ret != -ENODATA) {
> +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> +				msg->dev_num, ret);
> +		goto error;
> +	}
> +
> +	if (page)
> +		ret = sdw_reset_page(bus, msg->dev_num);
> +
> +error:
> +	mutex_unlock(&bus->msg_lock);
> +
> +	return ret;

So the logic here is that when -ENODATA is returned and page is false,
this function should return -ENODATA to the caller, too, but when page
is set, it returns 0?

> +static inline int sdw_fill_msg(struct sdw_msg *msg, u16 addr,
> +				size_t count, u16 dev_num, u8 flags, u8 *buf)
> +{
> +	msg->addr = (addr >> SDW_REG_SHIFT(SDW_REGADDR));
> +	msg->len = count;
> +	msg->dev_num = dev_num;
> +	msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
> +	msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
> +	msg->flags = flags;
> +	msg->buf = buf;
> +	msg->ssp_sync = false;
> +
> +	return 0;

This function can be void.


thanks,

Takashi

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

* Re: [alsa-devel] [PATCH 08/14] soundwire: Add Slave status handling    helpers
  2017-10-19  3:03 ` [PATCH 08/14] soundwire: Add Slave status handling helpers Vinod Koul
@ 2017-10-19 13:44   ` Takashi Iwai
  2017-10-31 13:04       ` Vinod Koul
  0 siblings, 1 reply; 139+ messages in thread
From: Takashi Iwai @ 2017-10-19 13:44 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, 19 Oct 2017 05:03:24 +0200,
Vinod Koul wrote:
> 
> +static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
> +{
> +	struct sdw_slave *slave;
> +
> +	list_for_each_entry(slave, &bus->slaves, node) {
> +		if (slave->dev_num == i)
> +			return slave;
> +	}
> +
> +	return NULL;

Is this performed always in bus_lock, right?
Better to document it.

> +static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
> +{
> +
> +	if ((slave->id.unique_id != id.unique_id) ||
> +			(slave->id.mfg_id != id.mfg_id) ||
> +			(slave->id.part_id != id.part_id) ||
> +			(slave->id.class_id != id.class_id))

Align indentations.

> +static int sdw_get_device_num(struct sdw_slave *slave)
> +{
> +	bool assigned = false;
> +	int i;
> +
> +	mutex_lock(&slave->bus->bus_lock);
> +	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
> +		if (slave->bus->assigned[i] == true)
> +			continue;
> +
> +		slave->bus->assigned[i] = true;
> +		assigned = true;
> +
> +		/*
> +		 * Do not update dev_num in Slave data structure here,
> +		 * Update once program dev_num is successful
> +		 */
> +		break;

With the bitmap, it's easier, you can use find_next_zero_bit() :)


> +static int sdw_program_device_num(struct sdw_bus *bus)
> +{
> +	u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
> +	unsigned long long addr;

Use u64.

> +	struct sdw_slave *slave;
> +	struct sdw_slave_id id;
> +	struct sdw_msg msg;
> +	bool found = false;
> +	int ret;
> +
> +	/* No Slave, so use raw xfer api */
> +	sdw_fill_msg(&msg, SDW_SCP_DEVID_0, SDW_NUM_DEV_ID_REGISTERS,
> +					0, SDW_MSG_FLAG_READ, buf);
> +
> +	do {
> +		ret = sdw_transfer(bus, NULL, &msg);
> +		if (ret == -ENODATA)
> +			break;
> +		if (ret < 0) {
> +			dev_err(bus->dev, "DEVID read fail:%d\n", ret);
> +			break;

So here we break, and the function returns zero.  Is this the expected
behavior?

> +		}
> +
> +		/*
> +		 * Construct the addr and extract. Cast the higher shift
> +		 * bits to avoid truncation due to size limit.
> +		 */
> +		addr = buf[5] | (buf[4] << 8) | (buf[3] << 16) |
> +			(buf[2] << 24) | ((unsigned long long)buf[1] << 32) |
> +			((unsigned long long)buf[0] << 40);
> +
> +		sdw_extract_slave_id(bus, addr, &id);
> +
> +		/* Now compare with entries */
> +		list_for_each_entry(slave, &bus->slaves, node) {

Isn't this function protected under bus_lock...?

> +			if (sdw_compare_devid(slave, id) == 0) {
> +				found = true;
> +
> +				/*
> +				 * Assign a new dev_num to this Slave and
> +				 * not mark it present. It will be marked
> +				 * present after it reports ATTACHED on new
> +				 * dev_num
> +				 */
> +				ret = sdw_assign_device_num(slave);
> +				if (ret) {
> +					dev_err(slave->bus->dev,
> +						"Assign dev_num failed:%d",
> +						ret);
> +					return ret;
> +				}
> +
> +				break;
> +			}
> +		}
> +
> +		if (found == false) {
> +			/* TODO: Park this device in Group 13 */
> +			dev_err(bus->dev, "Slave Entry not found");

No break here?  Otherwise...

> +		}
> +
> +	} while (ret == 0);

... the outer loop may go endlessly.
This condition doesn't look effective.

> +
> +	return 0;

... and here returns no error?


thanks,

Takashi

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  7:40   ` Takashi Iwai
@ 2017-10-20  5:11       ` Vinod Koul
  2017-10-20  5:11       ` Vinod Koul
  1 sibling, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:11 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, Oct 19, 2017 at 09:40:06AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:18 +0200,
> Vinod Koul wrote:
> > +
> > +config SOUNDWIRE_BUS
> > +	tristate
> > +	default SOUNDWIRE
> > +
> 
> Does it make sense to be tristate?
> Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> Y or N.  If it's Y and others select M, it'll be still Y.

hmmm good point. I think would make sense to make SOUNDWIRE as tristate too,
just like SOUND :)

> > + * sdw_get_device_id: find the matching SoundWire device id
> > + *
> > + * @slave: SoundWire Slave device
> > + * @drv: SoundWire Slave Driver
> 
> Inconsistent upper/lower letters in these two lines.

thanks for spotting, will fix

> > + * The match is done by comparing the mfg_id and part_id from the
> > + * struct sdw_device_id. class_id is unused, as it is a placeholder
> > + * in MIPI Spec.
> > + */
> > +static const struct sdw_device_id *
> > +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> > +{
> > +	const struct sdw_device_id *id = drv->id_table;
> > +
> > +	while (id && id->mfg_id) {
> > +		if (slave->id.mfg_id == id->mfg_id &&
> > +				slave->id.part_id == id->part_id) {
> 
> Please indentation properly.

what do you advise?

		if (slave->id.mfg_id == id->mfg_id &&
			slave->id.part_id == id->part_id) {

would mean below one is at same indent. Some people use:

		if (slave->id.mfg_id == id->mfg_id &&
		   slave->id.part_id == id->part_id) {

Is it Documented anywhere...


> 
> > +			return id;
> > +		}
> 
> Superfluous braces for a single-line.

That bit was intentional. Yes it is not required but given that if condition
was falling to two lines, I wanted to help readability by adding these. I can
remove them..

> 
> > +		id++;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> > +{
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> > +
> > +	return !!sdw_get_device_id(slave, drv);
> > +}
> > +
> > +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> 
> I'd put const to slave argument, as it won't be modified.

right...

> 
> > --- a/include/linux/mod_devicetable.h
> > +++ b/include/linux/mod_devicetable.h
> > @@ -228,6 +228,13 @@ struct hda_device_id {
> >  	unsigned long driver_data;
> >  };
> >  
> > +struct sdw_device_id {
> > +	__u16 mfg_id;
> > +	__u16 part_id;
> > +	__u8 class_id;
> > +	kernel_ulong_t driver_data;
> 
> Better to think of alignment.

sorry not quite clear, do you mind elaborating which ones to align?

> 
> 
> > --- /dev/null
> > +++ b/include/linux/soundwire/sdw.h
> ....
> > +/**
> > + * struct sdw_bus: SoundWire bus
> > + *
> > + * @dev: Master linux device
> > + * @link_id: Link id number, can be 0 to N, unique for each Master
> > + * @slaves: list of Slaves on this bus
> > + * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
> > + * @bus_lock: bus lock
> > + */
> > +struct sdw_bus {
> > +	struct device *dev;
> > +	unsigned int link_id;
> > +	struct list_head slaves;
> > +	bool assigned[SDW_MAX_DEVICES + 1];
> 
> Why not a bitmap?

That a very good suggestion, it will help in other things too :)

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-20  5:11       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:11 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: ALSA, Charles Keepax, Sudheer Papothi, patches.audio,
	Greg Kroah-Hartman, plai, LKML, Pierre, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 09:40:06AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:18 +0200,
> Vinod Koul wrote:
> > +
> > +config SOUNDWIRE_BUS
> > +	tristate
> > +	default SOUNDWIRE
> > +
> 
> Does it make sense to be tristate?
> Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> Y or N.  If it's Y and others select M, it'll be still Y.

hmmm good point. I think would make sense to make SOUNDWIRE as tristate too,
just like SOUND :)

> > + * sdw_get_device_id: find the matching SoundWire device id
> > + *
> > + * @slave: SoundWire Slave device
> > + * @drv: SoundWire Slave Driver
> 
> Inconsistent upper/lower letters in these two lines.

thanks for spotting, will fix

> > + * The match is done by comparing the mfg_id and part_id from the
> > + * struct sdw_device_id. class_id is unused, as it is a placeholder
> > + * in MIPI Spec.
> > + */
> > +static const struct sdw_device_id *
> > +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> > +{
> > +	const struct sdw_device_id *id = drv->id_table;
> > +
> > +	while (id && id->mfg_id) {
> > +		if (slave->id.mfg_id == id->mfg_id &&
> > +				slave->id.part_id == id->part_id) {
> 
> Please indentation properly.

what do you advise?

		if (slave->id.mfg_id == id->mfg_id &&
			slave->id.part_id == id->part_id) {

would mean below one is at same indent. Some people use:

		if (slave->id.mfg_id == id->mfg_id &&
		   slave->id.part_id == id->part_id) {

Is it Documented anywhere...


> 
> > +			return id;
> > +		}
> 
> Superfluous braces for a single-line.

That bit was intentional. Yes it is not required but given that if condition
was falling to two lines, I wanted to help readability by adding these. I can
remove them..

> 
> > +		id++;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> > +{
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> > +
> > +	return !!sdw_get_device_id(slave, drv);
> > +}
> > +
> > +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> 
> I'd put const to slave argument, as it won't be modified.

right...

> 
> > --- a/include/linux/mod_devicetable.h
> > +++ b/include/linux/mod_devicetable.h
> > @@ -228,6 +228,13 @@ struct hda_device_id {
> >  	unsigned long driver_data;
> >  };
> >  
> > +struct sdw_device_id {
> > +	__u16 mfg_id;
> > +	__u16 part_id;
> > +	__u8 class_id;
> > +	kernel_ulong_t driver_data;
> 
> Better to think of alignment.

sorry not quite clear, do you mind elaborating which ones to align?

> 
> 
> > --- /dev/null
> > +++ b/include/linux/soundwire/sdw.h
> ....
> > +/**
> > + * struct sdw_bus: SoundWire bus
> > + *
> > + * @dev: Master linux device
> > + * @link_id: Link id number, can be 0 to N, unique for each Master
> > + * @slaves: list of Slaves on this bus
> > + * @assigned: logical addresses assigned, Index 0 (broadcast) would be unused
> > + * @bus_lock: bus lock
> > + */
> > +struct sdw_bus {
> > +	struct device *dev;
> > +	unsigned int link_id;
> > +	struct list_head slaves;
> > +	bool assigned[SDW_MAX_DEVICES + 1];
> 
> Why not a bitmap?

That a very good suggestion, it will help in other things too :)

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 03/14] soundwire: Add Master registration
  2017-10-19  8:54     ` Takashi Iwai
@ 2017-10-20  5:19       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:19 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 10:54:50AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:19 +0200,
> Vinod Koul wrote:

> > +int sdw_add_bus_master(struct sdw_bus *bus)
> > +{
> > +	int ret;
> > +
> > +	if (!bus->dev) {
> > +		pr_err("SoundWire bus has no device");
> > +		return -ENODEV;
> > +	}
> > +
> > +	mutex_init(&bus->bus_lock);
> > +	INIT_LIST_HEAD(&bus->slaves);
> > +
> > +	/*
> > +	 * SDW is an enumerable bus, but devices can be powered off. So,
> > +	 * they won't be able to report as present.
> > +	 *
> > +	 * Create Slave devices based on Slaves described in
> > +	 * the respective firmware (ACPI/DT)
> > +	 */
> > +
> > +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> > +		ret = sdw_acpi_find_slaves(bus);
> > +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> 
> The bus->dev NULL check is already done at the beginning of the
> function, so here are superfluous.

right

> > +static int sdw_delete_slave(struct device *dev, void *data)
> > +{
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +	struct sdw_bus *bus = slave->bus;
> > +
> > +	mutex_lock(&bus->bus_lock);
> > +	if (!list_empty(&bus->slaves))
> > +		list_del(&slave->node);
> 
> You can perform list_del_init() without empty check.

Better :)

> 
> > +void sdw_extract_slave_id(struct sdw_bus *bus,
> > +			unsigned long long addr, struct sdw_slave_id *id)
> 
> Use u64 instead.

okay

> > +{
> > +	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
> > +
> > +	/*
> > +	 * Spec definition
> > +	 *   Register		Bit	Contents
> > +	 *   DevId_0 [7:4]	47:44	sdw_version
> > +	 *   DevId_0 [3:0]	43:40	unique_id
> > +	 *   DevId_1		39:32	mfg_id [15:8]
> > +	 *   DevId_2		31:24	mfg_id [7:0]
> > +	 *   DevId_3		23:16	part_id [15:8]
> > +	 *   DevId_4		15:08	part_id [7:0]
> > +	 *   DevId_5		07:00	class_id
> > +	 */
> > +	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
> > +	id->unique_id = (addr >> 40) & GENMASK(3, 0);
> > +	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
> > +	id->part_id = (addr >> 8) & GENMASK(15, 0);
> > +	id->class_id = addr & GENMASK(7, 0);
> > +
> > +	dev_info(bus->dev,
> > +		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
> > +				id->class_id, id->part_id, id->mfg_id,
> > +				id->unique_id, id->sdw_version);
> > +
> 
> Do we want to print a message always at each invocation?

Not really, lets make it debug

> > +static int sdw_slave_add(struct sdw_bus *bus,
> > +		struct sdw_slave_id *id, struct fwnode_handle *fwnode)
> > +{
> > +	struct sdw_slave *slave;
> > +	char name[32];
> > +	int ret;
> > +
> > +	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
> > +	if (!slave)
> > +		return -ENOMEM;
> > +
> > +	/* Initialize data structure */
> > +	memcpy(&slave->id, id, sizeof(*id));
> > +
> > +	/* name shall be sdw:link:mfg:part:class:unique */
> > +	snprintf(name, sizeof(name), "sdw:%x:%x:%x:%x:%x",
> > +			bus->link_id, id->mfg_id, id->part_id,
> > +			id->class_id, id->unique_id);
> 
> You can set the name directly via dev_set_name().  It's printf format,
> after all.

right, am using it but with this string :D

> > +	slave->dev.parent = bus->dev;
> > +	slave->dev.fwnode = fwnode;
> > +	dev_set_name(&slave->dev, "%s", name);
> > +	slave->dev.release = sdw_slave_release;
> > +	slave->dev.bus = &sdw_bus_type;
> > +	slave->bus = bus;
> > +	slave->status = SDW_SLAVE_UNATTACHED;
> > +	slave->dev_num = 0;
> > +
> > +	mutex_lock(&bus->bus_lock);
> > +	list_add_tail(&slave->node, &bus->slaves);
> > +	mutex_unlock(&bus->bus_lock);
> > +
> > +	ret = device_register(&slave->dev);
> > +	if (ret) {
> > +		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
> > +
> > +		/*
> > +		 * On err, don't free but drop ref as this will be freed
> > +		 * when release method is invoked.
> > +		 */
> > +		put_device(&slave->dev);
> 
> Wouldn't it leave a stale link to bus?

yes that needs to be removed too, thanks for pointing

-- 
~Vinod

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

* Re: [PATCH 03/14] soundwire: Add Master registration
@ 2017-10-20  5:19       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:19 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Thu, Oct 19, 2017 at 10:54:50AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:19 +0200,
> Vinod Koul wrote:

> > +int sdw_add_bus_master(struct sdw_bus *bus)
> > +{
> > +	int ret;
> > +
> > +	if (!bus->dev) {
> > +		pr_err("SoundWire bus has no device");
> > +		return -ENODEV;
> > +	}
> > +
> > +	mutex_init(&bus->bus_lock);
> > +	INIT_LIST_HEAD(&bus->slaves);
> > +
> > +	/*
> > +	 * SDW is an enumerable bus, but devices can be powered off. So,
> > +	 * they won't be able to report as present.
> > +	 *
> > +	 * Create Slave devices based on Slaves described in
> > +	 * the respective firmware (ACPI/DT)
> > +	 */
> > +
> > +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> > +		ret = sdw_acpi_find_slaves(bus);
> > +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> 
> The bus->dev NULL check is already done at the beginning of the
> function, so here are superfluous.

right

> > +static int sdw_delete_slave(struct device *dev, void *data)
> > +{
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +	struct sdw_bus *bus = slave->bus;
> > +
> > +	mutex_lock(&bus->bus_lock);
> > +	if (!list_empty(&bus->slaves))
> > +		list_del(&slave->node);
> 
> You can perform list_del_init() without empty check.

Better :)

> 
> > +void sdw_extract_slave_id(struct sdw_bus *bus,
> > +			unsigned long long addr, struct sdw_slave_id *id)
> 
> Use u64 instead.

okay

> > +{
> > +	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
> > +
> > +	/*
> > +	 * Spec definition
> > +	 *   Register		Bit	Contents
> > +	 *   DevId_0 [7:4]	47:44	sdw_version
> > +	 *   DevId_0 [3:0]	43:40	unique_id
> > +	 *   DevId_1		39:32	mfg_id [15:8]
> > +	 *   DevId_2		31:24	mfg_id [7:0]
> > +	 *   DevId_3		23:16	part_id [15:8]
> > +	 *   DevId_4		15:08	part_id [7:0]
> > +	 *   DevId_5		07:00	class_id
> > +	 */
> > +	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
> > +	id->unique_id = (addr >> 40) & GENMASK(3, 0);
> > +	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
> > +	id->part_id = (addr >> 8) & GENMASK(15, 0);
> > +	id->class_id = addr & GENMASK(7, 0);
> > +
> > +	dev_info(bus->dev,
> > +		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
> > +				id->class_id, id->part_id, id->mfg_id,
> > +				id->unique_id, id->sdw_version);
> > +
> 
> Do we want to print a message always at each invocation?

Not really, lets make it debug

> > +static int sdw_slave_add(struct sdw_bus *bus,
> > +		struct sdw_slave_id *id, struct fwnode_handle *fwnode)
> > +{
> > +	struct sdw_slave *slave;
> > +	char name[32];
> > +	int ret;
> > +
> > +	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
> > +	if (!slave)
> > +		return -ENOMEM;
> > +
> > +	/* Initialize data structure */
> > +	memcpy(&slave->id, id, sizeof(*id));
> > +
> > +	/* name shall be sdw:link:mfg:part:class:unique */
> > +	snprintf(name, sizeof(name), "sdw:%x:%x:%x:%x:%x",
> > +			bus->link_id, id->mfg_id, id->part_id,
> > +			id->class_id, id->unique_id);
> 
> You can set the name directly via dev_set_name().  It's printf format,
> after all.

right, am using it but with this string :D

> > +	slave->dev.parent = bus->dev;
> > +	slave->dev.fwnode = fwnode;
> > +	dev_set_name(&slave->dev, "%s", name);
> > +	slave->dev.release = sdw_slave_release;
> > +	slave->dev.bus = &sdw_bus_type;
> > +	slave->bus = bus;
> > +	slave->status = SDW_SLAVE_UNATTACHED;
> > +	slave->dev_num = 0;
> > +
> > +	mutex_lock(&bus->bus_lock);
> > +	list_add_tail(&slave->node, &bus->slaves);
> > +	mutex_unlock(&bus->bus_lock);
> > +
> > +	ret = device_register(&slave->dev);
> > +	if (ret) {
> > +		dev_err(bus->dev, "Failed to add slave: ret %d\n", ret);
> > +
> > +		/*
> > +		 * On err, don't free but drop ref as this will be freed
> > +		 * when release method is invoked.
> > +		 */
> > +		put_device(&slave->dev);
> 
> Wouldn't it leave a stale link to bus?

yes that needs to be removed too, thanks for pointing

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
  2017-10-19  9:02   ` [alsa-devel] " Takashi Iwai
@ 2017-10-20  5:25     ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:25 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 11:02:02AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:20 +0200,
> Vinod Koul wrote:
> >  
> > +	slave->ops = drv->ops;
> > +
> >  	ret = drv->probe(slave, id);
> >  	if (ret) {
> >  		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> >  		return ret;
> >  	}
> >  
> > +	/* device is probed so let's read the properties now */
> > +	if (slave->ops && slave->ops->read_prop)
> > +		slave->ops->read_prop(slave);
> > +
> > +	/*
> > +	 * Check for valid clk_stop_timeout, use DisCo worst case value of
> > +	 * 300ms
> > +	 */
> > +	if (slave->prop.clk_stop_timeout == 0)
> > +		slave->prop.clk_stop_timeout = 300;
> > +
> > +	slave->bus->clk_stop_timeout = max_t(u32, slave->bus->clk_stop_timeout,
> > +					slave->prop.clk_stop_timeout);
> 
> Isn't it racy?
> Also what happens after removing a driver?  The clk_stop_timeout is
> kept high?

Well the spec mandates 300 as worst case, in practice this _should_ be
lesser. I need to double check on behaviour of clock stop on driver removal.
We need to keep in mind that multiple Slaves can be on a bus and removal
maybe from one of them, so we may not do clock stop.

> > +
> > +int sdw_slave_read_dpn(struct sdw_slave *slave,
> > +		struct sdw_dpn_prop *dpn, int count, int ports, char *type)
> 
> Missing comment for a public API function.

Ah missed this one. It was made public for debug, lets make it static now :)

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 06/14] soundwire: Add IO transfer
  2017-10-19  9:13   ` [alsa-devel] " Takashi Iwai
@ 2017-10-20  5:30       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:30 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Thu, Oct 19, 2017 at 11:13:48AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:22 +0200,
> Vinod Koul wrote:
> > 
> > +static inline int find_error_code(unsigned int sdw_ret)
> > +{
> > +	switch (sdw_ret) {
> > +	case SDW_CMD_OK:
> > +		return 0;
> > +
> > +	case SDW_CMD_IGNORED:
> > +		return -ENODATA;
> > +
> > +	case SDW_CMD_TIMEOUT:
> > +		return -ETIMEDOUT;
> > +	}
> > +
> > +	return -EIO;
> > +}
> > +
> > +static inline int do_transfer(struct sdw_bus *bus,
> > +			struct sdw_msg *msg, bool page)
> > +{
> > +	int retry = bus->prop.err_threshold;
> > +	int ret, i;
> > +
> > +	for (ret = 0, i = 0; i <= retry; i++) {
> 
> Initializing ret here is a bit messy.  Better to do it outside.

sounds good

> > +		ret = bus->ops->xfer_msg(bus, msg, page);
> > +		ret = find_error_code(ret);
> > +		/* if cmd is ok or ignored return */
> > +		if (ret == 0 || ret == -ENODATA)
> > +			return ret;
> 
> Hmm, it's not good to use the same variable for representing two
> different things.  Either drop the substitution to ret for
> bus->ops->xfer_msg() call, or use another variable to make clear which
> one is for SDW_CMD_* and which one is for -EXXX.  The former should be
> basically an enum.

yes will do, sometimes we should not reuse :)

> > +/**
> > + * sdw_transfer: Synchronous transfer message to a SDW Slave device
> > + *
> > + * @bus: SDW bus
> > + * @slave: SDW Slave
> > + * @msg: SDW message to be xfered
> > + */
> > +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> > +					struct sdw_msg *msg)
> > +{
> > +	bool page;
> > +	int ret;
> > +
> > +	mutex_lock(&bus->msg_lock);
> > +
> > +	page = sdw_get_page(slave, msg);
> > +
> > +	ret = do_transfer(bus, msg, page);
> > +	if (ret != 0 && ret != -ENODATA) {
> > +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> > +				msg->dev_num, ret);
> > +		goto error;
> > +	}
> > +
> > +	if (page)
> > +		ret = sdw_reset_page(bus, msg->dev_num);
> > +
> > +error:
> > +	mutex_unlock(&bus->msg_lock);
> > +
> > +	return ret;
> 
> So the logic here is that when -ENODATA is returned and page is false,
> this function should return -ENODATA to the caller,  but when page
> is set, it returns 0?

Sorry no. do_transfer can succced (0) or in some case where Slaves didn't
care for return error (ENODATA), or other errors.
No ENODATA can be error depending on message sent so we dont treat this as
failure and let caller decide.

In case of errors (others) we don't need to reset page and we bail out

> 
> > +static inline int sdw_fill_msg(struct sdw_msg *msg, u16 addr,
> > +				size_t count, u16 dev_num, u8 flags, u8 *buf)
> > +{
> > +	msg->addr = (addr >> SDW_REG_SHIFT(SDW_REGADDR));
> > +	msg->len = count;
> > +	msg->dev_num = dev_num;
> > +	msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
> > +	msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
> > +	msg->flags = flags;
> > +	msg->buf = buf;
> > +	msg->ssp_sync = false;
> > +
> > +	return 0;
> 
> This function can be void.

yup

-- 
~Vinod

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

* Re: [PATCH 06/14] soundwire: Add IO transfer
@ 2017-10-20  5:30       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20  5:30 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: ALSA, Charles Keepax, Sudheer Papothi, patches.audio,
	Greg Kroah-Hartman, plai, LKML, Pierre, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 11:13:48AM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:22 +0200,
> Vinod Koul wrote:
> > 
> > +static inline int find_error_code(unsigned int sdw_ret)
> > +{
> > +	switch (sdw_ret) {
> > +	case SDW_CMD_OK:
> > +		return 0;
> > +
> > +	case SDW_CMD_IGNORED:
> > +		return -ENODATA;
> > +
> > +	case SDW_CMD_TIMEOUT:
> > +		return -ETIMEDOUT;
> > +	}
> > +
> > +	return -EIO;
> > +}
> > +
> > +static inline int do_transfer(struct sdw_bus *bus,
> > +			struct sdw_msg *msg, bool page)
> > +{
> > +	int retry = bus->prop.err_threshold;
> > +	int ret, i;
> > +
> > +	for (ret = 0, i = 0; i <= retry; i++) {
> 
> Initializing ret here is a bit messy.  Better to do it outside.

sounds good

> > +		ret = bus->ops->xfer_msg(bus, msg, page);
> > +		ret = find_error_code(ret);
> > +		/* if cmd is ok or ignored return */
> > +		if (ret == 0 || ret == -ENODATA)
> > +			return ret;
> 
> Hmm, it's not good to use the same variable for representing two
> different things.  Either drop the substitution to ret for
> bus->ops->xfer_msg() call, or use another variable to make clear which
> one is for SDW_CMD_* and which one is for -EXXX.  The former should be
> basically an enum.

yes will do, sometimes we should not reuse :)

> > +/**
> > + * sdw_transfer: Synchronous transfer message to a SDW Slave device
> > + *
> > + * @bus: SDW bus
> > + * @slave: SDW Slave
> > + * @msg: SDW message to be xfered
> > + */
> > +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> > +					struct sdw_msg *msg)
> > +{
> > +	bool page;
> > +	int ret;
> > +
> > +	mutex_lock(&bus->msg_lock);
> > +
> > +	page = sdw_get_page(slave, msg);
> > +
> > +	ret = do_transfer(bus, msg, page);
> > +	if (ret != 0 && ret != -ENODATA) {
> > +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> > +				msg->dev_num, ret);
> > +		goto error;
> > +	}
> > +
> > +	if (page)
> > +		ret = sdw_reset_page(bus, msg->dev_num);
> > +
> > +error:
> > +	mutex_unlock(&bus->msg_lock);
> > +
> > +	return ret;
> 
> So the logic here is that when -ENODATA is returned and page is false,
> this function should return -ENODATA to the caller,  but when page
> is set, it returns 0?

Sorry no. do_transfer can succced (0) or in some case where Slaves didn't
care for return error (ENODATA), or other errors.
No ENODATA can be error depending on message sent so we dont treat this as
failure and let caller decide.

In case of errors (others) we don't need to reset page and we bail out

> 
> > +static inline int sdw_fill_msg(struct sdw_msg *msg, u16 addr,
> > +				size_t count, u16 dev_num, u8 flags, u8 *buf)
> > +{
> > +	msg->addr = (addr >> SDW_REG_SHIFT(SDW_REGADDR));
> > +	msg->len = count;
> > +	msg->dev_num = dev_num;
> > +	msg->addr_page1 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE1_MASK));
> > +	msg->addr_page2 = (addr >> SDW_REG_SHIFT(SDW_SCP_ADDRPAGE2_MASK));
> > +	msg->flags = flags;
> > +	msg->buf = buf;
> > +	msg->ssp_sync = false;
> > +
> > +	return 0;
> 
> This function can be void.

yup

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20  5:11       ` Vinod Koul
  (?)
@ 2017-10-20  6:59       ` Takashi Iwai
  2017-10-20 15:46         ` Vinod Koul
  -1 siblings, 1 reply; 139+ messages in thread
From: Takashi Iwai @ 2017-10-20  6:59 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, 20 Oct 2017 07:11:01 +0200,
Vinod Koul wrote:
> 
> On Thu, Oct 19, 2017 at 09:40:06AM +0200, Takashi Iwai wrote:
> > On Thu, 19 Oct 2017 05:03:18 +0200,
> > Vinod Koul wrote:
> > > +
> > > +config SOUNDWIRE_BUS
> > > +	tristate
> > > +	default SOUNDWIRE
> > > +
> > 
> > Does it make sense to be tristate?
> > Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> > Y or N.  If it's Y and others select M, it'll be still Y.
> 
> hmmm good point. I think would make sense to make SOUNDWIRE as tristate too,
> just like SOUND :)

It's one option.  Another would be to simply drop the "default" line.

> > > + * The match is done by comparing the mfg_id and part_id from the
> > > + * struct sdw_device_id. class_id is unused, as it is a placeholder
> > > + * in MIPI Spec.
> > > + */
> > > +static const struct sdw_device_id *
> > > +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> > > +{
> > > +	const struct sdw_device_id *id = drv->id_table;
> > > +
> > > +	while (id && id->mfg_id) {
> > > +		if (slave->id.mfg_id == id->mfg_id &&
> > > +				slave->id.part_id == id->part_id) {
> > 
> > Please indentation properly.
> 
> what do you advise?
> 
> 		if (slave->id.mfg_id == id->mfg_id &&
> 			slave->id.part_id == id->part_id) {
> 
> would mean below one is at same indent. Some people use:
> 
> 		if (slave->id.mfg_id == id->mfg_id &&
> 		   slave->id.part_id == id->part_id) {
> 
> Is it Documented anywhere...

This is a matter of taste.  The latter is the way Emacs or indent does
as default.

> > > --- a/include/linux/mod_devicetable.h
> > > +++ b/include/linux/mod_devicetable.h
> > > @@ -228,6 +228,13 @@ struct hda_device_id {
> > >  	unsigned long driver_data;
> > >  };
> > >  
> > > +struct sdw_device_id {
> > > +	__u16 mfg_id;
> > > +	__u16 part_id;
> > > +	__u8 class_id;
> > > +	kernel_ulong_t driver_data;
> > 
> > Better to think of alignment.
> 
> sorry not quite clear, do you mind elaborating which ones to align?

kernel_ulong_t may be aligned to 4 or 8 bytes, depending on
architecture, so there can be a hole between class_id and driver_data.
It's not an ABI, so we don't have to care too much, but it's still
something exposed, hence better to be conscious about alignment.


Takashi

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

* Re: [alsa-devel] [PATCH 06/14] soundwire: Add IO transfer
  2017-10-20  5:30       ` Vinod Koul
@ 2017-10-20  7:06         ` Takashi Iwai
  -1 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-20  7:06 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Fri, 20 Oct 2017 07:30:06 +0200,
Vinod Koul wrote:
> 
> On Thu, Oct 19, 2017 at 11:13:48AM +0200, Takashi Iwai wrote:
> > On Thu, 19 Oct 2017 05:03:22 +0200,
> > Vinod Koul wrote:
> > > 
> > > +/**
> > > + * sdw_transfer: Synchronous transfer message to a SDW Slave device
> > > + *
> > > + * @bus: SDW bus
> > > + * @slave: SDW Slave
> > > + * @msg: SDW message to be xfered
> > > + */
> > > +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> > > +					struct sdw_msg *msg)
> > > +{
> > > +	bool page;
> > > +	int ret;
> > > +
> > > +	mutex_lock(&bus->msg_lock);
> > > +
> > > +	page = sdw_get_page(slave, msg);
> > > +
> > > +	ret = do_transfer(bus, msg, page);
> > > +	if (ret != 0 && ret != -ENODATA) {
> > > +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> > > +				msg->dev_num, ret);
> > > +		goto error;
> > > +	}
> > > +
> > > +	if (page)
> > > +		ret = sdw_reset_page(bus, msg->dev_num);
> > > +
> > > +error:
> > > +	mutex_unlock(&bus->msg_lock);
> > > +
> > > +	return ret;
> > 
> > So the logic here is that when -ENODATA is returned and page is false,
> > this function should return -ENODATA to the caller,  but when page
> > is set, it returns 0?
> 
> Sorry no. do_transfer can succced (0) or in some case where Slaves didn't
> care for return error (ENODATA), or other errors.
> No ENODATA can be error depending on message sent so we dont treat this as
> failure and let caller decide.
> 
> In case of errors (others) we don't need to reset page and we bail out

Well, the question is the handling of ENODATA.  Whether the function
returns 0 or -ENODATA depends on page flag.  If page flag is true,
-ENODATA is cleared.  My question was whether this behavior is
intended or not.

If -ENODATA should be returned whenever it gets that from
do_transfer(), the code has a potential bug there.


Takashi

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

* Re: [PATCH 06/14] soundwire: Add IO transfer
@ 2017-10-20  7:06         ` Takashi Iwai
  0 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-20  7:06 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, patches.audio,
	Greg Kroah-Hartman, plai, LKML, Pierre, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Fri, 20 Oct 2017 07:30:06 +0200,
Vinod Koul wrote:
> 
> On Thu, Oct 19, 2017 at 11:13:48AM +0200, Takashi Iwai wrote:
> > On Thu, 19 Oct 2017 05:03:22 +0200,
> > Vinod Koul wrote:
> > > 
> > > +/**
> > > + * sdw_transfer: Synchronous transfer message to a SDW Slave device
> > > + *
> > > + * @bus: SDW bus
> > > + * @slave: SDW Slave
> > > + * @msg: SDW message to be xfered
> > > + */
> > > +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> > > +					struct sdw_msg *msg)
> > > +{
> > > +	bool page;
> > > +	int ret;
> > > +
> > > +	mutex_lock(&bus->msg_lock);
> > > +
> > > +	page = sdw_get_page(slave, msg);
> > > +
> > > +	ret = do_transfer(bus, msg, page);
> > > +	if (ret != 0 && ret != -ENODATA) {
> > > +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> > > +				msg->dev_num, ret);
> > > +		goto error;
> > > +	}
> > > +
> > > +	if (page)
> > > +		ret = sdw_reset_page(bus, msg->dev_num);
> > > +
> > > +error:
> > > +	mutex_unlock(&bus->msg_lock);
> > > +
> > > +	return ret;
> > 
> > So the logic here is that when -ENODATA is returned and page is false,
> > this function should return -ENODATA to the caller,  but when page
> > is set, it returns 0?
> 
> Sorry no. do_transfer can succced (0) or in some case where Slaves didn't
> care for return error (ENODATA), or other errors.
> No ENODATA can be error depending on message sent so we dont treat this as
> failure and let caller decide.
> 
> In case of errors (others) we don't need to reset page and we bail out

Well, the question is the handling of ENODATA.  Whether the function
returns 0 or -ENODATA depends on page flag.  If page flag is true,
-ENODATA is cleared.  My question was whether this behavior is
intended or not.

If -ENODATA should be returned whenever it gets that from
do_transfer(), the code has a potential bug there.


Takashi

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-19  3:03 ` [PATCH 01/14] Documentation: Add SoundWire summary Vinod Koul
@ 2017-10-20 10:39     ` Greg Kroah-Hartman
  2017-10-20 10:39     ` Greg Kroah-Hartman
  2017-10-21  8:57     ` Mark Brown
  2 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 10:39 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> From: Sanyog Kale <sanyog.r.kale@intel.com>
> 
> SoundWire is a new Linux bus which implements a new MIPI bus protocol
> 'SoundWire'. The summary of SoundWire bus and registration APIs is
> documented in the 'summary' file.
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 192 insertions(+)
>  create mode 100644 Documentation/soundwire/summary.txt

Any specific reason this is not in .rst format and tied to the rest of
the kernel Documentation so it gets built automatically?

thanks,

greg k-h

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-20 10:39     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 10:39 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> From: Sanyog Kale <sanyog.r.kale@intel.com>
> 
> SoundWire is a new Linux bus which implements a new MIPI bus protocol
> 'SoundWire'. The summary of SoundWire bus and registration APIs is
> documented in the 'summary' file.
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---
>  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 192 insertions(+)
>  create mode 100644 Documentation/soundwire/summary.txt

Any specific reason this is not in .rst format and tied to the rest of
the kernel Documentation so it gets built automatically?

thanks,

greg k-h

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  3:03 ` [PATCH 02/14] soundwire: Add SoundWire bus type Vinod Koul
@ 2017-10-20 10:41     ` Greg Kroah-Hartman
  2017-10-20 10:41     ` Greg Kroah-Hartman
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 10:41 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> new file mode 100644
> index 000000000000..2683c6798b95
> --- /dev/null
> +++ b/drivers/soundwire/bus.h
> @@ -0,0 +1,62 @@
> +/*
> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> + *  redistributing this file, you may do so under either license.
> + *
> + *  GPL LICENSE SUMMARY
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of version 2 of the GNU General Public License 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.
> + *
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Intel Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +#ifndef __SDW_BUS_H
> +#define __SDW_BUS_H
> +
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/acpi.h>
> +#include <linux/soundwire/sdw.h>
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> +
> +#endif /* __SDW_BUS_H */

When your header boiler-plate text is bigger than the content, please
reconsider it.  Are you sure you need this .h file?  Why?

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-20 10:41     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 10:41 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> new file mode 100644
> index 000000000000..2683c6798b95
> --- /dev/null
> +++ b/drivers/soundwire/bus.h
> @@ -0,0 +1,62 @@
> +/*
> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> + *  redistributing this file, you may do so under either license.
> + *
> + *  GPL LICENSE SUMMARY
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of version 2 of the GNU General Public License 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.
> + *
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Intel Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
> +
> +#ifndef __SDW_BUS_H
> +#define __SDW_BUS_H
> +
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/acpi.h>
> +#include <linux/soundwire/sdw.h>
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> +
> +#endif /* __SDW_BUS_H */

When your header boiler-plate text is bigger than the content, please
reconsider it.  Are you sure you need this .h file?  Why?

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  3:03 ` [PATCH 02/14] soundwire: Add SoundWire bus type Vinod Koul
  2017-10-19  7:40   ` Takashi Iwai
  2017-10-20 10:41     ` Greg Kroah-Hartman
@ 2017-10-20 10:45   ` Greg Kroah-Hartman
  2017-10-20 16:01     ` Vinod Koul
  2017-10-20 16:03     ` Philippe Ombredanne
  2017-10-21  9:03   ` Mark Brown
  2017-11-09 21:14     ` Srinivas Kandagatla
  4 siblings, 2 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 10:45 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> new file mode 100644
> index 000000000000..a14d1de80afa
> --- /dev/null
> +++ b/drivers/soundwire/bus_type.c
> @@ -0,0 +1,229 @@
> +/*
> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> + *  redistributing this file, you may do so under either license.
> + *
> + *  GPL LICENSE SUMMARY
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of version 2 of the GNU General Public License 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.
> + *
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Intel Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Are you _sure_ that code that interacts with the driver core can have a
dual-license here?  Have you explained to lawyers what you are doing
here (wrapping gpl-only symbols with non-gpl-only exports)?

And why dual license something that will only ever work on Linux?

And finally, put a real SPDX header up there so that people don't have
to parse that horrid amount of text to try to determine exactly what
that license is.


> + *
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/soundwire/sdw.h>
> +#include "bus.h"
> +
> +/**
> + * sdw_get_device_id: find the matching SoundWire device id
> + *
> + * @slave: SoundWire Slave device
> + * @drv: SoundWire Slave Driver
> + *
> + * The match is done by comparing the mfg_id and part_id from the
> + * struct sdw_device_id. class_id is unused, as it is a placeholder
> + * in MIPI Spec.
> + */
> +static const struct sdw_device_id *
> +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> +{
> +	const struct sdw_device_id *id = drv->id_table;
> +
> +	while (id && id->mfg_id) {
> +		if (slave->id.mfg_id == id->mfg_id &&
> +				slave->id.part_id == id->part_id) {
> +			return id;
> +		}
> +		id++;
> +	}
> +
> +	return NULL;
> +}
> +
> +static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> +
> +	return !!sdw_get_device_id(slave, drv);
> +}
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> +{
> +	/* modalias is sdw:m<mfg_id>p<part_id> */
> +
> +	return snprintf(buf, size, "sdw:m%04Xp%04X\n",
> +			slave->id.mfg_id, slave->id.part_id);
> +}
> +
> +static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	char modalias[32];
> +
> +	sdw_slave_modalias(slave, modalias, sizeof(modalias));
> +
> +	if (add_uevent_var(env, "MODALIAS=%s", modalias))
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +struct bus_type sdw_bus_type = {
> +	.name = "soundwire",
> +	.match = sdw_bus_match,
> +	.uevent = sdw_uevent,
> +};
> +EXPORT_SYMBOL(sdw_bus_type);

EXPORT_SYMBOL_GPL()?

No release callback?  Who frees the device?

> +
> +static int sdw_drv_probe(struct device *dev)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> +	const struct sdw_device_id *id;
> +	int ret;
> +
> +	id = sdw_get_device_id(slave, drv);
> +	if (!id)
> +		return -ENODEV;
> +
> +	/*
> +	 * attach to power domain but don't turn on (last arg)
> +	 */
> +	ret = dev_pm_domain_attach(dev, false);
> +	if (ret) {
> +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drv->probe(slave, id);
> +	if (ret) {
> +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int sdw_drv_remove(struct device *dev)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> +
> +	if (drv->remove)
> +		drv->remove(slave);

No catching the error value?

> +
> +	dev_pm_domain_detach(dev, false);
> +
> +	return 0;
> +}
> +
> +static void sdw_drv_shutdown(struct device *dev)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> +
> +	if (drv->shutdown)
> +		drv->shutdown(slave);
> +}
> +
> +/**
> + * __sdw_register_driver - register a SoundWire Slave driver
> + *
> + * @drv: driver to register
> + * @owner: owning module/driver
> + *
> + * Return: zero on success, else a negative error code.
> + */
> +int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
> +{
> +	drv->driver.bus = &sdw_bus_type;
> +
> +	if (!drv->probe) {
> +		pr_err("driver %s didn't provide SDW probe routine\n",
> +							drv->name);
> +		return -EINVAL;
> +	}
> +
> +	drv->driver.owner = owner;
> +	drv->driver.probe = sdw_drv_probe;
> +
> +	if (drv->remove)
> +		drv->driver.remove = sdw_drv_remove;
> +
> +	if (drv->shutdown)
> +		drv->driver.shutdown = sdw_drv_shutdown;
> +
> +	return driver_register(&drv->driver);
> +}
> +EXPORT_SYMBOL(__sdw_register_driver);
> +
> +/*
> + * sdw_unregister_driver: unregisters the SoundWire Slave driver
> + *
> + * @drv: driver to unregister
> + */
> +void sdw_unregister_driver(struct sdw_driver *drv)
> +{
> +	driver_unregister(&drv->driver);
> +}
> +EXPORT_SYMBOL(sdw_unregister_driver);

EXPORT_SYMBOL_GPL()?  Same for all the exports here (I have to ask,
especially given what you are wrapping...)

thanks,

greg k-h

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-19  3:03   ` Vinod Koul
  (?)
  (?)
@ 2017-10-20 10:47   ` Greg Kroah-Hartman
  2017-10-20 16:05     ` Vinod Koul
  -1 siblings, 1 reply; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 10:47 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:
> +void sdw_extract_slave_id(struct sdw_bus *bus,
> +			unsigned long long addr, struct sdw_slave_id *id)
> +{
> +	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
> +
> +	/*
> +	 * Spec definition
> +	 *   Register		Bit	Contents
> +	 *   DevId_0 [7:4]	47:44	sdw_version
> +	 *   DevId_0 [3:0]	43:40	unique_id
> +	 *   DevId_1		39:32	mfg_id [15:8]
> +	 *   DevId_2		31:24	mfg_id [7:0]
> +	 *   DevId_3		23:16	part_id [15:8]
> +	 *   DevId_4		15:08	part_id [7:0]
> +	 *   DevId_5		07:00	class_id
> +	 */
> +	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
> +	id->unique_id = (addr >> 40) & GENMASK(3, 0);
> +	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
> +	id->part_id = (addr >> 8) & GENMASK(15, 0);
> +	id->class_id = addr & GENMASK(7, 0);
> +
> +	dev_info(bus->dev,
> +		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
> +				id->class_id, id->part_id, id->mfg_id,
> +				id->unique_id, id->sdw_version);
> +

Why are you so noisy?  Shouldn't this be dev_dbg()?


> +static void sdw_slave_release(struct device *dev)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +
> +	kfree(slave);
> +}

Ah, finally a release function, nice.  But that's all you need to do for
it?

thanks,

greg k-h

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20  6:59       ` Takashi Iwai
@ 2017-10-20 15:46         ` Vinod Koul
  2017-10-20 15:50             ` Takashi Iwai
  0 siblings, 1 reply; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 15:46 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 08:59:42AM +0200, Takashi Iwai wrote:
> On Fri, 20 Oct 2017 07:11:01 +0200,
> Vinod Koul wrote:
> > 
> > On Thu, Oct 19, 2017 at 09:40:06AM +0200, Takashi Iwai wrote:
> > > On Thu, 19 Oct 2017 05:03:18 +0200,
> > > Vinod Koul wrote:
> > > > +
> > > > +config SOUNDWIRE_BUS
> > > > +	tristate
> > > > +	default SOUNDWIRE
> > > > +
> > > 
> > > Does it make sense to be tristate?
> > > Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> > > Y or N.  If it's Y and others select M, it'll be still Y.
> > 
> > hmmm good point. I think would make sense to make SOUNDWIRE as tristate too,
> > just like SOUND :)
> 
> It's one option.  Another would be to simply drop the "default" line.

Okay good suggestion

> > > > + * The match is done by comparing the mfg_id and part_id from the
> > > > + * struct sdw_device_id. class_id is unused, as it is a placeholder
> > > > + * in MIPI Spec.
> > > > + */
> > > > +static const struct sdw_device_id *
> > > > +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> > > > +{
> > > > +	const struct sdw_device_id *id = drv->id_table;
> > > > +
> > > > +	while (id && id->mfg_id) {
> > > > +		if (slave->id.mfg_id == id->mfg_id &&
> > > > +				slave->id.part_id == id->part_id) {
> > > 
> > > Please indentation properly.
> > 
> > what do you advise?
> > 
> > 		if (slave->id.mfg_id == id->mfg_id &&
> > 			slave->id.part_id == id->part_id) {
> > 
> > would mean below one is at same indent. Some people use:
> > 
> > 		if (slave->id.mfg_id == id->mfg_id &&
> > 		   slave->id.part_id == id->part_id) {
> > 
> > Is it Documented anywhere...
> 
> This is a matter of taste.  The latter is the way Emacs or indent does
> as default.

okay as vi user I will try to do above :)

> 
> > > > --- a/include/linux/mod_devicetable.h
> > > > +++ b/include/linux/mod_devicetable.h
> > > > @@ -228,6 +228,13 @@ struct hda_device_id {
> > > >  	unsigned long driver_data;
> > > >  };
> > > >  
> > > > +struct sdw_device_id {
> > > > +	__u16 mfg_id;
> > > > +	__u16 part_id;
> > > > +	__u8 class_id;
> > > > +	kernel_ulong_t driver_data;
> > > 
> > > Better to think of alignment.
> > 
> > sorry not quite clear, do you mind elaborating which ones to align?
> 
> kernel_ulong_t may be aligned to 4 or 8 bytes, depending on
> architecture, so there can be a hole between class_id and driver_data.
> It's not an ABI, so we don't have to care too much, but it's still
> something exposed, hence better to be conscious about alignment.

ah :) is that why hda is unsigned long :) Btw doesnt that cause compat
issues, should we not do something like u64 here?

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 06/14] soundwire: Add IO transfer
  2017-10-20  7:06         ` Takashi Iwai
  (?)
@ 2017-10-20 15:48         ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 15:48 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Fri, Oct 20, 2017 at 09:06:13AM +0200, Takashi Iwai wrote:
> On Fri, 20 Oct 2017 07:30:06 +0200,
> Vinod Koul wrote:
> > 
> > On Thu, Oct 19, 2017 at 11:13:48AM +0200, Takashi Iwai wrote:
> > > On Thu, 19 Oct 2017 05:03:22 +0200,
> > > Vinod Koul wrote:
> > > > 
> > > > +/**
> > > > + * sdw_transfer: Synchronous transfer message to a SDW Slave device
> > > > + *
> > > > + * @bus: SDW bus
> > > > + * @slave: SDW Slave
> > > > + * @msg: SDW message to be xfered
> > > > + */
> > > > +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> > > > +					struct sdw_msg *msg)
> > > > +{
> > > > +	bool page;
> > > > +	int ret;
> > > > +
> > > > +	mutex_lock(&bus->msg_lock);
> > > > +
> > > > +	page = sdw_get_page(slave, msg);
> > > > +
> > > > +	ret = do_transfer(bus, msg, page);
> > > > +	if (ret != 0 && ret != -ENODATA) {
> > > > +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> > > > +				msg->dev_num, ret);
> > > > +		goto error;
> > > > +	}
> > > > +
> > > > +	if (page)
> > > > +		ret = sdw_reset_page(bus, msg->dev_num);
> > > > +
> > > > +error:
> > > > +	mutex_unlock(&bus->msg_lock);
> > > > +
> > > > +	return ret;
> > > 
> > > So the logic here is that when -ENODATA is returned and page is false,
> > > this function should return -ENODATA to the caller,  but when page
> > > is set, it returns 0?
> > 
> > Sorry no. do_transfer can succced (0) or in some case where Slaves didn't
> > care for return error (ENODATA), or other errors.
> > No ENODATA can be error depending on message sent so we dont treat this as
> > failure and let caller decide.
> > 
> > In case of errors (others) we don't need to reset page and we bail out
> 
> Well, the question is the handling of ENODATA.  Whether the function
> returns 0 or -ENODATA depends on page flag.  If page flag is true,
> -ENODATA is cleared.  My question was whether this behavior is
> intended or not.
> 
> If -ENODATA should be returned whenever it gets that from
> do_transfer(), the code has a potential bug there.

Ah right, the return from do_transfer needs to preserved in that case. I
will fix that up, thanks for spotting :)

-- 
~Vinod

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-20 10:39     ` Greg Kroah-Hartman
@ 2017-10-20 15:49       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 15:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 12:39:34PM +0200, Greg Kroah-Hartman wrote:
> On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> > From: Sanyog Kale <sanyog.r.kale@intel.com>
> > 
> > SoundWire is a new Linux bus which implements a new MIPI bus protocol
> > 'SoundWire'. The summary of SoundWire bus and registration APIs is
> > documented in the 'summary' file.
> > 
> > Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > ---
> >  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 192 insertions(+)
> >  create mode 100644 Documentation/soundwire/summary.txt
> 
> Any specific reason this is not in .rst format and tied to the rest of
> the kernel Documentation so it gets built automatically?

I was hoping to do rst conversion a bit later if that is not a deal
breaker :) That is certainly a todo in my list.

-- 
~Vinod

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-20 15:49       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 15:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 12:39:34PM +0200, Greg Kroah-Hartman wrote:
> On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> > From: Sanyog Kale <sanyog.r.kale@intel.com>
> > 
> > SoundWire is a new Linux bus which implements a new MIPI bus protocol
> > 'SoundWire'. The summary of SoundWire bus and registration APIs is
> > documented in the 'summary' file.
> > 
> > Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > ---
> >  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 192 insertions(+)
> >  create mode 100644 Documentation/soundwire/summary.txt
> 
> Any specific reason this is not in .rst format and tied to the rest of
> the kernel Documentation so it gets built automatically?

I was hoping to do rst conversion a bit later if that is not a deal
breaker :) That is certainly a todo in my list.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 15:46         ` Vinod Koul
@ 2017-10-20 15:50             ` Takashi Iwai
  0 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-20 15:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, 20 Oct 2017 17:46:49 +0200,
Vinod Koul wrote:
> 
> On Fri, Oct 20, 2017 at 08:59:42AM +0200, Takashi Iwai wrote:
> > On Fri, 20 Oct 2017 07:11:01 +0200,
> > Vinod Koul wrote:
> > > 
> > > On Thu, Oct 19, 2017 at 09:40:06AM +0200, Takashi Iwai wrote:
> > > > On Thu, 19 Oct 2017 05:03:18 +0200,
> > > > Vinod Koul wrote:
> > > > > +
> > > > > +config SOUNDWIRE_BUS
> > > > > +	tristate
> > > > > +	default SOUNDWIRE
> > > > > +
> > > > 
> > > > Does it make sense to be tristate?
> > > > Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> > > > Y or N.  If it's Y and others select M, it'll be still Y.
> > > 
> > > hmmm good point. I think would make sense to make SOUNDWIRE as tristate too,
> > > just like SOUND :)
> > 
> > It's one option.  Another would be to simply drop the "default" line.
> 
> Okay good suggestion
> 
> > > > > + * The match is done by comparing the mfg_id and part_id from the
> > > > > + * struct sdw_device_id. class_id is unused, as it is a placeholder
> > > > > + * in MIPI Spec.
> > > > > + */
> > > > > +static const struct sdw_device_id *
> > > > > +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> > > > > +{
> > > > > +	const struct sdw_device_id *id = drv->id_table;
> > > > > +
> > > > > +	while (id && id->mfg_id) {
> > > > > +		if (slave->id.mfg_id == id->mfg_id &&
> > > > > +				slave->id.part_id == id->part_id) {
> > > > 
> > > > Please indentation properly.
> > > 
> > > what do you advise?
> > > 
> > > 		if (slave->id.mfg_id == id->mfg_id &&
> > > 			slave->id.part_id == id->part_id) {
> > > 
> > > would mean below one is at same indent. Some people use:
> > > 
> > > 		if (slave->id.mfg_id == id->mfg_id &&
> > > 		   slave->id.part_id == id->part_id) {
> > > 
> > > Is it Documented anywhere...
> > 
> > This is a matter of taste.  The latter is the way Emacs or indent does
> > as default.
> 
> okay as vi user I will try to do above :)
> 
> > 
> > > > > --- a/include/linux/mod_devicetable.h
> > > > > +++ b/include/linux/mod_devicetable.h
> > > > > @@ -228,6 +228,13 @@ struct hda_device_id {
> > > > >  	unsigned long driver_data;
> > > > >  };
> > > > >  
> > > > > +struct sdw_device_id {
> > > > > +	__u16 mfg_id;
> > > > > +	__u16 part_id;
> > > > > +	__u8 class_id;
> > > > > +	kernel_ulong_t driver_data;
> > > > 
> > > > Better to think of alignment.
> > > 
> > > sorry not quite clear, do you mind elaborating which ones to align?
> > 
> > kernel_ulong_t may be aligned to 4 or 8 bytes, depending on
> > architecture, so there can be a hole between class_id and driver_data.
> > It's not an ABI, so we don't have to care too much, but it's still
> > something exposed, hence better to be conscious about alignment.
> 
> ah :) is that why hda is unsigned long :) Btw doesnt that cause compat
> issues, should we not do something like u64 here?

Oh, don't take the HD-audio case as a good reference, it's a bad guy
;)  In the case of hda, the definition isn't really exposed.

The alignment doesn't matter whether it's unsigned long or
kernel_ulong_t.  It's a generic issue when you define some struct and
expose it.  In a safer side, you can put the enough pad bytes so that
the long field is aligned in 8 bytes.  Or use packed struct.  Or you
can just ignore and let it be so, but aware of the possible holes in
your code.


Takashi

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-20 15:50             ` Takashi Iwai
  0 siblings, 0 replies; 139+ messages in thread
From: Takashi Iwai @ 2017-10-20 15:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, patches.audio,
	Greg Kroah-Hartman, plai, LKML, Pierre, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Fri, 20 Oct 2017 17:46:49 +0200,
Vinod Koul wrote:
> 
> On Fri, Oct 20, 2017 at 08:59:42AM +0200, Takashi Iwai wrote:
> > On Fri, 20 Oct 2017 07:11:01 +0200,
> > Vinod Koul wrote:
> > > 
> > > On Thu, Oct 19, 2017 at 09:40:06AM +0200, Takashi Iwai wrote:
> > > > On Thu, 19 Oct 2017 05:03:18 +0200,
> > > > Vinod Koul wrote:
> > > > > +
> > > > > +config SOUNDWIRE_BUS
> > > > > +	tristate
> > > > > +	default SOUNDWIRE
> > > > > +
> > > > 
> > > > Does it make sense to be tristate?
> > > > Since CONFIG_SOUNDWIRE is a bool, the above would be also only either
> > > > Y or N.  If it's Y and others select M, it'll be still Y.
> > > 
> > > hmmm good point. I think would make sense to make SOUNDWIRE as tristate too,
> > > just like SOUND :)
> > 
> > It's one option.  Another would be to simply drop the "default" line.
> 
> Okay good suggestion
> 
> > > > > + * The match is done by comparing the mfg_id and part_id from the
> > > > > + * struct sdw_device_id. class_id is unused, as it is a placeholder
> > > > > + * in MIPI Spec.
> > > > > + */
> > > > > +static const struct sdw_device_id *
> > > > > +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> > > > > +{
> > > > > +	const struct sdw_device_id *id = drv->id_table;
> > > > > +
> > > > > +	while (id && id->mfg_id) {
> > > > > +		if (slave->id.mfg_id == id->mfg_id &&
> > > > > +				slave->id.part_id == id->part_id) {
> > > > 
> > > > Please indentation properly.
> > > 
> > > what do you advise?
> > > 
> > > 		if (slave->id.mfg_id == id->mfg_id &&
> > > 			slave->id.part_id == id->part_id) {
> > > 
> > > would mean below one is at same indent. Some people use:
> > > 
> > > 		if (slave->id.mfg_id == id->mfg_id &&
> > > 		   slave->id.part_id == id->part_id) {
> > > 
> > > Is it Documented anywhere...
> > 
> > This is a matter of taste.  The latter is the way Emacs or indent does
> > as default.
> 
> okay as vi user I will try to do above :)
> 
> > 
> > > > > --- a/include/linux/mod_devicetable.h
> > > > > +++ b/include/linux/mod_devicetable.h
> > > > > @@ -228,6 +228,13 @@ struct hda_device_id {
> > > > >  	unsigned long driver_data;
> > > > >  };
> > > > >  
> > > > > +struct sdw_device_id {
> > > > > +	__u16 mfg_id;
> > > > > +	__u16 part_id;
> > > > > +	__u8 class_id;
> > > > > +	kernel_ulong_t driver_data;
> > > > 
> > > > Better to think of alignment.
> > > 
> > > sorry not quite clear, do you mind elaborating which ones to align?
> > 
> > kernel_ulong_t may be aligned to 4 or 8 bytes, depending on
> > architecture, so there can be a hole between class_id and driver_data.
> > It's not an ABI, so we don't have to care too much, but it's still
> > something exposed, hence better to be conscious about alignment.
> 
> ah :) is that why hda is unsigned long :) Btw doesnt that cause compat
> issues, should we not do something like u64 here?

Oh, don't take the HD-audio case as a good reference, it's a bad guy
;)  In the case of hda, the definition isn't really exposed.

The alignment doesn't matter whether it's unsigned long or
kernel_ulong_t.  It's a generic issue when you define some struct and
expose it.  In a safer side, you can put the enough pad bytes so that
the long field is aligned in 8 bytes.  Or use packed struct.  Or you
can just ignore and let it be so, but aware of the possible holes in
your code.


Takashi

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 10:41     ` Greg Kroah-Hartman
  (?)
@ 2017-10-20 15:52     ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 15:52 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 12:41:20PM +0200, Greg Kroah-Hartman wrote:
> On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h
> > new file mode 100644
> > index 000000000000..2683c6798b95
> > --- /dev/null
> > +++ b/drivers/soundwire/bus.h
> > @@ -0,0 +1,62 @@
> > +/*
> > + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > + *  redistributing this file, you may do so under either license.
> > + *
> > + *  GPL LICENSE SUMMARY
> > + *
> > + *  Copyright(c) 2015-17 Intel Corporation.
> > + *
> > + *  This program is free software; you can redistribute it and/or modify
> > + *  it under the terms of version 2 of the GNU General Public License 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.
> > + *
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015-17 Intel Corporation.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> > + *
> > + *    * Redistributions of source code must retain the above copyright
> > + *      notice, this list of conditions and the following disclaimer.
> > + *    * Redistributions in binary form must reproduce the above copyright
> > + *      notice, this list of conditions and the following disclaimer in
> > + *      the documentation and/or other materials provided with the
> > + *      distribution.
> > + *    * Neither the name of Intel Corporation nor the names of its
> > + *      contributors may be used to endorse or promote products derived
> > + *      from this software without specific prior written permission.
> > + *
> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + */
> > +
> > +#ifndef __SDW_BUS_H
> > +#define __SDW_BUS_H
> > +
> > +#include <linux/init.h>
> > +#include <linux/device.h>
> > +#include <linux/module.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/acpi.h>
> > +#include <linux/soundwire/sdw.h>
> > +
> > +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> > +
> > +#endif /* __SDW_BUS_H */
> 
> When your header boiler-plate text is bigger than the content, please
> reconsider it.  Are you sure you need this .h file?  Why?

At the start of the series it does indeed look so, but not at the end of the
series. Pls see [1] for this file at the end of this series :)

The header is required so that we can share sdw_slave_modalias() code and
not do it a two places in c files.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire.git/tree/drivers/soundwire/bus.h?h=topic/patch_v1

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 10:45   ` Greg Kroah-Hartman
@ 2017-10-20 16:01     ` Vinod Koul
  2017-10-20 16:21         ` Greg Kroah-Hartman
  2017-10-26  8:33         ` Vinod Koul
  2017-10-20 16:03     ` Philippe Ombredanne
  1 sibling, 2 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 16:01 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > +/*
> > + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > + *  redistributing this file, you may do so under either license.
> > + *
> > + *  GPL LICENSE SUMMARY
> > + *
> > + *  Copyright(c) 2015-17 Intel Corporation.
> > + *
> > + *  This program is free software; you can redistribute it and/or modify
> > + *  it under the terms of version 2 of the GNU General Public License 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.
> > + *
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015-17 Intel Corporation.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> > + *
> > + *    * Redistributions of source code must retain the above copyright
> > + *      notice, this list of conditions and the following disclaimer.
> > + *    * Redistributions in binary form must reproduce the above copyright
> > + *      notice, this list of conditions and the following disclaimer in
> > + *      the documentation and/or other materials provided with the
> > + *      distribution.
> > + *    * Neither the name of Intel Corporation nor the names of its
> > + *      contributors may be used to endorse or promote products derived
> > + *      from this software without specific prior written permission.
> > + *
> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> 
> Are you _sure_ that code that interacts with the driver core can have a
> dual-license here?  Have you explained to lawyers what you are doing
> here (wrapping gpl-only symbols with non-gpl-only exports)?

Sorry, the intention is not to wrap gpl symbols for non-gpl-only exports.

> And why dual license something that will only ever work on Linux?

We have non Linux users (mostly RTOS folks) which we would like to support
with as much as common code.

> And finally, put a real SPDX header up there so that people don't have
> to parse that horrid amount of text to try to determine exactly what
> that license is.

Sorry for confusion, For the record we are trying to do Dual GPL v2/ BSD 3
clause here. Can you give me example of SPDX use. I will be gald to use that

> > +struct bus_type sdw_bus_type = {
> > +	.name = "soundwire",
> > +	.match = sdw_bus_match,
> > +	.uevent = sdw_uevent,
> > +};
> > +EXPORT_SYMBOL(sdw_bus_type);
> 
> EXPORT_SYMBOL_GPL()?

This can be EXPORT_SYMBOL_GPL as non Linux users wont have this. But then
would it be to okay to have a module with some symbols _GPL and some non
_GPL (the SoundWire protocol ones would need to be non GPL)

> 
> No release callback?  Who frees the device?

Sorry to have missed that, will add that

> > +static int sdw_drv_remove(struct device *dev)
> > +{
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> > +
> > +	if (drv->remove)
> > +		drv->remove(slave);
> 
> No catching the error value?

will add

> > +/*
> > + * sdw_unregister_driver: unregisters the SoundWire Slave driver
> > + *
> > + * @drv: driver to unregister
> > + */
> > +void sdw_unregister_driver(struct sdw_driver *drv)
> > +{
> > +	driver_unregister(&drv->driver);
> > +}
> > +EXPORT_SYMBOL(sdw_unregister_driver);
> 
> EXPORT_SYMBOL_GPL()?  Same for all the exports here (I have to ask,
> especially given what you are wrapping...)

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 10:45   ` Greg Kroah-Hartman
  2017-10-20 16:01     ` Vinod Koul
@ 2017-10-20 16:03     ` Philippe Ombredanne
  2017-10-20 16:20         ` Vinod Koul
  1 sibling, 1 reply; 139+ messages in thread
From: Philippe Ombredanne @ 2017-10-20 16:03 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi, Greg Kroah-Hartman

On Fri, Oct 20, 2017 at 12:45 PM, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
> On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
>> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
>> new file mode 100644
>> index 000000000000..a14d1de80afa
>> --- /dev/null
>> +++ b/drivers/soundwire/bus_type.c
>> @@ -0,0 +1,229 @@
>> +/*
>> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
>> + *  redistributing this file, you may do so under either license.
>> + *
>> + *  GPL LICENSE SUMMARY
>> + *
>> + *  Copyright(c) 2015-17 Intel Corporation.
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of version 2 of the GNU General Public License 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.
>> + *
>> + *  BSD LICENSE
>> + *
>> + *  Copyright(c) 2015-17 Intel Corporation.
>> + *
>> + *  Redistribution and use in source and binary forms, with or without
>> + *  modification, are permitted provided that the following conditions
>> + *  are met:
>> + *
>> + *    * Redistributions of source code must retain the above copyright
>> + *      notice, this list of conditions and the following disclaimer.
>> + *    * Redistributions in binary form must reproduce the above copyright
>> + *      notice, this list of conditions and the following disclaimer in
>> + *      the documentation and/or other materials provided with the
>> + *      distribution.
>> + *    * Neither the name of Intel Corporation nor the names of its
>> + *      contributors may be used to endorse or promote products derived
>> + *      from this software without specific prior written permission.
>> + *
>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
> Are you _sure_ that code that interacts with the driver core can have a
> dual-license here?  Have you explained to lawyers what you are doing
> here (wrapping gpl-only symbols with non-gpl-only exports)?
>
> And why dual license something that will only ever work on Linux?
>
> And finally, put a real SPDX header up there so that people don't have
> to parse that horrid amount of text to try to determine exactly what
> that license is.

Vinod:

It is hard to parse for people ... but it is quite hard for tools to catch
this too. This license notice is so peculiar and special that I had to
make a special detection rule just for it [1] in my tool :|
Please have mercy: could you not pick something simpler?

[1]  https://github.com/nexB/scancode-toolkit/blob/develop/src/licensedcode/data/rules/gpl-2.0_or_bsd-new33.RULE
-- 
Cordially
Philippe Ombredanne

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-20 10:47   ` Greg Kroah-Hartman
@ 2017-10-20 16:05     ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 16:05 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 12:47:26PM +0200, Greg Kroah-Hartman wrote:
> On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:
> > +void sdw_extract_slave_id(struct sdw_bus *bus,
> > +			unsigned long long addr, struct sdw_slave_id *id)
> > +{
> > +	dev_dbg(bus->dev, "SDW Slave Addr: %llx", addr);
> > +
> > +	/*
> > +	 * Spec definition
> > +	 *   Register		Bit	Contents
> > +	 *   DevId_0 [7:4]	47:44	sdw_version
> > +	 *   DevId_0 [3:0]	43:40	unique_id
> > +	 *   DevId_1		39:32	mfg_id [15:8]
> > +	 *   DevId_2		31:24	mfg_id [7:0]
> > +	 *   DevId_3		23:16	part_id [15:8]
> > +	 *   DevId_4		15:08	part_id [7:0]
> > +	 *   DevId_5		07:00	class_id
> > +	 */
> > +	id->sdw_version = (addr >> 44) & GENMASK(3, 0);
> > +	id->unique_id = (addr >> 40) & GENMASK(3, 0);
> > +	id->mfg_id = (addr >> 24) & GENMASK(15, 0);
> > +	id->part_id = (addr >> 8) & GENMASK(15, 0);
> > +	id->class_id = addr & GENMASK(7, 0);
> > +
> > +	dev_info(bus->dev,
> > +		"SDW Slave class_id %x, part_id %x, mfg_id %x, unique_id %x, version %x",
> > +				id->class_id, id->part_id, id->mfg_id,
> > +				id->unique_id, id->sdw_version);
> > +
> 
> Why are you so noisy?  Shouldn't this be dev_dbg()?

Sure, Takashi had same comment so this is fixed.

> > +static void sdw_slave_release(struct device *dev)
> > +{
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +
> > +	kfree(slave);
> > +}
> 
> Ah, finally a release function, nice.  But that's all you need to do for
> it?

The only pending thing is to release the memory. The bus reference and
related cleanup is done when device is unregistered.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 15:50             ` Takashi Iwai
  (?)
@ 2017-10-20 16:11             ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 16:11 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 05:50:57PM +0200, Takashi Iwai wrote:
> On Fri, 20 Oct 2017 17:46:49 +0200,
> Vinod Koul wrote:
> > > > > > --- a/include/linux/mod_devicetable.h
> > > > > > +++ b/include/linux/mod_devicetable.h
> > > > > > @@ -228,6 +228,13 @@ struct hda_device_id {
> > > > > >  	unsigned long driver_data;
> > > > > >  };
> > > > > >  
> > > > > > +struct sdw_device_id {
> > > > > > +	__u16 mfg_id;
> > > > > > +	__u16 part_id;
> > > > > > +	__u8 class_id;
> > > > > > +	kernel_ulong_t driver_data;
> > > > > 
> > > > > Better to think of alignment.
> > > > 
> > > > sorry not quite clear, do you mind elaborating which ones to align?
> > > 
> > > kernel_ulong_t may be aligned to 4 or 8 bytes, depending on
> > > architecture, so there can be a hole between class_id and driver_data.
> > > It's not an ABI, so we don't have to care too much, but it's still
> > > something exposed, hence better to be conscious about alignment.
> > 
> > ah :) is that why hda is unsigned long :) Btw doesnt that cause compat
> > issues, should we not do something like u64 here?
> 
> Oh, don't take the HD-audio case as a good reference, it's a bad guy
> ;)  In the case of hda, the definition isn't really exposed.

Not really it is for ext-hda codecs

> The alignment doesn't matter whether it's unsigned long or
> kernel_ulong_t.  It's a generic issue when you define some struct and
> expose it.  In a safer side, you can put the enough pad bytes so that
> the long field is aligned in 8 bytes.  Or use packed struct.  Or you
> can just ignore and let it be so, but aware of the possible holes in
> your code.

that makes sense, I can add some reserved fields for padding here to fix and
retain the kernel_ulong_t then

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:03     ` Philippe Ombredanne
@ 2017-10-20 16:20         ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 16:20 UTC (permalink / raw)
  To: Philippe Ombredanne
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi, Greg Kroah-Hartman

On Fri, Oct 20, 2017 at 06:03:24PM +0200, Philippe Ombredanne wrote:
> On Fri, Oct 20, 2017 at 12:45 PM, Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> >> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> >> new file mode 100644
> >> index 000000000000..a14d1de80afa
> >> --- /dev/null
> >> +++ b/drivers/soundwire/bus_type.c
> >> @@ -0,0 +1,229 @@
> >> +/*
> >> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> >> + *  redistributing this file, you may do so under either license.
> >> + *
> >> + *  GPL LICENSE SUMMARY
> >> + *
> >> + *  Copyright(c) 2015-17 Intel Corporation.
> >> + *
> >> + *  This program is free software; you can redistribute it and/or modify
> >> + *  it under the terms of version 2 of the GNU General Public License 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.
> >> + *
> >> + *  BSD LICENSE
> >> + *
> >> + *  Copyright(c) 2015-17 Intel Corporation.
> >> + *
> >> + *  Redistribution and use in source and binary forms, with or without
> >> + *  modification, are permitted provided that the following conditions
> >> + *  are met:
> >> + *
> >> + *    * Redistributions of source code must retain the above copyright
> >> + *      notice, this list of conditions and the following disclaimer.
> >> + *    * Redistributions in binary form must reproduce the above copyright
> >> + *      notice, this list of conditions and the following disclaimer in
> >> + *      the documentation and/or other materials provided with the
> >> + *      distribution.
> >> + *    * Neither the name of Intel Corporation nor the names of its
> >> + *      contributors may be used to endorse or promote products derived
> >> + *      from this software without specific prior written permission.
> >> + *
> >> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> >> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> >> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> >> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> >> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> >> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> >> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> >> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> >> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> >> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> >> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> >
> > Are you _sure_ that code that interacts with the driver core can have a
> > dual-license here?  Have you explained to lawyers what you are doing
> > here (wrapping gpl-only symbols with non-gpl-only exports)?
> >
> > And why dual license something that will only ever work on Linux?
> >
> > And finally, put a real SPDX header up there so that people don't have
> > to parse that horrid amount of text to try to determine exactly what
> > that license is.
> 
> Vinod:
> 
> It is hard to parse for people ... but it is quite hard for tools to catch
> this too. This license notice is so peculiar and special that I had to
> make a special detection rule just for it [1] in my tool :|
> Please have mercy: could you not pick something simpler?

Sorry for the trouble it caused. The code is Dual license as indicated by
first two lines. I didn't invent the text here, legal folks did and used
the standard template available in my company

I quick grep on Dual license users looks like we already have this in kernel
code. See drivers/ntb/hw/intel/ntb_hw_intel.c

> [1]  https://github.com/nexB/scancode-toolkit/blob/develop/src/licensedcode/data/rules/gpl-2.0_or_bsd-new33.RULE

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-20 16:20         ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 16:20 UTC (permalink / raw)
  To: Philippe Ombredanne
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 06:03:24PM +0200, Philippe Ombredanne wrote:
> On Fri, Oct 20, 2017 at 12:45 PM, Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> >> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> >> new file mode 100644
> >> index 000000000000..a14d1de80afa
> >> --- /dev/null
> >> +++ b/drivers/soundwire/bus_type.c
> >> @@ -0,0 +1,229 @@
> >> +/*
> >> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> >> + *  redistributing this file, you may do so under either license.
> >> + *
> >> + *  GPL LICENSE SUMMARY
> >> + *
> >> + *  Copyright(c) 2015-17 Intel Corporation.
> >> + *
> >> + *  This program is free software; you can redistribute it and/or modify
> >> + *  it under the terms of version 2 of the GNU General Public License 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.
> >> + *
> >> + *  BSD LICENSE
> >> + *
> >> + *  Copyright(c) 2015-17 Intel Corporation.
> >> + *
> >> + *  Redistribution and use in source and binary forms, with or without
> >> + *  modification, are permitted provided that the following conditions
> >> + *  are met:
> >> + *
> >> + *    * Redistributions of source code must retain the above copyright
> >> + *      notice, this list of conditions and the following disclaimer.
> >> + *    * Redistributions in binary form must reproduce the above copyright
> >> + *      notice, this list of conditions and the following disclaimer in
> >> + *      the documentation and/or other materials provided with the
> >> + *      distribution.
> >> + *    * Neither the name of Intel Corporation nor the names of its
> >> + *      contributors may be used to endorse or promote products derived
> >> + *      from this software without specific prior written permission.
> >> + *
> >> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> >> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> >> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> >> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> >> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> >> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> >> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> >> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> >> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> >> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> >> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> >
> > Are you _sure_ that code that interacts with the driver core can have a
> > dual-license here?  Have you explained to lawyers what you are doing
> > here (wrapping gpl-only symbols with non-gpl-only exports)?
> >
> > And why dual license something that will only ever work on Linux?
> >
> > And finally, put a real SPDX header up there so that people don't have
> > to parse that horrid amount of text to try to determine exactly what
> > that license is.
> 
> Vinod:
> 
> It is hard to parse for people ... but it is quite hard for tools to catch
> this too. This license notice is so peculiar and special that I had to
> make a special detection rule just for it [1] in my tool :|
> Please have mercy: could you not pick something simpler?

Sorry for the trouble it caused. The code is Dual license as indicated by
first two lines. I didn't invent the text here, legal folks did and used
the standard template available in my company

I quick grep on Dual license users looks like we already have this in kernel
code. See drivers/ntb/hw/intel/ntb_hw_intel.c

> [1]  https://github.com/nexB/scancode-toolkit/blob/develop/src/licensedcode/data/rules/gpl-2.0_or_bsd-new33.RULE

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:01     ` Vinod Koul
@ 2017-10-20 16:21         ` Greg Kroah-Hartman
  2017-10-26  8:33         ` Vinod Koul
  1 sibling, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 16:21 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > > +/*
> > > + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > > + *  redistributing this file, you may do so under either license.
> > > + *
> > > + *  GPL LICENSE SUMMARY
> > > + *
> > > + *  Copyright(c) 2015-17 Intel Corporation.
> > > + *
> > > + *  This program is free software; you can redistribute it and/or modify
> > > + *  it under the terms of version 2 of the GNU General Public License 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.
> > > + *
> > > + *  BSD LICENSE
> > > + *
> > > + *  Copyright(c) 2015-17 Intel Corporation.
> > > + *
> > > + *  Redistribution and use in source and binary forms, with or without
> > > + *  modification, are permitted provided that the following conditions
> > > + *  are met:
> > > + *
> > > + *    * Redistributions of source code must retain the above copyright
> > > + *      notice, this list of conditions and the following disclaimer.
> > > + *    * Redistributions in binary form must reproduce the above copyright
> > > + *      notice, this list of conditions and the following disclaimer in
> > > + *      the documentation and/or other materials provided with the
> > > + *      distribution.
> > > + *    * Neither the name of Intel Corporation nor the names of its
> > > + *      contributors may be used to endorse or promote products derived
> > > + *      from this software without specific prior written permission.
> > > + *
> > > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > 
> > Are you _sure_ that code that interacts with the driver core can have a
> > dual-license here?  Have you explained to lawyers what you are doing
> > here (wrapping gpl-only symbols with non-gpl-only exports)?
> 
> Sorry, the intention is not to wrap gpl symbols for non-gpl-only exports.
> 
> > And why dual license something that will only ever work on Linux?
> 
> We have non Linux users (mostly RTOS folks) which we would like to support
> with as much as common code.

Note, you need to be VERY CAREFUL about doing this.  You need to have
all sorts of infrastructure set up and in place and paperwork up the
wazoo in order to make it work properly.

In the end, I can almost guarantee it will not be worth the extra hassle
and effort you are trying to do here.

Seriously, go talk to your managers and corporate lawyer about this, you
are in for a world of hurt if you want to do this in a way that actually
works (i.e. doesn't just degrade to GPLv2 only instantly.)

I recommend not doing this unless you have money to burn.  If you do,
then great!  If not, it is much easier just to have two separate code
repos.

> > And finally, put a real SPDX header up there so that people don't have
> > to parse that horrid amount of text to try to determine exactly what
> > that license is.
> 
> Sorry for confusion, For the record we are trying to do Dual GPL v2/ BSD 3
> clause here. Can you give me example of SPDX use. I will be gald to use that

I could give you an example, but you need to get the real marking from
your company as I am not the one to pick it for you :)

> > > +struct bus_type sdw_bus_type = {
> > > +	.name = "soundwire",
> > > +	.match = sdw_bus_match,
> > > +	.uevent = sdw_uevent,
> > > +};
> > > +EXPORT_SYMBOL(sdw_bus_type);
> > 
> > EXPORT_SYMBOL_GPL()?
> 
> This can be EXPORT_SYMBOL_GPL as non Linux users wont have this. But then
> would it be to okay to have a module with some symbols _GPL and some non
> _GPL (the SoundWire protocol ones would need to be non GPL)

Again, don't even try to do that, it's not going to work.

The only team I know that ever has done this successfully is the core
ACPI code.  Go talk to them about the work involved in doing this
properly to see if you are willing to do that.

good luck!

greg k-h

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-20 16:21         ` Greg Kroah-Hartman
  0 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 16:21 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > > +/*
> > > + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > > + *  redistributing this file, you may do so under either license.
> > > + *
> > > + *  GPL LICENSE SUMMARY
> > > + *
> > > + *  Copyright(c) 2015-17 Intel Corporation.
> > > + *
> > > + *  This program is free software; you can redistribute it and/or modify
> > > + *  it under the terms of version 2 of the GNU General Public License 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.
> > > + *
> > > + *  BSD LICENSE
> > > + *
> > > + *  Copyright(c) 2015-17 Intel Corporation.
> > > + *
> > > + *  Redistribution and use in source and binary forms, with or without
> > > + *  modification, are permitted provided that the following conditions
> > > + *  are met:
> > > + *
> > > + *    * Redistributions of source code must retain the above copyright
> > > + *      notice, this list of conditions and the following disclaimer.
> > > + *    * Redistributions in binary form must reproduce the above copyright
> > > + *      notice, this list of conditions and the following disclaimer in
> > > + *      the documentation and/or other materials provided with the
> > > + *      distribution.
> > > + *    * Neither the name of Intel Corporation nor the names of its
> > > + *      contributors may be used to endorse or promote products derived
> > > + *      from this software without specific prior written permission.
> > > + *
> > > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > 
> > Are you _sure_ that code that interacts with the driver core can have a
> > dual-license here?  Have you explained to lawyers what you are doing
> > here (wrapping gpl-only symbols with non-gpl-only exports)?
> 
> Sorry, the intention is not to wrap gpl symbols for non-gpl-only exports.
> 
> > And why dual license something that will only ever work on Linux?
> 
> We have non Linux users (mostly RTOS folks) which we would like to support
> with as much as common code.

Note, you need to be VERY CAREFUL about doing this.  You need to have
all sorts of infrastructure set up and in place and paperwork up the
wazoo in order to make it work properly.

In the end, I can almost guarantee it will not be worth the extra hassle
and effort you are trying to do here.

Seriously, go talk to your managers and corporate lawyer about this, you
are in for a world of hurt if you want to do this in a way that actually
works (i.e. doesn't just degrade to GPLv2 only instantly.)

I recommend not doing this unless you have money to burn.  If you do,
then great!  If not, it is much easier just to have two separate code
repos.

> > And finally, put a real SPDX header up there so that people don't have
> > to parse that horrid amount of text to try to determine exactly what
> > that license is.
> 
> Sorry for confusion, For the record we are trying to do Dual GPL v2/ BSD 3
> clause here. Can you give me example of SPDX use. I will be gald to use that

I could give you an example, but you need to get the real marking from
your company as I am not the one to pick it for you :)

> > > +struct bus_type sdw_bus_type = {
> > > +	.name = "soundwire",
> > > +	.match = sdw_bus_match,
> > > +	.uevent = sdw_uevent,
> > > +};
> > > +EXPORT_SYMBOL(sdw_bus_type);
> > 
> > EXPORT_SYMBOL_GPL()?
> 
> This can be EXPORT_SYMBOL_GPL as non Linux users wont have this. But then
> would it be to okay to have a module with some symbols _GPL and some non
> _GPL (the SoundWire protocol ones would need to be non GPL)

Again, don't even try to do that, it's not going to work.

The only team I know that ever has done this successfully is the core
ACPI code.  Go talk to them about the work involved in doing this
properly to see if you are willing to do that.

good luck!

greg k-h

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-20 15:49       ` Vinod Koul
@ 2017-10-20 16:22         ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 16:22 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 09:19:18PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 12:39:34PM +0200, Greg Kroah-Hartman wrote:
> > On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> > > From: Sanyog Kale <sanyog.r.kale@intel.com>
> > > 
> > > SoundWire is a new Linux bus which implements a new MIPI bus protocol
> > > 'SoundWire'. The summary of SoundWire bus and registration APIs is
> > > documented in the 'summary' file.
> > > 
> > > Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > > Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > ---
> > >  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 192 insertions(+)
> > >  create mode 100644 Documentation/soundwire/summary.txt
> > 
> > Any specific reason this is not in .rst format and tied to the rest of
> > the kernel Documentation so it gets built automatically?
> 
> I was hoping to do rst conversion a bit later if that is not a deal
> breaker :) That is certainly a todo in my list.

Should only take you a few minutes, don't add things to the tree that
you are going to fix up "some day", as that might never happen...

thanks,

greg k-h

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-20 16:22         ` Greg Kroah-Hartman
  0 siblings, 0 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 16:22 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 09:19:18PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 12:39:34PM +0200, Greg Kroah-Hartman wrote:
> > On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> > > From: Sanyog Kale <sanyog.r.kale@intel.com>
> > > 
> > > SoundWire is a new Linux bus which implements a new MIPI bus protocol
> > > 'SoundWire'. The summary of SoundWire bus and registration APIs is
> > > documented in the 'summary' file.
> > > 
> > > Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > > Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > ---
> > >  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 192 insertions(+)
> > >  create mode 100644 Documentation/soundwire/summary.txt
> > 
> > Any specific reason this is not in .rst format and tied to the rest of
> > the kernel Documentation so it gets built automatically?
> 
> I was hoping to do rst conversion a bit later if that is not a deal
> breaker :) That is certainly a todo in my list.

Should only take you a few minutes, don't add things to the tree that
you are going to fix up "some day", as that might never happen...

thanks,

greg k-h

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:20         ` Vinod Koul
  (?)
@ 2017-10-20 16:27         ` Greg Kroah-Hartman
  2017-10-20 17:13             ` Vinod Koul
  2017-10-23 11:52             ` Alan Cox
  -1 siblings, 2 replies; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-20 16:27 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Philippe Ombredanne, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 09:50:42PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 06:03:24PM +0200, Philippe Ombredanne wrote:
> > On Fri, Oct 20, 2017 at 12:45 PM, Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > >> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> > >> new file mode 100644
> > >> index 000000000000..a14d1de80afa
> > >> --- /dev/null
> > >> +++ b/drivers/soundwire/bus_type.c
> > >> @@ -0,0 +1,229 @@
> > >> +/*
> > >> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > >> + *  redistributing this file, you may do so under either license.
> > >> + *
> > >> + *  GPL LICENSE SUMMARY
> > >> + *
> > >> + *  Copyright(c) 2015-17 Intel Corporation.
> > >> + *
> > >> + *  This program is free software; you can redistribute it and/or modify
> > >> + *  it under the terms of version 2 of the GNU General Public License 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.
> > >> + *
> > >> + *  BSD LICENSE
> > >> + *
> > >> + *  Copyright(c) 2015-17 Intel Corporation.
> > >> + *
> > >> + *  Redistribution and use in source and binary forms, with or without
> > >> + *  modification, are permitted provided that the following conditions
> > >> + *  are met:
> > >> + *
> > >> + *    * Redistributions of source code must retain the above copyright
> > >> + *      notice, this list of conditions and the following disclaimer.
> > >> + *    * Redistributions in binary form must reproduce the above copyright
> > >> + *      notice, this list of conditions and the following disclaimer in
> > >> + *      the documentation and/or other materials provided with the
> > >> + *      distribution.
> > >> + *    * Neither the name of Intel Corporation nor the names of its
> > >> + *      contributors may be used to endorse or promote products derived
> > >> + *      from this software without specific prior written permission.
> > >> + *
> > >> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > >> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > >> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > >> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > >> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > >> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > >> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > >> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > >> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > >> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > >> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > >
> > > Are you _sure_ that code that interacts with the driver core can have a
> > > dual-license here?  Have you explained to lawyers what you are doing
> > > here (wrapping gpl-only symbols with non-gpl-only exports)?
> > >
> > > And why dual license something that will only ever work on Linux?
> > >
> > > And finally, put a real SPDX header up there so that people don't have
> > > to parse that horrid amount of text to try to determine exactly what
> > > that license is.
> > 
> > Vinod:
> > 
> > It is hard to parse for people ... but it is quite hard for tools to catch
> > this too. This license notice is so peculiar and special that I had to
> > make a special detection rule just for it [1] in my tool :|
> > Please have mercy: could you not pick something simpler?
> 
> Sorry for the trouble it caused. The code is Dual license as indicated by
> first two lines. I didn't invent the text here, legal folks did and used
> the standard template available in my company
> 
> I quick grep on Dual license users looks like we already have this in kernel
> code. See drivers/ntb/hw/intel/ntb_hw_intel.c

Just because someone did something wrong in the past, doesn't mean they
should keep doing more wrong things in the future :)

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-20 16:22         ` Greg Kroah-Hartman
@ 2017-10-20 17:09           ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 17:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 06:22:13PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 20, 2017 at 09:19:18PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 12:39:34PM +0200, Greg Kroah-Hartman wrote:
> > > On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> > > > From: Sanyog Kale <sanyog.r.kale@intel.com>
> > > > 
> > > > SoundWire is a new Linux bus which implements a new MIPI bus protocol
> > > > 'SoundWire'. The summary of SoundWire bus and registration APIs is
> > > > documented in the 'summary' file.
> > > > 
> > > > Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > > > Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> > > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > ---
> > > >  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 192 insertions(+)
> > > >  create mode 100644 Documentation/soundwire/summary.txt
> > > 
> > > Any specific reason this is not in .rst format and tied to the rest of
> > > the kernel Documentation so it gets built automatically?
> > 
> > I was hoping to do rst conversion a bit later if that is not a deal
> > breaker :) That is certainly a todo in my list.
> 
> Should only take you a few minutes, don't add things to the tree that
> you are going to fix up "some day", as that might never happen...

Yeah I need to do that anyway, so lets me get that done for this and some
other stuff I planned to do :)

-- 
~Vinod

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-20 17:09           ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 17:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 06:22:13PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 20, 2017 at 09:19:18PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 12:39:34PM +0200, Greg Kroah-Hartman wrote:
> > > On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> > > > From: Sanyog Kale <sanyog.r.kale@intel.com>
> > > > 
> > > > SoundWire is a new Linux bus which implements a new MIPI bus protocol
> > > > 'SoundWire'. The summary of SoundWire bus and registration APIs is
> > > > documented in the 'summary' file.
> > > > 
> > > > Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > > > Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
> > > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > > > Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > > > ---
> > > >  Documentation/soundwire/summary.txt | 192 ++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 192 insertions(+)
> > > >  create mode 100644 Documentation/soundwire/summary.txt
> > > 
> > > Any specific reason this is not in .rst format and tied to the rest of
> > > the kernel Documentation so it gets built automatically?
> > 
> > I was hoping to do rst conversion a bit later if that is not a deal
> > breaker :) That is certainly a todo in my list.
> 
> Should only take you a few minutes, don't add things to the tree that
> you are going to fix up "some day", as that might never happen...

Yeah I need to do that anyway, so lets me get that done for this and some
other stuff I planned to do :)

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:21         ` Greg Kroah-Hartman
  (?)
@ 2017-10-20 17:10         ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 17:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 06:21:23PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > > > +/*
> > > > + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > > > + *  redistributing this file, you may do so under either license.
> > > > + *
> > > > + *  GPL LICENSE SUMMARY
> > > > + *
> > > > + *  Copyright(c) 2015-17 Intel Corporation.
> > > > + *
> > > > + *  This program is free software; you can redistribute it and/or modify
> > > > + *  it under the terms of version 2 of the GNU General Public License 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.
> > > > + *
> > > > + *  BSD LICENSE
> > > > + *
> > > > + *  Copyright(c) 2015-17 Intel Corporation.
> > > > + *
> > > > + *  Redistribution and use in source and binary forms, with or without
> > > > + *  modification, are permitted provided that the following conditions
> > > > + *  are met:
> > > > + *
> > > > + *    * Redistributions of source code must retain the above copyright
> > > > + *      notice, this list of conditions and the following disclaimer.
> > > > + *    * Redistributions in binary form must reproduce the above copyright
> > > > + *      notice, this list of conditions and the following disclaimer in
> > > > + *      the documentation and/or other materials provided with the
> > > > + *      distribution.
> > > > + *    * Neither the name of Intel Corporation nor the names of its
> > > > + *      contributors may be used to endorse or promote products derived
> > > > + *      from this software without specific prior written permission.
> > > > + *
> > > > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > > > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > > > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > > > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > > > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > > > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > > > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > > > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > > > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > > > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > > > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > > 
> > > Are you _sure_ that code that interacts with the driver core can have a
> > > dual-license here?  Have you explained to lawyers what you are doing
> > > here (wrapping gpl-only symbols with non-gpl-only exports)?
> > 
> > Sorry, the intention is not to wrap gpl symbols for non-gpl-only exports.
> > 
> > > And why dual license something that will only ever work on Linux?
> > 
> > We have non Linux users (mostly RTOS folks) which we would like to support
> > with as much as common code.
> 
> Note, you need to be VERY CAREFUL about doing this.  You need to have
> all sorts of infrastructure set up and in place and paperwork up the
> wazoo in order to make it work properly.
> 
> In the end, I can almost guarantee it will not be worth the extra hassle
> and effort you are trying to do here.
> 
> Seriously, go talk to your managers and corporate lawyer about this, you
> are in for a world of hurt if you want to do this in a way that actually
> works (i.e. doesn't just degrade to GPLv2 only instantly.)
> 
> I recommend not doing this unless you have money to burn.  If you do,
> then great!  If not, it is much easier just to have two separate code
> repos.
> 
> > > And finally, put a real SPDX header up there so that people don't have
> > > to parse that horrid amount of text to try to determine exactly what
> > > that license is.
> > 
> > Sorry for confusion, For the record we are trying to do Dual GPL v2/ BSD 3
> > clause here. Can you give me example of SPDX use. I will be gald to use that
> 
> I could give you an example, but you need to get the real marking from
> your company as I am not the one to pick it for you :)
> 
> > > > +struct bus_type sdw_bus_type = {
> > > > +	.name = "soundwire",
> > > > +	.match = sdw_bus_match,
> > > > +	.uevent = sdw_uevent,
> > > > +};
> > > > +EXPORT_SYMBOL(sdw_bus_type);
> > > 
> > > EXPORT_SYMBOL_GPL()?
> > 
> > This can be EXPORT_SYMBOL_GPL as non Linux users wont have this. But then
> > would it be to okay to have a module with some symbols _GPL and some non
> > _GPL (the SoundWire protocol ones would need to be non GPL)
> 
> Again, don't even try to do that, it's not going to work.
> 
> The only team I know that ever has done this successfully is the core
> ACPI code.  Go talk to them about the work involved in doing this
> properly to see if you are willing to do that.

Thanks for the advice Greg, really appreciate it!

I will work with the folks and try to come up with a better proposal

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:27         ` Greg Kroah-Hartman
@ 2017-10-20 17:13             ` Vinod Koul
  2017-10-23 11:52             ` Alan Cox
  1 sibling, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 17:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Philippe Ombredanne, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 06:27:23PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 20, 2017 at 09:50:42PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 06:03:24PM +0200, Philippe Ombredanne wrote:
> > > On Fri, Oct 20, 2017 at 12:45 PM, Greg Kroah-Hartman
> > > <gregkh@linuxfoundation.org> wrote:
> > > > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > > >> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> > > >> new file mode 100644
> > > >> index 000000000000..a14d1de80afa
> > > >> --- /dev/null
> > > >> +++ b/drivers/soundwire/bus_type.c
> > > >> @@ -0,0 +1,229 @@
> > > >> +/*
> > > >> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > > >> + *  redistributing this file, you may do so under either license.
> > > >> + *
> > > >> + *  GPL LICENSE SUMMARY
> > > >> + *
> > > >> + *  Copyright(c) 2015-17 Intel Corporation.
> > > >> + *
> > > >> + *  This program is free software; you can redistribute it and/or modify
> > > >> + *  it under the terms of version 2 of the GNU General Public License 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.
> > > >> + *
> > > >> + *  BSD LICENSE
> > > >> + *
> > > >> + *  Copyright(c) 2015-17 Intel Corporation.
> > > >> + *
> > > >> + *  Redistribution and use in source and binary forms, with or without
> > > >> + *  modification, are permitted provided that the following conditions
> > > >> + *  are met:
> > > >> + *
> > > >> + *    * Redistributions of source code must retain the above copyright
> > > >> + *      notice, this list of conditions and the following disclaimer.
> > > >> + *    * Redistributions in binary form must reproduce the above copyright
> > > >> + *      notice, this list of conditions and the following disclaimer in
> > > >> + *      the documentation and/or other materials provided with the
> > > >> + *      distribution.
> > > >> + *    * Neither the name of Intel Corporation nor the names of its
> > > >> + *      contributors may be used to endorse or promote products derived
> > > >> + *      from this software without specific prior written permission.
> > > >> + *
> > > >> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > > >> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > > >> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > > >> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > > >> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > > >> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > > >> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > > >> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > > >> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > > >> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > > >> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > > >
> > > > Are you _sure_ that code that interacts with the driver core can have a
> > > > dual-license here?  Have you explained to lawyers what you are doing
> > > > here (wrapping gpl-only symbols with non-gpl-only exports)?
> > > >
> > > > And why dual license something that will only ever work on Linux?
> > > >
> > > > And finally, put a real SPDX header up there so that people don't have
> > > > to parse that horrid amount of text to try to determine exactly what
> > > > that license is.
> > > 
> > > Vinod:
> > > 
> > > It is hard to parse for people ... but it is quite hard for tools to catch
> > > this too. This license notice is so peculiar and special that I had to
> > > make a special detection rule just for it [1] in my tool :|
> > > Please have mercy: could you not pick something simpler?
> > 
> > Sorry for the trouble it caused. The code is Dual license as indicated by
> > first two lines. I didn't invent the text here, legal folks did and used
> > the standard template available in my company
> > 
> > I quick grep on Dual license users looks like we already have this in kernel
> > code. See drivers/ntb/hw/intel/ntb_hw_intel.c
> 
> Just because someone did something wrong in the past, doesn't mean they
> should keep doing more wrong things in the future :)

Sure, I agree w/ you that. But this is still a standard header to use for
me. I will check with folks to see if we can use as you suggested.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-20 17:13             ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-20 17:13 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, Shreyas NC,
	Pierre, LKML, patches.audio, Mark, srinivas.kandagatla,
	Philippe Ombredanne, Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 06:27:23PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 20, 2017 at 09:50:42PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 06:03:24PM +0200, Philippe Ombredanne wrote:
> > > On Fri, Oct 20, 2017 at 12:45 PM, Greg Kroah-Hartman
> > > <gregkh@linuxfoundation.org> wrote:
> > > > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > > >> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> > > >> new file mode 100644
> > > >> index 000000000000..a14d1de80afa
> > > >> --- /dev/null
> > > >> +++ b/drivers/soundwire/bus_type.c
> > > >> @@ -0,0 +1,229 @@
> > > >> +/*
> > > >> + *  This file is provided under a dual BSD/GPLv2 license.  When using or
> > > >> + *  redistributing this file, you may do so under either license.
> > > >> + *
> > > >> + *  GPL LICENSE SUMMARY
> > > >> + *
> > > >> + *  Copyright(c) 2015-17 Intel Corporation.
> > > >> + *
> > > >> + *  This program is free software; you can redistribute it and/or modify
> > > >> + *  it under the terms of version 2 of the GNU General Public License 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.
> > > >> + *
> > > >> + *  BSD LICENSE
> > > >> + *
> > > >> + *  Copyright(c) 2015-17 Intel Corporation.
> > > >> + *
> > > >> + *  Redistribution and use in source and binary forms, with or without
> > > >> + *  modification, are permitted provided that the following conditions
> > > >> + *  are met:
> > > >> + *
> > > >> + *    * Redistributions of source code must retain the above copyright
> > > >> + *      notice, this list of conditions and the following disclaimer.
> > > >> + *    * Redistributions in binary form must reproduce the above copyright
> > > >> + *      notice, this list of conditions and the following disclaimer in
> > > >> + *      the documentation and/or other materials provided with the
> > > >> + *      distribution.
> > > >> + *    * Neither the name of Intel Corporation nor the names of its
> > > >> + *      contributors may be used to endorse or promote products derived
> > > >> + *      from this software without specific prior written permission.
> > > >> + *
> > > >> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > > >> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > > >> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > > >> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > > >> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > > >> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > > >> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > > >> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > > >> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > > >> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > > >> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > > >
> > > > Are you _sure_ that code that interacts with the driver core can have a
> > > > dual-license here?  Have you explained to lawyers what you are doing
> > > > here (wrapping gpl-only symbols with non-gpl-only exports)?
> > > >
> > > > And why dual license something that will only ever work on Linux?
> > > >
> > > > And finally, put a real SPDX header up there so that people don't have
> > > > to parse that horrid amount of text to try to determine exactly what
> > > > that license is.
> > > 
> > > Vinod:
> > > 
> > > It is hard to parse for people ... but it is quite hard for tools to catch
> > > this too. This license notice is so peculiar and special that I had to
> > > make a special detection rule just for it [1] in my tool :|
> > > Please have mercy: could you not pick something simpler?
> > 
> > Sorry for the trouble it caused. The code is Dual license as indicated by
> > first two lines. I didn't invent the text here, legal folks did and used
> > the standard template available in my company
> > 
> > I quick grep on Dual license users looks like we already have this in kernel
> > code. See drivers/ntb/hw/intel/ntb_hw_intel.c
> 
> Just because someone did something wrong in the past, doesn't mean they
> should keep doing more wrong things in the future :)

Sure, I agree w/ you that. But this is still a standard header to use for
me. I will check with folks to see if we can use as you suggested.

-- 
~Vinod

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-19  3:03 ` [PATCH 01/14] Documentation: Add SoundWire summary Vinod Koul
@ 2017-10-21  8:57     ` Mark Brown
  2017-10-20 10:39     ` Greg Kroah-Hartman
  2017-10-21  8:57     ` Mark Brown
  2 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  8:57 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:

> +The SoundWire protocol supports up to eleven Slave interfaces. All the

There's lots of perfectly normal nouns in this document like Slave here
which are randomly capitalized.  Is there some great reason for this?
It makes the document pretty distracting to read.

> +Bus implements API to read standard Master MIPI properties and also provides
> +callback in Master ops for Master driver to implement own functions that

implement it's own functions.

> +provides capabilities information. DT support is not implemented at this
> +time but should be trivial to add since capabilities are enabled with the
> +device_property_ API.

Since we're making this up from whole cloth rather than following an
existing standard let's get a DT binding document together and review
the properties that are getting defined.

> +	/* Check ACPI for Slave devices */
> +        sdw_acpi_find_slaves(bus);

Tab/space issues here.

> +The MIPI specification requires each Slave interface to expose a unique
> +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> +identifier contains vendor and part information, as well as a field enabling
> +to differentiate between identical components. An additional class field is
> +currently unused. Slave driver is written for the specific 48-bit
> +identifier, Bus enumerates the Slave device based on the 48-bit identifier.

So this says that the instance identifer is part of the device
identifier but the driver should bind to the whole device identifer?
I'd expect the driver to bind to everything except the instance
identifer.

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

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-21  8:57     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  8:57 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:

> +The SoundWire protocol supports up to eleven Slave interfaces. All the

There's lots of perfectly normal nouns in this document like Slave here
which are randomly capitalized.  Is there some great reason for this?
It makes the document pretty distracting to read.

> +Bus implements API to read standard Master MIPI properties and also provides
> +callback in Master ops for Master driver to implement own functions that

implement it's own functions.

> +provides capabilities information. DT support is not implemented at this
> +time but should be trivial to add since capabilities are enabled with the
> +device_property_ API.

Since we're making this up from whole cloth rather than following an
existing standard let's get a DT binding document together and review
the properties that are getting defined.

> +	/* Check ACPI for Slave devices */
> +        sdw_acpi_find_slaves(bus);

Tab/space issues here.

> +The MIPI specification requires each Slave interface to expose a unique
> +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> +identifier contains vendor and part information, as well as a field enabling
> +to differentiate between identical components. An additional class field is
> +currently unused. Slave driver is written for the specific 48-bit
> +identifier, Bus enumerates the Slave device based on the 48-bit identifier.

So this says that the instance identifer is part of the device
identifier but the driver should bind to the whole device identifer?
I'd expect the driver to bind to everything except the instance
identifer.

[-- 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] 139+ messages in thread

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  3:03 ` [PATCH 02/14] soundwire: Add SoundWire bus type Vinod Koul
                     ` (2 preceding siblings ...)
  2017-10-20 10:45   ` Greg Kroah-Hartman
@ 2017-10-21  9:03   ` Mark Brown
  2017-10-21 11:29       ` Vinod Koul
  2017-11-09 21:14     ` Srinivas Kandagatla
  4 siblings, 1 reply; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:03 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:

> +	ret = dev_pm_domain_attach(dev, false);
> +	if (ret) {
> +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drv->probe(slave, id);
> +	if (ret) {
> +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> +		return ret;
> +	}

We don't detach the power domain if the probe fails.

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

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-19  3:03   ` Vinod Koul
@ 2017-10-21  9:12     ` Mark Brown
  -1 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:12 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:

> +	/*
> +	 * SDW is an enumerable bus, but devices can be powered off. So,
> +	 * they won't be able to report as present.
> +	 *
> +	 * Create Slave devices based on Slaves described in
> +	 * the respective firmware (ACPI/DT)
> +	 */
> +
> +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> +		ret = sdw_acpi_find_slaves(bus);
> +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> +		ret = sdw_of_find_slaves(bus);
> +	else
> +		ret = -ENOTSUPP; /* No ACPI/DT so error out */

Devices *can* be powered off but is there any reason that a system
couldn't be designed with them always powered?  Also given that we don't
actually have any DT support the stubs for it are at best misleading,
it's not going to be hard for someone to add them later.

> +	mutex_lock(&bus->bus_lock);
> +	if (!list_empty(&bus->slaves))
> +		list_del(&slave->node);

Shouldn't that be a while?  Or at least warn if there's anything extra
there.  The code just looks very wrong as is.

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

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

* Re: [PATCH 03/14] soundwire: Add Master registration
@ 2017-10-21  9:12     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:12 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:

> +	/*
> +	 * SDW is an enumerable bus, but devices can be powered off. So,
> +	 * they won't be able to report as present.
> +	 *
> +	 * Create Slave devices based on Slaves described in
> +	 * the respective firmware (ACPI/DT)
> +	 */
> +
> +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> +		ret = sdw_acpi_find_slaves(bus);
> +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> +		ret = sdw_of_find_slaves(bus);
> +	else
> +		ret = -ENOTSUPP; /* No ACPI/DT so error out */

Devices *can* be powered off but is there any reason that a system
couldn't be designed with them always powered?  Also given that we don't
actually have any DT support the stubs for it are at best misleading,
it's not going to be hard for someone to add them later.

> +	mutex_lock(&bus->bus_lock);
> +	if (!list_empty(&bus->slaves))
> +		list_del(&slave->node);

Shouldn't that be a while?  Or at least warn if there's anything extra
there.  The code just looks very wrong as is.

[-- 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] 139+ messages in thread

* Re: [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
  2017-10-19  3:03 ` [PATCH 04/14] soundwire: Add MIPI DisCo property helpers Vinod Koul
@ 2017-10-21  9:20     ` Mark Brown
  2017-10-21  9:20     ` Mark Brown
  1 sibling, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:20 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:20AM +0530, Vinod Koul wrote:

> +	/* device is probed so let's read the properties now */
> +	if (slave->ops && slave->ops->read_prop)
> +		slave->ops->read_prop(slave);

Is it valid for us to not be able to read the properties?

> +		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
> +						&dpn[i].max_word);
> +		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
> +						&dpn[i].min_word);

Don't we know this stuff simply by virtue of knowing what device we're
talking to (given that there aren't class devices)?

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

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

* Re: [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
@ 2017-10-21  9:20     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:20 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:20AM +0530, Vinod Koul wrote:

> +	/* device is probed so let's read the properties now */
> +	if (slave->ops && slave->ops->read_prop)
> +		slave->ops->read_prop(slave);

Is it valid for us to not be able to read the properties?

> +		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
> +						&dpn[i].max_word);
> +		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
> +						&dpn[i].min_word);

Don't we know this stuff simply by virtue of knowing what device we're
talking to (given that there aren't class devices)?

[-- 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] 139+ messages in thread

* Re: [PATCH 06/14] soundwire: Add IO transfer
  2017-10-19  3:03   ` Vinod Koul
@ 2017-10-21  9:29     ` Mark Brown
  -1 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:29 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:22AM +0530, Vinod Koul wrote:

> +static bool sdw_get_page(struct sdw_slave *slave, struct sdw_msg *msg)
> +{
> +	bool page = false, paging_support = false;
> +
> +	if (slave && slave->prop.paging_support)
> +		paging_support = true;
> +
> +	/*
> +	 * Programme SCP page addr for:
> +	 * 1. addr_page1 and addr_page2 contains non-zero values.
> +	 * 2. Paging supported by Slave.
> +	 */
> +	switch (msg->dev_num) {
> +	case SDW_ENUM_DEV_NUM:
> +	case SDW_BROADCAST_DEV_NUM:
> +		break;
> +
> +	default:
> +		if (paging_support && ((msg->addr_page1) || (msg->addr_page2)))
> +			page = true;
> +	}
> +
> +	return page;

So if a page was specified but we don't have paging support we silently
just write to the base pagee?

> +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> +					struct sdw_msg *msg)
> +{
> +	bool page;
> +	int ret;
> +
> +	mutex_lock(&bus->msg_lock);
> +
> +	page = sdw_get_page(slave, msg);

get_page() doesn't interact with the hardware at all so it could be
outside the lock.

> +	ret = do_transfer(bus, msg, page);
> +	if (ret != 0 && ret != -ENODATA) {
> +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> +				msg->dev_num, ret);
> +		goto error;
> +	}
> +
> +	if (page)
> +		ret = sdw_reset_page(bus, msg->dev_num);

Wouldn't it be safer to reset the page even on error so future messages
go to the right place if the paging bit of the failed operation worked?

> +int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> +{
> +	struct sdw_msg msg;
> +	int ret;
> +
> +	pm_runtime_get_sync(slave->bus->dev);

No error check.

> +	pm_runtime_get_sync(slave->bus->dev);
> +
> +	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_WRITE, val);

The device doesn't need to be powered up for us to fill in the data
structures we're going to use.

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

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

* Re: [PATCH 06/14] soundwire: Add IO transfer
@ 2017-10-21  9:29     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:29 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:22AM +0530, Vinod Koul wrote:

> +static bool sdw_get_page(struct sdw_slave *slave, struct sdw_msg *msg)
> +{
> +	bool page = false, paging_support = false;
> +
> +	if (slave && slave->prop.paging_support)
> +		paging_support = true;
> +
> +	/*
> +	 * Programme SCP page addr for:
> +	 * 1. addr_page1 and addr_page2 contains non-zero values.
> +	 * 2. Paging supported by Slave.
> +	 */
> +	switch (msg->dev_num) {
> +	case SDW_ENUM_DEV_NUM:
> +	case SDW_BROADCAST_DEV_NUM:
> +		break;
> +
> +	default:
> +		if (paging_support && ((msg->addr_page1) || (msg->addr_page2)))
> +			page = true;
> +	}
> +
> +	return page;

So if a page was specified but we don't have paging support we silently
just write to the base pagee?

> +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> +					struct sdw_msg *msg)
> +{
> +	bool page;
> +	int ret;
> +
> +	mutex_lock(&bus->msg_lock);
> +
> +	page = sdw_get_page(slave, msg);

get_page() doesn't interact with the hardware at all so it could be
outside the lock.

> +	ret = do_transfer(bus, msg, page);
> +	if (ret != 0 && ret != -ENODATA) {
> +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> +				msg->dev_num, ret);
> +		goto error;
> +	}
> +
> +	if (page)
> +		ret = sdw_reset_page(bus, msg->dev_num);

Wouldn't it be safer to reset the page even on error so future messages
go to the right place if the paging bit of the failed operation worked?

> +int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> +{
> +	struct sdw_msg msg;
> +	int ret;
> +
> +	pm_runtime_get_sync(slave->bus->dev);

No error check.

> +	pm_runtime_get_sync(slave->bus->dev);
> +
> +	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_WRITE, val);

The device doesn't need to be powered up for us to fill in the data
structures we're going to use.

[-- 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] 139+ messages in thread

* Re: [PATCH 07/14] regmap: Add SoundWire bus support
  2017-10-19  3:03 ` [PATCH 07/14] regmap: Add SoundWire bus support Vinod Koul
@ 2017-10-21  9:34     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:34 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:23AM +0530, Vinod Koul wrote:

> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:

Really unhappy with the dual licensing for regmap code, this is
interface code for some GPL only kernel code and...

> +static int regmap_sdw_write(void *context, unsigned int reg, unsigned int val)
> +{
> +	struct device *dev = context;
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +
> +	/* Check for Slave */
> +	if (!slave)
> +		return 0;

We silently ignore the device not existing?

> +static struct regmap_bus regmap_sdw = {
> +	.reg_read = regmap_sdw_read,
> +	.reg_write = regmap_sdw_write,

Given that the bus appears to support bulk operations why are we
implementing this with reg_read() and reg_write()?  

> +		return ERR_PTR(ret);
> +
> +	return __regmap_init(&sdw->dev, &regmap_sdw,
> +			&sdw->dev, config, lock_key, lock_name);
> +}
> +EXPORT_SYMBOL(__regmap_init_sdw);

...this is just an obvious attempt to allow non-GPL code to directly use
GPL code.

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

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

* Re: [PATCH 07/14] regmap: Add SoundWire bus support
@ 2017-10-21  9:34     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:34 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:23AM +0530, Vinod Koul wrote:

> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015-17 Intel Corporation.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:

Really unhappy with the dual licensing for regmap code, this is
interface code for some GPL only kernel code and...

> +static int regmap_sdw_write(void *context, unsigned int reg, unsigned int val)
> +{
> +	struct device *dev = context;
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +
> +	/* Check for Slave */
> +	if (!slave)
> +		return 0;

We silently ignore the device not existing?

> +static struct regmap_bus regmap_sdw = {
> +	.reg_read = regmap_sdw_read,
> +	.reg_write = regmap_sdw_write,

Given that the bus appears to support bulk operations why are we
implementing this with reg_read() and reg_write()?  

> +		return ERR_PTR(ret);
> +
> +	return __regmap_init(&sdw->dev, &regmap_sdw,
> +			&sdw->dev, config, lock_key, lock_name);
> +}
> +EXPORT_SYMBOL(__regmap_init_sdw);

...this is just an obvious attempt to allow non-GPL code to directly use
GPL code.

[-- 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] 139+ messages in thread

* Re: [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
  2017-10-19  3:03 ` [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties Vinod Koul
@ 2017-10-21  9:42     ` Mark Brown
  2017-11-09 21:14   ` Srinivas Kandagatla
  1 sibling, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:42 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:26AM +0530, Vinod Koul wrote:

> +static ssize_t clock_frequencies_show(struct sdw_bus *bus,
> +			struct sdw_prop_attribute *attr, char *buf)
> +{
> +	ssize_t size = 0;
> +	int i;
> +
> +	for (i = 0; i < bus->prop.num_freq; i++)
> +		size += sprintf(buf + size, "%8d\n", bus->prop.freq[i]);
> +
> +	return size;
> +}

sysfs is supposed to be one value per file...

> +int sdw_sysfs_slave_init(struct sdw_slave *slave)
> +{
> +	/* TODO: Initialize dp0 and dpn kobject and attribute */
> +	return 0;
> +}
> +
> +void sdw_sysfs_slave_exit(struct sdw_slave *slave)
> +{
> +}

Seems like an important TODO?

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

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

* Re: [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
@ 2017-10-21  9:42     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:42 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:26AM +0530, Vinod Koul wrote:

> +static ssize_t clock_frequencies_show(struct sdw_bus *bus,
> +			struct sdw_prop_attribute *attr, char *buf)
> +{
> +	ssize_t size = 0;
> +	int i;
> +
> +	for (i = 0; i < bus->prop.num_freq; i++)
> +		size += sprintf(buf + size, "%8d\n", bus->prop.freq[i]);
> +
> +	return size;
> +}

sysfs is supposed to be one value per file...

> +int sdw_sysfs_slave_init(struct sdw_slave *slave)
> +{
> +	/* TODO: Initialize dp0 and dpn kobject and attribute */
> +	return 0;
> +}
> +
> +void sdw_sysfs_slave_exit(struct sdw_slave *slave)
> +{
> +}

Seems like an important TODO?

[-- 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] 139+ messages in thread

* Re: [PATCH 11/14] soundwire: cdns: Add cadence module
  2017-10-19  3:03 ` [PATCH 11/14] soundwire: cdns: Add cadence module Vinod Koul
@ 2017-10-21  9:52     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:52 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Thu, Oct 19, 2017 at 08:33:27AM +0530, Vinod Koul wrote:

> Cadence IP implements SoundWire Master. Add base cadence module
> initialization and interrupt handling

It's probably worth saying something about how this isn't a device
driver but rather a library for device drivers.

> +	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
> +
> +		/* Slave is driving bit slot during control word */
> +		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
> +		int_status |= CDNS_MCP_INT_CTRL_CLASH;
> +	}

So with this (and the other error flags) we check to see if the bit is
set, print an error and then set the bit we were looking for in the same
variable we just checked?

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

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

* Re: [PATCH 11/14] soundwire: cdns: Add cadence module
@ 2017-10-21  9:52     ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-21  9:52 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Thu, Oct 19, 2017 at 08:33:27AM +0530, Vinod Koul wrote:

> Cadence IP implements SoundWire Master. Add base cadence module
> initialization and interrupt handling

It's probably worth saying something about how this isn't a device
driver but rather a library for device drivers.

> +	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
> +
> +		/* Slave is driving bit slot during control word */
> +		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
> +		int_status |= CDNS_MCP_INT_CTRL_CLASH;
> +	}

So with this (and the other error flags) we check to see if the bit is
set, print an error and then set the bit we were looking for in the same
variable we just checked?

[-- 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] 139+ messages in thread

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-21  8:57     ` Mark Brown
@ 2017-10-21 11:28       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:28 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> 
> > +The SoundWire protocol supports up to eleven Slave interfaces. All the
> 
> There's lots of perfectly normal nouns in this document like Slave here
> which are randomly capitalized.  Is there some great reason for this?
> It makes the document pretty distracting to read.

Slave, SoundWire etc are MIPI definitions hence capitalized.

> > +Bus implements API to read standard Master MIPI properties and also provides
> > +callback in Master ops for Master driver to implement own functions that
> 
> implement it's own functions.

ok

> 
> > +provides capabilities information. DT support is not implemented at this
> > +time but should be trivial to add since capabilities are enabled with the
> > +device_property_ API.
> 
> Since we're making this up from whole cloth rather than following an
> existing standard let's get a DT binding document together and review
> the properties that are getting defined.

I don't have a DT to test, but looking at Slimbus code I guess assumptions
are fair and we seem to have similar concepts and implementation.

> 
> > +	/* Check ACPI for Slave devices */
> > +        sdw_acpi_find_slaves(bus);
> 
> Tab/space issues here.

fixed now

> 
> > +The MIPI specification requires each Slave interface to expose a unique
> > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> > +identifier contains vendor and part information, as well as a field enabling
> > +to differentiate between identical components. An additional class field is
> > +currently unused. Slave driver is written for the specific 48-bit
> > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> 
> So this says that the instance identifer is part of the device
> identifier but the driver should bind to the whole device identifer?
> I'd expect the driver to bind to everything except the instance
> identifer.

Other parts are still TBD and not really used, like Device Class, Spec
version. We are using only mfg id and part id for binding.

-- 
~Vinod

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-21 11:28       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:28 UTC (permalink / raw)
  To: Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
> 
> > +The SoundWire protocol supports up to eleven Slave interfaces. All the
> 
> There's lots of perfectly normal nouns in this document like Slave here
> which are randomly capitalized.  Is there some great reason for this?
> It makes the document pretty distracting to read.

Slave, SoundWire etc are MIPI definitions hence capitalized.

> > +Bus implements API to read standard Master MIPI properties and also provides
> > +callback in Master ops for Master driver to implement own functions that
> 
> implement it's own functions.

ok

> 
> > +provides capabilities information. DT support is not implemented at this
> > +time but should be trivial to add since capabilities are enabled with the
> > +device_property_ API.
> 
> Since we're making this up from whole cloth rather than following an
> existing standard let's get a DT binding document together and review
> the properties that are getting defined.

I don't have a DT to test, but looking at Slimbus code I guess assumptions
are fair and we seem to have similar concepts and implementation.

> 
> > +	/* Check ACPI for Slave devices */
> > +        sdw_acpi_find_slaves(bus);
> 
> Tab/space issues here.

fixed now

> 
> > +The MIPI specification requires each Slave interface to expose a unique
> > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> > +identifier contains vendor and part information, as well as a field enabling
> > +to differentiate between identical components. An additional class field is
> > +currently unused. Slave driver is written for the specific 48-bit
> > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> 
> So this says that the instance identifer is part of the device
> identifier but the driver should bind to the whole device identifer?
> I'd expect the driver to bind to everything except the instance
> identifer.

Other parts are still TBD and not really used, like Device Class, Spec
version. We are using only mfg id and part id for binding.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-21  9:03   ` Mark Brown
@ 2017-10-21 11:29       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:29 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:03:48AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> 
> > +	ret = dev_pm_domain_attach(dev, false);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drv->probe(slave, id);
> > +	if (ret) {
> > +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> > +		return ret;
> > +	}
> 
> We don't detach the power domain if the probe fails.

we should, thanks for spotting

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-21 11:29       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:29 UTC (permalink / raw)
  To: Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Sat, Oct 21, 2017 at 10:03:48AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> 
> > +	ret = dev_pm_domain_attach(dev, false);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = drv->probe(slave, id);
> > +	if (ret) {
> > +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> > +		return ret;
> > +	}
> 
> We don't detach the power domain if the probe fails.

we should, thanks for spotting

-- 
~Vinod

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-21  9:12     ` Mark Brown
@ 2017-10-21 11:35       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:35 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:12:30AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:
> 
> > +	/*
> > +	 * SDW is an enumerable bus, but devices can be powered off. So,
> > +	 * they won't be able to report as present.
> > +	 *
> > +	 * Create Slave devices based on Slaves described in
> > +	 * the respective firmware (ACPI/DT)
> > +	 */
> > +
> > +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> > +		ret = sdw_acpi_find_slaves(bus);
> > +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> > +		ret = sdw_of_find_slaves(bus);
> > +	else
> > +		ret = -ENOTSUPP; /* No ACPI/DT so error out */
> 
> Devices *can* be powered off but is there any reason that a system
> couldn't be designed with them always powered?  Also given that we don't
> actually have any DT support the stubs for it are at best misleading,
> it's not going to be hard for someone to add them later.

Some people asked me to add it so it is clear how it would be supported on
DT based platforms. I would be too glad to remove if we have consensus on
that. Agree it is not too hard to add :)

> 
> > +	mutex_lock(&bus->bus_lock);
> > +	if (!list_empty(&bus->slaves))
> > +		list_del(&slave->node);
> 
> Shouldn't that be a while?  Or at least warn if there's anything extra
> there.  The code just looks very wrong as is.

I think you missed that it is called from sdw_delete_bus_master() which does
the loop by invoking device_for_each_child(), so this ones is supposed to
ensure one Slave is removed cleaned.

Let me know if i misread your comment.


Thanks
-- 
~Vinod

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

* Re: [PATCH 03/14] soundwire: Add Master registration
@ 2017-10-21 11:35       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:35 UTC (permalink / raw)
  To: Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Sat, Oct 21, 2017 at 10:12:30AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:
> 
> > +	/*
> > +	 * SDW is an enumerable bus, but devices can be powered off. So,
> > +	 * they won't be able to report as present.
> > +	 *
> > +	 * Create Slave devices based on Slaves described in
> > +	 * the respective firmware (ACPI/DT)
> > +	 */
> > +
> > +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> > +		ret = sdw_acpi_find_slaves(bus);
> > +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> > +		ret = sdw_of_find_slaves(bus);
> > +	else
> > +		ret = -ENOTSUPP; /* No ACPI/DT so error out */
> 
> Devices *can* be powered off but is there any reason that a system
> couldn't be designed with them always powered?  Also given that we don't
> actually have any DT support the stubs for it are at best misleading,
> it's not going to be hard for someone to add them later.

Some people asked me to add it so it is clear how it would be supported on
DT based platforms. I would be too glad to remove if we have consensus on
that. Agree it is not too hard to add :)

> 
> > +	mutex_lock(&bus->bus_lock);
> > +	if (!list_empty(&bus->slaves))
> > +		list_del(&slave->node);
> 
> Shouldn't that be a while?  Or at least warn if there's anything extra
> there.  The code just looks very wrong as is.

I think you missed that it is called from sdw_delete_bus_master() which does
the loop by invoking device_for_each_child(), so this ones is supposed to
ensure one Slave is removed cleaned.

Let me know if i misread your comment.


Thanks
-- 
~Vinod

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

* Re: [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
  2017-10-21  9:20     ` Mark Brown
  (?)
@ 2017-10-21 11:37     ` Vinod Koul
  2017-10-22 10:14         ` Pierre-Louis Bossart
  -1 siblings, 1 reply; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:37 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:20:46AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:20AM +0530, Vinod Koul wrote:
> 
> > +	/* device is probed so let's read the properties now */
> > +	if (slave->ops && slave->ops->read_prop)
> > +		slave->ops->read_prop(slave);
> 
> Is it valid for us to not be able to read the properties?

Practically no. Without the values bus wont work

> 
> > +		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
> > +						&dpn[i].max_word);
> > +		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
> > +						&dpn[i].min_word);
> 
> Don't we know this stuff simply by virtue of knowing what device we're
> talking to (given that there aren't class devices)?

Well I think the spec is midway to device class so they added it to make it
generic :)

-- 
~Vinod

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

* Re: [PATCH 06/14] soundwire: Add IO transfer
  2017-10-21  9:29     ` Mark Brown
  (?)
@ 2017-10-21 11:40     ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:40 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:29:08AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:22AM +0530, Vinod Koul wrote:
> 
> > +static bool sdw_get_page(struct sdw_slave *slave, struct sdw_msg *msg)
> > +{
> > +	bool page = false, paging_support = false;
> > +
> > +	if (slave && slave->prop.paging_support)
> > +		paging_support = true;
> > +
> > +	/*
> > +	 * Programme SCP page addr for:
> > +	 * 1. addr_page1 and addr_page2 contains non-zero values.
> > +	 * 2. Paging supported by Slave.
> > +	 */
> > +	switch (msg->dev_num) {
> > +	case SDW_ENUM_DEV_NUM:
> > +	case SDW_BROADCAST_DEV_NUM:
> > +		break;
> > +
> > +	default:
> > +		if (paging_support && ((msg->addr_page1) || (msg->addr_page2)))
> > +			page = true;
> > +	}
> > +
> > +	return page;
> 
> So if a page was specified but we don't have paging support we silently
> just write to the base pagee?

yeah we should log this, will add

> > +int sdw_transfer(struct sdw_bus *bus, struct sdw_slave *slave,
> > +					struct sdw_msg *msg)
> > +{
> > +	bool page;
> > +	int ret;
> > +
> > +	mutex_lock(&bus->msg_lock);
> > +
> > +	page = sdw_get_page(slave, msg);
> 
> get_page() doesn't interact with the hardware at all so it could be
> outside the lock.

right

> 
> > +	ret = do_transfer(bus, msg, page);
> > +	if (ret != 0 && ret != -ENODATA) {
> > +		dev_err(bus->dev, "trf on Slave %d failed:%d\n",
> > +				msg->dev_num, ret);
> > +		goto error;
> > +	}
> > +
> > +	if (page)
> > +		ret = sdw_reset_page(bus, msg->dev_num);
> 
> Wouldn't it be safer to reset the page even on error so future messages
> go to the right place if the paging bit of the failed operation worked?

You have a valid point, let me check that part.

> > +int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
> > +{
> > +	struct sdw_msg msg;
> > +	int ret;
> > +
> > +	pm_runtime_get_sync(slave->bus->dev);
> 
> No error check.

will add

> > +	pm_runtime_get_sync(slave->bus->dev);
> > +
> > +	sdw_fill_msg(&msg, addr, count, slave->dev_num, SDW_MSG_FLAG_WRITE, val);
> 
> The device doesn't need to be powered up for us to fill in the data
> structures we're going to use.

Yes I can move it down a bit before do_transfer()

-- 
~Vinod

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

* Re: [PATCH 07/14] regmap: Add SoundWire bus support
  2017-10-21  9:34     ` Mark Brown
  (?)
@ 2017-10-21 11:44     ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:34:26AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:23AM +0530, Vinod Koul wrote:
> 
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015-17 Intel Corporation.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> 
> Really unhappy with the dual licensing for regmap code, this is
> interface code for some GPL only kernel code and...

Yeah Greg has same concern wrt core code, I am looking with folks who
understand this more than I do and will update.

> > +static int regmap_sdw_write(void *context, unsigned int reg, unsigned int val)
> > +{
> > +	struct device *dev = context;
> > +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> > +
> > +	/* Check for Slave */
> > +	if (!slave)
> > +		return 0;
> 
> We silently ignore the device not existing?

Yes will log this one

> > +static struct regmap_bus regmap_sdw = {
> > +	.reg_read = regmap_sdw_read,
> > +	.reg_write = regmap_sdw_write,
> 
> Given that the bus appears to support bulk operations why are we
> implementing this with reg_read() and reg_write()?

Well it is just the start. I would like to have base SOundWire supported
upstream first, have some Slave drivers as well. Its real pain for codec
folks to keep updating their code as we keep developing.
We do plan to add more features as we go along. And yes bulk ops are right
at the top of this list

> 
> > +		return ERR_PTR(ret);
> > +
> > +	return __regmap_init(&sdw->dev, &regmap_sdw,
> > +			&sdw->dev, config, lock_key, lock_name);
> > +}
> > +EXPORT_SYMBOL(__regmap_init_sdw);
> 
> ...this is just an obvious attempt to allow non-GPL code to directly use
> GPL code.

Sorry that was not the aim. We wanted the code to be shared with RTOS code
so they can use stuff from here. I understand the concerns raised and will
surely address that.

-- 
~Vinod

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

* Re: [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
  2017-10-21  9:42     ` Mark Brown
@ 2017-10-21 11:53       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:53 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:42:53AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:26AM +0530, Vinod Koul wrote:
> 
> > +static ssize_t clock_frequencies_show(struct sdw_bus *bus,
> > +			struct sdw_prop_attribute *attr, char *buf)
> > +{
> > +	ssize_t size = 0;
> > +	int i;
> > +
> > +	for (i = 0; i < bus->prop.num_freq; i++)
> > +		size += sprintf(buf + size, "%8d\n", bus->prop.freq[i]);
> > +
> > +	return size;
> > +}
> 
> sysfs is supposed to be one value per file...

I though it needs to be human readable like:

$ cat /sys/bus/cpu/devices/cpu0/cpufreq/scaling_available_governors
performance powersave

In this case, if this is allowed it does help to have a single file with all
supported frequencies for a device

> 
> > +int sdw_sysfs_slave_init(struct sdw_slave *slave)
> > +{
> > +	/* TODO: Initialize dp0 and dpn kobject and attribute */
> > +	return 0;
> > +}
> > +
> > +void sdw_sysfs_slave_exit(struct sdw_slave *slave)
> > +{
> > +}
> 
> Seems like an important TODO?

Yes. For now I will remove the dummy code and add the patches for this after
this series is done.

Thanks
-- 
~Vinod

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

* Re: [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
@ 2017-10-21 11:53       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:53 UTC (permalink / raw)
  To: Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Sat, Oct 21, 2017 at 10:42:53AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:26AM +0530, Vinod Koul wrote:
> 
> > +static ssize_t clock_frequencies_show(struct sdw_bus *bus,
> > +			struct sdw_prop_attribute *attr, char *buf)
> > +{
> > +	ssize_t size = 0;
> > +	int i;
> > +
> > +	for (i = 0; i < bus->prop.num_freq; i++)
> > +		size += sprintf(buf + size, "%8d\n", bus->prop.freq[i]);
> > +
> > +	return size;
> > +}
> 
> sysfs is supposed to be one value per file...

I though it needs to be human readable like:

$ cat /sys/bus/cpu/devices/cpu0/cpufreq/scaling_available_governors
performance powersave

In this case, if this is allowed it does help to have a single file with all
supported frequencies for a device

> 
> > +int sdw_sysfs_slave_init(struct sdw_slave *slave)
> > +{
> > +	/* TODO: Initialize dp0 and dpn kobject and attribute */
> > +	return 0;
> > +}
> > +
> > +void sdw_sysfs_slave_exit(struct sdw_slave *slave)
> > +{
> > +}
> 
> Seems like an important TODO?

Yes. For now I will remove the dummy code and add the patches for this after
this series is done.

Thanks
-- 
~Vinod

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

* Re: [PATCH 11/14] soundwire: cdns: Add cadence module
  2017-10-21  9:52     ` Mark Brown
@ 2017-10-21 11:54       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, Oct 21, 2017 at 10:52:01AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:27AM +0530, Vinod Koul wrote:
> 
> > Cadence IP implements SoundWire Master. Add base cadence module
> > initialization and interrupt handling
> 
> It's probably worth saying something about how this isn't a device
> driver but rather a library for device drivers.

Yes you are right, I will update this to clarify

> 
> > +	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
> > +
> > +		/* Slave is driving bit slot during control word */
> > +		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
> > +		int_status |= CDNS_MCP_INT_CTRL_CLASH;
> > +	}
> 
> So with this (and the other error flags) we check to see if the bit is
> set, print an error and then set the bit we were looking for in the same
> variable we just checked?

no this doesnt look right, I will fix it up.

-- 
~Vinod

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

* Re: [PATCH 11/14] soundwire: cdns: Add cadence module
@ 2017-10-21 11:54       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-21 11:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Sat, Oct 21, 2017 at 10:52:01AM +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:27AM +0530, Vinod Koul wrote:
> 
> > Cadence IP implements SoundWire Master. Add base cadence module
> > initialization and interrupt handling
> 
> It's probably worth saying something about how this isn't a device
> driver but rather a library for device drivers.

Yes you are right, I will update this to clarify

> 
> > +	if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
> > +
> > +		/* Slave is driving bit slot during control word */
> > +		dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
> > +		int_status |= CDNS_MCP_INT_CTRL_CLASH;
> > +	}
> 
> So with this (and the other error flags) we check to see if the bit is
> set, print an error and then set the bit we were looking for in the same
> variable we just checked?

no this doesnt look right, I will fix it up.

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-21 11:28       ` Vinod Koul
  (?)
@ 2017-10-22 10:06       ` Pierre-Louis Bossart
  2017-10-23  8:21         ` Mark Brown
  -1 siblings, 1 reply; 139+ messages in thread
From: Pierre-Louis Bossart @ 2017-10-22 10:06 UTC (permalink / raw)
  To: Vinod Koul, Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On 10/21/17 4:58 PM, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:
>> On Thu, Oct 19, 2017 at 08:33:17AM +0530, Vinod Koul wrote:
>>
>>> +The SoundWire protocol supports up to eleven Slave interfaces. All the
>>
>> There's lots of perfectly normal nouns in this document like Slave here
>> which are randomly capitalized.  Is there some great reason for this?
>> It makes the document pretty distracting to read.
> 
> Slave, SoundWire etc are MIPI definitions hence capitalized.

I insisted to follow the conventions in the specification, it's not 
random at all.

> 
>>> +Bus implements API to read standard Master MIPI properties and also provides
>>> +callback in Master ops for Master driver to implement own functions that
>>
>> implement it's own functions.
> 
> ok
> 
>>
>>> +provides capabilities information. DT support is not implemented at this
>>> +time but should be trivial to add since capabilities are enabled with the
>>> +device_property_ API.
>>
>> Since we're making this up from whole cloth rather than following an
>> existing standard let's get a DT binding document together and review
>> the properties that are getting defined.

The properties are already defined in the DisCo spec (publicly 
accessible) and were reviewed by MIPI contributors, they are not Intel 
specific and not invented by Intel.
We can put together a DT binding document that follows the Disco spec 
but it'd be a bad idea to change the definitions or come up with new ones...

> 
> I don't have a DT to test, but looking at Slimbus code I guess assumptions
> are fair and we seem to have similar concepts and implementation.
> 
>>
>>> +	/* Check ACPI for Slave devices */
>>> +        sdw_acpi_find_slaves(bus);
>>
>> Tab/space issues here.
> 
> fixed now
> 
>>
>>> +The MIPI specification requires each Slave interface to expose a unique
>>> +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
>>> +identifier contains vendor and part information, as well as a field enabling
>>> +to differentiate between identical components. An additional class field is
>>> +currently unused. Slave driver is written for the specific 48-bit
>>> +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
>>
>> So this says that the instance identifer is part of the device
>> identifier but the driver should bind to the whole device identifer?
>> I'd expect the driver to bind to everything except the instance
>> identifer.
> 
> Other parts are still TBD and not really used, like Device Class, Spec
> version. We are using only mfg id and part id for binding.

Yes, for now the only useful information is manufacturer ID/part ID, the 
spec version is not necessary since there is compatibility between 1.0 
and 1.1 and the changes are documented in properties.

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

* Re: [alsa-devel] [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
  2017-10-21 11:37     ` Vinod Koul
@ 2017-10-22 10:14         ` Pierre-Louis Bossart
  0 siblings, 0 replies; 139+ messages in thread
From: Pierre-Louis Bossart @ 2017-10-22 10:14 UTC (permalink / raw)
  To: Vinod Koul, Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On 10/21/17 5:07 PM, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 10:20:46AM +0100, Mark Brown wrote:
>> On Thu, Oct 19, 2017 at 08:33:20AM +0530, Vinod Koul wrote:
>>
>>> +	/* device is probed so let's read the properties now */
>>> +	if (slave->ops && slave->ops->read_prop)
>>> +		slave->ops->read_prop(slave);
>>
>> Is it valid for us to not be able to read the properties?
> 
> Practically no. Without the values bus wont work

The notion of read is a bit overloaded here. What is needed is that the 
information is provided to the bus, whether you read it from firmware or 
a table in the codec driver is an implementation choice - see below.
> 
>>
>>> +		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
>>> +						&dpn[i].max_word);
>>> +		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
>>> +						&dpn[i].min_word);
>>
>> Don't we know this stuff simply by virtue of knowing what device we're
>> talking to (given that there aren't class devices)?
> 
> Well I think the spec is midway to device class so they added it to make it
> generic :)

The properties are needed so that the bus can perform all the 
transport-related stuff. As explained in the patches, we are not making 
assumptions on how the codec driver is written, the implementation can 
either get the properties from firmware (DT or ACPI) or hard-code them 
in the driver.

The only property that needs to be defined is for multi-lane setups, 
since the topology is not known to a codec driver.

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

* Re: [PATCH 04/14] soundwire: Add MIPI DisCo property helpers
@ 2017-10-22 10:14         ` Pierre-Louis Bossart
  0 siblings, 0 replies; 139+ messages in thread
From: Pierre-Louis Bossart @ 2017-10-22 10:14 UTC (permalink / raw)
  To: Vinod Koul, Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On 10/21/17 5:07 PM, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 10:20:46AM +0100, Mark Brown wrote:
>> On Thu, Oct 19, 2017 at 08:33:20AM +0530, Vinod Koul wrote:
>>
>>> +	/* device is probed so let's read the properties now */
>>> +	if (slave->ops && slave->ops->read_prop)
>>> +		slave->ops->read_prop(slave);
>>
>> Is it valid for us to not be able to read the properties?
> 
> Practically no. Without the values bus wont work

The notion of read is a bit overloaded here. What is needed is that the 
information is provided to the bus, whether you read it from firmware or 
a table in the codec driver is an implementation choice - see below.
> 
>>
>>> +		fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength",
>>> +						&dpn[i].max_word);
>>> +		fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength",
>>> +						&dpn[i].min_word);
>>
>> Don't we know this stuff simply by virtue of knowing what device we're
>> talking to (given that there aren't class devices)?
> 
> Well I think the spec is midway to device class so they added it to make it
> generic :)

The properties are needed so that the bus can perform all the 
transport-related stuff. As explained in the patches, we are not making 
assumptions on how the codec driver is written, the implementation can 
either get the properties from firmware (DT or ACPI) or hard-code them 
in the driver.

The only property that needs to be defined is for multi-lane setups, 
since the topology is not known to a codec driver.

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-21 11:28       ` Vinod Koul
@ 2017-10-23  7:50         ` Mark Brown
  -1 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-23  7:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Sat, Oct 21, 2017 at 04:58:40PM +0530, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:

> > There's lots of perfectly normal nouns in this document like Slave here
> > which are randomly capitalized.  Is there some great reason for this?
> > It makes the document pretty distracting to read.

> Slave, SoundWire etc are MIPI definitions hence capitalized.

Slave?  Really?

> > > +provides capabilities information. DT support is not implemented at this
> > > +time but should be trivial to add since capabilities are enabled with the
> > > +device_property_ API.

> > Since we're making this up from whole cloth rather than following an
> > existing standard let's get a DT binding document together and review
> > the properties that are getting defined.

> I don't have a DT to test, but looking at Slimbus code I guess assumptions
> are fair and we seem to have similar concepts and implementation.

That's fine, we can still review binding documents.

> > > +The MIPI specification requires each Slave interface to expose a unique
> > > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> > > +identifier contains vendor and part information, as well as a field enabling
> > > +to differentiate between identical components. An additional class field is
> > > +currently unused. Slave driver is written for the specific 48-bit
> > > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.

> > So this says that the instance identifer is part of the device
> > identifier but the driver should bind to the whole device identifer?
> > I'd expect the driver to bind to everything except the instance
> > identifer.

> Other parts are still TBD and not really used, like Device Class, Spec
> version. We are using only mfg id and part id for binding.

That's not what the document claims.

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

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

* Re: [PATCH 01/14] Documentation: Add SoundWire summary
@ 2017-10-23  7:50         ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-23  7:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Sat, Oct 21, 2017 at 04:58:40PM +0530, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:

> > There's lots of perfectly normal nouns in this document like Slave here
> > which are randomly capitalized.  Is there some great reason for this?
> > It makes the document pretty distracting to read.

> Slave, SoundWire etc are MIPI definitions hence capitalized.

Slave?  Really?

> > > +provides capabilities information. DT support is not implemented at this
> > > +time but should be trivial to add since capabilities are enabled with the
> > > +device_property_ API.

> > Since we're making this up from whole cloth rather than following an
> > existing standard let's get a DT binding document together and review
> > the properties that are getting defined.

> I don't have a DT to test, but looking at Slimbus code I guess assumptions
> are fair and we seem to have similar concepts and implementation.

That's fine, we can still review binding documents.

> > > +The MIPI specification requires each Slave interface to expose a unique
> > > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> > > +identifier contains vendor and part information, as well as a field enabling
> > > +to differentiate between identical components. An additional class field is
> > > +currently unused. Slave driver is written for the specific 48-bit
> > > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.

> > So this says that the instance identifer is part of the device
> > identifier but the driver should bind to the whole device identifer?
> > I'd expect the driver to bind to everything except the instance
> > identifer.

> Other parts are still TBD and not really used, like Device Class, Spec
> version. We are using only mfg id and part id for binding.

That's not what the document claims.

[-- 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] 139+ messages in thread

* Re: [alsa-devel] [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-22 10:06       ` [alsa-devel] " Pierre-Louis Bossart
@ 2017-10-23  8:21         ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-23  8:21 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Vinod Koul, Greg Kroah-Hartman, LKML, ALSA, Takashi, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi, mark.rutland

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

On Sun, Oct 22, 2017 at 03:36:32PM +0530, Pierre-Louis Bossart wrote:
> On 10/21/17 4:58 PM, Vinod Koul wrote:
> > On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:

> > > There's lots of perfectly normal nouns in this document like Slave here
> > > which are randomly capitalized.  Is there some great reason for this?
> > > It makes the document pretty distracting to read.

> > Slave, SoundWire etc are MIPI definitions hence capitalized.

> I insisted to follow the conventions in the specification, it's not random
> at all.

It's making it pretty painful to read as kernel documentation.

> We can put together a DT binding document that follows the Disco spec but
> it'd be a bad idea to change the definitions or come up with new ones...

Given that there's a goal to do this via the device property stuff with
the apparent goal that we also use this stuff for DT it should at least
be run past some DT people. It may be that everything is totally fine as
is but we should at least check.

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

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-21 11:35       ` Vinod Koul
@ 2017-10-23  8:24         ` Mark Brown
  -1 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-23  8:24 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

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

On Sat, Oct 21, 2017 at 05:05:13PM +0530, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 10:12:30AM +0100, Mark Brown wrote:
> > On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:

> > > +	mutex_lock(&bus->bus_lock);
> > > +	if (!list_empty(&bus->slaves))
> > > +		list_del(&slave->node);

> > Shouldn't that be a while?  Or at least warn if there's anything extra
> > there.  The code just looks very wrong as is.

> I think you missed that it is called from sdw_delete_bus_master() which does
> the loop by invoking device_for_each_child(), so this ones is supposed to
> ensure one Slave is removed cleaned.

> Let me know if i misread your comment.

My point is that this code just looks so obviously wrong it doesn't
matter if it actually works, we should refactor so people don't look at
the code and immediately think they've spotted a bug.

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

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

* Re: [PATCH 03/14] soundwire: Add Master registration
@ 2017-10-23  8:24         ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-23  8:24 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan


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

On Sat, Oct 21, 2017 at 05:05:13PM +0530, Vinod Koul wrote:
> On Sat, Oct 21, 2017 at 10:12:30AM +0100, Mark Brown wrote:
> > On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:

> > > +	mutex_lock(&bus->bus_lock);
> > > +	if (!list_empty(&bus->slaves))
> > > +		list_del(&slave->node);

> > Shouldn't that be a while?  Or at least warn if there's anything extra
> > there.  The code just looks very wrong as is.

> I think you missed that it is called from sdw_delete_bus_master() which does
> the loop by invoking device_for_each_child(), so this ones is supposed to
> ensure one Slave is removed cleaned.

> Let me know if i misread your comment.

My point is that this code just looks so obviously wrong it doesn't
matter if it actually works, we should refactor so people don't look at
the code and immediately think they've spotted a bug.

[-- 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] 139+ messages in thread

* Re: [alsa-devel] [PATCH 01/14] Documentation: Add SoundWire summary
  2017-10-23  7:50         ` Mark Brown
  (?)
@ 2017-10-23 11:18         ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-23 11:18 UTC (permalink / raw)
  To: Mark Brown
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi,
	Greg Kroah-Hartman, plai, LKML, Pierre, patches.audio,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Mon, Oct 23, 2017 at 08:50:50AM +0100, Mark Brown wrote:
> On Sat, Oct 21, 2017 at 04:58:40PM +0530, Vinod Koul wrote:
> > On Sat, Oct 21, 2017 at 09:57:44AM +0100, Mark Brown wrote:
> 
> > > There's lots of perfectly normal nouns in this document like Slave here
> > > which are randomly capitalized.  Is there some great reason for this?
> > > It makes the document pretty distracting to read.
> 
> > Slave, SoundWire etc are MIPI definitions hence capitalized.
> 
> Slave?  Really?
> 
> > > > +provides capabilities information. DT support is not implemented at this
> > > > +time but should be trivial to add since capabilities are enabled with the
> > > > +device_property_ API.
> 
> > > Since we're making this up from whole cloth rather than following an
> > > existing standard let's get a DT binding document together and review
> > > the properties that are getting defined.
> 
> > I don't have a DT to test, but looking at Slimbus code I guess assumptions
> > are fair and we seem to have similar concepts and implementation.
> 
> That's fine, we can still review binding documents.

I am not really sure about that part, let me see if I can come up or worst
case not talk about DT at all.

> > > > +The MIPI specification requires each Slave interface to expose a unique
> > > > +48-bit identifier, stored in 6 read only dev_id registers. This dev_id
> > > > +identifier contains vendor and part information, as well as a field enabling
> > > > +to differentiate between identical components. An additional class field is
> > > > +currently unused. Slave driver is written for the specific 48-bit
> > > > +identifier, Bus enumerates the Slave device based on the 48-bit identifier.
> 
> > > So this says that the instance identifer is part of the device
> > > identifier but the driver should bind to the whole device identifer?
> > > I'd expect the driver to bind to everything except the instance
> > > identifer.
> 
> > Other parts are still TBD and not really used, like Device Class, Spec
> > version. We are using only mfg id and part id for binding.
> 
> That's not what the document claims.

Sorry about that fixed now. Thanks for pointing

-- 
~Vinod

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-23  8:24         ` Mark Brown
  (?)
@ 2017-10-23 11:19         ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-23 11:19 UTC (permalink / raw)
  To: Mark Brown
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Mon, Oct 23, 2017 at 09:24:26AM +0100, Mark Brown wrote:
> On Sat, Oct 21, 2017 at 05:05:13PM +0530, Vinod Koul wrote:
> > On Sat, Oct 21, 2017 at 10:12:30AM +0100, Mark Brown wrote:
> > > On Thu, Oct 19, 2017 at 08:33:19AM +0530, Vinod Koul wrote:
> 
> > > > +	mutex_lock(&bus->bus_lock);
> > > > +	if (!list_empty(&bus->slaves))
> > > > +		list_del(&slave->node);
> 
> > > Shouldn't that be a while?  Or at least warn if there's anything extra
> > > there.  The code just looks very wrong as is.
> 
> > I think you missed that it is called from sdw_delete_bus_master() which does
> > the loop by invoking device_for_each_child(), so this ones is supposed to
> > ensure one Slave is removed cleaned.
> 
> > Let me know if i misread your comment.
> 
> My point is that this code just looks so obviously wrong it doesn't
> matter if it actually works, we should refactor so people don't look at
> the code and immediately think they've spotted a bug.

Okay will check and try to refactor this part.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:21         ` Greg Kroah-Hartman
@ 2017-10-23 11:46           ` Alan Cox
  -1 siblings, 0 replies; 139+ messages in thread
From: Alan Cox @ 2017-10-23 11:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, Charles Keepax, Sagar Dharia, srinivas.kandagatla,
	plai, Sudheer Papothi

> > > And why dual license something that will only ever work on Linux?
> > 
> > We have non Linux users (mostly RTOS folks) which we would like to
> > support
> > with as much as common code.
> 
> Note, you need to be VERY CAREFUL about doing this.  You need to have
> all sorts of infrastructure set up and in place and paperwork up the
> wazoo in order to make it work properly.

Intel knows that. We have processes in place. We've been doing it for
years (ACPI, Graphics, ..)

> In the end, I can almost guarantee it will not be worth the extra
> hassle and effort you are trying to do here.

We don't think that is the case, and I'd imagine the NetBSD, FreeBSD,
OpenBSD, Dragonfly and other projects probably also prefer our
approach.

Seriously, go talk to your managers and corporate lawyer about this,
you are in for a world of hurt if you want to do this in a way that
actually works (i.e. doesn't just degrade to GPLv2 only instantly.)

It's far from the only project we do this with for at least the core OS
independent parts of the driver.

Alan

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-23 11:46           ` Alan Cox
  0 siblings, 0 replies; 139+ messages in thread
From: Alan Cox @ 2017-10-23 11:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia

> > > And why dual license something that will only ever work on Linux?
> > 
> > We have non Linux users (mostly RTOS folks) which we would like to
> > support
> > with as much as common code.
> 
> Note, you need to be VERY CAREFUL about doing this.  You need to have
> all sorts of infrastructure set up and in place and paperwork up the
> wazoo in order to make it work properly.

Intel knows that. We have processes in place. We've been doing it for
years (ACPI, Graphics, ..)

> In the end, I can almost guarantee it will not be worth the extra
> hassle and effort you are trying to do here.

We don't think that is the case, and I'd imagine the NetBSD, FreeBSD,
OpenBSD, Dragonfly and other projects probably also prefer our
approach.

Seriously, go talk to your managers and corporate lawyer about this,
you are in for a world of hurt if you want to do this in a way that
actually works (i.e. doesn't just degrade to GPLv2 only instantly.)

It's far from the only project we do this with for at least the core OS
independent parts of the driver.

Alan

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:27         ` Greg Kroah-Hartman
@ 2017-10-23 11:52             ` Alan Cox
  2017-10-23 11:52             ` Alan Cox
  1 sibling, 0 replies; 139+ messages in thread
From: Alan Cox @ 2017-10-23 11:52 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Vinod Koul
  Cc: Philippe Ombredanne, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, Charles Keepax,
	Sagar Dharia, srinivas.kandagatla, plai, Sudheer Papothi

> > I quick grep on Dual license users looks like we already have this
> > in kernel
> > code. See drivers/ntb/hw/intel/ntb_hw_intel.c
> 
> Just because someone did something wrong in the past, doesn't mean
> they
> should keep doing more wrong things in the future :)

What makes you think it's wrong ? It's the same approach the kernel has
been using since back to Linux 1.2 and maybe earlier.

I know it's not your intention but you are also going to look bad to
the BSD and other communities if you try and break dual licensing as a
standard Linux thing for some code. It goes back decades (Ted's random
driver for example).

Alan

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-23 11:52             ` Alan Cox
  0 siblings, 0 replies; 139+ messages in thread
From: Alan Cox @ 2017-10-23 11:52 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Vinod Koul
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, Shreyas NC,
	Pierre, LKML, patches.audio, Mark, srinivas.kandagatla,
	Philippe Ombredanne, Sanyog Kale, Sagar Dharia

> > I quick grep on Dual license users looks like we already have this
> > in kernel
> > code. See drivers/ntb/hw/intel/ntb_hw_intel.c
> 
> Just because someone did something wrong in the past, doesn't mean
> they
> should keep doing more wrong things in the future :)

What makes you think it's wrong ? It's the same approach the kernel has
been using since back to Linux 1.2 and maybe earlier.

I know it's not your intention but you are also going to look bad to
the BSD and other communities if you try and break dual licensing as a
standard Linux thing for some code. It goes back decades (Ted's random
driver for example).

Alan

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

* Re: [PATCH 07/14] regmap: Add SoundWire bus support
  2017-10-21  9:34     ` Mark Brown
  (?)
  (?)
@ 2017-10-23 11:56     ` Alan Cox
  2017-10-23 13:16       ` Mark Brown
  -1 siblings, 1 reply; 139+ messages in thread
From: Alan Cox @ 2017-10-23 11:56 UTC (permalink / raw)
  To: Mark Brown, Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre, Sanyog Kale,
	Shreyas NC, patches.audio, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Sat, 2017-10-21 at 10:34 +0100, Mark Brown wrote:
> On Thu, Oct 19, 2017 at 08:33:23AM +0530, Vinod Koul wrote:
> 
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015-17 Intel Corporation.
> > + *
> > + *  Redistribution and use in source and binary forms, with or
> > without
> > + *  modification, are permitted provided that the following
> > conditions
> > + *  are met:
> 
> Really unhappy with the dual licensing for regmap code, this is
> interface code for some GPL only kernel code and...

if anyone uses it with GPL code then it ends up GPL so in the Linux
kernel context it's always going to be GPL.

> > +EXPORT_SYMBOL(__regmap_init_sdw);
> 
> ...this is just an obvious attempt to allow non-GPL code to directly
> use
> GPL code.


There's nothing in the GPL about EXPORT_SYMBOL. If its built GPL
dependent then it depends upon GPL code so is GPL.

Alan

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

* Re: [PATCH 07/14] regmap: Add SoundWire bus support
  2017-10-23 11:56     ` Alan Cox
@ 2017-10-23 13:16       ` Mark Brown
  0 siblings, 0 replies; 139+ messages in thread
From: Mark Brown @ 2017-10-23 13:16 UTC (permalink / raw)
  To: Alan Cox
  Cc: Vinod Koul, Greg Kroah-Hartman, LKML, ALSA, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, Charles Keepax,
	Sagar Dharia, srinivas.kandagatla, plai, Sudheer Papothi

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

On Mon, Oct 23, 2017 at 12:56:27PM +0100, Alan Cox wrote:
> On Sat, 2017-10-21 at 10:34 +0100, Mark Brown wrote:
> > On Thu, Oct 19, 2017 at 08:33:23AM +0530, Vinod Koul wrote:

> > > +EXPORT_SYMBOL(__regmap_init_sdw);

> > ...this is just an obvious attempt to allow non-GPL code to directly
> > use
> > GPL code.

> There's nothing in the GPL about EXPORT_SYMBOL. If its built GPL
> dependent then it depends upon GPL code so is GPL.

My point is that in the context of this very thin wrapper around an API
that's entirely EXPORT_SYMBOL_GPL() dropping the _GPL() from the export
looks like it's going to enable questionable usage, probably in this
case it's just an oversight caused by all the other non-GPL exports in
the Slimbus code rather than something that's intentional.  This seems
particularly important here in something that's for drivers rather than
the subsystem itself since people might make assumptions (justified or
not) based on the EXPORT_SYMBOL() exports.

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

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-20 16:01     ` Vinod Koul
@ 2017-10-26  8:33         ` Vinod Koul
  2017-10-26  8:33         ` Vinod Koul
  1 sibling, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-26  8:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:

> > > +struct bus_type sdw_bus_type = {
> > > +	.name = "soundwire",
> > > +	.match = sdw_bus_match,
> > > +	.uevent = sdw_uevent,
> > > +};
> > > +EXPORT_SYMBOL(sdw_bus_type);
> > 
> > No release callback?  Who frees the device?

Hmmm, bus_type doesn't seem to have a release callback. The sdw_device has
release and that is added in the next patch. So I am not changing anything
here. Let me know If I missed anything...

Thanks
-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-10-26  8:33         ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-26  8:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Sudheer Papothi, Takashi, plai, LKML,
	Pierre, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:

> > > +struct bus_type sdw_bus_type = {
> > > +	.name = "soundwire",
> > > +	.match = sdw_bus_match,
> > > +	.uevent = sdw_uevent,
> > > +};
> > > +EXPORT_SYMBOL(sdw_bus_type);
> > 
> > No release callback?  Who frees the device?

Hmmm, bus_type doesn't seem to have a release callback. The sdw_device has
release and that is added in the next patch. So I am not changing anything
here. Let me know If I missed anything...

Thanks
-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-26  8:33         ` Vinod Koul
  (?)
@ 2017-10-27  8:57         ` Greg Kroah-Hartman
  2017-10-30 13:11           ` Vinod Koul
  -1 siblings, 1 reply; 139+ messages in thread
From: Greg Kroah-Hartman @ 2017-10-27  8:57 UTC (permalink / raw)
  To: Vinod Koul
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Thu, Oct 26, 2017 at 02:03:42PM +0530, Vinod Koul wrote:
> On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> 
> > > > +struct bus_type sdw_bus_type = {
> > > > +	.name = "soundwire",
> > > > +	.match = sdw_bus_match,
> > > > +	.uevent = sdw_uevent,
> > > > +};
> > > > +EXPORT_SYMBOL(sdw_bus_type);
> > > 
> > > No release callback?  Who frees the device?
> 
> Hmmm, bus_type doesn't seem to have a release callback. The sdw_device has
> release and that is added in the next patch. So I am not changing anything
> here. Let me know If I missed anything...

Ok, as long as you really have a release callback for when the device
goes away, and you have tested device removal...

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-27  8:57         ` Greg Kroah-Hartman
@ 2017-10-30 13:11           ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-30 13:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia,
	srinivas.kandagatla, plai, Sudheer Papothi

On Fri, Oct 27, 2017 at 10:57:39AM +0200, Greg Kroah-Hartman wrote:
> On Thu, Oct 26, 2017 at 02:03:42PM +0530, Vinod Koul wrote:
> > On Fri, Oct 20, 2017 at 09:31:34PM +0530, Vinod Koul wrote:
> > > On Fri, Oct 20, 2017 at 12:45:28PM +0200, Greg Kroah-Hartman wrote:
> > > > On Thu, Oct 19, 2017 at 08:33:18AM +0530, Vinod Koul wrote:
> > 
> > > > > +struct bus_type sdw_bus_type = {
> > > > > +	.name = "soundwire",
> > > > > +	.match = sdw_bus_match,
> > > > > +	.uevent = sdw_uevent,
> > > > > +};
> > > > > +EXPORT_SYMBOL(sdw_bus_type);
> > > > 
> > > > No release callback?  Who frees the device?
> > 
> > Hmmm, bus_type doesn't seem to have a release callback. The sdw_device has
> > release and that is added in the next patch. So I am not changing anything
> > here. Let me know If I missed anything...
> 
> Ok, as long as you really have a release callback for when the device
> goes away, and you have tested device removal...

Yup both checks done, thanks for confirming...

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 08/14] soundwire: Add Slave status handling helpers
  2017-10-19 13:44   ` [alsa-devel] " Takashi Iwai
@ 2017-10-31 13:04       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-31 13:04 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, Pierre, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Thu, Oct 19, 2017 at 03:44:12PM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:24 +0200,
> Vinod Koul wrote:

Sorry looks like I missed replying on this one, my apologies

> > +static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
> > +{
> > +	struct sdw_slave *slave;
> > +
> > +	list_for_each_entry(slave, &bus->slaves, node) {
> > +		if (slave->dev_num == i)
> > +			return slave;
> > +	}
> > +
> > +	return NULL;
> 
> Is this performed always in bus_lock, right?
> Better to document it.

Thanks we need to have lock here, fixed

> > +static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
> > +{
> > +
> > +	if ((slave->id.unique_id != id.unique_id) ||
> > +			(slave->id.mfg_id != id.mfg_id) ||
> > +			(slave->id.part_id != id.part_id) ||
> > +			(slave->id.class_id != id.class_id))
> 
> Align indentations.

sure

> > +static int sdw_get_device_num(struct sdw_slave *slave)
> > +{
> > +	bool assigned = false;
> > +	int i;
> > +
> > +	mutex_lock(&slave->bus->bus_lock);
> > +	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
> > +		if (slave->bus->assigned[i] == true)
> > +			continue;
> > +
> > +		slave->bus->assigned[i] = true;
> > +		assigned = true;
> > +
> > +		/*
> > +		 * Do not update dev_num in Slave data structure here,
> > +		 * Update once program dev_num is successful
> > +		 */
> > +		break;
> 
> With the bitmap, it's easier, you can use find_next_zero_bit() :)

yes already done

> > +static int sdw_program_device_num(struct sdw_bus *bus)
> > +{
> > +	u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
> > +	unsigned long long addr;
> 
> Use u64.

yes fixed

> > +	struct sdw_slave *slave;
> > +	struct sdw_slave_id id;
> > +	struct sdw_msg msg;
> > +	bool found = false;
> > +	int ret;
> > +
> > +	/* No Slave, so use raw xfer api */
> > +	sdw_fill_msg(&msg, SDW_SCP_DEVID_0, SDW_NUM_DEV_ID_REGISTERS,
> > +					0, SDW_MSG_FLAG_READ, buf);
> > +
> > +	do {
> > +		ret = sdw_transfer(bus, NULL, &msg);
> > +		if (ret == -ENODATA)
> > +			break;
> > +		if (ret < 0) {
> > +			dev_err(bus->dev, "DEVID read fail:%d\n", ret);
> > +			break;
> 
> So here we break, and the function returns zero.  Is this the expected
> behavior?

nope, thats a bug fixed now

> > +		if (found == false) {
> > +			/* TODO: Park this device in Group 13 */
> > +			dev_err(bus->dev, "Slave Entry not found");
> 
> No break here?  Otherwise...

Thats intentional. We want to still read next device that show up

> 
> > +		}
> > +
> > +	} while (ret == 0);
> 
> ... the outer loop may go endlessly.
> This condition doesn't look effective.

not really. We cant keep reading successfully. At some point all slaves will
ignore and return ENODATA and we exit. Bus errors will also make it exit

BUT given that we have seen stuff i am inclined to add a counter, we cant
have more than 11 device so that's a sane value to use :)

-- 
~Vinod

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

* Re: [PATCH 08/14] soundwire: Add Slave status handling helpers
@ 2017-10-31 13:04       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-10-31 13:04 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Pierre, Sagar Dharia, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Thu, Oct 19, 2017 at 03:44:12PM +0200, Takashi Iwai wrote:
> On Thu, 19 Oct 2017 05:03:24 +0200,
> Vinod Koul wrote:

Sorry looks like I missed replying on this one, my apologies

> > +static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
> > +{
> > +	struct sdw_slave *slave;
> > +
> > +	list_for_each_entry(slave, &bus->slaves, node) {
> > +		if (slave->dev_num == i)
> > +			return slave;
> > +	}
> > +
> > +	return NULL;
> 
> Is this performed always in bus_lock, right?
> Better to document it.

Thanks we need to have lock here, fixed

> > +static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
> > +{
> > +
> > +	if ((slave->id.unique_id != id.unique_id) ||
> > +			(slave->id.mfg_id != id.mfg_id) ||
> > +			(slave->id.part_id != id.part_id) ||
> > +			(slave->id.class_id != id.class_id))
> 
> Align indentations.

sure

> > +static int sdw_get_device_num(struct sdw_slave *slave)
> > +{
> > +	bool assigned = false;
> > +	int i;
> > +
> > +	mutex_lock(&slave->bus->bus_lock);
> > +	for (i = 1; i <= SDW_MAX_DEVICES; i++) {
> > +		if (slave->bus->assigned[i] == true)
> > +			continue;
> > +
> > +		slave->bus->assigned[i] = true;
> > +		assigned = true;
> > +
> > +		/*
> > +		 * Do not update dev_num in Slave data structure here,
> > +		 * Update once program dev_num is successful
> > +		 */
> > +		break;
> 
> With the bitmap, it's easier, you can use find_next_zero_bit() :)

yes already done

> > +static int sdw_program_device_num(struct sdw_bus *bus)
> > +{
> > +	u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
> > +	unsigned long long addr;
> 
> Use u64.

yes fixed

> > +	struct sdw_slave *slave;
> > +	struct sdw_slave_id id;
> > +	struct sdw_msg msg;
> > +	bool found = false;
> > +	int ret;
> > +
> > +	/* No Slave, so use raw xfer api */
> > +	sdw_fill_msg(&msg, SDW_SCP_DEVID_0, SDW_NUM_DEV_ID_REGISTERS,
> > +					0, SDW_MSG_FLAG_READ, buf);
> > +
> > +	do {
> > +		ret = sdw_transfer(bus, NULL, &msg);
> > +		if (ret == -ENODATA)
> > +			break;
> > +		if (ret < 0) {
> > +			dev_err(bus->dev, "DEVID read fail:%d\n", ret);
> > +			break;
> 
> So here we break, and the function returns zero.  Is this the expected
> behavior?

nope, thats a bug fixed now

> > +		if (found == false) {
> > +			/* TODO: Park this device in Group 13 */
> > +			dev_err(bus->dev, "Slave Entry not found");
> 
> No break here?  Otherwise...

Thats intentional. We want to still read next device that show up

> 
> > +		}
> > +
> > +	} while (ret == 0);
> 
> ... the outer loop may go endlessly.
> This condition doesn't look effective.

not really. We cant keep reading successfully. At some point all slaves will
ignore and return ENODATA and we exit. Bus errors will also make it exit

BUT given that we have seen stuff i am inclined to add a counter, we cant
have more than 11 device so that's a sane value to use :)

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 08/14] soundwire: Add Slave status handling helpers
  2017-10-31 13:04       ` Vinod Koul
@ 2017-10-31 21:19         ` Pierre-Louis Bossart
  -1 siblings, 0 replies; 139+ messages in thread
From: Pierre-Louis Bossart @ 2017-10-31 21:19 UTC (permalink / raw)
  To: Vinod Koul, Takashi Iwai
  Cc: Greg Kroah-Hartman, ALSA, Charles Keepax, Sudheer Papothi, plai,
	LKML, patches.audio, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan


> 
>>> +		if (found == false) {
>>> +			/* TODO: Park this device in Group 13 */
>>> +			dev_err(bus->dev, "Slave Entry not found");
>>
>> No break here?  Otherwise...
> 
> Thats intentional. We want to still read next device that show up
> 
>>
>>> +		}
>>> +
>>> +	} while (ret == 0);
>>
>> ... the outer loop may go endlessly.
>> This condition doesn't look effective.
> 
> not really. We cant keep reading successfully. At some point all slaves will
> ignore and return ENODATA and we exit. Bus errors will also make it exit
> 
> BUT given that we have seen stuff i am inclined to add a counter, we cant
> have more than 11 device so that's a sane value to use :)

Yep. Keep in mind however that there could be theoretical corner cases: 
if a device is enumerated, loses sync and becomes attached again while 
you deal with others, you'd have more than 11 iterations.

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

* Re: [PATCH 08/14] soundwire: Add Slave status handling helpers
@ 2017-10-31 21:19         ` Pierre-Louis Bossart
  0 siblings, 0 replies; 139+ messages in thread
From: Pierre-Louis Bossart @ 2017-10-31 21:19 UTC (permalink / raw)
  To: Vinod Koul, Takashi Iwai
  Cc: ALSA, Charles Keepax, patches.audio, Greg Kroah-Hartman, plai,
	LKML, Sagar Dharia, Mark, srinivas.kandagatla, Shreyas NC,
	Sanyog Kale, Sudheer Papothi, alan


> 
>>> +		if (found == false) {
>>> +			/* TODO: Park this device in Group 13 */
>>> +			dev_err(bus->dev, "Slave Entry not found");
>>
>> No break here?  Otherwise...
> 
> Thats intentional. We want to still read next device that show up
> 
>>
>>> +		}
>>> +
>>> +	} while (ret == 0);
>>
>> ... the outer loop may go endlessly.
>> This condition doesn't look effective.
> 
> not really. We cant keep reading successfully. At some point all slaves will
> ignore and return ENODATA and we exit. Bus errors will also make it exit
> 
> BUT given that we have seen stuff i am inclined to add a counter, we cant
> have more than 11 device so that's a sane value to use :)

Yep. Keep in mind however that there could be theoretical corner cases: 
if a device is enumerated, loses sync and becomes attached again while 
you deal with others, you'd have more than 11 iterations.

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

* Re: [alsa-devel] [PATCH 08/14] soundwire: Add Slave status handling helpers
  2017-10-31 21:19         ` Pierre-Louis Bossart
@ 2017-11-01  9:08           ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-01  9:08 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Takashi Iwai, Greg Kroah-Hartman, ALSA, Charles Keepax,
	Sudheer Papothi, plai, LKML, patches.audio, Mark,
	srinivas.kandagatla, Shreyas NC, Sanyog Kale, Sagar Dharia, alan

On Wed, Nov 01, 2017 at 02:49:15AM +0530, Pierre-Louis Bossart wrote:
> 
> >
> >>>+		if (found == false) {
> >>>+			/* TODO: Park this device in Group 13 */
> >>>+			dev_err(bus->dev, "Slave Entry not found");
> >>
> >>No break here?  Otherwise...
> >
> >Thats intentional. We want to still read next device that show up
> >
> >>
> >>>+		}
> >>>+
> >>>+	} while (ret == 0);
> >>
> >>... the outer loop may go endlessly.
> >>This condition doesn't look effective.
> >
> >not really. We cant keep reading successfully. At some point all slaves will
> >ignore and return ENODATA and we exit. Bus errors will also make it exit
> >
> >BUT given that we have seen stuff i am inclined to add a counter, we cant
> >have more than 11 device so that's a sane value to use :)
> 
> Yep. Keep in mind however that there could be theoretical corner cases: if a
> device is enumerated, loses sync and becomes attached again while you deal
> with others, you'd have more than 11 iterations.

Not really as that would be another interrupt and another status report.

-- 
~Vinod

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

* Re: [PATCH 08/14] soundwire: Add Slave status handling helpers
@ 2017-11-01  9:08           ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-01  9:08 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: ALSA, Charles Keepax, Takashi Iwai, Greg Kroah-Hartman, plai,
	LKML, Sagar Dharia, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Wed, Nov 01, 2017 at 02:49:15AM +0530, Pierre-Louis Bossart wrote:
> 
> >
> >>>+		if (found == false) {
> >>>+			/* TODO: Park this device in Group 13 */
> >>>+			dev_err(bus->dev, "Slave Entry not found");
> >>
> >>No break here?  Otherwise...
> >
> >Thats intentional. We want to still read next device that show up
> >
> >>
> >>>+		}
> >>>+
> >>>+	} while (ret == 0);
> >>
> >>... the outer loop may go endlessly.
> >>This condition doesn't look effective.
> >
> >not really. We cant keep reading successfully. At some point all slaves will
> >ignore and return ENODATA and we exit. Bus errors will also make it exit
> >
> >BUT given that we have seen stuff i am inclined to add a counter, we cant
> >have more than 11 device so that's a sane value to use :)
> 
> Yep. Keep in mind however that there could be theoretical corner cases: if a
> device is enumerated, loses sync and becomes attached again while you deal
> with others, you'd have more than 11 iterations.

Not really as that would be another interrupt and another status report.

-- 
~Vinod

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

* Re: [alsa-devel] [PATCH 08/14] soundwire: Add Slave status handling helpers
  2017-11-01  9:08           ` Vinod Koul
  (?)
@ 2017-11-01 21:10           ` Pierre-Louis Bossart
  2017-11-02  3:28             ` Vinod Koul
  -1 siblings, 1 reply; 139+ messages in thread
From: Pierre-Louis Bossart @ 2017-11-01 21:10 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Takashi Iwai, Greg Kroah-Hartman, plai,
	LKML, Sagar Dharia, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On 11/1/17 4:08 AM, Vinod Koul wrote:
> On Wed, Nov 01, 2017 at 02:49:15AM +0530, Pierre-Louis Bossart wrote:
>>
>>>
>>>>> +		if (found == false) {
>>>>> +			/* TODO: Park this device in Group 13 */
>>>>> +			dev_err(bus->dev, "Slave Entry not found");
>>>>
>>>> No break here?  Otherwise...
>>>
>>> Thats intentional. We want to still read next device that show up
>>>
>>>>
>>>>> +		}
>>>>> +
>>>>> +	} while (ret == 0);
>>>>
>>>> ... the outer loop may go endlessly.
>>>> This condition doesn't look effective.
>>>
>>> not really. We cant keep reading successfully. At some point all slaves will
>>> ignore and return ENODATA and we exit. Bus errors will also make it exit
>>>
>>> BUT given that we have seen stuff i am inclined to add a counter, we cant
>>> have more than 11 device so that's a sane value to use :)
>>
>> Yep. Keep in mind however that there could be theoretical corner cases: if a
>> device is enumerated, loses sync and becomes attached again while you deal
>> with others, you'd have more than 11 iterations.
> 
> Not really as that would be another interrupt and another status report.

You are in a loop where you keep reading the devId registers, and that 
really has nothing to do with interrupts or status report. The point was 
that the number of times you read may be higher that the number of 
devices with a device being handled several times.
As mentioned above you need to limit this loop to a sane value.

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

* Re: [alsa-devel] [PATCH 08/14] soundwire: Add Slave status handling helpers
  2017-11-01 21:10           ` [alsa-devel] " Pierre-Louis Bossart
@ 2017-11-02  3:28             ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-02  3:28 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: ALSA, Charles Keepax, Takashi Iwai, Greg Kroah-Hartman, plai,
	LKML, Sagar Dharia, patches.audio, Mark, srinivas.kandagatla,
	Shreyas NC, Sanyog Kale, Sudheer Papothi, alan

On Wed, Nov 01, 2017 at 04:10:08PM -0500, Pierre-Louis Bossart wrote:
> On 11/1/17 4:08 AM, Vinod Koul wrote:
> >On Wed, Nov 01, 2017 at 02:49:15AM +0530, Pierre-Louis Bossart wrote:
> >>>
> >>>BUT given that we have seen stuff i am inclined to add a counter, we cant
> >>>have more than 11 device so that's a sane value to use :)
> >>
> >>Yep. Keep in mind however that there could be theoretical corner cases: if a
> >>device is enumerated, loses sync and becomes attached again while you deal
> >>with others, you'd have more than 11 iterations.
> >
> >Not really as that would be another interrupt and another status report.
> 
> You are in a loop where you keep reading the devId registers, and that
> really has nothing to do with interrupts or status report. The point was
> that the number of times you read may be higher that the number of devices
> with a device being handled several times.
> As mentioned above you need to limit this loop to a sane value.

Oh yes, I was thinking from status point of view which triggers this but yes
we keep reading so your point is valid. Lets add 2x buffer for that.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-10-19  3:03 ` [PATCH 02/14] soundwire: Add SoundWire bus type Vinod Koul
@ 2017-11-09 21:14     ` Srinivas Kandagatla
  2017-10-20 10:41     ` Greg Kroah-Hartman
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-09 21:14 UTC (permalink / raw)
  To: Vinod Koul, Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia, plai,
	Sudheer Papothi



On 19/10/17 04:03, Vinod Koul wrote:
> This adds the base SoundWire bus type, bus and driver registration.
> along with changes to module device table for new SoundWire
> device type.
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---

> +++ b/drivers/soundwire/Kconfig
> @@ -0,0 +1,22 @@
> +#
> +# SoundWire subsystem configuration
> +#
> +
> +menuconfig SOUNDWIRE
> +	bool "SoundWire support"

Any reason why this subsystem can not be build as module?

> +	---help---
> +	  SoundWire is a 2-Pin interface with data and clock line ratified
> +	  by the MIPI Alliance. SoundWire is used for transporting data
> +	  typically related to audio functions. SoundWire interface is

> +#ifndef __SDW_BUS_H
> +#define __SDW_BUS_H
> +
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/acpi.h>
Do you need these headers here?

> +#include <linux/soundwire/sdw.h>
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> +
> +#endif /* __SDW_BUS_H */
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> new file mode 100644
> index 000000000000..a14d1de80afa
> --- /dev/null
> +++ b/drivers/soundwire/bus_type.c
>
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/soundwire/sdw.h>
> +#include "bus.h"
> +
> +/**
> + * sdw_get_device_id: find the matching SoundWire device id
> + *
function name should end with () - according to kernel doc.

> + * @slave: SoundWire Slave device
> + * @drv: SoundWire Slave Driver
> + *
> + * The match is done by comparing the mfg_id and part_id from the
> + * struct sdw_device_id. class_id is unused, as it is a placeholder
> + * in MIPI Spec.
> + */

BTW, This is a static private function, why are we adding kernel doc for 
this?

> +static const struct sdw_device_id *
> +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> +{
> +	const struct sdw_device_id *id = drv->id_table;
> +
> +	while (id && id->mfg_id) {
> +		if (slave->id.mfg_id == id->mfg_id &&
> +				slave->id.part_id == id->part_id) {
> +			return id;
> +		}
> +		id++;
> +	}
> +
> +	return NULL;
> +}
> +
> +static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> +
> +	return !!sdw_get_device_id(slave, drv);
> +}
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> +{
> +	/* modalias is sdw:m<mfg_id>p<part_id> */
> +
> +	return snprintf(buf, size, "sdw:m%04Xp%04X\n",
> +			slave->id.mfg_id, slave->id.part_id);
> +}
> +
> +static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	char modalias[32];
> +
> +	sdw_slave_modalias(slave, modalias, sizeof(modalias));
> +
> +	if (add_uevent_var(env, "MODALIAS=%s", modalias))
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +struct bus_type sdw_bus_type = {
> +	.name = "soundwire",
> +	.match = sdw_bus_match,
> +	.uevent = sdw_uevent,
> +};
> +EXPORT_SYMBOL(sdw_bus_type);
> +
> +static int sdw_drv_probe(struct device *dev)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> +	const struct sdw_device_id *id;
> +	int ret;
> +
> +	id = sdw_get_device_id(slave, drv);

By this time we must have already matched dev and driver by the ID, 
shouldn't it be just slave->id  here?
> +	if (!id)
> +		return -ENODEV;
> +
> +	/*
> +	 * attach to power domain but don't turn on (last arg)
> +	 */
> +	ret = dev_pm_domain_attach(dev, false);
> +	if (ret) {
Shouldn't it just handle the EPROBE_DEFER case and ignore it for other 
errors.


> +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drv->probe(slave, id);
> +	if (ret) {
> +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> +		return ret;
> +	}


What happens if the slave driver is built as module and loaded after the 
slave device is attached to the bus. How does the slave driver get 
updated status in this case?

We have similar usecase in slimbus too.

> +
> +	return 0;
> +}
> +




> 

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-11-09 21:14     ` Srinivas Kandagatla
  0 siblings, 0 replies; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-09 21:14 UTC (permalink / raw)
  To: Vinod Koul, Greg Kroah-Hartman
  Cc: ALSA, Charles Keepax, Takashi, plai, LKML, Pierre, patches.audio,
	Mark, Sudheer Papothi, Shreyas NC, Sanyog Kale, Sagar Dharia,
	alan



On 19/10/17 04:03, Vinod Koul wrote:
> This adds the base SoundWire bus type, bus and driver registration.
> along with changes to module device table for new SoundWire
> device type.
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---

> +++ b/drivers/soundwire/Kconfig
> @@ -0,0 +1,22 @@
> +#
> +# SoundWire subsystem configuration
> +#
> +
> +menuconfig SOUNDWIRE
> +	bool "SoundWire support"

Any reason why this subsystem can not be build as module?

> +	---help---
> +	  SoundWire is a 2-Pin interface with data and clock line ratified
> +	  by the MIPI Alliance. SoundWire is used for transporting data
> +	  typically related to audio functions. SoundWire interface is

> +#ifndef __SDW_BUS_H
> +#define __SDW_BUS_H
> +
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/acpi.h>
Do you need these headers here?

> +#include <linux/soundwire/sdw.h>
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> +
> +#endif /* __SDW_BUS_H */
> diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> new file mode 100644
> index 000000000000..a14d1de80afa
> --- /dev/null
> +++ b/drivers/soundwire/bus_type.c
>
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/soundwire/sdw.h>
> +#include "bus.h"
> +
> +/**
> + * sdw_get_device_id: find the matching SoundWire device id
> + *
function name should end with () - according to kernel doc.

> + * @slave: SoundWire Slave device
> + * @drv: SoundWire Slave Driver
> + *
> + * The match is done by comparing the mfg_id and part_id from the
> + * struct sdw_device_id. class_id is unused, as it is a placeholder
> + * in MIPI Spec.
> + */

BTW, This is a static private function, why are we adding kernel doc for 
this?

> +static const struct sdw_device_id *
> +sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> +{
> +	const struct sdw_device_id *id = drv->id_table;
> +
> +	while (id && id->mfg_id) {
> +		if (slave->id.mfg_id == id->mfg_id &&
> +				slave->id.part_id == id->part_id) {
> +			return id;
> +		}
> +		id++;
> +	}
> +
> +	return NULL;
> +}
> +
> +static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> +
> +	return !!sdw_get_device_id(slave, drv);
> +}
> +
> +int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> +{
> +	/* modalias is sdw:m<mfg_id>p<part_id> */
> +
> +	return snprintf(buf, size, "sdw:m%04Xp%04X\n",
> +			slave->id.mfg_id, slave->id.part_id);
> +}
> +
> +static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	char modalias[32];
> +
> +	sdw_slave_modalias(slave, modalias, sizeof(modalias));
> +
> +	if (add_uevent_var(env, "MODALIAS=%s", modalias))
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +struct bus_type sdw_bus_type = {
> +	.name = "soundwire",
> +	.match = sdw_bus_match,
> +	.uevent = sdw_uevent,
> +};
> +EXPORT_SYMBOL(sdw_bus_type);
> +
> +static int sdw_drv_probe(struct device *dev)
> +{
> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> +	const struct sdw_device_id *id;
> +	int ret;
> +
> +	id = sdw_get_device_id(slave, drv);

By this time we must have already matched dev and driver by the ID, 
shouldn't it be just slave->id  here?
> +	if (!id)
> +		return -ENODEV;
> +
> +	/*
> +	 * attach to power domain but don't turn on (last arg)
> +	 */
> +	ret = dev_pm_domain_attach(dev, false);
> +	if (ret) {
Shouldn't it just handle the EPROBE_DEFER case and ignore it for other 
errors.


> +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = drv->probe(slave, id);
> +	if (ret) {
> +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> +		return ret;
> +	}


What happens if the slave driver is built as module and loaded after the 
slave device is attached to the bus. How does the slave driver get 
updated status in this case?

We have similar usecase in slimbus too.

> +
> +	return 0;
> +}
> +




> 

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-10-19  3:03   ` Vinod Koul
                     ` (3 preceding siblings ...)
  (?)
@ 2017-11-09 21:14   ` Srinivas Kandagatla
  2017-11-10  5:02       ` Vinod Koul
  -1 siblings, 1 reply; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-09 21:14 UTC (permalink / raw)
  To: Vinod Koul, Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia, plai,
	Sudheer Papothi



On 19/10/17 04:03, Vinod Koul wrote:

> +/**
> + * sdw_add_bus_master: add a bus Master instance
> + *
> + * @bus: bus instance
> + *
> + * Initializes the bus instance, read properties and create child
> + * devices.
> + */

Some of the exported functions are missing kerneldocs.
Is it something you plan to add in next version of the patcheset?

> +int sdw_add_bus_master(struct sdw_bus *bus)
> +{
> +	int ret;
> +
> +	if (!bus->dev) {
> +		pr_err("SoundWire bus has no device");
> +		return -ENODEV;
> +	}
> +
> +	mutex_init(&bus->bus_lock);
> +	INIT_LIST_HEAD(&bus->slaves);
> +
> +	/*
> +	 * SDW is an enumerable bus, but devices can be powered off. So,
> +	 * they won't be able to report as present.
> +	 *
> +	 * Create Slave devices based on Slaves described in
> +	 * the respective firmware (ACPI/DT)
> +	 */
> +
> +	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> +		ret = sdw_acpi_find_slaves(bus);
> +	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> +		ret = sdw_of_find_slaves(bus);
> +	else
bus->dev is already checked in the start of the function, do we need to 
check once again ?

> +		ret = -ENOTSUPP; /* No ACPI/DT so error out */
> +
> +	if (ret) {
> +		dev_err(bus->dev, "Finding slaves failed:%d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(sdw_add_bus_master);

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

* Re: [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
  2017-10-19  3:03 ` [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties Vinod Koul
  2017-10-21  9:42     ` Mark Brown
@ 2017-11-09 21:14   ` Srinivas Kandagatla
  2017-11-10  4:52     ` Vinod Koul
  1 sibling, 1 reply; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-09 21:14 UTC (permalink / raw)
  To: Vinod Koul, Greg Kroah-Hartman
  Cc: LKML, ALSA, Mark, Takashi, Pierre, Sanyog Kale, Shreyas NC,
	patches.audio, alan, Charles Keepax, Sagar Dharia, plai,
	Sudheer Papothi



On 19/10/17 04:03, Vinod Koul wrote:
> It helps to read the properties for understanding and debug
> SoundWire systems, so add sysfs files for SoundWire DisCo
> properties.
> 
> TODO: Add ABI files for sysfs
> 
> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> ---

> diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> index 6c4f41b64744..e3d7aea18892 100644
> --- a/drivers/soundwire/bus.c
> +++ b/drivers/soundwire/bus.c
> @@ -90,6 +90,8 @@ int sdw_add_bus_master(struct sdw_bus *bus)
>   		}
>   	}
>   
> +	sdw_sysfs_bus_init(bus);
> +
>   	/*
>   	 * SDW is an enumerable bus, but devices can be powered off. So,
>   	 * they won't be able to report as present.
> @@ -119,6 +121,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
>   	struct sdw_slave *slave = dev_to_sdw_dev(dev);
>   	struct sdw_bus *bus = slave->bus;
>   
> +	sdw_sysfs_slave_exit(slave);
> +
>   	mutex_lock(&bus->bus_lock);
>   	if (!list_empty(&bus->slaves))
>   		list_del(&slave->node);
> @@ -130,6 +134,7 @@ static int sdw_delete_slave(struct device *dev, void *data)
>   
>   void sdw_delete_bus_master(struct sdw_bus *bus)
>   {
> +	sdw_sysfs_bus_init(bus);

Shouldn't this be sdw_sysfs_bus_exit() here?


>   	device_for_each_child(bus->dev, NULL, sdw_delete_slave);
>   }

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

* Re: [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties
  2017-11-09 21:14   ` Srinivas Kandagatla
@ 2017-11-10  4:52     ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-10  4:52 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi

On Thu, Nov 09, 2017 at 09:14:35PM +0000, Srinivas Kandagatla wrote:
> 
> 
> On 19/10/17 04:03, Vinod Koul wrote:
> >It helps to read the properties for understanding and debug
> >SoundWire systems, so add sysfs files for SoundWire DisCo
> >properties.
> >
> >TODO: Add ABI files for sysfs
> >
> >Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> >Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> >---
> 
> >diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
> >index 6c4f41b64744..e3d7aea18892 100644
> >--- a/drivers/soundwire/bus.c
> >+++ b/drivers/soundwire/bus.c
> >@@ -90,6 +90,8 @@ int sdw_add_bus_master(struct sdw_bus *bus)
> >  		}
> >  	}
> >+	sdw_sysfs_bus_init(bus);
> >+
> >  	/*
> >  	 * SDW is an enumerable bus, but devices can be powered off. So,
> >  	 * they won't be able to report as present.
> >@@ -119,6 +121,8 @@ static int sdw_delete_slave(struct device *dev, void *data)
> >  	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >  	struct sdw_bus *bus = slave->bus;
> >+	sdw_sysfs_slave_exit(slave);
> >+
> >  	mutex_lock(&bus->bus_lock);
> >  	if (!list_empty(&bus->slaves))
> >  		list_del(&slave->node);
> >@@ -130,6 +134,7 @@ static int sdw_delete_slave(struct device *dev, void *data)
> >  void sdw_delete_bus_master(struct sdw_bus *bus)
> >  {
> >+	sdw_sysfs_bus_init(bus);
> 
> Shouldn't this be sdw_sysfs_bus_exit() here?

yes thats right, fixes in for v2

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-11-09 21:14     ` Srinivas Kandagatla
@ 2017-11-10  4:59       ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-10  4:59 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi

On Thu, Nov 09, 2017 at 09:14:07PM +0000, Srinivas Kandagatla wrote:
> 
> 
> On 19/10/17 04:03, Vinod Koul wrote:
> >This adds the base SoundWire bus type, bus and driver registration.
> >along with changes to module device table for new SoundWire
> >device type.
> >
> >Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> >Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> >---
> 
> >+++ b/drivers/soundwire/Kconfig
> >@@ -0,0 +1,22 @@
> >+#
> >+# SoundWire subsystem configuration
> >+#
> >+
> >+menuconfig SOUNDWIRE
> >+	bool "SoundWire support"
> 
> Any reason why this subsystem can not be build as module?

This is not subsystem symbol but the menu. The SOUNDWIRE_BUS can be module.

> 
> >+	---help---
> >+	  SoundWire is a 2-Pin interface with data and clock line ratified
> >+	  by the MIPI Alliance. SoundWire is used for transporting data
> >+	  typically related to audio functions. SoundWire interface is
> 
> >+#ifndef __SDW_BUS_H
> >+#define __SDW_BUS_H
> >+
> >+#include <linux/init.h>
> >+#include <linux/device.h>
> >+#include <linux/module.h>
> >+#include <linux/mod_devicetable.h>
> >+#include <linux/acpi.h>
> Do you need these headers here?

Yes :) I will double check though


> 
> >+#include <linux/soundwire/sdw.h>
> >+
> >+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> >+
> >+#endif /* __SDW_BUS_H */
> >diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> >new file mode 100644
> >index 000000000000..a14d1de80afa
> >--- /dev/null
> >+++ b/drivers/soundwire/bus_type.c
> >
> >+#include <linux/acpi.h>
> >+#include <linux/device.h>
> >+#include <linux/init.h>
> >+#include <linux/module.h>
> >+#include <linux/mod_devicetable.h>
> >+#include <linux/pm_domain.h>
> >+#include <linux/pm_runtime.h>
> >+#include <linux/soundwire/sdw.h>
> >+#include "bus.h"
> >+
> >+/**
> >+ * sdw_get_device_id: find the matching SoundWire device id
> >+ *
> function name should end with () - according to kernel doc.

ah thanks for pointing will add

> 
> >+ * @slave: SoundWire Slave device
> >+ * @drv: SoundWire Slave Driver
> >+ *
> >+ * The match is done by comparing the mfg_id and part_id from the
> >+ * struct sdw_device_id. class_id is unused, as it is a placeholder
> >+ * in MIPI Spec.
> >+ */
> 
> BTW, This is a static private function, why are we adding kernel doc for
> this?

the match is an important routine and helps people understand the logic
hence documentation. More doc is better right :)

> 
> >+static const struct sdw_device_id *
> >+sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> >+{
> >+	const struct sdw_device_id *id = drv->id_table;
> >+
> >+	while (id && id->mfg_id) {
> >+		if (slave->id.mfg_id == id->mfg_id &&
> >+				slave->id.part_id == id->part_id) {
> >+			return id;
> >+		}
> >+		id++;
> >+	}
> >+
> >+	return NULL;
> >+}
> >+
> >+static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> >+{
> >+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >+	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> >+
> >+	return !!sdw_get_device_id(slave, drv);
> >+}
> >+
> >+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> >+{
> >+	/* modalias is sdw:m<mfg_id>p<part_id> */
> >+
> >+	return snprintf(buf, size, "sdw:m%04Xp%04X\n",
> >+			slave->id.mfg_id, slave->id.part_id);
> >+}
> >+
> >+static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env)
> >+{
> >+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >+	char modalias[32];
> >+
> >+	sdw_slave_modalias(slave, modalias, sizeof(modalias));
> >+
> >+	if (add_uevent_var(env, "MODALIAS=%s", modalias))
> >+		return -ENOMEM;
> >+
> >+	return 0;
> >+}
> >+
> >+struct bus_type sdw_bus_type = {
> >+	.name = "soundwire",
> >+	.match = sdw_bus_match,
> >+	.uevent = sdw_uevent,
> >+};
> >+EXPORT_SYMBOL(sdw_bus_type);
> >+
> >+static int sdw_drv_probe(struct device *dev)
> >+{
> >+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >+	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> >+	const struct sdw_device_id *id;
> >+	int ret;
> >+
> >+	id = sdw_get_device_id(slave, drv);
> 
> By this time we must have already matched dev and driver by the ID,
> shouldn't it be just slave->id  here?

I don't think so we do not have slave->id, we pass the id in probe as an
argument

> >+	if (!id)
> >+		return -ENODEV;
> >+
> >+	/*
> >+	 * attach to power domain but don't turn on (last arg)
> >+	 */
> >+	ret = dev_pm_domain_attach(dev, false);
> >+	if (ret) {
> Shouldn't it just handle the EPROBE_DEFER case and ignore it for other
> errors.

why should we ignore other errors and continue?

> 
> 
> >+		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> >+		return ret;
> >+	}
> >+
> >+	ret = drv->probe(slave, id);
> >+	if (ret) {
> >+		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> >+		return ret;
> >+	}
> 
> 
> What happens if the slave driver is built as module and loaded after the
> slave device is attached to the bus. How does the slave driver get updated
> status in this case?
> 
> We have similar usecase in slimbus too.

So we create devices based on firmware description, then the Slave may
report as present and we mark it as present. Once a driver is loaded, the
driver is probed here, the slave->status clearly tells the driver that slave
has already reported present.

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-11-10  4:59       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-10  4:59 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: ALSA, Charles Keepax, Takashi, Greg Kroah-Hartman, plai, LKML,
	Pierre, patches.audio, Mark, Sudheer Papothi, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Thu, Nov 09, 2017 at 09:14:07PM +0000, Srinivas Kandagatla wrote:
> 
> 
> On 19/10/17 04:03, Vinod Koul wrote:
> >This adds the base SoundWire bus type, bus and driver registration.
> >along with changes to module device table for new SoundWire
> >device type.
> >
> >Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> >Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> >---
> 
> >+++ b/drivers/soundwire/Kconfig
> >@@ -0,0 +1,22 @@
> >+#
> >+# SoundWire subsystem configuration
> >+#
> >+
> >+menuconfig SOUNDWIRE
> >+	bool "SoundWire support"
> 
> Any reason why this subsystem can not be build as module?

This is not subsystem symbol but the menu. The SOUNDWIRE_BUS can be module.

> 
> >+	---help---
> >+	  SoundWire is a 2-Pin interface with data and clock line ratified
> >+	  by the MIPI Alliance. SoundWire is used for transporting data
> >+	  typically related to audio functions. SoundWire interface is
> 
> >+#ifndef __SDW_BUS_H
> >+#define __SDW_BUS_H
> >+
> >+#include <linux/init.h>
> >+#include <linux/device.h>
> >+#include <linux/module.h>
> >+#include <linux/mod_devicetable.h>
> >+#include <linux/acpi.h>
> Do you need these headers here?

Yes :) I will double check though


> 
> >+#include <linux/soundwire/sdw.h>
> >+
> >+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> >+
> >+#endif /* __SDW_BUS_H */
> >diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> >new file mode 100644
> >index 000000000000..a14d1de80afa
> >--- /dev/null
> >+++ b/drivers/soundwire/bus_type.c
> >
> >+#include <linux/acpi.h>
> >+#include <linux/device.h>
> >+#include <linux/init.h>
> >+#include <linux/module.h>
> >+#include <linux/mod_devicetable.h>
> >+#include <linux/pm_domain.h>
> >+#include <linux/pm_runtime.h>
> >+#include <linux/soundwire/sdw.h>
> >+#include "bus.h"
> >+
> >+/**
> >+ * sdw_get_device_id: find the matching SoundWire device id
> >+ *
> function name should end with () - according to kernel doc.

ah thanks for pointing will add

> 
> >+ * @slave: SoundWire Slave device
> >+ * @drv: SoundWire Slave Driver
> >+ *
> >+ * The match is done by comparing the mfg_id and part_id from the
> >+ * struct sdw_device_id. class_id is unused, as it is a placeholder
> >+ * in MIPI Spec.
> >+ */
> 
> BTW, This is a static private function, why are we adding kernel doc for
> this?

the match is an important routine and helps people understand the logic
hence documentation. More doc is better right :)

> 
> >+static const struct sdw_device_id *
> >+sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv)
> >+{
> >+	const struct sdw_device_id *id = drv->id_table;
> >+
> >+	while (id && id->mfg_id) {
> >+		if (slave->id.mfg_id == id->mfg_id &&
> >+				slave->id.part_id == id->part_id) {
> >+			return id;
> >+		}
> >+		id++;
> >+	}
> >+
> >+	return NULL;
> >+}
> >+
> >+static int sdw_bus_match(struct device *dev, struct device_driver *ddrv)
> >+{
> >+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >+	struct sdw_driver *drv = drv_to_sdw_driver(ddrv);
> >+
> >+	return !!sdw_get_device_id(slave, drv);
> >+}
> >+
> >+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size)
> >+{
> >+	/* modalias is sdw:m<mfg_id>p<part_id> */
> >+
> >+	return snprintf(buf, size, "sdw:m%04Xp%04X\n",
> >+			slave->id.mfg_id, slave->id.part_id);
> >+}
> >+
> >+static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env)
> >+{
> >+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >+	char modalias[32];
> >+
> >+	sdw_slave_modalias(slave, modalias, sizeof(modalias));
> >+
> >+	if (add_uevent_var(env, "MODALIAS=%s", modalias))
> >+		return -ENOMEM;
> >+
> >+	return 0;
> >+}
> >+
> >+struct bus_type sdw_bus_type = {
> >+	.name = "soundwire",
> >+	.match = sdw_bus_match,
> >+	.uevent = sdw_uevent,
> >+};
> >+EXPORT_SYMBOL(sdw_bus_type);
> >+
> >+static int sdw_drv_probe(struct device *dev)
> >+{
> >+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >+	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> >+	const struct sdw_device_id *id;
> >+	int ret;
> >+
> >+	id = sdw_get_device_id(slave, drv);
> 
> By this time we must have already matched dev and driver by the ID,
> shouldn't it be just slave->id  here?

I don't think so we do not have slave->id, we pass the id in probe as an
argument

> >+	if (!id)
> >+		return -ENODEV;
> >+
> >+	/*
> >+	 * attach to power domain but don't turn on (last arg)
> >+	 */
> >+	ret = dev_pm_domain_attach(dev, false);
> >+	if (ret) {
> Shouldn't it just handle the EPROBE_DEFER case and ignore it for other
> errors.

why should we ignore other errors and continue?

> 
> 
> >+		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> >+		return ret;
> >+	}
> >+
> >+	ret = drv->probe(slave, id);
> >+	if (ret) {
> >+		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> >+		return ret;
> >+	}
> 
> 
> What happens if the slave driver is built as module and loaded after the
> slave device is attached to the bus. How does the slave driver get updated
> status in this case?
> 
> We have similar usecase in slimbus too.

So we create devices based on firmware description, then the Slave may
report as present and we mark it as present. Once a driver is loaded, the
driver is probed here, the slave->status clearly tells the driver that slave
has already reported present.

-- 
~Vinod

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

* Re: [PATCH 03/14] soundwire: Add Master registration
  2017-11-09 21:14   ` Srinivas Kandagatla
@ 2017-11-10  5:02       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-10  5:02 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi

On Thu, Nov 09, 2017 at 09:14:16PM +0000, Srinivas Kandagatla wrote:
> 
> 
> On 19/10/17 04:03, Vinod Koul wrote:
> 
> >+/**
> >+ * sdw_add_bus_master: add a bus Master instance
> >+ *
> >+ * @bus: bus instance
> >+ *
> >+ * Initializes the bus instance, read properties and create child
> >+ * devices.
> >+ */
> 
> Some of the exported functions are missing kerneldocs.
> Is it something you plan to add in next version of the patcheset?

I though most were, will double check to be sure.

> 
> >+int sdw_add_bus_master(struct sdw_bus *bus)
> >+{
> >+	int ret;
> >+
> >+	if (!bus->dev) {
> >+		pr_err("SoundWire bus has no device");
> >+		return -ENODEV;
> >+	}
> >+
> >+	mutex_init(&bus->bus_lock);
> >+	INIT_LIST_HEAD(&bus->slaves);
> >+
> >+	/*
> >+	 * SDW is an enumerable bus, but devices can be powered off. So,
> >+	 * they won't be able to report as present.
> >+	 *
> >+	 * Create Slave devices based on Slaves described in
> >+	 * the respective firmware (ACPI/DT)
> >+	 */
> >+
> >+	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> >+		ret = sdw_acpi_find_slaves(bus);
> >+	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> >+		ret = sdw_of_find_slaves(bus);
> >+	else
> bus->dev is already checked in the start of the function, do we need to
> check once again ?

yes already fixed, thanks

-- 
~Vinod

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

* Re: [PATCH 03/14] soundwire: Add Master registration
@ 2017-11-10  5:02       ` Vinod Koul
  0 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-10  5:02 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: ALSA, Charles Keepax, Takashi, Greg Kroah-Hartman, plai, LKML,
	Pierre, patches.audio, Mark, Sudheer Papothi, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan

On Thu, Nov 09, 2017 at 09:14:16PM +0000, Srinivas Kandagatla wrote:
> 
> 
> On 19/10/17 04:03, Vinod Koul wrote:
> 
> >+/**
> >+ * sdw_add_bus_master: add a bus Master instance
> >+ *
> >+ * @bus: bus instance
> >+ *
> >+ * Initializes the bus instance, read properties and create child
> >+ * devices.
> >+ */
> 
> Some of the exported functions are missing kerneldocs.
> Is it something you plan to add in next version of the patcheset?

I though most were, will double check to be sure.

> 
> >+int sdw_add_bus_master(struct sdw_bus *bus)
> >+{
> >+	int ret;
> >+
> >+	if (!bus->dev) {
> >+		pr_err("SoundWire bus has no device");
> >+		return -ENODEV;
> >+	}
> >+
> >+	mutex_init(&bus->bus_lock);
> >+	INIT_LIST_HEAD(&bus->slaves);
> >+
> >+	/*
> >+	 * SDW is an enumerable bus, but devices can be powered off. So,
> >+	 * they won't be able to report as present.
> >+	 *
> >+	 * Create Slave devices based on Slaves described in
> >+	 * the respective firmware (ACPI/DT)
> >+	 */
> >+
> >+	if (IS_ENABLED(CONFIG_ACPI) && bus->dev && ACPI_HANDLE(bus->dev))
> >+		ret = sdw_acpi_find_slaves(bus);
> >+	else if (IS_ENABLED(CONFIG_OF) && bus->dev && bus->dev->of_node)
> >+		ret = sdw_of_find_slaves(bus);
> >+	else
> bus->dev is already checked in the start of the function, do we need to
> check once again ?

yes already fixed, thanks

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-11-10  4:59       ` Vinod Koul
  (?)
@ 2017-11-10  8:55       ` Vinod Koul
  2017-11-10 10:50         ` Srinivas Kandagatla
  -1 siblings, 1 reply; 139+ messages in thread
From: Vinod Koul @ 2017-11-10  8:55 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi

On Fri, Nov 10, 2017 at 10:29:51AM +0530, Vinod Koul wrote:
> On Thu, Nov 09, 2017 at 09:14:07PM +0000, Srinivas Kandagatla wrote:
> > 
> > 
> > On 19/10/17 04:03, Vinod Koul wrote:
> > >This adds the base SoundWire bus type, bus and driver registration.
> > >along with changes to module device table for new SoundWire
> > >device type.
> > >
> > >Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> > >Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> > >---
> > 
> > >+++ b/drivers/soundwire/Kconfig
> > >@@ -0,0 +1,22 @@
> > >+#
> > >+# SoundWire subsystem configuration
> > >+#
> > >+
> > >+menuconfig SOUNDWIRE
> > >+	bool "SoundWire support"
> > 
> > Any reason why this subsystem can not be build as module?
> 
> This is not subsystem symbol but the menu. The SOUNDWIRE_BUS can be module.
> 
> > 
> > >+	---help---
> > >+	  SoundWire is a 2-Pin interface with data and clock line ratified
> > >+	  by the MIPI Alliance. SoundWire is used for transporting data
> > >+	  typically related to audio functions. SoundWire interface is
> > 
> > >+#ifndef __SDW_BUS_H
> > >+#define __SDW_BUS_H
> > >+
> > >+#include <linux/init.h>
> > >+#include <linux/device.h>
> > >+#include <linux/module.h>
> > >+#include <linux/mod_devicetable.h>
> > >+#include <linux/acpi.h>
> > Do you need these headers here?
> 
> Yes :) I will double check though
> 
> 
> > 
> > >+#include <linux/soundwire/sdw.h>
> > >+
> > >+int sdw_slave_modalias(struct sdw_slave *slave, char *buf, size_t size);
> > >+
> > >+#endif /* __SDW_BUS_H */
> > >diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
> > >new file mode 100644
> > >index 000000000000..a14d1de80afa
> > >--- /dev/null
> > >+++ b/drivers/soundwire/bus_type.c
> > >
> > >+#include <linux/acpi.h>
> > >+#include <linux/device.h>
> > >+#include <linux/init.h>
> > >+#include <linux/module.h>
> > >+#include <linux/mod_devicetable.h>
> > >+#include <linux/pm_domain.h>
> > >+#include <linux/pm_runtime.h>
> > >+#include <linux/soundwire/sdw.h>
> > >+#include "bus.h"
> > >+
> > >+/**
> > >+ * sdw_get_device_id: find the matching SoundWire device id
> > >+ *
> > function name should end with () - according to kernel doc.
> 
> ah thanks for pointing will add

I ran the kernel-doc script, seems to not complain about this.

Looking at it closely scripts/kernel-doc parenthesis is not expected

-- 
~Vinod

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-11-10  4:59       ` Vinod Koul
@ 2017-11-10 10:42         ` Srinivas Kandagatla
  -1 siblings, 0 replies; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-10 10:42 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi



On 10/11/17 04:59, Vinod Koul wrote:
> On Thu, Nov 09, 2017 at 09:14:07PM +0000, Srinivas Kandagatla wrote:
>>
>>
>> On 19/10/17 04:03, Vinod Koul wrote:
>>> This adds the base SoundWire bus type, bus and driver registration.
>>> along with changes to module device table for new SoundWire
>>> device type.
>>>
>>> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
>>> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
>>> ---
>>
>>> +++ b/drivers/soundwire/Kconfig
>>> @@ -0,0 +1,22 @@
>>> +#
>>> +# SoundWire subsystem configuration
>>> +#
>>> +
>>> +menuconfig SOUNDWIRE
>>> +	bool "SoundWire support"
>>
>> Any reason why this subsystem can not be build as module?
> 
> This is not subsystem symbol but the menu. The SOUNDWIRE_BUS can be module.
I Noticed that.

Are you able to be build SOUNDWIRE_BUS as moudles?

I think the issue is that SOUNDWIRE_BUS default is set to SOUNDWIRE
This would never allow SOUNDWIRE_BUS to set as module if SOUNDWIRE is bool.

May be that is the issue.

config SOUNDWIRE_BUS
         tristate
         default SOUNDWIRE
         select REGMAP_SOUNDWIRE

> 
>>> +/**
>>> + * sdw_get_device_id: find the matching SoundWire device id
>>> + *
>> function name should end with () - according to kernel doc.
> 
> ah thanks for pointing will add
> 
>>
>>> + * @slave: SoundWire Slave device
>>> + * @drv: SoundWire Slave Driver
>>> + *
>>> + * The match is done by comparing the mfg_id and part_id from the
>>> + * struct sdw_device_id. class_id is unused, as it is a placeholder
>>> + * in MIPI Spec.
>>> + */
>>
>> BTW, This is a static private function, why are we adding kernel doc for
>> this?
> 
> the match is an important routine and helps people understand the logic
> hence documentation. More doc is better right :)
> 
I agree, more doc is better.

>>> +struct bus_type sdw_bus_type = {
>>> +	.name = "soundwire",
>>> +	.match = sdw_bus_match,
>>> +	.uevent = sdw_uevent,
>>> +};
>>> +EXPORT_SYMBOL(sdw_bus_type);
>>> +
>>> +static int sdw_drv_probe(struct device *dev)
>>> +{
>>> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
>>> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
>>> +	const struct sdw_device_id *id;
>>> +	int ret;
>>> +
>>> +	id = sdw_get_device_id(slave, drv);
>>
>> By this time we must have already matched dev and driver by the ID,
>> shouldn't it be just slave->id  here?
> 
> I don't think so we do not have slave->id, we pass the id in probe as an
> argument
> 
Which probe function are you referening too ?

Not sure I get it, Only way to get to this probe is that id_table from 
driver matches slave id which is done as part of sdw_bus_match().
So the id should be valid and calling sdw_get_device_id() is redundant here?

>>> +	if (!id)
>>> +		return -ENODEV;
>>> +
>>> +	/*
>>> +	 * attach to power domain but don't turn on (last arg)
>>> +	 */
>>> +	ret = dev_pm_domain_attach(dev, false);
>>> +	if (ret) {
>> Shouldn't it just handle the EPROBE_DEFER case and ignore it for other
>> errors.
> 
> why should we ignore other errors and continue?
> 

If you are making power domain as mandatory for all the devices, then it 
makes sense to err out. But not all the devices might have pm domains 
associated, so continuing on other errors makes sense.. All of the bus 
drivers in the kernel do that ex: ./drivers/base/platform.c,
./drivers/mmc/core/sdio_bus.c, ./drivers/spi/spi.c...


>>
>>
>>> +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	ret = drv->probe(slave, id);
>>> +	if (ret) {
>>> +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
>>> +		return ret;
>>> +	}
>>
>>
>> What happens if the slave driver is built as module and loaded after the
>> slave device is attached to the bus. How does the slave driver get updated
>> status in this case?
>>
>> We have similar usecase in slimbus too.
> 
> So we create devices based on firmware description, then the Slave may
> report as present and we mark it as present. Once a driver is loaded, the
> driver is probed here, the slave->status clearly tells the driver that slave
> has already reported present.

Yep, that solution makes sense, Looks like I can do the same for slimbus 
too.


> 

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
@ 2017-11-10 10:42         ` Srinivas Kandagatla
  0 siblings, 0 replies; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-10 10:42 UTC (permalink / raw)
  To: Vinod Koul
  Cc: ALSA, Charles Keepax, Takashi, Greg Kroah-Hartman, plai, LKML,
	Pierre, patches.audio, Mark, Sudheer Papothi, Shreyas NC,
	Sanyog Kale, Sagar Dharia, alan



On 10/11/17 04:59, Vinod Koul wrote:
> On Thu, Nov 09, 2017 at 09:14:07PM +0000, Srinivas Kandagatla wrote:
>>
>>
>> On 19/10/17 04:03, Vinod Koul wrote:
>>> This adds the base SoundWire bus type, bus and driver registration.
>>> along with changes to module device table for new SoundWire
>>> device type.
>>>
>>> Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
>>> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
>>> ---
>>
>>> +++ b/drivers/soundwire/Kconfig
>>> @@ -0,0 +1,22 @@
>>> +#
>>> +# SoundWire subsystem configuration
>>> +#
>>> +
>>> +menuconfig SOUNDWIRE
>>> +	bool "SoundWire support"
>>
>> Any reason why this subsystem can not be build as module?
> 
> This is not subsystem symbol but the menu. The SOUNDWIRE_BUS can be module.
I Noticed that.

Are you able to be build SOUNDWIRE_BUS as moudles?

I think the issue is that SOUNDWIRE_BUS default is set to SOUNDWIRE
This would never allow SOUNDWIRE_BUS to set as module if SOUNDWIRE is bool.

May be that is the issue.

config SOUNDWIRE_BUS
         tristate
         default SOUNDWIRE
         select REGMAP_SOUNDWIRE

> 
>>> +/**
>>> + * sdw_get_device_id: find the matching SoundWire device id
>>> + *
>> function name should end with () - according to kernel doc.
> 
> ah thanks for pointing will add
> 
>>
>>> + * @slave: SoundWire Slave device
>>> + * @drv: SoundWire Slave Driver
>>> + *
>>> + * The match is done by comparing the mfg_id and part_id from the
>>> + * struct sdw_device_id. class_id is unused, as it is a placeholder
>>> + * in MIPI Spec.
>>> + */
>>
>> BTW, This is a static private function, why are we adding kernel doc for
>> this?
> 
> the match is an important routine and helps people understand the logic
> hence documentation. More doc is better right :)
> 
I agree, more doc is better.

>>> +struct bus_type sdw_bus_type = {
>>> +	.name = "soundwire",
>>> +	.match = sdw_bus_match,
>>> +	.uevent = sdw_uevent,
>>> +};
>>> +EXPORT_SYMBOL(sdw_bus_type);
>>> +
>>> +static int sdw_drv_probe(struct device *dev)
>>> +{
>>> +	struct sdw_slave *slave = dev_to_sdw_dev(dev);
>>> +	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
>>> +	const struct sdw_device_id *id;
>>> +	int ret;
>>> +
>>> +	id = sdw_get_device_id(slave, drv);
>>
>> By this time we must have already matched dev and driver by the ID,
>> shouldn't it be just slave->id  here?
> 
> I don't think so we do not have slave->id, we pass the id in probe as an
> argument
> 
Which probe function are you referening too ?

Not sure I get it, Only way to get to this probe is that id_table from 
driver matches slave id which is done as part of sdw_bus_match().
So the id should be valid and calling sdw_get_device_id() is redundant here?

>>> +	if (!id)
>>> +		return -ENODEV;
>>> +
>>> +	/*
>>> +	 * attach to power domain but don't turn on (last arg)
>>> +	 */
>>> +	ret = dev_pm_domain_attach(dev, false);
>>> +	if (ret) {
>> Shouldn't it just handle the EPROBE_DEFER case and ignore it for other
>> errors.
> 
> why should we ignore other errors and continue?
> 

If you are making power domain as mandatory for all the devices, then it 
makes sense to err out. But not all the devices might have pm domains 
associated, so continuing on other errors makes sense.. All of the bus 
drivers in the kernel do that ex: ./drivers/base/platform.c,
./drivers/mmc/core/sdio_bus.c, ./drivers/spi/spi.c...


>>
>>
>>> +		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	ret = drv->probe(slave, id);
>>> +	if (ret) {
>>> +		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
>>> +		return ret;
>>> +	}
>>
>>
>> What happens if the slave driver is built as module and loaded after the
>> slave device is attached to the bus. How does the slave driver get updated
>> status in this case?
>>
>> We have similar usecase in slimbus too.
> 
> So we create devices based on firmware description, then the Slave may
> report as present and we mark it as present. Once a driver is loaded, the
> driver is probed here, the slave->status clearly tells the driver that slave
> has already reported present.

Yep, that solution makes sense, Looks like I can do the same for slimbus 
too.


> 

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-11-10  8:55       ` Vinod Koul
@ 2017-11-10 10:50         ` Srinivas Kandagatla
  0 siblings, 0 replies; 139+ messages in thread
From: Srinivas Kandagatla @ 2017-11-10 10:50 UTC (permalink / raw)
  To: Vinod Koul
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi



On 10/11/17 08:55, Vinod Koul wrote:
>>>> +
>>>> +/**
>>>> + * sdw_get_device_id: find the matching SoundWire device id
>>>> + *
>>> function name should end with () - according to kernel doc.
>> ah thanks for pointing will add
> I ran the kernel-doc script, seems to not complain about this.
> 
> Looking at it closely scripts/kernel-doc parenthesis is not expected

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/doc-guide/kernel-doc.rst?h=v4.14-rc8#n204

Examples in the doc does suggest that we need (). Am not 100% sure if : 
is also a valid with functions.

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

* Re: [PATCH 02/14] soundwire: Add SoundWire bus type
  2017-11-10 10:42         ` Srinivas Kandagatla
  (?)
@ 2017-11-10 10:58         ` Vinod Koul
  -1 siblings, 0 replies; 139+ messages in thread
From: Vinod Koul @ 2017-11-10 10:58 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Greg Kroah-Hartman, LKML, ALSA, Mark, Takashi, Pierre,
	Sanyog Kale, Shreyas NC, patches.audio, alan, Charles Keepax,
	Sagar Dharia, plai, Sudheer Papothi

On Fri, Nov 10, 2017 at 10:42:06AM +0000, Srinivas Kandagatla wrote:
> 
> 
> On 10/11/17 04:59, Vinod Koul wrote:
> >On Thu, Nov 09, 2017 at 09:14:07PM +0000, Srinivas Kandagatla wrote:
> >>
> >>
> >>On 19/10/17 04:03, Vinod Koul wrote:
> >>>This adds the base SoundWire bus type, bus and driver registration.
> >>>along with changes to module device table for new SoundWire
> >>>device type.
> >>>
> >>>Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
> >>>Signed-off-by: Vinod Koul <vinod.koul@intel.com>
> >>>---
> >>
> >>>+++ b/drivers/soundwire/Kconfig
> >>>@@ -0,0 +1,22 @@
> >>>+#
> >>>+# SoundWire subsystem configuration
> >>>+#
> >>>+
> >>>+menuconfig SOUNDWIRE
> >>>+	bool "SoundWire support"
> >>
> >>Any reason why this subsystem can not be build as module?
> >
> >This is not subsystem symbol but the menu. The SOUNDWIRE_BUS can be module.
> I Noticed that.
> 
> Are you able to be build SOUNDWIRE_BUS as moudles?
> 
> I think the issue is that SOUNDWIRE_BUS default is set to SOUNDWIRE
> This would never allow SOUNDWIRE_BUS to set as module if SOUNDWIRE is bool.
> 
> May be that is the issue.
> 
> config SOUNDWIRE_BUS
>         tristate
>         default SOUNDWIRE

removing this makes it build as module, sorry I assumed you have already
seen Takashi's comment. I have fixed it in v2. Posting anytime now :)

> >
> >>
> >>>+ * @slave: SoundWire Slave device
> >>>+ * @drv: SoundWire Slave Driver
> >>>+ *
> >>>+ * The match is done by comparing the mfg_id and part_id from the
> >>>+ * struct sdw_device_id. class_id is unused, as it is a placeholder
> >>>+ * in MIPI Spec.
> >>>+ */
> >>
> >>BTW, This is a static private function, why are we adding kernel doc for
> >>this?
> >
> >the match is an important routine and helps people understand the logic
> >hence documentation. More doc is better right :)
> >
> I agree, more doc is better.
> 
> >>>+struct bus_type sdw_bus_type = {
> >>>+	.name = "soundwire",
> >>>+	.match = sdw_bus_match,
> >>>+	.uevent = sdw_uevent,
> >>>+};
> >>>+EXPORT_SYMBOL(sdw_bus_type);
> >>>+
> >>>+static int sdw_drv_probe(struct device *dev)
> >>>+{
> >>>+	struct sdw_slave *slave = dev_to_sdw_dev(dev);
> >>>+	struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
> >>>+	const struct sdw_device_id *id;
> >>>+	int ret;
> >>>+
> >>>+	id = sdw_get_device_id(slave, drv);
> >>
> >>By this time we must have already matched dev and driver by the ID,
> >>shouldn't it be just slave->id  here?
> >
> >I don't think so we do not have slave->id, we pass the id in probe as an
> >argument
> >
> Which probe function are you referening too ?
> 
> Not sure I get it, Only way to get to this probe is that id_table from
> driver matches slave id which is done as part of sdw_bus_match().
> So the id should be valid and calling sdw_get_device_id() is redundant here?

we dont store in id so we have to lookup again. I see the point
in doing so, let me check that

> >>>+	if (!id)
> >>>+		return -ENODEV;
> >>>+
> >>>+	/*
> >>>+	 * attach to power domain but don't turn on (last arg)
> >>>+	 */
> >>>+	ret = dev_pm_domain_attach(dev, false);
> >>>+	if (ret) {
> >>Shouldn't it just handle the EPROBE_DEFER case and ignore it for other
> >>errors.
> >
> >why should we ignore other errors and continue?
> >
> 
> If you are making power domain as mandatory for all the devices, then it
> makes sense to err out. But not all the devices might have pm domains
> associated, so continuing on other errors makes sense.. All of the bus
> drivers in the kernel do that ex: ./drivers/base/platform.c,
> ./drivers/mmc/core/sdio_bus.c, ./drivers/spi/spi.c...

Ah thanks for pointing, let me check that

> >>>+		dev_err(dev, "Failed to attach PM domain: %d\n", ret);
> >>>+		return ret;
> >>>+	}
> >>>+
> >>>+	ret = drv->probe(slave, id);
> >>>+	if (ret) {
> >>>+		dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret);
> >>>+		return ret;
> >>>+	}
> >>
> >>
> >>What happens if the slave driver is built as module and loaded after the
> >>slave device is attached to the bus. How does the slave driver get updated
> >>status in this case?
> >>
> >>We have similar usecase in slimbus too.
> >
> >So we create devices based on firmware description, then the Slave may
> >report as present and we mark it as present. Once a driver is loaded, the
> >driver is probed here, the slave->status clearly tells the driver that slave
> >has already reported present.
> 
> Yep, that solution makes sense, Looks like I can do the same for slimbus
> too.

yup!

-- 
~Vinod

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

end of thread, other threads:[~2017-11-10 10:55 UTC | newest]

Thread overview: 139+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-19  3:03 [PATCH 00/14] soundwire: Add a new SoundWire subsystem Vinod Koul
2017-10-19  3:03 ` Vinod Koul
2017-10-19  3:03 ` [PATCH 01/14] Documentation: Add SoundWire summary Vinod Koul
2017-10-19  3:33   ` Randy Dunlap
2017-10-19  3:33     ` Randy Dunlap
2017-10-19  4:44     ` Vinod Koul
2017-10-19  4:44       ` Vinod Koul
2017-10-20 10:39   ` Greg Kroah-Hartman
2017-10-20 10:39     ` Greg Kroah-Hartman
2017-10-20 15:49     ` Vinod Koul
2017-10-20 15:49       ` Vinod Koul
2017-10-20 16:22       ` Greg Kroah-Hartman
2017-10-20 16:22         ` Greg Kroah-Hartman
2017-10-20 17:09         ` Vinod Koul
2017-10-20 17:09           ` Vinod Koul
2017-10-21  8:57   ` Mark Brown
2017-10-21  8:57     ` Mark Brown
2017-10-21 11:28     ` Vinod Koul
2017-10-21 11:28       ` Vinod Koul
2017-10-22 10:06       ` [alsa-devel] " Pierre-Louis Bossart
2017-10-23  8:21         ` Mark Brown
2017-10-23  7:50       ` Mark Brown
2017-10-23  7:50         ` Mark Brown
2017-10-23 11:18         ` [alsa-devel] " Vinod Koul
2017-10-19  3:03 ` [PATCH 02/14] soundwire: Add SoundWire bus type Vinod Koul
2017-10-19  7:40   ` Takashi Iwai
2017-10-19  8:32     ` [alsa-devel] " Takashi Iwai
2017-10-19  8:32       ` Takashi Iwai
2017-10-20  5:11     ` Vinod Koul
2017-10-20  5:11       ` Vinod Koul
2017-10-20  6:59       ` Takashi Iwai
2017-10-20 15:46         ` Vinod Koul
2017-10-20 15:50           ` Takashi Iwai
2017-10-20 15:50             ` Takashi Iwai
2017-10-20 16:11             ` Vinod Koul
2017-10-20 10:41   ` Greg Kroah-Hartman
2017-10-20 10:41     ` Greg Kroah-Hartman
2017-10-20 15:52     ` Vinod Koul
2017-10-20 10:45   ` Greg Kroah-Hartman
2017-10-20 16:01     ` Vinod Koul
2017-10-20 16:21       ` Greg Kroah-Hartman
2017-10-20 16:21         ` Greg Kroah-Hartman
2017-10-20 17:10         ` Vinod Koul
2017-10-23 11:46         ` Alan Cox
2017-10-23 11:46           ` Alan Cox
2017-10-26  8:33       ` Vinod Koul
2017-10-26  8:33         ` Vinod Koul
2017-10-27  8:57         ` Greg Kroah-Hartman
2017-10-30 13:11           ` Vinod Koul
2017-10-20 16:03     ` Philippe Ombredanne
2017-10-20 16:20       ` Vinod Koul
2017-10-20 16:20         ` Vinod Koul
2017-10-20 16:27         ` Greg Kroah-Hartman
2017-10-20 17:13           ` Vinod Koul
2017-10-20 17:13             ` Vinod Koul
2017-10-23 11:52           ` Alan Cox
2017-10-23 11:52             ` Alan Cox
2017-10-21  9:03   ` Mark Brown
2017-10-21 11:29     ` Vinod Koul
2017-10-21 11:29       ` Vinod Koul
2017-11-09 21:14   ` Srinivas Kandagatla
2017-11-09 21:14     ` Srinivas Kandagatla
2017-11-10  4:59     ` Vinod Koul
2017-11-10  4:59       ` Vinod Koul
2017-11-10  8:55       ` Vinod Koul
2017-11-10 10:50         ` Srinivas Kandagatla
2017-11-10 10:42       ` Srinivas Kandagatla
2017-11-10 10:42         ` Srinivas Kandagatla
2017-11-10 10:58         ` Vinod Koul
2017-10-19  3:03 ` [PATCH 03/14] soundwire: Add Master registration Vinod Koul
2017-10-19  3:03   ` Vinod Koul
2017-10-19  8:54   ` [alsa-devel] " Takashi Iwai
2017-10-19  8:54     ` Takashi Iwai
2017-10-20  5:19     ` [alsa-devel] " Vinod Koul
2017-10-20  5:19       ` Vinod Koul
2017-10-20 10:47   ` Greg Kroah-Hartman
2017-10-20 16:05     ` Vinod Koul
2017-10-21  9:12   ` Mark Brown
2017-10-21  9:12     ` Mark Brown
2017-10-21 11:35     ` Vinod Koul
2017-10-21 11:35       ` Vinod Koul
2017-10-23  8:24       ` Mark Brown
2017-10-23  8:24         ` Mark Brown
2017-10-23 11:19         ` Vinod Koul
2017-11-09 21:14   ` Srinivas Kandagatla
2017-11-10  5:02     ` Vinod Koul
2017-11-10  5:02       ` Vinod Koul
2017-10-19  3:03 ` [PATCH 04/14] soundwire: Add MIPI DisCo property helpers Vinod Koul
2017-10-19  9:02   ` [alsa-devel] " Takashi Iwai
2017-10-20  5:25     ` Vinod Koul
2017-10-21  9:20   ` Mark Brown
2017-10-21  9:20     ` Mark Brown
2017-10-21 11:37     ` Vinod Koul
2017-10-22 10:14       ` [alsa-devel] " Pierre-Louis Bossart
2017-10-22 10:14         ` Pierre-Louis Bossart
2017-10-19  3:03 ` [PATCH 05/14] soundwire: Add SoundWire MIPI defined registers Vinod Koul
2017-10-19  3:03 ` [PATCH 06/14] soundwire: Add IO transfer Vinod Koul
2017-10-19  3:03   ` Vinod Koul
2017-10-19  9:13   ` [alsa-devel] " Takashi Iwai
2017-10-20  5:30     ` Vinod Koul
2017-10-20  5:30       ` Vinod Koul
2017-10-20  7:06       ` [alsa-devel] " Takashi Iwai
2017-10-20  7:06         ` Takashi Iwai
2017-10-20 15:48         ` [alsa-devel] " Vinod Koul
2017-10-21  9:29   ` Mark Brown
2017-10-21  9:29     ` Mark Brown
2017-10-21 11:40     ` Vinod Koul
2017-10-19  3:03 ` [PATCH 07/14] regmap: Add SoundWire bus support Vinod Koul
2017-10-21  9:34   ` Mark Brown
2017-10-21  9:34     ` Mark Brown
2017-10-21 11:44     ` Vinod Koul
2017-10-23 11:56     ` Alan Cox
2017-10-23 13:16       ` Mark Brown
2017-10-19  3:03 ` [PATCH 08/14] soundwire: Add Slave status handling helpers Vinod Koul
2017-10-19 13:44   ` [alsa-devel] " Takashi Iwai
2017-10-31 13:04     ` Vinod Koul
2017-10-31 13:04       ` Vinod Koul
2017-10-31 21:19       ` [alsa-devel] " Pierre-Louis Bossart
2017-10-31 21:19         ` Pierre-Louis Bossart
2017-11-01  9:08         ` [alsa-devel] " Vinod Koul
2017-11-01  9:08           ` Vinod Koul
2017-11-01 21:10           ` [alsa-devel] " Pierre-Louis Bossart
2017-11-02  3:28             ` Vinod Koul
2017-10-19  3:03 ` [PATCH 09/14] soundwire: Add slave status handling Vinod Koul
2017-10-19  3:03 ` [PATCH 10/14] soundwire: Add sysfs for SoundWire DisCo properties Vinod Koul
2017-10-21  9:42   ` Mark Brown
2017-10-21  9:42     ` Mark Brown
2017-10-21 11:53     ` Vinod Koul
2017-10-21 11:53       ` Vinod Koul
2017-11-09 21:14   ` Srinivas Kandagatla
2017-11-10  4:52     ` Vinod Koul
2017-10-19  3:03 ` [PATCH 11/14] soundwire: cdns: Add cadence module Vinod Koul
2017-10-21  9:52   ` Mark Brown
2017-10-21  9:52     ` Mark Brown
2017-10-21 11:54     ` Vinod Koul
2017-10-21 11:54       ` Vinod Koul
2017-10-19  3:03 ` [PATCH 12/14] soundwire: cdns: Add sdw_master_ops and IO transfer support Vinod Koul
2017-10-19  3:03 ` [PATCH 13/14] soundwire: intel: Add Intel Master driver Vinod Koul
2017-10-19  3:03 ` [PATCH 14/14] soundwire: intel: Add Intel init module Vinod Koul

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.