diff options
-rw-r--r-- | drivers/pnp/interface.c | 2 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 9 | ||||
-rw-r--r-- | drivers/pnp/quirks.c | 71 | ||||
-rw-r--r-- | include/linux/ioport.h | 1 |
4 files changed, 39 insertions, 44 deletions
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index b09f67de13d0..7a9fb5544b80 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -90,6 +90,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, | |||
90 | pnp_printf(buffer, " High-Level"); | 90 | pnp_printf(buffer, " High-Level"); |
91 | if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) | 91 | if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) |
92 | pnp_printf(buffer, " Low-Level"); | 92 | pnp_printf(buffer, " Low-Level"); |
93 | if (irq->flags & IORESOURCE_IRQ_OPTIONAL) | ||
94 | pnp_printf(buffer, " (optional)"); | ||
93 | pnp_printf(buffer, "\n"); | 95 | pnp_printf(buffer, "\n"); |
94 | } | 96 | } |
95 | 97 | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 7ea9e1e28003..a20accb5ef8f 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -153,6 +153,15 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
153 | goto __add; | 153 | goto __add; |
154 | } | 154 | } |
155 | } | 155 | } |
156 | |||
157 | if (rule->flags & IORESOURCE_IRQ_OPTIONAL) { | ||
158 | res->start = -1; | ||
159 | res->end = -1; | ||
160 | res->flags |= IORESOURCE_DISABLED; | ||
161 | dev_dbg(&dev->dev, " irq %d disabled (optional)\n", idx); | ||
162 | goto __add; | ||
163 | } | ||
164 | |||
156 | dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); | 165 | dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); |
157 | return -EBUSY; | 166 | return -EBUSY; |
158 | 167 | ||
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 48e60171b3ba..e8515ce0d296 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -121,34 +121,46 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) | |||
121 | struct pnp_option *res; | 121 | struct pnp_option *res; |
122 | 122 | ||
123 | /* | 123 | /* |
124 | * Build a functional IRQ-less variant of each MPU option. | 124 | * Build a functional IRQ-optional variant of each MPU option. |
125 | */ | 125 | */ |
126 | 126 | ||
127 | for (res = dev->dependent; res; res = res->next) { | 127 | for (res = dev->dependent; res; res = res->next) { |
128 | struct pnp_option *curr; | 128 | struct pnp_option *curr; |
129 | struct pnp_port *port; | 129 | struct pnp_port *port; |
130 | struct pnp_port *copy; | 130 | struct pnp_port *copy_port; |
131 | struct pnp_irq *irq; | ||
132 | struct pnp_irq *copy_irq; | ||
131 | 133 | ||
132 | port = res->port; | 134 | port = res->port; |
133 | if (!port || !res->irq) | 135 | irq = res->irq; |
136 | if (!port || !irq) | ||
134 | continue; | 137 | continue; |
135 | 138 | ||
136 | copy = pnp_alloc(sizeof *copy); | 139 | copy_port = pnp_alloc(sizeof *copy_port); |
137 | if (!copy) | 140 | if (!copy_port) |
141 | break; | ||
142 | |||
143 | copy_irq = pnp_alloc(sizeof *copy_irq); | ||
144 | if (!copy_irq) { | ||
145 | kfree(copy_port); | ||
138 | break; | 146 | break; |
147 | } | ||
148 | |||
149 | *copy_port = *port; | ||
150 | copy_port->next = NULL; | ||
139 | 151 | ||
140 | copy->min = port->min; | 152 | *copy_irq = *irq; |
141 | copy->max = port->max; | 153 | copy_irq->flags |= IORESOURCE_IRQ_OPTIONAL; |
142 | copy->align = port->align; | 154 | copy_irq->next = NULL; |
143 | copy->size = port->size; | ||
144 | copy->flags = port->flags; | ||
145 | 155 | ||
146 | curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); | 156 | curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); |
147 | if (!curr) { | 157 | if (!curr) { |
148 | kfree(copy); | 158 | kfree(copy_port); |
159 | kfree(copy_irq); | ||
149 | break; | 160 | break; |
150 | } | 161 | } |
151 | curr->port = copy; | 162 | curr->port = copy_port; |
163 | curr->irq = copy_irq; | ||
152 | 164 | ||
153 | if (prev) | 165 | if (prev) |
154 | prev->next = curr; | 166 | prev->next = curr; |
@@ -157,7 +169,7 @@ static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) | |||
157 | prev = curr; | 169 | prev = curr; |
158 | } | 170 | } |
159 | if (head) | 171 | if (head) |
160 | dev_info(&dev->dev, "adding IRQ-less MPU options\n"); | 172 | dev_info(&dev->dev, "adding IRQ-optional MPU options\n"); |
161 | 173 | ||
162 | return head; | 174 | return head; |
163 | } | 175 | } |
@@ -167,10 +179,6 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) | |||
167 | struct pnp_option *res; | 179 | struct pnp_option *res; |
168 | struct pnp_irq *irq; | 180 | struct pnp_irq *irq; |
169 | 181 | ||
170 | /* | ||
171 | * Distribute the independent IRQ over the dependent options | ||
172 | */ | ||
173 | |||
174 | res = dev->independent; | 182 | res = dev->independent; |
175 | if (!res) | 183 | if (!res) |
176 | return; | 184 | return; |
@@ -179,33 +187,8 @@ static void quirk_ad1815_mpu_resources(struct pnp_dev *dev) | |||
179 | if (!irq || irq->next) | 187 | if (!irq || irq->next) |
180 | return; | 188 | return; |
181 | 189 | ||
182 | res = dev->dependent; | 190 | irq->flags |= IORESOURCE_IRQ_OPTIONAL; |
183 | if (!res) | 191 | dev_info(&dev->dev, "made independent IRQ optional\n"); |
184 | return; | ||
185 | |||
186 | while (1) { | ||
187 | struct pnp_irq *copy; | ||
188 | |||
189 | copy = pnp_alloc(sizeof *copy); | ||
190 | if (!copy) | ||
191 | break; | ||
192 | |||
193 | bitmap_copy(copy->map.bits, irq->map.bits, PNP_IRQ_NR); | ||
194 | copy->flags = irq->flags; | ||
195 | |||
196 | copy->next = res->irq; /* Yes, this is NULL */ | ||
197 | res->irq = copy; | ||
198 | |||
199 | if (!res->next) | ||
200 | break; | ||
201 | res = res->next; | ||
202 | } | ||
203 | kfree(irq); | ||
204 | |||
205 | res->next = quirk_isapnp_mpu_options(dev); | ||
206 | |||
207 | res = dev->independent; | ||
208 | res->irq = NULL; | ||
209 | } | 192 | } |
210 | 193 | ||
211 | static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) | 194 | static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 39db059ffb8b..2cd07cc29687 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -59,6 +59,7 @@ struct resource_list { | |||
59 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) | 59 | #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) |
60 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) | 60 | #define IORESOURCE_IRQ_LOWLEVEL (1<<3) |
61 | #define IORESOURCE_IRQ_SHAREABLE (1<<4) | 61 | #define IORESOURCE_IRQ_SHAREABLE (1<<4) |
62 | #define IORESOURCE_IRQ_OPTIONAL (1<<5) | ||
62 | 63 | ||
63 | /* PnP DMA specific bits (IORESOURCE_BITS) */ | 64 | /* PnP DMA specific bits (IORESOURCE_BITS) */ |
64 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) | 65 | #define IORESOURCE_DMA_TYPE_MASK (3<<0) |