diff options
Diffstat (limited to 'arch/arm/mach-pxa/ssp.c')
-rw-r--r-- | arch/arm/mach-pxa/ssp.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index 93096befd017..1fddfeaa630d 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c | |||
@@ -40,6 +40,8 @@ | |||
40 | 40 | ||
41 | #define PXA_SSP_PORTS 3 | 41 | #define PXA_SSP_PORTS 3 |
42 | 42 | ||
43 | #define TIMEOUT 100000 | ||
44 | |||
43 | struct ssp_info_ { | 45 | struct ssp_info_ { |
44 | int irq; | 46 | int irq; |
45 | u32 clock; | 47 | u32 clock; |
@@ -92,13 +94,18 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
92 | * The caller is expected to perform the necessary locking. | 94 | * The caller is expected to perform the necessary locking. |
93 | * | 95 | * |
94 | * Returns: | 96 | * Returns: |
95 | * %-ETIMEDOUT timeout occurred (for future) | 97 | * %-ETIMEDOUT timeout occurred |
96 | * 0 success | 98 | * 0 success |
97 | */ | 99 | */ |
98 | int ssp_write_word(struct ssp_dev *dev, u32 data) | 100 | int ssp_write_word(struct ssp_dev *dev, u32 data) |
99 | { | 101 | { |
100 | while (!(SSSR_P(dev->port) & SSSR_TNF)) | 102 | int timeout = TIMEOUT; |
103 | |||
104 | while (!(SSSR_P(dev->port) & SSSR_TNF)) { | ||
105 | if (!--timeout) | ||
106 | return -ETIMEDOUT; | ||
101 | cpu_relax(); | 107 | cpu_relax(); |
108 | } | ||
102 | 109 | ||
103 | SSDR_P(dev->port) = data; | 110 | SSDR_P(dev->port) = data; |
104 | 111 | ||
@@ -117,15 +124,21 @@ int ssp_write_word(struct ssp_dev *dev, u32 data) | |||
117 | * The caller is expected to perform the necessary locking. | 124 | * The caller is expected to perform the necessary locking. |
118 | * | 125 | * |
119 | * Returns: | 126 | * Returns: |
120 | * %-ETIMEDOUT timeout occurred (for future) | 127 | * %-ETIMEDOUT timeout occurred |
121 | * 32-bit data success | 128 | * 32-bit data success |
122 | */ | 129 | */ |
123 | int ssp_read_word(struct ssp_dev *dev) | 130 | int ssp_read_word(struct ssp_dev *dev, u32 *data) |
124 | { | 131 | { |
125 | while (!(SSSR_P(dev->port) & SSSR_RNE)) | 132 | int timeout = TIMEOUT; |
133 | |||
134 | while (!(SSSR_P(dev->port) & SSSR_RNE)) { | ||
135 | if (!--timeout) | ||
136 | return -ETIMEDOUT; | ||
126 | cpu_relax(); | 137 | cpu_relax(); |
138 | } | ||
127 | 139 | ||
128 | return SSDR_P(dev->port); | 140 | *data = SSDR_P(dev->port); |
141 | return 0; | ||
129 | } | 142 | } |
130 | 143 | ||
131 | /** | 144 | /** |
@@ -136,13 +149,21 @@ int ssp_read_word(struct ssp_dev *dev) | |||
136 | * | 149 | * |
137 | * The caller is expected to perform the necessary locking. | 150 | * The caller is expected to perform the necessary locking. |
138 | */ | 151 | */ |
139 | void ssp_flush(struct ssp_dev *dev) | 152 | int ssp_flush(struct ssp_dev *dev) |
140 | { | 153 | { |
154 | int timeout = TIMEOUT * 2; | ||
155 | |||
141 | do { | 156 | do { |
142 | while (SSSR_P(dev->port) & SSSR_RNE) { | 157 | while (SSSR_P(dev->port) & SSSR_RNE) { |
158 | if (!--timeout) | ||
159 | return -ETIMEDOUT; | ||
143 | (void) SSDR_P(dev->port); | 160 | (void) SSDR_P(dev->port); |
144 | } | 161 | } |
162 | if (!--timeout) | ||
163 | return -ETIMEDOUT; | ||
145 | } while (SSSR_P(dev->port) & SSSR_BSY); | 164 | } while (SSSR_P(dev->port) & SSSR_BSY); |
165 | |||
166 | return 0; | ||
146 | } | 167 | } |
147 | 168 | ||
148 | /** | 169 | /** |