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:
Arnd Bergmann 2024-03-04 16:48:15 +01:00
commit 3326155e5b
11 changed files with 278 additions and 115 deletions

View File

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

View File

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

View File

@ -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);

View File

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

View File

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

View File

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

View File

@ -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[] = {

View File

@ -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);

View File

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

View File

@ -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)
{
}

View File

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