aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/power/pd-samsung.txt20
-rw-r--r--Documentation/devicetree/bindings/soc/rockchip/power_domain.txt12
-rw-r--r--drivers/bus/Kconfig1
-rw-r--r--drivers/bus/arm-cci.c2
-rw-r--r--drivers/bus/hisi_lpc.c159
-rw-r--r--drivers/cpufreq/scmi-cpufreq.c4
-rw-r--r--drivers/firmware/arm_scmi/base.c43
-rw-r--r--drivers/firmware/arm_scmi/bus.c22
-rw-r--r--drivers/firmware/arm_scmi/clock.c24
-rw-r--r--drivers/firmware/arm_scmi/common.h22
-rw-r--r--drivers/firmware/arm_scmi/driver.c109
-rw-r--r--drivers/firmware/arm_scmi/perf.c38
-rw-r--r--drivers/firmware/arm_scmi/power.c16
-rw-r--r--drivers/firmware/arm_scmi/sensors.c20
-rw-r--r--drivers/firmware/ti_sci.c10
-rw-r--r--drivers/firmware/ti_sci.h30
-rw-r--r--drivers/memory/Kconfig10
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/brcmstb_dpfe.c42
-rw-r--r--drivers/memory/omap-gpmc.c4
-rw-r--r--drivers/memory/tegra/Makefile1
-rw-r--r--drivers/memory/tegra/mc.c362
-rw-r--r--drivers/memory/tegra/mc.h22
-rw-r--r--drivers/memory/tegra/tegra114.c33
-rw-r--r--drivers/memory/tegra/tegra124.c48
-rw-r--r--drivers/memory/tegra/tegra20.c296
-rw-r--r--drivers/memory/tegra/tegra210.c53
-rw-r--r--drivers/memory/tegra/tegra30.c35
-rw-r--r--drivers/memory/tegra20-mc.c254
-rw-r--r--drivers/memory/ti-aemif.c60
-rw-r--r--drivers/reset/reset-uniphier.c13
-rw-r--r--drivers/soc/imx/gpc.c18
-rw-r--r--drivers/soc/imx/gpcv2.c22
-rw-r--r--drivers/soc/mediatek/mtk-infracfg.c46
-rw-r--r--drivers/soc/mediatek/mtk-pmic-wrap.c13
-rw-r--r--drivers/soc/mediatek/mtk-scpsys.c167
-rw-r--r--drivers/soc/rockchip/pm_domains.c117
-rw-r--r--drivers/soc/samsung/pm_domains.c90
-rw-r--r--drivers/soc/ti/knav_qmss.h14
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c60
-rw-r--r--include/dt-bindings/memory/tegra114-mc.h17
-rw-r--r--include/dt-bindings/memory/tegra124-mc.h25
-rw-r--r--include/dt-bindings/memory/tegra20-mc.h21
-rw-r--r--include/dt-bindings/memory/tegra210-mc.h31
-rw-r--r--include/dt-bindings/memory/tegra30-mc.h19
-rw-r--r--include/dt-bindings/power/px30-power.h27
-rw-r--r--include/dt-bindings/power/rk3036-power.h13
-rw-r--r--include/dt-bindings/power/rk3128-power.h14
-rw-r--r--include/dt-bindings/power/rk3228-power.h21
-rw-r--r--include/linux/platform_data/ti-aemif.h25
-rw-r--r--include/linux/scmi_protocol.h18
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h10
-rw-r--r--include/soc/tegra/cpuidle.h2
-rw-r--r--include/soc/tegra/mc.h37
54 files changed, 1677 insertions, 916 deletions
diff --git a/Documentation/devicetree/bindings/power/pd-samsung.txt b/Documentation/devicetree/bindings/power/pd-samsung.txt
index 549f7dee9b9d..92ef355e8f64 100644
--- a/Documentation/devicetree/bindings/power/pd-samsung.txt
+++ b/Documentation/devicetree/bindings/power/pd-samsung.txt
@@ -15,23 +15,13 @@ Required Properties:
15Optional Properties: 15Optional Properties:
16- label: Human readable string with domain name. Will be visible in userspace 16- label: Human readable string with domain name. Will be visible in userspace
17 to let user to distinguish between multiple domains in SoC. 17 to let user to distinguish between multiple domains in SoC.
18- clocks: List of clock handles. The parent clocks of the input clocks to the
19 devices in this power domain are set to oscclk before power gating
20 and restored back after powering on a domain. This is required for
21 all domains which are powered on and off and not required for unused
22 domains.
23- clock-names: The following clocks can be specified:
24 - oscclk: Oscillator clock.
25 - clkN: Input clocks to the devices in this power domain. These clocks
26 will be reparented to oscclk before switching power domain off.
27 Their original parent will be brought back after turning on
28 the domain. Maximum of 4 clocks (N = 0 to 3) are supported.
29 - asbN: Clocks required by asynchronous bridges (ASB) present in
30 the power domain. These clock should be enabled during power
31 domain on/off operations.
32- power-domains: phandle pointing to the parent power domain, for more details 18- power-domains: phandle pointing to the parent power domain, for more details
33 see Documentation/devicetree/bindings/power/power_domain.txt 19 see Documentation/devicetree/bindings/power/power_domain.txt
34 20
21Deprecated Properties:
22- clocks
23- clock-names
24
35Node of a device using power domains must have a power-domains property 25Node of a device using power domains must have a power-domains property
36defined with a phandle to respective power domain. 26defined with a phandle to respective power domain.
37 27
@@ -47,8 +37,6 @@ Example:
47 mfc_pd: power-domain@10044060 { 37 mfc_pd: power-domain@10044060 {
48 compatible = "samsung,exynos4210-pd"; 38 compatible = "samsung,exynos4210-pd";
49 reg = <0x10044060 0x20>; 39 reg = <0x10044060 0x20>;
50 clocks = <&clock CLK_FIN_PLL>, <&clock CLK_MOUT_USER_ACLK333>;
51 clock-names = "oscclk", "clk0";
52 #power-domain-cells = <0>; 40 #power-domain-cells = <0>;
53 label = "MFC"; 41 label = "MFC";
54 }; 42 };
diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
index 301d2a9bc1b8..5d49d0a2ff29 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
+++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -5,6 +5,10 @@ powered up/down by software based on different application scenes to save power.
5 5
6Required properties for power domain controller: 6Required properties for power domain controller:
7- compatible: Should be one of the following. 7- compatible: Should be one of the following.
8 "rockchip,px30-power-controller" - for PX30 SoCs.
9 "rockchip,rk3036-power-controller" - for RK3036 SoCs.
10 "rockchip,rk3128-power-controller" - for RK3128 SoCs.
11 "rockchip,rk3228-power-controller" - for RK3228 SoCs.
8 "rockchip,rk3288-power-controller" - for RK3288 SoCs. 12 "rockchip,rk3288-power-controller" - for RK3288 SoCs.
9 "rockchip,rk3328-power-controller" - for RK3328 SoCs. 13 "rockchip,rk3328-power-controller" - for RK3328 SoCs.
10 "rockchip,rk3366-power-controller" - for RK3366 SoCs. 14 "rockchip,rk3366-power-controller" - for RK3366 SoCs.
@@ -17,6 +21,10 @@ Required properties for power domain controller:
17 21
18Required properties for power domain sub nodes: 22Required properties for power domain sub nodes:
19- reg: index of the power domain, should use macros in: 23- reg: index of the power domain, should use macros in:
24 "include/dt-bindings/power/px30-power.h" - for PX30 type power domain.
25 "include/dt-bindings/power/rk3036-power.h" - for RK3036 type power domain.
26 "include/dt-bindings/power/rk3128-power.h" - for RK3128 type power domain.
27 "include/dt-bindings/power/rk3228-power.h" - for RK3228 type power domain.
20 "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. 28 "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
21 "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain. 29 "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
22 "include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain. 30 "include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain.
@@ -93,6 +101,10 @@ Node of a device using power domains must have a power-domains property,
93containing a phandle to the power device node and an index specifying which 101containing a phandle to the power device node and an index specifying which
94power domain to use. 102power domain to use.
95The index should use macros in: 103The index should use macros in:
104 "include/dt-bindings/power/px30-power.h" - for px30 type power domain.
105 "include/dt-bindings/power/rk3036-power.h" - for rk3036 type power domain.
106 "include/dt-bindings/power/rk3128-power.h" - for rk3128 type power domain.
107 "include/dt-bindings/power/rk3128-power.h" - for rk3228 type power domain.
96 "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. 108 "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
97 "include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain. 109 "include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain.
98 "include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain. 110 "include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain.
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 6dc177bf4c42..d1c0b60e9326 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -33,7 +33,6 @@ config HISILICON_LPC
33 bool "Support for ISA I/O space on HiSilicon Hip06/7" 33 bool "Support for ISA I/O space on HiSilicon Hip06/7"
34 depends on ARM64 && (ARCH_HISI || COMPILE_TEST) 34 depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
35 select INDIRECT_PIO 35 select INDIRECT_PIO
36 select MFD_CORE if ACPI
37 help 36 help
38 Driver to enable I/O access to devices attached to the Low Pin 37 Driver to enable I/O access to devices attached to the Low Pin
39 Count bus on the HiSilicon Hip06/7 SoC. 38 Count bus on the HiSilicon Hip06/7 SoC.
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 443e4c3fd357..b8184a903583 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -371,8 +371,6 @@ asmlinkage void __naked cci_enable_port_for_self(void)
371 [sizeof_struct_cpu_port] "i" (sizeof(struct cpu_port)), 371 [sizeof_struct_cpu_port] "i" (sizeof(struct cpu_port)),
372 [sizeof_struct_ace_port] "i" (sizeof(struct cci_ace_port)), 372 [sizeof_struct_ace_port] "i" (sizeof(struct cci_ace_port)),
373 [offsetof_port_phys] "i" (offsetof(struct cci_ace_port, phys)) ); 373 [offsetof_port_phys] "i" (offsetof(struct cci_ace_port, phys)) );
374
375 unreachable();
376} 374}
377 375
378/** 376/**
diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
index 2d4611e4c339..d5f85455fa62 100644
--- a/drivers/bus/hisi_lpc.c
+++ b/drivers/bus/hisi_lpc.c
@@ -11,12 +11,12 @@
11#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/logic_pio.h> 13#include <linux/logic_pio.h>
14#include <linux/mfd/core.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/of.h> 15#include <linux/of.h>
17#include <linux/of_address.h> 16#include <linux/of_address.h>
18#include <linux/of_platform.h> 17#include <linux/of_platform.h>
19#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/serial_8250.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21 21
22#define DRV_NAME "hisi-lpc" 22#define DRV_NAME "hisi-lpc"
@@ -341,15 +341,6 @@ static const struct logic_pio_host_ops hisi_lpc_ops = {
341}; 341};
342 342
343#ifdef CONFIG_ACPI 343#ifdef CONFIG_ACPI
344#define MFD_CHILD_NAME_PREFIX DRV_NAME"-"
345#define MFD_CHILD_NAME_LEN (ACPI_ID_LEN + sizeof(MFD_CHILD_NAME_PREFIX) - 1)
346
347struct hisi_lpc_mfd_cell {
348 struct mfd_cell_acpi_match acpi_match;
349 char name[MFD_CHILD_NAME_LEN];
350 char pnpid[ACPI_ID_LEN];
351};
352
353static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, 344static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
354 struct acpi_device *host, 345 struct acpi_device *host,
355 struct resource *res) 346 struct resource *res)
@@ -368,7 +359,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
368} 359}
369 360
370/* 361/*
371 * hisi_lpc_acpi_set_io_res - set the resources for a child's MFD 362 * hisi_lpc_acpi_set_io_res - set the resources for a child
372 * @child: the device node to be updated the I/O resource 363 * @child: the device node to be updated the I/O resource
373 * @hostdev: the device node associated with host controller 364 * @hostdev: the device node associated with host controller
374 * @res: double pointer to be set to the address of translated resources 365 * @res: double pointer to be set to the address of translated resources
@@ -452,78 +443,122 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
452 return 0; 443 return 0;
453} 444}
454 445
446static int hisi_lpc_acpi_remove_subdev(struct device *dev, void *unused)
447{
448 platform_device_unregister(to_platform_device(dev));
449 return 0;
450}
451
452struct hisi_lpc_acpi_cell {
453 const char *hid;
454 const char *name;
455 void *pdata;
456 size_t pdata_size;
457};
458
455/* 459/*
456 * hisi_lpc_acpi_probe - probe children for ACPI FW 460 * hisi_lpc_acpi_probe - probe children for ACPI FW
457 * @hostdev: LPC host device pointer 461 * @hostdev: LPC host device pointer
458 * 462 *
459 * Returns 0 when successful, and a negative value for failure. 463 * Returns 0 when successful, and a negative value for failure.
460 * 464 *
461 * Scan all child devices and create a per-device MFD with 465 * Create a platform device per child, fixing up the resources
462 * logical PIO translated IO resources. 466 * from bus addresses to Logical PIO addresses.
467 *
463 */ 468 */
464static int hisi_lpc_acpi_probe(struct device *hostdev) 469static int hisi_lpc_acpi_probe(struct device *hostdev)
465{ 470{
466 struct acpi_device *adev = ACPI_COMPANION(hostdev); 471 struct acpi_device *adev = ACPI_COMPANION(hostdev);
467 struct hisi_lpc_mfd_cell *hisi_lpc_mfd_cells;
468 struct mfd_cell *mfd_cells;
469 struct acpi_device *child; 472 struct acpi_device *child;
470 int size, ret, count = 0, cell_num = 0; 473 int ret;
471
472 list_for_each_entry(child, &adev->children, node)
473 cell_num++;
474
475 /* allocate the mfd cell and companion ACPI info, one per child */
476 size = sizeof(*mfd_cells) + sizeof(*hisi_lpc_mfd_cells);
477 mfd_cells = devm_kcalloc(hostdev, cell_num, size, GFP_KERNEL);
478 if (!mfd_cells)
479 return -ENOMEM;
480 474
481 hisi_lpc_mfd_cells = (struct hisi_lpc_mfd_cell *)&mfd_cells[cell_num];
482 /* Only consider the children of the host */ 475 /* Only consider the children of the host */
483 list_for_each_entry(child, &adev->children, node) { 476 list_for_each_entry(child, &adev->children, node) {
484 struct mfd_cell *mfd_cell = &mfd_cells[count]; 477 const char *hid = acpi_device_hid(child);
485 struct hisi_lpc_mfd_cell *hisi_lpc_mfd_cell = 478 const struct hisi_lpc_acpi_cell *cell;
486 &hisi_lpc_mfd_cells[count]; 479 struct platform_device *pdev;
487 struct mfd_cell_acpi_match *acpi_match = 480 const struct resource *res;
488 &hisi_lpc_mfd_cell->acpi_match; 481 bool found = false;
489 char *name = hisi_lpc_mfd_cell[count].name; 482 int num_res;
490 char *pnpid = hisi_lpc_mfd_cell[count].pnpid; 483
491 struct mfd_cell_acpi_match match = { 484 ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev, &res,
492 .pnpid = pnpid, 485 &num_res);
486 if (ret) {
487 dev_warn(hostdev, "set resource fail (%d)\n", ret);
488 goto fail;
489 }
490
491 cell = (struct hisi_lpc_acpi_cell []){
492 /* ipmi */
493 {
494 .hid = "IPI0001",
495 .name = "hisi-lpc-ipmi",
496 },
497 /* 8250-compatible uart */
498 {
499 .hid = "HISI1031",
500 .name = "serial8250",
501 .pdata = (struct plat_serial8250_port []) {
502 {
503 .iobase = res->start,
504 .uartclk = 1843200,
505 .iotype = UPIO_PORT,
506 .flags = UPF_BOOT_AUTOCONF,
507 },
508 {}
509 },
510 .pdata_size = 2 *
511 sizeof(struct plat_serial8250_port),
512 },
513 {}
493 }; 514 };
494 515
495 /* 516 for (; cell && cell->name; cell++) {
496 * For any instances of this host controller (Hip06 and Hip07 517 if (!strcmp(cell->hid, hid)) {
497 * are the only chipsets), we would not have multiple slaves 518 found = true;
498 * with the same HID. And in any system we would have just one 519 break;
499 * controller active. So don't worrry about MFD name clashes. 520 }
500 */
501 snprintf(name, MFD_CHILD_NAME_LEN, MFD_CHILD_NAME_PREFIX"%s",
502 acpi_device_hid(child));
503 snprintf(pnpid, ACPI_ID_LEN, "%s", acpi_device_hid(child));
504
505 memcpy(acpi_match, &match, sizeof(*acpi_match));
506 mfd_cell->name = name;
507 mfd_cell->acpi_match = acpi_match;
508
509 ret = hisi_lpc_acpi_set_io_res(&child->dev, &adev->dev,
510 &mfd_cell->resources,
511 &mfd_cell->num_resources);
512 if (ret) {
513 dev_warn(&child->dev, "set resource fail (%d)\n", ret);
514 return ret;
515 } 521 }
516 count++;
517 }
518 522
519 ret = mfd_add_devices(hostdev, PLATFORM_DEVID_NONE, 523 if (!found) {
520 mfd_cells, cell_num, NULL, 0, NULL); 524 dev_warn(hostdev,
521 if (ret) { 525 "could not find cell for child device (%s)\n",
522 dev_err(hostdev, "failed to add mfd cells (%d)\n", ret); 526 hid);
523 return ret; 527 ret = -ENODEV;
528 goto fail;
529 }
530
531 pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO);
532 if (!pdev) {
533 ret = -ENOMEM;
534 goto fail;
535 }
536
537 pdev->dev.parent = hostdev;
538 ACPI_COMPANION_SET(&pdev->dev, child);
539
540 ret = platform_device_add_resources(pdev, res, num_res);
541 if (ret)
542 goto fail;
543
544 ret = platform_device_add_data(pdev, cell->pdata,
545 cell->pdata_size);
546 if (ret)
547 goto fail;
548
549 ret = platform_device_add(pdev);
550 if (ret)
551 goto fail;
552
553 acpi_device_set_enumerated(child);
524 } 554 }
525 555
526 return 0; 556 return 0;
557
558fail:
559 device_for_each_child(hostdev, NULL,
560 hisi_lpc_acpi_remove_subdev);
561 return ret;
527} 562}
528 563
529static const struct acpi_device_id hisi_lpc_acpi_match[] = { 564static const struct acpi_device_id hisi_lpc_acpi_match[] = {
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index b4dbc77459b6..50b1551ba894 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -117,7 +117,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
117 return -ENODEV; 117 return -ENODEV;
118 } 118 }
119 119
120 ret = handle->perf_ops->add_opps_to_device(handle, cpu_dev); 120 ret = handle->perf_ops->device_opps_add(handle, cpu_dev);
121 if (ret) { 121 if (ret) {
122 dev_warn(cpu_dev, "failed to add opps to the device\n"); 122 dev_warn(cpu_dev, "failed to add opps to the device\n");
123 return ret; 123 return ret;
@@ -164,7 +164,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
164 /* SCMI allows DVFS request for any domain from any CPU */ 164 /* SCMI allows DVFS request for any domain from any CPU */
165 policy->dvfs_possible_from_any_cpu = true; 165 policy->dvfs_possible_from_any_cpu = true;
166 166
167 latency = handle->perf_ops->get_transition_latency(handle, cpu_dev); 167 latency = handle->perf_ops->transition_latency_get(handle, cpu_dev);
168 if (!latency) 168 if (!latency)
169 latency = CPUFREQ_ETERNAL; 169 latency = CPUFREQ_ETERNAL;
170 170
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index 0d3806c0d432..9dff33ea6416 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -26,7 +26,7 @@ struct scmi_msg_resp_base_attributes {
26 * scmi_base_attributes_get() - gets the implementation details 26 * scmi_base_attributes_get() - gets the implementation details
27 * that are associated with the base protocol. 27 * that are associated with the base protocol.
28 * 28 *
29 * @handle - SCMI entity handle 29 * @handle: SCMI entity handle
30 * 30 *
31 * Return: 0 on success, else appropriate SCMI error. 31 * Return: 0 on success, else appropriate SCMI error.
32 */ 32 */
@@ -37,7 +37,7 @@ static int scmi_base_attributes_get(const struct scmi_handle *handle)
37 struct scmi_msg_resp_base_attributes *attr_info; 37 struct scmi_msg_resp_base_attributes *attr_info;
38 struct scmi_revision_info *rev = handle->version; 38 struct scmi_revision_info *rev = handle->version;
39 39
40 ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES, 40 ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
41 SCMI_PROTOCOL_BASE, 0, sizeof(*attr_info), &t); 41 SCMI_PROTOCOL_BASE, 0, sizeof(*attr_info), &t);
42 if (ret) 42 if (ret)
43 return ret; 43 return ret;
@@ -49,15 +49,16 @@ static int scmi_base_attributes_get(const struct scmi_handle *handle)
49 rev->num_agents = attr_info->num_agents; 49 rev->num_agents = attr_info->num_agents;
50 } 50 }
51 51
52 scmi_one_xfer_put(handle, t); 52 scmi_xfer_put(handle, t);
53
53 return ret; 54 return ret;
54} 55}
55 56
56/** 57/**
57 * scmi_base_vendor_id_get() - gets vendor/subvendor identifier ASCII string. 58 * scmi_base_vendor_id_get() - gets vendor/subvendor identifier ASCII string.
58 * 59 *
59 * @handle - SCMI entity handle 60 * @handle: SCMI entity handle
60 * @sub_vendor - specify true if sub-vendor ID is needed 61 * @sub_vendor: specify true if sub-vendor ID is needed
61 * 62 *
62 * Return: 0 on success, else appropriate SCMI error. 63 * Return: 0 on success, else appropriate SCMI error.
63 */ 64 */
@@ -80,7 +81,7 @@ scmi_base_vendor_id_get(const struct scmi_handle *handle, bool sub_vendor)
80 size = ARRAY_SIZE(rev->vendor_id); 81 size = ARRAY_SIZE(rev->vendor_id);
81 } 82 }
82 83
83 ret = scmi_one_xfer_init(handle, cmd, SCMI_PROTOCOL_BASE, 0, size, &t); 84 ret = scmi_xfer_get_init(handle, cmd, SCMI_PROTOCOL_BASE, 0, size, &t);
84 if (ret) 85 if (ret)
85 return ret; 86 return ret;
86 87
@@ -88,7 +89,8 @@ scmi_base_vendor_id_get(const struct scmi_handle *handle, bool sub_vendor)
88 if (!ret) 89 if (!ret)
89 memcpy(vendor_id, t->rx.buf, size); 90 memcpy(vendor_id, t->rx.buf, size);
90 91
91 scmi_one_xfer_put(handle, t); 92 scmi_xfer_put(handle, t);
93
92 return ret; 94 return ret;
93} 95}
94 96
@@ -97,7 +99,7 @@ scmi_base_vendor_id_get(const struct scmi_handle *handle, bool sub_vendor)
97 * implementation 32-bit version. The format of the version number is 99 * implementation 32-bit version. The format of the version number is
98 * vendor-specific 100 * vendor-specific
99 * 101 *
100 * @handle - SCMI entity handle 102 * @handle: SCMI entity handle
101 * 103 *
102 * Return: 0 on success, else appropriate SCMI error. 104 * Return: 0 on success, else appropriate SCMI error.
103 */ 105 */
@@ -109,7 +111,7 @@ scmi_base_implementation_version_get(const struct scmi_handle *handle)
109 struct scmi_xfer *t; 111 struct scmi_xfer *t;
110 struct scmi_revision_info *rev = handle->version; 112 struct scmi_revision_info *rev = handle->version;
111 113
112 ret = scmi_one_xfer_init(handle, BASE_DISCOVER_IMPLEMENT_VERSION, 114 ret = scmi_xfer_get_init(handle, BASE_DISCOVER_IMPLEMENT_VERSION,
113 SCMI_PROTOCOL_BASE, 0, sizeof(*impl_ver), &t); 115 SCMI_PROTOCOL_BASE, 0, sizeof(*impl_ver), &t);
114 if (ret) 116 if (ret)
115 return ret; 117 return ret;
@@ -120,7 +122,8 @@ scmi_base_implementation_version_get(const struct scmi_handle *handle)
120 rev->impl_ver = le32_to_cpu(*impl_ver); 122 rev->impl_ver = le32_to_cpu(*impl_ver);
121 } 123 }
122 124
123 scmi_one_xfer_put(handle, t); 125 scmi_xfer_put(handle, t);
126
124 return ret; 127 return ret;
125} 128}
126 129
@@ -128,8 +131,8 @@ scmi_base_implementation_version_get(const struct scmi_handle *handle)
128 * scmi_base_implementation_list_get() - gets the list of protocols it is 131 * scmi_base_implementation_list_get() - gets the list of protocols it is
129 * OSPM is allowed to access 132 * OSPM is allowed to access
130 * 133 *
131 * @handle - SCMI entity handle 134 * @handle: SCMI entity handle
132 * @protocols_imp - pointer to hold the list of protocol identifiers 135 * @protocols_imp: pointer to hold the list of protocol identifiers
133 * 136 *
134 * Return: 0 on success, else appropriate SCMI error. 137 * Return: 0 on success, else appropriate SCMI error.
135 */ 138 */
@@ -143,7 +146,7 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle,
143 u32 tot_num_ret = 0, loop_num_ret; 146 u32 tot_num_ret = 0, loop_num_ret;
144 struct device *dev = handle->dev; 147 struct device *dev = handle->dev;
145 148
146 ret = scmi_one_xfer_init(handle, BASE_DISCOVER_LIST_PROTOCOLS, 149 ret = scmi_xfer_get_init(handle, BASE_DISCOVER_LIST_PROTOCOLS,
147 SCMI_PROTOCOL_BASE, sizeof(*num_skip), 0, &t); 150 SCMI_PROTOCOL_BASE, sizeof(*num_skip), 0, &t);
148 if (ret) 151 if (ret)
149 return ret; 152 return ret;
@@ -172,16 +175,17 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle,
172 tot_num_ret += loop_num_ret; 175 tot_num_ret += loop_num_ret;
173 } while (loop_num_ret); 176 } while (loop_num_ret);
174 177
175 scmi_one_xfer_put(handle, t); 178 scmi_xfer_put(handle, t);
179
176 return ret; 180 return ret;
177} 181}
178 182
179/** 183/**
180 * scmi_base_discover_agent_get() - discover the name of an agent 184 * scmi_base_discover_agent_get() - discover the name of an agent
181 * 185 *
182 * @handle - SCMI entity handle 186 * @handle: SCMI entity handle
183 * @id - Agent identifier 187 * @id: Agent identifier
184 * @name - Agent identifier ASCII string 188 * @name: Agent identifier ASCII string
185 * 189 *
186 * An agent id of 0 is reserved to identify the platform itself. 190 * An agent id of 0 is reserved to identify the platform itself.
187 * Generally operating system is represented as "OSPM" 191 * Generally operating system is represented as "OSPM"
@@ -194,7 +198,7 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
194 int ret; 198 int ret;
195 struct scmi_xfer *t; 199 struct scmi_xfer *t;
196 200
197 ret = scmi_one_xfer_init(handle, BASE_DISCOVER_AGENT, 201 ret = scmi_xfer_get_init(handle, BASE_DISCOVER_AGENT,
198 SCMI_PROTOCOL_BASE, sizeof(__le32), 202 SCMI_PROTOCOL_BASE, sizeof(__le32),
199 SCMI_MAX_STR_SIZE, &t); 203 SCMI_MAX_STR_SIZE, &t);
200 if (ret) 204 if (ret)
@@ -206,7 +210,8 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
206 if (!ret) 210 if (!ret)
207 memcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE); 211 memcpy(name, t->rx.buf, SCMI_MAX_STR_SIZE);
208 212
209 scmi_one_xfer_put(handle, t); 213 scmi_xfer_put(handle, t);
214
210 return ret; 215 return ret;
211} 216}
212 217
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index f2760a596c28..472c88ae1c0f 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -125,13 +125,13 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
125 int id, retval; 125 int id, retval;
126 struct scmi_device *scmi_dev; 126 struct scmi_device *scmi_dev;
127 127
128 id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
129 if (id < 0)
130 return NULL;
131
132 scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL); 128 scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL);
133 if (!scmi_dev) 129 if (!scmi_dev)
134 goto no_mem; 130 return NULL;
131
132 id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
133 if (id < 0)
134 goto free_mem;
135 135
136 scmi_dev->id = id; 136 scmi_dev->id = id;
137 scmi_dev->protocol_id = protocol; 137 scmi_dev->protocol_id = protocol;
@@ -141,13 +141,15 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
141 dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id); 141 dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
142 142
143 retval = device_register(&scmi_dev->dev); 143 retval = device_register(&scmi_dev->dev);
144 if (!retval) 144 if (retval)
145 return scmi_dev; 145 goto put_dev;
146 146
147 return scmi_dev;
148put_dev:
147 put_device(&scmi_dev->dev); 149 put_device(&scmi_dev->dev);
148 kfree(scmi_dev);
149no_mem:
150 ida_simple_remove(&scmi_bus_id, id); 150 ida_simple_remove(&scmi_bus_id, id);
151free_mem:
152 kfree(scmi_dev);
151 return NULL; 153 return NULL;
152} 154}
153 155
@@ -171,9 +173,9 @@ int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn)
171 spin_lock(&protocol_lock); 173 spin_lock(&protocol_lock);
172 ret = idr_alloc(&scmi_protocols, fn, protocol_id, protocol_id + 1, 174 ret = idr_alloc(&scmi_protocols, fn, protocol_id, protocol_id + 1,
173 GFP_ATOMIC); 175 GFP_ATOMIC);
176 spin_unlock(&protocol_lock);
174 if (ret != protocol_id) 177 if (ret != protocol_id)
175 pr_err("unable to allocate SCMI idr slot, err %d\n", ret); 178 pr_err("unable to allocate SCMI idr slot, err %d\n", ret);
176 spin_unlock(&protocol_lock);
177 179
178 return ret; 180 return ret;
179} 181}
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 2b90606452a2..e4119eb34986 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -77,7 +77,7 @@ static int scmi_clock_protocol_attributes_get(const struct scmi_handle *handle,
77 struct scmi_xfer *t; 77 struct scmi_xfer *t;
78 struct scmi_msg_resp_clock_protocol_attributes *attr; 78 struct scmi_msg_resp_clock_protocol_attributes *attr;
79 79
80 ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES, 80 ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
81 SCMI_PROTOCOL_CLOCK, 0, sizeof(*attr), &t); 81 SCMI_PROTOCOL_CLOCK, 0, sizeof(*attr), &t);
82 if (ret) 82 if (ret)
83 return ret; 83 return ret;
@@ -90,7 +90,7 @@ static int scmi_clock_protocol_attributes_get(const struct scmi_handle *handle,
90 ci->max_async_req = attr->max_async_req; 90 ci->max_async_req = attr->max_async_req;
91 } 91 }
92 92
93 scmi_one_xfer_put(handle, t); 93 scmi_xfer_put(handle, t);
94 return ret; 94 return ret;
95} 95}
96 96
@@ -101,7 +101,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle,
101 struct scmi_xfer *t; 101 struct scmi_xfer *t;
102 struct scmi_msg_resp_clock_attributes *attr; 102 struct scmi_msg_resp_clock_attributes *attr;
103 103
104 ret = scmi_one_xfer_init(handle, CLOCK_ATTRIBUTES, SCMI_PROTOCOL_CLOCK, 104 ret = scmi_xfer_get_init(handle, CLOCK_ATTRIBUTES, SCMI_PROTOCOL_CLOCK,
105 sizeof(clk_id), sizeof(*attr), &t); 105 sizeof(clk_id), sizeof(*attr), &t);
106 if (ret) 106 if (ret)
107 return ret; 107 return ret;
@@ -115,7 +115,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle,
115 else 115 else
116 clk->name[0] = '\0'; 116 clk->name[0] = '\0';
117 117
118 scmi_one_xfer_put(handle, t); 118 scmi_xfer_put(handle, t);
119 return ret; 119 return ret;
120} 120}
121 121
@@ -132,7 +132,7 @@ scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
132 struct scmi_msg_clock_describe_rates *clk_desc; 132 struct scmi_msg_clock_describe_rates *clk_desc;
133 struct scmi_msg_resp_clock_describe_rates *rlist; 133 struct scmi_msg_resp_clock_describe_rates *rlist;
134 134
135 ret = scmi_one_xfer_init(handle, CLOCK_DESCRIBE_RATES, 135 ret = scmi_xfer_get_init(handle, CLOCK_DESCRIBE_RATES,
136 SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, &t); 136 SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, &t);
137 if (ret) 137 if (ret)
138 return ret; 138 return ret;
@@ -186,7 +186,7 @@ scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
186 clk->list.num_rates = tot_rate_cnt; 186 clk->list.num_rates = tot_rate_cnt;
187 187
188err: 188err:
189 scmi_one_xfer_put(handle, t); 189 scmi_xfer_put(handle, t);
190 return ret; 190 return ret;
191} 191}
192 192
@@ -196,7 +196,7 @@ scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
196 int ret; 196 int ret;
197 struct scmi_xfer *t; 197 struct scmi_xfer *t;
198 198
199 ret = scmi_one_xfer_init(handle, CLOCK_RATE_GET, SCMI_PROTOCOL_CLOCK, 199 ret = scmi_xfer_get_init(handle, CLOCK_RATE_GET, SCMI_PROTOCOL_CLOCK,
200 sizeof(__le32), sizeof(u64), &t); 200 sizeof(__le32), sizeof(u64), &t);
201 if (ret) 201 if (ret)
202 return ret; 202 return ret;
@@ -211,7 +211,7 @@ scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
211 *value |= (u64)le32_to_cpu(*(pval + 1)) << 32; 211 *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
212 } 212 }
213 213
214 scmi_one_xfer_put(handle, t); 214 scmi_xfer_put(handle, t);
215 return ret; 215 return ret;
216} 216}
217 217
@@ -222,7 +222,7 @@ static int scmi_clock_rate_set(const struct scmi_handle *handle, u32 clk_id,
222 struct scmi_xfer *t; 222 struct scmi_xfer *t;
223 struct scmi_clock_set_rate *cfg; 223 struct scmi_clock_set_rate *cfg;
224 224
225 ret = scmi_one_xfer_init(handle, CLOCK_RATE_SET, SCMI_PROTOCOL_CLOCK, 225 ret = scmi_xfer_get_init(handle, CLOCK_RATE_SET, SCMI_PROTOCOL_CLOCK,
226 sizeof(*cfg), 0, &t); 226 sizeof(*cfg), 0, &t);
227 if (ret) 227 if (ret)
228 return ret; 228 return ret;
@@ -235,7 +235,7 @@ static int scmi_clock_rate_set(const struct scmi_handle *handle, u32 clk_id,
235 235
236 ret = scmi_do_xfer(handle, t); 236 ret = scmi_do_xfer(handle, t);
237 237
238 scmi_one_xfer_put(handle, t); 238 scmi_xfer_put(handle, t);
239 return ret; 239 return ret;
240} 240}
241 241
@@ -246,7 +246,7 @@ scmi_clock_config_set(const struct scmi_handle *handle, u32 clk_id, u32 config)
246 struct scmi_xfer *t; 246 struct scmi_xfer *t;
247 struct scmi_clock_set_config *cfg; 247 struct scmi_clock_set_config *cfg;
248 248
249 ret = scmi_one_xfer_init(handle, CLOCK_CONFIG_SET, SCMI_PROTOCOL_CLOCK, 249 ret = scmi_xfer_get_init(handle, CLOCK_CONFIG_SET, SCMI_PROTOCOL_CLOCK,
250 sizeof(*cfg), 0, &t); 250 sizeof(*cfg), 0, &t);
251 if (ret) 251 if (ret)
252 return ret; 252 return ret;
@@ -257,7 +257,7 @@ scmi_clock_config_set(const struct scmi_handle *handle, u32 clk_id, u32 config)
257 257
258 ret = scmi_do_xfer(handle, t); 258 ret = scmi_do_xfer(handle, t);
259 259
260 scmi_one_xfer_put(handle, t); 260 scmi_xfer_put(handle, t);
261 return ret; 261 return ret;
262} 262}
263 263
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 0c30234f9098..937a930ce87d 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -7,6 +7,7 @@
7 * Copyright (C) 2018 ARM Ltd. 7 * Copyright (C) 2018 ARM Ltd.
8 */ 8 */
9 9
10#include <linux/bitfield.h>
10#include <linux/completion.h> 11#include <linux/completion.h>
11#include <linux/device.h> 12#include <linux/device.h>
12#include <linux/errno.h> 13#include <linux/errno.h>
@@ -14,10 +15,10 @@
14#include <linux/scmi_protocol.h> 15#include <linux/scmi_protocol.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#define PROTOCOL_REV_MINOR_BITS 16 18#define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0)
18#define PROTOCOL_REV_MINOR_MASK ((1U << PROTOCOL_REV_MINOR_BITS) - 1) 19#define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16)
19#define PROTOCOL_REV_MAJOR(x) ((x) >> PROTOCOL_REV_MINOR_BITS) 20#define PROTOCOL_REV_MAJOR(x) (u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))
20#define PROTOCOL_REV_MINOR(x) ((x) & PROTOCOL_REV_MINOR_MASK) 21#define PROTOCOL_REV_MINOR(x) (u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x)))
21#define MAX_PROTOCOLS_IMP 16 22#define MAX_PROTOCOLS_IMP 16
22#define MAX_OPPS 16 23#define MAX_OPPS 16
23 24
@@ -50,8 +51,11 @@ struct scmi_msg_resp_prot_version {
50 * @id: The identifier of the command being sent 51 * @id: The identifier of the command being sent
51 * @protocol_id: The identifier of the protocol used to send @id command 52 * @protocol_id: The identifier of the protocol used to send @id command
52 * @seq: The token to identify the message. when a message/command returns, 53 * @seq: The token to identify the message. when a message/command returns,
53 * the platform returns the whole message header unmodified including 54 * the platform returns the whole message header unmodified including
54 * the token. 55 * the token
56 * @status: Status of the transfer once it's complete
57 * @poll_completion: Indicate if the transfer needs to be polled for
58 * completion or interrupt mode is used
55 */ 59 */
56struct scmi_msg_hdr { 60struct scmi_msg_hdr {
57 u8 id; 61 u8 id;
@@ -82,18 +86,16 @@ struct scmi_msg {
82 * buffer for the rx path as we use for the tx path. 86 * buffer for the rx path as we use for the tx path.
83 * @done: completion event 87 * @done: completion event
84 */ 88 */
85
86struct scmi_xfer { 89struct scmi_xfer {
87 void *con_priv;
88 struct scmi_msg_hdr hdr; 90 struct scmi_msg_hdr hdr;
89 struct scmi_msg tx; 91 struct scmi_msg tx;
90 struct scmi_msg rx; 92 struct scmi_msg rx;
91 struct completion done; 93 struct completion done;
92}; 94};
93 95
94void scmi_one_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer); 96void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer);
95int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer); 97int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer);
96int scmi_one_xfer_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id, 98int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
97 size_t tx_size, size_t rx_size, struct scmi_xfer **p); 99 size_t tx_size, size_t rx_size, struct scmi_xfer **p);
98int scmi_handle_put(const struct scmi_handle *handle); 100int scmi_handle_put(const struct scmi_handle *handle);
99struct scmi_handle *scmi_handle_get(struct device *dev); 101struct scmi_handle *scmi_handle_get(struct device *dev);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 2455be8cbc4f..8f952f2f1a29 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -29,16 +29,12 @@
29 29
30#include "common.h" 30#include "common.h"
31 31
32#define MSG_ID_SHIFT 0 32#define MSG_ID_MASK GENMASK(7, 0)
33#define MSG_ID_MASK 0xff 33#define MSG_TYPE_MASK GENMASK(9, 8)
34#define MSG_TYPE_SHIFT 8 34#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10)
35#define MSG_TYPE_MASK 0x3 35#define MSG_TOKEN_ID_MASK GENMASK(27, 18)
36#define MSG_PROTOCOL_ID_SHIFT 10 36#define MSG_XTRACT_TOKEN(hdr) FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
37#define MSG_PROTOCOL_ID_MASK 0xff 37#define MSG_TOKEN_MAX (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
38#define MSG_TOKEN_ID_SHIFT 18
39#define MSG_TOKEN_ID_MASK 0x3ff
40#define MSG_XTRACT_TOKEN(header) \
41 (((header) >> MSG_TOKEN_ID_SHIFT) & MSG_TOKEN_ID_MASK)
42 38
43enum scmi_error_codes { 39enum scmi_error_codes {
44 SCMI_SUCCESS = 0, /* Success */ 40 SCMI_SUCCESS = 0, /* Success */
@@ -55,7 +51,7 @@ enum scmi_error_codes {
55 SCMI_ERR_MAX 51 SCMI_ERR_MAX
56}; 52};
57 53
58/* List of all SCMI devices active in system */ 54/* List of all SCMI devices active in system */
59static LIST_HEAD(scmi_list); 55static LIST_HEAD(scmi_list);
60/* Protection for the entire list */ 56/* Protection for the entire list */
61static DEFINE_MUTEX(scmi_list_mutex); 57static DEFINE_MUTEX(scmi_list_mutex);
@@ -72,7 +68,6 @@ static DEFINE_MUTEX(scmi_list_mutex);
72struct scmi_xfers_info { 68struct scmi_xfers_info {
73 struct scmi_xfer *xfer_block; 69 struct scmi_xfer *xfer_block;
74 unsigned long *xfer_alloc_table; 70 unsigned long *xfer_alloc_table;
75 /* protect transfer allocation */
76 spinlock_t xfer_lock; 71 spinlock_t xfer_lock;
77}; 72};
78 73
@@ -98,6 +93,7 @@ struct scmi_desc {
98 * @payload: Transmit/Receive mailbox channel payload area 93 * @payload: Transmit/Receive mailbox channel payload area
99 * @dev: Reference to device in the SCMI hierarchy corresponding to this 94 * @dev: Reference to device in the SCMI hierarchy corresponding to this
100 * channel 95 * channel
96 * @handle: Pointer to SCMI entity handle
101 */ 97 */
102struct scmi_chan_info { 98struct scmi_chan_info {
103 struct mbox_client cl; 99 struct mbox_client cl;
@@ -108,7 +104,7 @@ struct scmi_chan_info {
108}; 104};
109 105
110/** 106/**
111 * struct scmi_info - Structure representing a SCMI instance 107 * struct scmi_info - Structure representing a SCMI instance
112 * 108 *
113 * @dev: Device pointer 109 * @dev: Device pointer
114 * @desc: SoC description for this instance 110 * @desc: SoC description for this instance
@@ -117,9 +113,9 @@ struct scmi_chan_info {
117 * implementation version and (sub-)vendor identification. 113 * implementation version and (sub-)vendor identification.
118 * @minfo: Message info 114 * @minfo: Message info
119 * @tx_idr: IDR object to map protocol id to channel info pointer 115 * @tx_idr: IDR object to map protocol id to channel info pointer
120 * @protocols_imp: list of protocols implemented, currently maximum of 116 * @protocols_imp: List of protocols implemented, currently maximum of
121 * MAX_PROTOCOLS_IMP elements allocated by the base protocol 117 * MAX_PROTOCOLS_IMP elements allocated by the base protocol
122 * @node: list head 118 * @node: List head
123 * @users: Number of users of this instance 119 * @users: Number of users of this instance
124 */ 120 */
125struct scmi_info { 121struct scmi_info {
@@ -225,9 +221,7 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m)
225 221
226 xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header)); 222 xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
227 223
228 /* 224 /* Are we even expecting this? */
229 * Are we even expecting this?
230 */
231 if (!test_bit(xfer_id, minfo->xfer_alloc_table)) { 225 if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
232 dev_err(dev, "message for %d is not expected!\n", xfer_id); 226 dev_err(dev, "message for %d is not expected!\n", xfer_id);
233 return; 227 return;
@@ -252,12 +246,14 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m)
252 * 246 *
253 * @hdr: pointer to header containing all the information on message id, 247 * @hdr: pointer to header containing all the information on message id,
254 * protocol id and sequence id. 248 * protocol id and sequence id.
249 *
250 * Return: 32-bit packed command header to be sent to the platform.
255 */ 251 */
256static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr) 252static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
257{ 253{
258 return ((hdr->id & MSG_ID_MASK) << MSG_ID_SHIFT) | 254 return FIELD_PREP(MSG_ID_MASK, hdr->id) |
259 ((hdr->seq & MSG_TOKEN_ID_MASK) << MSG_TOKEN_ID_SHIFT) | 255 FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) |
260 ((hdr->protocol_id & MSG_PROTOCOL_ID_MASK) << MSG_PROTOCOL_ID_SHIFT); 256 FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id);
261} 257}
262 258
263/** 259/**
@@ -286,9 +282,9 @@ static void scmi_tx_prepare(struct mbox_client *cl, void *m)
286} 282}
287 283
288/** 284/**
289 * scmi_one_xfer_get() - Allocate one message 285 * scmi_xfer_get() - Allocate one message
290 * 286 *
291 * @handle: SCMI entity handle 287 * @handle: Pointer to SCMI entity handle
292 * 288 *
293 * Helper function which is used by various command functions that are 289 * Helper function which is used by various command functions that are
294 * exposed to clients of this driver for allocating a message traffic event. 290 * exposed to clients of this driver for allocating a message traffic event.
@@ -299,7 +295,7 @@ static void scmi_tx_prepare(struct mbox_client *cl, void *m)
299 * 295 *
300 * Return: 0 if all went fine, else corresponding error. 296 * Return: 0 if all went fine, else corresponding error.
301 */ 297 */
302static struct scmi_xfer *scmi_one_xfer_get(const struct scmi_handle *handle) 298static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle)
303{ 299{
304 u16 xfer_id; 300 u16 xfer_id;
305 struct scmi_xfer *xfer; 301 struct scmi_xfer *xfer;
@@ -328,14 +324,14 @@ static struct scmi_xfer *scmi_one_xfer_get(const struct scmi_handle *handle)
328} 324}
329 325
330/** 326/**
331 * scmi_one_xfer_put() - Release a message 327 * scmi_xfer_put() - Release a message
332 * 328 *
333 * @minfo: transfer info pointer 329 * @handle: Pointer to SCMI entity handle
334 * @xfer: message that was reserved by scmi_one_xfer_get 330 * @xfer: message that was reserved by scmi_xfer_get
335 * 331 *
336 * This holds a spinlock to maintain integrity of internal data structures. 332 * This holds a spinlock to maintain integrity of internal data structures.
337 */ 333 */
338void scmi_one_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) 334void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
339{ 335{
340 unsigned long flags; 336 unsigned long flags;
341 struct scmi_info *info = handle_to_scmi_info(handle); 337 struct scmi_info *info = handle_to_scmi_info(handle);
@@ -378,12 +374,12 @@ static bool scmi_xfer_done_no_timeout(const struct scmi_chan_info *cinfo,
378/** 374/**
379 * scmi_do_xfer() - Do one transfer 375 * scmi_do_xfer() - Do one transfer
380 * 376 *
381 * @info: Pointer to SCMI entity information 377 * @handle: Pointer to SCMI entity handle
382 * @xfer: Transfer to initiate and wait for response 378 * @xfer: Transfer to initiate and wait for response
383 * 379 *
384 * Return: -ETIMEDOUT in case of no response, if transmit error, 380 * Return: -ETIMEDOUT in case of no response, if transmit error,
385 * return corresponding error, else if all goes well, 381 * return corresponding error, else if all goes well,
386 * return 0. 382 * return 0.
387 */ 383 */
388int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) 384int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
389{ 385{
@@ -440,22 +436,22 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
440} 436}
441 437
442/** 438/**
443 * scmi_one_xfer_init() - Allocate and initialise one message 439 * scmi_xfer_get_init() - Allocate and initialise one message
444 * 440 *
445 * @handle: SCMI entity handle 441 * @handle: Pointer to SCMI entity handle
446 * @msg_id: Message identifier 442 * @msg_id: Message identifier
447 * @msg_prot_id: Protocol identifier for the message 443 * @prot_id: Protocol identifier for the message
448 * @tx_size: transmit message size 444 * @tx_size: transmit message size
449 * @rx_size: receive message size 445 * @rx_size: receive message size
450 * @p: pointer to the allocated and initialised message 446 * @p: pointer to the allocated and initialised message
451 * 447 *
452 * This function allocates the message using @scmi_one_xfer_get and 448 * This function allocates the message using @scmi_xfer_get and
453 * initialise the header. 449 * initialise the header.
454 * 450 *
455 * Return: 0 if all went fine with @p pointing to message, else 451 * Return: 0 if all went fine with @p pointing to message, else
456 * corresponding error. 452 * corresponding error.
457 */ 453 */
458int scmi_one_xfer_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id, 454int scmi_xfer_get_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id,
459 size_t tx_size, size_t rx_size, struct scmi_xfer **p) 455 size_t tx_size, size_t rx_size, struct scmi_xfer **p)
460{ 456{
461 int ret; 457 int ret;
@@ -468,7 +464,7 @@ int scmi_one_xfer_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id,
468 tx_size > info->desc->max_msg_size) 464 tx_size > info->desc->max_msg_size)
469 return -ERANGE; 465 return -ERANGE;
470 466
471 xfer = scmi_one_xfer_get(handle); 467 xfer = scmi_xfer_get(handle);
472 if (IS_ERR(xfer)) { 468 if (IS_ERR(xfer)) {
473 ret = PTR_ERR(xfer); 469 ret = PTR_ERR(xfer);
474 dev_err(dev, "failed to get free message slot(%d)\n", ret); 470 dev_err(dev, "failed to get free message slot(%d)\n", ret);
@@ -482,13 +478,16 @@ int scmi_one_xfer_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id,
482 xfer->hdr.poll_completion = false; 478 xfer->hdr.poll_completion = false;
483 479
484 *p = xfer; 480 *p = xfer;
481
485 return 0; 482 return 0;
486} 483}
487 484
488/** 485/**
489 * scmi_version_get() - command to get the revision of the SCMI entity 486 * scmi_version_get() - command to get the revision of the SCMI entity
490 * 487 *
491 * @handle: Handle to SCMI entity information 488 * @handle: Pointer to SCMI entity handle
489 * @protocol: Protocol identifier for the message
490 * @version: Holds returned version of protocol.
492 * 491 *
493 * Updates the SCMI information in the internal data structure. 492 * Updates the SCMI information in the internal data structure.
494 * 493 *
@@ -501,7 +500,7 @@ int scmi_version_get(const struct scmi_handle *handle, u8 protocol,
501 __le32 *rev_info; 500 __le32 *rev_info;
502 struct scmi_xfer *t; 501 struct scmi_xfer *t;
503 502
504 ret = scmi_one_xfer_init(handle, PROTOCOL_VERSION, protocol, 0, 503 ret = scmi_xfer_get_init(handle, PROTOCOL_VERSION, protocol, 0,
505 sizeof(*version), &t); 504 sizeof(*version), &t);
506 if (ret) 505 if (ret)
507 return ret; 506 return ret;
@@ -512,7 +511,7 @@ int scmi_version_get(const struct scmi_handle *handle, u8 protocol,
512 *version = le32_to_cpu(*rev_info); 511 *version = le32_to_cpu(*rev_info);
513 } 512 }
514 513
515 scmi_one_xfer_put(handle, t); 514 scmi_xfer_put(handle, t);
516 return ret; 515 return ret;
517} 516}
518 517
@@ -540,12 +539,12 @@ scmi_is_protocol_implemented(const struct scmi_handle *handle, u8 prot_id)
540} 539}
541 540
542/** 541/**
543 * scmi_handle_get() - Get the SCMI handle for a device 542 * scmi_handle_get() - Get the SCMI handle for a device
544 * 543 *
545 * @dev: pointer to device for which we want SCMI handle 544 * @dev: pointer to device for which we want SCMI handle
546 * 545 *
547 * NOTE: The function does not track individual clients of the framework 546 * NOTE: The function does not track individual clients of the framework
548 * and is expected to be maintained by caller of SCMI protocol library. 547 * and is expected to be maintained by caller of SCMI protocol library.
549 * scmi_handle_put must be balanced with successful scmi_handle_get 548 * scmi_handle_put must be balanced with successful scmi_handle_get
550 * 549 *
551 * Return: pointer to handle if successful, NULL on error 550 * Return: pointer to handle if successful, NULL on error
@@ -576,7 +575,7 @@ struct scmi_handle *scmi_handle_get(struct device *dev)
576 * @handle: handle acquired by scmi_handle_get 575 * @handle: handle acquired by scmi_handle_get
577 * 576 *
578 * NOTE: The function does not track individual clients of the framework 577 * NOTE: The function does not track individual clients of the framework
579 * and is expected to be maintained by caller of SCMI protocol library. 578 * and is expected to be maintained by caller of SCMI protocol library.
580 * scmi_handle_put must be balanced with successful scmi_handle_get 579 * scmi_handle_put must be balanced with successful scmi_handle_get
581 * 580 *
582 * Return: 0 is successfully released 581 * Return: 0 is successfully released
@@ -599,7 +598,7 @@ int scmi_handle_put(const struct scmi_handle *handle)
599} 598}
600 599
601static const struct scmi_desc scmi_generic_desc = { 600static const struct scmi_desc scmi_generic_desc = {
602 .max_rx_timeout_ms = 30, /* we may increase this if required */ 601 .max_rx_timeout_ms = 30, /* We may increase this if required */
603 .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */ 602 .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
604 .max_msg_size = 128, 603 .max_msg_size = 128,
605}; 604};
@@ -621,9 +620,9 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo)
621 struct scmi_xfers_info *info = &sinfo->minfo; 620 struct scmi_xfers_info *info = &sinfo->minfo;
622 621
623 /* Pre-allocated messages, no more than what hdr.seq can support */ 622 /* Pre-allocated messages, no more than what hdr.seq can support */
624 if (WARN_ON(desc->max_msg >= (MSG_TOKEN_ID_MASK + 1))) { 623 if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) {
625 dev_err(dev, "Maximum message of %d exceeds supported %d\n", 624 dev_err(dev, "Maximum message of %d exceeds supported %ld\n",
626 desc->max_msg, MSG_TOKEN_ID_MASK + 1); 625 desc->max_msg, MSG_TOKEN_MAX);
627 return -EINVAL; 626 return -EINVAL;
628 } 627 }
629 628
@@ -637,8 +636,6 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo)
637 if (!info->xfer_alloc_table) 636 if (!info->xfer_alloc_table)
638 return -ENOMEM; 637 return -ENOMEM;
639 638
640 bitmap_zero(info->xfer_alloc_table, desc->max_msg);
641
642 /* Pre-initialize the buffer pointer to pre-allocated buffers */ 639 /* Pre-initialize the buffer pointer to pre-allocated buffers */
643 for (i = 0, xfer = info->xfer_block; i < desc->max_msg; i++, xfer++) { 640 for (i = 0, xfer = info->xfer_block; i < desc->max_msg; i++, xfer++) {
644 xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size, 641 xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size,
@@ -690,11 +687,12 @@ static int scmi_remove(struct platform_device *pdev)
690 list_del(&info->node); 687 list_del(&info->node);
691 mutex_unlock(&scmi_list_mutex); 688 mutex_unlock(&scmi_list_mutex);
692 689
693 if (!ret) { 690 if (ret)
694 /* Safe to free channels since no more users */ 691 return ret;
695 ret = idr_for_each(idr, scmi_mbox_free_channel, idr); 692
696 idr_destroy(&info->tx_idr); 693 /* Safe to free channels since no more users */
697 } 694 ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
695 idr_destroy(&info->tx_idr);
698 696
699 return ret; 697 return ret;
700} 698}
@@ -841,7 +839,8 @@ static int scmi_probe(struct platform_device *pdev)
841 if (of_property_read_u32(child, "reg", &prot_id)) 839 if (of_property_read_u32(child, "reg", &prot_id))
842 continue; 840 continue;
843 841
844 prot_id &= MSG_PROTOCOL_ID_MASK; 842 if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id))
843 dev_err(dev, "Out of range protocol %d\n", prot_id);
845 844
846 if (!scmi_is_protocol_implemented(handle, prot_id)) { 845 if (!scmi_is_protocol_implemented(handle, prot_id)) {
847 dev_err(dev, "SCMI protocol %d not implemented\n", 846 dev_err(dev, "SCMI protocol %d not implemented\n",
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 987c64d19801..2a219b1261b1 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -115,7 +115,7 @@ static int scmi_perf_attributes_get(const struct scmi_handle *handle,
115 struct scmi_xfer *t; 115 struct scmi_xfer *t;
116 struct scmi_msg_resp_perf_attributes *attr; 116 struct scmi_msg_resp_perf_attributes *attr;
117 117
118 ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES, 118 ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
119 SCMI_PROTOCOL_PERF, 0, sizeof(*attr), &t); 119 SCMI_PROTOCOL_PERF, 0, sizeof(*attr), &t);
120 if (ret) 120 if (ret)
121 return ret; 121 return ret;
@@ -133,7 +133,7 @@ static int scmi_perf_attributes_get(const struct scmi_handle *handle,
133 pi->stats_size = le32_to_cpu(attr->stats_size); 133 pi->stats_size = le32_to_cpu(attr->stats_size);
134 } 134 }
135 135
136 scmi_one_xfer_put(handle, t); 136 scmi_xfer_put(handle, t);
137 return ret; 137 return ret;
138} 138}
139 139
@@ -145,7 +145,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
145 struct scmi_xfer *t; 145 struct scmi_xfer *t;
146 struct scmi_msg_resp_perf_domain_attributes *attr; 146 struct scmi_msg_resp_perf_domain_attributes *attr;
147 147
148 ret = scmi_one_xfer_init(handle, PERF_DOMAIN_ATTRIBUTES, 148 ret = scmi_xfer_get_init(handle, PERF_DOMAIN_ATTRIBUTES,
149 SCMI_PROTOCOL_PERF, sizeof(domain), 149 SCMI_PROTOCOL_PERF, sizeof(domain),
150 sizeof(*attr), &t); 150 sizeof(*attr), &t);
151 if (ret) 151 if (ret)
@@ -171,7 +171,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
171 memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); 171 memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
172 } 172 }
173 173
174 scmi_one_xfer_put(handle, t); 174 scmi_xfer_put(handle, t);
175 return ret; 175 return ret;
176} 176}
177 177
@@ -194,7 +194,7 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
194 struct scmi_msg_perf_describe_levels *dom_info; 194 struct scmi_msg_perf_describe_levels *dom_info;
195 struct scmi_msg_resp_perf_describe_levels *level_info; 195 struct scmi_msg_resp_perf_describe_levels *level_info;
196 196
197 ret = scmi_one_xfer_init(handle, PERF_DESCRIBE_LEVELS, 197 ret = scmi_xfer_get_init(handle, PERF_DESCRIBE_LEVELS,
198 SCMI_PROTOCOL_PERF, sizeof(*dom_info), 0, &t); 198 SCMI_PROTOCOL_PERF, sizeof(*dom_info), 0, &t);
199 if (ret) 199 if (ret)
200 return ret; 200 return ret;
@@ -237,7 +237,7 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
237 } while (num_returned && num_remaining); 237 } while (num_returned && num_remaining);
238 238
239 perf_dom->opp_count = tot_opp_cnt; 239 perf_dom->opp_count = tot_opp_cnt;
240 scmi_one_xfer_put(handle, t); 240 scmi_xfer_put(handle, t);
241 241
242 sort(perf_dom->opp, tot_opp_cnt, sizeof(*opp), opp_cmp_func, NULL); 242 sort(perf_dom->opp, tot_opp_cnt, sizeof(*opp), opp_cmp_func, NULL);
243 return ret; 243 return ret;
@@ -250,7 +250,7 @@ static int scmi_perf_limits_set(const struct scmi_handle *handle, u32 domain,
250 struct scmi_xfer *t; 250 struct scmi_xfer *t;
251 struct scmi_perf_set_limits *limits; 251 struct scmi_perf_set_limits *limits;
252 252
253 ret = scmi_one_xfer_init(handle, PERF_LIMITS_SET, SCMI_PROTOCOL_PERF, 253 ret = scmi_xfer_get_init(handle, PERF_LIMITS_SET, SCMI_PROTOCOL_PERF,
254 sizeof(*limits), 0, &t); 254 sizeof(*limits), 0, &t);
255 if (ret) 255 if (ret)
256 return ret; 256 return ret;
@@ -262,7 +262,7 @@ static int scmi_perf_limits_set(const struct scmi_handle *handle, u32 domain,
262 262
263 ret = scmi_do_xfer(handle, t); 263 ret = scmi_do_xfer(handle, t);
264 264
265 scmi_one_xfer_put(handle, t); 265 scmi_xfer_put(handle, t);
266 return ret; 266 return ret;
267} 267}
268 268
@@ -273,7 +273,7 @@ static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
273 struct scmi_xfer *t; 273 struct scmi_xfer *t;
274 struct scmi_perf_get_limits *limits; 274 struct scmi_perf_get_limits *limits;
275 275
276 ret = scmi_one_xfer_init(handle, PERF_LIMITS_GET, SCMI_PROTOCOL_PERF, 276 ret = scmi_xfer_get_init(handle, PERF_LIMITS_GET, SCMI_PROTOCOL_PERF,
277 sizeof(__le32), 0, &t); 277 sizeof(__le32), 0, &t);
278 if (ret) 278 if (ret)
279 return ret; 279 return ret;
@@ -288,7 +288,7 @@ static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
288 *min_perf = le32_to_cpu(limits->min_level); 288 *min_perf = le32_to_cpu(limits->min_level);
289 } 289 }
290 290
291 scmi_one_xfer_put(handle, t); 291 scmi_xfer_put(handle, t);
292 return ret; 292 return ret;
293} 293}
294 294
@@ -299,7 +299,7 @@ static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
299 struct scmi_xfer *t; 299 struct scmi_xfer *t;
300 struct scmi_perf_set_level *lvl; 300 struct scmi_perf_set_level *lvl;
301 301
302 ret = scmi_one_xfer_init(handle, PERF_LEVEL_SET, SCMI_PROTOCOL_PERF, 302 ret = scmi_xfer_get_init(handle, PERF_LEVEL_SET, SCMI_PROTOCOL_PERF,
303 sizeof(*lvl), 0, &t); 303 sizeof(*lvl), 0, &t);
304 if (ret) 304 if (ret)
305 return ret; 305 return ret;
@@ -311,7 +311,7 @@ static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
311 311
312 ret = scmi_do_xfer(handle, t); 312 ret = scmi_do_xfer(handle, t);
313 313
314 scmi_one_xfer_put(handle, t); 314 scmi_xfer_put(handle, t);
315 return ret; 315 return ret;
316} 316}
317 317
@@ -321,7 +321,7 @@ static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
321 int ret; 321 int ret;
322 struct scmi_xfer *t; 322 struct scmi_xfer *t;
323 323
324 ret = scmi_one_xfer_init(handle, PERF_LEVEL_GET, SCMI_PROTOCOL_PERF, 324 ret = scmi_xfer_get_init(handle, PERF_LEVEL_GET, SCMI_PROTOCOL_PERF,
325 sizeof(u32), sizeof(u32), &t); 325 sizeof(u32), sizeof(u32), &t);
326 if (ret) 326 if (ret)
327 return ret; 327 return ret;
@@ -333,7 +333,7 @@ static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
333 if (!ret) 333 if (!ret)
334 *level = le32_to_cpu(*(__le32 *)t->rx.buf); 334 *level = le32_to_cpu(*(__le32 *)t->rx.buf);
335 335
336 scmi_one_xfer_put(handle, t); 336 scmi_xfer_put(handle, t);
337 return ret; 337 return ret;
338} 338}
339 339
@@ -349,8 +349,8 @@ static int scmi_dev_domain_id(struct device *dev)
349 return clkspec.args[0]; 349 return clkspec.args[0];
350} 350}
351 351
352static int scmi_dvfs_add_opps_to_device(const struct scmi_handle *handle, 352static int scmi_dvfs_device_opps_add(const struct scmi_handle *handle,
353 struct device *dev) 353 struct device *dev)
354{ 354{
355 int idx, ret, domain; 355 int idx, ret, domain;
356 unsigned long freq; 356 unsigned long freq;
@@ -383,7 +383,7 @@ static int scmi_dvfs_add_opps_to_device(const struct scmi_handle *handle,
383 return 0; 383 return 0;
384} 384}
385 385
386static int scmi_dvfs_get_transition_latency(const struct scmi_handle *handle, 386static int scmi_dvfs_transition_latency_get(const struct scmi_handle *handle,
387 struct device *dev) 387 struct device *dev)
388{ 388{
389 struct perf_dom_info *dom; 389 struct perf_dom_info *dom;
@@ -432,8 +432,8 @@ static struct scmi_perf_ops perf_ops = {
432 .level_set = scmi_perf_level_set, 432 .level_set = scmi_perf_level_set,
433 .level_get = scmi_perf_level_get, 433 .level_get = scmi_perf_level_get,
434 .device_domain_id = scmi_dev_domain_id, 434 .device_domain_id = scmi_dev_domain_id,
435 .get_transition_latency = scmi_dvfs_get_transition_latency, 435 .transition_latency_get = scmi_dvfs_transition_latency_get,
436 .add_opps_to_device = scmi_dvfs_add_opps_to_device, 436 .device_opps_add = scmi_dvfs_device_opps_add,
437 .freq_set = scmi_dvfs_freq_set, 437 .freq_set = scmi_dvfs_freq_set,
438 .freq_get = scmi_dvfs_freq_get, 438 .freq_get = scmi_dvfs_freq_get,
439}; 439};
diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c
index 087c2876cdf2..cfa033b05aed 100644
--- a/drivers/firmware/arm_scmi/power.c
+++ b/drivers/firmware/arm_scmi/power.c
@@ -63,7 +63,7 @@ static int scmi_power_attributes_get(const struct scmi_handle *handle,
63 struct scmi_xfer *t; 63 struct scmi_xfer *t;
64 struct scmi_msg_resp_power_attributes *attr; 64 struct scmi_msg_resp_power_attributes *attr;
65 65
66 ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES, 66 ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
67 SCMI_PROTOCOL_POWER, 0, sizeof(*attr), &t); 67 SCMI_PROTOCOL_POWER, 0, sizeof(*attr), &t);
68 if (ret) 68 if (ret)
69 return ret; 69 return ret;
@@ -78,7 +78,7 @@ static int scmi_power_attributes_get(const struct scmi_handle *handle,
78 pi->stats_size = le32_to_cpu(attr->stats_size); 78 pi->stats_size = le32_to_cpu(attr->stats_size);
79 } 79 }
80 80
81 scmi_one_xfer_put(handle, t); 81 scmi_xfer_put(handle, t);
82 return ret; 82 return ret;
83} 83}
84 84
@@ -90,7 +90,7 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
90 struct scmi_xfer *t; 90 struct scmi_xfer *t;
91 struct scmi_msg_resp_power_domain_attributes *attr; 91 struct scmi_msg_resp_power_domain_attributes *attr;
92 92
93 ret = scmi_one_xfer_init(handle, POWER_DOMAIN_ATTRIBUTES, 93 ret = scmi_xfer_get_init(handle, POWER_DOMAIN_ATTRIBUTES,
94 SCMI_PROTOCOL_POWER, sizeof(domain), 94 SCMI_PROTOCOL_POWER, sizeof(domain),
95 sizeof(*attr), &t); 95 sizeof(*attr), &t);
96 if (ret) 96 if (ret)
@@ -109,7 +109,7 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
109 memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); 109 memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
110 } 110 }
111 111
112 scmi_one_xfer_put(handle, t); 112 scmi_xfer_put(handle, t);
113 return ret; 113 return ret;
114} 114}
115 115
@@ -120,7 +120,7 @@ scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state)
120 struct scmi_xfer *t; 120 struct scmi_xfer *t;
121 struct scmi_power_set_state *st; 121 struct scmi_power_set_state *st;
122 122
123 ret = scmi_one_xfer_init(handle, POWER_STATE_SET, SCMI_PROTOCOL_POWER, 123 ret = scmi_xfer_get_init(handle, POWER_STATE_SET, SCMI_PROTOCOL_POWER,
124 sizeof(*st), 0, &t); 124 sizeof(*st), 0, &t);
125 if (ret) 125 if (ret)
126 return ret; 126 return ret;
@@ -132,7 +132,7 @@ scmi_power_state_set(const struct scmi_handle *handle, u32 domain, u32 state)
132 132
133 ret = scmi_do_xfer(handle, t); 133 ret = scmi_do_xfer(handle, t);
134 134
135 scmi_one_xfer_put(handle, t); 135 scmi_xfer_put(handle, t);
136 return ret; 136 return ret;
137} 137}
138 138
@@ -142,7 +142,7 @@ scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state)
142 int ret; 142 int ret;
143 struct scmi_xfer *t; 143 struct scmi_xfer *t;
144 144
145 ret = scmi_one_xfer_init(handle, POWER_STATE_GET, SCMI_PROTOCOL_POWER, 145 ret = scmi_xfer_get_init(handle, POWER_STATE_GET, SCMI_PROTOCOL_POWER,
146 sizeof(u32), sizeof(u32), &t); 146 sizeof(u32), sizeof(u32), &t);
147 if (ret) 147 if (ret)
148 return ret; 148 return ret;
@@ -153,7 +153,7 @@ scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state)
153 if (!ret) 153 if (!ret)
154 *state = le32_to_cpu(*(__le32 *)t->rx.buf); 154 *state = le32_to_cpu(*(__le32 *)t->rx.buf);
155 155
156 scmi_one_xfer_put(handle, t); 156 scmi_xfer_put(handle, t);
157 return ret; 157 return ret;
158} 158}
159 159
diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
index bbb469fea0ed..27f2092b9882 100644
--- a/drivers/firmware/arm_scmi/sensors.c
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -79,7 +79,7 @@ static int scmi_sensor_attributes_get(const struct scmi_handle *handle,
79 struct scmi_xfer *t; 79 struct scmi_xfer *t;
80 struct scmi_msg_resp_sensor_attributes *attr; 80 struct scmi_msg_resp_sensor_attributes *attr;
81 81
82 ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES, 82 ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
83 SCMI_PROTOCOL_SENSOR, 0, sizeof(*attr), &t); 83 SCMI_PROTOCOL_SENSOR, 0, sizeof(*attr), &t);
84 if (ret) 84 if (ret)
85 return ret; 85 return ret;
@@ -95,7 +95,7 @@ static int scmi_sensor_attributes_get(const struct scmi_handle *handle,
95 si->reg_size = le32_to_cpu(attr->reg_size); 95 si->reg_size = le32_to_cpu(attr->reg_size);
96 } 96 }
97 97
98 scmi_one_xfer_put(handle, t); 98 scmi_xfer_put(handle, t);
99 return ret; 99 return ret;
100} 100}
101 101
@@ -108,7 +108,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
108 struct scmi_xfer *t; 108 struct scmi_xfer *t;
109 struct scmi_msg_resp_sensor_description *buf; 109 struct scmi_msg_resp_sensor_description *buf;
110 110
111 ret = scmi_one_xfer_init(handle, SENSOR_DESCRIPTION_GET, 111 ret = scmi_xfer_get_init(handle, SENSOR_DESCRIPTION_GET,
112 SCMI_PROTOCOL_SENSOR, sizeof(__le32), 0, &t); 112 SCMI_PROTOCOL_SENSOR, sizeof(__le32), 0, &t);
113 if (ret) 113 if (ret)
114 return ret; 114 return ret;
@@ -150,7 +150,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
150 */ 150 */
151 } while (num_returned && num_remaining); 151 } while (num_returned && num_remaining);
152 152
153 scmi_one_xfer_put(handle, t); 153 scmi_xfer_put(handle, t);
154 return ret; 154 return ret;
155} 155}
156 156
@@ -162,7 +162,7 @@ scmi_sensor_configuration_set(const struct scmi_handle *handle, u32 sensor_id)
162 struct scmi_xfer *t; 162 struct scmi_xfer *t;
163 struct scmi_msg_set_sensor_config *cfg; 163 struct scmi_msg_set_sensor_config *cfg;
164 164
165 ret = scmi_one_xfer_init(handle, SENSOR_CONFIG_SET, 165 ret = scmi_xfer_get_init(handle, SENSOR_CONFIG_SET,
166 SCMI_PROTOCOL_SENSOR, sizeof(*cfg), 0, &t); 166 SCMI_PROTOCOL_SENSOR, sizeof(*cfg), 0, &t);
167 if (ret) 167 if (ret)
168 return ret; 168 return ret;
@@ -173,7 +173,7 @@ scmi_sensor_configuration_set(const struct scmi_handle *handle, u32 sensor_id)
173 173
174 ret = scmi_do_xfer(handle, t); 174 ret = scmi_do_xfer(handle, t);
175 175
176 scmi_one_xfer_put(handle, t); 176 scmi_xfer_put(handle, t);
177 return ret; 177 return ret;
178} 178}
179 179
@@ -185,7 +185,7 @@ static int scmi_sensor_trip_point_set(const struct scmi_handle *handle,
185 struct scmi_xfer *t; 185 struct scmi_xfer *t;
186 struct scmi_msg_set_sensor_trip_point *trip; 186 struct scmi_msg_set_sensor_trip_point *trip;
187 187
188 ret = scmi_one_xfer_init(handle, SENSOR_TRIP_POINT_SET, 188 ret = scmi_xfer_get_init(handle, SENSOR_TRIP_POINT_SET,
189 SCMI_PROTOCOL_SENSOR, sizeof(*trip), 0, &t); 189 SCMI_PROTOCOL_SENSOR, sizeof(*trip), 0, &t);
190 if (ret) 190 if (ret)
191 return ret; 191 return ret;
@@ -198,7 +198,7 @@ static int scmi_sensor_trip_point_set(const struct scmi_handle *handle,
198 198
199 ret = scmi_do_xfer(handle, t); 199 ret = scmi_do_xfer(handle, t);
200 200
201 scmi_one_xfer_put(handle, t); 201 scmi_xfer_put(handle, t);
202 return ret; 202 return ret;
203} 203}
204 204
@@ -209,7 +209,7 @@ static int scmi_sensor_reading_get(const struct scmi_handle *handle,
209 struct scmi_xfer *t; 209 struct scmi_xfer *t;
210 struct scmi_msg_sensor_reading_get *sensor; 210 struct scmi_msg_sensor_reading_get *sensor;
211 211
212 ret = scmi_one_xfer_init(handle, SENSOR_READING_GET, 212 ret = scmi_xfer_get_init(handle, SENSOR_READING_GET,
213 SCMI_PROTOCOL_SENSOR, sizeof(*sensor), 213 SCMI_PROTOCOL_SENSOR, sizeof(*sensor),
214 sizeof(u64), &t); 214 sizeof(u64), &t);
215 if (ret) 215 if (ret)
@@ -227,7 +227,7 @@ static int scmi_sensor_reading_get(const struct scmi_handle *handle,
227 *value |= (u64)le32_to_cpu(*(pval + 1)) << 32; 227 *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
228 } 228 }
229 229
230 scmi_one_xfer_put(handle, t); 230 scmi_xfer_put(handle, t);
231 return ret; 231 return ret;
232} 232}
233 233
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 5229036dcfbf..b74a533ef35b 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Texas Instruments System Control Interface Protocol Driver 3 * Texas Instruments System Control Interface Protocol Driver
3 * 4 *
4 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ 5 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
5 * Nishanth Menon 6 * Nishanth Menon
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#define pr_fmt(fmt) "%s: " fmt, __func__ 9#define pr_fmt(fmt) "%s: " fmt, __func__
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 9b611e9e6f6d..12bf316b68df 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: BSD-3-Clause
1/* 2/*
2 * Texas Instruments System Control Interface (TISCI) Protocol 3 * Texas Instruments System Control Interface (TISCI) Protocol
3 * 4 *
@@ -6,35 +7,6 @@
6 * See: http://processors.wiki.ti.com/index.php/TISCI for details 7 * See: http://processors.wiki.ti.com/index.php/TISCI for details
7 * 8 *
8 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ 9 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the
20 * distribution.
21 *
22 * Neither the name of Texas Instruments Incorporated nor the names of
23 * its contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 */ 10 */
39 11
40#ifndef __TI_SCI_H 12#ifndef __TI_SCI_H
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 19a0e83f260d..8d731d6c3e54 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -104,16 +104,6 @@ config MVEBU_DEVBUS
104 Armada 370 and Armada XP. This controller allows to handle flash 104 Armada 370 and Armada XP. This controller allows to handle flash
105 devices such as NOR, NAND, SRAM, and FPGA. 105 devices such as NOR, NAND, SRAM, and FPGA.
106 106
107config TEGRA20_MC
108 bool "Tegra20 Memory Controller(MC) driver"
109 default y
110 depends on ARCH_TEGRA_2x_SOC
111 help
112 This driver is for the Memory Controller(MC) module available
113 in Tegra20 SoCs, mainly for a address translation fault
114 analysis, especially for IOMMU/GART(Graphics Address
115 Relocation Table) module.
116
117config FSL_CORENET_CF 107config FSL_CORENET_CF
118 tristate "Freescale CoreNet Error Reporting" 108 tristate "Freescale CoreNet Error Reporting"
119 depends on FSL_SOC_BOOKE 109 depends on FSL_SOC_BOOKE
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 66f55240830e..a01ab3e22f94 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o
16obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o 16obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
17obj-$(CONFIG_FSL_IFC) += fsl_ifc.o 17obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
18obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o 18obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
19obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
20obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o 19obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
21obj-$(CONFIG_MTK_SMI) += mtk-smi.o 20obj-$(CONFIG_MTK_SMI) += mtk-smi.o
22obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o 21obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c
index e9c1485c32b9..04599eccd604 100644
--- a/drivers/memory/brcmstb_dpfe.c
+++ b/drivers/memory/brcmstb_dpfe.c
@@ -176,7 +176,6 @@ struct private_data {
176 void __iomem *dmem; 176 void __iomem *dmem;
177 void __iomem *imem; 177 void __iomem *imem;
178 struct device *dev; 178 struct device *dev;
179 unsigned int index;
180 struct mutex lock; 179 struct mutex lock;
181}; 180};
182 181
@@ -674,10 +673,8 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
674{ 673{
675 struct device *dev = &pdev->dev; 674 struct device *dev = &pdev->dev;
676 struct private_data *priv; 675 struct private_data *priv;
677 struct device *dpfe_dev;
678 struct init_data init; 676 struct init_data init;
679 struct resource *res; 677 struct resource *res;
680 u32 index;
681 int ret; 678 int ret;
682 679
683 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 680 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -687,11 +684,6 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
687 mutex_init(&priv->lock); 684 mutex_init(&priv->lock);
688 platform_set_drvdata(pdev, priv); 685 platform_set_drvdata(pdev, priv);
689 686
690 /* Cell index is optional; default to 0 if not present. */
691 ret = of_property_read_u32(dev->of_node, "cell-index", &index);
692 if (ret)
693 index = 0;
694
695 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-cpu"); 687 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-cpu");
696 priv->regs = devm_ioremap_resource(dev, res); 688 priv->regs = devm_ioremap_resource(dev, res);
697 if (IS_ERR(priv->regs)) { 689 if (IS_ERR(priv->regs)) {
@@ -715,35 +707,20 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
715 707
716 ret = brcmstb_dpfe_download_firmware(pdev, &init); 708 ret = brcmstb_dpfe_download_firmware(pdev, &init);
717 if (ret) 709 if (ret)
718 goto err; 710 return ret;
719
720 dpfe_dev = devm_kzalloc(dev, sizeof(*dpfe_dev), GFP_KERNEL);
721 if (!dpfe_dev) {
722 ret = -ENOMEM;
723 goto err;
724 }
725
726 priv->dev = dpfe_dev;
727 priv->index = index;
728 711
729 dpfe_dev->parent = dev; 712 ret = sysfs_create_groups(&pdev->dev.kobj, dpfe_groups);
730 dpfe_dev->groups = dpfe_groups; 713 if (!ret)
731 dpfe_dev->of_node = dev->of_node; 714 dev_info(dev, "registered.\n");
732 dev_set_drvdata(dpfe_dev, priv);
733 dev_set_name(dpfe_dev, "dpfe%u", index);
734 715
735 ret = device_register(dpfe_dev); 716 return ret;
736 if (ret) 717}
737 goto err;
738 718
739 dev_info(dev, "registered.\n"); 719static int brcmstb_dpfe_remove(struct platform_device *pdev)
720{
721 sysfs_remove_groups(&pdev->dev.kobj, dpfe_groups);
740 722
741 return 0; 723 return 0;
742
743err:
744 dev_err(dev, "failed to initialize -- error %d\n", ret);
745
746 return ret;
747} 724}
748 725
749static const struct of_device_id brcmstb_dpfe_of_match[] = { 726static const struct of_device_id brcmstb_dpfe_of_match[] = {
@@ -758,6 +735,7 @@ static struct platform_driver brcmstb_dpfe_driver = {
758 .of_match_table = brcmstb_dpfe_of_match, 735 .of_match_table = brcmstb_dpfe_of_match,
759 }, 736 },
760 .probe = brcmstb_dpfe_probe, 737 .probe = brcmstb_dpfe_probe,
738 .remove = brcmstb_dpfe_remove,
761 .resume = brcmstb_dpfe_resume, 739 .resume = brcmstb_dpfe_resume,
762}; 740};
763 741
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 90a66b3f7ae1..c215287e80cf 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -2060,8 +2060,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
2060 * timings. 2060 * timings.
2061 */ 2061 */
2062 name = gpmc_cs_get_name(cs); 2062 name = gpmc_cs_get_name(cs);
2063 if (name && child->name && of_node_cmp(child->name, name) == 0) 2063 if (name && of_node_cmp(child->name, name) == 0)
2064 goto no_timings; 2064 goto no_timings;
2065 2065
2066 ret = gpmc_cs_request(cs, resource_size(&res), &base); 2066 ret = gpmc_cs_request(cs, resource_size(&res), &base);
2067 if (ret < 0) { 2067 if (ret < 0) {
diff --git a/drivers/memory/tegra/Makefile b/drivers/memory/tegra/Makefile
index ce87a9470034..94ab16ba075b 100644
--- a/drivers/memory/tegra/Makefile
+++ b/drivers/memory/tegra/Makefile
@@ -1,6 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2tegra-mc-y := mc.o 2tegra-mc-y := mc.o
3 3
4tegra-mc-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20.o
4tegra-mc-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30.o 5tegra-mc-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30.o
5tegra-mc-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114.o 6tegra-mc-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114.o
6tegra-mc-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o 7tegra-mc-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index a4803ac192bb..bb93cc53554e 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/clk.h> 9#include <linux/clk.h>
10#include <linux/delay.h>
10#include <linux/interrupt.h> 11#include <linux/interrupt.h>
11#include <linux/kernel.h> 12#include <linux/kernel.h>
12#include <linux/module.h> 13#include <linux/module.h>
@@ -20,14 +21,6 @@
20#include "mc.h" 21#include "mc.h"
21 22
22#define MC_INTSTATUS 0x000 23#define MC_INTSTATUS 0x000
23#define MC_INT_DECERR_MTS (1 << 16)
24#define MC_INT_SECERR_SEC (1 << 13)
25#define MC_INT_DECERR_VPR (1 << 12)
26#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
27#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
28#define MC_INT_ARBITRATION_EMEM (1 << 9)
29#define MC_INT_SECURITY_VIOLATION (1 << 8)
30#define MC_INT_DECERR_EMEM (1 << 6)
31 24
32#define MC_INTMASK 0x004 25#define MC_INTMASK 0x004
33 26
@@ -45,6 +38,9 @@
45 38
46#define MC_ERR_ADR 0x0c 39#define MC_ERR_ADR 0x0c
47 40
41#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
42#define MC_SECURITY_VIOLATION_STATUS 0x74
43
48#define MC_EMEM_ARB_CFG 0x90 44#define MC_EMEM_ARB_CFG 0x90
49#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) (((x) & 0x1ff) << 0) 45#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) (((x) & 0x1ff) << 0)
50#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff 46#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff
@@ -54,6 +50,9 @@
54#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0) 50#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
55 51
56static const struct of_device_id tegra_mc_of_match[] = { 52static const struct of_device_id tegra_mc_of_match[] = {
53#ifdef CONFIG_ARCH_TEGRA_2x_SOC
54 { .compatible = "nvidia,tegra20-mc", .data = &tegra20_mc_soc },
55#endif
57#ifdef CONFIG_ARCH_TEGRA_3x_SOC 56#ifdef CONFIG_ARCH_TEGRA_3x_SOC
58 { .compatible = "nvidia,tegra30-mc", .data = &tegra30_mc_soc }, 57 { .compatible = "nvidia,tegra30-mc", .data = &tegra30_mc_soc },
59#endif 58#endif
@@ -73,6 +72,207 @@ static const struct of_device_id tegra_mc_of_match[] = {
73}; 72};
74MODULE_DEVICE_TABLE(of, tegra_mc_of_match); 73MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
75 74
75static int terga_mc_block_dma_common(struct tegra_mc *mc,
76 const struct tegra_mc_reset *rst)
77{
78 unsigned long flags;
79 u32 value;
80
81 spin_lock_irqsave(&mc->lock, flags);
82
83 value = mc_readl(mc, rst->control) | BIT(rst->bit);
84 mc_writel(mc, value, rst->control);
85
86 spin_unlock_irqrestore(&mc->lock, flags);
87
88 return 0;
89}
90
91static bool terga_mc_dma_idling_common(struct tegra_mc *mc,
92 const struct tegra_mc_reset *rst)
93{
94 return (mc_readl(mc, rst->status) & BIT(rst->bit)) != 0;
95}
96
97static int terga_mc_unblock_dma_common(struct tegra_mc *mc,
98 const struct tegra_mc_reset *rst)
99{
100 unsigned long flags;
101 u32 value;
102
103 spin_lock_irqsave(&mc->lock, flags);
104
105 value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
106 mc_writel(mc, value, rst->control);
107
108 spin_unlock_irqrestore(&mc->lock, flags);
109
110 return 0;
111}
112
113static int terga_mc_reset_status_common(struct tegra_mc *mc,
114 const struct tegra_mc_reset *rst)
115{
116 return (mc_readl(mc, rst->control) & BIT(rst->bit)) != 0;
117}
118
119const struct tegra_mc_reset_ops terga_mc_reset_ops_common = {
120 .block_dma = terga_mc_block_dma_common,
121 .dma_idling = terga_mc_dma_idling_common,
122 .unblock_dma = terga_mc_unblock_dma_common,
123 .reset_status = terga_mc_reset_status_common,
124};
125
126static inline struct tegra_mc *reset_to_mc(struct reset_controller_dev *rcdev)
127{
128 return container_of(rcdev, struct tegra_mc, reset);
129}
130
131static const struct tegra_mc_reset *tegra_mc_reset_find(struct tegra_mc *mc,
132 unsigned long id)
133{
134 unsigned int i;
135
136 for (i = 0; i < mc->soc->num_resets; i++)
137 if (mc->soc->resets[i].id == id)
138 return &mc->soc->resets[i];
139
140 return NULL;
141}
142
143static int tegra_mc_hotreset_assert(struct reset_controller_dev *rcdev,
144 unsigned long id)
145{
146 struct tegra_mc *mc = reset_to_mc(rcdev);
147 const struct tegra_mc_reset_ops *rst_ops;
148 const struct tegra_mc_reset *rst;
149 int retries = 500;
150 int err;
151
152 rst = tegra_mc_reset_find(mc, id);
153 if (!rst)
154 return -ENODEV;
155
156 rst_ops = mc->soc->reset_ops;
157 if (!rst_ops)
158 return -ENODEV;
159
160 if (rst_ops->block_dma) {
161 /* block clients DMA requests */
162 err = rst_ops->block_dma(mc, rst);
163 if (err) {
164 dev_err(mc->dev, "Failed to block %s DMA: %d\n",
165 rst->name, err);
166 return err;
167 }
168 }
169
170 if (rst_ops->dma_idling) {
171 /* wait for completion of the outstanding DMA requests */
172 while (!rst_ops->dma_idling(mc, rst)) {
173 if (!retries--) {
174 dev_err(mc->dev, "Failed to flush %s DMA\n",
175 rst->name);
176 return -EBUSY;
177 }
178
179 usleep_range(10, 100);
180 }
181 }
182
183 if (rst_ops->hotreset_assert) {
184 /* clear clients DMA requests sitting before arbitration */
185 err = rst_ops->hotreset_assert(mc, rst);
186 if (err) {
187 dev_err(mc->dev, "Failed to hot reset %s: %d\n",
188 rst->name, err);
189 return err;
190 }
191 }
192
193 return 0;
194}
195
196static int tegra_mc_hotreset_deassert(struct reset_controller_dev *rcdev,
197 unsigned long id)
198{
199 struct tegra_mc *mc = reset_to_mc(rcdev);
200 const struct tegra_mc_reset_ops *rst_ops;
201 const struct tegra_mc_reset *rst;
202 int err;
203
204 rst = tegra_mc_reset_find(mc, id);
205 if (!rst)
206 return -ENODEV;
207
208 rst_ops = mc->soc->reset_ops;
209 if (!rst_ops)
210 return -ENODEV;
211
212 if (rst_ops->hotreset_deassert) {
213 /* take out client from hot reset */
214 err = rst_ops->hotreset_deassert(mc, rst);
215 if (err) {
216 dev_err(mc->dev, "Failed to deassert hot reset %s: %d\n",
217 rst->name, err);
218 return err;
219 }
220 }
221
222 if (rst_ops->unblock_dma) {
223 /* allow new DMA requests to proceed to arbitration */
224 err = rst_ops->unblock_dma(mc, rst);
225 if (err) {
226 dev_err(mc->dev, "Failed to unblock %s DMA : %d\n",
227 rst->name, err);
228 return err;
229 }
230 }
231
232 return 0;
233}
234
235static int tegra_mc_hotreset_status(struct reset_controller_dev *rcdev,
236 unsigned long id)
237{
238 struct tegra_mc *mc = reset_to_mc(rcdev);
239 const struct tegra_mc_reset_ops *rst_ops;
240 const struct tegra_mc_reset *rst;
241
242 rst = tegra_mc_reset_find(mc, id);
243 if (!rst)
244 return -ENODEV;
245
246 rst_ops = mc->soc->reset_ops;
247 if (!rst_ops)
248 return -ENODEV;
249
250 return rst_ops->reset_status(mc, rst);
251}
252
253static const struct reset_control_ops tegra_mc_reset_ops = {
254 .assert = tegra_mc_hotreset_assert,
255 .deassert = tegra_mc_hotreset_deassert,
256 .status = tegra_mc_hotreset_status,
257};
258
259static int tegra_mc_reset_setup(struct tegra_mc *mc)
260{
261 int err;
262
263 mc->reset.ops = &tegra_mc_reset_ops;
264 mc->reset.owner = THIS_MODULE;
265 mc->reset.of_node = mc->dev->of_node;
266 mc->reset.of_reset_n_cells = 1;
267 mc->reset.nr_resets = mc->soc->num_resets;
268
269 err = reset_controller_register(&mc->reset);
270 if (err < 0)
271 return err;
272
273 return 0;
274}
275
76static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc) 276static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
77{ 277{
78 unsigned long long tick; 278 unsigned long long tick;
@@ -229,6 +429,7 @@ static int tegra_mc_setup_timings(struct tegra_mc *mc)
229static const char *const status_names[32] = { 429static const char *const status_names[32] = {
230 [ 1] = "External interrupt", 430 [ 1] = "External interrupt",
231 [ 6] = "EMEM address decode error", 431 [ 6] = "EMEM address decode error",
432 [ 7] = "GART page fault",
232 [ 8] = "Security violation", 433 [ 8] = "Security violation",
233 [ 9] = "EMEM arbitration error", 434 [ 9] = "EMEM arbitration error",
234 [10] = "Page fault", 435 [10] = "Page fault",
@@ -248,12 +449,13 @@ static const char *const error_names[8] = {
248static irqreturn_t tegra_mc_irq(int irq, void *data) 449static irqreturn_t tegra_mc_irq(int irq, void *data)
249{ 450{
250 struct tegra_mc *mc = data; 451 struct tegra_mc *mc = data;
251 unsigned long status, mask; 452 unsigned long status;
252 unsigned int bit; 453 unsigned int bit;
253 454
254 /* mask all interrupts to avoid flooding */ 455 /* mask all interrupts to avoid flooding */
255 status = mc_readl(mc, MC_INTSTATUS); 456 status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
256 mask = mc_readl(mc, MC_INTMASK); 457 if (!status)
458 return IRQ_NONE;
257 459
258 for_each_set_bit(bit, &status, 32) { 460 for_each_set_bit(bit, &status, 32) {
259 const char *error = status_names[bit] ?: "unknown"; 461 const char *error = status_names[bit] ?: "unknown";
@@ -341,12 +543,78 @@ static irqreturn_t tegra_mc_irq(int irq, void *data)
341 return IRQ_HANDLED; 543 return IRQ_HANDLED;
342} 544}
343 545
546static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
547{
548 struct tegra_mc *mc = data;
549 unsigned long status;
550 unsigned int bit;
551
552 /* mask all interrupts to avoid flooding */
553 status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
554 if (!status)
555 return IRQ_NONE;
556
557 for_each_set_bit(bit, &status, 32) {
558 const char *direction = "read", *secure = "";
559 const char *error = status_names[bit];
560 const char *client, *desc;
561 phys_addr_t addr;
562 u32 value, reg;
563 u8 id, type;
564
565 switch (BIT(bit)) {
566 case MC_INT_DECERR_EMEM:
567 reg = MC_DECERR_EMEM_OTHERS_STATUS;
568 value = mc_readl(mc, reg);
569
570 id = value & mc->soc->client_id_mask;
571 desc = error_names[2];
572
573 if (value & BIT(31))
574 direction = "write";
575 break;
576
577 case MC_INT_INVALID_GART_PAGE:
578 dev_err_ratelimited(mc->dev, "%s\n", error);
579 continue;
580
581 case MC_INT_SECURITY_VIOLATION:
582 reg = MC_SECURITY_VIOLATION_STATUS;
583 value = mc_readl(mc, reg);
584
585 id = value & mc->soc->client_id_mask;
586 type = (value & BIT(30)) ? 4 : 3;
587 desc = error_names[type];
588 secure = "secure ";
589
590 if (value & BIT(31))
591 direction = "write";
592 break;
593
594 default:
595 continue;
596 }
597
598 client = mc->soc->clients[id].name;
599 addr = mc_readl(mc, reg + sizeof(u32));
600
601 dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s)\n",
602 client, secure, direction, &addr, error,
603 desc);
604 }
605
606 /* clear interrupts */
607 mc_writel(mc, status, MC_INTSTATUS);
608
609 return IRQ_HANDLED;
610}
611
344static int tegra_mc_probe(struct platform_device *pdev) 612static int tegra_mc_probe(struct platform_device *pdev)
345{ 613{
346 const struct of_device_id *match; 614 const struct of_device_id *match;
347 struct resource *res; 615 struct resource *res;
348 struct tegra_mc *mc; 616 struct tegra_mc *mc;
349 u32 value; 617 void *isr;
350 int err; 618 int err;
351 619
352 match = of_match_node(tegra_mc_of_match, pdev->dev.of_node); 620 match = of_match_node(tegra_mc_of_match, pdev->dev.of_node);
@@ -358,6 +626,7 @@ static int tegra_mc_probe(struct platform_device *pdev)
358 return -ENOMEM; 626 return -ENOMEM;
359 627
360 platform_set_drvdata(pdev, mc); 628 platform_set_drvdata(pdev, mc);
629 spin_lock_init(&mc->lock);
361 mc->soc = match->data; 630 mc->soc = match->data;
362 mc->dev = &pdev->dev; 631 mc->dev = &pdev->dev;
363 632
@@ -369,18 +638,32 @@ static int tegra_mc_probe(struct platform_device *pdev)
369 if (IS_ERR(mc->regs)) 638 if (IS_ERR(mc->regs))
370 return PTR_ERR(mc->regs); 639 return PTR_ERR(mc->regs);
371 640
372 mc->clk = devm_clk_get(&pdev->dev, "mc"); 641#ifdef CONFIG_ARCH_TEGRA_2x_SOC
373 if (IS_ERR(mc->clk)) { 642 if (mc->soc == &tegra20_mc_soc) {
374 dev_err(&pdev->dev, "failed to get MC clock: %ld\n", 643 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
375 PTR_ERR(mc->clk)); 644 mc->regs2 = devm_ioremap_resource(&pdev->dev, res);
376 return PTR_ERR(mc->clk); 645 if (IS_ERR(mc->regs2))
377 } 646 return PTR_ERR(mc->regs2);
378 647
379 err = tegra_mc_setup_latency_allowance(mc); 648 isr = tegra20_mc_irq;
380 if (err < 0) { 649 } else
381 dev_err(&pdev->dev, "failed to setup latency allowance: %d\n", 650#endif
382 err); 651 {
383 return err; 652 mc->clk = devm_clk_get(&pdev->dev, "mc");
653 if (IS_ERR(mc->clk)) {
654 dev_err(&pdev->dev, "failed to get MC clock: %ld\n",
655 PTR_ERR(mc->clk));
656 return PTR_ERR(mc->clk);
657 }
658
659 err = tegra_mc_setup_latency_allowance(mc);
660 if (err < 0) {
661 dev_err(&pdev->dev, "failed to setup latency allowance: %d\n",
662 err);
663 return err;
664 }
665
666 isr = tegra_mc_irq;
384 } 667 }
385 668
386 err = tegra_mc_setup_timings(mc); 669 err = tegra_mc_setup_timings(mc);
@@ -389,13 +672,11 @@ static int tegra_mc_probe(struct platform_device *pdev)
389 return err; 672 return err;
390 } 673 }
391 674
392 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU)) { 675 err = tegra_mc_reset_setup(mc);
393 mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc); 676 if (err < 0) {
394 if (IS_ERR(mc->smmu)) { 677 dev_err(&pdev->dev, "failed to register reset controller: %d\n",
395 dev_err(&pdev->dev, "failed to probe SMMU: %ld\n", 678 err);
396 PTR_ERR(mc->smmu)); 679 return err;
397 return PTR_ERR(mc->smmu);
398 }
399 } 680 }
400 681
401 mc->irq = platform_get_irq(pdev, 0); 682 mc->irq = platform_get_irq(pdev, 0);
@@ -404,7 +685,11 @@ static int tegra_mc_probe(struct platform_device *pdev)
404 return mc->irq; 685 return mc->irq;
405 } 686 }
406 687
407 err = devm_request_irq(&pdev->dev, mc->irq, tegra_mc_irq, IRQF_SHARED, 688 WARN(!mc->soc->client_id_mask, "Missing client ID mask for this SoC\n");
689
690 mc_writel(mc, mc->soc->intmask, MC_INTMASK);
691
692 err = devm_request_irq(&pdev->dev, mc->irq, isr, IRQF_SHARED,
408 dev_name(&pdev->dev), mc); 693 dev_name(&pdev->dev), mc);
409 if (err < 0) { 694 if (err < 0) {
410 dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq, 695 dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
@@ -412,13 +697,14 @@ static int tegra_mc_probe(struct platform_device *pdev)
412 return err; 697 return err;
413 } 698 }
414 699
415 WARN(!mc->soc->client_id_mask, "Missing client ID mask for this SoC\n"); 700 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU)) {
416 701 mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
417 value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | 702 if (IS_ERR(mc->smmu)) {
418 MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE | 703 dev_err(&pdev->dev, "failed to probe SMMU: %ld\n",
419 MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM; 704 PTR_ERR(mc->smmu));
420 705 return PTR_ERR(mc->smmu);
421 mc_writel(mc, value, MC_INTMASK); 706 }
707 }
422 708
423 return 0; 709 return 0;
424} 710}
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index ddb16676c3af..01065f12ebeb 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -14,17 +14,39 @@
14 14
15#include <soc/tegra/mc.h> 15#include <soc/tegra/mc.h>
16 16
17#define MC_INT_DECERR_MTS (1 << 16)
18#define MC_INT_SECERR_SEC (1 << 13)
19#define MC_INT_DECERR_VPR (1 << 12)
20#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
21#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
22#define MC_INT_ARBITRATION_EMEM (1 << 9)
23#define MC_INT_SECURITY_VIOLATION (1 << 8)
24#define MC_INT_INVALID_GART_PAGE (1 << 7)
25#define MC_INT_DECERR_EMEM (1 << 6)
26
17static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset) 27static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
18{ 28{
29 if (mc->regs2 && offset >= 0x24)
30 return readl(mc->regs2 + offset - 0x3c);
31
19 return readl(mc->regs + offset); 32 return readl(mc->regs + offset);
20} 33}
21 34
22static inline void mc_writel(struct tegra_mc *mc, u32 value, 35static inline void mc_writel(struct tegra_mc *mc, u32 value,
23 unsigned long offset) 36 unsigned long offset)
24{ 37{
38 if (mc->regs2 && offset >= 0x24)
39 return writel(value, mc->regs2 + offset - 0x3c);
40
25 writel(value, mc->regs + offset); 41 writel(value, mc->regs + offset);
26} 42}
27 43
44extern const struct tegra_mc_reset_ops terga_mc_reset_ops_common;
45
46#ifdef CONFIG_ARCH_TEGRA_2x_SOC
47extern const struct tegra_mc_soc tegra20_mc_soc;
48#endif
49
28#ifdef CONFIG_ARCH_TEGRA_3x_SOC 50#ifdef CONFIG_ARCH_TEGRA_3x_SOC
29extern const struct tegra_mc_soc tegra30_mc_soc; 51extern const struct tegra_mc_soc tegra30_mc_soc;
30#endif 52#endif
diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index b20e6e3e208e..6560a5101322 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -938,6 +938,34 @@ static const struct tegra_smmu_soc tegra114_smmu_soc = {
938 .num_asids = 4, 938 .num_asids = 4,
939}; 939};
940 940
941#define TEGRA114_MC_RESET(_name, _control, _status, _bit) \
942 { \
943 .name = #_name, \
944 .id = TEGRA114_MC_RESET_##_name, \
945 .control = _control, \
946 .status = _status, \
947 .bit = _bit, \
948 }
949
950static const struct tegra_mc_reset tegra114_mc_resets[] = {
951 TEGRA114_MC_RESET(AVPC, 0x200, 0x204, 1),
952 TEGRA114_MC_RESET(DC, 0x200, 0x204, 2),
953 TEGRA114_MC_RESET(DCB, 0x200, 0x204, 3),
954 TEGRA114_MC_RESET(EPP, 0x200, 0x204, 4),
955 TEGRA114_MC_RESET(2D, 0x200, 0x204, 5),
956 TEGRA114_MC_RESET(HC, 0x200, 0x204, 6),
957 TEGRA114_MC_RESET(HDA, 0x200, 0x204, 7),
958 TEGRA114_MC_RESET(ISP, 0x200, 0x204, 8),
959 TEGRA114_MC_RESET(MPCORE, 0x200, 0x204, 9),
960 TEGRA114_MC_RESET(MPCORELP, 0x200, 0x204, 10),
961 TEGRA114_MC_RESET(MPE, 0x200, 0x204, 11),
962 TEGRA114_MC_RESET(3D, 0x200, 0x204, 12),
963 TEGRA114_MC_RESET(3D2, 0x200, 0x204, 13),
964 TEGRA114_MC_RESET(PPCS, 0x200, 0x204, 14),
965 TEGRA114_MC_RESET(VDE, 0x200, 0x204, 16),
966 TEGRA114_MC_RESET(VI, 0x200, 0x204, 17),
967};
968
941const struct tegra_mc_soc tegra114_mc_soc = { 969const struct tegra_mc_soc tegra114_mc_soc = {
942 .clients = tegra114_mc_clients, 970 .clients = tegra114_mc_clients,
943 .num_clients = ARRAY_SIZE(tegra114_mc_clients), 971 .num_clients = ARRAY_SIZE(tegra114_mc_clients),
@@ -945,4 +973,9 @@ const struct tegra_mc_soc tegra114_mc_soc = {
945 .atom_size = 32, 973 .atom_size = 32,
946 .client_id_mask = 0x7f, 974 .client_id_mask = 0x7f,
947 .smmu = &tegra114_smmu_soc, 975 .smmu = &tegra114_smmu_soc,
976 .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
977 MC_INT_DECERR_EMEM,
978 .reset_ops = &terga_mc_reset_ops_common,
979 .resets = tegra114_mc_resets,
980 .num_resets = ARRAY_SIZE(tegra114_mc_resets),
948}; 981};
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 8b6360eabb8a..b561a1fe7f46 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1012,6 +1012,42 @@ static const struct tegra_smmu_group_soc tegra124_groups[] = {
1012 }, 1012 },
1013}; 1013};
1014 1014
1015#define TEGRA124_MC_RESET(_name, _control, _status, _bit) \
1016 { \
1017 .name = #_name, \
1018 .id = TEGRA124_MC_RESET_##_name, \
1019 .control = _control, \
1020 .status = _status, \
1021 .bit = _bit, \
1022 }
1023
1024static const struct tegra_mc_reset tegra124_mc_resets[] = {
1025 TEGRA124_MC_RESET(AFI, 0x200, 0x204, 0),
1026 TEGRA124_MC_RESET(AVPC, 0x200, 0x204, 1),
1027 TEGRA124_MC_RESET(DC, 0x200, 0x204, 2),
1028 TEGRA124_MC_RESET(DCB, 0x200, 0x204, 3),
1029 TEGRA124_MC_RESET(HC, 0x200, 0x204, 6),
1030 TEGRA124_MC_RESET(HDA, 0x200, 0x204, 7),
1031 TEGRA124_MC_RESET(ISP2, 0x200, 0x204, 8),
1032 TEGRA124_MC_RESET(MPCORE, 0x200, 0x204, 9),
1033 TEGRA124_MC_RESET(MPCORELP, 0x200, 0x204, 10),
1034 TEGRA124_MC_RESET(MSENC, 0x200, 0x204, 11),
1035 TEGRA124_MC_RESET(PPCS, 0x200, 0x204, 14),
1036 TEGRA124_MC_RESET(SATA, 0x200, 0x204, 15),
1037 TEGRA124_MC_RESET(VDE, 0x200, 0x204, 16),
1038 TEGRA124_MC_RESET(VI, 0x200, 0x204, 17),
1039 TEGRA124_MC_RESET(VIC, 0x200, 0x204, 18),
1040 TEGRA124_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
1041 TEGRA124_MC_RESET(XUSB_DEV, 0x200, 0x204, 20),
1042 TEGRA124_MC_RESET(TSEC, 0x200, 0x204, 21),
1043 TEGRA124_MC_RESET(SDMMC1, 0x200, 0x204, 22),
1044 TEGRA124_MC_RESET(SDMMC2, 0x200, 0x204, 23),
1045 TEGRA124_MC_RESET(SDMMC3, 0x200, 0x204, 25),
1046 TEGRA124_MC_RESET(SDMMC4, 0x970, 0x974, 0),
1047 TEGRA124_MC_RESET(ISP2B, 0x970, 0x974, 1),
1048 TEGRA124_MC_RESET(GPU, 0x970, 0x974, 2),
1049};
1050
1015#ifdef CONFIG_ARCH_TEGRA_124_SOC 1051#ifdef CONFIG_ARCH_TEGRA_124_SOC
1016static const struct tegra_smmu_soc tegra124_smmu_soc = { 1052static const struct tegra_smmu_soc tegra124_smmu_soc = {
1017 .clients = tegra124_mc_clients, 1053 .clients = tegra124_mc_clients,
@@ -1035,6 +1071,12 @@ const struct tegra_mc_soc tegra124_mc_soc = {
1035 .smmu = &tegra124_smmu_soc, 1071 .smmu = &tegra124_smmu_soc,
1036 .emem_regs = tegra124_mc_emem_regs, 1072 .emem_regs = tegra124_mc_emem_regs,
1037 .num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs), 1073 .num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs),
1074 .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
1075 MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
1076 MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
1077 .reset_ops = &terga_mc_reset_ops_common,
1078 .resets = tegra124_mc_resets,
1079 .num_resets = ARRAY_SIZE(tegra124_mc_resets),
1038}; 1080};
1039#endif /* CONFIG_ARCH_TEGRA_124_SOC */ 1081#endif /* CONFIG_ARCH_TEGRA_124_SOC */
1040 1082
@@ -1059,5 +1101,11 @@ const struct tegra_mc_soc tegra132_mc_soc = {
1059 .atom_size = 32, 1101 .atom_size = 32,
1060 .client_id_mask = 0x7f, 1102 .client_id_mask = 0x7f,
1061 .smmu = &tegra132_smmu_soc, 1103 .smmu = &tegra132_smmu_soc,
1104 .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
1105 MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
1106 MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
1107 .reset_ops = &terga_mc_reset_ops_common,
1108 .resets = tegra124_mc_resets,
1109 .num_resets = ARRAY_SIZE(tegra124_mc_resets),
1062}; 1110};
1063#endif /* CONFIG_ARCH_TEGRA_132_SOC */ 1111#endif /* CONFIG_ARCH_TEGRA_132_SOC */
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
new file mode 100644
index 000000000000..7119e532471c
--- /dev/null
+++ b/drivers/memory/tegra/tegra20.c
@@ -0,0 +1,296 @@
1/*
2 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <dt-bindings/memory/tegra20-mc.h>
10
11#include "mc.h"
12
13static const struct tegra_mc_client tegra20_mc_clients[] = {
14 {
15 .id = 0x00,
16 .name = "display0a",
17 }, {
18 .id = 0x01,
19 .name = "display0ab",
20 }, {
21 .id = 0x02,
22 .name = "display0b",
23 }, {
24 .id = 0x03,
25 .name = "display0bb",
26 }, {
27 .id = 0x04,
28 .name = "display0c",
29 }, {
30 .id = 0x05,
31 .name = "display0cb",
32 }, {
33 .id = 0x06,
34 .name = "display1b",
35 }, {
36 .id = 0x07,
37 .name = "display1bb",
38 }, {
39 .id = 0x08,
40 .name = "eppup",
41 }, {
42 .id = 0x09,
43 .name = "g2pr",
44 }, {
45 .id = 0x0a,
46 .name = "g2sr",
47 }, {
48 .id = 0x0b,
49 .name = "mpeunifbr",
50 }, {
51 .id = 0x0c,
52 .name = "viruv",
53 }, {
54 .id = 0x0d,
55 .name = "avpcarm7r",
56 }, {
57 .id = 0x0e,
58 .name = "displayhc",
59 }, {
60 .id = 0x0f,
61 .name = "displayhcb",
62 }, {
63 .id = 0x10,
64 .name = "fdcdrd",
65 }, {
66 .id = 0x11,
67 .name = "g2dr",
68 }, {
69 .id = 0x12,
70 .name = "host1xdmar",
71 }, {
72 .id = 0x13,
73 .name = "host1xr",
74 }, {
75 .id = 0x14,
76 .name = "idxsrd",
77 }, {
78 .id = 0x15,
79 .name = "mpcorer",
80 }, {
81 .id = 0x16,
82 .name = "mpe_ipred",
83 }, {
84 .id = 0x17,
85 .name = "mpeamemrd",
86 }, {
87 .id = 0x18,
88 .name = "mpecsrd",
89 }, {
90 .id = 0x19,
91 .name = "ppcsahbdmar",
92 }, {
93 .id = 0x1a,
94 .name = "ppcsahbslvr",
95 }, {
96 .id = 0x1b,
97 .name = "texsrd",
98 }, {
99 .id = 0x1c,
100 .name = "vdebsevr",
101 }, {
102 .id = 0x1d,
103 .name = "vdember",
104 }, {
105 .id = 0x1e,
106 .name = "vdemcer",
107 }, {
108 .id = 0x1f,
109 .name = "vdetper",
110 }, {
111 .id = 0x20,
112 .name = "eppu",
113 }, {
114 .id = 0x21,
115 .name = "eppv",
116 }, {
117 .id = 0x22,
118 .name = "eppy",
119 }, {
120 .id = 0x23,
121 .name = "mpeunifbw",
122 }, {
123 .id = 0x24,
124 .name = "viwsb",
125 }, {
126 .id = 0x25,
127 .name = "viwu",
128 }, {
129 .id = 0x26,
130 .name = "viwv",
131 }, {
132 .id = 0x27,
133 .name = "viwy",
134 }, {
135 .id = 0x28,
136 .name = "g2dw",
137 }, {
138 .id = 0x29,
139 .name = "avpcarm7w",
140 }, {
141 .id = 0x2a,
142 .name = "fdcdwr",
143 }, {
144 .id = 0x2b,
145 .name = "host1xw",
146 }, {
147 .id = 0x2c,
148 .name = "ispw",
149 }, {
150 .id = 0x2d,
151 .name = "mpcorew",
152 }, {
153 .id = 0x2e,
154 .name = "mpecswr",
155 }, {
156 .id = 0x2f,
157 .name = "ppcsahbdmaw",
158 }, {
159 .id = 0x30,
160 .name = "ppcsahbslvw",
161 }, {
162 .id = 0x31,
163 .name = "vdebsevw",
164 }, {
165 .id = 0x32,
166 .name = "vdembew",
167 }, {
168 .id = 0x33,
169 .name = "vdetpmw",
170 },
171};
172
173#define TEGRA20_MC_RESET(_name, _control, _status, _reset, _bit) \
174 { \
175 .name = #_name, \
176 .id = TEGRA20_MC_RESET_##_name, \
177 .control = _control, \
178 .status = _status, \
179 .reset = _reset, \
180 .bit = _bit, \
181 }
182
183static const struct tegra_mc_reset tegra20_mc_resets[] = {
184 TEGRA20_MC_RESET(AVPC, 0x100, 0x140, 0x104, 0),
185 TEGRA20_MC_RESET(DC, 0x100, 0x144, 0x104, 1),
186 TEGRA20_MC_RESET(DCB, 0x100, 0x148, 0x104, 2),
187 TEGRA20_MC_RESET(EPP, 0x100, 0x14c, 0x104, 3),
188 TEGRA20_MC_RESET(2D, 0x100, 0x150, 0x104, 4),
189 TEGRA20_MC_RESET(HC, 0x100, 0x154, 0x104, 5),
190 TEGRA20_MC_RESET(ISP, 0x100, 0x158, 0x104, 6),
191 TEGRA20_MC_RESET(MPCORE, 0x100, 0x15c, 0x104, 7),
192 TEGRA20_MC_RESET(MPEA, 0x100, 0x160, 0x104, 8),
193 TEGRA20_MC_RESET(MPEB, 0x100, 0x164, 0x104, 9),
194 TEGRA20_MC_RESET(MPEC, 0x100, 0x168, 0x104, 10),
195 TEGRA20_MC_RESET(3D, 0x100, 0x16c, 0x104, 11),
196 TEGRA20_MC_RESET(PPCS, 0x100, 0x170, 0x104, 12),
197 TEGRA20_MC_RESET(VDE, 0x100, 0x174, 0x104, 13),
198 TEGRA20_MC_RESET(VI, 0x100, 0x178, 0x104, 14),
199};
200
201static int terga20_mc_hotreset_assert(struct tegra_mc *mc,
202 const struct tegra_mc_reset *rst)
203{
204 unsigned long flags;
205 u32 value;
206
207 spin_lock_irqsave(&mc->lock, flags);
208
209 value = mc_readl(mc, rst->reset);
210 mc_writel(mc, value & ~BIT(rst->bit), rst->reset);
211
212 spin_unlock_irqrestore(&mc->lock, flags);
213
214 return 0;
215}
216
217static int terga20_mc_hotreset_deassert(struct tegra_mc *mc,
218 const struct tegra_mc_reset *rst)
219{
220 unsigned long flags;
221 u32 value;
222
223 spin_lock_irqsave(&mc->lock, flags);
224
225 value = mc_readl(mc, rst->reset);
226 mc_writel(mc, value | BIT(rst->bit), rst->reset);
227
228 spin_unlock_irqrestore(&mc->lock, flags);
229
230 return 0;
231}
232
233static int terga20_mc_block_dma(struct tegra_mc *mc,
234 const struct tegra_mc_reset *rst)
235{
236 unsigned long flags;
237 u32 value;
238
239 spin_lock_irqsave(&mc->lock, flags);
240
241 value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
242 mc_writel(mc, value, rst->control);
243
244 spin_unlock_irqrestore(&mc->lock, flags);
245
246 return 0;
247}
248
249static bool terga20_mc_dma_idling(struct tegra_mc *mc,
250 const struct tegra_mc_reset *rst)
251{
252 return mc_readl(mc, rst->status) == 0;
253}
254
255static int terga20_mc_reset_status(struct tegra_mc *mc,
256 const struct tegra_mc_reset *rst)
257{
258 return (mc_readl(mc, rst->reset) & BIT(rst->bit)) == 0;
259}
260
261static int terga20_mc_unblock_dma(struct tegra_mc *mc,
262 const struct tegra_mc_reset *rst)
263{
264 unsigned long flags;
265 u32 value;
266
267 spin_lock_irqsave(&mc->lock, flags);
268
269 value = mc_readl(mc, rst->control) | BIT(rst->bit);
270 mc_writel(mc, value, rst->control);
271
272 spin_unlock_irqrestore(&mc->lock, flags);
273
274 return 0;
275}
276
277const struct tegra_mc_reset_ops terga20_mc_reset_ops = {
278 .hotreset_assert = terga20_mc_hotreset_assert,
279 .hotreset_deassert = terga20_mc_hotreset_deassert,
280 .block_dma = terga20_mc_block_dma,
281 .dma_idling = terga20_mc_dma_idling,
282 .unblock_dma = terga20_mc_unblock_dma,
283 .reset_status = terga20_mc_reset_status,
284};
285
286const struct tegra_mc_soc tegra20_mc_soc = {
287 .clients = tegra20_mc_clients,
288 .num_clients = ARRAY_SIZE(tegra20_mc_clients),
289 .num_address_bits = 32,
290 .client_id_mask = 0x3f,
291 .intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
292 MC_INT_DECERR_EMEM,
293 .reset_ops = &terga20_mc_reset_ops,
294 .resets = tegra20_mc_resets,
295 .num_resets = ARRAY_SIZE(tegra20_mc_resets),
296};
diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index d398bcd3fc57..d00a77160407 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -6,11 +6,6 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#include <linux/of.h>
10#include <linux/mm.h>
11
12#include <asm/cacheflush.h>
13
14#include <dt-bindings/memory/tegra210-mc.h> 9#include <dt-bindings/memory/tegra210-mc.h>
15 10
16#include "mc.h" 11#include "mc.h"
@@ -1085,6 +1080,48 @@ static const struct tegra_smmu_soc tegra210_smmu_soc = {
1085 .num_asids = 128, 1080 .num_asids = 128,
1086}; 1081};
1087 1082
1083#define TEGRA210_MC_RESET(_name, _control, _status, _bit) \
1084 { \
1085 .name = #_name, \
1086 .id = TEGRA210_MC_RESET_##_name, \
1087 .control = _control, \
1088 .status = _status, \
1089 .bit = _bit, \
1090 }
1091
1092static const struct tegra_mc_reset tegra210_mc_resets[] = {
1093 TEGRA210_MC_RESET(AFI, 0x200, 0x204, 0),
1094 TEGRA210_MC_RESET(AVPC, 0x200, 0x204, 1),
1095 TEGRA210_MC_RESET(DC, 0x200, 0x204, 2),
1096 TEGRA210_MC_RESET(DCB, 0x200, 0x204, 3),
1097 TEGRA210_MC_RESET(HC, 0x200, 0x204, 6),
1098 TEGRA210_MC_RESET(HDA, 0x200, 0x204, 7),
1099 TEGRA210_MC_RESET(ISP2, 0x200, 0x204, 8),
1100 TEGRA210_MC_RESET(MPCORE, 0x200, 0x204, 9),
1101 TEGRA210_MC_RESET(NVENC, 0x200, 0x204, 11),
1102 TEGRA210_MC_RESET(PPCS, 0x200, 0x204, 14),
1103 TEGRA210_MC_RESET(SATA, 0x200, 0x204, 15),
1104 TEGRA210_MC_RESET(VI, 0x200, 0x204, 17),
1105 TEGRA210_MC_RESET(VIC, 0x200, 0x204, 18),
1106 TEGRA210_MC_RESET(XUSB_HOST, 0x200, 0x204, 19),
1107 TEGRA210_MC_RESET(XUSB_DEV, 0x200, 0x204, 20),
1108 TEGRA210_MC_RESET(A9AVP, 0x200, 0x204, 21),
1109 TEGRA210_MC_RESET(TSEC, 0x200, 0x204, 22),
1110 TEGRA210_MC_RESET(SDMMC1, 0x200, 0x204, 29),
1111 TEGRA210_MC_RESET(SDMMC2, 0x200, 0x204, 30),
1112 TEGRA210_MC_RESET(SDMMC3, 0x200, 0x204, 31),
1113 TEGRA210_MC_RESET(SDMMC4, 0x970, 0x974, 0),
1114 TEGRA210_MC_RESET(ISP2B, 0x970, 0x974, 1),
1115 TEGRA210_MC_RESET(GPU, 0x970, 0x974, 2),
1116 TEGRA210_MC_RESET(NVDEC, 0x970, 0x974, 5),
1117 TEGRA210_MC_RESET(APE, 0x970, 0x974, 6),
1118 TEGRA210_MC_RESET(SE, 0x970, 0x974, 7),
1119 TEGRA210_MC_RESET(NVJPG, 0x970, 0x974, 8),
1120 TEGRA210_MC_RESET(AXIAP, 0x970, 0x974, 11),
1121 TEGRA210_MC_RESET(ETR, 0x970, 0x974, 12),
1122 TEGRA210_MC_RESET(TSECB, 0x970, 0x974, 13),
1123};
1124
1088const struct tegra_mc_soc tegra210_mc_soc = { 1125const struct tegra_mc_soc tegra210_mc_soc = {
1089 .clients = tegra210_mc_clients, 1126 .clients = tegra210_mc_clients,
1090 .num_clients = ARRAY_SIZE(tegra210_mc_clients), 1127 .num_clients = ARRAY_SIZE(tegra210_mc_clients),
@@ -1092,4 +1129,10 @@ const struct tegra_mc_soc tegra210_mc_soc = {
1092 .atom_size = 64, 1129 .atom_size = 64,
1093 .client_id_mask = 0xff, 1130 .client_id_mask = 0xff,
1094 .smmu = &tegra210_smmu_soc, 1131 .smmu = &tegra210_smmu_soc,
1132 .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
1133 MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
1134 MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
1135 .reset_ops = &terga_mc_reset_ops_common,
1136 .resets = tegra210_mc_resets,
1137 .num_resets = ARRAY_SIZE(tegra210_mc_resets),
1095}; 1138};
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index d756c837f23e..bee5314ed404 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -960,6 +960,36 @@ static const struct tegra_smmu_soc tegra30_smmu_soc = {
960 .num_asids = 4, 960 .num_asids = 4,
961}; 961};
962 962
963#define TEGRA30_MC_RESET(_name, _control, _status, _bit) \
964 { \
965 .name = #_name, \
966 .id = TEGRA30_MC_RESET_##_name, \
967 .control = _control, \
968 .status = _status, \
969 .bit = _bit, \
970 }
971
972static const struct tegra_mc_reset tegra30_mc_resets[] = {
973 TEGRA30_MC_RESET(AFI, 0x200, 0x204, 0),
974 TEGRA30_MC_RESET(AVPC, 0x200, 0x204, 1),
975 TEGRA30_MC_RESET(DC, 0x200, 0x204, 2),
976 TEGRA30_MC_RESET(DCB, 0x200, 0x204, 3),
977 TEGRA30_MC_RESET(EPP, 0x200, 0x204, 4),
978 TEGRA30_MC_RESET(2D, 0x200, 0x204, 5),
979 TEGRA30_MC_RESET(HC, 0x200, 0x204, 6),
980 TEGRA30_MC_RESET(HDA, 0x200, 0x204, 7),
981 TEGRA30_MC_RESET(ISP, 0x200, 0x204, 8),
982 TEGRA30_MC_RESET(MPCORE, 0x200, 0x204, 9),
983 TEGRA30_MC_RESET(MPCORELP, 0x200, 0x204, 10),
984 TEGRA30_MC_RESET(MPE, 0x200, 0x204, 11),
985 TEGRA30_MC_RESET(3D, 0x200, 0x204, 12),
986 TEGRA30_MC_RESET(3D2, 0x200, 0x204, 13),
987 TEGRA30_MC_RESET(PPCS, 0x200, 0x204, 14),
988 TEGRA30_MC_RESET(SATA, 0x200, 0x204, 15),
989 TEGRA30_MC_RESET(VDE, 0x200, 0x204, 16),
990 TEGRA30_MC_RESET(VI, 0x200, 0x204, 17),
991};
992
963const struct tegra_mc_soc tegra30_mc_soc = { 993const struct tegra_mc_soc tegra30_mc_soc = {
964 .clients = tegra30_mc_clients, 994 .clients = tegra30_mc_clients,
965 .num_clients = ARRAY_SIZE(tegra30_mc_clients), 995 .num_clients = ARRAY_SIZE(tegra30_mc_clients),
@@ -967,4 +997,9 @@ const struct tegra_mc_soc tegra30_mc_soc = {
967 .atom_size = 16, 997 .atom_size = 16,
968 .client_id_mask = 0x7f, 998 .client_id_mask = 0x7f,
969 .smmu = &tegra30_smmu_soc, 999 .smmu = &tegra30_smmu_soc,
1000 .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
1001 MC_INT_DECERR_EMEM,
1002 .reset_ops = &terga_mc_reset_ops_common,
1003 .resets = tegra30_mc_resets,
1004 .num_resets = ARRAY_SIZE(tegra30_mc_resets),
970}; 1005};
diff --git a/drivers/memory/tegra20-mc.c b/drivers/memory/tegra20-mc.c
deleted file mode 100644
index cc309a05289a..000000000000
--- a/drivers/memory/tegra20-mc.c
+++ /dev/null
@@ -1,254 +0,0 @@
1/*
2 * Tegra20 Memory Controller
3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <linux/err.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/ratelimit.h>
24#include <linux/platform_device.h>
25#include <linux/interrupt.h>
26#include <linux/io.h>
27
28#define DRV_NAME "tegra20-mc"
29
30#define MC_INTSTATUS 0x0
31#define MC_INTMASK 0x4
32
33#define MC_INT_ERR_SHIFT 6
34#define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT)
35#define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT)
36#define MC_INT_INVALID_GART_PAGE BIT(MC_INT_ERR_SHIFT + 1)
37#define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2)
38#define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3)
39
40#define MC_GART_ERROR_REQ 0x30
41#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
42#define MC_SECURITY_VIOLATION_STATUS 0x74
43
44#define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */
45
46#define MC_CLIENT_ID_MASK 0x3f
47
48#define NUM_MC_REG_BANKS 2
49
50struct tegra20_mc {
51 void __iomem *regs[NUM_MC_REG_BANKS];
52 struct device *dev;
53};
54
55static inline u32 mc_readl(struct tegra20_mc *mc, u32 offs)
56{
57 u32 val = 0;
58
59 if (offs < 0x24)
60 val = readl(mc->regs[0] + offs);
61 else if (offs < 0x400)
62 val = readl(mc->regs[1] + offs - 0x3c);
63
64 return val;
65}
66
67static inline void mc_writel(struct tegra20_mc *mc, u32 val, u32 offs)
68{
69 if (offs < 0x24)
70 writel(val, mc->regs[0] + offs);
71 else if (offs < 0x400)
72 writel(val, mc->regs[1] + offs - 0x3c);
73}
74
75static const char * const tegra20_mc_client[] = {
76 "cbr_display0a",
77 "cbr_display0ab",
78 "cbr_display0b",
79 "cbr_display0bb",
80 "cbr_display0c",
81 "cbr_display0cb",
82 "cbr_display1b",
83 "cbr_display1bb",
84 "cbr_eppup",
85 "cbr_g2pr",
86 "cbr_g2sr",
87 "cbr_mpeunifbr",
88 "cbr_viruv",
89 "csr_avpcarm7r",
90 "csr_displayhc",
91 "csr_displayhcb",
92 "csr_fdcdrd",
93 "csr_g2dr",
94 "csr_host1xdmar",
95 "csr_host1xr",
96 "csr_idxsrd",
97 "csr_mpcorer",
98 "csr_mpe_ipred",
99 "csr_mpeamemrd",
100 "csr_mpecsrd",
101 "csr_ppcsahbdmar",
102 "csr_ppcsahbslvr",
103 "csr_texsrd",
104 "csr_vdebsevr",
105 "csr_vdember",
106 "csr_vdemcer",
107 "csr_vdetper",
108 "cbw_eppu",
109 "cbw_eppv",
110 "cbw_eppy",
111 "cbw_mpeunifbw",
112 "cbw_viwsb",
113 "cbw_viwu",
114 "cbw_viwv",
115 "cbw_viwy",
116 "ccw_g2dw",
117 "csw_avpcarm7w",
118 "csw_fdcdwr",
119 "csw_host1xw",
120 "csw_ispw",
121 "csw_mpcorew",
122 "csw_mpecswr",
123 "csw_ppcsahbdmaw",
124 "csw_ppcsahbslvw",
125 "csw_vdebsevw",
126 "csw_vdembew",
127 "csw_vdetpmw",
128};
129
130static void tegra20_mc_decode(struct tegra20_mc *mc, int n)
131{
132 u32 addr, req;
133 const char *client = "Unknown";
134 int idx, cid;
135 const struct reg_info {
136 u32 offset;
137 u32 write_bit; /* 0=READ, 1=WRITE */
138 int cid_shift;
139 char *message;
140 } reg[] = {
141 {
142 .offset = MC_DECERR_EMEM_OTHERS_STATUS,
143 .write_bit = 31,
144 .message = "MC_DECERR",
145 },
146 {
147 .offset = MC_GART_ERROR_REQ,
148 .cid_shift = 1,
149 .message = "MC_GART_ERR",
150
151 },
152 {
153 .offset = MC_SECURITY_VIOLATION_STATUS,
154 .write_bit = 31,
155 .message = "MC_SECURITY_ERR",
156 },
157 };
158
159 idx = n - MC_INT_ERR_SHIFT;
160 if ((idx < 0) || (idx >= ARRAY_SIZE(reg))) {
161 dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n",
162 BIT(n));
163 return;
164 }
165
166 req = mc_readl(mc, reg[idx].offset);
167 cid = (req >> reg[idx].cid_shift) & MC_CLIENT_ID_MASK;
168 if (cid < ARRAY_SIZE(tegra20_mc_client))
169 client = tegra20_mc_client[cid];
170
171 addr = mc_readl(mc, reg[idx].offset + sizeof(u32));
172
173 dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s)\n",
174 reg[idx].message, req, addr, client,
175 (req & BIT(reg[idx].write_bit)) ? "write" : "read",
176 (reg[idx].offset == MC_SECURITY_VIOLATION_STATUS) ?
177 ((req & SECURITY_VIOLATION_TYPE) ?
178 "carveout" : "trustzone") : "");
179}
180
181static const struct of_device_id tegra20_mc_of_match[] = {
182 { .compatible = "nvidia,tegra20-mc", },
183 {},
184};
185
186static irqreturn_t tegra20_mc_isr(int irq, void *data)
187{
188 u32 stat, mask, bit;
189 struct tegra20_mc *mc = data;
190
191 stat = mc_readl(mc, MC_INTSTATUS);
192 mask = mc_readl(mc, MC_INTMASK);
193 mask &= stat;
194 if (!mask)
195 return IRQ_NONE;
196 while ((bit = ffs(mask)) != 0) {
197 tegra20_mc_decode(mc, bit - 1);
198 mask &= ~BIT(bit - 1);
199 }
200
201 mc_writel(mc, stat, MC_INTSTATUS);
202 return IRQ_HANDLED;
203}
204
205static int tegra20_mc_probe(struct platform_device *pdev)
206{
207 struct resource *irq;
208 struct tegra20_mc *mc;
209 int i, err;
210 u32 intmask;
211
212 mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
213 if (!mc)
214 return -ENOMEM;
215 mc->dev = &pdev->dev;
216
217 for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
218 struct resource *res;
219
220 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
221 mc->regs[i] = devm_ioremap_resource(&pdev->dev, res);
222 if (IS_ERR(mc->regs[i]))
223 return PTR_ERR(mc->regs[i]);
224 }
225
226 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
227 if (!irq)
228 return -ENODEV;
229 err = devm_request_irq(&pdev->dev, irq->start, tegra20_mc_isr,
230 IRQF_SHARED, dev_name(&pdev->dev), mc);
231 if (err)
232 return -ENODEV;
233
234 platform_set_drvdata(pdev, mc);
235
236 intmask = MC_INT_INVALID_GART_PAGE |
237 MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
238 mc_writel(mc, intmask, MC_INTMASK);
239 return 0;
240}
241
242static struct platform_driver tegra20_mc_driver = {
243 .probe = tegra20_mc_probe,
244 .driver = {
245 .name = DRV_NAME,
246 .of_match_table = tegra20_mc_of_match,
247 },
248};
249module_platform_driver(tegra20_mc_driver);
250
251MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
252MODULE_DESCRIPTION("Tegra20 MC driver");
253MODULE_LICENSE("GPL v2");
254MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/memory/ti-aemif.c b/drivers/memory/ti-aemif.c
index 2744b1b91b57..31112f622b88 100644
--- a/drivers/memory/ti-aemif.c
+++ b/drivers/memory/ti-aemif.c
@@ -339,9 +339,6 @@ static int aemif_probe(struct platform_device *pdev)
339 struct aemif_platform_data *pdata; 339 struct aemif_platform_data *pdata;
340 struct of_dev_auxdata *dev_lookup; 340 struct of_dev_auxdata *dev_lookup;
341 341
342 if (np == NULL)
343 return 0;
344
345 aemif = devm_kzalloc(dev, sizeof(*aemif), GFP_KERNEL); 342 aemif = devm_kzalloc(dev, sizeof(*aemif), GFP_KERNEL);
346 if (!aemif) 343 if (!aemif)
347 return -ENOMEM; 344 return -ENOMEM;
@@ -363,8 +360,10 @@ static int aemif_probe(struct platform_device *pdev)
363 360
364 aemif->clk_rate = clk_get_rate(aemif->clk) / MSEC_PER_SEC; 361 aemif->clk_rate = clk_get_rate(aemif->clk) / MSEC_PER_SEC;
365 362
366 if (of_device_is_compatible(np, "ti,da850-aemif")) 363 if (np && of_device_is_compatible(np, "ti,da850-aemif"))
367 aemif->cs_offset = 2; 364 aemif->cs_offset = 2;
365 else if (pdata)
366 aemif->cs_offset = pdata->cs_offset;
368 367
369 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 368 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
370 aemif->base = devm_ioremap_resource(dev, res); 369 aemif->base = devm_ioremap_resource(dev, res);
@@ -373,15 +372,23 @@ static int aemif_probe(struct platform_device *pdev)
373 goto error; 372 goto error;
374 } 373 }
375 374
376 /* 375 if (np) {
377 * For every controller device node, there is a cs device node that 376 /*
378 * describe the bus configuration parameters. This functions iterate 377 * For every controller device node, there is a cs device node
379 * over these nodes and update the cs data array. 378 * that describe the bus configuration parameters. This
380 */ 379 * functions iterate over these nodes and update the cs data
381 for_each_available_child_of_node(np, child_np) { 380 * array.
382 ret = of_aemif_parse_abus_config(pdev, child_np); 381 */
383 if (ret < 0) 382 for_each_available_child_of_node(np, child_np) {
384 goto error; 383 ret = of_aemif_parse_abus_config(pdev, child_np);
384 if (ret < 0)
385 goto error;
386 }
387 } else if (pdata && pdata->num_abus_data > 0) {
388 for (i = 0; i < pdata->num_abus_data; i++, aemif->num_cs++) {
389 aemif->cs_data[i].cs = pdata->abus_data[i].cs;
390 aemif_get_hw_params(pdev, i);
391 }
385 } 392 }
386 393
387 for (i = 0; i < aemif->num_cs; i++) { 394 for (i = 0; i < aemif->num_cs; i++) {
@@ -394,14 +401,25 @@ static int aemif_probe(struct platform_device *pdev)
394 } 401 }
395 402
396 /* 403 /*
397 * Create a child devices explicitly from here to 404 * Create a child devices explicitly from here to guarantee that the
398 * guarantee that the child will be probed after the AEMIF timing 405 * child will be probed after the AEMIF timing parameters are set.
399 * parameters are set.
400 */ 406 */
401 for_each_available_child_of_node(np, child_np) { 407 if (np) {
402 ret = of_platform_populate(child_np, NULL, dev_lookup, dev); 408 for_each_available_child_of_node(np, child_np) {
403 if (ret < 0) 409 ret = of_platform_populate(child_np, NULL,
404 goto error; 410 dev_lookup, dev);
411 if (ret < 0)
412 goto error;
413 }
414 } else {
415 for (i = 0; i < pdata->num_sub_devices; i++) {
416 pdata->sub_devices[i].dev.parent = dev;
417 ret = platform_device_register(&pdata->sub_devices[i]);
418 if (ret) {
419 dev_warn(dev, "Error register sub device %s\n",
420 pdata->sub_devices[i].name);
421 }
422 }
405 } 423 }
406 424
407 return 0; 425 return 0;
@@ -422,7 +440,7 @@ static struct platform_driver aemif_driver = {
422 .probe = aemif_probe, 440 .probe = aemif_probe,
423 .remove = aemif_remove, 441 .remove = aemif_remove,
424 .driver = { 442 .driver = {
425 .name = KBUILD_MODNAME, 443 .name = "ti-aemif",
426 .of_match_table = of_match_ptr(aemif_of_match), 444 .of_match_table = of_match_ptr(aemif_of_match),
427 }, 445 },
428}; 446};
diff --git a/drivers/reset/reset-uniphier.c b/drivers/reset/reset-uniphier.c
index ac18f2f27881..e9030ff1bf2f 100644
--- a/drivers/reset/reset-uniphier.c
+++ b/drivers/reset/reset-uniphier.c
@@ -63,6 +63,9 @@ static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
63 UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (Ether, SATA, USB3) */ 63 UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (Ether, SATA, USB3) */
64 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 64 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */
65 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 65 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */
66 UNIPHIER_RESETX(28, 0x2000, 18), /* SATA0 */
67 UNIPHIER_RESETX(29, 0x2004, 18), /* SATA1 */
68 UNIPHIER_RESETX(30, 0x2000, 19), /* SATA-PHY */
66 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 69 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */
67 UNIPHIER_RESET_END, 70 UNIPHIER_RESET_END,
68}; 71};
@@ -73,6 +76,7 @@ static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
73 UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (PCIe, USB3) */ 76 UNIPHIER_RESETX(12, 0x2000, 6), /* GIO (PCIe, USB3) */
74 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */ 77 UNIPHIER_RESETX(14, 0x2000, 17), /* USB30 */
75 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */ 78 UNIPHIER_RESETX(15, 0x2004, 17), /* USB31 */
79 UNIPHIER_RESETX(24, 0x2008, 2), /* PCIe */
76 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 80 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */
77 UNIPHIER_RESET_END, 81 UNIPHIER_RESET_END,
78}; 82};
@@ -89,7 +93,7 @@ static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
89 UNIPHIER_RESETX(20, 0x2014, 5), /* USB31-PHY0 */ 93 UNIPHIER_RESETX(20, 0x2014, 5), /* USB31-PHY0 */
90 UNIPHIER_RESETX(21, 0x2014, 1), /* USB31-PHY1 */ 94 UNIPHIER_RESETX(21, 0x2014, 1), /* USB31-PHY1 */
91 UNIPHIER_RESETX(28, 0x2014, 12), /* SATA */ 95 UNIPHIER_RESETX(28, 0x2014, 12), /* SATA */
92 UNIPHIER_RESET(29, 0x2014, 8), /* SATA-PHY (active high) */ 96 UNIPHIER_RESET(30, 0x2014, 8), /* SATA-PHY (active high) */
93 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */ 97 UNIPHIER_RESETX(40, 0x2000, 13), /* AIO */
94 UNIPHIER_RESET_END, 98 UNIPHIER_RESET_END,
95}; 99};
@@ -99,6 +103,7 @@ static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = {
99 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 103 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */
100 UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ 104 UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */
101 UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */ 105 UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC, MIO) */
106 UNIPHIER_RESETX(9, 0x200c, 9), /* HSC */
102 UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ 107 UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */
103 UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ 108 UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */
104 UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ 109 UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */
@@ -110,11 +115,13 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
110 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */ 115 UNIPHIER_RESETX(4, 0x200c, 2), /* eMMC */
111 UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */ 116 UNIPHIER_RESETX(6, 0x200c, 6), /* Ether */
112 UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */ 117 UNIPHIER_RESETX(8, 0x200c, 8), /* STDMAC (HSC) */
118 UNIPHIER_RESETX(9, 0x200c, 9), /* HSC */
113 UNIPHIER_RESETX(14, 0x200c, 5), /* USB30 */ 119 UNIPHIER_RESETX(14, 0x200c, 5), /* USB30 */
114 UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ 120 UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */
115 UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */ 121 UNIPHIER_RESETX(17, 0x200c, 13), /* USB30-PHY1 */
116 UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */ 122 UNIPHIER_RESETX(18, 0x200c, 14), /* USB30-PHY2 */
117 UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */ 123 UNIPHIER_RESETX(19, 0x200c, 15), /* USB30-PHY3 */
124 UNIPHIER_RESETX(24, 0x200c, 4), /* PCIe */
118 UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */ 125 UNIPHIER_RESETX(40, 0x2008, 0), /* AIO */
119 UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */ 126 UNIPHIER_RESETX(41, 0x2008, 1), /* EVEA */
120 UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */ 127 UNIPHIER_RESETX(42, 0x2010, 2), /* EXIV */
@@ -134,6 +141,10 @@ static const struct uniphier_reset_data uniphier_pxs3_sys_reset_data[] = {
134 UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */ 141 UNIPHIER_RESETX(18, 0x200c, 20), /* USB30-PHY2 */
135 UNIPHIER_RESETX(20, 0x200c, 17), /* USB31-PHY0 */ 142 UNIPHIER_RESETX(20, 0x200c, 17), /* USB31-PHY0 */
136 UNIPHIER_RESETX(21, 0x200c, 19), /* USB31-PHY1 */ 143 UNIPHIER_RESETX(21, 0x200c, 19), /* USB31-PHY1 */
144 UNIPHIER_RESETX(24, 0x200c, 3), /* PCIe */
145 UNIPHIER_RESETX(28, 0x200c, 7), /* SATA0 */
146 UNIPHIER_RESETX(29, 0x200c, 8), /* SATA1 */
147 UNIPHIER_RESETX(30, 0x200c, 21), /* SATA-PHY */
137 UNIPHIER_RESET_END, 148 UNIPHIER_RESET_END,
138}; 149};
139 150
diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
index c4d35f32af8d..32f0748fd067 100644
--- a/drivers/soc/imx/gpc.c
+++ b/drivers/soc/imx/gpc.c
@@ -443,17 +443,25 @@ static int imx_gpc_probe(struct platform_device *pdev)
443 if (domain_index >= of_id_data->num_domains) 443 if (domain_index >= of_id_data->num_domains)
444 continue; 444 continue;
445 445
446 domain = &imx_gpc_domains[domain_index];
447 domain->regmap = regmap;
448 domain->ipg_rate_mhz = ipg_rate_mhz;
449
450 pd_pdev = platform_device_alloc("imx-pgc-power-domain", 446 pd_pdev = platform_device_alloc("imx-pgc-power-domain",
451 domain_index); 447 domain_index);
452 if (!pd_pdev) { 448 if (!pd_pdev) {
453 of_node_put(np); 449 of_node_put(np);
454 return -ENOMEM; 450 return -ENOMEM;
455 } 451 }
456 pd_pdev->dev.platform_data = domain; 452
453 ret = platform_device_add_data(pd_pdev,
454 &imx_gpc_domains[domain_index],
455 sizeof(imx_gpc_domains[domain_index]));
456 if (ret) {
457 platform_device_put(pd_pdev);
458 of_node_put(np);
459 return ret;
460 }
461 domain = pd_pdev->dev.platform_data;
462 domain->regmap = regmap;
463 domain->ipg_rate_mhz = ipg_rate_mhz;
464
457 pd_pdev->dev.parent = &pdev->dev; 465 pd_pdev->dev.parent = &pdev->dev;
458 pd_pdev->dev.of_node = np; 466 pd_pdev->dev.of_node = np;
459 467
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index afc7ecc3c187..f4e3bd40c72e 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -155,7 +155,7 @@ static int imx7_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
155 return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false); 155 return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false);
156} 156}
157 157
158static struct imx7_pgc_domain imx7_pgc_domains[] = { 158static const struct imx7_pgc_domain imx7_pgc_domains[] = {
159 [IMX7_POWER_DOMAIN_MIPI_PHY] = { 159 [IMX7_POWER_DOMAIN_MIPI_PHY] = {
160 .genpd = { 160 .genpd = {
161 .name = "mipi-phy", 161 .name = "mipi-phy",
@@ -321,11 +321,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
321 continue; 321 continue;
322 } 322 }
323 323
324 domain = &imx7_pgc_domains[domain_index];
325 domain->regmap = regmap;
326 domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req;
327 domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req;
328
329 pd_pdev = platform_device_alloc("imx7-pgc-domain", 324 pd_pdev = platform_device_alloc("imx7-pgc-domain",
330 domain_index); 325 domain_index);
331 if (!pd_pdev) { 326 if (!pd_pdev) {
@@ -334,7 +329,20 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
334 return -ENOMEM; 329 return -ENOMEM;
335 } 330 }
336 331
337 pd_pdev->dev.platform_data = domain; 332 ret = platform_device_add_data(pd_pdev,
333 &imx7_pgc_domains[domain_index],
334 sizeof(imx7_pgc_domains[domain_index]));
335 if (ret) {
336 platform_device_put(pd_pdev);
337 of_node_put(np);
338 return ret;
339 }
340
341 domain = pd_pdev->dev.platform_data;
342 domain->regmap = regmap;
343 domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req;
344 domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req;
345
338 pd_pdev->dev.parent = dev; 346 pd_pdev->dev.parent = dev;
339 pd_pdev->dev.of_node = np; 347 pd_pdev->dev.of_node = np;
340 348
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
index 8c310de01e93..958861c9e6ee 100644
--- a/drivers/soc/mediatek/mtk-infracfg.c
+++ b/drivers/soc/mediatek/mtk-infracfg.c
@@ -17,6 +17,9 @@
17#include <linux/soc/mediatek/infracfg.h> 17#include <linux/soc/mediatek/infracfg.h>
18#include <asm/processor.h> 18#include <asm/processor.h>
19 19
20#define MTK_POLL_DELAY_US 10
21#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
22
20#define INFRA_TOPAXI_PROTECTEN 0x0220 23#define INFRA_TOPAXI_PROTECTEN 0x0220
21#define INFRA_TOPAXI_PROTECTSTA1 0x0228 24#define INFRA_TOPAXI_PROTECTSTA1 0x0228
22#define INFRA_TOPAXI_PROTECTEN_SET 0x0260 25#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
@@ -37,7 +40,6 @@
37int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, 40int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
38 bool reg_update) 41 bool reg_update)
39{ 42{
40 unsigned long expired;
41 u32 val; 43 u32 val;
42 int ret; 44 int ret;
43 45
@@ -47,22 +49,11 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
47 else 49 else
48 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); 50 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
49 51
50 expired = jiffies + HZ; 52 ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
51 53 val, (val & mask) == mask,
52 while (1) { 54 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
53 ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
54 if (ret)
55 return ret;
56
57 if ((val & mask) == mask)
58 break;
59 55
60 cpu_relax(); 56 return ret;
61 if (time_after(jiffies, expired))
62 return -EIO;
63 }
64
65 return 0;
66} 57}
67 58
68/** 59/**
@@ -80,30 +71,17 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
80int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, 71int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
81 bool reg_update) 72 bool reg_update)
82{ 73{
83 unsigned long expired;
84 int ret; 74 int ret;
75 u32 val;
85 76
86 if (reg_update) 77 if (reg_update)
87 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); 78 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
88 else 79 else
89 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask); 80 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
90 81
91 expired = jiffies + HZ; 82 ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
92 83 val, !(val & mask),
93 while (1) { 84 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
94 u32 val;
95
96 ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
97 if (ret)
98 return ret;
99
100 if (!(val & mask))
101 break;
102
103 cpu_relax();
104 if (time_after(jiffies, expired))
105 return -EIO;
106 }
107 85
108 return 0; 86 return ret;
109} 87}
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index e9e054a15b7d..2afae64061d8 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -1458,19 +1458,12 @@ static int pwrap_probe(struct platform_device *pdev)
1458 int ret, irq; 1458 int ret, irq;
1459 struct pmic_wrapper *wrp; 1459 struct pmic_wrapper *wrp;
1460 struct device_node *np = pdev->dev.of_node; 1460 struct device_node *np = pdev->dev.of_node;
1461 const struct of_device_id *of_id =
1462 of_match_device(of_pwrap_match_tbl, &pdev->dev);
1463 const struct of_device_id *of_slave_id = NULL; 1461 const struct of_device_id *of_slave_id = NULL;
1464 struct resource *res; 1462 struct resource *res;
1465 1463
1466 if (!of_id) { 1464 if (np->child)
1467 dev_err(&pdev->dev, "Error: No device match found\n"); 1465 of_slave_id = of_match_node(of_slave_match_tbl, np->child);
1468 return -ENODEV;
1469 }
1470 1466
1471 if (pdev->dev.of_node->child)
1472 of_slave_id = of_match_node(of_slave_match_tbl,
1473 pdev->dev.of_node->child);
1474 if (!of_slave_id) { 1467 if (!of_slave_id) {
1475 dev_dbg(&pdev->dev, "slave pmic should be defined in dts\n"); 1468 dev_dbg(&pdev->dev, "slave pmic should be defined in dts\n");
1476 return -EINVAL; 1469 return -EINVAL;
@@ -1482,7 +1475,7 @@ static int pwrap_probe(struct platform_device *pdev)
1482 1475
1483 platform_set_drvdata(pdev, wrp); 1476 platform_set_drvdata(pdev, wrp);
1484 1477
1485 wrp->master = of_id->data; 1478 wrp->master = of_device_get_match_data(&pdev->dev);
1486 wrp->slave = of_slave_id->data; 1479 wrp->slave = of_slave_id->data;
1487 wrp->dev = &pdev->dev; 1480 wrp->dev = &pdev->dev;
1488 1481
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index d762a46d434f..128e3dd3186d 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -13,6 +13,7 @@
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/iopoll.h>
16#include <linux/mfd/syscon.h> 17#include <linux/mfd/syscon.h>
17#include <linux/of_device.h> 18#include <linux/of_device.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -27,6 +28,13 @@
27#include <dt-bindings/power/mt7623a-power.h> 28#include <dt-bindings/power/mt7623a-power.h>
28#include <dt-bindings/power/mt8173-power.h> 29#include <dt-bindings/power/mt8173-power.h>
29 30
31#define MTK_POLL_DELAY_US 10
32#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
33
34#define MTK_SCPD_ACTIVE_WAKEUP BIT(0)
35#define MTK_SCPD_FWAIT_SRAM BIT(1)
36#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
37
30#define SPM_VDE_PWR_CON 0x0210 38#define SPM_VDE_PWR_CON 0x0210
31#define SPM_MFG_PWR_CON 0x0214 39#define SPM_MFG_PWR_CON 0x0214
32#define SPM_VEN_PWR_CON 0x0230 40#define SPM_VEN_PWR_CON 0x0230
@@ -116,7 +124,7 @@ struct scp_domain_data {
116 u32 sram_pdn_ack_bits; 124 u32 sram_pdn_ack_bits;
117 u32 bus_prot_mask; 125 u32 bus_prot_mask;
118 enum clk_id clk_id[MAX_CLKS]; 126 enum clk_id clk_id[MAX_CLKS];
119 bool active_wakeup; 127 u8 caps;
120}; 128};
121 129
122struct scp; 130struct scp;
@@ -184,12 +192,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
184{ 192{
185 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); 193 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
186 struct scp *scp = scpd->scp; 194 struct scp *scp = scpd->scp;
187 unsigned long timeout;
188 bool expired;
189 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; 195 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
190 u32 sram_pdn_ack = scpd->data->sram_pdn_ack_bits; 196 u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
191 u32 val; 197 u32 val;
192 int ret; 198 int ret, tmp;
193 int i; 199 int i;
194 200
195 if (scpd->supply) { 201 if (scpd->supply) {
@@ -215,23 +221,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
215 writel(val, ctl_addr); 221 writel(val, ctl_addr);
216 222
217 /* wait until PWR_ACK = 1 */ 223 /* wait until PWR_ACK = 1 */
218 timeout = jiffies + HZ; 224 ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
219 expired = false; 225 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
220 while (1) { 226 if (ret < 0)
221 ret = scpsys_domain_is_on(scpd); 227 goto err_pwr_ack;
222 if (ret > 0)
223 break;
224
225 if (expired) {
226 ret = -ETIMEDOUT;
227 goto err_pwr_ack;
228 }
229
230 cpu_relax();
231
232 if (time_after(jiffies, timeout))
233 expired = true;
234 }
235 228
236 val &= ~PWR_CLK_DIS_BIT; 229 val &= ~PWR_CLK_DIS_BIT;
237 writel(val, ctl_addr); 230 writel(val, ctl_addr);
@@ -245,20 +238,20 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
245 val &= ~scpd->data->sram_pdn_bits; 238 val &= ~scpd->data->sram_pdn_bits;
246 writel(val, ctl_addr); 239 writel(val, ctl_addr);
247 240
248 /* wait until SRAM_PDN_ACK all 0 */ 241 /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
249 timeout = jiffies + HZ; 242 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
250 expired = false; 243 /*
251 while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) { 244 * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
245 * MT7622_POWER_DOMAIN_WB and thus just a trivial setup is
246 * applied here.
247 */
248 usleep_range(12000, 12100);
252 249
253 if (expired) { 250 } else {
254 ret = -ETIMEDOUT; 251 ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
252 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
253 if (ret < 0)
255 goto err_pwr_ack; 254 goto err_pwr_ack;
256 }
257
258 cpu_relax();
259
260 if (time_after(jiffies, timeout))
261 expired = true;
262 } 255 }
263 256
264 if (scpd->data->bus_prot_mask) { 257 if (scpd->data->bus_prot_mask) {
@@ -289,12 +282,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
289{ 282{
290 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); 283 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
291 struct scp *scp = scpd->scp; 284 struct scp *scp = scpd->scp;
292 unsigned long timeout;
293 bool expired;
294 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; 285 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
295 u32 pdn_ack = scpd->data->sram_pdn_ack_bits; 286 u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
296 u32 val; 287 u32 val;
297 int ret; 288 int ret, tmp;
298 int i; 289 int i;
299 290
300 if (scpd->data->bus_prot_mask) { 291 if (scpd->data->bus_prot_mask) {
@@ -310,19 +301,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
310 writel(val, ctl_addr); 301 writel(val, ctl_addr);
311 302
312 /* wait until SRAM_PDN_ACK all 1 */ 303 /* wait until SRAM_PDN_ACK all 1 */
313 timeout = jiffies + HZ; 304 ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
314 expired = false; 305 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
315 while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) { 306 if (ret < 0)
316 if (expired) { 307 goto out;
317 ret = -ETIMEDOUT;
318 goto out;
319 }
320
321 cpu_relax();
322
323 if (time_after(jiffies, timeout))
324 expired = true;
325 }
326 308
327 val |= PWR_ISO_BIT; 309 val |= PWR_ISO_BIT;
328 writel(val, ctl_addr); 310 writel(val, ctl_addr);
@@ -340,23 +322,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
340 writel(val, ctl_addr); 322 writel(val, ctl_addr);
341 323
342 /* wait until PWR_ACK = 0 */ 324 /* wait until PWR_ACK = 0 */
343 timeout = jiffies + HZ; 325 ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
344 expired = false; 326 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
345 while (1) { 327 if (ret < 0)
346 ret = scpsys_domain_is_on(scpd); 328 goto out;
347 if (ret == 0)
348 break;
349
350 if (expired) {
351 ret = -ETIMEDOUT;
352 goto out;
353 }
354
355 cpu_relax();
356
357 if (time_after(jiffies, timeout))
358 expired = true;
359 }
360 329
361 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) 330 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
362 clk_disable_unprepare(scpd->clk[i]); 331 clk_disable_unprepare(scpd->clk[i]);
@@ -469,7 +438,7 @@ static struct scp *init_scp(struct platform_device *pdev,
469 genpd->name = data->name; 438 genpd->name = data->name;
470 genpd->power_off = scpsys_power_off; 439 genpd->power_off = scpsys_power_off;
471 genpd->power_on = scpsys_power_on; 440 genpd->power_on = scpsys_power_on;
472 if (scpd->data->active_wakeup) 441 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
473 genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; 442 genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
474 } 443 }
475 444
@@ -522,7 +491,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
522 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 491 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
523 MT2701_TOP_AXI_PROT_EN_CONN_S, 492 MT2701_TOP_AXI_PROT_EN_CONN_S,
524 .clk_id = {CLK_NONE}, 493 .clk_id = {CLK_NONE},
525 .active_wakeup = true, 494 .caps = MTK_SCPD_ACTIVE_WAKEUP,
526 }, 495 },
527 [MT2701_POWER_DOMAIN_DISP] = { 496 [MT2701_POWER_DOMAIN_DISP] = {
528 .name = "disp", 497 .name = "disp",
@@ -531,7 +500,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
531 .sram_pdn_bits = GENMASK(11, 8), 500 .sram_pdn_bits = GENMASK(11, 8),
532 .clk_id = {CLK_MM}, 501 .clk_id = {CLK_MM},
533 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0, 502 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
534 .active_wakeup = true, 503 .caps = MTK_SCPD_ACTIVE_WAKEUP,
535 }, 504 },
536 [MT2701_POWER_DOMAIN_MFG] = { 505 [MT2701_POWER_DOMAIN_MFG] = {
537 .name = "mfg", 506 .name = "mfg",
@@ -540,7 +509,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
540 .sram_pdn_bits = GENMASK(11, 8), 509 .sram_pdn_bits = GENMASK(11, 8),
541 .sram_pdn_ack_bits = GENMASK(12, 12), 510 .sram_pdn_ack_bits = GENMASK(12, 12),
542 .clk_id = {CLK_MFG}, 511 .clk_id = {CLK_MFG},
543 .active_wakeup = true, 512 .caps = MTK_SCPD_ACTIVE_WAKEUP,
544 }, 513 },
545 [MT2701_POWER_DOMAIN_VDEC] = { 514 [MT2701_POWER_DOMAIN_VDEC] = {
546 .name = "vdec", 515 .name = "vdec",
@@ -549,7 +518,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
549 .sram_pdn_bits = GENMASK(11, 8), 518 .sram_pdn_bits = GENMASK(11, 8),
550 .sram_pdn_ack_bits = GENMASK(12, 12), 519 .sram_pdn_ack_bits = GENMASK(12, 12),
551 .clk_id = {CLK_MM}, 520 .clk_id = {CLK_MM},
552 .active_wakeup = true, 521 .caps = MTK_SCPD_ACTIVE_WAKEUP,
553 }, 522 },
554 [MT2701_POWER_DOMAIN_ISP] = { 523 [MT2701_POWER_DOMAIN_ISP] = {
555 .name = "isp", 524 .name = "isp",
@@ -558,7 +527,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
558 .sram_pdn_bits = GENMASK(11, 8), 527 .sram_pdn_bits = GENMASK(11, 8),
559 .sram_pdn_ack_bits = GENMASK(13, 12), 528 .sram_pdn_ack_bits = GENMASK(13, 12),
560 .clk_id = {CLK_MM}, 529 .clk_id = {CLK_MM},
561 .active_wakeup = true, 530 .caps = MTK_SCPD_ACTIVE_WAKEUP,
562 }, 531 },
563 [MT2701_POWER_DOMAIN_BDP] = { 532 [MT2701_POWER_DOMAIN_BDP] = {
564 .name = "bdp", 533 .name = "bdp",
@@ -566,7 +535,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
566 .ctl_offs = SPM_BDP_PWR_CON, 535 .ctl_offs = SPM_BDP_PWR_CON,
567 .sram_pdn_bits = GENMASK(11, 8), 536 .sram_pdn_bits = GENMASK(11, 8),
568 .clk_id = {CLK_NONE}, 537 .clk_id = {CLK_NONE},
569 .active_wakeup = true, 538 .caps = MTK_SCPD_ACTIVE_WAKEUP,
570 }, 539 },
571 [MT2701_POWER_DOMAIN_ETH] = { 540 [MT2701_POWER_DOMAIN_ETH] = {
572 .name = "eth", 541 .name = "eth",
@@ -575,7 +544,7 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
575 .sram_pdn_bits = GENMASK(11, 8), 544 .sram_pdn_bits = GENMASK(11, 8),
576 .sram_pdn_ack_bits = GENMASK(15, 12), 545 .sram_pdn_ack_bits = GENMASK(15, 12),
577 .clk_id = {CLK_ETHIF}, 546 .clk_id = {CLK_ETHIF},
578 .active_wakeup = true, 547 .caps = MTK_SCPD_ACTIVE_WAKEUP,
579 }, 548 },
580 [MT2701_POWER_DOMAIN_HIF] = { 549 [MT2701_POWER_DOMAIN_HIF] = {
581 .name = "hif", 550 .name = "hif",
@@ -584,14 +553,14 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
584 .sram_pdn_bits = GENMASK(11, 8), 553 .sram_pdn_bits = GENMASK(11, 8),
585 .sram_pdn_ack_bits = GENMASK(15, 12), 554 .sram_pdn_ack_bits = GENMASK(15, 12),
586 .clk_id = {CLK_ETHIF}, 555 .clk_id = {CLK_ETHIF},
587 .active_wakeup = true, 556 .caps = MTK_SCPD_ACTIVE_WAKEUP,
588 }, 557 },
589 [MT2701_POWER_DOMAIN_IFR_MSC] = { 558 [MT2701_POWER_DOMAIN_IFR_MSC] = {
590 .name = "ifr_msc", 559 .name = "ifr_msc",
591 .sta_mask = PWR_STATUS_IFR_MSC, 560 .sta_mask = PWR_STATUS_IFR_MSC,
592 .ctl_offs = SPM_IFR_MSC_PWR_CON, 561 .ctl_offs = SPM_IFR_MSC_PWR_CON,
593 .clk_id = {CLK_NONE}, 562 .clk_id = {CLK_NONE},
594 .active_wakeup = true, 563 .caps = MTK_SCPD_ACTIVE_WAKEUP,
595 }, 564 },
596}; 565};
597 566
@@ -606,7 +575,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
606 .sram_pdn_bits = GENMASK(8, 8), 575 .sram_pdn_bits = GENMASK(8, 8),
607 .sram_pdn_ack_bits = GENMASK(12, 12), 576 .sram_pdn_ack_bits = GENMASK(12, 12),
608 .clk_id = {CLK_MM}, 577 .clk_id = {CLK_MM},
609 .active_wakeup = true, 578 .caps = MTK_SCPD_ACTIVE_WAKEUP,
610 }, 579 },
611 [MT2712_POWER_DOMAIN_VDEC] = { 580 [MT2712_POWER_DOMAIN_VDEC] = {
612 .name = "vdec", 581 .name = "vdec",
@@ -615,7 +584,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
615 .sram_pdn_bits = GENMASK(8, 8), 584 .sram_pdn_bits = GENMASK(8, 8),
616 .sram_pdn_ack_bits = GENMASK(12, 12), 585 .sram_pdn_ack_bits = GENMASK(12, 12),
617 .clk_id = {CLK_MM, CLK_VDEC}, 586 .clk_id = {CLK_MM, CLK_VDEC},
618 .active_wakeup = true, 587 .caps = MTK_SCPD_ACTIVE_WAKEUP,
619 }, 588 },
620 [MT2712_POWER_DOMAIN_VENC] = { 589 [MT2712_POWER_DOMAIN_VENC] = {
621 .name = "venc", 590 .name = "venc",
@@ -624,7 +593,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
624 .sram_pdn_bits = GENMASK(11, 8), 593 .sram_pdn_bits = GENMASK(11, 8),
625 .sram_pdn_ack_bits = GENMASK(15, 12), 594 .sram_pdn_ack_bits = GENMASK(15, 12),
626 .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC}, 595 .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
627 .active_wakeup = true, 596 .caps = MTK_SCPD_ACTIVE_WAKEUP,
628 }, 597 },
629 [MT2712_POWER_DOMAIN_ISP] = { 598 [MT2712_POWER_DOMAIN_ISP] = {
630 .name = "isp", 599 .name = "isp",
@@ -633,7 +602,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
633 .sram_pdn_bits = GENMASK(11, 8), 602 .sram_pdn_bits = GENMASK(11, 8),
634 .sram_pdn_ack_bits = GENMASK(13, 12), 603 .sram_pdn_ack_bits = GENMASK(13, 12),
635 .clk_id = {CLK_MM}, 604 .clk_id = {CLK_MM},
636 .active_wakeup = true, 605 .caps = MTK_SCPD_ACTIVE_WAKEUP,
637 }, 606 },
638 [MT2712_POWER_DOMAIN_AUDIO] = { 607 [MT2712_POWER_DOMAIN_AUDIO] = {
639 .name = "audio", 608 .name = "audio",
@@ -642,7 +611,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
642 .sram_pdn_bits = GENMASK(11, 8), 611 .sram_pdn_bits = GENMASK(11, 8),
643 .sram_pdn_ack_bits = GENMASK(15, 12), 612 .sram_pdn_ack_bits = GENMASK(15, 12),
644 .clk_id = {CLK_AUDIO}, 613 .clk_id = {CLK_AUDIO},
645 .active_wakeup = true, 614 .caps = MTK_SCPD_ACTIVE_WAKEUP,
646 }, 615 },
647 [MT2712_POWER_DOMAIN_USB] = { 616 [MT2712_POWER_DOMAIN_USB] = {
648 .name = "usb", 617 .name = "usb",
@@ -651,7 +620,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
651 .sram_pdn_bits = GENMASK(10, 8), 620 .sram_pdn_bits = GENMASK(10, 8),
652 .sram_pdn_ack_bits = GENMASK(14, 12), 621 .sram_pdn_ack_bits = GENMASK(14, 12),
653 .clk_id = {CLK_NONE}, 622 .clk_id = {CLK_NONE},
654 .active_wakeup = true, 623 .caps = MTK_SCPD_ACTIVE_WAKEUP,
655 }, 624 },
656 [MT2712_POWER_DOMAIN_USB2] = { 625 [MT2712_POWER_DOMAIN_USB2] = {
657 .name = "usb2", 626 .name = "usb2",
@@ -660,7 +629,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
660 .sram_pdn_bits = GENMASK(10, 8), 629 .sram_pdn_bits = GENMASK(10, 8),
661 .sram_pdn_ack_bits = GENMASK(14, 12), 630 .sram_pdn_ack_bits = GENMASK(14, 12),
662 .clk_id = {CLK_NONE}, 631 .clk_id = {CLK_NONE},
663 .active_wakeup = true, 632 .caps = MTK_SCPD_ACTIVE_WAKEUP,
664 }, 633 },
665 [MT2712_POWER_DOMAIN_MFG] = { 634 [MT2712_POWER_DOMAIN_MFG] = {
666 .name = "mfg", 635 .name = "mfg",
@@ -670,7 +639,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
670 .sram_pdn_ack_bits = GENMASK(16, 16), 639 .sram_pdn_ack_bits = GENMASK(16, 16),
671 .clk_id = {CLK_MFG}, 640 .clk_id = {CLK_MFG},
672 .bus_prot_mask = BIT(14) | BIT(21) | BIT(23), 641 .bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
673 .active_wakeup = true, 642 .caps = MTK_SCPD_ACTIVE_WAKEUP,
674 }, 643 },
675 [MT2712_POWER_DOMAIN_MFG_SC1] = { 644 [MT2712_POWER_DOMAIN_MFG_SC1] = {
676 .name = "mfg_sc1", 645 .name = "mfg_sc1",
@@ -679,7 +648,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
679 .sram_pdn_bits = GENMASK(8, 8), 648 .sram_pdn_bits = GENMASK(8, 8),
680 .sram_pdn_ack_bits = GENMASK(16, 16), 649 .sram_pdn_ack_bits = GENMASK(16, 16),
681 .clk_id = {CLK_NONE}, 650 .clk_id = {CLK_NONE},
682 .active_wakeup = true, 651 .caps = MTK_SCPD_ACTIVE_WAKEUP,
683 }, 652 },
684 [MT2712_POWER_DOMAIN_MFG_SC2] = { 653 [MT2712_POWER_DOMAIN_MFG_SC2] = {
685 .name = "mfg_sc2", 654 .name = "mfg_sc2",
@@ -688,7 +657,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
688 .sram_pdn_bits = GENMASK(8, 8), 657 .sram_pdn_bits = GENMASK(8, 8),
689 .sram_pdn_ack_bits = GENMASK(16, 16), 658 .sram_pdn_ack_bits = GENMASK(16, 16),
690 .clk_id = {CLK_NONE}, 659 .clk_id = {CLK_NONE},
691 .active_wakeup = true, 660 .caps = MTK_SCPD_ACTIVE_WAKEUP,
692 }, 661 },
693 [MT2712_POWER_DOMAIN_MFG_SC3] = { 662 [MT2712_POWER_DOMAIN_MFG_SC3] = {
694 .name = "mfg_sc3", 663 .name = "mfg_sc3",
@@ -697,7 +666,7 @@ static const struct scp_domain_data scp_domain_data_mt2712[] = {
697 .sram_pdn_bits = GENMASK(8, 8), 666 .sram_pdn_bits = GENMASK(8, 8),
698 .sram_pdn_ack_bits = GENMASK(16, 16), 667 .sram_pdn_ack_bits = GENMASK(16, 16),
699 .clk_id = {CLK_NONE}, 668 .clk_id = {CLK_NONE},
700 .active_wakeup = true, 669 .caps = MTK_SCPD_ACTIVE_WAKEUP,
701 }, 670 },
702}; 671};
703 672
@@ -797,7 +766,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = {
797 .sram_pdn_ack_bits = GENMASK(15, 12), 766 .sram_pdn_ack_bits = GENMASK(15, 12),
798 .clk_id = {CLK_NONE}, 767 .clk_id = {CLK_NONE},
799 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS, 768 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
800 .active_wakeup = true, 769 .caps = MTK_SCPD_ACTIVE_WAKEUP,
801 }, 770 },
802 [MT7622_POWER_DOMAIN_HIF0] = { 771 [MT7622_POWER_DOMAIN_HIF0] = {
803 .name = "hif0", 772 .name = "hif0",
@@ -807,7 +776,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = {
807 .sram_pdn_ack_bits = GENMASK(15, 12), 776 .sram_pdn_ack_bits = GENMASK(15, 12),
808 .clk_id = {CLK_HIFSEL}, 777 .clk_id = {CLK_HIFSEL},
809 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0, 778 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
810 .active_wakeup = true, 779 .caps = MTK_SCPD_ACTIVE_WAKEUP,
811 }, 780 },
812 [MT7622_POWER_DOMAIN_HIF1] = { 781 [MT7622_POWER_DOMAIN_HIF1] = {
813 .name = "hif1", 782 .name = "hif1",
@@ -817,7 +786,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = {
817 .sram_pdn_ack_bits = GENMASK(15, 12), 786 .sram_pdn_ack_bits = GENMASK(15, 12),
818 .clk_id = {CLK_HIFSEL}, 787 .clk_id = {CLK_HIFSEL},
819 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, 788 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
820 .active_wakeup = true, 789 .caps = MTK_SCPD_ACTIVE_WAKEUP,
821 }, 790 },
822 [MT7622_POWER_DOMAIN_WB] = { 791 [MT7622_POWER_DOMAIN_WB] = {
823 .name = "wb", 792 .name = "wb",
@@ -827,7 +796,7 @@ static const struct scp_domain_data scp_domain_data_mt7622[] = {
827 .sram_pdn_ack_bits = 0, 796 .sram_pdn_ack_bits = 0,
828 .clk_id = {CLK_NONE}, 797 .clk_id = {CLK_NONE},
829 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, 798 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
830 .active_wakeup = true, 799 .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM,
831 }, 800 },
832}; 801};
833 802
@@ -843,7 +812,7 @@ static const struct scp_domain_data scp_domain_data_mt7623a[] = {
843 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 812 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
844 MT2701_TOP_AXI_PROT_EN_CONN_S, 813 MT2701_TOP_AXI_PROT_EN_CONN_S,
845 .clk_id = {CLK_NONE}, 814 .clk_id = {CLK_NONE},
846 .active_wakeup = true, 815 .caps = MTK_SCPD_ACTIVE_WAKEUP,
847 }, 816 },
848 [MT7623A_POWER_DOMAIN_ETH] = { 817 [MT7623A_POWER_DOMAIN_ETH] = {
849 .name = "eth", 818 .name = "eth",
@@ -852,7 +821,7 @@ static const struct scp_domain_data scp_domain_data_mt7623a[] = {
852 .sram_pdn_bits = GENMASK(11, 8), 821 .sram_pdn_bits = GENMASK(11, 8),
853 .sram_pdn_ack_bits = GENMASK(15, 12), 822 .sram_pdn_ack_bits = GENMASK(15, 12),
854 .clk_id = {CLK_ETHIF}, 823 .clk_id = {CLK_ETHIF},
855 .active_wakeup = true, 824 .caps = MTK_SCPD_ACTIVE_WAKEUP,
856 }, 825 },
857 [MT7623A_POWER_DOMAIN_HIF] = { 826 [MT7623A_POWER_DOMAIN_HIF] = {
858 .name = "hif", 827 .name = "hif",
@@ -861,14 +830,14 @@ static const struct scp_domain_data scp_domain_data_mt7623a[] = {
861 .sram_pdn_bits = GENMASK(11, 8), 830 .sram_pdn_bits = GENMASK(11, 8),
862 .sram_pdn_ack_bits = GENMASK(15, 12), 831 .sram_pdn_ack_bits = GENMASK(15, 12),
863 .clk_id = {CLK_ETHIF}, 832 .clk_id = {CLK_ETHIF},
864 .active_wakeup = true, 833 .caps = MTK_SCPD_ACTIVE_WAKEUP,
865 }, 834 },
866 [MT7623A_POWER_DOMAIN_IFR_MSC] = { 835 [MT7623A_POWER_DOMAIN_IFR_MSC] = {
867 .name = "ifr_msc", 836 .name = "ifr_msc",
868 .sta_mask = PWR_STATUS_IFR_MSC, 837 .sta_mask = PWR_STATUS_IFR_MSC,
869 .ctl_offs = SPM_IFR_MSC_PWR_CON, 838 .ctl_offs = SPM_IFR_MSC_PWR_CON,
870 .clk_id = {CLK_NONE}, 839 .clk_id = {CLK_NONE},
871 .active_wakeup = true, 840 .caps = MTK_SCPD_ACTIVE_WAKEUP,
872 }, 841 },
873}; 842};
874 843
@@ -934,7 +903,7 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = {
934 .sram_pdn_bits = GENMASK(11, 8), 903 .sram_pdn_bits = GENMASK(11, 8),
935 .sram_pdn_ack_bits = GENMASK(15, 12), 904 .sram_pdn_ack_bits = GENMASK(15, 12),
936 .clk_id = {CLK_NONE}, 905 .clk_id = {CLK_NONE},
937 .active_wakeup = true, 906 .caps = MTK_SCPD_ACTIVE_WAKEUP,
938 }, 907 },
939 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 908 [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
940 .name = "mfg_async", 909 .name = "mfg_async",
@@ -1067,15 +1036,13 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
1067 1036
1068static int scpsys_probe(struct platform_device *pdev) 1037static int scpsys_probe(struct platform_device *pdev)
1069{ 1038{
1070 const struct of_device_id *match;
1071 const struct scp_subdomain *sd; 1039 const struct scp_subdomain *sd;
1072 const struct scp_soc_data *soc; 1040 const struct scp_soc_data *soc;
1073 struct scp *scp; 1041 struct scp *scp;
1074 struct genpd_onecell_data *pd_data; 1042 struct genpd_onecell_data *pd_data;
1075 int i, ret; 1043 int i, ret;
1076 1044
1077 match = of_match_device(of_scpsys_match_tbl, &pdev->dev); 1045 soc = of_device_get_match_data(&pdev->dev);
1078 soc = (const struct scp_soc_data *)match->data;
1079 1046
1080 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs, 1047 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
1081 soc->bus_prot_reg_update); 1048 soc->bus_prot_reg_update);
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
index f874baaf934c..6dff8682155f 100644
--- a/drivers/soc/rockchip/pm_domains.c
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -19,6 +19,10 @@
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/regmap.h> 20#include <linux/regmap.h>
21#include <linux/mfd/syscon.h> 21#include <linux/mfd/syscon.h>
22#include <dt-bindings/power/px30-power.h>
23#include <dt-bindings/power/rk3036-power.h>
24#include <dt-bindings/power/rk3128-power.h>
25#include <dt-bindings/power/rk3228-power.h>
22#include <dt-bindings/power/rk3288-power.h> 26#include <dt-bindings/power/rk3288-power.h>
23#include <dt-bindings/power/rk3328-power.h> 27#include <dt-bindings/power/rk3328-power.h>
24#include <dt-bindings/power/rk3366-power.h> 28#include <dt-bindings/power/rk3366-power.h>
@@ -104,6 +108,18 @@ struct rockchip_pmu {
104 .active_wakeup = wakeup, \ 108 .active_wakeup = wakeup, \
105} 109}
106 110
111#define DOMAIN_RK3036(req, ack, idle, wakeup) \
112{ \
113 .req_mask = (req >= 0) ? BIT(req) : 0, \
114 .req_w_mask = (req >= 0) ? BIT(req + 16) : 0, \
115 .ack_mask = (ack >= 0) ? BIT(ack) : 0, \
116 .idle_mask = (idle >= 0) ? BIT(idle) : 0, \
117 .active_wakeup = wakeup, \
118}
119
120#define DOMAIN_PX30(pwr, status, req, wakeup) \
121 DOMAIN_M(pwr, status, req, (req) + 16, req, wakeup)
122
107#define DOMAIN_RK3288(pwr, status, req, wakeup) \ 123#define DOMAIN_RK3288(pwr, status, req, wakeup) \
108 DOMAIN(pwr, status, req, req, (req) + 16, wakeup) 124 DOMAIN(pwr, status, req, req, (req) + 16, wakeup)
109 125
@@ -256,7 +272,7 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
256 return; 272 return;
257 else if (pd->info->pwr_w_mask) 273 else if (pd->info->pwr_w_mask)
258 regmap_write(pmu->regmap, pmu->info->pwr_offset, 274 regmap_write(pmu->regmap, pmu->info->pwr_offset,
259 on ? pd->info->pwr_mask : 275 on ? pd->info->pwr_w_mask :
260 (pd->info->pwr_mask | pd->info->pwr_w_mask)); 276 (pd->info->pwr_mask | pd->info->pwr_w_mask));
261 else 277 else
262 regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, 278 regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
@@ -700,6 +716,49 @@ err_out:
700 return error; 716 return error;
701} 717}
702 718
719static const struct rockchip_domain_info px30_pm_domains[] = {
720 [PX30_PD_USB] = DOMAIN_PX30(5, 5, 10, false),
721 [PX30_PD_SDCARD] = DOMAIN_PX30(8, 8, 9, false),
722 [PX30_PD_GMAC] = DOMAIN_PX30(10, 10, 6, false),
723 [PX30_PD_MMC_NAND] = DOMAIN_PX30(11, 11, 5, false),
724 [PX30_PD_VPU] = DOMAIN_PX30(12, 12, 14, false),
725 [PX30_PD_VO] = DOMAIN_PX30(13, 13, 7, false),
726 [PX30_PD_VI] = DOMAIN_PX30(14, 14, 8, false),
727 [PX30_PD_GPU] = DOMAIN_PX30(15, 15, 2, false),
728};
729
730static const struct rockchip_domain_info rk3036_pm_domains[] = {
731 [RK3036_PD_MSCH] = DOMAIN_RK3036(14, 23, 30, true),
732 [RK3036_PD_CORE] = DOMAIN_RK3036(13, 17, 24, false),
733 [RK3036_PD_PERI] = DOMAIN_RK3036(12, 18, 25, false),
734 [RK3036_PD_VIO] = DOMAIN_RK3036(11, 19, 26, false),
735 [RK3036_PD_VPU] = DOMAIN_RK3036(10, 20, 27, false),
736 [RK3036_PD_GPU] = DOMAIN_RK3036(9, 21, 28, false),
737 [RK3036_PD_SYS] = DOMAIN_RK3036(8, 22, 29, false),
738};
739
740static const struct rockchip_domain_info rk3128_pm_domains[] = {
741 [RK3128_PD_CORE] = DOMAIN_RK3288(0, 0, 4, false),
742 [RK3128_PD_MSCH] = DOMAIN_RK3288(-1, -1, 6, true),
743 [RK3128_PD_VIO] = DOMAIN_RK3288(3, 3, 2, false),
744 [RK3128_PD_VIDEO] = DOMAIN_RK3288(2, 2, 1, false),
745 [RK3128_PD_GPU] = DOMAIN_RK3288(1, 1, 3, false),
746};
747
748static const struct rockchip_domain_info rk3228_pm_domains[] = {
749 [RK3228_PD_CORE] = DOMAIN_RK3036(0, 0, 16, true),
750 [RK3228_PD_MSCH] = DOMAIN_RK3036(1, 1, 17, true),
751 [RK3228_PD_BUS] = DOMAIN_RK3036(2, 2, 18, true),
752 [RK3228_PD_SYS] = DOMAIN_RK3036(3, 3, 19, true),
753 [RK3228_PD_VIO] = DOMAIN_RK3036(4, 4, 20, false),
754 [RK3228_PD_VOP] = DOMAIN_RK3036(5, 5, 21, false),
755 [RK3228_PD_VPU] = DOMAIN_RK3036(6, 6, 22, false),
756 [RK3228_PD_RKVDEC] = DOMAIN_RK3036(7, 7, 23, false),
757 [RK3228_PD_GPU] = DOMAIN_RK3036(8, 8, 24, false),
758 [RK3228_PD_PERI] = DOMAIN_RK3036(9, 9, 25, true),
759 [RK3228_PD_GMAC] = DOMAIN_RK3036(10, 10, 26, false),
760};
761
703static const struct rockchip_domain_info rk3288_pm_domains[] = { 762static const struct rockchip_domain_info rk3288_pm_domains[] = {
704 [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false), 763 [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4, false),
705 [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false), 764 [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9, false),
@@ -767,6 +826,46 @@ static const struct rockchip_domain_info rk3399_pm_domains[] = {
767 [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29, true), 826 [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399(31, 31, 29, true),
768}; 827};
769 828
829static const struct rockchip_pmu_info px30_pmu = {
830 .pwr_offset = 0x18,
831 .status_offset = 0x20,
832 .req_offset = 0x64,
833 .idle_offset = 0x6c,
834 .ack_offset = 0x6c,
835
836 .num_domains = ARRAY_SIZE(px30_pm_domains),
837 .domain_info = px30_pm_domains,
838};
839
840static const struct rockchip_pmu_info rk3036_pmu = {
841 .req_offset = 0x148,
842 .idle_offset = 0x14c,
843 .ack_offset = 0x14c,
844
845 .num_domains = ARRAY_SIZE(rk3036_pm_domains),
846 .domain_info = rk3036_pm_domains,
847};
848
849static const struct rockchip_pmu_info rk3128_pmu = {
850 .pwr_offset = 0x04,
851 .status_offset = 0x08,
852 .req_offset = 0x0c,
853 .idle_offset = 0x10,
854 .ack_offset = 0x10,
855
856 .num_domains = ARRAY_SIZE(rk3128_pm_domains),
857 .domain_info = rk3128_pm_domains,
858};
859
860static const struct rockchip_pmu_info rk3228_pmu = {
861 .req_offset = 0x40c,
862 .idle_offset = 0x488,
863 .ack_offset = 0x488,
864
865 .num_domains = ARRAY_SIZE(rk3228_pm_domains),
866 .domain_info = rk3228_pm_domains,
867};
868
770static const struct rockchip_pmu_info rk3288_pmu = { 869static const struct rockchip_pmu_info rk3288_pmu = {
771 .pwr_offset = 0x08, 870 .pwr_offset = 0x08,
772 .status_offset = 0x0c, 871 .status_offset = 0x0c,
@@ -842,6 +941,22 @@ static const struct rockchip_pmu_info rk3399_pmu = {
842 941
843static const struct of_device_id rockchip_pm_domain_dt_match[] = { 942static const struct of_device_id rockchip_pm_domain_dt_match[] = {
844 { 943 {
944 .compatible = "rockchip,px30-power-controller",
945 .data = (void *)&px30_pmu,
946 },
947 {
948 .compatible = "rockchip,rk3036-power-controller",
949 .data = (void *)&rk3036_pmu,
950 },
951 {
952 .compatible = "rockchip,rk3128-power-controller",
953 .data = (void *)&rk3128_pmu,
954 },
955 {
956 .compatible = "rockchip,rk3228-power-controller",
957 .data = (void *)&rk3228_pmu,
958 },
959 {
845 .compatible = "rockchip,rk3288-power-controller", 960 .compatible = "rockchip,rk3288-power-controller",
846 .data = (void *)&rk3288_pmu, 961 .data = (void *)&rk3288_pmu,
847 }, 962 },
diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c
index caf45cf7aa8e..ab8582971bfc 100644
--- a/drivers/soc/samsung/pm_domains.c
+++ b/drivers/soc/samsung/pm_domains.c
@@ -13,14 +13,11 @@
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/pm_domain.h> 15#include <linux/pm_domain.h>
16#include <linux/clk.h>
17#include <linux/delay.h> 16#include <linux/delay.h>
18#include <linux/of_address.h> 17#include <linux/of_address.h>
19#include <linux/of_platform.h> 18#include <linux/of_platform.h>
20#include <linux/sched.h> 19#include <linux/sched.h>
21 20
22#define MAX_CLK_PER_DOMAIN 4
23
24struct exynos_pm_domain_config { 21struct exynos_pm_domain_config {
25 /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */ 22 /* Value for LOCAL_PWR_CFG and STATUS fields for each domain */
26 u32 local_pwr_cfg; 23 u32 local_pwr_cfg;
@@ -33,10 +30,6 @@ struct exynos_pm_domain {
33 void __iomem *base; 30 void __iomem *base;
34 bool is_off; 31 bool is_off;
35 struct generic_pm_domain pd; 32 struct generic_pm_domain pd;
36 struct clk *oscclk;
37 struct clk *clk[MAX_CLK_PER_DOMAIN];
38 struct clk *pclk[MAX_CLK_PER_DOMAIN];
39 struct clk *asb_clk[MAX_CLK_PER_DOMAIN];
40 u32 local_pwr_cfg; 33 u32 local_pwr_cfg;
41}; 34};
42 35
@@ -46,29 +39,10 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
46 void __iomem *base; 39 void __iomem *base;
47 u32 timeout, pwr; 40 u32 timeout, pwr;
48 char *op; 41 char *op;
49 int i;
50 42
51 pd = container_of(domain, struct exynos_pm_domain, pd); 43 pd = container_of(domain, struct exynos_pm_domain, pd);
52 base = pd->base; 44 base = pd->base;
53 45
54 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
55 if (IS_ERR(pd->asb_clk[i]))
56 break;
57 clk_prepare_enable(pd->asb_clk[i]);
58 }
59
60 /* Set oscclk before powering off a domain*/
61 if (!power_on) {
62 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
63 if (IS_ERR(pd->clk[i]))
64 break;
65 pd->pclk[i] = clk_get_parent(pd->clk[i]);
66 if (clk_set_parent(pd->clk[i], pd->oscclk))
67 pr_err("%s: error setting oscclk as parent to clock %d\n",
68 domain->name, i);
69 }
70 }
71
72 pwr = power_on ? pd->local_pwr_cfg : 0; 46 pwr = power_on ? pd->local_pwr_cfg : 0;
73 writel_relaxed(pwr, base); 47 writel_relaxed(pwr, base);
74 48
@@ -86,26 +60,6 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
86 usleep_range(80, 100); 60 usleep_range(80, 100);
87 } 61 }
88 62
89 /* Restore clocks after powering on a domain*/
90 if (power_on) {
91 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
92 if (IS_ERR(pd->clk[i]))
93 break;
94
95 if (IS_ERR(pd->pclk[i]))
96 continue; /* Skip on first power up */
97 if (clk_set_parent(pd->clk[i], pd->pclk[i]))
98 pr_err("%s: error setting parent to clock%d\n",
99 domain->name, i);
100 }
101 }
102
103 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
104 if (IS_ERR(pd->asb_clk[i]))
105 break;
106 clk_disable_unprepare(pd->asb_clk[i]);
107 }
108
109 return 0; 63 return 0;
110} 64}
111 65
@@ -147,12 +101,6 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
147 return kstrdup_const(name, GFP_KERNEL); 101 return kstrdup_const(name, GFP_KERNEL);
148} 102}
149 103
150static const char *soc_force_no_clk[] = {
151 "samsung,exynos5250-clock",
152 "samsung,exynos5420-clock",
153 "samsung,exynos5800-clock",
154};
155
156static __init int exynos4_pm_init_power_domain(void) 104static __init int exynos4_pm_init_power_domain(void)
157{ 105{
158 struct device_node *np; 106 struct device_node *np;
@@ -161,7 +109,7 @@ static __init int exynos4_pm_init_power_domain(void)
161 for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) { 109 for_each_matching_node_and_match(np, exynos_pm_domain_of_match, &match) {
162 const struct exynos_pm_domain_config *pm_domain_cfg; 110 const struct exynos_pm_domain_config *pm_domain_cfg;
163 struct exynos_pm_domain *pd; 111 struct exynos_pm_domain *pd;
164 int on, i; 112 int on;
165 113
166 pm_domain_cfg = match->data; 114 pm_domain_cfg = match->data;
167 115
@@ -189,42 +137,6 @@ static __init int exynos4_pm_init_power_domain(void)
189 pd->pd.power_on = exynos_pd_power_on; 137 pd->pd.power_on = exynos_pd_power_on;
190 pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg; 138 pd->local_pwr_cfg = pm_domain_cfg->local_pwr_cfg;
191 139
192 for (i = 0; i < ARRAY_SIZE(soc_force_no_clk); i++)
193 if (of_find_compatible_node(NULL, NULL,
194 soc_force_no_clk[i]))
195 goto no_clk;
196
197 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
198 char clk_name[8];
199
200 snprintf(clk_name, sizeof(clk_name), "asb%d", i);
201 pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
202 if (IS_ERR(pd->asb_clk[i]))
203 break;
204 }
205
206 pd->oscclk = of_clk_get_by_name(np, "oscclk");
207 if (IS_ERR(pd->oscclk))
208 goto no_clk;
209
210 for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
211 char clk_name[8];
212
213 snprintf(clk_name, sizeof(clk_name), "clk%d", i);
214 pd->clk[i] = of_clk_get_by_name(np, clk_name);
215 if (IS_ERR(pd->clk[i]))
216 break;
217 /*
218 * Skip setting parent on first power up.
219 * The parent at this time may not be useful at all.
220 */
221 pd->pclk[i] = ERR_PTR(-EINVAL);
222 }
223
224 if (IS_ERR(pd->clk[0]))
225 clk_put(pd->oscclk);
226
227no_clk:
228 on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg; 140 on = readl_relaxed(pd->base + 0x4) & pd->local_pwr_cfg;
229 141
230 pm_genpd_init(&pd->pd, NULL, !on); 142 pm_genpd_init(&pd->pd, NULL, !on);
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
index 56866ba4cfc4..3efc47e82973 100644
--- a/drivers/soc/ti/knav_qmss.h
+++ b/drivers/soc/ti/knav_qmss.h
@@ -19,6 +19,8 @@
19#ifndef __KNAV_QMSS_H__ 19#ifndef __KNAV_QMSS_H__
20#define __KNAV_QMSS_H__ 20#define __KNAV_QMSS_H__
21 21
22#include <linux/percpu.h>
23
22#define THRESH_GTE BIT(7) 24#define THRESH_GTE BIT(7)
23#define THRESH_LT 0 25#define THRESH_LT 0
24 26
@@ -162,11 +164,11 @@ struct knav_qmgr_info {
162 * notifies: notifier counts 164 * notifies: notifier counts
163 */ 165 */
164struct knav_queue_stats { 166struct knav_queue_stats {
165 atomic_t pushes; 167 unsigned int pushes;
166 atomic_t pops; 168 unsigned int pops;
167 atomic_t push_errors; 169 unsigned int push_errors;
168 atomic_t pop_errors; 170 unsigned int pop_errors;
169 atomic_t notifies; 171 unsigned int notifies;
170}; 172};
171 173
172/** 174/**
@@ -283,7 +285,7 @@ struct knav_queue_inst {
283struct knav_queue { 285struct knav_queue {
284 struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek; 286 struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
285 struct knav_queue_inst *inst; 287 struct knav_queue_inst *inst;
286 struct knav_queue_stats stats; 288 struct knav_queue_stats __percpu *stats;
287 knav_queue_notify_fn notifier_fn; 289 knav_queue_notify_fn notifier_fn;
288 void *notifier_fn_arg; 290 void *notifier_fn_arg;
289 atomic_t notifier_enabled; 291 atomic_t notifier_enabled;
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 419365a8d1c2..6755f2af5619 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -99,7 +99,7 @@ void knav_queue_notify(struct knav_queue_inst *inst)
99 continue; 99 continue;
100 if (WARN_ON(!qh->notifier_fn)) 100 if (WARN_ON(!qh->notifier_fn))
101 continue; 101 continue;
102 atomic_inc(&qh->stats.notifies); 102 this_cpu_inc(qh->stats->notifies);
103 qh->notifier_fn(qh->notifier_fn_arg); 103 qh->notifier_fn(qh->notifier_fn_arg);
104 } 104 }
105 rcu_read_unlock(); 105 rcu_read_unlock();
@@ -230,6 +230,12 @@ static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst,
230 if (!qh) 230 if (!qh)
231 return ERR_PTR(-ENOMEM); 231 return ERR_PTR(-ENOMEM);
232 232
233 qh->stats = alloc_percpu(struct knav_queue_stats);
234 if (!qh->stats) {
235 ret = -ENOMEM;
236 goto err;
237 }
238
233 qh->flags = flags; 239 qh->flags = flags;
234 qh->inst = inst; 240 qh->inst = inst;
235 id = inst->id - inst->qmgr->start_queue; 241 id = inst->id - inst->qmgr->start_queue;
@@ -245,13 +251,17 @@ static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst,
245 if (range->ops && range->ops->open_queue) 251 if (range->ops && range->ops->open_queue)
246 ret = range->ops->open_queue(range, inst, flags); 252 ret = range->ops->open_queue(range, inst, flags);
247 253
248 if (ret) { 254 if (ret)
249 devm_kfree(inst->kdev->dev, qh); 255 goto err;
250 return ERR_PTR(ret);
251 }
252 } 256 }
253 list_add_tail_rcu(&qh->list, &inst->handles); 257 list_add_tail_rcu(&qh->list, &inst->handles);
254 return qh; 258 return qh;
259
260err:
261 if (qh->stats)
262 free_percpu(qh->stats);
263 devm_kfree(inst->kdev->dev, qh);
264 return ERR_PTR(ret);
255} 265}
256 266
257static struct knav_queue * 267static struct knav_queue *
@@ -427,6 +437,12 @@ static void knav_queue_debug_show_instance(struct seq_file *s,
427{ 437{
428 struct knav_device *kdev = inst->kdev; 438 struct knav_device *kdev = inst->kdev;
429 struct knav_queue *qh; 439 struct knav_queue *qh;
440 int cpu = 0;
441 int pushes = 0;
442 int pops = 0;
443 int push_errors = 0;
444 int pop_errors = 0;
445 int notifies = 0;
430 446
431 if (!knav_queue_is_busy(inst)) 447 if (!knav_queue_is_busy(inst))
432 return; 448 return;
@@ -434,19 +450,22 @@ static void knav_queue_debug_show_instance(struct seq_file *s,
434 seq_printf(s, "\tqueue id %d (%s)\n", 450 seq_printf(s, "\tqueue id %d (%s)\n",
435 kdev->base_id + inst->id, inst->name); 451 kdev->base_id + inst->id, inst->name);
436 for_each_handle_rcu(qh, inst) { 452 for_each_handle_rcu(qh, inst) {
437 seq_printf(s, "\t\thandle %p: ", qh); 453 for_each_possible_cpu(cpu) {
438 seq_printf(s, "pushes %8d, ", 454 pushes += per_cpu_ptr(qh->stats, cpu)->pushes;
439 atomic_read(&qh->stats.pushes)); 455 pops += per_cpu_ptr(qh->stats, cpu)->pops;
440 seq_printf(s, "pops %8d, ", 456 push_errors += per_cpu_ptr(qh->stats, cpu)->push_errors;
441 atomic_read(&qh->stats.pops)); 457 pop_errors += per_cpu_ptr(qh->stats, cpu)->pop_errors;
442 seq_printf(s, "count %8d, ", 458 notifies += per_cpu_ptr(qh->stats, cpu)->notifies;
443 knav_queue_get_count(qh)); 459 }
444 seq_printf(s, "notifies %8d, ", 460
445 atomic_read(&qh->stats.notifies)); 461 seq_printf(s, "\t\thandle %p: pushes %8d, pops %8d, count %8d, notifies %8d, push errors %8d, pop errors %8d\n",
446 seq_printf(s, "push errors %8d, ", 462 qh,
447 atomic_read(&qh->stats.push_errors)); 463 pushes,
448 seq_printf(s, "pop errors %8d\n", 464 pops,
449 atomic_read(&qh->stats.pop_errors)); 465 knav_queue_get_count(qh),
466 notifies,
467 push_errors,
468 pop_errors);
450 } 469 }
451} 470}
452 471
@@ -563,6 +582,7 @@ void knav_queue_close(void *qhandle)
563 if (range->ops && range->ops->close_queue) 582 if (range->ops && range->ops->close_queue)
564 range->ops->close_queue(range, inst); 583 range->ops->close_queue(range, inst);
565 } 584 }
585 free_percpu(qh->stats);
566 devm_kfree(inst->kdev->dev, qh); 586 devm_kfree(inst->kdev->dev, qh);
567} 587}
568EXPORT_SYMBOL_GPL(knav_queue_close); 588EXPORT_SYMBOL_GPL(knav_queue_close);
@@ -636,7 +656,7 @@ int knav_queue_push(void *qhandle, dma_addr_t dma,
636 val = (u32)dma | ((size / 16) - 1); 656 val = (u32)dma | ((size / 16) - 1);
637 writel_relaxed(val, &qh->reg_push[0].ptr_size_thresh); 657 writel_relaxed(val, &qh->reg_push[0].ptr_size_thresh);
638 658
639 atomic_inc(&qh->stats.pushes); 659 this_cpu_inc(qh->stats->pushes);
640 return 0; 660 return 0;
641} 661}
642EXPORT_SYMBOL_GPL(knav_queue_push); 662EXPORT_SYMBOL_GPL(knav_queue_push);
@@ -674,7 +694,7 @@ dma_addr_t knav_queue_pop(void *qhandle, unsigned *size)
674 if (size) 694 if (size)
675 *size = ((val & DESC_SIZE_MASK) + 1) * 16; 695 *size = ((val & DESC_SIZE_MASK) + 1) * 16;
676 696
677 atomic_inc(&qh->stats.pops); 697 this_cpu_inc(qh->stats->pops);
678 return dma; 698 return dma;
679} 699}
680EXPORT_SYMBOL_GPL(knav_queue_pop); 700EXPORT_SYMBOL_GPL(knav_queue_pop);
diff --git a/include/dt-bindings/memory/tegra114-mc.h b/include/dt-bindings/memory/tegra114-mc.h
index 27c8386987ff..dfe99c8a5ba5 100644
--- a/include/dt-bindings/memory/tegra114-mc.h
+++ b/include/dt-bindings/memory/tegra114-mc.h
@@ -23,4 +23,21 @@
23#define TEGRA_SWGROUP_EMUCIF 18 23#define TEGRA_SWGROUP_EMUCIF 18
24#define TEGRA_SWGROUP_TSEC 19 24#define TEGRA_SWGROUP_TSEC 19
25 25
26#define TEGRA114_MC_RESET_AVPC 0
27#define TEGRA114_MC_RESET_DC 1
28#define TEGRA114_MC_RESET_DCB 2
29#define TEGRA114_MC_RESET_EPP 3
30#define TEGRA114_MC_RESET_2D 4
31#define TEGRA114_MC_RESET_HC 5
32#define TEGRA114_MC_RESET_HDA 6
33#define TEGRA114_MC_RESET_ISP 7
34#define TEGRA114_MC_RESET_MPCORE 8
35#define TEGRA114_MC_RESET_MPCORELP 9
36#define TEGRA114_MC_RESET_MPE 10
37#define TEGRA114_MC_RESET_3D 11
38#define TEGRA114_MC_RESET_3D2 12
39#define TEGRA114_MC_RESET_PPCS 13
40#define TEGRA114_MC_RESET_VDE 14
41#define TEGRA114_MC_RESET_VI 15
42
26#endif 43#endif
diff --git a/include/dt-bindings/memory/tegra124-mc.h b/include/dt-bindings/memory/tegra124-mc.h
index f534d7c06019..186e6b7e9b35 100644
--- a/include/dt-bindings/memory/tegra124-mc.h
+++ b/include/dt-bindings/memory/tegra124-mc.h
@@ -29,4 +29,29 @@
29#define TEGRA_SWGROUP_VIC 24 29#define TEGRA_SWGROUP_VIC 24
30#define TEGRA_SWGROUP_VI 25 30#define TEGRA_SWGROUP_VI 25
31 31
32#define TEGRA124_MC_RESET_AFI 0
33#define TEGRA124_MC_RESET_AVPC 1
34#define TEGRA124_MC_RESET_DC 2
35#define TEGRA124_MC_RESET_DCB 3
36#define TEGRA124_MC_RESET_HC 4
37#define TEGRA124_MC_RESET_HDA 5
38#define TEGRA124_MC_RESET_ISP2 6
39#define TEGRA124_MC_RESET_MPCORE 7
40#define TEGRA124_MC_RESET_MPCORELP 8
41#define TEGRA124_MC_RESET_MSENC 9
42#define TEGRA124_MC_RESET_PPCS 10
43#define TEGRA124_MC_RESET_SATA 11
44#define TEGRA124_MC_RESET_VDE 12
45#define TEGRA124_MC_RESET_VI 13
46#define TEGRA124_MC_RESET_VIC 14
47#define TEGRA124_MC_RESET_XUSB_HOST 15
48#define TEGRA124_MC_RESET_XUSB_DEV 16
49#define TEGRA124_MC_RESET_TSEC 17
50#define TEGRA124_MC_RESET_SDMMC1 18
51#define TEGRA124_MC_RESET_SDMMC2 19
52#define TEGRA124_MC_RESET_SDMMC3 20
53#define TEGRA124_MC_RESET_SDMMC4 21
54#define TEGRA124_MC_RESET_ISP2B 22
55#define TEGRA124_MC_RESET_GPU 23
56
32#endif 57#endif
diff --git a/include/dt-bindings/memory/tegra20-mc.h b/include/dt-bindings/memory/tegra20-mc.h
new file mode 100644
index 000000000000..35e131eee198
--- /dev/null
+++ b/include/dt-bindings/memory/tegra20-mc.h
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef DT_BINDINGS_MEMORY_TEGRA20_MC_H
3#define DT_BINDINGS_MEMORY_TEGRA20_MC_H
4
5#define TEGRA20_MC_RESET_AVPC 0
6#define TEGRA20_MC_RESET_DC 1
7#define TEGRA20_MC_RESET_DCB 2
8#define TEGRA20_MC_RESET_EPP 3
9#define TEGRA20_MC_RESET_2D 4
10#define TEGRA20_MC_RESET_HC 5
11#define TEGRA20_MC_RESET_ISP 6
12#define TEGRA20_MC_RESET_MPCORE 7
13#define TEGRA20_MC_RESET_MPEA 8
14#define TEGRA20_MC_RESET_MPEB 9
15#define TEGRA20_MC_RESET_MPEC 10
16#define TEGRA20_MC_RESET_3D 11
17#define TEGRA20_MC_RESET_PPCS 12
18#define TEGRA20_MC_RESET_VDE 13
19#define TEGRA20_MC_RESET_VI 14
20
21#endif
diff --git a/include/dt-bindings/memory/tegra210-mc.h b/include/dt-bindings/memory/tegra210-mc.h
index 4490f7cf4772..cacf05617e03 100644
--- a/include/dt-bindings/memory/tegra210-mc.h
+++ b/include/dt-bindings/memory/tegra210-mc.h
@@ -34,4 +34,35 @@
34#define TEGRA_SWGROUP_ETR 29 34#define TEGRA_SWGROUP_ETR 29
35#define TEGRA_SWGROUP_TSECB 30 35#define TEGRA_SWGROUP_TSECB 30
36 36
37#define TEGRA210_MC_RESET_AFI 0
38#define TEGRA210_MC_RESET_AVPC 1
39#define TEGRA210_MC_RESET_DC 2
40#define TEGRA210_MC_RESET_DCB 3
41#define TEGRA210_MC_RESET_HC 4
42#define TEGRA210_MC_RESET_HDA 5
43#define TEGRA210_MC_RESET_ISP2 6
44#define TEGRA210_MC_RESET_MPCORE 7
45#define TEGRA210_MC_RESET_NVENC 8
46#define TEGRA210_MC_RESET_PPCS 9
47#define TEGRA210_MC_RESET_SATA 10
48#define TEGRA210_MC_RESET_VI 11
49#define TEGRA210_MC_RESET_VIC 12
50#define TEGRA210_MC_RESET_XUSB_HOST 13
51#define TEGRA210_MC_RESET_XUSB_DEV 14
52#define TEGRA210_MC_RESET_A9AVP 15
53#define TEGRA210_MC_RESET_TSEC 16
54#define TEGRA210_MC_RESET_SDMMC1 17
55#define TEGRA210_MC_RESET_SDMMC2 18
56#define TEGRA210_MC_RESET_SDMMC3 19
57#define TEGRA210_MC_RESET_SDMMC4 20
58#define TEGRA210_MC_RESET_ISP2B 21
59#define TEGRA210_MC_RESET_GPU 22
60#define TEGRA210_MC_RESET_NVDEC 23
61#define TEGRA210_MC_RESET_APE 24
62#define TEGRA210_MC_RESET_SE 25
63#define TEGRA210_MC_RESET_NVJPG 26
64#define TEGRA210_MC_RESET_AXIAP 27
65#define TEGRA210_MC_RESET_ETR 28
66#define TEGRA210_MC_RESET_TSECB 29
67
37#endif 68#endif
diff --git a/include/dt-bindings/memory/tegra30-mc.h b/include/dt-bindings/memory/tegra30-mc.h
index 3cac81919023..169f005fbc78 100644
--- a/include/dt-bindings/memory/tegra30-mc.h
+++ b/include/dt-bindings/memory/tegra30-mc.h
@@ -22,4 +22,23 @@
22#define TEGRA_SWGROUP_MPCORE 17 22#define TEGRA_SWGROUP_MPCORE 17
23#define TEGRA_SWGROUP_ISP 18 23#define TEGRA_SWGROUP_ISP 18
24 24
25#define TEGRA30_MC_RESET_AFI 0
26#define TEGRA30_MC_RESET_AVPC 1
27#define TEGRA30_MC_RESET_DC 2
28#define TEGRA30_MC_RESET_DCB 3
29#define TEGRA30_MC_RESET_EPP 4
30#define TEGRA30_MC_RESET_2D 5
31#define TEGRA30_MC_RESET_HC 6
32#define TEGRA30_MC_RESET_HDA 7
33#define TEGRA30_MC_RESET_ISP 8
34#define TEGRA30_MC_RESET_MPCORE 9
35#define TEGRA30_MC_RESET_MPCORELP 10
36#define TEGRA30_MC_RESET_MPE 11
37#define TEGRA30_MC_RESET_3D 12
38#define TEGRA30_MC_RESET_3D2 13
39#define TEGRA30_MC_RESET_PPCS 14
40#define TEGRA30_MC_RESET_SATA 15
41#define TEGRA30_MC_RESET_VDE 16
42#define TEGRA30_MC_RESET_VI 17
43
25#endif 44#endif
diff --git a/include/dt-bindings/power/px30-power.h b/include/dt-bindings/power/px30-power.h
new file mode 100644
index 000000000000..30917a99ad20
--- /dev/null
+++ b/include/dt-bindings/power/px30-power.h
@@ -0,0 +1,27 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__
3#define __DT_BINDINGS_POWER_PX30_POWER_H__
4
5/* VD_CORE */
6#define PX30_PD_A35_0 0
7#define PX30_PD_A35_1 1
8#define PX30_PD_A35_2 2
9#define PX30_PD_A35_3 3
10#define PX30_PD_SCU 4
11
12/* VD_LOGIC */
13#define PX30_PD_USB 5
14#define PX30_PD_DDR 6
15#define PX30_PD_SDCARD 7
16#define PX30_PD_CRYPTO 8
17#define PX30_PD_GMAC 9
18#define PX30_PD_MMC_NAND 10
19#define PX30_PD_VPU 11
20#define PX30_PD_VO 12
21#define PX30_PD_VI 13
22#define PX30_PD_GPU 14
23
24/* VD_PMU */
25#define PX30_PD_PMU 15
26
27#endif
diff --git a/include/dt-bindings/power/rk3036-power.h b/include/dt-bindings/power/rk3036-power.h
new file mode 100644
index 000000000000..0bc6b5d5075e
--- /dev/null
+++ b/include/dt-bindings/power/rk3036-power.h
@@ -0,0 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_POWER_RK3036_POWER_H__
3#define __DT_BINDINGS_POWER_RK3036_POWER_H__
4
5#define RK3036_PD_MSCH 0
6#define RK3036_PD_CORE 1
7#define RK3036_PD_PERI 2
8#define RK3036_PD_VIO 3
9#define RK3036_PD_VPU 4
10#define RK3036_PD_GPU 5
11#define RK3036_PD_SYS 6
12
13#endif
diff --git a/include/dt-bindings/power/rk3128-power.h b/include/dt-bindings/power/rk3128-power.h
new file mode 100644
index 000000000000..c051dc3108db
--- /dev/null
+++ b/include/dt-bindings/power/rk3128-power.h
@@ -0,0 +1,14 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_POWER_RK3128_POWER_H__
3#define __DT_BINDINGS_POWER_RK3128_POWER_H__
4
5/* VD_CORE */
6#define RK3128_PD_CORE 0
7
8/* VD_LOGIC */
9#define RK3128_PD_VIO 1
10#define RK3128_PD_VIDEO 2
11#define RK3128_PD_GPU 3
12#define RK3128_PD_MSCH 4
13
14#endif
diff --git a/include/dt-bindings/power/rk3228-power.h b/include/dt-bindings/power/rk3228-power.h
new file mode 100644
index 000000000000..6a8dc1bf76ce
--- /dev/null
+++ b/include/dt-bindings/power/rk3228-power.h
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_POWER_RK3228_POWER_H__
3#define __DT_BINDINGS_POWER_RK3228_POWER_H__
4
5/**
6 * RK3228 idle id Summary.
7 */
8
9#define RK3228_PD_CORE 0
10#define RK3228_PD_MSCH 1
11#define RK3228_PD_BUS 2
12#define RK3228_PD_SYS 3
13#define RK3228_PD_VIO 4
14#define RK3228_PD_VOP 5
15#define RK3228_PD_VPU 6
16#define RK3228_PD_RKVDEC 7
17#define RK3228_PD_GPU 8
18#define RK3228_PD_PERI 9
19#define RK3228_PD_GMAC 10
20
21#endif
diff --git a/include/linux/platform_data/ti-aemif.h b/include/linux/platform_data/ti-aemif.h
index ac72e115093c..e6407bafcbf8 100644
--- a/include/linux/platform_data/ti-aemif.h
+++ b/include/linux/platform_data/ti-aemif.h
@@ -16,8 +16,33 @@
16 16
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18 18
19/**
20 * struct aemif_abus_data - Async bus configuration parameters.
21 *
22 * @cs - Chip-select number.
23 */
24struct aemif_abus_data {
25 u32 cs;
26};
27
28/**
29 * struct aemif_platform_data - Data to set up the TI aemif driver.
30 *
31 * @dev_lookup: of_dev_auxdata passed to of_platform_populate() for aemif
32 * subdevices.
33 * @cs_offset: Lowest allowed chip-select number.
34 * @abus_data: Array of async bus configuration entries.
35 * @num_abus_data: Number of abus entries.
36 * @sub_devices: Array of platform subdevices.
37 * @num_sub_devices: Number of subdevices.
38 */
19struct aemif_platform_data { 39struct aemif_platform_data {
20 struct of_dev_auxdata *dev_lookup; 40 struct of_dev_auxdata *dev_lookup;
41 u32 cs_offset;
42 struct aemif_abus_data *abus_data;
43 size_t num_abus_data;
44 struct platform_device *sub_devices;
45 size_t num_sub_devices;
21}; 46};
22 47
23#endif /* __TI_DAVINCI_AEMIF_DATA_H__ */ 48#endif /* __TI_DAVINCI_AEMIF_DATA_H__ */
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index b458c87b866c..f4c9fc0fc755 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -85,8 +85,8 @@ struct scmi_clk_ops {
85 * @level_set: sets the performance level of a domain 85 * @level_set: sets the performance level of a domain
86 * @level_get: gets the performance level of a domain 86 * @level_get: gets the performance level of a domain
87 * @device_domain_id: gets the scmi domain id for a given device 87 * @device_domain_id: gets the scmi domain id for a given device
88 * @get_transition_latency: gets the DVFS transition latency for a given device 88 * @transition_latency_get: gets the DVFS transition latency for a given device
89 * @add_opps_to_device: adds all the OPPs for a given device 89 * @device_opps_add: adds all the OPPs for a given device
90 * @freq_set: sets the frequency for a given device using sustained frequency 90 * @freq_set: sets the frequency for a given device using sustained frequency
91 * to sustained performance level mapping 91 * to sustained performance level mapping
92 * @freq_get: gets the frequency for a given device using sustained frequency 92 * @freq_get: gets the frequency for a given device using sustained frequency
@@ -102,10 +102,10 @@ struct scmi_perf_ops {
102 int (*level_get)(const struct scmi_handle *handle, u32 domain, 102 int (*level_get)(const struct scmi_handle *handle, u32 domain,
103 u32 *level, bool poll); 103 u32 *level, bool poll);
104 int (*device_domain_id)(struct device *dev); 104 int (*device_domain_id)(struct device *dev);
105 int (*get_transition_latency)(const struct scmi_handle *handle, 105 int (*transition_latency_get)(const struct scmi_handle *handle,
106 struct device *dev); 106 struct device *dev);
107 int (*add_opps_to_device)(const struct scmi_handle *handle, 107 int (*device_opps_add)(const struct scmi_handle *handle,
108 struct device *dev); 108 struct device *dev);
109 int (*freq_set)(const struct scmi_handle *handle, u32 domain, 109 int (*freq_set)(const struct scmi_handle *handle, u32 domain,
110 unsigned long rate, bool poll); 110 unsigned long rate, bool poll);
111 int (*freq_get)(const struct scmi_handle *handle, u32 domain, 111 int (*freq_get)(const struct scmi_handle *handle, u32 domain,
@@ -189,6 +189,14 @@ struct scmi_sensor_ops {
189 * @perf_ops: pointer to set of performance protocol operations 189 * @perf_ops: pointer to set of performance protocol operations
190 * @clk_ops: pointer to set of clock protocol operations 190 * @clk_ops: pointer to set of clock protocol operations
191 * @sensor_ops: pointer to set of sensor protocol operations 191 * @sensor_ops: pointer to set of sensor protocol operations
192 * @perf_priv: pointer to private data structure specific to performance
193 * protocol(for internal use only)
194 * @clk_priv: pointer to private data structure specific to clock
195 * protocol(for internal use only)
196 * @power_priv: pointer to private data structure specific to power
197 * protocol(for internal use only)
198 * @sensor_priv: pointer to private data structure specific to sensors
199 * protocol(for internal use only)
192 */ 200 */
193struct scmi_handle { 201struct scmi_handle {
194 struct device *dev; 202 struct device *dev;
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 0ccbc138c26a..18435e5c6364 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Texas Instruments System Control Interface Protocol 3 * Texas Instruments System Control Interface Protocol
3 * 4 *
4 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ 5 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
5 * Nishanth Menon 6 * Nishanth Menon
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#ifndef __TISCI_PROTOCOL_H 9#ifndef __TISCI_PROTOCOL_H
diff --git a/include/soc/tegra/cpuidle.h b/include/soc/tegra/cpuidle.h
index 1fae9c7800d1..b6cf32211520 100644
--- a/include/soc/tegra/cpuidle.h
+++ b/include/soc/tegra/cpuidle.h
@@ -14,7 +14,7 @@
14#ifndef __SOC_TEGRA_CPUIDLE_H__ 14#ifndef __SOC_TEGRA_CPUIDLE_H__
15#define __SOC_TEGRA_CPUIDLE_H__ 15#define __SOC_TEGRA_CPUIDLE_H__
16 16
17#if defined(CONFIG_ARM) && defined(CONFIG_CPU_IDLE) 17#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_TEGRA) && defined(CONFIG_CPU_IDLE)
18void tegra_cpuidle_pcie_irqs_in_use(void); 18void tegra_cpuidle_pcie_irqs_in_use(void);
19#else 19#else
20static inline void tegra_cpuidle_pcie_irqs_in_use(void) 20static inline void tegra_cpuidle_pcie_irqs_in_use(void)
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 233bae954970..b43f37fea096 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -9,6 +9,7 @@
9#ifndef __SOC_TEGRA_MC_H__ 9#ifndef __SOC_TEGRA_MC_H__
10#define __SOC_TEGRA_MC_H__ 10#define __SOC_TEGRA_MC_H__
11 11
12#include <linux/reset-controller.h>
12#include <linux/types.h> 13#include <linux/types.h>
13 14
14struct clk; 15struct clk;
@@ -95,6 +96,30 @@ static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
95} 96}
96#endif 97#endif
97 98
99struct tegra_mc_reset {
100 const char *name;
101 unsigned long id;
102 unsigned int control;
103 unsigned int status;
104 unsigned int reset;
105 unsigned int bit;
106};
107
108struct tegra_mc_reset_ops {
109 int (*hotreset_assert)(struct tegra_mc *mc,
110 const struct tegra_mc_reset *rst);
111 int (*hotreset_deassert)(struct tegra_mc *mc,
112 const struct tegra_mc_reset *rst);
113 int (*block_dma)(struct tegra_mc *mc,
114 const struct tegra_mc_reset *rst);
115 bool (*dma_idling)(struct tegra_mc *mc,
116 const struct tegra_mc_reset *rst);
117 int (*unblock_dma)(struct tegra_mc *mc,
118 const struct tegra_mc_reset *rst);
119 int (*reset_status)(struct tegra_mc *mc,
120 const struct tegra_mc_reset *rst);
121};
122
98struct tegra_mc_soc { 123struct tegra_mc_soc {
99 const struct tegra_mc_client *clients; 124 const struct tegra_mc_client *clients;
100 unsigned int num_clients; 125 unsigned int num_clients;
@@ -108,12 +133,18 @@ struct tegra_mc_soc {
108 u8 client_id_mask; 133 u8 client_id_mask;
109 134
110 const struct tegra_smmu_soc *smmu; 135 const struct tegra_smmu_soc *smmu;
136
137 u32 intmask;
138
139 const struct tegra_mc_reset_ops *reset_ops;
140 const struct tegra_mc_reset *resets;
141 unsigned int num_resets;
111}; 142};
112 143
113struct tegra_mc { 144struct tegra_mc {
114 struct device *dev; 145 struct device *dev;
115 struct tegra_smmu *smmu; 146 struct tegra_smmu *smmu;
116 void __iomem *regs; 147 void __iomem *regs, *regs2;
117 struct clk *clk; 148 struct clk *clk;
118 int irq; 149 int irq;
119 150
@@ -122,6 +153,10 @@ struct tegra_mc {
122 153
123 struct tegra_mc_timing *timings; 154 struct tegra_mc_timing *timings;
124 unsigned int num_timings; 155 unsigned int num_timings;
156
157 struct reset_controller_dev reset;
158
159 spinlock_t lock;
125}; 160};
126 161
127void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate); 162void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);