Commit 8b9f9ebe authored by Linus Torvalds's avatar Linus Torvalds

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
parents 7686e3c1 8e7199c2
...@@ -206,6 +206,8 @@ static void component_match_release(struct device *master, ...@@ -206,6 +206,8 @@ static void component_match_release(struct device *master,
if (mc->release) if (mc->release)
mc->release(master, mc->data); mc->release(master, mc->data);
} }
kfree(match->compare);
} }
static void devm_component_match_release(struct device *dev, void *res) static void devm_component_match_release(struct device *dev, void *res)
...@@ -221,14 +223,14 @@ static int component_match_realloc(struct device *dev, ...@@ -221,14 +223,14 @@ static int component_match_realloc(struct device *dev,
if (match->alloc == num) if (match->alloc == num)
return 0; return 0;
new = devm_kmalloc_array(dev, num, sizeof(*new), GFP_KERNEL); new = kmalloc_array(num, sizeof(*new), GFP_KERNEL);
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;
if (match->compare) { if (match->compare) {
memcpy(new, match->compare, sizeof(*new) * memcpy(new, match->compare, sizeof(*new) *
min(match->num, num)); min(match->num, num));
devm_kfree(dev, match->compare); kfree(match->compare);
} }
match->compare = new; match->compare = new;
match->alloc = num; match->alloc = num;
...@@ -283,6 +285,24 @@ void component_match_add_release(struct device *master, ...@@ -283,6 +285,24 @@ void component_match_add_release(struct device *master,
} }
EXPORT_SYMBOL(component_match_add_release); 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, int component_master_add_with_match(struct device *dev,
const struct component_master_ops *ops, const struct component_master_ops *ops,
struct component_match *match) struct component_match *match)
...@@ -309,11 +329,9 @@ int component_master_add_with_match(struct device *dev, ...@@ -309,11 +329,9 @@ int component_master_add_with_match(struct device *dev,
ret = try_to_bring_up_master(master, NULL); ret = try_to_bring_up_master(master, NULL);
if (ret < 0) { if (ret < 0)
/* Delete off the list if we weren't successful */ free_master(master);
list_del(&master->node);
kfree(master);
}
mutex_unlock(&component_mutex); mutex_unlock(&component_mutex);
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
...@@ -324,25 +342,12 @@ void component_master_del(struct device *dev, ...@@ -324,25 +342,12 @@ void component_master_del(struct device *dev,
const struct component_master_ops *ops) const struct component_master_ops *ops)
{ {
struct master *master; struct master *master;
int i;
mutex_lock(&component_mutex); mutex_lock(&component_mutex);
master = __master_find(dev, ops); master = __master_find(dev, ops);
if (master) { if (master) {
struct component_match *match = master->match;
take_down_master(master); take_down_master(master);
free_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);
} }
mutex_unlock(&component_mutex); mutex_unlock(&component_mutex);
} }
...@@ -486,6 +491,8 @@ int component_add(struct device *dev, const struct component_ops *ops) ...@@ -486,6 +491,8 @@ int component_add(struct device *dev, const struct component_ops *ops)
ret = try_to_bring_up_masters(component); ret = try_to_bring_up_masters(component);
if (ret < 0) { if (ret < 0) {
if (component->master)
remove_component(component->master, component);
list_del(&component->node); list_del(&component->node);
kfree(component); kfree(component);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment