firmware: Changes for v4.17-rc1

These changes are rather small, with just a fix for a return value check
 and some preparatory work for Tegra194 BPMP support.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAlqrz+cTHHRyZWRpbmdA
 bnZpZGlhLmNvbQAKCRDdI6zXfz6zoeYLEACtgcGVUSA/gsqdskhIHVE9zVmFgQes
 sivqoXAsMKvuHnBpJ3QG0BLXF0FWFmXwpRtCmblWwsp+OredeXv+Kv7Zki4/hvBD
 IsuXaerTxTcI8PgD94TwiPNqSX8HrqAvQs5402QxShSkQO0eGXUcFo3I1nzKAerm
 kHX2GNBqg2qDaAGA7jUcmAs/XNV4hxdm3tPWntqgB89jyuM2Qhyg0/v/XVnYjZJr
 gc8oClIpXZMdM1dRLbHWMVYUBLeSIHdAGVp9mfx53cCALoW9aGmwceO0I7ZWU2F0
 07YHSnoRZO6Ma2+yzoDFNeaOzA3yuX2dfGYQ+kHHUXdWvO61uArs5eBrOinPNPSb
 +ohQtkxcU29NZ5YkIaS1C36sKrPDJMYFm/6aKB8bp+I+cy16g/P6I3XE5yFu/r55
 7uWmfEiu9oNvllHEEPSlsslwaFZds9l8ticQ5D+DUm6duPsInrk4hNrqXRlM9daK
 kHw5dq/+gAZJOUhhjMqhTthyqpqKHJlR6hUX9clEB8H2LMkGbcQZQGJ669nNJBL1
 FxROPfSm1cPsU6YdXePY0OGHoGN0U2jVgDgqwNdZW1I8QZSH1YDAG1I7YvCEyGdf
 4egRaOPcE7JGhaOExVxDEI8Z1Nk1HAoSLEwVKeIeJEcrzknzCmAtnJ4L9tSlwYFp
 Ea8cQ9BWAcqX0w==
 =oigm
 -----END PGP SIGNATURE-----

Merge tag 'tegra-for-4.17-firmware' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers

Pull "firmware: Changes for v4.17-rc1" from Thierry Reding:

These changes are rather small, with just a fix for a return value check
and some preparatory work for Tegra194 BPMP support.

* tag 'tegra-for-4.17-firmware' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  firmware: tegra: adjust tested variable
  firmware: tegra: Simplify channel management
This commit is contained in:
Arnd Bergmann 2018-03-27 15:50:57 +02:00
commit d0994465d0
2 changed files with 68 additions and 82 deletions

View File

@ -70,57 +70,20 @@ void tegra_bpmp_put(struct tegra_bpmp *bpmp)
}
EXPORT_SYMBOL_GPL(tegra_bpmp_put);
static int tegra_bpmp_channel_get_index(struct tegra_bpmp_channel *channel)
{
return channel - channel->bpmp->channels;
}
static int
tegra_bpmp_channel_get_thread_index(struct tegra_bpmp_channel *channel)
{
struct tegra_bpmp *bpmp = channel->bpmp;
unsigned int offset, count;
unsigned int count;
int index;
offset = bpmp->soc->channels.thread.offset;
count = bpmp->soc->channels.thread.count;
index = tegra_bpmp_channel_get_index(channel);
if (index < 0)
return index;
if (index < offset || index >= offset + count)
index = channel - channel->bpmp->threaded_channels;
if (index < 0 || index >= count)
return -EINVAL;
return index - offset;
}
static struct tegra_bpmp_channel *
tegra_bpmp_channel_get_thread(struct tegra_bpmp *bpmp, unsigned int index)
{
unsigned int offset = bpmp->soc->channels.thread.offset;
unsigned int count = bpmp->soc->channels.thread.count;
if (index >= count)
return NULL;
return &bpmp->channels[offset + index];
}
static struct tegra_bpmp_channel *
tegra_bpmp_channel_get_tx(struct tegra_bpmp *bpmp)
{
unsigned int offset = bpmp->soc->channels.cpu_tx.offset;
return &bpmp->channels[offset + smp_processor_id()];
}
static struct tegra_bpmp_channel *
tegra_bpmp_channel_get_rx(struct tegra_bpmp *bpmp)
{
unsigned int offset = bpmp->soc->channels.cpu_rx.offset;
return &bpmp->channels[offset];
return index;
}
static bool tegra_bpmp_message_valid(const struct tegra_bpmp_message *msg)
@ -271,11 +234,7 @@ tegra_bpmp_write_threaded(struct tegra_bpmp *bpmp, unsigned int mrq,
goto unlock;
}
channel = tegra_bpmp_channel_get_thread(bpmp, index);
if (!channel) {
err = -EINVAL;
goto unlock;
}
channel = &bpmp->threaded_channels[index];
if (!tegra_bpmp_master_free(channel)) {
err = -EBUSY;
@ -328,12 +287,18 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
if (!tegra_bpmp_message_valid(msg))
return -EINVAL;
channel = tegra_bpmp_channel_get_tx(bpmp);
channel = bpmp->tx_channel;
spin_lock(&bpmp->atomic_tx_lock);
err = tegra_bpmp_channel_write(channel, msg->mrq, MSG_ACK,
msg->tx.data, msg->tx.size);
if (err < 0)
if (err < 0) {
spin_unlock(&bpmp->atomic_tx_lock);
return err;
}
spin_unlock(&bpmp->atomic_tx_lock);
err = mbox_send_message(bpmp->mbox.channel, NULL);
if (err < 0)
@ -607,7 +572,7 @@ static void tegra_bpmp_handle_rx(struct mbox_client *client, void *data)
unsigned int i, count;
unsigned long *busy;
channel = tegra_bpmp_channel_get_rx(bpmp);
channel = bpmp->rx_channel;
count = bpmp->soc->channels.thread.count;
busy = bpmp->threaded.busy;
@ -619,9 +584,7 @@ static void tegra_bpmp_handle_rx(struct mbox_client *client, void *data)
for_each_set_bit(i, busy, count) {
struct tegra_bpmp_channel *channel;
channel = tegra_bpmp_channel_get_thread(bpmp, i);
if (!channel)
continue;
channel = &bpmp->threaded_channels[i];
if (tegra_bpmp_master_acked(channel)) {
tegra_bpmp_channel_signal(channel);
@ -698,7 +661,6 @@ static void tegra_bpmp_channel_cleanup(struct tegra_bpmp_channel *channel)
static int tegra_bpmp_probe(struct platform_device *pdev)
{
struct tegra_bpmp_channel *channel;
struct tegra_bpmp *bpmp;
unsigned int i;
char tag[32];
@ -732,7 +694,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
}
bpmp->rx.virt = gen_pool_dma_alloc(bpmp->rx.pool, 4096, &bpmp->rx.phys);
if (!bpmp->rx.pool) {
if (!bpmp->rx.virt) {
dev_err(&pdev->dev, "failed to allocate from RX pool\n");
err = -ENOMEM;
goto free_tx;
@ -758,24 +720,45 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
goto free_rx;
}
bpmp->num_channels = bpmp->soc->channels.cpu_tx.count +
bpmp->soc->channels.thread.count +
bpmp->soc->channels.cpu_rx.count;
bpmp->channels = devm_kcalloc(&pdev->dev, bpmp->num_channels,
sizeof(*channel), GFP_KERNEL);
if (!bpmp->channels) {
spin_lock_init(&bpmp->atomic_tx_lock);
bpmp->tx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->tx_channel),
GFP_KERNEL);
if (!bpmp->tx_channel) {
err = -ENOMEM;
goto free_rx;
}
/* message channel initialization */
for (i = 0; i < bpmp->num_channels; i++) {
struct tegra_bpmp_channel *channel = &bpmp->channels[i];
bpmp->rx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->rx_channel),
GFP_KERNEL);
if (!bpmp->rx_channel) {
err = -ENOMEM;
goto free_rx;
}
err = tegra_bpmp_channel_init(channel, bpmp, i);
bpmp->threaded_channels = devm_kcalloc(&pdev->dev, bpmp->threaded.count,
sizeof(*bpmp->threaded_channels),
GFP_KERNEL);
if (!bpmp->threaded_channels) {
err = -ENOMEM;
goto free_rx;
}
err = tegra_bpmp_channel_init(bpmp->tx_channel, bpmp,
bpmp->soc->channels.cpu_tx.offset);
if (err < 0)
goto free_rx;
err = tegra_bpmp_channel_init(bpmp->rx_channel, bpmp,
bpmp->soc->channels.cpu_rx.offset);
if (err < 0)
goto cleanup_tx_channel;
for (i = 0; i < bpmp->threaded.count; i++) {
err = tegra_bpmp_channel_init(
&bpmp->threaded_channels[i], bpmp,
bpmp->soc->channels.thread.offset + i);
if (err < 0)
goto cleanup_channels;
goto cleanup_threaded_channels;
}
/* mbox registration */
@ -788,15 +771,14 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
if (IS_ERR(bpmp->mbox.channel)) {
err = PTR_ERR(bpmp->mbox.channel);
dev_err(&pdev->dev, "failed to get HSP mailbox: %d\n", err);
goto cleanup_channels;
goto cleanup_threaded_channels;
}
/* reset message channels */
for (i = 0; i < bpmp->num_channels; i++) {
struct tegra_bpmp_channel *channel = &bpmp->channels[i];
tegra_bpmp_channel_reset(channel);
}
tegra_bpmp_channel_reset(bpmp->tx_channel);
tegra_bpmp_channel_reset(bpmp->rx_channel);
for (i = 0; i < bpmp->threaded.count; i++)
tegra_bpmp_channel_reset(&bpmp->threaded_channels[i]);
err = tegra_bpmp_request_mrq(bpmp, MRQ_PING,
tegra_bpmp_mrq_handle_ping, bpmp);
@ -845,9 +827,15 @@ free_mrq:
tegra_bpmp_free_mrq(bpmp, MRQ_PING, bpmp);
free_mbox:
mbox_free_channel(bpmp->mbox.channel);
cleanup_channels:
while (i--)
tegra_bpmp_channel_cleanup(&bpmp->channels[i]);
cleanup_threaded_channels:
for (i = 0; i < bpmp->threaded.count; i++) {
if (bpmp->threaded_channels[i].bpmp)
tegra_bpmp_channel_cleanup(&bpmp->threaded_channels[i]);
}
tegra_bpmp_channel_cleanup(bpmp->rx_channel);
cleanup_tx_channel:
tegra_bpmp_channel_cleanup(bpmp->tx_channel);
free_rx:
gen_pool_free(bpmp->rx.pool, (unsigned long)bpmp->rx.virt, 4096);
free_tx:
@ -858,18 +846,16 @@ free_tx:
static const struct tegra_bpmp_soc tegra186_soc = {
.channels = {
.cpu_tx = {
.offset = 0,
.count = 6,
.offset = 3,
.timeout = 60 * USEC_PER_SEC,
},
.thread = {
.offset = 6,
.count = 7,
.offset = 0,
.count = 3,
.timeout = 600 * USEC_PER_SEC,
},
.cpu_rx = {
.offset = 13,
.count = 1,
.timeout = 0,
},
},

View File

@ -75,8 +75,8 @@ struct tegra_bpmp {
struct mbox_chan *channel;
} mbox;
struct tegra_bpmp_channel *channels;
unsigned int num_channels;
spinlock_t atomic_tx_lock;
struct tegra_bpmp_channel *tx_channel, *rx_channel, *threaded_channels;
struct {
unsigned long *allocated;