18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#include <linux/memremap.h> 68c2ecf20Sopenharmony_ci#include <linux/rculist.h> 78c2ecf20Sopenharmony_ci#include <linux/export.h> 88c2ecf20Sopenharmony_ci#include <linux/ioport.h> 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/types.h> 118c2ecf20Sopenharmony_ci#include <linux/pfn_t.h> 128c2ecf20Sopenharmony_ci#include <linux/acpi.h> 138c2ecf20Sopenharmony_ci#include <linux/io.h> 148c2ecf20Sopenharmony_ci#include <linux/mm.h> 158c2ecf20Sopenharmony_ci#include "nfit_test.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic LIST_HEAD(iomap_head); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic struct iomap_ops { 208c2ecf20Sopenharmony_ci nfit_test_lookup_fn nfit_test_lookup; 218c2ecf20Sopenharmony_ci nfit_test_evaluate_dsm_fn evaluate_dsm; 228c2ecf20Sopenharmony_ci struct list_head list; 238c2ecf20Sopenharmony_ci} iomap_ops = { 248c2ecf20Sopenharmony_ci .list = LIST_HEAD_INIT(iomap_ops.list), 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_civoid nfit_test_setup(nfit_test_lookup_fn lookup, 288c2ecf20Sopenharmony_ci nfit_test_evaluate_dsm_fn evaluate) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci iomap_ops.nfit_test_lookup = lookup; 318c2ecf20Sopenharmony_ci iomap_ops.evaluate_dsm = evaluate; 328c2ecf20Sopenharmony_ci list_add_rcu(&iomap_ops.list, &iomap_head); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ciEXPORT_SYMBOL(nfit_test_setup); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_civoid nfit_test_teardown(void) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci list_del_rcu(&iomap_ops.list); 398c2ecf20Sopenharmony_ci synchronize_rcu(); 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ciEXPORT_SYMBOL(nfit_test_teardown); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic struct nfit_test_resource *__get_nfit_res(resource_size_t resource) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci struct iomap_ops *ops; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci ops = list_first_or_null_rcu(&iomap_head, typeof(*ops), list); 488c2ecf20Sopenharmony_ci if (ops) 498c2ecf20Sopenharmony_ci return ops->nfit_test_lookup(resource); 508c2ecf20Sopenharmony_ci return NULL; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistruct nfit_test_resource *get_nfit_res(resource_size_t resource) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci struct nfit_test_resource *res; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci rcu_read_lock(); 588c2ecf20Sopenharmony_ci res = __get_nfit_res(resource); 598c2ecf20Sopenharmony_ci rcu_read_unlock(); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci return res; 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ciEXPORT_SYMBOL(get_nfit_res); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_civoid __iomem *__nfit_test_ioremap(resource_size_t offset, unsigned long size, 668c2ecf20Sopenharmony_ci void __iomem *(*fallback_fn)(resource_size_t, unsigned long)) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (nfit_res) 718c2ecf20Sopenharmony_ci return (void __iomem *) nfit_res->buf + offset 728c2ecf20Sopenharmony_ci - nfit_res->res.start; 738c2ecf20Sopenharmony_ci return fallback_fn(offset, size); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_civoid __iomem *__wrap_devm_ioremap(struct device *dev, 778c2ecf20Sopenharmony_ci resource_size_t offset, unsigned long size) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (nfit_res) 828c2ecf20Sopenharmony_ci return (void __iomem *) nfit_res->buf + offset 838c2ecf20Sopenharmony_ci - nfit_res->res.start; 848c2ecf20Sopenharmony_ci return devm_ioremap(dev, offset, size); 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_devm_ioremap); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_civoid *__wrap_devm_memremap(struct device *dev, resource_size_t offset, 898c2ecf20Sopenharmony_ci size_t size, unsigned long flags) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci if (nfit_res) 948c2ecf20Sopenharmony_ci return nfit_res->buf + offset - nfit_res->res.start; 958c2ecf20Sopenharmony_ci return devm_memremap(dev, offset, size, flags); 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_devm_memremap); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic void nfit_test_kill(void *_pgmap) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci struct dev_pagemap *pgmap = _pgmap; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci WARN_ON(!pgmap || !pgmap->ref); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci if (pgmap->ops && pgmap->ops->kill) 1068c2ecf20Sopenharmony_ci pgmap->ops->kill(pgmap); 1078c2ecf20Sopenharmony_ci else 1088c2ecf20Sopenharmony_ci percpu_ref_kill(pgmap->ref); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci if (pgmap->ops && pgmap->ops->cleanup) { 1118c2ecf20Sopenharmony_ci pgmap->ops->cleanup(pgmap); 1128c2ecf20Sopenharmony_ci } else { 1138c2ecf20Sopenharmony_ci wait_for_completion(&pgmap->done); 1148c2ecf20Sopenharmony_ci percpu_ref_exit(pgmap->ref); 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistatic void dev_pagemap_percpu_release(struct percpu_ref *ref) 1198c2ecf20Sopenharmony_ci{ 1208c2ecf20Sopenharmony_ci struct dev_pagemap *pgmap = 1218c2ecf20Sopenharmony_ci container_of(ref, struct dev_pagemap, internal_ref); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci complete(&pgmap->done); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_civoid *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci int error; 1298c2ecf20Sopenharmony_ci resource_size_t offset = pgmap->range.start; 1308c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci if (!nfit_res) 1338c2ecf20Sopenharmony_ci return devm_memremap_pages(dev, pgmap); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci if (!pgmap->ref) { 1368c2ecf20Sopenharmony_ci if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup)) 1378c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci init_completion(&pgmap->done); 1408c2ecf20Sopenharmony_ci error = percpu_ref_init(&pgmap->internal_ref, 1418c2ecf20Sopenharmony_ci dev_pagemap_percpu_release, 0, GFP_KERNEL); 1428c2ecf20Sopenharmony_ci if (error) 1438c2ecf20Sopenharmony_ci return ERR_PTR(error); 1448c2ecf20Sopenharmony_ci pgmap->ref = &pgmap->internal_ref; 1458c2ecf20Sopenharmony_ci } else { 1468c2ecf20Sopenharmony_ci if (!pgmap->ops || !pgmap->ops->kill || !pgmap->ops->cleanup) { 1478c2ecf20Sopenharmony_ci WARN(1, "Missing reference count teardown definition\n"); 1488c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci error = devm_add_action_or_reset(dev, nfit_test_kill, pgmap); 1538c2ecf20Sopenharmony_ci if (error) 1548c2ecf20Sopenharmony_ci return ERR_PTR(error); 1558c2ecf20Sopenharmony_ci return nfit_res->buf + offset - nfit_res->res.start; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cipfn_t __wrap_phys_to_pfn_t(phys_addr_t addr, unsigned long flags) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(addr); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if (nfit_res) 1648c2ecf20Sopenharmony_ci flags &= ~PFN_MAP; 1658c2ecf20Sopenharmony_ci return phys_to_pfn_t(addr, flags); 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_phys_to_pfn_t); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_civoid *__wrap_memremap(resource_size_t offset, size_t size, 1708c2ecf20Sopenharmony_ci unsigned long flags) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci if (nfit_res) 1758c2ecf20Sopenharmony_ci return nfit_res->buf + offset - nfit_res->res.start; 1768c2ecf20Sopenharmony_ci return memremap(offset, size, flags); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_memremap); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_civoid __wrap_devm_memunmap(struct device *dev, void *addr) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci if (nfit_res) 1858c2ecf20Sopenharmony_ci return; 1868c2ecf20Sopenharmony_ci return devm_memunmap(dev, addr); 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_devm_memunmap); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_civoid __iomem *__wrap_ioremap(resource_size_t offset, unsigned long size) 1918c2ecf20Sopenharmony_ci{ 1928c2ecf20Sopenharmony_ci return __nfit_test_ioremap(offset, size, ioremap); 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_ioremap); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_civoid __iomem *__wrap_ioremap_wc(resource_size_t offset, unsigned long size) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci return __nfit_test_ioremap(offset, size, ioremap_wc); 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_ioremap_wc); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_civoid __wrap_iounmap(volatile void __iomem *addr) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); 2058c2ecf20Sopenharmony_ci if (nfit_res) 2068c2ecf20Sopenharmony_ci return; 2078c2ecf20Sopenharmony_ci return iounmap(addr); 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_iounmap); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_civoid __wrap_memunmap(void *addr) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci if (nfit_res) 2168c2ecf20Sopenharmony_ci return; 2178c2ecf20Sopenharmony_ci return memunmap(addr); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_memunmap); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_cistatic bool nfit_test_release_region(struct device *dev, 2228c2ecf20Sopenharmony_ci struct resource *parent, resource_size_t start, 2238c2ecf20Sopenharmony_ci resource_size_t n); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic void nfit_devres_release(struct device *dev, void *data) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci struct resource *res = *((struct resource **) data); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci WARN_ON(!nfit_test_release_region(NULL, &iomem_resource, res->start, 2308c2ecf20Sopenharmony_ci resource_size(res))); 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cistatic int match(struct device *dev, void *__res, void *match_data) 2348c2ecf20Sopenharmony_ci{ 2358c2ecf20Sopenharmony_ci struct resource *res = *((struct resource **) __res); 2368c2ecf20Sopenharmony_ci resource_size_t start = *((resource_size_t *) match_data); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci return res->start == start; 2398c2ecf20Sopenharmony_ci} 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic bool nfit_test_release_region(struct device *dev, 2428c2ecf20Sopenharmony_ci struct resource *parent, resource_size_t start, 2438c2ecf20Sopenharmony_ci resource_size_t n) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci if (parent == &iomem_resource) { 2468c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(start); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci if (nfit_res) { 2498c2ecf20Sopenharmony_ci struct nfit_test_request *req; 2508c2ecf20Sopenharmony_ci struct resource *res = NULL; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci if (dev) { 2538c2ecf20Sopenharmony_ci devres_release(dev, nfit_devres_release, match, 2548c2ecf20Sopenharmony_ci &start); 2558c2ecf20Sopenharmony_ci return true; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci spin_lock(&nfit_res->lock); 2598c2ecf20Sopenharmony_ci list_for_each_entry(req, &nfit_res->requests, list) 2608c2ecf20Sopenharmony_ci if (req->res.start == start) { 2618c2ecf20Sopenharmony_ci res = &req->res; 2628c2ecf20Sopenharmony_ci list_del(&req->list); 2638c2ecf20Sopenharmony_ci break; 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci spin_unlock(&nfit_res->lock); 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci WARN(!res || resource_size(res) != n, 2688c2ecf20Sopenharmony_ci "%s: start: %llx n: %llx mismatch: %pr\n", 2698c2ecf20Sopenharmony_ci __func__, start, n, res); 2708c2ecf20Sopenharmony_ci if (res) 2718c2ecf20Sopenharmony_ci kfree(req); 2728c2ecf20Sopenharmony_ci return true; 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci return false; 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_cistatic struct resource *nfit_test_request_region(struct device *dev, 2798c2ecf20Sopenharmony_ci struct resource *parent, resource_size_t start, 2808c2ecf20Sopenharmony_ci resource_size_t n, const char *name, int flags) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci if (parent == &iomem_resource) { 2858c2ecf20Sopenharmony_ci nfit_res = get_nfit_res(start); 2868c2ecf20Sopenharmony_ci if (nfit_res) { 2878c2ecf20Sopenharmony_ci struct nfit_test_request *req; 2888c2ecf20Sopenharmony_ci struct resource *res = NULL; 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci if (start + n > nfit_res->res.start 2918c2ecf20Sopenharmony_ci + resource_size(&nfit_res->res)) { 2928c2ecf20Sopenharmony_ci pr_debug("%s: start: %llx n: %llx overflow: %pr\n", 2938c2ecf20Sopenharmony_ci __func__, start, n, 2948c2ecf20Sopenharmony_ci &nfit_res->res); 2958c2ecf20Sopenharmony_ci return NULL; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci spin_lock(&nfit_res->lock); 2998c2ecf20Sopenharmony_ci list_for_each_entry(req, &nfit_res->requests, list) 3008c2ecf20Sopenharmony_ci if (start == req->res.start) { 3018c2ecf20Sopenharmony_ci res = &req->res; 3028c2ecf20Sopenharmony_ci break; 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci spin_unlock(&nfit_res->lock); 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (res) { 3078c2ecf20Sopenharmony_ci WARN(1, "%pr already busy\n", res); 3088c2ecf20Sopenharmony_ci return NULL; 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci req = kzalloc(sizeof(*req), GFP_KERNEL); 3128c2ecf20Sopenharmony_ci if (!req) 3138c2ecf20Sopenharmony_ci return NULL; 3148c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&req->list); 3158c2ecf20Sopenharmony_ci res = &req->res; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci res->start = start; 3188c2ecf20Sopenharmony_ci res->end = start + n - 1; 3198c2ecf20Sopenharmony_ci res->name = name; 3208c2ecf20Sopenharmony_ci res->flags = resource_type(parent); 3218c2ecf20Sopenharmony_ci res->flags |= IORESOURCE_BUSY | flags; 3228c2ecf20Sopenharmony_ci spin_lock(&nfit_res->lock); 3238c2ecf20Sopenharmony_ci list_add(&req->list, &nfit_res->requests); 3248c2ecf20Sopenharmony_ci spin_unlock(&nfit_res->lock); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci if (dev) { 3278c2ecf20Sopenharmony_ci struct resource **d; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci d = devres_alloc(nfit_devres_release, 3308c2ecf20Sopenharmony_ci sizeof(struct resource *), 3318c2ecf20Sopenharmony_ci GFP_KERNEL); 3328c2ecf20Sopenharmony_ci if (!d) 3338c2ecf20Sopenharmony_ci return NULL; 3348c2ecf20Sopenharmony_ci *d = res; 3358c2ecf20Sopenharmony_ci devres_add(dev, d); 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci pr_debug("%s: %pr\n", __func__, res); 3398c2ecf20Sopenharmony_ci return res; 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci if (dev) 3438c2ecf20Sopenharmony_ci return __devm_request_region(dev, parent, start, n, name); 3448c2ecf20Sopenharmony_ci return __request_region(parent, start, n, name, flags); 3458c2ecf20Sopenharmony_ci} 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistruct resource *__wrap___request_region(struct resource *parent, 3488c2ecf20Sopenharmony_ci resource_size_t start, resource_size_t n, const char *name, 3498c2ecf20Sopenharmony_ci int flags) 3508c2ecf20Sopenharmony_ci{ 3518c2ecf20Sopenharmony_ci return nfit_test_request_region(NULL, parent, start, n, name, flags); 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap___request_region); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ciint __wrap_insert_resource(struct resource *parent, struct resource *res) 3568c2ecf20Sopenharmony_ci{ 3578c2ecf20Sopenharmony_ci if (get_nfit_res(res->start)) 3588c2ecf20Sopenharmony_ci return 0; 3598c2ecf20Sopenharmony_ci return insert_resource(parent, res); 3608c2ecf20Sopenharmony_ci} 3618c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_insert_resource); 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ciint __wrap_remove_resource(struct resource *res) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci if (get_nfit_res(res->start)) 3668c2ecf20Sopenharmony_ci return 0; 3678c2ecf20Sopenharmony_ci return remove_resource(res); 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_remove_resource); 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_cistruct resource *__wrap___devm_request_region(struct device *dev, 3728c2ecf20Sopenharmony_ci struct resource *parent, resource_size_t start, 3738c2ecf20Sopenharmony_ci resource_size_t n, const char *name) 3748c2ecf20Sopenharmony_ci{ 3758c2ecf20Sopenharmony_ci if (!dev) 3768c2ecf20Sopenharmony_ci return NULL; 3778c2ecf20Sopenharmony_ci return nfit_test_request_region(dev, parent, start, n, name, 0); 3788c2ecf20Sopenharmony_ci} 3798c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap___devm_request_region); 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_civoid __wrap___release_region(struct resource *parent, resource_size_t start, 3828c2ecf20Sopenharmony_ci resource_size_t n) 3838c2ecf20Sopenharmony_ci{ 3848c2ecf20Sopenharmony_ci if (!nfit_test_release_region(NULL, parent, start, n)) 3858c2ecf20Sopenharmony_ci __release_region(parent, start, n); 3868c2ecf20Sopenharmony_ci} 3878c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap___release_region); 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_civoid __wrap___devm_release_region(struct device *dev, struct resource *parent, 3908c2ecf20Sopenharmony_ci resource_size_t start, resource_size_t n) 3918c2ecf20Sopenharmony_ci{ 3928c2ecf20Sopenharmony_ci if (!nfit_test_release_region(dev, parent, start, n)) 3938c2ecf20Sopenharmony_ci __devm_release_region(dev, parent, start, n); 3948c2ecf20Sopenharmony_ci} 3958c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap___devm_release_region); 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ciacpi_status __wrap_acpi_evaluate_object(acpi_handle handle, acpi_string path, 3988c2ecf20Sopenharmony_ci struct acpi_object_list *p, struct acpi_buffer *buf) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) handle); 4018c2ecf20Sopenharmony_ci union acpi_object **obj; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci if (!nfit_res || strcmp(path, "_FIT") || !buf) 4048c2ecf20Sopenharmony_ci return acpi_evaluate_object(handle, path, p, buf); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci obj = nfit_res->buf; 4078c2ecf20Sopenharmony_ci buf->length = sizeof(union acpi_object); 4088c2ecf20Sopenharmony_ci buf->pointer = *obj; 4098c2ecf20Sopenharmony_ci return AE_OK; 4108c2ecf20Sopenharmony_ci} 4118c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_acpi_evaluate_object); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ciunion acpi_object * __wrap_acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, 4148c2ecf20Sopenharmony_ci u64 rev, u64 func, union acpi_object *argv4) 4158c2ecf20Sopenharmony_ci{ 4168c2ecf20Sopenharmony_ci union acpi_object *obj = ERR_PTR(-ENXIO); 4178c2ecf20Sopenharmony_ci struct iomap_ops *ops; 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci rcu_read_lock(); 4208c2ecf20Sopenharmony_ci ops = list_first_or_null_rcu(&iomap_head, typeof(*ops), list); 4218c2ecf20Sopenharmony_ci if (ops) 4228c2ecf20Sopenharmony_ci obj = ops->evaluate_dsm(handle, guid, rev, func, argv4); 4238c2ecf20Sopenharmony_ci rcu_read_unlock(); 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci if (IS_ERR(obj)) 4268c2ecf20Sopenharmony_ci return acpi_evaluate_dsm(handle, guid, rev, func, argv4); 4278c2ecf20Sopenharmony_ci return obj; 4288c2ecf20Sopenharmony_ci} 4298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__wrap_acpi_evaluate_dsm); 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 432