diff options
author | Jens Taprogge <jens.taprogge@taprogge.org> | 2012-09-12 08:55:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-12 12:54:15 -0400 |
commit | 0118681b2bc2f182b7cd4c6569632cf2729cc73e (patch) | |
tree | 996506d8f187920df196427c41591c79993eeec1 | |
parent | 0d660025564343e7c20c096d386f8ef8bacebdcd (diff) |
Staging: ipack/bridges/tpci200: add helpers for writing control regs.
Convert tpci200_set_clockrate and tpci200_interrupt.
Signed-off-by: Jens Taprogge <jens.taprogge@taprogge.org>
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/ipack/bridges/tpci200.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 9d886b7fdfc6..25605196dbac 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c | |||
@@ -53,6 +53,32 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) | |||
53 | return tpci200; | 53 | return tpci200; |
54 | } | 54 | } |
55 | 55 | ||
56 | static void __tpci200_clear_mask(__le16 __iomem *addr, u16 mask) | ||
57 | { | ||
58 | iowrite16(ioread16(addr) & (~mask), addr); | ||
59 | } | ||
60 | |||
61 | static void tpci200_clear_mask(struct tpci200_board *tpci200, | ||
62 | __le16 __iomem *addr, u16 mask) | ||
63 | { | ||
64 | mutex_lock(&tpci200->mutex); | ||
65 | __tpci200_clear_mask(addr, mask); | ||
66 | mutex_unlock(&tpci200->mutex); | ||
67 | } | ||
68 | |||
69 | static void __tpci200_set_mask(__le16 __iomem *addr, u16 mask) | ||
70 | { | ||
71 | iowrite16(ioread16(addr) | mask, addr); | ||
72 | } | ||
73 | |||
74 | static void tpci200_set_mask(struct tpci200_board *tpci200, | ||
75 | __le16 __iomem *addr, u16 mask) | ||
76 | { | ||
77 | mutex_lock(&tpci200->mutex); | ||
78 | __tpci200_set_mask(addr, mask); | ||
79 | mutex_unlock(&tpci200->mutex); | ||
80 | } | ||
81 | |||
56 | static void tpci200_unregister(struct tpci200_board *tpci200) | 82 | static void tpci200_unregister(struct tpci200_board *tpci200) |
57 | { | 83 | { |
58 | int i; | 84 | int i; |
@@ -86,7 +112,7 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) | |||
86 | { | 112 | { |
87 | struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; | 113 | struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; |
88 | int i; | 114 | int i; |
89 | unsigned short status_reg, reg_value; | 115 | unsigned short status_reg; |
90 | unsigned short unhandled_ints = 0; | 116 | unsigned short unhandled_ints = 0; |
91 | irqreturn_t ret = IRQ_NONE; | 117 | irqreturn_t ret = IRQ_NONE; |
92 | struct slot_irq *slot_irq; | 118 | struct slot_irq *slot_irq; |
@@ -124,12 +150,9 @@ static irqreturn_t tpci200_interrupt(int irq, void *dev_id) | |||
124 | dev_info(&slot_irq->holder->dev, | 150 | dev_info(&slot_irq->holder->dev, |
125 | "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", | 151 | "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", |
126 | tpci200->number, i); | 152 | tpci200->number, i); |
127 | reg_value = readw( | 153 | __tpci200_clear_mask( |
128 | &tpci200->info->interface_regs->control[i]); | 154 | &tpci200->info->interface_regs->control[i], |
129 | reg_value &= | 155 | TPCI200_INT0_EN | TPCI200_INT1_EN); |
130 | ~(TPCI200_INT0_EN | TPCI200_INT1_EN); | ||
131 | writew(reg_value, | ||
132 | &tpci200->info->interface_regs->control[i]); | ||
133 | } | 156 | } |
134 | } | 157 | } |
135 | } | 158 | } |
@@ -518,30 +541,22 @@ static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) | |||
518 | { | 541 | { |
519 | struct tpci200_board *tpci200 = check_slot(dev); | 542 | struct tpci200_board *tpci200 = check_slot(dev); |
520 | u16 __iomem *addr; | 543 | u16 __iomem *addr; |
521 | u16 reg; | ||
522 | 544 | ||
523 | if (!tpci200) | 545 | if (!tpci200) |
524 | return -ENODEV; | 546 | return -ENODEV; |
525 | 547 | ||
526 | addr = &tpci200->info->interface_regs->control[dev->slot]; | 548 | addr = &tpci200->info->interface_regs->control[dev->slot]; |
527 | 549 | ||
528 | /* Ensure the control register is not changed by another task after we | ||
529 | * have read it. */ | ||
530 | mutex_lock(&tpci200->mutex); | ||
531 | reg = ioread16(addr); | ||
532 | switch (mherz) { | 550 | switch (mherz) { |
533 | case 8: | 551 | case 8: |
534 | reg &= ~(TPCI200_CLK32); | 552 | tpci200_clear_mask(tpci200, addr, TPCI200_CLK32); |
535 | break; | 553 | break; |
536 | case 32: | 554 | case 32: |
537 | reg |= TPCI200_CLK32; | 555 | tpci200_set_mask(tpci200, addr, TPCI200_CLK32); |
538 | break; | 556 | break; |
539 | default: | 557 | default: |
540 | mutex_unlock(&tpci200->mutex); | ||
541 | return -EINVAL; | 558 | return -EINVAL; |
542 | } | 559 | } |
543 | iowrite16(reg, addr); | ||
544 | mutex_unlock(&tpci200->mutex); | ||
545 | return 0; | 560 | return 0; |
546 | } | 561 | } |
547 | 562 | ||