| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: acpi_machdep.c,v 1.15 2019/12/30 19:50:29 jmcneill Exp $ */ | | 1 | /* $NetBSD: acpi_machdep.c,v 1.16 2019/12/31 11:42:46 jmcneill Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jared McNeill <jmcneill@invisible.ca>. | | 8 | * by Jared McNeill <jmcneill@invisible.ca>. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include "pci.h" | | 32 | #include "pci.h" |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.15 2019/12/30 19:50:29 jmcneill Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.16 2019/12/31 11:42:46 jmcneill Exp $"); |
36 | | | 36 | |
37 | #include <sys/param.h> | | 37 | #include <sys/param.h> |
38 | #include <sys/systm.h> | | 38 | #include <sys/systm.h> |
39 | #include <sys/bus.h> | | 39 | #include <sys/bus.h> |
40 | #include <sys/cpu.h> | | 40 | #include <sys/cpu.h> |
41 | #include <sys/device.h> | | 41 | #include <sys/device.h> |
42 | | | 42 | |
43 | #include <uvm/uvm_extern.h> | | 43 | #include <uvm/uvm_extern.h> |
44 | | | 44 | |
45 | #include <dev/fdt/fdtvar.h> | | 45 | #include <dev/fdt/fdtvar.h> |
46 | | | 46 | |
47 | #include <dev/acpi/acpica.h> | | 47 | #include <dev/acpi/acpica.h> |
48 | #include <dev/acpi/acpivar.h> | | 48 | #include <dev/acpi/acpivar.h> |
| @@ -400,41 +400,62 @@ arm_acpi_dma_tag_subregion(struct acpi_s | | | @@ -400,41 +400,62 @@ arm_acpi_dma_tag_subregion(struct acpi_s |
400 | if (error != 0) { | | 400 | if (error != 0) { |
401 | aprint_error_dev(sc->sc_dev, | | 401 | aprint_error_dev(sc->sc_dev, |
402 | "_DMA subregion failed: %d\n", error); | | 402 | "_DMA subregion failed: %d\n", error); |
403 | goto done; | | 403 | goto done; |
404 | } | | 404 | } |
405 | dmat = newtag; | | 405 | dmat = newtag; |
406 | | | 406 | |
407 | done: | | 407 | done: |
408 | acpi_resource_cleanup(&res); | | 408 | acpi_resource_cleanup(&res); |
409 | | | 409 | |
410 | return dmat; | | 410 | return dmat; |
411 | } | | 411 | } |
412 | | | 412 | |
| | | 413 | static ACPI_HANDLE |
| | | 414 | arm_acpi_dma_module(struct acpi_softc *sc, struct acpi_devnode *ad) |
| | | 415 | { |
| | | 416 | ACPI_HANDLE tmp; |
| | | 417 | ACPI_STATUS rv; |
| | | 418 | |
| | | 419 | /* |
| | | 420 | * Search up the tree for a module device with a _DMA method. |
| | | 421 | */ |
| | | 422 | for (; ad != NULL; ad = ad->ad_parent) { |
| | | 423 | if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE) |
| | | 424 | continue; |
| | | 425 | if (!acpi_match_hid(ad->ad_devinfo, module_hid)) |
| | | 426 | continue; |
| | | 427 | rv = AcpiGetHandle(ad->ad_handle, "_DMA", &tmp); |
| | | 428 | if (ACPI_SUCCESS(rv)) |
| | | 429 | return ad->ad_handle; |
| | | 430 | } |
| | | 431 | |
| | | 432 | return NULL; |
| | | 433 | } |
| | | 434 | |
413 | bus_dma_tag_t | | 435 | bus_dma_tag_t |
414 | arm_acpi_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad) | | 436 | arm_acpi_dma_tag(struct acpi_softc *sc, struct acpi_devnode *ad) |
415 | { | | 437 | { |
| | | 438 | ACPI_HANDLE module; |
416 | ACPI_INTEGER cca; | | 439 | ACPI_INTEGER cca; |
417 | bus_dma_tag_t dmat; | | 440 | bus_dma_tag_t dmat; |
418 | | | 441 | |
419 | if (ACPI_FAILURE(acpi_eval_integer(ad->ad_handle, "_CCA", &cca))) | | 442 | if (ACPI_FAILURE(acpi_eval_integer(ad->ad_handle, "_CCA", &cca))) |
420 | cca = 1; | | 443 | cca = 1; |
421 | | | 444 | |
422 | if (cca) | | 445 | if (cca) |
423 | dmat = &acpi_coherent_dma_tag; | | 446 | dmat = &acpi_coherent_dma_tag; |
424 | else | | 447 | else |
425 | dmat = &arm_generic_dma_tag; | | 448 | dmat = &arm_generic_dma_tag; |
426 | | | 449 | |
427 | /* | | 450 | /* |
428 | * If the parent device is a bus, it may define valid DMA ranges | | 451 | * If a parent device is a bus, it may define valid DMA ranges |
429 | * and translations for child nodes. | | 452 | * and translations for child nodes. |
430 | */ | | 453 | */ |
431 | if (ad->ad_parent != NULL && | | 454 | module = arm_acpi_dma_module(sc, ad); |
432 | acpi_match_hid(ad->ad_parent->ad_devinfo, module_hid)) { | | 455 | if (module != NULL) |
433 | dmat = arm_acpi_dma_tag_subregion(sc, dmat, | | 456 | dmat = arm_acpi_dma_tag_subregion(sc, dmat, module); |
434 | ad->ad_parent->ad_handle); | | | |
435 | } | | | |
436 | | | 457 | |
437 | return dmat; | | 458 | return dmat; |
438 | } | | 459 | } |
439 | __strong_alias(acpi_get_dma_tag,arm_acpi_dma_tag); | | 460 | __strong_alias(acpi_get_dma_tag,arm_acpi_dma_tag); |
440 | __strong_alias(acpi_get_dma64_tag,arm_acpi_dma_tag); | | 461 | __strong_alias(acpi_get_dma64_tag,arm_acpi_dma_tag); |