diff options
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: | |||
15 | Optional Properties: | 15 | Optional 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 | ||
21 | Deprecated Properties: | ||
22 | - clocks | ||
23 | - clock-names | ||
24 | |||
35 | Node of a device using power domains must have a power-domains property | 25 | Node of a device using power domains must have a power-domains property |
36 | defined with a phandle to respective power domain. | 26 | defined 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 | ||
6 | Required properties for power domain controller: | 6 | Required 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 | ||
18 | Required properties for power domain sub nodes: | 22 | Required 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, | |||
93 | containing a phandle to the power device node and an index specifying which | 101 | containing a phandle to the power device node and an index specifying which |
94 | power domain to use. | 102 | power domain to use. |
95 | The index should use macros in: | 103 | The 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 | |||
347 | struct 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 | |||
353 | static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, | 344 | static 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 | ||
446 | static 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 | |||
452 | struct 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 | */ |
464 | static int hisi_lpc_acpi_probe(struct device *hostdev) | 469 | static 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 | |||
558 | fail: | ||
559 | device_for_each_child(hostdev, NULL, | ||
560 | hisi_lpc_acpi_remove_subdev); | ||
561 | return ret; | ||
527 | } | 562 | } |
528 | 563 | ||
529 | static const struct acpi_device_id hisi_lpc_acpi_match[] = { | 564 | static 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; | ||
148 | put_dev: | ||
147 | put_device(&scmi_dev->dev); | 149 | put_device(&scmi_dev->dev); |
148 | kfree(scmi_dev); | ||
149 | no_mem: | ||
150 | ida_simple_remove(&scmi_bus_id, id); | 150 | ida_simple_remove(&scmi_bus_id, id); |
151 | free_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 | ||
188 | err: | 188 | err: |
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 | */ |
56 | struct scmi_msg_hdr { | 60 | struct 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 | |||
86 | struct scmi_xfer { | 89 | struct 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 | ||
94 | void scmi_one_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer); | 96 | void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer); |
95 | int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer); | 97 | int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer); |
96 | int scmi_one_xfer_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id, | 98 | int 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); |
98 | int scmi_handle_put(const struct scmi_handle *handle); | 100 | int scmi_handle_put(const struct scmi_handle *handle); |
99 | struct scmi_handle *scmi_handle_get(struct device *dev); | 101 | struct 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 | ||
43 | enum scmi_error_codes { | 39 | enum 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 */ |
59 | static LIST_HEAD(scmi_list); | 55 | static LIST_HEAD(scmi_list); |
60 | /* Protection for the entire list */ | 56 | /* Protection for the entire list */ |
61 | static DEFINE_MUTEX(scmi_list_mutex); | 57 | static DEFINE_MUTEX(scmi_list_mutex); |
@@ -72,7 +68,6 @@ static DEFINE_MUTEX(scmi_list_mutex); | |||
72 | struct scmi_xfers_info { | 68 | struct 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 | */ |
102 | struct scmi_chan_info { | 98 | struct 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 | */ |
125 | struct scmi_info { | 121 | struct 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 | */ |
256 | static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr) | 252 | static 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 | */ |
302 | static struct scmi_xfer *scmi_one_xfer_get(const struct scmi_handle *handle) | 298 | static 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 | */ |
338 | void scmi_one_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) | 334 | void 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 | */ |
388 | int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) | 384 | int 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 | */ |
458 | int scmi_one_xfer_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id, | 454 | int 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 | ||
601 | static const struct scmi_desc scmi_generic_desc = { | 600 | static 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 | ||
352 | static int scmi_dvfs_add_opps_to_device(const struct scmi_handle *handle, | 352 | static 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 | ||
386 | static int scmi_dvfs_get_transition_latency(const struct scmi_handle *handle, | 386 | static 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 | ||
107 | config 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 | |||
117 | config FSL_CORENET_CF | 107 | config 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 | |||
16 | obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o | 16 | obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o |
17 | obj-$(CONFIG_FSL_IFC) += fsl_ifc.o | 17 | obj-$(CONFIG_FSL_IFC) += fsl_ifc.o |
18 | obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o | 18 | obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o |
19 | obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o | ||
20 | obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o | 19 | obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o |
21 | obj-$(CONFIG_MTK_SMI) += mtk-smi.o | 20 | obj-$(CONFIG_MTK_SMI) += mtk-smi.o |
22 | obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o | 21 | obj-$(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"); | 719 | static 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 | |||
743 | err: | ||
744 | dev_err(dev, "failed to initialize -- error %d\n", ret); | ||
745 | |||
746 | return ret; | ||
747 | } | 724 | } |
748 | 725 | ||
749 | static const struct of_device_id brcmstb_dpfe_of_match[] = { | 726 | static 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 |
2 | tegra-mc-y := mc.o | 2 | tegra-mc-y := mc.o |
3 | 3 | ||
4 | tegra-mc-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20.o | ||
4 | tegra-mc-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30.o | 5 | tegra-mc-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30.o |
5 | tegra-mc-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114.o | 6 | tegra-mc-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114.o |
6 | tegra-mc-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o | 7 | tegra-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 | ||
56 | static const struct of_device_id tegra_mc_of_match[] = { | 52 | static 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 | }; |
74 | MODULE_DEVICE_TABLE(of, tegra_mc_of_match); | 73 | MODULE_DEVICE_TABLE(of, tegra_mc_of_match); |
75 | 74 | ||
75 | static 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 | |||
91 | static 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 | |||
97 | static 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 | |||
113 | static 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 | |||
119 | const 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 | |||
126 | static inline struct tegra_mc *reset_to_mc(struct reset_controller_dev *rcdev) | ||
127 | { | ||
128 | return container_of(rcdev, struct tegra_mc, reset); | ||
129 | } | ||
130 | |||
131 | static 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 | |||
143 | static 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 | |||
196 | static 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 | |||
235 | static 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 | |||
253 | static 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 | |||
259 | static 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 | |||
76 | static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc) | 276 | static 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) | |||
229 | static const char *const status_names[32] = { | 429 | static 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] = { | |||
248 | static irqreturn_t tegra_mc_irq(int irq, void *data) | 449 | static 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 | ||
546 | static __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 | |||
344 | static int tegra_mc_probe(struct platform_device *pdev) | 612 | static 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 | |||
17 | static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset) | 27 | static 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 | ||
22 | static inline void mc_writel(struct tegra_mc *mc, u32 value, | 35 | static 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 | ||
44 | extern const struct tegra_mc_reset_ops terga_mc_reset_ops_common; | ||
45 | |||
46 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
47 | extern 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 |
29 | extern const struct tegra_mc_soc tegra30_mc_soc; | 51 | extern 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 | |||
950 | static 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 | |||
941 | const struct tegra_mc_soc tegra114_mc_soc = { | 969 | const 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 | |||
1024 | static 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 |
1016 | static const struct tegra_smmu_soc tegra124_smmu_soc = { | 1052 | static 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 | |||
13 | static 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 | |||
183 | static 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 | |||
201 | static 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 | |||
217 | static 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 | |||
233 | static 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 | |||
249 | static 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 | |||
255 | static 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 | |||
261 | static 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 | |||
277 | const 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 | |||
286 | const 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 | |||
1092 | static 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 | |||
1088 | const struct tegra_mc_soc tegra210_mc_soc = { | 1125 | const 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 | |||
972 | static 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 | |||
963 | const struct tegra_mc_soc tegra30_mc_soc = { | 993 | const 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 | |||
50 | struct tegra20_mc { | ||
51 | void __iomem *regs[NUM_MC_REG_BANKS]; | ||
52 | struct device *dev; | ||
53 | }; | ||
54 | |||
55 | static 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 | |||
67 | static 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 | |||
75 | static 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 | |||
130 | static 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 | |||
181 | static const struct of_device_id tegra20_mc_of_match[] = { | ||
182 | { .compatible = "nvidia,tegra20-mc", }, | ||
183 | {}, | ||
184 | }; | ||
185 | |||
186 | static 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 | |||
205 | static 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 | |||
242 | static 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 | }; | ||
249 | module_platform_driver(tegra20_mc_driver); | ||
250 | |||
251 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | ||
252 | MODULE_DESCRIPTION("Tegra20 MC driver"); | ||
253 | MODULE_LICENSE("GPL v2"); | ||
254 | MODULE_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 | ||
158 | static struct imx7_pgc_domain imx7_pgc_domains[] = { | 158 | static 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 @@ | |||
37 | int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, | 40 | int 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, | |||
80 | int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, | 71 | int 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 | ||
122 | struct scp; | 130 | struct 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 | ||
1068 | static int scpsys_probe(struct platform_device *pdev) | 1037 | static 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 | ||
719 | static 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 | |||
730 | static 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 | |||
740 | static 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 | |||
748 | static 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 | |||
703 | static const struct rockchip_domain_info rk3288_pm_domains[] = { | 762 | static 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 | ||
829 | static 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 | |||
840 | static 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 | |||
849 | static 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 | |||
860 | static 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 | |||
770 | static const struct rockchip_pmu_info rk3288_pmu = { | 869 | static 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 | ||
843 | static const struct of_device_id rockchip_pm_domain_dt_match[] = { | 942 | static 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 | |||
24 | struct exynos_pm_domain_config { | 21 | struct 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 | ||
150 | static const char *soc_force_no_clk[] = { | ||
151 | "samsung,exynos5250-clock", | ||
152 | "samsung,exynos5420-clock", | ||
153 | "samsung,exynos5800-clock", | ||
154 | }; | ||
155 | |||
156 | static __init int exynos4_pm_init_power_domain(void) | 104 | static __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 | |||
227 | no_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 | */ |
164 | struct knav_queue_stats { | 166 | struct 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 { | |||
283 | struct knav_queue { | 285 | struct 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 | |||
260 | err: | ||
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 | ||
257 | static struct knav_queue * | 267 | static 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 | } |
568 | EXPORT_SYMBOL_GPL(knav_queue_close); | 588 | EXPORT_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 | } |
642 | EXPORT_SYMBOL_GPL(knav_queue_push); | 662 | EXPORT_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 | } |
680 | EXPORT_SYMBOL_GPL(knav_queue_pop); | 700 | EXPORT_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 | */ | ||
24 | struct 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 | */ | ||
19 | struct aemif_platform_data { | 39 | struct 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 | */ |
193 | struct scmi_handle { | 201 | struct 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) |
18 | void tegra_cpuidle_pcie_irqs_in_use(void); | 18 | void tegra_cpuidle_pcie_irqs_in_use(void); |
19 | #else | 19 | #else |
20 | static inline void tegra_cpuidle_pcie_irqs_in_use(void) | 20 | static 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 | ||
14 | struct clk; | 15 | struct clk; |
@@ -95,6 +96,30 @@ static inline void tegra_smmu_remove(struct tegra_smmu *smmu) | |||
95 | } | 96 | } |
96 | #endif | 97 | #endif |
97 | 98 | ||
99 | struct 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 | |||
108 | struct 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 | |||
98 | struct tegra_mc_soc { | 123 | struct 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 | ||
113 | struct tegra_mc { | 144 | struct 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 | ||
127 | void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate); | 162 | void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate); |