mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge remote-tracking branch 'sm8350/lineage-20' into lineage-22.2
* sm8350/lineage-20: ANDROID: fix wakeup reason findings Revert "genirq: Provide new interfaces for affinity hints" Revert "i40e: Use irq_update_affinity_hint()" Revert "i40e: fix IRQ freeing in i40e_vsi_request_irq_msix error path" Linux 5.4.300 mm/hugetlb: fix folio is still mapped when deleted i40e: add mask to apply valid bits for itr_idx i40e: fix validation of VF state in get resources i40e: fix idx validation in config queues msg i40e: add validation for ring_len param i40e: increase max descriptors for XL710 mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize() fbcon: Fix OOB access in font allocation fbcon: fix integer overflow in fbcon_do_set_font i40e: add max boundary check for VF filters i40e: fix input validation logic for action_meta i40e: fix idx validation in i40e_validate_queue_map drm/gma500: Fix null dereference in hdmi teardown can: peak_usb: fix shift-out-of-bounds issue can: mcba_usb: populate ndo_change_mtu() to prevent buffer overflow ... Change-Id: I35c2bd8174f8de67fbe46fb7fba584ee769722fa
This commit is contained in:
commit
cd41689b70
622 changed files with 45008 additions and 3929 deletions
|
|
@ -60,6 +60,7 @@ struct aspeed_lpc_snoop_model_data {
|
|||
};
|
||||
|
||||
struct aspeed_lpc_snoop_channel {
|
||||
bool enabled;
|
||||
struct kfifo fifo;
|
||||
wait_queue_head_t wq;
|
||||
struct miscdevice miscdev;
|
||||
|
|
@ -192,6 +193,9 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
|||
const struct aspeed_lpc_snoop_model_data *model_data =
|
||||
of_device_get_match_data(dev);
|
||||
|
||||
if (WARN_ON(lpc_snoop->chan[channel].enabled))
|
||||
return -EBUSY;
|
||||
|
||||
init_waitqueue_head(&lpc_snoop->chan[channel].wq);
|
||||
/* Create FIFO datastructure */
|
||||
rc = kfifo_alloc(&lpc_snoop->chan[channel].fifo,
|
||||
|
|
@ -238,6 +242,8 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
|||
regmap_update_bits(lpc_snoop->regmap, HICRB,
|
||||
hicrb_en, hicrb_en);
|
||||
|
||||
lpc_snoop->chan[channel].enabled = true;
|
||||
|
||||
return 0;
|
||||
|
||||
err_misc_deregister:
|
||||
|
|
@ -250,6 +256,9 @@ err_free_fifo:
|
|||
static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
||||
int channel)
|
||||
{
|
||||
if (!lpc_snoop->chan[channel].enabled)
|
||||
return;
|
||||
|
||||
switch (channel) {
|
||||
case 0:
|
||||
regmap_update_bits(lpc_snoop->regmap, HICR5,
|
||||
|
|
@ -265,8 +274,10 @@ static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
|||
return;
|
||||
}
|
||||
|
||||
kfifo_free(&lpc_snoop->chan[channel].fifo);
|
||||
lpc_snoop->chan[channel].enabled = false;
|
||||
/* Consider improving safety wrt concurrent reader(s) */
|
||||
misc_deregister(&lpc_snoop->chan[channel].miscdev);
|
||||
kfifo_free(&lpc_snoop->chan[channel].fifo);
|
||||
}
|
||||
|
||||
static int aspeed_lpc_snoop_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -12,11 +12,45 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
|
||||
static bool mdt_header_valid(const struct firmware *fw)
|
||||
{
|
||||
const struct elf32_hdr *ehdr;
|
||||
size_t phend;
|
||||
size_t shend;
|
||||
|
||||
if (fw->size < sizeof(*ehdr))
|
||||
return false;
|
||||
|
||||
ehdr = (struct elf32_hdr *)fw->data;
|
||||
|
||||
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG))
|
||||
return false;
|
||||
|
||||
if (ehdr->e_phentsize != sizeof(struct elf32_phdr))
|
||||
return false;
|
||||
|
||||
phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff);
|
||||
if (phend > fw->size)
|
||||
return false;
|
||||
|
||||
if (ehdr->e_shentsize || ehdr->e_shnum) {
|
||||
if (ehdr->e_shentsize != sizeof(struct elf32_shdr))
|
||||
return false;
|
||||
|
||||
shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff);
|
||||
if (shend > fw->size)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mdt_phdr_valid(const struct elf32_phdr *phdr)
|
||||
{
|
||||
if (phdr->p_type != PT_LOAD)
|
||||
|
|
@ -66,6 +100,9 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
|
|||
phys_addr_t max_addr = 0;
|
||||
int i;
|
||||
|
||||
if (!mdt_header_valid(fw))
|
||||
return -EINVAL;
|
||||
|
||||
ehdr = (struct elf32_hdr *)fw->data;
|
||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
||||
|
||||
|
|
@ -121,6 +158,9 @@ void *qcom_mdt_read_metadata(struct device *dev, const struct firmware *fw, cons
|
|||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (!mdt_header_valid(fw))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ehdr = (struct elf32_hdr *)fw->data;
|
||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
||||
|
||||
|
|
@ -206,6 +246,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
|||
if (!fw || !mem_region || !mem_phys || !mem_size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!mdt_header_valid(fw))
|
||||
return -EINVAL;
|
||||
|
||||
is_split = qcom_mdt_bins_are_split(fw);
|
||||
ehdr = (struct elf32_hdr *)fw->data;
|
||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
||||
|
|
|
|||
|
|
@ -950,7 +950,7 @@ err:
|
|||
}
|
||||
|
||||
static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
|
||||
struct device_node *np, bool off)
|
||||
struct device_node *np)
|
||||
{
|
||||
struct device *dev = pg->pmc->dev;
|
||||
int err;
|
||||
|
|
@ -965,22 +965,6 @@ static int tegra_powergate_of_get_resets(struct tegra_powergate *pg,
|
|||
err = reset_control_acquire(pg->reset);
|
||||
if (err < 0) {
|
||||
pr_err("failed to acquire resets: %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (off) {
|
||||
err = reset_control_assert(pg->reset);
|
||||
} else {
|
||||
err = reset_control_deassert(pg->reset);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
reset_control_release(pg->reset);
|
||||
}
|
||||
|
||||
out:
|
||||
if (err) {
|
||||
reset_control_release(pg->reset);
|
||||
reset_control_put(pg->reset);
|
||||
}
|
||||
|
||||
|
|
@ -1025,20 +1009,43 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
|
|||
goto set_available;
|
||||
}
|
||||
|
||||
err = tegra_powergate_of_get_resets(pg, np, off);
|
||||
err = tegra_powergate_of_get_resets(pg, np);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "failed to get resets for %pOFn: %d\n", np, err);
|
||||
goto remove_clks;
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
|
||||
if (off)
|
||||
WARN_ON(tegra_powergate_power_up(pg, true));
|
||||
/*
|
||||
* If the power-domain is off, then ensure the resets are asserted.
|
||||
* If the power-domain is on, then power down to ensure that when is
|
||||
* it turned on the power-domain, clocks and resets are all in the
|
||||
* expected state.
|
||||
*/
|
||||
if (off) {
|
||||
err = reset_control_assert(pg->reset);
|
||||
if (err) {
|
||||
pr_err("failed to assert resets: %d\n", err);
|
||||
goto remove_resets;
|
||||
}
|
||||
} else {
|
||||
err = tegra_powergate_power_down(pg);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to turn off PM domain %s: %d\n",
|
||||
pg->genpd.name, err);
|
||||
goto remove_resets;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If PM_GENERIC_DOMAINS is not enabled, power-on
|
||||
* the domain and skip the genpd registration.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
|
||||
WARN_ON(tegra_powergate_power_up(pg, true));
|
||||
goto remove_resets;
|
||||
}
|
||||
|
||||
err = pm_genpd_init(&pg->genpd, NULL, off);
|
||||
err = pm_genpd_init(&pg->genpd, NULL, true);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "failed to initialise PM domain %pOFn: %d\n", np,
|
||||
err);
|
||||
|
|
|
|||
Loading…
Reference in a new issue