VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
b24413180f560 (Greg Kroah-Hartman     2017-11-01 15:07:57 +0100   1) // SPDX-License-Identifier: GPL-2.0
f4a18312f46a6 (Thierry Reding         2013-01-22 22:24:46 +0100   2) #include <linux/err.h>
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000   3) #include <linux/pci.h>
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000   4) #include <linux/io.h>
5a0e3ad6af866 (Tejun Heo              2010-03-24 17:04:11 +0900   5) #include <linux/gfp.h>
8bc3bcc93a2b4 (Paul Gortmaker         2011-11-16 21:29:17 -0500   6) #include <linux/export.h>
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000   7) #include <linux/of_address.h>
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000   8) 
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800   9) enum devm_ioremap_type {
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  10) 	DEVM_IOREMAP = 0,
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  11) 	DEVM_IOREMAP_UC,
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  12) 	DEVM_IOREMAP_WC,
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900  13) 	DEVM_IOREMAP_NP,
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  14) };
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  15) 
b41e5fffe8b81 (Emil Medve             2008-05-03 06:34:04 +1000  16) void devm_ioremap_release(struct device *dev, void *res)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  17) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  18) 	iounmap(*(void __iomem **)res);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  19) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  20) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  21) static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  22) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  23) 	return *(void **)res == match_data;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  24) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  25) 
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  26) static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  27) 				    resource_size_t size,
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  28) 				    enum devm_ioremap_type type)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  29) {
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  30) 	void __iomem **ptr, *addr = NULL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  31) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  32) 	ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  33) 	if (!ptr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  34) 		return NULL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  35) 
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  36) 	switch (type) {
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  37) 	case DEVM_IOREMAP:
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  38) 		addr = ioremap(offset, size);
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  39) 		break;
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  40) 	case DEVM_IOREMAP_UC:
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  41) 		addr = ioremap_uc(offset, size);
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  42) 		break;
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  43) 	case DEVM_IOREMAP_WC:
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  44) 		addr = ioremap_wc(offset, size);
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  45) 		break;
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900  46) 	case DEVM_IOREMAP_NP:
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900  47) 		addr = ioremap_np(offset, size);
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900  48) 		break;
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  49) 	}
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  50) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  51) 	if (addr) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  52) 		*ptr = addr;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  53) 		devres_add(dev, ptr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  54) 	} else
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  55) 		devres_free(ptr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  56) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  57) 	return addr;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  58) }
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  59) 
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  60) /**
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  61)  * devm_ioremap - Managed ioremap()
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  62)  * @dev: Generic device to remap IO address for
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  63)  * @offset: Resource address to map
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  64)  * @size: Size of map
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  65)  *
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  66)  * Managed ioremap().  Map is automatically unmapped on driver detach.
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  67)  */
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  68) void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  69) 			   resource_size_t size)
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  70) {
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  71) 	return __devm_ioremap(dev, offset, size, DEVM_IOREMAP);
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800  72) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  73) EXPORT_SYMBOL(devm_ioremap);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000  74) 
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  75) /**
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  76)  * devm_ioremap_uc - Managed ioremap_uc()
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  77)  * @dev: Generic device to remap IO address for
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  78)  * @offset: Resource address to map
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  79)  * @size: Size of map
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  80)  *
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  81)  * Managed ioremap_uc().  Map is automatically unmapped on driver detach.
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  82)  */
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  83) void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  84) 			      resource_size_t size)
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  85) {
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  86) 	return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_UC);
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  87) }
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  88) EXPORT_SYMBOL_GPL(devm_ioremap_uc);
e537654b7039a (Tuowen Zhao            2019-10-16 15:06:28 -0600  89) 
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  90) /**
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  91)  * devm_ioremap_wc - Managed ioremap_wc()
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  92)  * @dev: Generic device to remap IO address for
6524754eff305 (Lorenzo Pieralisi      2017-04-19 17:48:54 +0100  93)  * @offset: Resource address to map
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  94)  * @size: Size of map
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  95)  *
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  96)  * Managed ioremap_wc().  Map is automatically unmapped on driver detach.
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  97)  */
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  98) void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530  99) 			      resource_size_t size)
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530 100) {
1b723413aada7 (Yisheng Xie            2018-01-29 19:48:16 +0800 101) 	return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_WC);
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530 102) }
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530 103) EXPORT_SYMBOL(devm_ioremap_wc);
34644524bce91 (Abhilash Kesavan       2015-02-06 19:15:27 +0530 104) 
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 105) /**
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 106)  * devm_ioremap_np - Managed ioremap_np()
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 107)  * @dev: Generic device to remap IO address for
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 108)  * @offset: Resource address to map
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 109)  * @size: Size of map
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 110)  *
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 111)  * Managed ioremap_np().  Map is automatically unmapped on driver detach.
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 112)  */
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 113) void __iomem *devm_ioremap_np(struct device *dev, resource_size_t offset,
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 114) 			      resource_size_t size)
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 115) {
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 116) 	return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NP);
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 117) }
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 118) EXPORT_SYMBOL(devm_ioremap_np);
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 119) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 120) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 121)  * devm_iounmap - Managed iounmap()
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 122)  * @dev: Generic device to unmap for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 123)  * @addr: Address to unmap
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 124)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 125)  * Managed iounmap().  @addr must have been mapped using devm_ioremap*().
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 126)  */
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 127) void devm_iounmap(struct device *dev, void __iomem *addr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 128) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 129) 	WARN_ON(devres_destroy(dev, devm_ioremap_release, devm_ioremap_match,
b104d6a5a82a5 (Steven Rostedt         2014-04-03 14:49:07 -0700 130) 			       (__force void *)addr));
ae891a1b93bf6 (Maxin B John           2011-07-25 17:12:59 -0700 131) 	iounmap(addr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 132) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 133) EXPORT_SYMBOL(devm_iounmap);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 134) 
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 135) static void __iomem *
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 136) __devm_ioremap_resource(struct device *dev, const struct resource *res,
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 137) 			enum devm_ioremap_type type)
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 138) {
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 139) 	resource_size_t size;
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 140) 	void __iomem *dest_ptr;
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 141) 	char *pretty_name;
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 142) 
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 143) 	BUG_ON(!dev);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 144) 
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 145) 	if (!res || resource_type(res) != IORESOURCE_MEM) {
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 146) 		dev_err(dev, "invalid resource\n");
b104d6a5a82a5 (Steven Rostedt         2014-04-03 14:49:07 -0700 147) 		return IOMEM_ERR_PTR(-EINVAL);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 148) 	}
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 149) 
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 150) 	if (type == DEVM_IOREMAP && res->flags & IORESOURCE_MEM_NONPOSTED)
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 151) 		type = DEVM_IOREMAP_NP;
7c566bb5e4d5f (Hector Martin          2021-02-11 21:35:46 +0900 152) 
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 153) 	size = resource_size(res);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 154) 
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 155) 	if (res->name)
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 156) 		pretty_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s",
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 157) 					     dev_name(dev), res->name);
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 158) 	else
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 159) 		pretty_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 160) 	if (!pretty_name)
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 161) 		return IOMEM_ERR_PTR(-ENOMEM);
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 162) 
35bd8c07db2ce (Vladimir Oltean        2020-06-01 12:58:26 +0300 163) 	if (!devm_request_mem_region(dev, res->start, size, pretty_name)) {
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 164) 		dev_err(dev, "can't request region for resource %pR\n", res);
b104d6a5a82a5 (Steven Rostedt         2014-04-03 14:49:07 -0700 165) 		return IOMEM_ERR_PTR(-EBUSY);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 166) 	}
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 167) 
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 168) 	dest_ptr = __devm_ioremap(dev, res->start, size, type);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 169) 	if (!dest_ptr) {
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 170) 		dev_err(dev, "ioremap failed for resource %pR\n", res);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 171) 		devm_release_mem_region(dev, res->start, size);
b104d6a5a82a5 (Steven Rostedt         2014-04-03 14:49:07 -0700 172) 		dest_ptr = IOMEM_ERR_PTR(-ENOMEM);
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 173) 	}
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 174) 
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 175) 	return dest_ptr;
72f8c0bfa0de6 (Wolfram Sang           2011-10-25 15:16:47 +0200 176) }
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 177) 
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 178) /**
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 179)  * devm_ioremap_resource() - check, request region, and ioremap resource
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 180)  * @dev: generic device to handle the resource for
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 181)  * @res: resource to be handled
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 182)  *
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 183)  * Checks that a resource is a valid memory region, requests the memory
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 184)  * region and ioremaps it. All operations are managed and will be undone
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 185)  * on driver detach.
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 186)  *
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 187)  * Usage example:
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 188)  *
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 189)  *	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 190)  *	base = devm_ioremap_resource(&pdev->dev, res);
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 191)  *	if (IS_ERR(base))
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 192)  *		return PTR_ERR(base);
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 193)  *
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 194)  * Return: a pointer to the remapped memory or an ERR_PTR() encoded error code
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 195)  * on failure.
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 196)  */
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 197) void __iomem *devm_ioremap_resource(struct device *dev,
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 198) 				    const struct resource *res)
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 199) {
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 200) 	return __devm_ioremap_resource(dev, res, DEVM_IOREMAP);
6e924822752cb (Bartosz Golaszewski    2019-10-22 10:43:12 +0200 201) }
75096579c3ac3 (Thierry Reding         2013-01-21 11:08:54 +0100 202) EXPORT_SYMBOL(devm_ioremap_resource);
75096579c3ac3 (Thierry Reding         2013-01-21 11:08:54 +0100 203) 
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 204) /**
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 205)  * devm_ioremap_resource_wc() - write-combined variant of
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 206)  *				devm_ioremap_resource()
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 207)  * @dev: generic device to handle the resource for
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 208)  * @res: resource to be handled
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 209)  *
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 210)  * Return: a pointer to the remapped memory or an ERR_PTR() encoded error code
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 211)  * on failure.
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 212)  */
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 213) void __iomem *devm_ioremap_resource_wc(struct device *dev,
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 214) 				       const struct resource *res)
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 215) {
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 216) 	return __devm_ioremap_resource(dev, res, DEVM_IOREMAP_WC);
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 217) }
b873af620e588 (Bartosz Golaszewski    2019-10-22 10:43:13 +0200 218) 
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 219) /*
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 220)  * devm_of_iomap - Requests a resource and maps the memory mapped IO
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 221)  *		   for a given device_node managed by a given device
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 222)  *
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 223)  * Checks that a resource is a valid memory region, requests the memory
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 224)  * region and ioremaps it. All operations are managed and will be undone
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 225)  * on driver detach of the device.
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 226)  *
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 227)  * This is to be used when a device requests/maps resources described
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 228)  * by other device tree nodes (children or otherwise).
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 229)  *
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 230)  * @dev:	The device "managing" the resource
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 231)  * @node:       The device-tree node where the resource resides
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 232)  * @index:	index of the MMIO range in the "reg" property
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 233)  * @size:	Returns the size of the resource (pass NULL if not needed)
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 234)  *
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 235)  * Usage example:
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 236)  *
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 237)  *	base = devm_of_iomap(&pdev->dev, node, 0, NULL);
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 238)  *	if (IS_ERR(base))
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 239)  *		return PTR_ERR(base);
7ae731a8441d7 (Dan Carpenter          2020-06-09 13:46:42 +0300 240)  *
7ae731a8441d7 (Dan Carpenter          2020-06-09 13:46:42 +0300 241)  * Please Note: This is not a one-to-one replacement for of_iomap() because the
7ae731a8441d7 (Dan Carpenter          2020-06-09 13:46:42 +0300 242)  * of_iomap() function does not track whether the region is already mapped.  If
7ae731a8441d7 (Dan Carpenter          2020-06-09 13:46:42 +0300 243)  * two drivers try to map the same memory, the of_iomap() function will succeed
28d9fdf04573c (Randy Dunlap           2020-08-22 21:04:43 -0700 244)  * but the devm_of_iomap() function will return -EBUSY.
7ae731a8441d7 (Dan Carpenter          2020-06-09 13:46:42 +0300 245)  *
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 246)  * Return: a pointer to the requested and mapped memory or an ERR_PTR() encoded
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 247)  * error code on failure.
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 248)  */
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 249) void __iomem *devm_of_iomap(struct device *dev, struct device_node *node, int index,
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 250) 			    resource_size_t *size)
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 251) {
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 252) 	struct resource res;
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 253) 
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 254) 	if (of_address_to_resource(node, index, &res))
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 255) 		return IOMEM_ERR_PTR(-EINVAL);
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 256) 	if (size)
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 257) 		*size = resource_size(&res);
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 258) 	return devm_ioremap_resource(dev, &res);
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 259) }
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 260) EXPORT_SYMBOL(devm_of_iomap);
d5e838275c80a (Benjamin Herrenschmidt 2018-06-05 13:21:26 +1000 261) 
ce816fa88cca0 (Uwe Kleine-König       2014-04-07 15:39:19 -0700 262) #ifdef CONFIG_HAS_IOPORT_MAP
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 263) /*
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 264)  * Generic iomap devres
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 265)  */
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 266) static void devm_ioport_map_release(struct device *dev, void *res)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 267) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 268) 	ioport_unmap(*(void __iomem **)res);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 269) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 270) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 271) static int devm_ioport_map_match(struct device *dev, void *res,
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 272) 				 void *match_data)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 273) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 274) 	return *(void **)res == match_data;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 275) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 276) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 277) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 278)  * devm_ioport_map - Managed ioport_map()
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 279)  * @dev: Generic device to map ioport for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 280)  * @port: Port to map
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 281)  * @nr: Number of ports to map
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 282)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 283)  * Managed ioport_map().  Map is automatically unmapped on driver
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 284)  * detach.
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 285)  *
0c7a6b91d2276 (Stephen Boyd           2020-09-09 23:04:40 -0700 286)  * Return: a pointer to the remapped memory or NULL on failure.
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 287)  */
5cbb00cc4aae5 (Fabian Frederick       2014-05-23 22:30:50 +0200 288) void __iomem *devm_ioport_map(struct device *dev, unsigned long port,
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 289) 			       unsigned int nr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 290) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 291) 	void __iomem **ptr, *addr;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 292) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 293) 	ptr = devres_alloc(devm_ioport_map_release, sizeof(*ptr), GFP_KERNEL);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 294) 	if (!ptr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 295) 		return NULL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 296) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 297) 	addr = ioport_map(port, nr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 298) 	if (addr) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 299) 		*ptr = addr;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 300) 		devres_add(dev, ptr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 301) 	} else
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 302) 		devres_free(ptr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 303) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 304) 	return addr;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 305) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 306) EXPORT_SYMBOL(devm_ioport_map);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 307) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 308) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 309)  * devm_ioport_unmap - Managed ioport_unmap()
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 310)  * @dev: Generic device to unmap for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 311)  * @addr: Address to unmap
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 312)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 313)  * Managed ioport_unmap().  @addr must have been mapped using
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 314)  * devm_ioport_map().
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 315)  */
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 316) void devm_ioport_unmap(struct device *dev, void __iomem *addr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 317) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 318) 	ioport_unmap(addr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 319) 	WARN_ON(devres_destroy(dev, devm_ioport_map_release,
b104d6a5a82a5 (Steven Rostedt         2014-04-03 14:49:07 -0700 320) 			       devm_ioport_map_match, (__force void *)addr));
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 321) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 322) EXPORT_SYMBOL(devm_ioport_unmap);
ce816fa88cca0 (Uwe Kleine-König       2014-04-07 15:39:19 -0700 323) #endif /* CONFIG_HAS_IOPORT_MAP */
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 324) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 325) #ifdef CONFIG_PCI
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 326) /*
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 327)  * PCI iomap devres
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 328)  */
c9c13ba428ef9 (Denis Efremov          2019-09-28 02:43:08 +0300 329) #define PCIM_IOMAP_MAX	PCI_STD_NUM_BARS
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 330) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 331) struct pcim_iomap_devres {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 332) 	void __iomem *table[PCIM_IOMAP_MAX];
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 333) };
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 334) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 335) static void pcim_iomap_release(struct device *gendev, void *res)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 336) {
20af74ef140f0 (Geliang Tang           2015-12-27 18:46:05 +0800 337) 	struct pci_dev *dev = to_pci_dev(gendev);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 338) 	struct pcim_iomap_devres *this = res;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 339) 	int i;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 340) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 341) 	for (i = 0; i < PCIM_IOMAP_MAX; i++)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 342) 		if (this->table[i])
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 343) 			pci_iounmap(dev, this->table[i]);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 344) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 345) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 346) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 347)  * pcim_iomap_table - access iomap allocation table
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 348)  * @pdev: PCI device to access iomap table for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 349)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 350)  * Access iomap allocation table for @dev.  If iomap table doesn't
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 351)  * exist and @pdev is managed, it will be allocated.  All iomaps
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 352)  * recorded in the iomap table are automatically unmapped on driver
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 353)  * detach.
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 354)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 355)  * This function might sleep when the table is first allocated but can
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 356)  * be safely called without context and guaranteed to succed once
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 357)  * allocated.
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 358)  */
5cbb00cc4aae5 (Fabian Frederick       2014-05-23 22:30:50 +0200 359) void __iomem * const *pcim_iomap_table(struct pci_dev *pdev)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 360) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 361) 	struct pcim_iomap_devres *dr, *new_dr;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 362) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 363) 	dr = devres_find(&pdev->dev, pcim_iomap_release, NULL, NULL);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 364) 	if (dr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 365) 		return dr->table;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 366) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 367) 	new_dr = devres_alloc(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 368) 	if (!new_dr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 369) 		return NULL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 370) 	dr = devres_get(&pdev->dev, new_dr, NULL, NULL);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 371) 	return dr->table;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 372) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 373) EXPORT_SYMBOL(pcim_iomap_table);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 374) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 375) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 376)  * pcim_iomap - Managed pcim_iomap()
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 377)  * @pdev: PCI device to iomap for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 378)  * @bar: BAR to iomap
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 379)  * @maxlen: Maximum length of iomap
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 380)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 381)  * Managed pci_iomap().  Map is automatically unmapped on driver
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 382)  * detach.
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 383)  */
5cbb00cc4aae5 (Fabian Frederick       2014-05-23 22:30:50 +0200 384) void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 385) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 386) 	void __iomem **tbl;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 387) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 388) 	BUG_ON(bar >= PCIM_IOMAP_MAX);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 389) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 390) 	tbl = (void __iomem **)pcim_iomap_table(pdev);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 391) 	if (!tbl || tbl[bar])	/* duplicate mappings not allowed */
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 392) 		return NULL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 393) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 394) 	tbl[bar] = pci_iomap(pdev, bar, maxlen);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 395) 	return tbl[bar];
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 396) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 397) EXPORT_SYMBOL(pcim_iomap);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 398) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 399) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 400)  * pcim_iounmap - Managed pci_iounmap()
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 401)  * @pdev: PCI device to iounmap for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 402)  * @addr: Address to unmap
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 403)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 404)  * Managed pci_iounmap().  @addr must have been mapped using pcim_iomap().
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 405)  */
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 406) void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 407) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 408) 	void __iomem **tbl;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 409) 	int i;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 410) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 411) 	pci_iounmap(pdev, addr);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 412) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 413) 	tbl = (void __iomem **)pcim_iomap_table(pdev);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 414) 	BUG_ON(!tbl);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 415) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 416) 	for (i = 0; i < PCIM_IOMAP_MAX; i++)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 417) 		if (tbl[i] == addr) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 418) 			tbl[i] = NULL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 419) 			return;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 420) 		}
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 421) 	WARN_ON(1);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 422) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 423) EXPORT_SYMBOL(pcim_iounmap);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 424) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 425) /**
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 426)  * pcim_iomap_regions - Request and iomap PCI BARs
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 427)  * @pdev: PCI device to map IO resources for
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 428)  * @mask: Mask of BARs to request and iomap
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 429)  * @name: Name used when requesting regions
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 430)  *
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 431)  * Request and iomap regions specified by @mask.
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 432)  */
fb7ebfe4108e2 (Yinghai Lu             2012-01-04 15:50:02 -0800 433) int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 434) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 435) 	void __iomem * const *iomap;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 436) 	int i, rc;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 437) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 438) 	iomap = pcim_iomap_table(pdev);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 439) 	if (!iomap)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 440) 		return -ENOMEM;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 441) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 442) 	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 443) 		unsigned long len;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 444) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 445) 		if (!(mask & (1 << i)))
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 446) 			continue;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 447) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 448) 		rc = -EINVAL;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 449) 		len = pci_resource_len(pdev, i);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 450) 		if (!len)
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 451) 			goto err_inval;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 452) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 453) 		rc = pci_request_region(pdev, i, name);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 454) 		if (rc)
fb4d64e78ceab (Frederik Deweerdt      2007-02-16 01:27:15 -0800 455) 			goto err_inval;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 456) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 457) 		rc = -ENOMEM;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 458) 		if (!pcim_iomap(pdev, i, 0))
fb4d64e78ceab (Frederik Deweerdt      2007-02-16 01:27:15 -0800 459) 			goto err_region;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 460) 	}
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 461) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 462) 	return 0;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 463) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 464)  err_region:
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 465) 	pci_release_region(pdev, i);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 466)  err_inval:
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 467) 	while (--i >= 0) {
fb4d64e78ceab (Frederik Deweerdt      2007-02-16 01:27:15 -0800 468) 		if (!(mask & (1 << i)))
fb4d64e78ceab (Frederik Deweerdt      2007-02-16 01:27:15 -0800 469) 			continue;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 470) 		pcim_iounmap(pdev, iomap[i]);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 471) 		pci_release_region(pdev, i);
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 472) 	}
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 473) 
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 474) 	return rc;
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 475) }
5ea8176994003 (Al Viro                2007-02-11 15:41:31 +0000 476) EXPORT_SYMBOL(pcim_iomap_regions);
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 477) 
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 478) /**
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 479)  * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 480)  * @pdev: PCI device to map IO resources for
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 481)  * @mask: Mask of BARs to iomap
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 482)  * @name: Name used when requesting regions
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 483)  *
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 484)  * Request all PCI BARs and iomap regions specified by @mask.
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 485)  */
fb7ebfe4108e2 (Yinghai Lu             2012-01-04 15:50:02 -0800 486) int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 487) 				   const char *name)
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 488) {
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 489) 	int request_mask = ((1 << 6) - 1) & ~mask;
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 490) 	int rc;
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 491) 
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 492) 	rc = pci_request_selected_regions(pdev, request_mask, name);
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 493) 	if (rc)
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 494) 		return rc;
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 495) 
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 496) 	rc = pcim_iomap_regions(pdev, mask, name);
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 497) 	if (rc)
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 498) 		pci_release_selected_regions(pdev, request_mask);
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 499) 	return rc;
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 500) }
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 501) EXPORT_SYMBOL(pcim_iomap_regions_request_all);
916fbfb7ae5f8 (Tejun Heo              2008-03-12 15:26:34 +0900 502) 
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 503) /**
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 504)  * pcim_iounmap_regions - Unmap and release PCI BARs
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 505)  * @pdev: PCI device to map IO resources for
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 506)  * @mask: Mask of BARs to unmap and release
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 507)  *
4d45ada36b36a (Kulikov Vasiliy        2010-07-10 14:07:41 +0400 508)  * Unmap and release regions specified by @mask.
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 509)  */
fb7ebfe4108e2 (Yinghai Lu             2012-01-04 15:50:02 -0800 510) void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 511) {
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 512) 	void __iomem * const *iomap;
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 513) 	int i;
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 514) 
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 515) 	iomap = pcim_iomap_table(pdev);
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 516) 	if (!iomap)
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 517) 		return;
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 518) 
1f35d04a02a65 (Dan Carpenter          2015-09-21 19:21:51 +0300 519) 	for (i = 0; i < PCIM_IOMAP_MAX; i++) {
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 520) 		if (!(mask & (1 << i)))
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 521) 			continue;
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 522) 
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 523) 		pcim_iounmap(pdev, iomap[i]);
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 524) 		pci_release_region(pdev, i);
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 525) 	}
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 526) }
ec04b075843d1 (Tejun Heo              2007-03-09 19:45:58 +0900 527) EXPORT_SYMBOL(pcim_iounmap_regions);
571806a9f70fc (Wolfram Sang           2011-10-25 15:03:42 +0200 528) #endif /* CONFIG_PCI */