Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+68 -82
+66 -80
drivers/firmware/tegra/bpmp.c
··· 70 70 } 71 71 EXPORT_SYMBOL_GPL(tegra_bpmp_put); 72 72 73 - static int tegra_bpmp_channel_get_index(struct tegra_bpmp_channel *channel) 74 - { 75 - return channel - channel->bpmp->channels; 76 - } 77 - 78 73 static int 79 74 tegra_bpmp_channel_get_thread_index(struct tegra_bpmp_channel *channel) 80 75 { 81 76 struct tegra_bpmp *bpmp = channel->bpmp; 82 - unsigned int offset, count; 77 + unsigned int count; 83 78 int index; 84 79 85 - offset = bpmp->soc->channels.thread.offset; 86 80 count = bpmp->soc->channels.thread.count; 87 81 88 - index = tegra_bpmp_channel_get_index(channel); 89 - if (index < 0) 90 - return index; 91 - 92 - if (index < offset || index >= offset + count) 82 + index = channel - channel->bpmp->threaded_channels; 83 + if (index < 0 || index >= count) 93 84 return -EINVAL; 94 85 95 - return index - offset; 96 - } 97 - 98 - static struct tegra_bpmp_channel * 99 - tegra_bpmp_channel_get_thread(struct tegra_bpmp *bpmp, unsigned int index) 100 - { 101 - unsigned int offset = bpmp->soc->channels.thread.offset; 102 - unsigned int count = bpmp->soc->channels.thread.count; 103 - 104 - if (index >= count) 105 - return NULL; 106 - 107 - return &bpmp->channels[offset + index]; 108 - } 109 - 110 - static struct tegra_bpmp_channel * 111 - tegra_bpmp_channel_get_tx(struct tegra_bpmp *bpmp) 112 - { 113 - unsigned int offset = bpmp->soc->channels.cpu_tx.offset; 114 - 115 - return &bpmp->channels[offset + smp_processor_id()]; 116 - } 117 - 118 - static struct tegra_bpmp_channel * 119 - tegra_bpmp_channel_get_rx(struct tegra_bpmp *bpmp) 120 - { 121 - unsigned int offset = bpmp->soc->channels.cpu_rx.offset; 122 - 123 - return &bpmp->channels[offset]; 86 + return index; 124 87 } 125 88 126 89 static bool tegra_bpmp_message_valid(const struct tegra_bpmp_message *msg) ··· 234 271 goto unlock; 235 272 } 236 273 237 - channel = tegra_bpmp_channel_get_thread(bpmp, index); 238 - if (!channel) { 239 - err = -EINVAL; 240 - goto unlock; 241 - } 274 + channel = &bpmp->threaded_channels[index]; 242 275 243 276 if (!tegra_bpmp_master_free(channel)) { 244 277 err = -EBUSY; ··· 287 328 if (!tegra_bpmp_message_valid(msg)) 288 329 return -EINVAL; 289 330 290 - channel = tegra_bpmp_channel_get_tx(bpmp); 331 + channel = bpmp->tx_channel; 332 + 333 + spin_lock(&bpmp->atomic_tx_lock); 291 334 292 335 err = tegra_bpmp_channel_write(channel, msg->mrq, MSG_ACK, 293 336 msg->tx.data, msg->tx.size); 294 - if (err < 0) 337 + if (err < 0) { 338 + spin_unlock(&bpmp->atomic_tx_lock); 295 339 return err; 340 + } 341 + 342 + spin_unlock(&bpmp->atomic_tx_lock); 296 343 297 344 err = mbox_send_message(bpmp->mbox.channel, NULL); 298 345 if (err < 0) ··· 572 607 unsigned int i, count; 573 608 unsigned long *busy; 574 609 575 - channel = tegra_bpmp_channel_get_rx(bpmp); 610 + channel = bpmp->rx_channel; 576 611 count = bpmp->soc->channels.thread.count; 577 612 busy = bpmp->threaded.busy; 578 613 ··· 584 619 for_each_set_bit(i, busy, count) { 585 620 struct tegra_bpmp_channel *channel; 586 621 587 - channel = tegra_bpmp_channel_get_thread(bpmp, i); 588 - if (!channel) 589 - continue; 622 + channel = &bpmp->threaded_channels[i]; 590 623 591 624 if (tegra_bpmp_master_acked(channel)) { 592 625 tegra_bpmp_channel_signal(channel); ··· 661 698 662 699 static int tegra_bpmp_probe(struct platform_device *pdev) 663 700 { 664 - struct tegra_bpmp_channel *channel; 665 701 struct tegra_bpmp *bpmp; 666 702 unsigned int i; 667 703 char tag[32]; ··· 694 732 } 695 733 696 734 bpmp->rx.virt = gen_pool_dma_alloc(bpmp->rx.pool, 4096, &bpmp->rx.phys); 697 - if (!bpmp->rx.pool) { 735 + if (!bpmp->rx.virt) { 698 736 dev_err(&pdev->dev, "failed to allocate from RX pool\n"); 699 737 err = -ENOMEM; 700 738 goto free_tx; ··· 720 758 goto free_rx; 721 759 } 722 760 723 - bpmp->num_channels = bpmp->soc->channels.cpu_tx.count + 724 - bpmp->soc->channels.thread.count + 725 - bpmp->soc->channels.cpu_rx.count; 726 - 727 - bpmp->channels = devm_kcalloc(&pdev->dev, bpmp->num_channels, 728 - sizeof(*channel), GFP_KERNEL); 729 - if (!bpmp->channels) { 761 + spin_lock_init(&bpmp->atomic_tx_lock); 762 + bpmp->tx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->tx_channel), 763 + GFP_KERNEL); 764 + if (!bpmp->tx_channel) { 730 765 err = -ENOMEM; 731 766 goto free_rx; 732 767 } 733 768 734 - /* message channel initialization */ 735 - for (i = 0; i < bpmp->num_channels; i++) { 736 - struct tegra_bpmp_channel *channel = &bpmp->channels[i]; 769 + bpmp->rx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->rx_channel), 770 + GFP_KERNEL); 771 + if (!bpmp->rx_channel) { 772 + err = -ENOMEM; 773 + goto free_rx; 774 + } 737 775 738 - err = tegra_bpmp_channel_init(channel, bpmp, i); 776 + bpmp->threaded_channels = devm_kcalloc(&pdev->dev, bpmp->threaded.count, 777 + sizeof(*bpmp->threaded_channels), 778 + GFP_KERNEL); 779 + if (!bpmp->threaded_channels) { 780 + err = -ENOMEM; 781 + goto free_rx; 782 + } 783 + 784 + err = tegra_bpmp_channel_init(bpmp->tx_channel, bpmp, 785 + bpmp->soc->channels.cpu_tx.offset); 786 + if (err < 0) 787 + goto free_rx; 788 + 789 + err = tegra_bpmp_channel_init(bpmp->rx_channel, bpmp, 790 + bpmp->soc->channels.cpu_rx.offset); 791 + if (err < 0) 792 + goto cleanup_tx_channel; 793 + 794 + for (i = 0; i < bpmp->threaded.count; i++) { 795 + err = tegra_bpmp_channel_init( 796 + &bpmp->threaded_channels[i], bpmp, 797 + bpmp->soc->channels.thread.offset + i); 739 798 if (err < 0) 740 - goto cleanup_channels; 799 + goto cleanup_threaded_channels; 741 800 } 742 801 743 802 /* mbox registration */ ··· 771 788 if (IS_ERR(bpmp->mbox.channel)) { 772 789 err = PTR_ERR(bpmp->mbox.channel); 773 790 dev_err(&pdev->dev, "failed to get HSP mailbox: %d\n", err); 774 - goto cleanup_channels; 791 + goto cleanup_threaded_channels; 775 792 } 776 793 777 794 /* reset message channels */ 778 - for (i = 0; i < bpmp->num_channels; i++) { 779 - struct tegra_bpmp_channel *channel = &bpmp->channels[i]; 780 - 781 - tegra_bpmp_channel_reset(channel); 782 - } 795 + tegra_bpmp_channel_reset(bpmp->tx_channel); 796 + tegra_bpmp_channel_reset(bpmp->rx_channel); 797 + for (i = 0; i < bpmp->threaded.count; i++) 798 + tegra_bpmp_channel_reset(&bpmp->threaded_channels[i]); 783 799 784 800 err = tegra_bpmp_request_mrq(bpmp, MRQ_PING, 785 801 tegra_bpmp_mrq_handle_ping, bpmp); ··· 827 845 tegra_bpmp_free_mrq(bpmp, MRQ_PING, bpmp); 828 846 free_mbox: 829 847 mbox_free_channel(bpmp->mbox.channel); 830 - cleanup_channels: 831 - while (i--) 832 - tegra_bpmp_channel_cleanup(&bpmp->channels[i]); 848 + cleanup_threaded_channels: 849 + for (i = 0; i < bpmp->threaded.count; i++) { 850 + if (bpmp->threaded_channels[i].bpmp) 851 + tegra_bpmp_channel_cleanup(&bpmp->threaded_channels[i]); 852 + } 853 + 854 + tegra_bpmp_channel_cleanup(bpmp->rx_channel); 855 + cleanup_tx_channel: 856 + tegra_bpmp_channel_cleanup(bpmp->tx_channel); 833 857 free_rx: 834 858 gen_pool_free(bpmp->rx.pool, (unsigned long)bpmp->rx.virt, 4096); 835 859 free_tx: ··· 846 858 static const struct tegra_bpmp_soc tegra186_soc = { 847 859 .channels = { 848 860 .cpu_tx = { 849 - .offset = 0, 850 - .count = 6, 861 + .offset = 3, 851 862 .timeout = 60 * USEC_PER_SEC, 852 863 }, 853 864 .thread = { 854 - .offset = 6, 855 - .count = 7, 865 + .offset = 0, 866 + .count = 3, 856 867 .timeout = 600 * USEC_PER_SEC, 857 868 }, 858 869 .cpu_rx = { 859 870 .offset = 13, 860 - .count = 1, 861 871 .timeout = 0, 862 872 }, 863 873 },
+2 -2
include/soc/tegra/bpmp.h
··· 75 75 struct mbox_chan *channel; 76 76 } mbox; 77 77 78 - struct tegra_bpmp_channel *channels; 79 - unsigned int num_channels; 78 + spinlock_t atomic_tx_lock; 79 + struct tegra_bpmp_channel *tx_channel, *rx_channel, *threaded_channels; 80 80 81 81 struct { 82 82 unsigned long *allocated;