Skip to content

Commit 44b1671

Browse files
committed
Merge tag 'driver-core-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core update from Greg KH: "Here is the "big" driver core update for 4.14-rc1. It's really not all that big, the largest thing here being some firmware tests to help ensure that that crazy api is working properly. There's also a new uevent for when a driver is bound or unbound from a device, fixing a hole in the driver model that's been there since the very beginning. Many thanks to Dmitry for being persistent and pointing out how wrong I was about this all along :) Patches for the new uevents are already in the systemd tree, if people want to play around with them. Otherwise just a number of other small api changes and updates here, nothing major. All of these patches have been in linux-next for a while with no reported issues" * tag 'driver-core-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (28 commits) driver core: bus: Fix a potential double free Do not disable driver and bus shutdown hook when class shutdown hook is set. base: topology: constify attribute_group structures. base: Convert to using %pOF instead of full_name kernfs: Clarify lockdep name for kn->count fbdev: uvesafb: remove DRIVER_ATTR() usage xen: xen-pciback: remove DRIVER_ATTR() usage driver core: Document struct device:dma_ops mod_devicetable: Remove excess description from structured comment test_firmware: add batched firmware tests firmware: enable a debug print for batched requests firmware: define pr_fmt firmware: send -EINTR on signal abort on fallback mechanism test_firmware: add test case for SIGCHLD on sync fallback initcall_debug: add deferred probe times Input: axp20x-pek - switch to using devm_device_add_group() Input: synaptics_rmi4 - use devm_device_add_group() for attributes in F01 Input: gpio_keys - use devm_device_add_group() for attributes driver core: add devm_device_add_group() and friends driver core: add device_{add|remove}_group() helpers ...
2 parents bf1d6b2 + 0f9b011 commit 44b1671

File tree

23 files changed

+1291
-142
lines changed

23 files changed

+1291
-142
lines changed

drivers/base/arch_topology.c

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ static ssize_t cpu_capacity_show(struct device *dev,
4141
{
4242
struct cpu *cpu = container_of(dev, struct cpu, dev);
4343

44-
return sprintf(buf, "%lu\n",
45-
topology_get_cpu_scale(NULL, cpu->dev.id));
44+
return sprintf(buf, "%lu\n", topology_get_cpu_scale(NULL, cpu->dev.id));
4645
}
4746

4847
static ssize_t cpu_capacity_store(struct device *dev,
@@ -96,14 +95,21 @@ subsys_initcall(register_cpu_capacity_sysctl);
9695

9796
static u32 capacity_scale;
9897
static u32 *raw_capacity;
99-
static bool cap_parsing_failed;
98+
99+
static int __init free_raw_capacity(void)
100+
{
101+
kfree(raw_capacity);
102+
raw_capacity = NULL;
103+
104+
return 0;
105+
}
100106

101107
void topology_normalize_cpu_scale(void)
102108
{
103109
u64 capacity;
104110
int cpu;
105111

106-
if (!raw_capacity || cap_parsing_failed)
112+
if (!raw_capacity)
107113
return;
108114

109115
pr_debug("cpu_capacity: capacity_scale=%u\n", capacity_scale);
@@ -120,16 +126,16 @@ void topology_normalize_cpu_scale(void)
120126
mutex_unlock(&cpu_scale_mutex);
121127
}
122128

123-
int __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
129+
bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
124130
{
125-
int ret = 1;
131+
static bool cap_parsing_failed;
132+
int ret;
126133
u32 cpu_capacity;
127134

128135
if (cap_parsing_failed)
129-
return !ret;
136+
return false;
130137

131-
ret = of_property_read_u32(cpu_node,
132-
"capacity-dmips-mhz",
138+
ret = of_property_read_u32(cpu_node, "capacity-dmips-mhz",
133139
&cpu_capacity);
134140
if (!ret) {
135141
if (!raw_capacity) {
@@ -139,29 +145,28 @@ int __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
139145
if (!raw_capacity) {
140146
pr_err("cpu_capacity: failed to allocate memory for raw capacities\n");
141147
cap_parsing_failed = true;
142-
return 0;
148+
return false;
143149
}
144150
}
145151
capacity_scale = max(cpu_capacity, capacity_scale);
146152
raw_capacity[cpu] = cpu_capacity;
147-
pr_debug("cpu_capacity: %s cpu_capacity=%u (raw)\n",
148-
cpu_node->full_name, raw_capacity[cpu]);
153+
pr_debug("cpu_capacity: %pOF cpu_capacity=%u (raw)\n",
154+
cpu_node, raw_capacity[cpu]);
149155
} else {
150156
if (raw_capacity) {
151-
pr_err("cpu_capacity: missing %s raw capacity\n",
152-
cpu_node->full_name);
157+
pr_err("cpu_capacity: missing %pOF raw capacity\n",
158+
cpu_node);
153159
pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
154160
}
155161
cap_parsing_failed = true;
156-
kfree(raw_capacity);
162+
free_raw_capacity();
157163
}
158164

159165
return !ret;
160166
}
161167

162168
#ifdef CONFIG_CPU_FREQ
163169
static cpumask_var_t cpus_to_visit;
164-
static bool cap_parsing_done;
165170
static void parsing_done_workfn(struct work_struct *work);
166171
static DECLARE_WORK(parsing_done_work, parsing_done_workfn);
167172

@@ -173,30 +178,31 @@ init_cpu_capacity_callback(struct notifier_block *nb,
173178
struct cpufreq_policy *policy = data;
174179
int cpu;
175180

176-
if (cap_parsing_failed || cap_parsing_done)
181+
if (!raw_capacity)
177182
return 0;
178183

179-
switch (val) {
180-
case CPUFREQ_NOTIFY:
181-
pr_debug("cpu_capacity: init cpu capacity for CPUs [%*pbl] (to_visit=%*pbl)\n",
182-
cpumask_pr_args(policy->related_cpus),
183-
cpumask_pr_args(cpus_to_visit));
184-
cpumask_andnot(cpus_to_visit,
185-
cpus_to_visit,
186-
policy->related_cpus);
187-
for_each_cpu(cpu, policy->related_cpus) {
188-
raw_capacity[cpu] = topology_get_cpu_scale(NULL, cpu) *
189-
policy->cpuinfo.max_freq / 1000UL;
190-
capacity_scale = max(raw_capacity[cpu], capacity_scale);
191-
}
192-
if (cpumask_empty(cpus_to_visit)) {
193-
topology_normalize_cpu_scale();
194-
kfree(raw_capacity);
195-
pr_debug("cpu_capacity: parsing done\n");
196-
cap_parsing_done = true;
197-
schedule_work(&parsing_done_work);
198-
}
184+
if (val != CPUFREQ_NOTIFY)
185+
return 0;
186+
187+
pr_debug("cpu_capacity: init cpu capacity for CPUs [%*pbl] (to_visit=%*pbl)\n",
188+
cpumask_pr_args(policy->related_cpus),
189+
cpumask_pr_args(cpus_to_visit));
190+
191+
cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
192+
193+
for_each_cpu(cpu, policy->related_cpus) {
194+
raw_capacity[cpu] = topology_get_cpu_scale(NULL, cpu) *
195+
policy->cpuinfo.max_freq / 1000UL;
196+
capacity_scale = max(raw_capacity[cpu], capacity_scale);
197+
}
198+
199+
if (cpumask_empty(cpus_to_visit)) {
200+
topology_normalize_cpu_scale();
201+
free_raw_capacity();
202+
pr_debug("cpu_capacity: parsing done\n");
203+
schedule_work(&parsing_done_work);
199204
}
205+
200206
return 0;
201207
}
202208

@@ -233,11 +239,5 @@ static void parsing_done_workfn(struct work_struct *work)
233239
}
234240

235241
#else
236-
static int __init free_raw_capacity(void)
237-
{
238-
kfree(raw_capacity);
239-
240-
return 0;
241-
}
242242
core_initcall(free_raw_capacity);
243243
#endif

drivers/base/base.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,6 @@ extern int driver_add_groups(struct device_driver *drv,
126126
extern void driver_remove_groups(struct device_driver *drv,
127127
const struct attribute_group **groups);
128128

129-
extern int device_add_groups(struct device *dev,
130-
const struct attribute_group **groups);
131-
extern void device_remove_groups(struct device *dev,
132-
const struct attribute_group **groups);
133-
134129
extern char *make_class_name(const char *name, struct kobject *kobj);
135130

136131
extern int devres_release_all(struct device *dev);

drivers/base/bus.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ int bus_add_driver(struct device_driver *drv)
698698

699699
out_unregister:
700700
kobject_put(&priv->kobj);
701-
kfree(drv->p);
701+
/* drv->p is freed in driver_release() */
702702
drv->p = NULL;
703703
out_put_bus:
704704
bus_put(bus);

drivers/base/core.c

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,12 +1023,144 @@ int device_add_groups(struct device *dev, const struct attribute_group **groups)
10231023
{
10241024
return sysfs_create_groups(&dev->kobj, groups);
10251025
}
1026+
EXPORT_SYMBOL_GPL(device_add_groups);
10261027

10271028
void device_remove_groups(struct device *dev,
10281029
const struct attribute_group **groups)
10291030
{
10301031
sysfs_remove_groups(&dev->kobj, groups);
10311032
}
1033+
EXPORT_SYMBOL_GPL(device_remove_groups);
1034+
1035+
union device_attr_group_devres {
1036+
const struct attribute_group *group;
1037+
const struct attribute_group **groups;
1038+
};
1039+
1040+
static int devm_attr_group_match(struct device *dev, void *res, void *data)
1041+
{
1042+
return ((union device_attr_group_devres *)res)->group == data;
1043+
}
1044+
1045+
static void devm_attr_group_remove(struct device *dev, void *res)
1046+
{
1047+
union device_attr_group_devres *devres = res;
1048+
const struct attribute_group *group = devres->group;
1049+
1050+
dev_dbg(dev, "%s: removing group %p\n", __func__, group);
1051+
sysfs_remove_group(&dev->kobj, group);
1052+
}
1053+
1054+
static void devm_attr_groups_remove(struct device *dev, void *res)
1055+
{
1056+
union device_attr_group_devres *devres = res;
1057+
const struct attribute_group **groups = devres->groups;
1058+
1059+
dev_dbg(dev, "%s: removing groups %p\n", __func__, groups);
1060+
sysfs_remove_groups(&dev->kobj, groups);
1061+
}
1062+
1063+
/**
1064+
* devm_device_add_group - given a device, create a managed attribute group
1065+
* @dev: The device to create the group for
1066+
* @grp: The attribute group to create
1067+
*
1068+
* This function creates a group for the first time. It will explicitly
1069+
* warn and error if any of the attribute files being created already exist.
1070+
*
1071+
* Returns 0 on success or error code on failure.
1072+
*/
1073+
int devm_device_add_group(struct device *dev, const struct attribute_group *grp)
1074+
{
1075+
union device_attr_group_devres *devres;
1076+
int error;
1077+
1078+
devres = devres_alloc(devm_attr_group_remove,
1079+
sizeof(*devres), GFP_KERNEL);
1080+
if (!devres)
1081+
return -ENOMEM;
1082+
1083+
error = sysfs_create_group(&dev->kobj, grp);
1084+
if (error) {
1085+
devres_free(devres);
1086+
return error;
1087+
}
1088+
1089+
devres->group = grp;
1090+
devres_add(dev, devres);
1091+
return 0;
1092+
}
1093+
EXPORT_SYMBOL_GPL(devm_device_add_group);
1094+
1095+
/**
1096+
* devm_device_remove_group: remove a managed group from a device
1097+
* @dev: device to remove the group from
1098+
* @grp: group to remove
1099+
*
1100+
* This function removes a group of attributes from a device. The attributes
1101+
* previously have to have been created for this group, otherwise it will fail.
1102+
*/
1103+
void devm_device_remove_group(struct device *dev,
1104+
const struct attribute_group *grp)
1105+
{
1106+
WARN_ON(devres_release(dev, devm_attr_group_remove,
1107+
devm_attr_group_match,
1108+
/* cast away const */ (void *)grp));
1109+
}
1110+
EXPORT_SYMBOL_GPL(devm_device_remove_group);
1111+
1112+
/**
1113+
* devm_device_add_groups - create a bunch of managed attribute groups
1114+
* @dev: The device to create the group for
1115+
* @groups: The attribute groups to create, NULL terminated
1116+
*
1117+
* This function creates a bunch of managed attribute groups. If an error
1118+
* occurs when creating a group, all previously created groups will be
1119+
* removed, unwinding everything back to the original state when this
1120+
* function was called. It will explicitly warn and error if any of the
1121+
* attribute files being created already exist.
1122+
*
1123+
* Returns 0 on success or error code from sysfs_create_group on failure.
1124+
*/
1125+
int devm_device_add_groups(struct device *dev,
1126+
const struct attribute_group **groups)
1127+
{
1128+
union device_attr_group_devres *devres;
1129+
int error;
1130+
1131+
devres = devres_alloc(devm_attr_groups_remove,
1132+
sizeof(*devres), GFP_KERNEL);
1133+
if (!devres)
1134+
return -ENOMEM;
1135+
1136+
error = sysfs_create_groups(&dev->kobj, groups);
1137+
if (error) {
1138+
devres_free(devres);
1139+
return error;
1140+
}
1141+
1142+
devres->groups = groups;
1143+
devres_add(dev, devres);
1144+
return 0;
1145+
}
1146+
EXPORT_SYMBOL_GPL(devm_device_add_groups);
1147+
1148+
/**
1149+
* devm_device_remove_groups - remove a list of managed groups
1150+
*
1151+
* @dev: The device for the groups to be removed from
1152+
* @groups: NULL terminated list of groups to be removed
1153+
*
1154+
* If groups is not NULL, remove the specified groups from the device.
1155+
*/
1156+
void devm_device_remove_groups(struct device *dev,
1157+
const struct attribute_group **groups)
1158+
{
1159+
WARN_ON(devres_release(dev, devm_attr_groups_remove,
1160+
devm_attr_group_match,
1161+
/* cast away const */ (void *)groups));
1162+
}
1163+
EXPORT_SYMBOL_GPL(devm_device_remove_groups);
10321164

10331165
static int device_add_attrs(struct device *dev)
10341166
{
@@ -2664,11 +2796,12 @@ void device_shutdown(void)
26642796
pm_runtime_get_noresume(dev);
26652797
pm_runtime_barrier(dev);
26662798

2667-
if (dev->class && dev->class->shutdown) {
2799+
if (dev->class && dev->class->shutdown_pre) {
26682800
if (initcall_debug)
2669-
dev_info(dev, "shutdown\n");
2670-
dev->class->shutdown(dev);
2671-
} else if (dev->bus && dev->bus->shutdown) {
2801+
dev_info(dev, "shutdown_pre\n");
2802+
dev->class->shutdown_pre(dev);
2803+
}
2804+
if (dev->bus && dev->bus->shutdown) {
26722805
if (initcall_debug)
26732806
dev_info(dev, "shutdown\n");
26742807
dev->bus->shutdown(dev);

0 commit comments

Comments
 (0)