aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWitold Szczeponik <Witold.Szczeponik@gmx.net>2012-12-14 19:02:08 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-03 07:10:53 -0500
commit13cde3b2a617e2927c8ee6da7a8f8d103994430f (patch)
tree2015dad7b156ac82ddac079dea36943568ad1de1
parentc9377667e6cdf4ac910b0932868275eb0dbfcfeb (diff)
PNP: Handle IORESOURCE_BITS in resource allocation
The patch copies the flags masked by IORESOURCE_BITS from a resource's template. This is necessary because the resource settings require proper IORESOURCE_BITS which are not known during the definition of these resources using the "/sys/bus/pnp/*/*/resources" interface. (In fact, they should not be set by the user as the resource templates define the proper settings.) If the patch is not applied, the resource flags are not initialized properly and obscure messages in the kernel log have been seen ("invalid flags"). Signed-off-by: Witold Szczeponik <Witold.Szczeponik@gmx.net> Reviewed-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/pnp/manager.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index ed9ce507149a..95cebf0185de 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -18,11 +18,27 @@
18 18
19DEFINE_MUTEX(pnp_res_mutex); 19DEFINE_MUTEX(pnp_res_mutex);
20 20
21static struct resource *pnp_find_resource(struct pnp_dev *dev,
22 unsigned char rule,
23 unsigned long type,
24 unsigned int bar)
25{
26 struct resource *res = pnp_get_resource(dev, type, bar);
27
28 /* when the resource already exists, set its resource bits from rule */
29 if (res) {
30 res->flags &= ~IORESOURCE_BITS;
31 res->flags |= rule & IORESOURCE_BITS;
32 }
33
34 return res;
35}
36
21static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 37static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
22{ 38{
23 struct resource *res, local_res; 39 struct resource *res, local_res;
24 40
25 res = pnp_get_resource(dev, IORESOURCE_IO, idx); 41 res = pnp_find_resource(dev, rule->flags, IORESOURCE_IO, idx);
26 if (res) { 42 if (res) {
27 pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx " 43 pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
28 "flags %#lx\n", idx, (unsigned long long) res->start, 44 "flags %#lx\n", idx, (unsigned long long) res->start,
@@ -65,7 +81,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
65{ 81{
66 struct resource *res, local_res; 82 struct resource *res, local_res;
67 83
68 res = pnp_get_resource(dev, IORESOURCE_MEM, idx); 84 res = pnp_find_resource(dev, rule->flags, IORESOURCE_MEM, idx);
69 if (res) { 85 if (res) {
70 pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " 86 pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
71 "flags %#lx\n", idx, (unsigned long long) res->start, 87 "flags %#lx\n", idx, (unsigned long long) res->start,
@@ -78,6 +94,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
78 res->start = 0; 94 res->start = 0;
79 res->end = 0; 95 res->end = 0;
80 96
97 /* ??? rule->flags restricted to 8 bits, all tests bogus ??? */
81 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) 98 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
82 res->flags |= IORESOURCE_READONLY; 99 res->flags |= IORESOURCE_READONLY;
83 if (rule->flags & IORESOURCE_MEM_CACHEABLE) 100 if (rule->flags & IORESOURCE_MEM_CACHEABLE)
@@ -123,7 +140,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
123 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 140 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
124 }; 141 };
125 142
126 res = pnp_get_resource(dev, IORESOURCE_IRQ, idx); 143 res = pnp_find_resource(dev, rule->flags, IORESOURCE_IRQ, idx);
127 if (res) { 144 if (res) {
128 pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", 145 pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
129 idx, (int) res->start, res->flags); 146 idx, (int) res->start, res->flags);
@@ -182,7 +199,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
182 1, 3, 5, 6, 7, 0, 2, 4 199 1, 3, 5, 6, 7, 0, 2, 4
183 }; 200 };
184 201
185 res = pnp_get_resource(dev, IORESOURCE_DMA, idx); 202 res = pnp_find_resource(dev, rule->flags, IORESOURCE_DMA, idx);
186 if (res) { 203 if (res) {
187 pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", 204 pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
188 idx, (int) res->start, res->flags); 205 idx, (int) res->start, res->flags);