firmware: tegra: Changes for v4.13-rc1
This contains a fix for missing semaphore release in error paths as well as a bogus error code return in the BPMP firmware implementation. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAllDkJsTHHRyZWRpbmdA bnZpZGlhLmNvbQAKCRDdI6zXfz6zoXtgD/449NCGPiDlOyxouUF/44RGdu0JPCHg 3xOc8QJHvTqjEXBFW0WFM6ziIfi5l8+QirlEURmhEemkyCToRRN8L78WFXGZqQNl HM54X9ba4d7ac00hXXpsU+OMxJ3SnLkU4m5Vi7FbOPRx3CZvbLa9xDUMwgKNm97H W90eFDlmpEmLnw1Bzeasy3dyEvJSSCPbl+6oAyk/FYThAwpn9KlSRw6L5vIptggK qIHRqvN6OGx5B2Rc26oNiB2/RVMcO7+01J+IItPBuTtWJ7tW7XFQCMMTcSAqKtoV 7EToSZK3wnVTQwCufMnsAA+bBoMtk08g/yMGlXpIdKgzzBJiL3U++YAkimmSVUpD gnUYqwQvLzw7IbHcunQohXF22wGvdsZqv9mnGdC9jgxKt3meSVhiD4c8zjvbAfWk wBS7CcWGMGt6QLiAzajIzxVGOM2rgTMrOGGw8uzHhteSl5krSm09JKO/dpn4AUXX O6jO1+5mTdLUJmsvYi21X2ZBjJfxy258VTSzjlzcm/QRw2Nz98L+x8N5a1iOjCVC eOb5cfeEaT5MBkR7wwvFyWBVmdVb9xNqkAiL//p4qfMeq+oRmT4fTO37gv44BYoK qsGd1LMsa5TDnvKoy/Ij5ZNvaVlVXRYIswIy41k7THy+9jeuNWp0HLA5Cr2brXJV VcZeaRT81se5tQ== =nTv2 -----END PGP SIGNATURE----- Merge tag 'tegra-for-4.13-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers firmware: tegra: Changes for v4.13-rc1 This contains a fix for missing semaphore release in error paths as well as a bogus error code return in the BPMP firmware implementation. * tag 'tegra-for-4.13-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: firmware: tegra: Fix locking bugs in BPMP Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
43e68aa7b5
|
@ -211,14 +211,17 @@ static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
index = tegra_bpmp_channel_get_thread_index(channel);
|
index = tegra_bpmp_channel_get_thread_index(channel);
|
||||||
if (index < 0)
|
if (index < 0) {
|
||||||
return index;
|
err = index;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&bpmp->lock, flags);
|
spin_lock_irqsave(&bpmp->lock, flags);
|
||||||
err = __tegra_bpmp_channel_read(channel, data, size);
|
err = __tegra_bpmp_channel_read(channel, data, size);
|
||||||
clear_bit(index, bpmp->threaded.allocated);
|
clear_bit(index, bpmp->threaded.allocated);
|
||||||
spin_unlock_irqrestore(&bpmp->lock, flags);
|
spin_unlock_irqrestore(&bpmp->lock, flags);
|
||||||
|
|
||||||
|
unlock:
|
||||||
up(&bpmp->threaded.lock);
|
up(&bpmp->threaded.lock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -256,18 +259,18 @@ tegra_bpmp_write_threaded(struct tegra_bpmp *bpmp, unsigned int mrq,
|
||||||
|
|
||||||
index = find_first_zero_bit(bpmp->threaded.allocated, count);
|
index = find_first_zero_bit(bpmp->threaded.allocated, count);
|
||||||
if (index == count) {
|
if (index == count) {
|
||||||
channel = ERR_PTR(-EBUSY);
|
err = -EBUSY;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = tegra_bpmp_channel_get_thread(bpmp, index);
|
channel = tegra_bpmp_channel_get_thread(bpmp, index);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
channel = ERR_PTR(-EINVAL);
|
err = -EINVAL;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tegra_bpmp_master_free(channel)) {
|
if (!tegra_bpmp_master_free(channel)) {
|
||||||
channel = ERR_PTR(-EBUSY);
|
err = -EBUSY;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,16 +278,21 @@ tegra_bpmp_write_threaded(struct tegra_bpmp *bpmp, unsigned int mrq,
|
||||||
|
|
||||||
err = __tegra_bpmp_channel_write(channel, mrq, MSG_ACK | MSG_RING,
|
err = __tegra_bpmp_channel_write(channel, mrq, MSG_ACK | MSG_RING,
|
||||||
data, size);
|
data, size);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
clear_bit(index, bpmp->threaded.allocated);
|
goto clear_allocated;
|
||||||
goto unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_bit(index, bpmp->threaded.busy);
|
set_bit(index, bpmp->threaded.busy);
|
||||||
|
|
||||||
unlock:
|
|
||||||
spin_unlock_irqrestore(&bpmp->lock, flags);
|
spin_unlock_irqrestore(&bpmp->lock, flags);
|
||||||
return channel;
|
return channel;
|
||||||
|
|
||||||
|
clear_allocated:
|
||||||
|
clear_bit(index, bpmp->threaded.allocated);
|
||||||
|
unlock:
|
||||||
|
spin_unlock_irqrestore(&bpmp->lock, flags);
|
||||||
|
up(&bpmp->threaded.lock);
|
||||||
|
|
||||||
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
|
static ssize_t tegra_bpmp_channel_write(struct tegra_bpmp_channel *channel,
|
||||||
|
|
Loading…
Reference in New Issue