diff options
| author | Eric W. Biederman <ebiederm@xmission.com> | 2006-11-08 17:44:57 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-11-08 18:29:25 -0800 | 
| commit | 43539c38cd8edb915d1f0e1f55dcb70638b4cc8e (patch) | |
| tree | 623568ee8f87684be487145fbc7a5da16320afde | |
| parent | ec68307cc5a8dc499e48693843bb42f6b6028458 (diff) | |
| download | olio-linux-3.10-43539c38cd8edb915d1f0e1f55dcb70638b4cc8e.tar.xz olio-linux-3.10-43539c38cd8edb915d1f0e1f55dcb70638b4cc8e.zip  | |
[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>
| -rw-r--r-- | drivers/pci/htirq.c | 29 | ||||
| -rw-r--r-- | include/linux/htirq.h | 5 | 
2 files changed, 29 insertions, 5 deletions
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index e346fe31f97..0a8d1cce9fa 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c @@ -25,6 +25,8 @@ static DEFINE_SPINLOCK(ht_irq_lock);  struct ht_irq_cfg {  	struct pci_dev *dev; +	 /* Update callback used to cope with buggy hardware */ +	ht_irq_update_t *update;  	unsigned pos;  	unsigned idx;  	struct ht_irq_msg msg; @@ -44,6 +46,8 @@ void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)  		pci_write_config_byte(cfg->dev, cfg->pos + 2, cfg->idx + 1);  		pci_write_config_dword(cfg->dev, cfg->pos + 4, msg->address_hi);  	} +	if (cfg->update) +		cfg->update(cfg->dev, irq, msg);  	spin_unlock_irqrestore(&ht_irq_lock, flags);  	cfg->msg = *msg;  } @@ -79,16 +83,14 @@ void unmask_ht_irq(unsigned int irq)  }  /** - * ht_create_irq - create an irq and attach it to a device. + * __ht_create_irq - create an irq and attach it to a device.   * @dev: The hypertransport device to find the irq capability on.   * @idx: Which of the possible irqs to attach to. - * - * ht_create_irq is needs to be called for all hypertransport devices - * that generate irqs. + * @update: Function to be called when changing the htirq message   *   * The irq number of the new irq or a negative error value is returned.   */ -int ht_create_irq(struct pci_dev *dev, int idx) +int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)  {  	struct ht_irq_cfg *cfg;  	unsigned long flags; @@ -123,6 +125,7 @@ int ht_create_irq(struct pci_dev *dev, int idx)  		return -ENOMEM;  	cfg->dev = dev; +	cfg->update = update;  	cfg->pos = pos;  	cfg->idx = 0x10 + (idx * 2);  	/* Initialize msg to a value that will never match the first write. */ @@ -145,6 +148,21 @@ int ht_create_irq(struct pci_dev *dev, int idx)  }  /** + * ht_create_irq - create an irq and attach it to a device. + * @dev: The hypertransport device to find the irq capability on. + * @idx: Which of the possible irqs to attach to. + * + * ht_create_irq needs to be called for all hypertransport devices + * that generate irqs. + * + * The irq number of the new irq or a negative error value is returned. + */ +int ht_create_irq(struct pci_dev *dev, int idx) +{ +	return __ht_create_irq(dev, idx, NULL); +} + +/**   * ht_destroy_irq - destroy an irq created with ht_create_irq   *   * This reverses ht_create_irq removing the specified irq from @@ -162,5 +180,6 @@ void ht_destroy_irq(unsigned int irq)  	kfree(cfg);  } +EXPORT_SYMBOL(__ht_create_irq);  EXPORT_SYMBOL(ht_create_irq);  EXPORT_SYMBOL(ht_destroy_irq); diff --git a/include/linux/htirq.h b/include/linux/htirq.h index 108f0d91e11..c96ea46737d 100644 --- a/include/linux/htirq.h +++ b/include/linux/htirq.h @@ -15,4 +15,9 @@ void unmask_ht_irq(unsigned int irq);  /* The arch hook for getting things started */  int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev); +/* For drivers of buggy hardware */ +typedef void (ht_irq_update_t)(struct pci_dev *dev, int irq, +			       struct ht_irq_msg *msg); +int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update); +  #endif /* LINUX_HTIRQ_H */  |