Commit 43539c38cd8edb915d1f0e1f55dcb70638b4cc8e
Committed by
Linus Torvalds
1 parent
ec68307cc5
Exists in
master
and in
39 other branches
[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
drivers/pci/htirq.c
... | ... | @@ -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 */ |