162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#include <linux/memremap.h> 662306a36Sopenharmony_ci#include <linux/rculist.h> 762306a36Sopenharmony_ci#include <linux/export.h> 862306a36Sopenharmony_ci#include <linux/ioport.h> 962306a36Sopenharmony_ci#include <linux/module.h> 1062306a36Sopenharmony_ci#include <linux/types.h> 1162306a36Sopenharmony_ci#include <linux/pfn_t.h> 1262306a36Sopenharmony_ci#include <linux/acpi.h> 1362306a36Sopenharmony_ci#include <linux/io.h> 1462306a36Sopenharmony_ci#include <linux/mm.h> 1562306a36Sopenharmony_ci#include "nfit_test.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic LIST_HEAD(iomap_head); 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic struct iomap_ops { 2062306a36Sopenharmony_ci nfit_test_lookup_fn nfit_test_lookup; 2162306a36Sopenharmony_ci nfit_test_evaluate_dsm_fn evaluate_dsm; 2262306a36Sopenharmony_ci struct list_head list; 2362306a36Sopenharmony_ci} iomap_ops = { 2462306a36Sopenharmony_ci .list = LIST_HEAD_INIT(iomap_ops.list), 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_civoid nfit_test_setup(nfit_test_lookup_fn lookup, 2862306a36Sopenharmony_ci nfit_test_evaluate_dsm_fn evaluate) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci iomap_ops.nfit_test_lookup = lookup; 3162306a36Sopenharmony_ci iomap_ops.evaluate_dsm = evaluate; 3262306a36Sopenharmony_ci list_add_rcu(&iomap_ops.list, &iomap_head); 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ciEXPORT_SYMBOL(nfit_test_setup); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_civoid nfit_test_teardown(void) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci list_del_rcu(&iomap_ops.list); 3962306a36Sopenharmony_ci synchronize_rcu(); 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ciEXPORT_SYMBOL(nfit_test_teardown); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic struct nfit_test_resource *__get_nfit_res(resource_size_t resource) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci struct iomap_ops *ops; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci ops = list_first_or_null_rcu(&iomap_head, typeof(*ops), list); 4862306a36Sopenharmony_ci if (ops) 4962306a36Sopenharmony_ci return ops->nfit_test_lookup(resource); 5062306a36Sopenharmony_ci return NULL; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistruct nfit_test_resource *get_nfit_res(resource_size_t resource) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci struct nfit_test_resource *res; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci rcu_read_lock(); 5862306a36Sopenharmony_ci res = __get_nfit_res(resource); 5962306a36Sopenharmony_ci rcu_read_unlock(); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return res; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ciEXPORT_SYMBOL(get_nfit_res); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define __nfit_test_ioremap(offset, size, fallback_fn) ({ \ 6662306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); \ 6762306a36Sopenharmony_ci nfit_res ? \ 6862306a36Sopenharmony_ci (void __iomem *) nfit_res->buf + (offset) \ 6962306a36Sopenharmony_ci - nfit_res->res.start \ 7062306a36Sopenharmony_ci : \ 7162306a36Sopenharmony_ci fallback_fn((offset), (size)) ; \ 7262306a36Sopenharmony_ci}) 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_civoid __iomem *__wrap_devm_ioremap(struct device *dev, 7562306a36Sopenharmony_ci resource_size_t offset, unsigned long size) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if (nfit_res) 8062306a36Sopenharmony_ci return (void __iomem *) nfit_res->buf + offset 8162306a36Sopenharmony_ci - nfit_res->res.start; 8262306a36Sopenharmony_ci return devm_ioremap(dev, offset, size); 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_devm_ioremap); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_civoid *__wrap_devm_memremap(struct device *dev, resource_size_t offset, 8762306a36Sopenharmony_ci size_t size, unsigned long flags) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci if (nfit_res) 9262306a36Sopenharmony_ci return nfit_res->buf + offset - nfit_res->res.start; 9362306a36Sopenharmony_ci return devm_memremap(dev, offset, size, flags); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_devm_memremap); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic void nfit_test_kill(void *_pgmap) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci struct dev_pagemap *pgmap = _pgmap; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci WARN_ON(!pgmap); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci percpu_ref_kill(&pgmap->ref); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci wait_for_completion(&pgmap->done); 10662306a36Sopenharmony_ci percpu_ref_exit(&pgmap->ref); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic void dev_pagemap_percpu_release(struct percpu_ref *ref) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci struct dev_pagemap *pgmap = container_of(ref, struct dev_pagemap, ref); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci complete(&pgmap->done); 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_civoid *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci int error; 11962306a36Sopenharmony_ci resource_size_t offset = pgmap->range.start; 12062306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (!nfit_res) 12362306a36Sopenharmony_ci return devm_memremap_pages(dev, pgmap); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci init_completion(&pgmap->done); 12662306a36Sopenharmony_ci error = percpu_ref_init(&pgmap->ref, dev_pagemap_percpu_release, 0, 12762306a36Sopenharmony_ci GFP_KERNEL); 12862306a36Sopenharmony_ci if (error) 12962306a36Sopenharmony_ci return ERR_PTR(error); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci error = devm_add_action_or_reset(dev, nfit_test_kill, pgmap); 13262306a36Sopenharmony_ci if (error) 13362306a36Sopenharmony_ci return ERR_PTR(error); 13462306a36Sopenharmony_ci return nfit_res->buf + offset - nfit_res->res.start; 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cipfn_t __wrap_phys_to_pfn_t(phys_addr_t addr, unsigned long flags) 13962306a36Sopenharmony_ci{ 14062306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(addr); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci if (nfit_res) 14362306a36Sopenharmony_ci flags &= ~PFN_MAP; 14462306a36Sopenharmony_ci return phys_to_pfn_t(addr, flags); 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_phys_to_pfn_t); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_civoid *__wrap_memremap(resource_size_t offset, size_t size, 14962306a36Sopenharmony_ci unsigned long flags) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(offset); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci if (nfit_res) 15462306a36Sopenharmony_ci return nfit_res->buf + offset - nfit_res->res.start; 15562306a36Sopenharmony_ci return memremap(offset, size, flags); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_memremap); 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_civoid __wrap_devm_memunmap(struct device *dev, void *addr) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci if (nfit_res) 16462306a36Sopenharmony_ci return; 16562306a36Sopenharmony_ci return devm_memunmap(dev, addr); 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_devm_memunmap); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_civoid __iomem *__wrap_ioremap(resource_size_t offset, unsigned long size) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci return __nfit_test_ioremap(offset, size, ioremap); 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_ioremap); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_civoid __iomem *__wrap_ioremap_wc(resource_size_t offset, unsigned long size) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci return __nfit_test_ioremap(offset, size, ioremap_wc); 17862306a36Sopenharmony_ci} 17962306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_ioremap_wc); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_civoid __wrap_iounmap(volatile void __iomem *addr) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); 18462306a36Sopenharmony_ci if (nfit_res) 18562306a36Sopenharmony_ci return; 18662306a36Sopenharmony_ci return iounmap(addr); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_iounmap); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_civoid __wrap_memunmap(void *addr) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) addr); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci if (nfit_res) 19562306a36Sopenharmony_ci return; 19662306a36Sopenharmony_ci return memunmap(addr); 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_memunmap); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistatic bool nfit_test_release_region(struct device *dev, 20162306a36Sopenharmony_ci struct resource *parent, resource_size_t start, 20262306a36Sopenharmony_ci resource_size_t n); 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic void nfit_devres_release(struct device *dev, void *data) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci struct resource *res = *((struct resource **) data); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci WARN_ON(!nfit_test_release_region(NULL, &iomem_resource, res->start, 20962306a36Sopenharmony_ci resource_size(res))); 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistatic int match(struct device *dev, void *__res, void *match_data) 21362306a36Sopenharmony_ci{ 21462306a36Sopenharmony_ci struct resource *res = *((struct resource **) __res); 21562306a36Sopenharmony_ci resource_size_t start = *((resource_size_t *) match_data); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci return res->start == start; 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic bool nfit_test_release_region(struct device *dev, 22162306a36Sopenharmony_ci struct resource *parent, resource_size_t start, 22262306a36Sopenharmony_ci resource_size_t n) 22362306a36Sopenharmony_ci{ 22462306a36Sopenharmony_ci if (parent == &iomem_resource) { 22562306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res(start); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci if (nfit_res) { 22862306a36Sopenharmony_ci struct nfit_test_request *req; 22962306a36Sopenharmony_ci struct resource *res = NULL; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci if (dev) { 23262306a36Sopenharmony_ci devres_release(dev, nfit_devres_release, match, 23362306a36Sopenharmony_ci &start); 23462306a36Sopenharmony_ci return true; 23562306a36Sopenharmony_ci } 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci spin_lock(&nfit_res->lock); 23862306a36Sopenharmony_ci list_for_each_entry(req, &nfit_res->requests, list) 23962306a36Sopenharmony_ci if (req->res.start == start) { 24062306a36Sopenharmony_ci res = &req->res; 24162306a36Sopenharmony_ci list_del(&req->list); 24262306a36Sopenharmony_ci break; 24362306a36Sopenharmony_ci } 24462306a36Sopenharmony_ci spin_unlock(&nfit_res->lock); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci WARN(!res || resource_size(res) != n, 24762306a36Sopenharmony_ci "%s: start: %llx n: %llx mismatch: %pr\n", 24862306a36Sopenharmony_ci __func__, start, n, res); 24962306a36Sopenharmony_ci if (res) 25062306a36Sopenharmony_ci kfree(req); 25162306a36Sopenharmony_ci return true; 25262306a36Sopenharmony_ci } 25362306a36Sopenharmony_ci } 25462306a36Sopenharmony_ci return false; 25562306a36Sopenharmony_ci} 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistatic struct resource *nfit_test_request_region(struct device *dev, 25862306a36Sopenharmony_ci struct resource *parent, resource_size_t start, 25962306a36Sopenharmony_ci resource_size_t n, const char *name, int flags) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci struct nfit_test_resource *nfit_res; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci if (parent == &iomem_resource) { 26462306a36Sopenharmony_ci nfit_res = get_nfit_res(start); 26562306a36Sopenharmony_ci if (nfit_res) { 26662306a36Sopenharmony_ci struct nfit_test_request *req; 26762306a36Sopenharmony_ci struct resource *res = NULL; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci if (start + n > nfit_res->res.start 27062306a36Sopenharmony_ci + resource_size(&nfit_res->res)) { 27162306a36Sopenharmony_ci pr_debug("%s: start: %llx n: %llx overflow: %pr\n", 27262306a36Sopenharmony_ci __func__, start, n, 27362306a36Sopenharmony_ci &nfit_res->res); 27462306a36Sopenharmony_ci return NULL; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci spin_lock(&nfit_res->lock); 27862306a36Sopenharmony_ci list_for_each_entry(req, &nfit_res->requests, list) 27962306a36Sopenharmony_ci if (start == req->res.start) { 28062306a36Sopenharmony_ci res = &req->res; 28162306a36Sopenharmony_ci break; 28262306a36Sopenharmony_ci } 28362306a36Sopenharmony_ci spin_unlock(&nfit_res->lock); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (res) { 28662306a36Sopenharmony_ci WARN(1, "%pr already busy\n", res); 28762306a36Sopenharmony_ci return NULL; 28862306a36Sopenharmony_ci } 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci req = kzalloc(sizeof(*req), GFP_KERNEL); 29162306a36Sopenharmony_ci if (!req) 29262306a36Sopenharmony_ci return NULL; 29362306a36Sopenharmony_ci INIT_LIST_HEAD(&req->list); 29462306a36Sopenharmony_ci res = &req->res; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci res->start = start; 29762306a36Sopenharmony_ci res->end = start + n - 1; 29862306a36Sopenharmony_ci res->name = name; 29962306a36Sopenharmony_ci res->flags = resource_type(parent); 30062306a36Sopenharmony_ci res->flags |= IORESOURCE_BUSY | flags; 30162306a36Sopenharmony_ci spin_lock(&nfit_res->lock); 30262306a36Sopenharmony_ci list_add(&req->list, &nfit_res->requests); 30362306a36Sopenharmony_ci spin_unlock(&nfit_res->lock); 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci if (dev) { 30662306a36Sopenharmony_ci struct resource **d; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci d = devres_alloc(nfit_devres_release, 30962306a36Sopenharmony_ci sizeof(struct resource *), 31062306a36Sopenharmony_ci GFP_KERNEL); 31162306a36Sopenharmony_ci if (!d) 31262306a36Sopenharmony_ci return NULL; 31362306a36Sopenharmony_ci *d = res; 31462306a36Sopenharmony_ci devres_add(dev, d); 31562306a36Sopenharmony_ci } 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci pr_debug("%s: %pr\n", __func__, res); 31862306a36Sopenharmony_ci return res; 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci if (dev) 32262306a36Sopenharmony_ci return __devm_request_region(dev, parent, start, n, name); 32362306a36Sopenharmony_ci return __request_region(parent, start, n, name, flags); 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistruct resource *__wrap___request_region(struct resource *parent, 32762306a36Sopenharmony_ci resource_size_t start, resource_size_t n, const char *name, 32862306a36Sopenharmony_ci int flags) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci return nfit_test_request_region(NULL, parent, start, n, name, flags); 33162306a36Sopenharmony_ci} 33262306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap___request_region); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ciint __wrap_insert_resource(struct resource *parent, struct resource *res) 33562306a36Sopenharmony_ci{ 33662306a36Sopenharmony_ci if (get_nfit_res(res->start)) 33762306a36Sopenharmony_ci return 0; 33862306a36Sopenharmony_ci return insert_resource(parent, res); 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_insert_resource); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ciint __wrap_remove_resource(struct resource *res) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci if (get_nfit_res(res->start)) 34562306a36Sopenharmony_ci return 0; 34662306a36Sopenharmony_ci return remove_resource(res); 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_remove_resource); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cistruct resource *__wrap___devm_request_region(struct device *dev, 35162306a36Sopenharmony_ci struct resource *parent, resource_size_t start, 35262306a36Sopenharmony_ci resource_size_t n, const char *name) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci if (!dev) 35562306a36Sopenharmony_ci return NULL; 35662306a36Sopenharmony_ci return nfit_test_request_region(dev, parent, start, n, name, 0); 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap___devm_request_region); 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_civoid __wrap___release_region(struct resource *parent, resource_size_t start, 36162306a36Sopenharmony_ci resource_size_t n) 36262306a36Sopenharmony_ci{ 36362306a36Sopenharmony_ci if (!nfit_test_release_region(NULL, parent, start, n)) 36462306a36Sopenharmony_ci __release_region(parent, start, n); 36562306a36Sopenharmony_ci} 36662306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap___release_region); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_civoid __wrap___devm_release_region(struct device *dev, struct resource *parent, 36962306a36Sopenharmony_ci resource_size_t start, resource_size_t n) 37062306a36Sopenharmony_ci{ 37162306a36Sopenharmony_ci if (!nfit_test_release_region(dev, parent, start, n)) 37262306a36Sopenharmony_ci __devm_release_region(dev, parent, start, n); 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap___devm_release_region); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ciacpi_status __wrap_acpi_evaluate_object(acpi_handle handle, acpi_string path, 37762306a36Sopenharmony_ci struct acpi_object_list *p, struct acpi_buffer *buf) 37862306a36Sopenharmony_ci{ 37962306a36Sopenharmony_ci struct nfit_test_resource *nfit_res = get_nfit_res((long) handle); 38062306a36Sopenharmony_ci union acpi_object **obj; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci if (!nfit_res || strcmp(path, "_FIT") || !buf) 38362306a36Sopenharmony_ci return acpi_evaluate_object(handle, path, p, buf); 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci obj = nfit_res->buf; 38662306a36Sopenharmony_ci buf->length = sizeof(union acpi_object); 38762306a36Sopenharmony_ci buf->pointer = *obj; 38862306a36Sopenharmony_ci return AE_OK; 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_acpi_evaluate_object); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ciunion acpi_object * __wrap_acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid, 39362306a36Sopenharmony_ci u64 rev, u64 func, union acpi_object *argv4) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci union acpi_object *obj = ERR_PTR(-ENXIO); 39662306a36Sopenharmony_ci struct iomap_ops *ops; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci rcu_read_lock(); 39962306a36Sopenharmony_ci ops = list_first_or_null_rcu(&iomap_head, typeof(*ops), list); 40062306a36Sopenharmony_ci if (ops) 40162306a36Sopenharmony_ci obj = ops->evaluate_dsm(handle, guid, rev, func, argv4); 40262306a36Sopenharmony_ci rcu_read_unlock(); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci if (IS_ERR(obj)) 40562306a36Sopenharmony_ci return acpi_evaluate_dsm(handle, guid, rev, func, argv4); 40662306a36Sopenharmony_ci return obj; 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ciEXPORT_SYMBOL(__wrap_acpi_evaluate_dsm); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 411