21
21
#include <linux/types.h>
22
22
#include <linux/spinlock.h>
23
23
24
+ #include <asm/unaligned.h>
25
+
24
26
#define QUAD8_EXTENT 32
25
27
26
28
static unsigned int base [max_num_isa_dev (QUAD8_EXTENT )];
@@ -232,52 +234,60 @@ static int quad8_count_read(struct counter_device *counter,
232
234
struct quad8 * const priv = counter_priv (counter );
233
235
struct channel_reg __iomem * const chan = priv -> reg -> channel + count -> id ;
234
236
unsigned long irqflags ;
235
- int i ;
236
-
237
- * val = 0 ;
237
+ u8 value [3 ];
238
238
239
239
spin_lock_irqsave (& priv -> lock , irqflags );
240
240
241
241
iowrite8 (SELECT_RLD | RESET_BP | TRANSFER_CNTR_TO_OL , & chan -> control );
242
-
243
- for (i = 0 ; i < 3 ; i ++ )
244
- * val |= (unsigned long )ioread8 (& chan -> data ) << (8 * i );
242
+ ioread8_rep (& chan -> data , value , sizeof (value ));
245
243
246
244
spin_unlock_irqrestore (& priv -> lock , irqflags );
247
245
246
+ * val = get_unaligned_le24 (value );
247
+
248
248
return 0 ;
249
249
}
250
250
251
+ static void quad8_preset_register_set (struct quad8 * const priv , const size_t id ,
252
+ const unsigned long preset )
253
+ {
254
+ struct channel_reg __iomem * const chan = priv -> reg -> channel + id ;
255
+ u8 value [3 ];
256
+
257
+ put_unaligned_le24 (preset , value );
258
+
259
+ iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
260
+ iowrite8_rep (& chan -> data , value , sizeof (value ));
261
+ }
262
+
263
+ static void quad8_flag_register_reset (struct quad8 * const priv , const size_t id )
264
+ {
265
+ struct channel_reg __iomem * const chan = priv -> reg -> channel + id ;
266
+
267
+ iowrite8 (SELECT_RLD | RESET_BT_CT_CPT_S_IDX , & chan -> control );
268
+ iowrite8 (SELECT_RLD | RESET_E , & chan -> control );
269
+ }
270
+
251
271
static int quad8_count_write (struct counter_device * counter ,
252
272
struct counter_count * count , u64 val )
253
273
{
254
274
struct quad8 * const priv = counter_priv (counter );
255
275
struct channel_reg __iomem * const chan = priv -> reg -> channel + count -> id ;
256
276
unsigned long irqflags ;
257
- int i ;
258
277
259
278
if (val > LS7267_CNTR_MAX )
260
279
return - ERANGE ;
261
280
262
281
spin_lock_irqsave (& priv -> lock , irqflags );
263
282
264
- iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
265
-
266
283
/* Counter can only be set via Preset Register */
267
- for (i = 0 ; i < 3 ; i ++ )
268
- iowrite8 (val >> (8 * i ), & chan -> data );
269
-
284
+ quad8_preset_register_set (priv , count -> id , val );
270
285
iowrite8 (SELECT_RLD | TRANSFER_PR_TO_CNTR , & chan -> control );
271
286
272
- iowrite8 ( SELECT_RLD | RESET_BP , & chan -> control );
287
+ quad8_flag_register_reset ( priv , count -> id );
273
288
274
289
/* Set Preset Register back to original value */
275
- val = priv -> preset [count -> id ];
276
- for (i = 0 ; i < 3 ; i ++ )
277
- iowrite8 (val >> (8 * i ), & chan -> data );
278
-
279
- iowrite8 (SELECT_RLD | RESET_BT_CT_CPT_S_IDX , & chan -> control );
280
- iowrite8 (SELECT_RLD | RESET_E , & chan -> control );
290
+ quad8_preset_register_set (priv , count -> id , priv -> preset [count -> id ]);
281
291
282
292
spin_unlock_irqrestore (& priv -> lock , irqflags );
283
293
@@ -771,21 +781,6 @@ static int quad8_count_preset_read(struct counter_device *counter,
771
781
return 0 ;
772
782
}
773
783
774
- static void quad8_preset_register_set (struct quad8 * const priv , const int id ,
775
- const unsigned int preset )
776
- {
777
- struct channel_reg __iomem * const chan = priv -> reg -> channel + id ;
778
- int i ;
779
-
780
- priv -> preset [id ] = preset ;
781
-
782
- iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
783
-
784
- /* Set Preset Register */
785
- for (i = 0 ; i < 3 ; i ++ )
786
- iowrite8 (preset >> (8 * i ), & chan -> data );
787
- }
788
-
789
784
static int quad8_count_preset_write (struct counter_device * counter ,
790
785
struct counter_count * count , u64 preset )
791
786
{
@@ -797,6 +792,7 @@ static int quad8_count_preset_write(struct counter_device *counter,
797
792
798
793
spin_lock_irqsave (& priv -> lock , irqflags );
799
794
795
+ priv -> preset [count -> id ] = preset ;
800
796
quad8_preset_register_set (priv , count -> id , preset );
801
797
802
798
spin_unlock_irqrestore (& priv -> lock , irqflags );
@@ -843,6 +839,7 @@ static int quad8_count_ceiling_write(struct counter_device *counter,
843
839
switch (u8_get_bits (priv -> cmr [count -> id ], COUNT_MODE )) {
844
840
case RANGE_LIMIT :
845
841
case MODULO_N :
842
+ priv -> preset [count -> id ] = ceiling ;
846
843
quad8_preset_register_set (priv , count -> id , ceiling );
847
844
spin_unlock_irqrestore (& priv -> lock , irqflags );
848
845
return 0 ;
@@ -961,24 +958,28 @@ static int quad8_signal_fck_prescaler_read(struct counter_device *counter,
961
958
return 0 ;
962
959
}
963
960
961
+ static void quad8_filter_clock_prescaler_set (struct quad8 * const priv , const size_t id ,
962
+ const u8 prescaler )
963
+ {
964
+ struct channel_reg __iomem * const chan = priv -> reg -> channel + id ;
965
+
966
+ iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
967
+ iowrite8 (prescaler , & chan -> data );
968
+ iowrite8 (SELECT_RLD | TRANSFER_PR0_TO_PSC , & chan -> control );
969
+ }
970
+
964
971
static int quad8_signal_fck_prescaler_write (struct counter_device * counter ,
965
972
struct counter_signal * signal ,
966
973
u8 prescaler )
967
974
{
968
975
struct quad8 * const priv = counter_priv (counter );
969
976
const size_t channel_id = signal -> id / 2 ;
970
- struct channel_reg __iomem * const chan = priv -> reg -> channel + channel_id ;
971
977
unsigned long irqflags ;
972
978
973
979
spin_lock_irqsave (& priv -> lock , irqflags );
974
980
975
981
priv -> fck_prescaler [channel_id ] = prescaler ;
976
-
977
- iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
978
-
979
- /* Set filter clock factor */
980
- iowrite8 (prescaler , & chan -> data );
981
- iowrite8 (SELECT_RLD | RESET_BP | TRANSFER_PR0_TO_PSC , & chan -> control );
982
+ quad8_filter_clock_prescaler_set (priv , channel_id , prescaler );
982
983
983
984
spin_unlock_irqrestore (& priv -> lock , irqflags );
984
985
@@ -1178,18 +1179,10 @@ static irqreturn_t quad8_irq_handler(int irq, void *private)
1178
1179
static void quad8_init_counter (struct quad8 * const priv , const size_t channel )
1179
1180
{
1180
1181
struct channel_reg __iomem * const chan = priv -> reg -> channel + channel ;
1181
- unsigned long i ;
1182
1182
1183
- iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
1184
- /* Reset filter clock factor */
1185
- iowrite8 (0 , & chan -> data );
1186
- iowrite8 (SELECT_RLD | RESET_BP | TRANSFER_PR0_TO_PSC , & chan -> control );
1187
- iowrite8 (SELECT_RLD | RESET_BP , & chan -> control );
1188
- /* Reset Preset Register */
1189
- for (i = 0 ; i < 3 ; i ++ )
1190
- iowrite8 (0x00 , & chan -> data );
1191
- iowrite8 (SELECT_RLD | RESET_BT_CT_CPT_S_IDX , & chan -> control );
1192
- iowrite8 (SELECT_RLD | RESET_E , & chan -> control );
1183
+ quad8_filter_clock_prescaler_set (priv , channel , 0 );
1184
+ quad8_preset_register_set (priv , channel , 0 );
1185
+ quad8_flag_register_reset (priv , channel );
1193
1186
1194
1187
/* Binary encoding; Normal count; non-quadrature mode */
1195
1188
priv -> cmr [channel ] = SELECT_CMR | BINARY | u8_encode_bits (NORMAL_COUNT , COUNT_MODE ) |
0 commit comments