1commit 706027ba60649c8023582d805d5d789b7cffb7fe 2Author: zhaoxc0502 <zhaoxc0502@thundersoft.com> 3Date: Thu Jun 16 17:17:03 2022 +0800 4 5 linux_drivers_base 6 7 Change-Id: Id94037ba2fca19e9bb74bced3a69c41ce9723e91 8 9diff --git a/drivers/base/core.c b/drivers/base/core.c 10index 2bc4db5ff..8952f231f 100644 11--- a/drivers/base/core.c 12+++ b/drivers/base/core.c 13@@ -2055,6 +2055,34 @@ static ssize_t online_store(struct device *dev, struct device_attribute *attr, 14 } 15 static DEVICE_ATTR_RW(online); 16 17+static ssize_t suppliers_show(struct device *dev, struct device_attribute *attr, 18+ char *buf) 19+{ 20+ struct device_link *link; 21+ size_t count = 0; 22+ 23+ list_for_each_entry(link, &dev->links.suppliers, c_node) 24+ count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n", 25+ dev_name(link->supplier)); 26+ 27+ return count; 28+} 29+static DEVICE_ATTR_RO(suppliers); 30+ 31+static ssize_t consumers_show(struct device *dev, struct device_attribute *attr, 32+ char *buf) 33+{ 34+ struct device_link *link; 35+ size_t count = 0; 36+ 37+ list_for_each_entry(link, &dev->links.consumers, s_node) 38+ count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n", 39+ dev_name(link->consumer)); 40+ 41+ return count; 42+} 43+static DEVICE_ATTR_RO(consumers); 44+ 45 int device_add_groups(struct device *dev, const struct attribute_group **groups) 46 { 47 return sysfs_create_groups(&dev->kobj, groups); 48@@ -2226,14 +2254,26 @@ static int device_add_attrs(struct device *dev) 49 goto err_remove_dev_groups; 50 } 51 52+ error = device_create_file(dev, &dev_attr_suppliers); 53+ if (error) 54+ goto err_remove_dev_online; 55+ 56+ error = device_create_file(dev, &dev_attr_consumers); 57+ if (error) 58+ goto err_remove_dev_suppliers; 59+ 60 if (fw_devlink_flags && !fw_devlink_is_permissive()) { 61 error = device_create_file(dev, &dev_attr_waiting_for_supplier); 62 if (error) 63- goto err_remove_dev_online; 64+ goto err_remove_dev_consumers; 65 } 66 67 return 0; 68 69+ err_remove_dev_consumers: 70+ device_remove_file(dev, &dev_attr_consumers); 71+ err_remove_dev_suppliers: 72+ device_remove_file(dev, &dev_attr_suppliers); 73 err_remove_dev_online: 74 device_remove_file(dev, &dev_attr_online); 75 err_remove_dev_groups: 76@@ -2254,6 +2294,8 @@ static void device_remove_attrs(struct device *dev) 77 const struct device_type *type = dev->type; 78 79 device_remove_file(dev, &dev_attr_waiting_for_supplier); 80+ device_remove_file(dev, &dev_attr_consumers); 81+ device_remove_file(dev, &dev_attr_suppliers); 82 device_remove_file(dev, &dev_attr_online); 83 device_remove_groups(dev, dev->groups); 84 85@@ -4354,6 +4396,13 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) 86 } 87 EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); 88 89+void device_set_node(struct device *dev, struct fwnode_handle *fwnode) 90+{ 91+ dev->fwnode = fwnode; 92+ dev->of_node = to_of_node(fwnode); 93+} 94+EXPORT_SYMBOL_GPL(device_set_node); 95+ 96 int device_match_name(struct device *dev, const void *name) 97 { 98 return sysfs_streq(dev_name(dev), name); 99diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c 100index f41e4e499..81ee92fec 100644 101--- a/drivers/base/firmware_loader/main.c 102+++ b/drivers/base/firmware_loader/main.c 103@@ -464,11 +464,13 @@ static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv, 104 /* direct firmware loading support */ 105 static char fw_path_para[256]; 106 static const char * const fw_path[] = { 107- fw_path_para, 108- "/lib/firmware/updates/" UTS_RELEASE, 109- "/lib/firmware/updates", 110- "/lib/firmware/" UTS_RELEASE, 111- "/lib/firmware" 112+ fw_path_para, 113+ "/lib/firmware/updates/" UTS_RELEASE, 114+ "/lib/firmware/updates", 115+ "/lib/firmware/" UTS_RELEASE, 116+ "/lib/firmware", 117+ "/system/etc/imx_sdma/" UTS_RELEASE, 118+ "/system/etc/imx_sdma" 119 }; 120 121 /* 122diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c 123index 743268996..e91bbd75f 100644 124--- a/drivers/base/power/domain.c 125+++ b/drivers/base/power/domain.c 126@@ -475,6 +475,9 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed) 127 if (!genpd->power_off) 128 goto out; 129 130+ if (atomic_read(&genpd->sd_count) > 0) 131+ return -EBUSY; 132+ 133 if (!timed) { 134 ret = genpd->power_off(genpd); 135 if (ret) 136@@ -583,9 +586,9 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, 137 if (!genpd->gov) 138 genpd->state_idx = 0; 139 140- /* Don't power off, if a child domain is waiting to power on. */ 141- if (atomic_read(&genpd->sd_count) > 0) 142- return -EBUSY; 143+ /* Choose the deepest state if no devices using this domain */ 144+ if (!genpd->device_count) 145+ genpd->state_idx = genpd->state_count - 1; 146 147 ret = _genpd_power_off(genpd, true); 148 if (ret) { 149@@ -980,11 +983,20 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, 150 { 151 struct gpd_link *link; 152 153- if (!genpd_status_on(genpd) || genpd_is_always_on(genpd)) 154+ /* 155+ * Give the power domain a chance to switch to the deepest state in 156+ * case it's already off but in an intermediate low power state. 157+ */ 158+ genpd->state_idx_saved = genpd->state_idx; 159+ 160+ if (genpd_is_always_on(genpd)) 161+ return; 162+ 163+ if (!genpd_status_on(genpd) && 164+ genpd->state_idx == (genpd->state_count - 1)) 165 return; 166 167- if (genpd->suspended_count != genpd->device_count 168- || atomic_read(&genpd->sd_count) > 0) 169+ if (genpd->suspended_count != genpd->device_count) 170 return; 171 172 /* Choose the deepest state when suspending */ 173@@ -992,6 +1004,9 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, 174 if (_genpd_power_off(genpd, false)) 175 return; 176 177+ if (genpd->status == GENPD_STATE_OFF) 178+ return; 179+ 180 genpd->status = GENPD_STATE_OFF; 181 182 list_for_each_entry(link, &genpd->child_links, child_node) { 183@@ -1038,6 +1053,9 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, 184 } 185 186 _genpd_power_on(genpd, false); 187+ /* restore save power domain state after resume */ 188+ genpd->state_idx = genpd->state_idx_saved; 189+ 190 genpd->status = GENPD_STATE_ON; 191 } 192 193