aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parisc/gsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parisc/gsc.c')
-rw-r--r--drivers/parisc/gsc.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index e76db9e4d504..d33632917696 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
189static struct device *next_device(struct klist_iter *i) 189struct gsc_fixup_struct {
190 void (*choose_irq)(struct parisc_device *, void *);
191 void *ctrl;
192};
193
194static 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
195void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, 208void 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
214int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) 219int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)