60
60
#define LPC_ODR4 0x118
61
61
#define LPC_STR4 0x11C
62
62
63
+ #define OBE_POLL_PERIOD (HZ / 2)
64
+
63
65
struct aspeed_kcs_bmc {
64
66
struct kcs_bmc_device kcs_bmc ;
65
67
66
68
struct regmap * map ;
69
+
70
+ struct {
71
+ spinlock_t lock ;
72
+ bool remove ;
73
+ struct timer_list timer ;
74
+ } obe ;
67
75
};
68
76
69
77
struct aspeed_kcs_of_ops {
@@ -159,68 +167,89 @@ static void aspeed_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enabl
159
167
160
168
switch (kcs_bmc -> channel ) {
161
169
case 1 :
162
- if (enable ) {
163
- regmap_update_bits (priv -> map , LPC_HICR2 ,
164
- LPC_HICR2_IBFIF1 , LPC_HICR2_IBFIF1 );
165
- regmap_update_bits (priv -> map , LPC_HICR0 ,
166
- LPC_HICR0_LPC1E , LPC_HICR0_LPC1E );
167
- } else {
168
- regmap_update_bits (priv -> map , LPC_HICR0 ,
169
- LPC_HICR0_LPC1E , 0 );
170
- regmap_update_bits (priv -> map , LPC_HICR2 ,
171
- LPC_HICR2_IBFIF1 , 0 );
172
- }
173
- break ;
174
-
170
+ regmap_update_bits (priv -> map , LPC_HICR0 , LPC_HICR0_LPC1E , enable * LPC_HICR0_LPC1E );
171
+ return ;
175
172
case 2 :
176
- if (enable ) {
177
- regmap_update_bits (priv -> map , LPC_HICR2 ,
178
- LPC_HICR2_IBFIF2 , LPC_HICR2_IBFIF2 );
179
- regmap_update_bits (priv -> map , LPC_HICR0 ,
180
- LPC_HICR0_LPC2E , LPC_HICR0_LPC2E );
181
- } else {
182
- regmap_update_bits (priv -> map , LPC_HICR0 ,
183
- LPC_HICR0_LPC2E , 0 );
184
- regmap_update_bits (priv -> map , LPC_HICR2 ,
185
- LPC_HICR2_IBFIF2 , 0 );
186
- }
187
- break ;
188
-
173
+ regmap_update_bits (priv -> map , LPC_HICR0 , LPC_HICR0_LPC2E , enable * LPC_HICR0_LPC2E );
174
+ return ;
189
175
case 3 :
190
- if (enable ) {
191
- regmap_update_bits (priv -> map , LPC_HICR2 ,
192
- LPC_HICR2_IBFIF3 , LPC_HICR2_IBFIF3 );
193
- regmap_update_bits (priv -> map , LPC_HICR0 ,
194
- LPC_HICR0_LPC3E , LPC_HICR0_LPC3E );
195
- regmap_update_bits (priv -> map , LPC_HICR4 ,
196
- LPC_HICR4_KCSENBL , LPC_HICR4_KCSENBL );
197
- } else {
198
- regmap_update_bits (priv -> map , LPC_HICR0 ,
199
- LPC_HICR0_LPC3E , 0 );
200
- regmap_update_bits (priv -> map , LPC_HICR4 ,
201
- LPC_HICR4_KCSENBL , 0 );
202
- regmap_update_bits (priv -> map , LPC_HICR2 ,
203
- LPC_HICR2_IBFIF3 , 0 );
204
- }
205
- break ;
206
-
176
+ regmap_update_bits (priv -> map , LPC_HICR0 , LPC_HICR0_LPC3E , enable * LPC_HICR0_LPC3E );
177
+ regmap_update_bits (priv -> map , LPC_HICR4 ,
178
+ LPC_HICR4_KCSENBL , enable * LPC_HICR4_KCSENBL );
179
+ return ;
207
180
case 4 :
208
- if (enable )
209
- regmap_update_bits (priv -> map , LPC_HICRB ,
210
- LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E ,
211
- LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E );
181
+ regmap_update_bits (priv -> map , LPC_HICRB , LPC_HICRB_LPC4E , enable * LPC_HICRB_LPC4E );
182
+ return ;
183
+ default :
184
+ pr_warn ("%s: Unsupported channel: %d" , __func__ , kcs_bmc -> channel );
185
+ return ;
186
+ }
187
+ }
188
+
189
+ static void aspeed_kcs_check_obe (struct timer_list * timer )
190
+ {
191
+ struct aspeed_kcs_bmc * priv = container_of (timer , struct aspeed_kcs_bmc , obe .timer );
192
+ unsigned long flags ;
193
+ u8 str ;
194
+
195
+ spin_lock_irqsave (& priv -> obe .lock , flags );
196
+ if (priv -> obe .remove ) {
197
+ spin_unlock_irqrestore (& priv -> obe .lock , flags );
198
+ return ;
199
+ }
200
+
201
+ str = aspeed_kcs_inb (& priv -> kcs_bmc , priv -> kcs_bmc .ioreg .str );
202
+ if (str & KCS_BMC_STR_OBF ) {
203
+ mod_timer (timer , jiffies + OBE_POLL_PERIOD );
204
+ spin_unlock_irqrestore (& priv -> obe .lock , flags );
205
+ return ;
206
+ }
207
+ spin_unlock_irqrestore (& priv -> obe .lock , flags );
208
+
209
+ kcs_bmc_handle_event (& priv -> kcs_bmc );
210
+ }
211
+
212
+ static void aspeed_kcs_irq_mask_update (struct kcs_bmc_device * kcs_bmc , u8 mask , u8 state )
213
+ {
214
+ struct aspeed_kcs_bmc * priv = to_aspeed_kcs_bmc (kcs_bmc );
215
+
216
+ /* We don't have an OBE IRQ, emulate it */
217
+ if (mask & KCS_BMC_EVENT_TYPE_OBE ) {
218
+ if (KCS_BMC_EVENT_TYPE_OBE & state )
219
+ mod_timer (& priv -> obe .timer , jiffies + OBE_POLL_PERIOD );
212
220
else
213
- regmap_update_bits (priv -> map , LPC_HICRB ,
214
- LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E ,
215
- 0 );
216
- break ;
221
+ del_timer (& priv -> obe .timer );
222
+ }
217
223
218
- default :
219
- break ;
224
+ if (mask & KCS_BMC_EVENT_TYPE_IBF ) {
225
+ const bool enable = !!(state & KCS_BMC_EVENT_TYPE_IBF );
226
+
227
+ switch (kcs_bmc -> channel ) {
228
+ case 1 :
229
+ regmap_update_bits (priv -> map , LPC_HICR2 , LPC_HICR2_IBFIF1 ,
230
+ enable * LPC_HICR2_IBFIF1 );
231
+ return ;
232
+ case 2 :
233
+ regmap_update_bits (priv -> map , LPC_HICR2 , LPC_HICR2_IBFIF2 ,
234
+ enable * LPC_HICR2_IBFIF2 );
235
+ return ;
236
+ case 3 :
237
+ regmap_update_bits (priv -> map , LPC_HICR2 , LPC_HICR2_IBFIF3 ,
238
+ enable * LPC_HICR2_IBFIF3 );
239
+ return ;
240
+ case 4 :
241
+ regmap_update_bits (priv -> map , LPC_HICRB , LPC_HICRB_IBFIF4 ,
242
+ enable * LPC_HICRB_IBFIF4 );
243
+ return ;
244
+ default :
245
+ pr_warn ("%s: Unsupported channel: %d" , __func__ , kcs_bmc -> channel );
246
+ return ;
247
+ }
220
248
}
221
249
}
222
250
223
251
static const struct kcs_bmc_device_ops aspeed_kcs_ops = {
252
+ .irq_mask_update = aspeed_kcs_irq_mask_update ,
224
253
.io_inputb = aspeed_kcs_inb ,
225
254
.io_outputb = aspeed_kcs_outb ,
226
255
.io_updateb = aspeed_kcs_updateb ,
@@ -375,6 +404,10 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
375
404
return - ENODEV ;
376
405
}
377
406
407
+ spin_lock_init (& priv -> obe .lock );
408
+ priv -> obe .remove = false;
409
+ timer_setup (& priv -> obe .timer , aspeed_kcs_check_obe , 0 );
410
+
378
411
aspeed_kcs_set_address (kcs_bmc , addr );
379
412
380
413
rc = aspeed_kcs_config_irq (kcs_bmc , pdev );
@@ -383,6 +416,8 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
383
416
384
417
platform_set_drvdata (pdev , priv );
385
418
419
+ aspeed_kcs_irq_mask_update (kcs_bmc , (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE ),
420
+ KCS_BMC_EVENT_TYPE_IBF );
386
421
aspeed_kcs_enable_channel (kcs_bmc , true);
387
422
388
423
rc = kcs_bmc_add_device (& priv -> kcs_bmc );
@@ -403,6 +438,15 @@ static int aspeed_kcs_remove(struct platform_device *pdev)
403
438
404
439
kcs_bmc_remove_device (kcs_bmc );
405
440
441
+ aspeed_kcs_enable_channel (kcs_bmc , false);
442
+ aspeed_kcs_irq_mask_update (kcs_bmc , (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE ), 0 );
443
+
444
+ /* Make sure it's proper dead */
445
+ spin_lock_irq (& priv -> obe .lock );
446
+ priv -> obe .remove = true;
447
+ spin_unlock_irq (& priv -> obe .lock );
448
+ del_timer_sync (& priv -> obe .timer );
449
+
406
450
return 0 ;
407
451
}
408
452
0 commit comments