diff options
| -rw-r--r-- | arch/sparc64/kernel/ds.c | 270 | ||||
| -rw-r--r-- | arch/sparc64/kernel/mdesc.c | 20 | ||||
| -rw-r--r-- | arch/sparc64/kernel/setup.c | 4 | ||||
| -rw-r--r-- | drivers/serial/sunhv.c | 12 |
4 files changed, 150 insertions, 156 deletions
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c index 1c587107cef0..ba01533f4e03 100644 --- a/arch/sparc64/kernel/ds.c +++ b/arch/sparc64/kernel/ds.c | |||
| @@ -228,7 +228,7 @@ static struct ds_cap_state *find_cap_by_string(const char *name) | |||
| 228 | return NULL; | 228 | return NULL; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | static int ds_send(struct ldc_channel *lp, void *data, int len) | 231 | static int __ds_send(struct ldc_channel *lp, void *data, int len) |
| 232 | { | 232 | { |
| 233 | int err, limit = 1000; | 233 | int err, limit = 1000; |
| 234 | 234 | ||
| @@ -243,6 +243,18 @@ static int ds_send(struct ldc_channel *lp, void *data, int len) | |||
| 243 | return err; | 243 | return err; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | static int ds_send(struct ldc_channel *lp, void *data, int len) | ||
| 247 | { | ||
| 248 | unsigned long flags; | ||
| 249 | int err; | ||
| 250 | |||
| 251 | spin_lock_irqsave(&ds_lock, flags); | ||
| 252 | err = __ds_send(lp, data, len); | ||
| 253 | spin_unlock_irqrestore(&ds_lock, flags); | ||
| 254 | |||
| 255 | return err; | ||
| 256 | } | ||
| 257 | |||
| 246 | struct ds_md_update_req { | 258 | struct ds_md_update_req { |
| 247 | __u64 req_num; | 259 | __u64 req_num; |
| 248 | }; | 260 | }; |
| @@ -267,6 +279,8 @@ static void md_update_data(struct ldc_channel *lp, | |||
| 267 | 279 | ||
| 268 | printk(KERN_INFO PFX "Machine description update.\n"); | 280 | printk(KERN_INFO PFX "Machine description update.\n"); |
| 269 | 281 | ||
| 282 | mdesc_update(); | ||
| 283 | |||
| 270 | memset(&pkt, 0, sizeof(pkt)); | 284 | memset(&pkt, 0, sizeof(pkt)); |
| 271 | pkt.data.tag.type = DS_DATA; | 285 | pkt.data.tag.type = DS_DATA; |
| 272 | pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); | 286 | pkt.data.tag.len = sizeof(pkt) - sizeof(struct ds_msg_tag); |
| @@ -275,8 +289,6 @@ static void md_update_data(struct ldc_channel *lp, | |||
| 275 | pkt.res.result = DS_OK; | 289 | pkt.res.result = DS_OK; |
| 276 | 290 | ||
| 277 | ds_send(lp, &pkt, sizeof(pkt)); | 291 | ds_send(lp, &pkt, sizeof(pkt)); |
| 278 | |||
| 279 | mdesc_update(); | ||
| 280 | } | 292 | } |
| 281 | 293 | ||
| 282 | struct ds_shutdown_req { | 294 | struct ds_shutdown_req { |
| @@ -391,18 +403,6 @@ struct dr_cpu_resp_entry { | |||
| 391 | __u32 str_off; | 403 | __u32 str_off; |
| 392 | }; | 404 | }; |
| 393 | 405 | ||
| 394 | /* DR cpu requests get queued onto the work list by the | ||
| 395 | * dr_cpu_data() callback. The list is protected by | ||
| 396 | * ds_lock, and processed by dr_cpu_process() in order. | ||
| 397 | */ | ||
| 398 | static LIST_HEAD(dr_cpu_work_list); | ||
| 399 | static DECLARE_WAIT_QUEUE_HEAD(dr_cpu_wait); | ||
| 400 | |||
| 401 | struct dr_cpu_queue_entry { | ||
| 402 | struct list_head list; | ||
| 403 | char req[0]; | ||
| 404 | }; | ||
| 405 | |||
| 406 | static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) | 406 | static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) |
| 407 | { | 407 | { |
| 408 | struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); | 408 | struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); |
| @@ -425,7 +425,7 @@ static void __dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) | |||
| 425 | 425 | ||
| 426 | pkt.data.tag.len = msg_len - sizeof(struct ds_msg_tag); | 426 | pkt.data.tag.len = msg_len - sizeof(struct ds_msg_tag); |
| 427 | 427 | ||
| 428 | ds_send(dp->lp, &pkt, msg_len); | 428 | __ds_send(dp->lp, &pkt, msg_len); |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | static void dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) | 431 | static void dr_cpu_send_error(struct ds_cap_state *cp, struct ds_data *data) |
| @@ -555,7 +555,7 @@ static int dr_cpu_configure(struct ds_cap_state *cp, u64 req_num, | |||
| 555 | } | 555 | } |
| 556 | 556 | ||
| 557 | spin_lock_irqsave(&ds_lock, flags); | 557 | spin_lock_irqsave(&ds_lock, flags); |
| 558 | ds_send(ds_info->lp, resp, resp_len); | 558 | __ds_send(ds_info->lp, resp, resp_len); |
| 559 | spin_unlock_irqrestore(&ds_lock, flags); | 559 | spin_unlock_irqrestore(&ds_lock, flags); |
| 560 | 560 | ||
| 561 | kfree(resp); | 561 | kfree(resp); |
| @@ -596,7 +596,7 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num, | |||
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | spin_lock_irqsave(&ds_lock, flags); | 598 | spin_lock_irqsave(&ds_lock, flags); |
| 599 | ds_send(ds_info->lp, resp, resp_len); | 599 | __ds_send(ds_info->lp, resp, resp_len); |
| 600 | spin_unlock_irqrestore(&ds_lock, flags); | 600 | spin_unlock_irqrestore(&ds_lock, flags); |
| 601 | 601 | ||
| 602 | kfree(resp); | 602 | kfree(resp); |
| @@ -604,107 +604,49 @@ static int dr_cpu_unconfigure(struct ds_cap_state *cp, u64 req_num, | |||
| 604 | return 0; | 604 | return 0; |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | static void process_dr_cpu_list(struct ds_cap_state *cp) | 607 | static void dr_cpu_data(struct ldc_channel *lp, |
| 608 | struct ds_cap_state *cp, | ||
| 609 | void *buf, int len) | ||
| 608 | { | 610 | { |
| 609 | struct dr_cpu_queue_entry *qp, *tmp; | 611 | struct ds_data *data = buf; |
| 610 | unsigned long flags; | 612 | struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); |
| 611 | LIST_HEAD(todo); | 613 | u32 *cpu_list = (u32 *) (tag + 1); |
| 614 | u64 req_num = tag->req_num; | ||
| 612 | cpumask_t mask; | 615 | cpumask_t mask; |
| 616 | unsigned int i; | ||
| 617 | int err; | ||
| 613 | 618 | ||
| 614 | spin_lock_irqsave(&ds_lock, flags); | 619 | switch (tag->type) { |
| 615 | list_splice(&dr_cpu_work_list, &todo); | 620 | case DR_CPU_CONFIGURE: |
| 616 | INIT_LIST_HEAD(&dr_cpu_work_list); | 621 | case DR_CPU_UNCONFIGURE: |
| 617 | spin_unlock_irqrestore(&ds_lock, flags); | 622 | case DR_CPU_FORCE_UNCONFIGURE: |
| 618 | 623 | break; | |
| 619 | list_for_each_entry_safe(qp, tmp, &todo, list) { | ||
| 620 | struct ds_data *data = (struct ds_data *) qp->req; | ||
| 621 | struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); | ||
| 622 | u32 *cpu_list = (u32 *) (tag + 1); | ||
| 623 | u64 req_num = tag->req_num; | ||
| 624 | unsigned int i; | ||
| 625 | int err; | ||
| 626 | |||
| 627 | switch (tag->type) { | ||
| 628 | case DR_CPU_CONFIGURE: | ||
| 629 | case DR_CPU_UNCONFIGURE: | ||
| 630 | case DR_CPU_FORCE_UNCONFIGURE: | ||
| 631 | break; | ||
| 632 | |||
| 633 | default: | ||
| 634 | dr_cpu_send_error(cp, data); | ||
| 635 | goto next; | ||
| 636 | } | ||
| 637 | |||
| 638 | purge_dups(cpu_list, tag->num_records); | ||
| 639 | |||
| 640 | cpus_clear(mask); | ||
| 641 | for (i = 0; i < tag->num_records; i++) { | ||
| 642 | if (cpu_list[i] == CPU_SENTINEL) | ||
| 643 | continue; | ||
| 644 | |||
| 645 | if (cpu_list[i] < NR_CPUS) | ||
| 646 | cpu_set(cpu_list[i], mask); | ||
| 647 | } | ||
| 648 | |||
| 649 | if (tag->type == DR_CPU_CONFIGURE) | ||
| 650 | err = dr_cpu_configure(cp, req_num, &mask); | ||
| 651 | else | ||
| 652 | err = dr_cpu_unconfigure(cp, req_num, &mask); | ||
| 653 | |||
| 654 | if (err) | ||
| 655 | dr_cpu_send_error(cp, data); | ||
| 656 | 624 | ||
| 657 | next: | 625 | default: |
| 658 | list_del(&qp->list); | 626 | dr_cpu_send_error(cp, data); |
| 659 | kfree(qp); | 627 | return; |
| 660 | } | 628 | } |
| 661 | } | ||
| 662 | 629 | ||
| 663 | static int dr_cpu_thread(void *__unused) | 630 | purge_dups(cpu_list, tag->num_records); |
| 664 | { | ||
| 665 | struct ds_cap_state *cp; | ||
| 666 | DEFINE_WAIT(wait); | ||
| 667 | 631 | ||
| 668 | cp = find_cap_by_string("dr-cpu"); | 632 | cpus_clear(mask); |
| 669 | 633 | for (i = 0; i < tag->num_records; i++) { | |
| 670 | while (1) { | 634 | if (cpu_list[i] == CPU_SENTINEL) |
| 671 | prepare_to_wait(&dr_cpu_wait, &wait, TASK_INTERRUPTIBLE); | 635 | continue; |
| 672 | if (list_empty(&dr_cpu_work_list)) | ||
| 673 | schedule(); | ||
| 674 | finish_wait(&dr_cpu_wait, &wait); | ||
| 675 | |||
| 676 | if (kthread_should_stop()) | ||
| 677 | break; | ||
| 678 | 636 | ||
| 679 | process_dr_cpu_list(cp); | 637 | if (cpu_list[i] < NR_CPUS) |
| 638 | cpu_set(cpu_list[i], mask); | ||
| 680 | } | 639 | } |
| 681 | 640 | ||
| 682 | return 0; | 641 | if (tag->type == DR_CPU_CONFIGURE) |
| 683 | } | 642 | err = dr_cpu_configure(cp, req_num, &mask); |
| 684 | 643 | else | |
| 685 | static void dr_cpu_data(struct ldc_channel *lp, | 644 | err = dr_cpu_unconfigure(cp, req_num, &mask); |
| 686 | struct ds_cap_state *dp, | ||
| 687 | void *buf, int len) | ||
| 688 | { | ||
| 689 | struct dr_cpu_queue_entry *qp; | ||
| 690 | struct ds_data *dpkt = buf; | ||
| 691 | struct dr_cpu_tag *rp; | ||
| 692 | 645 | ||
| 693 | rp = (struct dr_cpu_tag *) (dpkt + 1); | 646 | if (err) |
| 694 | 647 | dr_cpu_send_error(cp, data); | |
| 695 | qp = kmalloc(sizeof(struct dr_cpu_queue_entry) + len, GFP_ATOMIC); | ||
| 696 | if (!qp) { | ||
| 697 | struct ds_cap_state *cp; | ||
| 698 | |||
| 699 | cp = find_cap_by_string("dr-cpu"); | ||
| 700 | __dr_cpu_send_error(cp, dpkt); | ||
| 701 | } else { | ||
| 702 | memcpy(&qp->req, buf, len); | ||
| 703 | list_add_tail(&qp->list, &dr_cpu_work_list); | ||
| 704 | wake_up(&dr_cpu_wait); | ||
| 705 | } | ||
| 706 | } | 648 | } |
| 707 | #endif | 649 | #endif /* CONFIG_HOTPLUG_CPU */ |
| 708 | 650 | ||
| 709 | struct ds_pri_msg { | 651 | struct ds_pri_msg { |
| 710 | __u64 req_num; | 652 | __u64 req_num; |
| @@ -820,7 +762,7 @@ void ldom_set_var(const char *var, const char *value) | |||
| 820 | ds_var_doorbell = 0; | 762 | ds_var_doorbell = 0; |
| 821 | ds_var_response = -1; | 763 | ds_var_response = -1; |
| 822 | 764 | ||
| 823 | ds_send(dp->lp, &pkt, msg_len); | 765 | __ds_send(dp->lp, &pkt, msg_len); |
| 824 | spin_unlock_irqrestore(&ds_lock, flags); | 766 | spin_unlock_irqrestore(&ds_lock, flags); |
| 825 | 767 | ||
| 826 | loops = 1000; | 768 | loops = 1000; |
| @@ -904,7 +846,7 @@ static int register_services(struct ds_info *dp) | |||
| 904 | pbuf.req.minor = 0; | 846 | pbuf.req.minor = 0; |
| 905 | strcpy(pbuf.req.svc_id, cp->service_id); | 847 | strcpy(pbuf.req.svc_id, cp->service_id); |
| 906 | 848 | ||
| 907 | err = ds_send(lp, &pbuf, msg_len); | 849 | err = __ds_send(lp, &pbuf, msg_len); |
| 908 | if (err > 0) | 850 | if (err > 0) |
| 909 | cp->state = CAP_STATE_REG_SENT; | 851 | cp->state = CAP_STATE_REG_SENT; |
| 910 | } | 852 | } |
| @@ -960,27 +902,97 @@ conn_reset: | |||
| 960 | return -ECONNRESET; | 902 | return -ECONNRESET; |
| 961 | } | 903 | } |
| 962 | 904 | ||
| 905 | static void __send_ds_nack(struct ds_info *dp, u64 handle) | ||
| 906 | { | ||
| 907 | struct ds_data_nack nack = { | ||
| 908 | .tag = { | ||
| 909 | .type = DS_NACK, | ||
| 910 | .len = (sizeof(struct ds_data_nack) - | ||
| 911 | sizeof(struct ds_msg_tag)), | ||
| 912 | }, | ||
| 913 | .handle = handle, | ||
| 914 | .result = DS_INV_HDL, | ||
| 915 | }; | ||
| 916 | |||
| 917 | __ds_send(dp->lp, &nack, sizeof(nack)); | ||
| 918 | } | ||
| 919 | |||
| 920 | static LIST_HEAD(ds_work_list); | ||
| 921 | static DECLARE_WAIT_QUEUE_HEAD(ds_wait); | ||
| 922 | |||
| 923 | struct ds_queue_entry { | ||
| 924 | struct list_head list; | ||
| 925 | int req_len; | ||
| 926 | int __pad; | ||
| 927 | u64 req[0]; | ||
| 928 | }; | ||
| 929 | |||
| 930 | static void process_ds_work(void) | ||
| 931 | { | ||
| 932 | struct ds_queue_entry *qp, *tmp; | ||
| 933 | static struct ds_info *dp; | ||
| 934 | unsigned long flags; | ||
| 935 | LIST_HEAD(todo); | ||
| 936 | |||
| 937 | spin_lock_irqsave(&ds_lock, flags); | ||
| 938 | list_splice(&ds_work_list, &todo); | ||
| 939 | INIT_LIST_HEAD(&ds_work_list); | ||
| 940 | spin_unlock_irqrestore(&ds_lock, flags); | ||
| 941 | |||
| 942 | dp = ds_info; | ||
| 943 | |||
| 944 | list_for_each_entry_safe(qp, tmp, &todo, list) { | ||
| 945 | struct ds_data *dpkt = (struct ds_data *) qp->req; | ||
| 946 | struct ds_cap_state *cp = find_cap(dpkt->handle); | ||
| 947 | int req_len = qp->req_len; | ||
| 948 | |||
| 949 | if (!cp) { | ||
| 950 | printk(KERN_ERR PFX "Data for unknown handle %lu\n", | ||
| 951 | dpkt->handle); | ||
| 952 | |||
| 953 | spin_lock_irqsave(&ds_lock, flags); | ||
| 954 | __send_ds_nack(dp, dpkt->handle); | ||
| 955 | spin_unlock_irqrestore(&ds_lock, flags); | ||
| 956 | } else { | ||
| 957 | cp->data(dp->lp, cp, dpkt, req_len); | ||
| 958 | } | ||
| 959 | |||
| 960 | list_del(&qp->list); | ||
| 961 | kfree(qp); | ||
| 962 | } | ||
| 963 | } | ||
| 964 | |||
| 965 | static int ds_thread(void *__unused) | ||
| 966 | { | ||
| 967 | DEFINE_WAIT(wait); | ||
| 968 | |||
| 969 | while (1) { | ||
| 970 | prepare_to_wait(&ds_wait, &wait, TASK_INTERRUPTIBLE); | ||
| 971 | if (list_empty(&ds_work_list)) | ||
| 972 | schedule(); | ||
| 973 | finish_wait(&ds_wait, &wait); | ||
| 974 | |||
| 975 | if (kthread_should_stop()) | ||
| 976 | break; | ||
| 977 | |||
| 978 | process_ds_work(); | ||
| 979 | } | ||
| 980 | |||
| 981 | return 0; | ||
| 982 | } | ||
| 983 | |||
| 963 | static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len) | 984 | static int ds_data(struct ds_info *dp, struct ds_msg_tag *pkt, int len) |
| 964 | { | 985 | { |
| 965 | struct ds_data *dpkt = (struct ds_data *) pkt; | 986 | struct ds_data *dpkt = (struct ds_data *) pkt; |
| 966 | struct ds_cap_state *cp = find_cap(dpkt->handle); | 987 | struct ds_queue_entry *qp; |
| 967 | 988 | ||
| 968 | if (!cp) { | 989 | qp = kmalloc(sizeof(struct ds_queue_entry) + len, GFP_ATOMIC); |
| 969 | struct ds_data_nack nack = { | 990 | if (!qp) { |
| 970 | .tag = { | 991 | __send_ds_nack(dp, dpkt->handle); |
| 971 | .type = DS_NACK, | ||
| 972 | .len = (sizeof(struct ds_data_nack) - | ||
| 973 | sizeof(struct ds_msg_tag)), | ||
| 974 | }, | ||
| 975 | .handle = dpkt->handle, | ||
| 976 | .result = DS_INV_HDL, | ||
| 977 | }; | ||
| 978 | |||
| 979 | printk(KERN_ERR PFX "Data for unknown handle %lu\n", | ||
| 980 | dpkt->handle); | ||
| 981 | ds_send(dp->lp, &nack, sizeof(nack)); | ||
| 982 | } else { | 992 | } else { |
| 983 | cp->data(dp->lp, cp, dpkt, len); | 993 | memcpy(&qp->req, pkt, len); |
| 994 | list_add_tail(&qp->list, &ds_work_list); | ||
| 995 | wake_up(&ds_wait); | ||
| 984 | } | 996 | } |
| 985 | return 0; | 997 | return 0; |
| 986 | } | 998 | } |
| @@ -996,7 +1008,7 @@ static void ds_up(struct ds_info *dp) | |||
| 996 | req.ver.major = 1; | 1008 | req.ver.major = 1; |
| 997 | req.ver.minor = 0; | 1009 | req.ver.minor = 0; |
| 998 | 1010 | ||
| 999 | err = ds_send(lp, &req, sizeof(req)); | 1011 | err = __ds_send(lp, &req, sizeof(req)); |
| 1000 | if (err > 0) | 1012 | if (err > 0) |
| 1001 | dp->hs_state = DS_HS_START; | 1013 | dp->hs_state = DS_HS_START; |
| 1002 | } | 1014 | } |
| @@ -1148,9 +1160,7 @@ static int __init ds_init(void) | |||
| 1148 | for (i = 0; i < ARRAY_SIZE(ds_states); i++) | 1160 | for (i = 0; i < ARRAY_SIZE(ds_states); i++) |
| 1149 | ds_states[i].handle = ((u64)i << 32); | 1161 | ds_states[i].handle = ((u64)i << 32); |
| 1150 | 1162 | ||
| 1151 | #ifdef CONFIG_HOTPLUG_CPU | 1163 | kthread_run(ds_thread, NULL, "kldomd"); |
| 1152 | kthread_run(dr_cpu_thread, NULL, "kdrcpud"); | ||
| 1153 | #endif | ||
| 1154 | 1164 | ||
| 1155 | return vio_register_driver(&ds_driver); | 1165 | return vio_register_driver(&ds_driver); |
| 1156 | } | 1166 | } |
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 62a389793949..de5310ffdb48 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c | |||
| @@ -214,7 +214,7 @@ void mdesc_release(struct mdesc_handle *hp) | |||
| 214 | } | 214 | } |
| 215 | EXPORT_SYMBOL(mdesc_release); | 215 | EXPORT_SYMBOL(mdesc_release); |
| 216 | 216 | ||
| 217 | static void do_mdesc_update(struct work_struct *work) | 217 | void mdesc_update(void) |
| 218 | { | 218 | { |
| 219 | unsigned long len, real_len, status; | 219 | unsigned long len, real_len, status; |
| 220 | struct mdesc_handle *hp, *orig_hp; | 220 | struct mdesc_handle *hp, *orig_hp; |
| @@ -248,13 +248,6 @@ static void do_mdesc_update(struct work_struct *work) | |||
| 248 | spin_unlock_irqrestore(&mdesc_lock, flags); | 248 | spin_unlock_irqrestore(&mdesc_lock, flags); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | static DECLARE_WORK(mdesc_update_work, do_mdesc_update); | ||
| 252 | |||
| 253 | void mdesc_update(void) | ||
| 254 | { | ||
| 255 | schedule_work(&mdesc_update_work); | ||
| 256 | } | ||
| 257 | |||
| 258 | static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) | 251 | static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) |
| 259 | { | 252 | { |
| 260 | return (struct mdesc_elem *) (mdesc + 1); | 253 | return (struct mdesc_elem *) (mdesc + 1); |
| @@ -278,13 +271,14 @@ u64 mdesc_node_by_name(struct mdesc_handle *hp, | |||
| 278 | u64 last_node = hp->mdesc.node_sz / 16; | 271 | u64 last_node = hp->mdesc.node_sz / 16; |
| 279 | u64 ret; | 272 | u64 ret; |
| 280 | 273 | ||
| 281 | if (from_node == MDESC_NODE_NULL) | 274 | if (from_node == MDESC_NODE_NULL) { |
| 282 | from_node = 0; | 275 | ret = from_node = 0; |
| 283 | 276 | } else if (from_node >= last_node) { | |
| 284 | if (from_node >= last_node) | ||
| 285 | return MDESC_NODE_NULL; | 277 | return MDESC_NODE_NULL; |
| 278 | } else { | ||
| 279 | ret = ep[from_node].d.val; | ||
| 280 | } | ||
| 286 | 281 | ||
| 287 | ret = ep[from_node].d.val; | ||
| 288 | while (ret < last_node) { | 282 | while (ret < last_node) { |
| 289 | if (ep[ret].tag != MD_NODE) | 283 | if (ep[ret].tag != MD_NODE) |
| 290 | return MDESC_NODE_NULL; | 284 | return MDESC_NODE_NULL; |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index dc928e49e341..aafde3dd9fd4 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
| @@ -454,9 +454,9 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) | |||
| 454 | ncpus_probed, | 454 | ncpus_probed, |
| 455 | num_online_cpus(), | 455 | num_online_cpus(), |
| 456 | dcache_parity_tl1_occurred, | 456 | dcache_parity_tl1_occurred, |
| 457 | icache_parity_tl1_occurred, | 457 | icache_parity_tl1_occurred |
| 458 | #ifndef CONFIG_SMP | 458 | #ifndef CONFIG_SMP |
| 459 | cpu_data(0).clock_tick | 459 | , cpu_data(0).clock_tick |
| 460 | #endif | 460 | #endif |
| 461 | ); | 461 | ); |
| 462 | #ifdef CONFIG_SMP | 462 | #ifdef CONFIG_SMP |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 17bcca53d6a1..d82be42ff29a 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
| @@ -258,17 +258,7 @@ static void sunhv_stop_tx(struct uart_port *port) | |||
| 258 | /* port->lock held by caller. */ | 258 | /* port->lock held by caller. */ |
| 259 | static void sunhv_start_tx(struct uart_port *port) | 259 | static void sunhv_start_tx(struct uart_port *port) |
| 260 | { | 260 | { |
| 261 | struct circ_buf *xmit = &port->info->xmit; | 261 | transmit_chars(port); |
| 262 | |||
| 263 | while (!uart_circ_empty(xmit)) { | ||
| 264 | long status = sun4v_con_putchar(xmit->buf[xmit->tail]); | ||
| 265 | |||
| 266 | if (status != HV_EOK) | ||
| 267 | break; | ||
| 268 | |||
| 269 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
| 270 | port->icount.tx++; | ||
| 271 | } | ||
| 272 | } | 262 | } |
| 273 | 263 | ||
| 274 | /* port->lock is not held. */ | 264 | /* port->lock is not held. */ |
