diff options
Diffstat (limited to 'drivers/parisc/gsc.c')
| -rw-r--r-- | drivers/parisc/gsc.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index e76db9e4d50..d3363291769 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
| @@ -186,29 +186,34 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp) | |||
| 186 | *irqp = irq; | 186 | *irqp = irq; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | static struct device *next_device(struct klist_iter *i) | 189 | struct gsc_fixup_struct { |
| 190 | void (*choose_irq)(struct parisc_device *, void *); | ||
| 191 | void *ctrl; | ||
| 192 | }; | ||
| 193 | |||
| 194 | static int gsc_fixup_irqs_callback(struct device *dev, void *data) | ||
| 190 | { | 195 | { |
| 191 | struct klist_node * n = klist_next(i); | 196 | struct parisc_device *padev = to_parisc_device(dev); |
| 192 | return n ? container_of(n, struct device, knode_parent) : NULL; | 197 | struct gsc_fixup_struct *gf = data; |
| 198 | |||
| 199 | /* work-around for 715/64 and others which have parent | ||
| 200 | at path [5] and children at path [5/0/x] */ | ||
| 201 | if (padev->id.hw_type == HPHW_FAULTY) | ||
| 202 | gsc_fixup_irqs(padev, gf->ctrl, gf->choose_irq); | ||
| 203 | gf->choose_irq(padev, gf->ctrl); | ||
| 204 | |||
| 205 | return 0; | ||
| 193 | } | 206 | } |
| 194 | 207 | ||
| 195 | void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, | 208 | void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, |
| 196 | void (*choose_irq)(struct parisc_device *, void *)) | 209 | void (*choose_irq)(struct parisc_device *, void *)) |
| 197 | { | 210 | { |
| 198 | struct device *dev; | 211 | struct gsc_fixup_struct data = { |
| 199 | struct klist_iter i; | 212 | .choose_irq = choose_irq, |
| 200 | 213 | .ctrl = ctrl, | |
| 201 | klist_iter_init(&parent->dev.klist_children, &i); | 214 | }; |
| 202 | while ((dev = next_device(&i))) { | 215 | |
| 203 | struct parisc_device *padev = to_parisc_device(dev); | 216 | device_for_each_child(&parent->dev, &data, gsc_fixup_irqs_callback); |
| 204 | |||
| 205 | /* work-around for 715/64 and others which have parent | ||
| 206 | at path [5] and children at path [5/0/x] */ | ||
| 207 | if (padev->id.hw_type == HPHW_FAULTY) | ||
| 208 | return gsc_fixup_irqs(padev, ctrl, choose_irq); | ||
| 209 | choose_irq(padev, ctrl); | ||
| 210 | } | ||
| 211 | klist_iter_exit(&i); | ||
| 212 | } | 217 | } |
| 213 | 218 | ||
| 214 | int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) | 219 | int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) |
