6060#define LPC_ODR4 0x118
6161#define LPC_STR4 0x11C
6262
63+ #define OBE_POLL_PERIOD (HZ / 2)
64+
6365struct aspeed_kcs_bmc {
6466 struct kcs_bmc_device kcs_bmc ;
6567
6668 struct regmap * map ;
69+
70+ struct {
71+ spinlock_t lock ;
72+ bool remove ;
73+ struct timer_list timer ;
74+ } obe ;
6775};
6876
6977struct aspeed_kcs_of_ops {
@@ -159,68 +167,89 @@ static void aspeed_kcs_enable_channel(struct kcs_bmc_device *kcs_bmc, bool enabl
159167
160168 switch (kcs_bmc -> channel ) {
161169 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 ;
175172 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 ;
189175 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 ;
207180 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 );
212220 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+ }
217223
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+ }
220248 }
221249}
222250
223251static const struct kcs_bmc_device_ops aspeed_kcs_ops = {
252+ .irq_mask_update = aspeed_kcs_irq_mask_update ,
224253 .io_inputb = aspeed_kcs_inb ,
225254 .io_outputb = aspeed_kcs_outb ,
226255 .io_updateb = aspeed_kcs_updateb ,
@@ -375,6 +404,10 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
375404 return - ENODEV ;
376405 }
377406
407+ spin_lock_init (& priv -> obe .lock );
408+ priv -> obe .remove = false;
409+ timer_setup (& priv -> obe .timer , aspeed_kcs_check_obe , 0 );
410+
378411 aspeed_kcs_set_address (kcs_bmc , addr );
379412
380413 rc = aspeed_kcs_config_irq (kcs_bmc , pdev );
@@ -383,6 +416,8 @@ static int aspeed_kcs_probe(struct platform_device *pdev)
383416
384417 platform_set_drvdata (pdev , priv );
385418
419+ aspeed_kcs_irq_mask_update (kcs_bmc , (KCS_BMC_EVENT_TYPE_IBF | KCS_BMC_EVENT_TYPE_OBE ),
420+ KCS_BMC_EVENT_TYPE_IBF );
386421 aspeed_kcs_enable_channel (kcs_bmc , true);
387422
388423 rc = kcs_bmc_add_device (& priv -> kcs_bmc );
@@ -403,6 +438,15 @@ static int aspeed_kcs_remove(struct platform_device *pdev)
403438
404439 kcs_bmc_remove_device (kcs_bmc );
405440
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+
406450 return 0 ;
407451}
408452
0 commit comments