Merge branch 'component' of git://ftp.arm.linux.org.uk/~rmk/linux-arm

Pull component helper fixes from Russell King:
 "A few fixes for problems people have encountered with the recent
  update to the component helpers"

* 'component' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
  component: remove device from master match list on failed add
  component: Detach components when deleting master struct
  component: fix crash on x86_64 with hda audio drivers
This commit is contained in:
Linus Torvalds 2016-02-14 10:40:21 -08:00
commit 8b9f9ebe07
1 changed files with 28 additions and 21 deletions

View File

@ -206,6 +206,8 @@ static void component_match_release(struct device *master,
if (mc->release)
mc->release(master, mc->data);
}
kfree(match->compare);
}
static void devm_component_match_release(struct device *dev, void *res)
@ -221,14 +223,14 @@ static int component_match_realloc(struct device *dev,
if (match->alloc == num)
return 0;
new = devm_kmalloc_array(dev, num, sizeof(*new), GFP_KERNEL);
new = kmalloc_array(num, sizeof(*new), GFP_KERNEL);
if (!new)
return -ENOMEM;
if (match->compare) {
memcpy(new, match->compare, sizeof(*new) *
min(match->num, num));
devm_kfree(dev, match->compare);
kfree(match->compare);
}
match->compare = new;
match->alloc = num;
@ -283,6 +285,24 @@ void component_match_add_release(struct device *master,
}
EXPORT_SYMBOL(component_match_add_release);
static void free_master(struct master *master)
{
struct component_match *match = master->match;
int i;
list_del(&master->node);
if (match) {
for (i = 0; i < match->num; i++) {
struct component *c = match->compare[i].component;
if (c)
c->master = NULL;
}
}
kfree(master);
}
int component_master_add_with_match(struct device *dev,
const struct component_master_ops *ops,
struct component_match *match)
@ -309,11 +329,9 @@ int component_master_add_with_match(struct device *dev,
ret = try_to_bring_up_master(master, NULL);
if (ret < 0) {
/* Delete off the list if we weren't successful */
list_del(&master->node);
kfree(master);
}
if (ret < 0)
free_master(master);
mutex_unlock(&component_mutex);
return ret < 0 ? ret : 0;
@ -324,25 +342,12 @@ void component_master_del(struct device *dev,
const struct component_master_ops *ops)
{
struct master *master;
int i;
mutex_lock(&component_mutex);
master = __master_find(dev, ops);
if (master) {
struct component_match *match = master->match;
take_down_master(master);
list_del(&master->node);
if (match) {
for (i = 0; i < match->num; i++) {
struct component *c = match->compare[i].component;
if (c)
c->master = NULL;
}
}
kfree(master);
free_master(master);
}
mutex_unlock(&component_mutex);
}
@ -486,6 +491,8 @@ int component_add(struct device *dev, const struct component_ops *ops)
ret = try_to_bring_up_masters(component);
if (ret < 0) {
if (component->master)
remove_component(component->master, component);
list_del(&component->node);
kfree(component);