diff options
Diffstat (limited to 'drivers/misc/ti-st/st_core.c')
-rw-r--r-- | drivers/misc/ti-st/st_core.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index ba168a7d54d..2b62232c2c6 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c | |||
@@ -137,6 +137,8 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) | |||
137 | * st_reg_complete - | 137 | * st_reg_complete - |
138 | * to call registration complete callbacks | 138 | * to call registration complete callbacks |
139 | * of all protocol stack drivers | 139 | * of all protocol stack drivers |
140 | * This function is being called with spin lock held, protocol drivers are | ||
141 | * only expected to complete their waits and do nothing more than that. | ||
140 | */ | 142 | */ |
141 | void st_reg_complete(struct st_data_s *st_gdata, char err) | 143 | void st_reg_complete(struct st_data_s *st_gdata, char err) |
142 | { | 144 | { |
@@ -538,11 +540,12 @@ long st_register(struct st_proto_s *new_proto) | |||
538 | set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); | 540 | set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); |
539 | st_recv = st_kim_recv; | 541 | st_recv = st_kim_recv; |
540 | 542 | ||
543 | /* enable the ST LL - to set default chip state */ | ||
544 | st_ll_enable(st_gdata); | ||
545 | |||
541 | /* release lock previously held - re-locked below */ | 546 | /* release lock previously held - re-locked below */ |
542 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 547 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
543 | 548 | ||
544 | /* enable the ST LL - to set default chip state */ | ||
545 | st_ll_enable(st_gdata); | ||
546 | /* this may take a while to complete | 549 | /* this may take a while to complete |
547 | * since it involves BT fw download | 550 | * since it involves BT fw download |
548 | */ | 551 | */ |
@@ -553,10 +556,13 @@ long st_register(struct st_proto_s *new_proto) | |||
553 | (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { | 556 | (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { |
554 | pr_err(" KIM failure complete callback "); | 557 | pr_err(" KIM failure complete callback "); |
555 | st_reg_complete(st_gdata, err); | 558 | st_reg_complete(st_gdata, err); |
559 | clear_bit(ST_REG_PENDING, &st_gdata->st_state); | ||
556 | } | 560 | } |
557 | return -EINVAL; | 561 | return -EINVAL; |
558 | } | 562 | } |
559 | 563 | ||
564 | spin_lock_irqsave(&st_gdata->lock, flags); | ||
565 | |||
560 | clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); | 566 | clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); |
561 | st_recv = st_int_recv; | 567 | st_recv = st_int_recv; |
562 | 568 | ||
@@ -576,10 +582,10 @@ long st_register(struct st_proto_s *new_proto) | |||
576 | if (st_gdata->is_registered[new_proto->chnl_id] == true) { | 582 | if (st_gdata->is_registered[new_proto->chnl_id] == true) { |
577 | pr_err(" proto %d already registered ", | 583 | pr_err(" proto %d already registered ", |
578 | new_proto->chnl_id); | 584 | new_proto->chnl_id); |
585 | spin_unlock_irqrestore(&st_gdata->lock, flags); | ||
579 | return -EALREADY; | 586 | return -EALREADY; |
580 | } | 587 | } |
581 | 588 | ||
582 | spin_lock_irqsave(&st_gdata->lock, flags); | ||
583 | add_channel_to_table(st_gdata, new_proto); | 589 | add_channel_to_table(st_gdata, new_proto); |
584 | st_gdata->protos_registered++; | 590 | st_gdata->protos_registered++; |
585 | new_proto->write = st_write; | 591 | new_proto->write = st_write; |
@@ -619,7 +625,7 @@ long st_unregister(struct st_proto_s *proto) | |||
619 | 625 | ||
620 | spin_lock_irqsave(&st_gdata->lock, flags); | 626 | spin_lock_irqsave(&st_gdata->lock, flags); |
621 | 627 | ||
622 | if (st_gdata->list[proto->chnl_id] == NULL) { | 628 | if (st_gdata->is_registered[proto->chnl_id] == false) { |
623 | pr_err(" chnl_id %d not registered", proto->chnl_id); | 629 | pr_err(" chnl_id %d not registered", proto->chnl_id); |
624 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 630 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
625 | return -EPROTONOSUPPORT; | 631 | return -EPROTONOSUPPORT; |
@@ -629,6 +635,10 @@ long st_unregister(struct st_proto_s *proto) | |||
629 | remove_channel_from_table(st_gdata, proto); | 635 | remove_channel_from_table(st_gdata, proto); |
630 | spin_unlock_irqrestore(&st_gdata->lock, flags); | 636 | spin_unlock_irqrestore(&st_gdata->lock, flags); |
631 | 637 | ||
638 | /* paranoid check */ | ||
639 | if (st_gdata->protos_registered < ST_EMPTY) | ||
640 | st_gdata->protos_registered = ST_EMPTY; | ||
641 | |||
632 | if ((st_gdata->protos_registered == ST_EMPTY) && | 642 | if ((st_gdata->protos_registered == ST_EMPTY) && |
633 | (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { | 643 | (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { |
634 | pr_info(" all chnl_ids unregistered "); | 644 | pr_info(" all chnl_ids unregistered "); |