mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 03:06:43 +00:00
soc/tegra: Changes for v6.9-rc1
This set of changes adds ACPI support for the APBMISC driver and cleans up a few things like dependencies and unused code. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmXY1VEACgkQ3SOs138+ s6HqkA//ZtHaCTLiQQI97Go9dd0OnFIhQi1fnp1jwzexTWe5mT6RDJaSH/k+H/8c wZiSGuZrgedKKAHX4luYJNPrZNIU3u5pEAe/H78N+c29mcS2Ynv0M++Kc3vKn1DW yfRv6vXge6UaFZsS8zvrsb9F8q5yAouhAW3BosOwYwv41Z6KoqOBzIAnGzSSgfLl fBErk8IutUscTeQHj9UNxeRZeYmr1M5nin4LwrQ9cZWASN0OBFXL+PpGatlY701z 5uCIJb4obz0z4NV27JxdrX12Z3ej+dd0NE3swwKGGi02ROCMlcQO8Zc9/+seSZGe M9q6CWzelvJYVEFISGidx0N0l/eexJQac7koDNHJVvqVlVYYpBtY5RG5dsVofXTk gNc+T0bI/D4h5kHbCFNPhwrwEp2rvkWufh7zgBLlBamjoc/VAkpxSXgJal7Wc6HS YG0WziUARNsFHdff5s1g3ayh3ssnAT3m/1SNjMo5cqrv421tiy2gwsuL/LbxeBDY RQ3dUfsVGmsCJUvbiJIetJUBX5VnVDkwIVBSd97i7yez4e3dBKhb1sAP1wWYcFKw CcfWHPW9XNypDo66vmXtEGXtsero10/d9BhmUjrAQ8iY9/kgCpsyEnL5oYMP8sEM UwZ6tPoAyPZQcqQpTwjPHwjYtXcXamUKrjx8zIeR7bLa6JYfd+Q= =8s0Z -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmXl7UkACgkQYKtH/8kJ UifTQxAAqGsI+jW/1MFAokcJ3qOSZddlVl/5E6W1Ds6+okP6HnMN9lrVAuHkbiqc j2fGRp3b6J0uqNjCKGa1FM+5jnY7C/ym73b43BGm4I5bEhuhE0CseOs3iCtNZa4Y r2MQa9Ink0H2JDP4MrACTt7ig0mvmQy8favE9ETMc75AxuQSWyxCG/ApgsXTI7Lx mcGO8s5aggpBksuAZPzSGf2tbxmF1lQemjg69ciRGtGFR7EQ2bIdyrZoH+AzQnje tgxzk8sPJhqq0wbqbtrrIHbKLzmSH5R+0wXEUdRSvdinbL5VHKWkWOpeGS2ca0k1 umZ/hAQWWVNmZylsEBpF4W3yX13SivpTfUPkmVdNKQfEnTez2GiDYZyOEWVuvbFj WhNxu2YTY44X4N8bY4lpJ7x9YCAUJm2Z8cuZ0m0lD22fM64rJQaG7dsGhAy9MK5M jO6S0xmNfehC8v5gn2RBNCikVpp25W1IzhTpfWPjLJi4pYSeM+wRwWsgGbX6QrfI me6WrRGVwgCFTbmyUgH/d3wgSLHf5J7hP2+NZ4VBjRhGc3ltwzo99crypQFpUlhY D39wYI3jb+16cLLfryRP4LEik1WND+0h5JrYMMG2x3lswzRVv66A+v/00LAiOSQj 2DFxP0NS8Ig/AgkPR5g5KLBtCn7GvjrYm9+qFmCToZOcRbIqINA= =j1US -----END PGP SIGNATURE----- Merge tag 'tegra-for-6.9-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/drivers soc/tegra: Changes for v6.9-rc1 This set of changes adds ACPI support for the APBMISC driver and cleans up a few things like dependencies and unused code. * tag 'tegra-for-6.9-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: soc/tegra: pmc: Add SD wake event for Tegra234 soc/tegra: pmc: Update scratch as an optional aperture soc/tegra: pmc: Update address mapping sequence for PMC apertures bus: tegra-aconnect: Update dependency to ARCH_TEGRA soc/tegra: Fix build failure on Tegra241 soc/tegra: fuse: Fix crash in tegra_fuse_readl() soc/tegra: fuse: Define tegra194_soc_attr_group for Tegra241 soc/tegra: fuse: Add support for Tegra241 soc/tegra: fuse: Add ACPI support for Tegra194 and Tegra234 soc/tegra: fuse: Add function to print SKU info soc/tegra: fuse: Add function to add lookups soc/tegra: fuse: Add tegra_acpi_init_apbmisc() soc/tegra: fuse: Refactor resource mapping soc/tegra: fuse: Use dev_err_probe for probe failures mm/util: Introduce kmemdup_array() soc/tegra: pmc: Remove some old and deprecated functions and constants Link: https://lore.kernel.org/r/20240223174849.1509465-1-thierry.reding@gmail.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
3326155e5b
@ -186,11 +186,12 @@ config SUNXI_RSB
|
||||
|
||||
config TEGRA_ACONNECT
|
||||
tristate "Tegra ACONNECT Bus Driver"
|
||||
depends on ARCH_TEGRA_210_SOC
|
||||
depends on ARCH_TEGRA
|
||||
depends on OF && PM
|
||||
help
|
||||
Driver for the Tegra ACONNECT bus which is used to interface with
|
||||
the devices inside the Audio Processing Engine (APE) for Tegra210.
|
||||
the devices inside the Audio Processing Engine (APE) for
|
||||
Tegra210 and later.
|
||||
|
||||
config TEGRA_GMI
|
||||
tristate "Tegra Generic Memory Interface bus driver"
|
||||
|
@ -133,6 +133,11 @@ config ARCH_TEGRA_234_SOC
|
||||
help
|
||||
Enable support for the NVIDIA Tegra234 SoC.
|
||||
|
||||
config ARCH_TEGRA_241_SOC
|
||||
bool "NVIDIA Tegra241 SoC"
|
||||
help
|
||||
Enable support for the NVIDIA Tegra241 SoC.
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -3,11 +3,13 @@
|
||||
* Copyright (c) 2013-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
@ -113,6 +115,28 @@ static void tegra_fuse_restore(void *base)
|
||||
fuse->clk = NULL;
|
||||
}
|
||||
|
||||
static void tegra_fuse_print_sku_info(struct tegra_sku_info *tegra_sku_info)
|
||||
{
|
||||
pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n",
|
||||
tegra_revision_name[tegra_sku_info->revision],
|
||||
tegra_sku_info->sku_id, tegra_sku_info->cpu_process_id,
|
||||
tegra_sku_info->soc_process_id);
|
||||
pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
|
||||
tegra_sku_info->cpu_speedo_id, tegra_sku_info->soc_speedo_id);
|
||||
}
|
||||
|
||||
static int tegra_fuse_add_lookups(struct tegra_fuse *fuse)
|
||||
{
|
||||
fuse->lookups = kmemdup_array(fuse->soc->lookups, sizeof(*fuse->lookups),
|
||||
fuse->soc->num_lookups, GFP_KERNEL);
|
||||
if (!fuse->lookups)
|
||||
return -ENOMEM;
|
||||
|
||||
nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_fuse_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *base = fuse->base;
|
||||
@ -130,15 +154,46 @@ static int tegra_fuse_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(fuse->base);
|
||||
fuse->phys = res->start;
|
||||
|
||||
fuse->clk = devm_clk_get(&pdev->dev, "fuse");
|
||||
if (IS_ERR(fuse->clk)) {
|
||||
if (PTR_ERR(fuse->clk) != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
|
||||
PTR_ERR(fuse->clk));
|
||||
/* Initialize the soc data and lookups if using ACPI boot. */
|
||||
if (is_acpi_node(dev_fwnode(&pdev->dev)) && !fuse->soc) {
|
||||
u8 chip;
|
||||
|
||||
return PTR_ERR(fuse->clk);
|
||||
tegra_acpi_init_apbmisc();
|
||||
|
||||
chip = tegra_get_chip_id();
|
||||
switch (chip) {
|
||||
#if defined(CONFIG_ARCH_TEGRA_194_SOC)
|
||||
case TEGRA194:
|
||||
fuse->soc = &tegra194_fuse_soc;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_TEGRA_234_SOC)
|
||||
case TEGRA234:
|
||||
fuse->soc = &tegra234_fuse_soc;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_TEGRA_241_SOC)
|
||||
case TEGRA241:
|
||||
fuse->soc = &tegra241_fuse_soc;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip);
|
||||
}
|
||||
|
||||
fuse->soc->init(fuse);
|
||||
tegra_fuse_print_sku_info(&tegra_sku_info);
|
||||
tegra_soc_device_register();
|
||||
|
||||
err = tegra_fuse_add_lookups(fuse);
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err, "failed to add FUSE lookups\n");
|
||||
}
|
||||
|
||||
fuse->clk = devm_clk_get_optional(&pdev->dev, "fuse");
|
||||
if (IS_ERR(fuse->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(fuse->clk), "failed to get FUSE clock\n");
|
||||
|
||||
platform_set_drvdata(pdev, fuse);
|
||||
fuse->dev = &pdev->dev;
|
||||
|
||||
@ -179,12 +234,8 @@ static int tegra_fuse_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse");
|
||||
if (IS_ERR(fuse->rst)) {
|
||||
err = PTR_ERR(fuse->rst);
|
||||
dev_err(&pdev->dev, "failed to get FUSE reset: %pe\n",
|
||||
fuse->rst);
|
||||
return err;
|
||||
}
|
||||
if (IS_ERR(fuse->rst))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(fuse->rst), "failed to get FUSE reset\n");
|
||||
|
||||
/*
|
||||
* FUSE clock is enabled at a boot time, hence this resume/suspend
|
||||
@ -262,10 +313,17 @@ static const struct dev_pm_ops tegra_fuse_pm = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume)
|
||||
};
|
||||
|
||||
static const struct acpi_device_id tegra_fuse_acpi_match[] = {
|
||||
{ "NVDA200F" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, tegra_fuse_acpi_match);
|
||||
|
||||
static struct platform_driver tegra_fuse_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-fuse",
|
||||
.of_match_table = tegra_fuse_match,
|
||||
.acpi_match_table = tegra_fuse_acpi_match,
|
||||
.pm = &tegra_fuse_pm,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
@ -287,7 +345,16 @@ u32 __init tegra_fuse_read_early(unsigned int offset)
|
||||
|
||||
int tegra_fuse_readl(unsigned long offset, u32 *value)
|
||||
{
|
||||
if (!fuse->read || !fuse->clk)
|
||||
if (!fuse->dev)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
/*
|
||||
* Wait for fuse->clk to be initialized if device-tree boot is used.
|
||||
*/
|
||||
if (is_of_node(dev_fwnode(fuse->dev)) && !fuse->clk)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (!fuse->read)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (IS_ERR(fuse->clk))
|
||||
@ -343,7 +410,8 @@ const struct attribute_group tegra_soc_attr_group = {
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC)
|
||||
static ssize_t platform_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@ -370,7 +438,7 @@ const struct attribute_group tegra194_soc_attr_group = {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct device * __init tegra_soc_device_register(void)
|
||||
struct device *tegra_soc_device_register(void)
|
||||
{
|
||||
struct soc_device_attribute *attr;
|
||||
struct soc_device *dev;
|
||||
@ -407,6 +475,7 @@ static int __init tegra_init_fuse(void)
|
||||
const struct of_device_id *match;
|
||||
struct device_node *np;
|
||||
struct resource regs;
|
||||
int err;
|
||||
|
||||
tegra_init_apbmisc();
|
||||
|
||||
@ -497,22 +566,13 @@ static int __init tegra_init_fuse(void)
|
||||
|
||||
fuse->soc->init(fuse);
|
||||
|
||||
pr_info("Tegra Revision: %s SKU: %d CPU Process: %d SoC Process: %d\n",
|
||||
tegra_revision_name[tegra_sku_info.revision],
|
||||
tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id,
|
||||
tegra_sku_info.soc_process_id);
|
||||
pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
|
||||
tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
|
||||
tegra_fuse_print_sku_info(&tegra_sku_info);
|
||||
|
||||
if (fuse->soc->lookups) {
|
||||
size_t size = sizeof(*fuse->lookups) * fuse->soc->num_lookups;
|
||||
err = tegra_fuse_add_lookups(fuse);
|
||||
if (err)
|
||||
pr_err("failed to add FUSE lookups\n");
|
||||
|
||||
fuse->lookups = kmemdup(fuse->soc->lookups, size, GFP_KERNEL);
|
||||
if (fuse->lookups)
|
||||
nvmem_add_cell_lookups(fuse->lookups, fuse->soc->num_lookups);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
early_initcall(tegra_init_fuse);
|
||||
|
||||
|
@ -38,7 +38,8 @@
|
||||
defined(CONFIG_ARCH_TEGRA_210_SOC) || \
|
||||
defined(CONFIG_ARCH_TEGRA_186_SOC) || \
|
||||
defined(CONFIG_ARCH_TEGRA_194_SOC) || \
|
||||
defined(CONFIG_ARCH_TEGRA_234_SOC)
|
||||
defined(CONFIG_ARCH_TEGRA_234_SOC) || \
|
||||
defined(CONFIG_ARCH_TEGRA_241_SOC)
|
||||
static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset)
|
||||
{
|
||||
if (WARN_ON(!fuse->base))
|
||||
@ -678,3 +679,23 @@ const struct tegra_fuse_soc tegra234_fuse_soc = {
|
||||
.clk_suspend_on = false,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_TEGRA_241_SOC)
|
||||
static const struct tegra_fuse_info tegra241_fuse_info = {
|
||||
.read = tegra30_fuse_read,
|
||||
.size = 0x16008,
|
||||
.spare = 0xcf0,
|
||||
};
|
||||
|
||||
static const struct nvmem_keepout tegra241_fuse_keepouts[] = {
|
||||
{ .start = 0xc, .end = 0x1600c }
|
||||
};
|
||||
|
||||
const struct tegra_fuse_soc tegra241_fuse_soc = {
|
||||
.init = tegra30_fuse_init,
|
||||
.info = &tegra241_fuse_info,
|
||||
.keepouts = tegra241_fuse_keepouts,
|
||||
.num_keepouts = ARRAY_SIZE(tegra241_fuse_keepouts),
|
||||
.soc_attr_group = &tegra194_soc_attr_group,
|
||||
};
|
||||
#endif
|
||||
|
@ -69,6 +69,7 @@ struct tegra_fuse {
|
||||
|
||||
void tegra_init_revision(void);
|
||||
void tegra_init_apbmisc(void);
|
||||
void tegra_acpi_init_apbmisc(void);
|
||||
|
||||
u32 __init tegra_fuse_read_spare(unsigned int spare);
|
||||
u32 __init tegra_fuse_read_early(unsigned int offset);
|
||||
@ -123,7 +124,8 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
|
||||
IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC)
|
||||
extern const struct attribute_group tegra194_soc_attr_group;
|
||||
#endif
|
||||
|
||||
@ -135,4 +137,8 @@ extern const struct tegra_fuse_soc tegra194_fuse_soc;
|
||||
extern const struct tegra_fuse_soc tegra234_fuse_soc;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_241_SOC
|
||||
extern const struct tegra_fuse_soc tegra241_fuse_soc;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -3,9 +3,11 @@
|
||||
* Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
@ -62,6 +64,7 @@ bool tegra_is_silicon(void)
|
||||
switch (tegra_get_chip_id()) {
|
||||
case TEGRA194:
|
||||
case TEGRA234:
|
||||
case TEGRA241:
|
||||
case TEGRA264:
|
||||
if (tegra_get_platform() == 0)
|
||||
return true;
|
||||
@ -160,9 +163,34 @@ void __init tegra_init_revision(void)
|
||||
tegra_sku_info.platform = tegra_get_platform();
|
||||
}
|
||||
|
||||
void __init tegra_init_apbmisc(void)
|
||||
static void tegra_init_apbmisc_resources(struct resource *apbmisc,
|
||||
struct resource *straps)
|
||||
{
|
||||
void __iomem *strapping_base;
|
||||
|
||||
apbmisc_base = ioremap(apbmisc->start, resource_size(apbmisc));
|
||||
if (apbmisc_base)
|
||||
chipid = readl_relaxed(apbmisc_base + 4);
|
||||
else
|
||||
pr_err("failed to map APBMISC registers\n");
|
||||
|
||||
strapping_base = ioremap(straps->start, resource_size(straps));
|
||||
if (strapping_base) {
|
||||
strapping = readl_relaxed(strapping_base);
|
||||
iounmap(strapping_base);
|
||||
} else {
|
||||
pr_err("failed to map strapping options registers\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_init_apbmisc - Initializes Tegra APBMISC and Strapping registers.
|
||||
*
|
||||
* This is called during early init as some of the old 32-bit ARM code needs
|
||||
* information from the APBMISC registers very early during boot.
|
||||
*/
|
||||
void __init tegra_init_apbmisc(void)
|
||||
{
|
||||
struct resource apbmisc, straps;
|
||||
struct device_node *np;
|
||||
|
||||
@ -219,23 +247,73 @@ void __init tegra_init_apbmisc(void)
|
||||
}
|
||||
}
|
||||
|
||||
apbmisc_base = ioremap(apbmisc.start, resource_size(&apbmisc));
|
||||
if (!apbmisc_base) {
|
||||
pr_err("failed to map APBMISC registers\n");
|
||||
} else {
|
||||
chipid = readl_relaxed(apbmisc_base + 4);
|
||||
}
|
||||
|
||||
strapping_base = ioremap(straps.start, resource_size(&straps));
|
||||
if (!strapping_base) {
|
||||
pr_err("failed to map strapping options registers\n");
|
||||
} else {
|
||||
strapping = readl_relaxed(strapping_base);
|
||||
iounmap(strapping_base);
|
||||
}
|
||||
|
||||
tegra_init_apbmisc_resources(&apbmisc, &straps);
|
||||
long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code");
|
||||
|
||||
put:
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id apbmisc_acpi_match[] = {
|
||||
{ "NVDA2010" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
void tegra_acpi_init_apbmisc(void)
|
||||
{
|
||||
struct resource *resources[2] = { NULL };
|
||||
struct resource_entry *rentry;
|
||||
struct acpi_device *adev = NULL;
|
||||
struct list_head resource_list;
|
||||
int rcount = 0;
|
||||
int ret;
|
||||
|
||||
adev = acpi_dev_get_first_match_dev(apbmisc_acpi_match[0].id, NULL, -1);
|
||||
if (!adev)
|
||||
return;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
|
||||
ret = acpi_dev_get_memory_resources(adev, &resource_list);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to get APBMISC memory resources");
|
||||
goto out_put_acpi_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get required memory resources.
|
||||
*
|
||||
* resources[0]: apbmisc.
|
||||
* resources[1]: straps.
|
||||
*/
|
||||
resource_list_for_each_entry(rentry, &resource_list) {
|
||||
if (rcount >= ARRAY_SIZE(resources))
|
||||
break;
|
||||
|
||||
resources[rcount++] = rentry->res;
|
||||
}
|
||||
|
||||
if (!resources[0]) {
|
||||
pr_err("failed to get APBMISC registers\n");
|
||||
goto out_free_resource_list;
|
||||
}
|
||||
|
||||
if (!resources[1]) {
|
||||
pr_err("failed to get strapping options registers\n");
|
||||
goto out_free_resource_list;
|
||||
}
|
||||
|
||||
tegra_init_apbmisc_resources(resources[0], resources[1]);
|
||||
|
||||
out_free_resource_list:
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
out_put_acpi_dev:
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
#else
|
||||
void tegra_acpi_init_apbmisc(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
* drivers/soc/tegra/pmc.c
|
||||
*
|
||||
* Copyright (c) 2010 Google, Inc
|
||||
* Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@google.com>
|
||||
@ -384,6 +384,7 @@ struct tegra_pmc_soc {
|
||||
bool has_blink_output;
|
||||
bool has_usb_sleepwalk;
|
||||
bool supports_core_domain;
|
||||
bool has_single_mmio_aperture;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1777,30 +1778,6 @@ static int tegra_io_pad_get_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id)
|
||||
return TEGRA_IO_PAD_VOLTAGE_3V3;
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_io_rail_power_on() - enable power to I/O rail
|
||||
* @id: Tegra I/O pad ID for which to enable power
|
||||
*
|
||||
* See also: tegra_io_pad_power_enable()
|
||||
*/
|
||||
int tegra_io_rail_power_on(unsigned int id)
|
||||
{
|
||||
return tegra_io_pad_power_enable(id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_io_rail_power_on);
|
||||
|
||||
/**
|
||||
* tegra_io_rail_power_off() - disable power to I/O rail
|
||||
* @id: Tegra I/O pad ID for which to disable power
|
||||
*
|
||||
* See also: tegra_io_pad_power_disable()
|
||||
*/
|
||||
int tegra_io_rail_power_off(unsigned int id)
|
||||
{
|
||||
return tegra_io_pad_power_disable(id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_io_rail_power_off);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
|
||||
{
|
||||
@ -2909,31 +2886,33 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wake");
|
||||
if (res) {
|
||||
if (pmc->soc->has_single_mmio_aperture) {
|
||||
pmc->wake = base;
|
||||
pmc->aotag = base;
|
||||
pmc->scratch = base;
|
||||
} else {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"wake");
|
||||
pmc->wake = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(pmc->wake))
|
||||
return PTR_ERR(pmc->wake);
|
||||
} else {
|
||||
pmc->wake = base;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aotag");
|
||||
if (res) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"aotag");
|
||||
pmc->aotag = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(pmc->aotag))
|
||||
return PTR_ERR(pmc->aotag);
|
||||
} else {
|
||||
pmc->aotag = base;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "scratch");
|
||||
if (res) {
|
||||
pmc->scratch = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(pmc->scratch))
|
||||
return PTR_ERR(pmc->scratch);
|
||||
} else {
|
||||
pmc->scratch = base;
|
||||
/* "scratch" is an optional aperture */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"scratch");
|
||||
if (res) {
|
||||
pmc->scratch = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(pmc->scratch))
|
||||
return PTR_ERR(pmc->scratch);
|
||||
} else {
|
||||
pmc->scratch = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pmc->clk = devm_clk_get_optional(&pdev->dev, "pclk");
|
||||
@ -2945,12 +2924,15 @@ static int tegra_pmc_probe(struct platform_device *pdev)
|
||||
* PMC should be last resort for restarting since it soft-resets
|
||||
* CPU without resetting everything else.
|
||||
*/
|
||||
err = devm_register_reboot_notifier(&pdev->dev,
|
||||
&tegra_pmc_reboot_notifier);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "unable to register reboot notifier, %d\n",
|
||||
err);
|
||||
return err;
|
||||
if (pmc->scratch) {
|
||||
err = devm_register_reboot_notifier(&pdev->dev,
|
||||
&tegra_pmc_reboot_notifier);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"unable to register reboot notifier, %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = devm_register_sys_off_handler(&pdev->dev,
|
||||
@ -3324,6 +3306,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
};
|
||||
|
||||
static const char * const tegra30_powergates[] = {
|
||||
@ -3385,6 +3368,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
};
|
||||
|
||||
static const char * const tegra114_powergates[] = {
|
||||
@ -3442,6 +3426,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
};
|
||||
|
||||
static const char * const tegra124_powergates[] = {
|
||||
@ -3586,6 +3571,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
};
|
||||
|
||||
static const char * const tegra210_powergates[] = {
|
||||
@ -3749,6 +3735,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
|
||||
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
|
||||
.has_blink_output = true,
|
||||
.has_usb_sleepwalk = true,
|
||||
.has_single_mmio_aperture = true,
|
||||
};
|
||||
|
||||
static const struct tegra_io_pad_soc tegra186_io_pads[] = {
|
||||
@ -3946,6 +3933,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = false,
|
||||
.has_usb_sleepwalk = false,
|
||||
.has_single_mmio_aperture = false,
|
||||
};
|
||||
|
||||
static const struct tegra_io_pad_soc tegra194_io_pads[] = {
|
||||
@ -4131,6 +4119,7 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = false,
|
||||
.has_usb_sleepwalk = false,
|
||||
.has_single_mmio_aperture = false,
|
||||
};
|
||||
|
||||
static const struct tegra_io_pad_soc tegra234_io_pads[] = {
|
||||
@ -4220,6 +4209,7 @@ static const char * const tegra234_reset_sources[] = {
|
||||
};
|
||||
|
||||
static const struct tegra_wake_event tegra234_wake_events[] = {
|
||||
TEGRA_WAKE_GPIO("sd-wake", 8, 0, TEGRA234_MAIN_GPIO(G, 7)),
|
||||
TEGRA_WAKE_IRQ("pmu", 24, 209),
|
||||
TEGRA_WAKE_GPIO("power", 29, 1, TEGRA234_AON_GPIO(EE, 4)),
|
||||
TEGRA_WAKE_GPIO("mgbe", 56, 0, TEGRA234_MAIN_GPIO(Y, 3)),
|
||||
@ -4259,6 +4249,7 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
|
||||
.pmc_clks_data = NULL,
|
||||
.num_pmc_clks = 0,
|
||||
.has_blink_output = false,
|
||||
.has_single_mmio_aperture = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_pmc_match[] = {
|
||||
|
@ -217,6 +217,7 @@ extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
|
||||
extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
|
||||
extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
|
||||
extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
|
||||
extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp);
|
||||
|
||||
extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
|
||||
extern void argv_free(char **argv);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define TEGRA186 0x18
|
||||
#define TEGRA194 0x19
|
||||
#define TEGRA234 0x23
|
||||
#define TEGRA241 0x24
|
||||
#define TEGRA264 0x26
|
||||
|
||||
#define TEGRA_FUSE_SKU_CALIB_0 0xf0
|
||||
|
@ -148,10 +148,6 @@ enum tegra_io_pad {
|
||||
TEGRA_IO_PAD_AO_HV,
|
||||
};
|
||||
|
||||
/* deprecated, use TEGRA_IO_PAD_{HDMI,LVDS} instead */
|
||||
#define TEGRA_IO_RAIL_HDMI TEGRA_IO_PAD_HDMI
|
||||
#define TEGRA_IO_RAIL_LVDS TEGRA_IO_PAD_LVDS
|
||||
|
||||
#ifdef CONFIG_SOC_TEGRA_PMC
|
||||
int tegra_powergate_power_on(unsigned int id);
|
||||
int tegra_powergate_power_off(unsigned int id);
|
||||
@ -164,10 +160,6 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
||||
int tegra_io_pad_power_enable(enum tegra_io_pad id);
|
||||
int tegra_io_pad_power_disable(enum tegra_io_pad id);
|
||||
|
||||
/* deprecated, use tegra_io_pad_power_{enable,disable}() instead */
|
||||
int tegra_io_rail_power_on(unsigned int id);
|
||||
int tegra_io_rail_power_off(unsigned int id);
|
||||
|
||||
void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
|
||||
void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode);
|
||||
|
||||
@ -211,16 +203,6 @@ static inline int tegra_io_pad_get_voltage(enum tegra_io_pad id)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int tegra_io_rail_power_on(unsigned int id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int tegra_io_rail_power_off(unsigned int id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode)
|
||||
{
|
||||
}
|
||||
|
17
mm/util.c
17
mm/util.c
@ -135,6 +135,23 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
|
||||
}
|
||||
EXPORT_SYMBOL(kmemdup);
|
||||
|
||||
/**
|
||||
* kmemdup_array - duplicate a given array.
|
||||
*
|
||||
* @src: array to duplicate.
|
||||
* @element_size: size of each element of array.
|
||||
* @count: number of elements to duplicate from array.
|
||||
* @gfp: GFP mask to use.
|
||||
*
|
||||
* Return: duplicated array of @src or %NULL in case of error,
|
||||
* result is physically contiguous. Use kfree() to free.
|
||||
*/
|
||||
void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp)
|
||||
{
|
||||
return kmemdup(src, size_mul(element_size, count), gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(kmemdup_array);
|
||||
|
||||
/**
|
||||
* kvmemdup - duplicate region of memory
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user