| 1 | From 6e8ae6e2cee0e7e5939dc7042584c808366e61e0 Mon Sep 17 00:00:00 2001 |
| 2 | From: Hauke Mehrtens <hauke@hauke-m.de> |
| 3 | Date: Sun, 27 Nov 2011 14:01:01 +0100 |
| 4 | Subject: [PATCH 16/21] =?UTF-8?q?bcma:=20add=20function=20to=20check=20every?= |
| 5 | =?UTF-8?q?=2010=20=C2=B5s=20if=20a=20reg=20is=20set?= |
| 6 | MIME-Version: 1.0 |
| 7 | Content-Type: text/plain; charset=UTF-8 |
| 8 | Content-Transfer-Encoding: 8bit |
| 9 | |
| 10 | This function checks if a reg get set or cleared every 10 microseconds. |
| 11 | It is used in bcma_core_set_clockmode() and bcma_core_pll_ctl() to |
| 12 | reduce code duplication. In addition it is needed in the USB host |
| 13 | driver. |
| 14 | |
| 15 | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> |
| 16 | --- |
| 17 | drivers/bcma/core.c | 48 ++++++++++++++++++++++++++++---------------- |
| 18 | include/linux/bcma/bcma.h | 2 + |
| 19 | 2 files changed, 32 insertions(+), 18 deletions(-) |
| 20 | |
| 21 | --- a/drivers/bcma/core.c |
| 22 | +++ b/drivers/bcma/core.c |
| 23 | @@ -51,11 +51,36 @@ int bcma_core_enable(struct bcma_device |
| 24 | } |
| 25 | EXPORT_SYMBOL_GPL(bcma_core_enable); |
| 26 | |
| 27 | +/* Wait for bitmask in a register to get set or cleared. |
| 28 | + * timeout is in units of ten-microseconds. |
| 29 | + */ |
| 30 | +int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask, int timeout, |
| 31 | + int set) |
| 32 | +{ |
| 33 | + int i; |
| 34 | + u32 val; |
| 35 | + |
| 36 | + for (i = 0; i < timeout; i++) { |
| 37 | + val = bcma_read32(dev, reg); |
| 38 | + if (set) { |
| 39 | + if ((val & bitmask) == bitmask) |
| 40 | + return 0; |
| 41 | + } else { |
| 42 | + if (!(val & bitmask)) |
| 43 | + return 0; |
| 44 | + } |
| 45 | + udelay(10); |
| 46 | + } |
| 47 | + pr_err("Timeout waiting for bitmask %08X on register %04X to %s.\n", |
| 48 | + bitmask, reg, (set ? "set" : "clear")); |
| 49 | + |
| 50 | + return -ETIMEDOUT; |
| 51 | +} |
| 52 | +EXPORT_SYMBOL_GPL(bcma_wait_bits); |
| 53 | + |
| 54 | void bcma_core_set_clockmode(struct bcma_device *core, |
| 55 | enum bcma_clkmode clkmode) |
| 56 | { |
| 57 | - u16 i; |
| 58 | - |
| 59 | WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON && |
| 60 | core->id.id != BCMA_CORE_PCIE && |
| 61 | core->id.id != BCMA_CORE_80211); |
| 62 | @@ -64,15 +89,8 @@ void bcma_core_set_clockmode(struct bcma |
| 63 | case BCMA_CLKMODE_FAST: |
| 64 | bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); |
| 65 | udelay(64); |
| 66 | - for (i = 0; i < 1500; i++) { |
| 67 | - if (bcma_read32(core, BCMA_CLKCTLST) & |
| 68 | - BCMA_CLKCTLST_HAVEHT) { |
| 69 | - i = 0; |
| 70 | - break; |
| 71 | - } |
| 72 | - udelay(10); |
| 73 | - } |
| 74 | - if (i) |
| 75 | + if (bcma_wait_bits(core, BCMA_CLKCTLST, BCMA_CLKCTLST_HAVEHT, |
| 76 | + 1500, 1)) |
| 77 | pr_err("HT force timeout\n"); |
| 78 | break; |
| 79 | case BCMA_CLKMODE_DYNAMIC: |
| 80 | @@ -84,22 +102,12 @@ EXPORT_SYMBOL_GPL(bcma_core_set_clockmod |
| 81 | |
| 82 | void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on) |
| 83 | { |
| 84 | - u16 i; |
| 85 | - |
| 86 | WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ); |
| 87 | WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST); |
| 88 | |
| 89 | if (on) { |
| 90 | bcma_set32(core, BCMA_CLKCTLST, req); |
| 91 | - for (i = 0; i < 10000; i++) { |
| 92 | - if ((bcma_read32(core, BCMA_CLKCTLST) & status) == |
| 93 | - status) { |
| 94 | - i = 0; |
| 95 | - break; |
| 96 | - } |
| 97 | - udelay(10); |
| 98 | - } |
| 99 | - if (i) |
| 100 | + if (bcma_wait_bits(core, BCMA_CLKCTLST, status, 10000, 1)) |
| 101 | pr_err("PLL enable timeout\n"); |
| 102 | } else { |
| 103 | pr_warn("Disabling PLL not supported yet!\n"); |
| 104 | --- a/include/linux/bcma/bcma.h |
| 105 | +++ b/include/linux/bcma/bcma.h |
| 106 | @@ -283,6 +283,9 @@ static inline void bcma_maskset16(struct |
| 107 | bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); |
| 108 | } |
| 109 | |
| 110 | +extern int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask, |
| 111 | + int timeout, int set); |
| 112 | + |
| 113 | extern bool bcma_core_is_enabled(struct bcma_device *core); |
| 114 | extern void bcma_core_disable(struct bcma_device *core, u32 flags); |
| 115 | extern int bcma_core_enable(struct bcma_device *core, u32 flags); |
| 116 | |