Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) // Copyright(c) 2019-2020 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/soundwire/sdw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/soundwire/sdw_type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "bus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * The 3s value for autosuspend will only be used if there are no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * devices physically attached on a bus segment. In practice enabling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * the bus operation will result in children devices become active and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * the master device will only suspend when all its children are no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * longer active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define SDW_MASTER_SUSPEND_DELAY_MS 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * The sysfs for properties reflects the MIPI description as given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * in the MIPI DisCo spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * Base file is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *	sdw-master-N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *      |---- revision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *      |---- clk_stop_modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *      |---- max_clk_freq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *      |---- clk_freq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *      |---- clk_gears
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *      |---- default_row
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *      |---- default_col
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *      |---- dynamic_shape
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *      |---- err_threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define sdw_master_attr(field, format_string)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static ssize_t field##_show(struct device *dev,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			    struct device_attribute *attr,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			    char *buf)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct sdw_master_device *md = dev_to_sdw_master_device(dev);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return sprintf(buf, format_string, md->bus->prop.field);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static DEVICE_ATTR_RO(field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) sdw_master_attr(revision, "0x%x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) sdw_master_attr(clk_stop_modes, "0x%x\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) sdw_master_attr(max_clk_freq, "%d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) sdw_master_attr(default_row, "%d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) sdw_master_attr(default_col, "%d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) sdw_master_attr(default_frame_rate, "%d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) sdw_master_attr(dynamic_frame, "%d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) sdw_master_attr(err_threshold, "%d\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static ssize_t clock_frequencies_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 				      struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	struct sdw_master_device *md = dev_to_sdw_master_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	ssize_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	for (i = 0; i < md->bus->prop.num_clk_freq; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		size += sprintf(buf + size, "%8d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 				md->bus->prop.clk_freq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	size += sprintf(buf + size, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static DEVICE_ATTR_RO(clock_frequencies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static ssize_t clock_gears_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct sdw_master_device *md = dev_to_sdw_master_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	ssize_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	for (i = 0; i < md->bus->prop.num_clk_gears; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		size += sprintf(buf + size, "%8d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				md->bus->prop.clk_gears[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	size += sprintf(buf + size, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static DEVICE_ATTR_RO(clock_gears);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static struct attribute *master_node_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	&dev_attr_revision.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	&dev_attr_clk_stop_modes.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	&dev_attr_max_clk_freq.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	&dev_attr_default_row.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	&dev_attr_default_col.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	&dev_attr_default_frame_rate.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	&dev_attr_dynamic_frame.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	&dev_attr_err_threshold.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	&dev_attr_clock_frequencies.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	&dev_attr_clock_gears.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ATTRIBUTE_GROUPS(master_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void sdw_master_device_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	struct sdw_master_device *md = dev_to_sdw_master_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	kfree(md);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static const struct dev_pm_ops master_dev_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			   pm_generic_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct device_type sdw_master_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	.name =		"soundwire_master",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	.release =	sdw_master_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	.pm = &master_dev_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * sdw_master_device_add() - create a Linux Master Device representation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * @bus: SDW bus instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * @parent: parent device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @fwnode: firmware node handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int sdw_master_device_add(struct sdw_bus *bus, struct device *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			  struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct sdw_master_device *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	md = kzalloc(sizeof(*md), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (!md)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	md->dev.bus = &sdw_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	md->dev.type = &sdw_master_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	md->dev.parent = parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	md->dev.groups = master_node_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	md->dev.of_node = parent->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	md->dev.fwnode = fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	md->dev.dma_mask = parent->dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	dev_set_name(&md->dev, "sdw-master-%d", bus->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	ret = device_register(&md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		dev_err(parent, "Failed to add master: ret %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		 * On err, don't free but drop ref as this will be freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		 * when release method is invoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		put_device(&md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		goto device_register_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	/* add shortcuts to improve code readability/compactness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	md->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	bus->dev = &md->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	bus->md = md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	pm_runtime_set_autosuspend_delay(&bus->md->dev, SDW_MASTER_SUSPEND_DELAY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	pm_runtime_use_autosuspend(&bus->md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	pm_runtime_mark_last_busy(&bus->md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	pm_runtime_set_active(&bus->md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	pm_runtime_enable(&bus->md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	pm_runtime_idle(&bus->md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) device_register_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * sdw_master_device_del() - delete a Linux Master Device representation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  * @bus: bus handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * This function is the dual of sdw_master_device_add()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int sdw_master_device_del(struct sdw_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	pm_runtime_disable(&bus->md->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	device_unregister(bus->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }