History

soundwire: bus_type: add sdw_master_device support

In the existing SoundWire code, Master Devices are not explicitly represented - only SoundWire Slave Devices are exposed (the use of capital letters follows the SoundWire specification conventions). With the existing code, the bus is handled without using a proper device, and bus->dev typically points to a platform device. The right thing to do as discussed in multiple reviews is use a device for each bus. The sdw_master_device addition is done with minimal internal plumbing and not exposed externally. The existing API based on sdw_bus_master_add() and sdw_bus_master_delete() will deal with the sdw_master_device life cycle, which minimizes changes to existing drivers. Note that the Intel code will be modified in follow-up patches (no impact on any platform since the connection with ASoC is not supported upstream so far).

Pierre-Louis Bossart committed 6 years ago

Commit 7ceaa401 parent dbb50c77 files · +112 −7Browse files

Unified · Split

7 files
  1. drivers/soundwire/Makefile +1 −1
  2. drivers/soundwire/bus.c +11 −3
  3. drivers/soundwire/bus.h +3 −0
  4. drivers/soundwire/intel.c +0 −1
  5. drivers/soundwire/master.c +81 −0
  6. drivers/soundwire/qcom.c +0 −1
  7. include/linux/soundwire/sdw.h +16 −1
drivers/soundwire/Makefile+1−1
@@ -4,7 +4,7 @@ · 3 unmodified lines
44 #
55
66 #Bus Objs
7−soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o
7+soundwire-bus-objs := bus_type.o bus.o master.o slave.o mipi_disco.o stream.o
88 obj-$(CONFIG_SOUNDWIRE) += soundwire-bus.o
99
1010 ifdef CONFIG_DEBUG_FS
drivers/soundwire/bus.c+11−3
@@ -37,14 +37,21 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent, · 36 unmodified lines
3737 struct sdw_master_prop *prop = NULL;
3838 int ret;
3939
40− if (!bus->dev) {
41− pr_err("SoundWire bus has no device\n");
40+ if (!parent) {
41+ pr_err("SoundWire parent device is not set\n");
4242 return -ENODEV;
4343 }
4444
4545 ret = sdw_get_id(bus);
4646 if (ret) {
47− dev_err(bus->dev, "Failed to get bus id\n");
47+ dev_err(parent, "Failed to get bus id\n");
48+ return ret;
49+ }
50+
51+ ret = sdw_master_device_add(bus, parent, fwnode);
52+ if (ret) {
53+ dev_err(parent, "Failed to add master device at link %d\n",
54+ bus->link_id);
4855 return ret;
4956 }
5057
@@ -161,6 +168,7 @@ static int sdw_delete_slave(struct device *dev, void *data) · 110 unmodified lines
161168 void sdw_bus_master_delete(struct sdw_bus *bus)
162169 {
163170 device_for_each_child(bus->dev, NULL, sdw_delete_slave);
171+ sdw_master_device_del(bus);
164172
165173 sdw_bus_debugfs_exit(bus);
166174 ida_free(&sdw_ida, bus->id);
drivers/soundwire/bus.h+3−0
@@ -19,6 +19,9 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus) · 18 unmodified lines
1919 int sdw_of_find_slaves(struct sdw_bus *bus);
2020 void sdw_extract_slave_id(struct sdw_bus *bus,
2121 u64 addr, struct sdw_slave_id *id);
22+int sdw_master_device_add(struct sdw_bus *bus, struct device *parent,
23+ struct fwnode_handle *fwnode);
24+int sdw_master_device_del(struct sdw_bus *bus);
2225
2326 #ifdef CONFIG_DEBUG_FS
2427 void sdw_bus_debugfs_init(struct sdw_bus *bus);
drivers/soundwire/intel.c+0−1
@@ -1099,7 +1099,6 @@ static int intel_probe(struct platform_device *pdev) · 1098 unmodified lines
10991099 sdw->cdns.registers = sdw->link_res->registers;
11001100 sdw->cdns.instance = sdw->instance;
11011101 sdw->cdns.msg_count = 0;
1102− sdw->cdns.bus.dev = &pdev->dev;
11031102 sdw->cdns.bus.link_id = pdev->id;
11041103
11051104 sdw_cdns_probe(&sdw->cdns);
drivers/soundwire/master.c+81−0
@@ -0,0 +1,81 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+// Copyright(c) 2019-2020 Intel Corporation.
3+
4+#include <linux/device.h>
5+#include <linux/acpi.h>
6+#include <linux/soundwire/sdw.h>
7+#include <linux/soundwire/sdw_type.h>
8+#include "bus.h"
9+
10+static void sdw_master_device_release(struct device *dev)
11+{
12+ struct sdw_master_device *md = dev_to_sdw_master_device(dev);
13+
14+ kfree(md);
15+}
16+
17+struct device_type sdw_master_type = {
18+ .name = "soundwire_master",
19+ .release = sdw_master_device_release,
20+};
21+
22+/**
23+ * sdw_master_device_add() - create a Linux Master Device representation.
24+ * @bus: SDW bus instance
25+ * @parent: parent device
26+ * @fwnode: firmware node handle
27+ */
28+int sdw_master_device_add(struct sdw_bus *bus, struct device *parent,
29+ struct fwnode_handle *fwnode)
30+{
31+ struct sdw_master_device *md;
32+ int ret;
33+
34+ if (!parent)
35+ return -EINVAL;
36+
37+ md = kzalloc(sizeof(*md), GFP_KERNEL);
38+ if (!md)
39+ return -ENOMEM;
40+
41+ md->dev.bus = &sdw_bus_type;
42+ md->dev.type = &sdw_master_type;
43+ md->dev.parent = parent;
44+ md->dev.of_node = parent->of_node;
45+ md->dev.fwnode = fwnode;
46+ md->dev.dma_mask = parent->dma_mask;
47+
48+ dev_set_name(&md->dev, "sdw-master-%d", bus->id);
49+
50+ ret = device_register(&md->dev);
51+ if (ret) {
52+ dev_err(parent, "Failed to add master: ret %d\n", ret);
53+ /*
54+ * On err, don't free but drop ref as this will be freed
55+ * when release method is invoked.
56+ */
57+ put_device(&md->dev);
58+ goto device_register_err;
59+ }
60+
61+ /* add shortcuts to improve code readability/compactness */
62+ md->bus = bus;
63+ bus->dev = &md->dev;
64+ bus->md = md;
65+
66+device_register_err:
67+ return ret;
68+}
69+
70+/**
71+ * sdw_master_device_del() - delete a Linux Master Device representation.
72+ * @bus: bus handle
73+ *
74+ * This function is the dual of sdw_master_device_add()
75+ */
76+int sdw_master_device_del(struct sdw_bus *bus)
77+{
78+ device_unregister(bus->dev);
79+
80+ return 0;
81+}
drivers/soundwire/qcom.c+0−1
@@ -784,7 +784,6 @@ static int qcom_swrm_probe(struct platform_device *pdev) · 783 unmodified lines
784784 mutex_init(&ctrl->port_lock);
785785 INIT_WORK(&ctrl->slave_work, qcom_swrm_slave_wq);
786786
787− ctrl->bus.dev = dev;
788787 ctrl->bus.ops = &qcom_swrm_ops;
789788 ctrl->bus.port_ops = &qcom_swrm_port_ops;
790789 ctrl->bus.compute_params = &qcom_swrm_compute_params;
include/linux/soundwire/sdw.h+16−1
@@ -632,6 +632,19 @@ struct sdw_slave { · 631 unmodified lines
632632
633633 #define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
634634
635+/**
636+ * struct sdw_master_device - SoundWire 'Master Device' representation
637+ * @dev: Linux device for this Master
638+ * @bus: Bus handle shortcut
639+ */
640+struct sdw_master_device {
641+ struct device dev;
642+ struct sdw_bus *bus;
643+};
644+
645+#define dev_to_sdw_master_device(d) \
646+ container_of(d, struct sdw_master_device, dev)
647+
635648 struct sdw_driver {
636649 const char *name;
637650
@@ -787,7 +800,8 @@ struct sdw_master_ops { · 149 unmodified lines
787800
788801 /**
789802 * struct sdw_bus - SoundWire bus
790− * @dev: Master linux device
803+ * @dev: Shortcut to &bus->md->dev to avoid changing the entire code.
804+ * @md: Master device
791805 * @link_id: Link id number, can be 0 to N, unique for each Master
792806 * @id: bus system-wide unique id
793807 * @slaves: list of Slaves on this bus
@@ -813,6 +827,7 @@ struct sdw_master_ops { · 19 unmodified lines
813827 */
814828 struct sdw_bus {
815829 struct device *dev;
830+ struct sdw_master_device *md;
816831 unsigned int link_id;
817832 int id;
818833 struct list_head slaves;