Skip to content

Commit 098c305

Browse files
committed
Merge tag 'driver-core-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core updates from Greg KH: "Here's the new driver core patches for 4.10-rc1. Big thing here is the nice addition of "functional dependencies" to the driver core. The idea has been talked about for a very long time, great job to Rafael for stepping up and implementing it. It's been tested for longer than the 4.9-rc1 date, we held off on merging it earlier in order to feel more comfortable about it. Other than that, it's just a handful of small other patches, some good cleanups to the mess that is the firmware class code, and we have a test driver for the deferred probe logic. All of these have been in linux-next for a while with no reported issues" * tag 'driver-core-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (30 commits) firmware: Correct handling of fw_state_wait() return value driver core: Silence device links sphinx warning firmware: remove warning at documentation generation time drivers: base: dma-mapping: Fix typo in dmam_alloc_non_coherent comments driver core: test_async: fix up typo found by 0-day firmware: move fw_state_is_done() into UHM section firmware: do not use fw_lock for fw_state protection firmware: drop bit ops in favor of simple state machine firmware: refactor loading status firmware: fix usermode helper fallback loading driver core: firmware_class: convert to use class_groups driver core: devcoredump: convert to use class_groups driver core: class: add class_groups support kernfs: Declare two local data structures static driver-core: fix platform_no_drv_owner.cocci warnings drivers/base/memory.c: Remove unused 'first_page' variable driver core: add CLASS_ATTR_WO() drivers: base: cacheinfo: support DT overrides for cache properties drivers: base: cacheinfo: add pr_fmt logging drivers: base: cacheinfo: fix boot error message when acpi is enabled ...
2 parents 72cca7b + 5d47ec0 commit 098c305

File tree

26 files changed

+1517
-128
lines changed

26 files changed

+1517
-128
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
What: /sys/devices/.../deferred_probe
2+
Date: August 2016
3+
Contact: Ben Hutchings <ben.hutchings@codethink.co.uk>
4+
Description:
5+
The /sys/devices/.../deferred_probe attribute is
6+
present for all devices. If a driver detects during
7+
probing a device that a related device is not yet
8+
ready, it may defer probing of the first device. The
9+
kernel will retry probing the first device after any
10+
other device is successfully probed. This attribute
11+
reads as 1 if probing of this device is currently
12+
deferred, or 0 otherwise.

arch/x86/kernel/cpu/intel_cacheinfo.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,8 @@ static int __populate_cache_leaves(unsigned int cpu)
934934
ci_leaf_init(this_leaf++, &id4_regs);
935935
__cache_cpumap_setup(cpu, idx, &id4_regs);
936936
}
937+
this_cpu_ci->cpu_map_populated = true;
938+
937939
return 0;
938940
}
939941

drivers/base/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ config DEBUG_TEST_DRIVER_REMOVE
224224
unusable. You should say N here unless you are explicitly looking to
225225
test this functionality.
226226

227+
source "drivers/base/test/Kconfig"
228+
227229
config SYS_HYPERVISOR
228230
bool
229231
default n

drivers/base/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o
2424
obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o
2525
obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) += platform-msi.o
2626

27+
obj-y += test/
28+
2729
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
2830

drivers/base/base.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ extern void bus_remove_device(struct device *dev);
107107

108108
extern int bus_add_driver(struct device_driver *drv);
109109
extern void bus_remove_driver(struct device_driver *drv);
110+
extern void device_release_driver_internal(struct device *dev,
111+
struct device_driver *drv,
112+
struct device *parent);
110113

111114
extern void driver_detach(struct device_driver *drv);
112115
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
@@ -138,6 +141,8 @@ extern void device_unblock_probing(void);
138141
extern struct kset *devices_kset;
139142
extern void devices_kset_move_last(struct device *dev);
140143

144+
extern struct device_attribute dev_attr_deferred_probe;
145+
141146
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
142147
extern void module_add_driver(struct module *mod, struct device_driver *drv);
143148
extern void module_remove_driver(struct device_driver *drv);
@@ -152,3 +157,13 @@ extern int devtmpfs_init(void);
152157
#else
153158
static inline int devtmpfs_init(void) { return 0; }
154159
#endif
160+
161+
/* Device links support */
162+
extern int device_links_read_lock(void);
163+
extern void device_links_read_unlock(int idx);
164+
extern int device_links_check_suppliers(struct device *dev);
165+
extern void device_links_driver_bound(struct device *dev);
166+
extern void device_links_driver_cleanup(struct device *dev);
167+
extern void device_links_no_driver(struct device *dev);
168+
extern bool device_links_busy(struct device *dev);
169+
extern void device_links_unbind_consumers(struct device *dev);

drivers/base/cacheinfo.c

Lines changed: 134 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
* You should have received a copy of the GNU General Public License
1717
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
*/
19+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20+
21+
#include <linux/acpi.h>
1922
#include <linux/bitops.h>
2023
#include <linux/cacheinfo.h>
2124
#include <linux/compiler.h>
@@ -85,7 +88,120 @@ static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
8588
{
8689
return sib_leaf->of_node == this_leaf->of_node;
8790
}
91+
92+
/* OF properties to query for a given cache type */
93+
struct cache_type_info {
94+
const char *size_prop;
95+
const char *line_size_props[2];
96+
const char *nr_sets_prop;
97+
};
98+
99+
static const struct cache_type_info cache_type_info[] = {
100+
{
101+
.size_prop = "cache-size",
102+
.line_size_props = { "cache-line-size",
103+
"cache-block-size", },
104+
.nr_sets_prop = "cache-sets",
105+
}, {
106+
.size_prop = "i-cache-size",
107+
.line_size_props = { "i-cache-line-size",
108+
"i-cache-block-size", },
109+
.nr_sets_prop = "i-cache-sets",
110+
}, {
111+
.size_prop = "d-cache-size",
112+
.line_size_props = { "d-cache-line-size",
113+
"d-cache-block-size", },
114+
.nr_sets_prop = "d-cache-sets",
115+
},
116+
};
117+
118+
static inline int get_cacheinfo_idx(enum cache_type type)
119+
{
120+
if (type == CACHE_TYPE_UNIFIED)
121+
return 0;
122+
return type;
123+
}
124+
125+
static void cache_size(struct cacheinfo *this_leaf)
126+
{
127+
const char *propname;
128+
const __be32 *cache_size;
129+
int ct_idx;
130+
131+
ct_idx = get_cacheinfo_idx(this_leaf->type);
132+
propname = cache_type_info[ct_idx].size_prop;
133+
134+
cache_size = of_get_property(this_leaf->of_node, propname, NULL);
135+
if (cache_size)
136+
this_leaf->size = of_read_number(cache_size, 1);
137+
}
138+
139+
/* not cache_line_size() because that's a macro in include/linux/cache.h */
140+
static void cache_get_line_size(struct cacheinfo *this_leaf)
141+
{
142+
const __be32 *line_size;
143+
int i, lim, ct_idx;
144+
145+
ct_idx = get_cacheinfo_idx(this_leaf->type);
146+
lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props);
147+
148+
for (i = 0; i < lim; i++) {
149+
const char *propname;
150+
151+
propname = cache_type_info[ct_idx].line_size_props[i];
152+
line_size = of_get_property(this_leaf->of_node, propname, NULL);
153+
if (line_size)
154+
break;
155+
}
156+
157+
if (line_size)
158+
this_leaf->coherency_line_size = of_read_number(line_size, 1);
159+
}
160+
161+
static void cache_nr_sets(struct cacheinfo *this_leaf)
162+
{
163+
const char *propname;
164+
const __be32 *nr_sets;
165+
int ct_idx;
166+
167+
ct_idx = get_cacheinfo_idx(this_leaf->type);
168+
propname = cache_type_info[ct_idx].nr_sets_prop;
169+
170+
nr_sets = of_get_property(this_leaf->of_node, propname, NULL);
171+
if (nr_sets)
172+
this_leaf->number_of_sets = of_read_number(nr_sets, 1);
173+
}
174+
175+
static void cache_associativity(struct cacheinfo *this_leaf)
176+
{
177+
unsigned int line_size = this_leaf->coherency_line_size;
178+
unsigned int nr_sets = this_leaf->number_of_sets;
179+
unsigned int size = this_leaf->size;
180+
181+
/*
182+
* If the cache is fully associative, there is no need to
183+
* check the other properties.
184+
*/
185+
if (!(nr_sets == 1) && (nr_sets > 0 && size > 0 && line_size > 0))
186+
this_leaf->ways_of_associativity = (size / nr_sets) / line_size;
187+
}
188+
189+
static void cache_of_override_properties(unsigned int cpu)
190+
{
191+
int index;
192+
struct cacheinfo *this_leaf;
193+
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
194+
195+
for (index = 0; index < cache_leaves(cpu); index++) {
196+
this_leaf = this_cpu_ci->info_list + index;
197+
cache_size(this_leaf);
198+
cache_get_line_size(this_leaf);
199+
cache_nr_sets(this_leaf);
200+
cache_associativity(this_leaf);
201+
}
202+
}
88203
#else
204+
static void cache_of_override_properties(unsigned int cpu) { }
89205
static inline int cache_setup_of_node(unsigned int cpu) { return 0; }
90206
static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf,
91207
struct cacheinfo *sib_leaf)
@@ -104,9 +220,16 @@ static int cache_shared_cpu_map_setup(unsigned int cpu)
104220
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
105221
struct cacheinfo *this_leaf, *sib_leaf;
106222
unsigned int index;
107-
int ret;
223+
int ret = 0;
108224

109-
ret = cache_setup_of_node(cpu);
225+
if (this_cpu_ci->cpu_map_populated)
226+
return 0;
227+
228+
if (of_have_populated_dt())
229+
ret = cache_setup_of_node(cpu);
230+
else if (!acpi_disabled)
231+
/* No cache property/hierarchy support yet in ACPI */
232+
ret = -ENOTSUPP;
110233
if (ret)
111234
return ret;
112235

@@ -161,6 +284,12 @@ static void cache_shared_cpu_map_remove(unsigned int cpu)
161284
}
162285
}
163286

287+
static void cache_override_properties(unsigned int cpu)
288+
{
289+
if (of_have_populated_dt())
290+
return cache_of_override_properties(cpu);
291+
}
292+
164293
static void free_cache_attributes(unsigned int cpu)
165294
{
166295
if (!per_cpu_cacheinfo(cpu))
@@ -203,10 +332,11 @@ static int detect_cache_attributes(unsigned int cpu)
203332
*/
204333
ret = cache_shared_cpu_map_setup(cpu);
205334
if (ret) {
206-
pr_warn("Unable to detect cache hierarchy from DT for CPU %d\n",
207-
cpu);
335+
pr_warn("Unable to detect cache hierarchy for CPU %d\n", cpu);
208336
goto free_ci;
209337
}
338+
339+
cache_override_properties(cpu);
210340
return 0;
211341

212342
free_ci:

drivers/base/class.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,18 @@ static void klist_class_dev_put(struct klist_node *n)
163163
put_device(dev);
164164
}
165165

166+
static int class_add_groups(struct class *cls,
167+
const struct attribute_group **groups)
168+
{
169+
return sysfs_create_groups(&cls->p->subsys.kobj, groups);
170+
}
171+
172+
static void class_remove_groups(struct class *cls,
173+
const struct attribute_group **groups)
174+
{
175+
return sysfs_remove_groups(&cls->p->subsys.kobj, groups);
176+
}
177+
166178
int __class_register(struct class *cls, struct lock_class_key *key)
167179
{
168180
struct subsys_private *cp;
@@ -203,6 +215,8 @@ int __class_register(struct class *cls, struct lock_class_key *key)
203215
kfree(cp);
204216
return error;
205217
}
218+
error = class_add_groups(class_get(cls), cls->class_groups);
219+
class_put(cls);
206220
error = add_class_attrs(class_get(cls));
207221
class_put(cls);
208222
return error;
@@ -213,6 +227,7 @@ void class_unregister(struct class *cls)
213227
{
214228
pr_debug("device class '%s': unregistering\n", cls->name);
215229
remove_class_attrs(cls);
230+
class_remove_groups(cls, cls->class_groups);
216231
kset_unregister(&cls->p->subsys);
217232
}
218233

0 commit comments

Comments
 (0)