Commit 43539c38cd8edb915d1f0e1f55dcb70638b4cc8e

Authored by Eric W. Biederman
Committed by Linus Torvalds
1 parent ec68307cc5

[PATCH] htirq: allow buggy drivers of buggy hardware to write the registers

This patch adds a variant of ht_create_irq __ht_create_irq that takes an
aditional parameter update that is a function that is called whenever we want
to write to a drivers htirq configuration registers.

This is needed to support the ipath_iba6110 because it's registers in the
proper location are not actually conected to the hardware that controlls
interrupt delivery.

[bos@serpentine.com: fixes]
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Andi Kleen <ak@suse.de>
Cc: <olson@pathscale.com>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 2 changed files with 29 additions and 5 deletions Side-by-side Diff

... ... @@ -25,6 +25,8 @@
25 25  
26 26 struct ht_irq_cfg {
27 27 struct pci_dev *dev;
  28 + /* Update callback used to cope with buggy hardware */
  29 + ht_irq_update_t *update;
28 30 unsigned pos;
29 31 unsigned idx;
30 32 struct ht_irq_msg msg;
... ... @@ -44,6 +46,8 @@
44 46 pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);
45 47 pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi);
46 48 }
  49 + if (cfg->update)
  50 + cfg->update(cfg->dev, irq, msg);
47 51 spin_unlock_irqrestore(&ht_irq_lock, flags);
48 52 cfg->msg = *msg;
49 53 }
50 54  
51 55  
52 56  
... ... @@ -79,16 +83,14 @@
79 83 }
80 84  
81 85 /**
82   - * ht_create_irq - create an irq and attach it to a device.
  86 + * __ht_create_irq - create an irq and attach it to a device.
83 87 * @dev: The hypertransport device to find the irq capability on.
84 88 * @idx: Which of the possible irqs to attach to.
  89 + * @update: Function to be called when changing the htirq message
85 90 *
86   - * ht_create_irq is needs to be called for all hypertransport devices
87   - * that generate irqs.
88   - *
89 91 * The irq number of the new irq or a negative error value is returned.
90 92 */
91   -int ht_create_irq(struct pci_dev *dev, int idx)
  93 +int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
92 94 {
93 95 struct ht_irq_cfg *cfg;
94 96 unsigned long flags;
... ... @@ -123,6 +125,7 @@
123 125 return -ENOMEM;
124 126  
125 127 cfg->dev = dev;
  128 + cfg->update = update;
126 129 cfg->pos = pos;
127 130 cfg->idx = 0x10 + (idx * 2);
128 131 /* Initialize msg to a value that will never match the first write. */
... ... @@ -145,6 +148,21 @@
145 148 }
146 149  
147 150 /**
  151 + * ht_create_irq - create an irq and attach it to a device.
  152 + * @dev: The hypertransport device to find the irq capability on.
  153 + * @idx: Which of the possible irqs to attach to.
  154 + *
  155 + * ht_create_irq needs to be called for all hypertransport devices
  156 + * that generate irqs.
  157 + *
  158 + * The irq number of the new irq or a negative error value is returned.
  159 + */
  160 +int ht_create_irq(struct pci_dev *dev, int idx)
  161 +{
  162 + return __ht_create_irq(dev, idx, NULL);
  163 +}
  164 +
  165 +/**
148 166 * ht_destroy_irq - destroy an irq created with ht_create_irq
149 167 *
150 168 * This reverses ht_create_irq removing the specified irq from
... ... @@ -162,6 +180,7 @@
162 180 kfree(cfg);
163 181 }
164 182  
  183 +EXPORT_SYMBOL(__ht_create_irq);
165 184 EXPORT_SYMBOL(ht_create_irq);
166 185 EXPORT_SYMBOL(ht_destroy_irq);
include/linux/htirq.h
... ... @@ -15,5 +15,10 @@
15 15 /* The arch hook for getting things started */
16 16 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev);
17 17  
  18 +/* For drivers of buggy hardware */
  19 +typedef void (ht_irq_update_t)(struct pci_dev *dev, int irq,
  20 + struct ht_irq_msg *msg);
  21 +int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update);
  22 +
18 23 #endif /* LINUX_HTIRQ_H */