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:
Olof Johansson 2017-06-18 21:01:15 -07:00
commit 43e68aa7b5
1 changed files with 18 additions and 10 deletions

View File

@ -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,