diff options
Diffstat (limited to 'drivers')
31 files changed, 1105 insertions, 814 deletions
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index bd5de08ad6fd..0576a7dd32a5 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c | |||
@@ -157,6 +157,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn) | |||
157 | EXPORT_SYMBOL(tegra_ahb_enable_smmu); | 157 | EXPORT_SYMBOL(tegra_ahb_enable_smmu); |
158 | #endif | 158 | #endif |
159 | 159 | ||
160 | #ifdef CONFIG_PM_SLEEP | ||
160 | static int tegra_ahb_suspend(struct device *dev) | 161 | static int tegra_ahb_suspend(struct device *dev) |
161 | { | 162 | { |
162 | int i; | 163 | int i; |
@@ -176,6 +177,7 @@ static int tegra_ahb_resume(struct device *dev) | |||
176 | gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]); | 177 | gizmo_writel(ahb, ahb->ctx[i], tegra_ahb_gizmo[i]); |
177 | return 0; | 178 | return 0; |
178 | } | 179 | } |
180 | #endif | ||
179 | 181 | ||
180 | static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm, | 182 | static UNIVERSAL_DEV_PM_OPS(tegra_ahb_pm, |
181 | tegra_ahb_suspend, | 183 | tegra_ahb_suspend, |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 460e22dee36d..a3f79c495a41 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -298,6 +298,8 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, | |||
298 | struct sg_table *sg_table, | 298 | struct sg_table *sg_table, |
299 | enum dma_data_direction direction) | 299 | enum dma_data_direction direction) |
300 | { | 300 | { |
301 | might_sleep(); | ||
302 | |||
301 | if (WARN_ON(!attach || !attach->dmabuf || !sg_table)) | 303 | if (WARN_ON(!attach || !attach->dmabuf || !sg_table)) |
302 | return; | 304 | return; |
303 | 305 | ||
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 90493d4ead1f..c594cb16c37b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -37,8 +37,12 @@ | |||
37 | #include <linux/wait.h> | 37 | #include <linux/wait.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/dma-mapping.h> | ||
41 | #include <linux/kconfig.h> | ||
40 | #include "../tty/hvc/hvc_console.h" | 42 | #include "../tty/hvc/hvc_console.h" |
41 | 43 | ||
44 | #define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC) | ||
45 | |||
42 | /* | 46 | /* |
43 | * This is a global struct for storing common data for all the devices | 47 | * This is a global struct for storing common data for all the devices |
44 | * this driver handles. | 48 | * this driver handles. |
@@ -111,6 +115,21 @@ struct port_buffer { | |||
111 | size_t len; | 115 | size_t len; |
112 | /* offset in the buf from which to consume data */ | 116 | /* offset in the buf from which to consume data */ |
113 | size_t offset; | 117 | size_t offset; |
118 | |||
119 | /* DMA address of buffer */ | ||
120 | dma_addr_t dma; | ||
121 | |||
122 | /* Device we got DMA memory from */ | ||
123 | struct device *dev; | ||
124 | |||
125 | /* List of pending dma buffers to free */ | ||
126 | struct list_head list; | ||
127 | |||
128 | /* If sgpages == 0 then buf is used */ | ||
129 | unsigned int sgpages; | ||
130 | |||
131 | /* sg is used if spages > 0. sg must be the last in is struct */ | ||
132 | struct scatterlist sg[0]; | ||
114 | }; | 133 | }; |
115 | 134 | ||
116 | /* | 135 | /* |
@@ -325,6 +344,11 @@ static bool is_console_port(struct port *port) | |||
325 | return false; | 344 | return false; |
326 | } | 345 | } |
327 | 346 | ||
347 | static bool is_rproc_serial(const struct virtio_device *vdev) | ||
348 | { | ||
349 | return is_rproc_enabled && vdev->id.device == VIRTIO_ID_RPROC_SERIAL; | ||
350 | } | ||
351 | |||
328 | static inline bool use_multiport(struct ports_device *portdev) | 352 | static inline bool use_multiport(struct ports_device *portdev) |
329 | { | 353 | { |
330 | /* | 354 | /* |
@@ -336,20 +360,110 @@ static inline bool use_multiport(struct ports_device *portdev) | |||
336 | return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT); | 360 | return portdev->vdev->features[0] & (1 << VIRTIO_CONSOLE_F_MULTIPORT); |
337 | } | 361 | } |
338 | 362 | ||
339 | static void free_buf(struct port_buffer *buf) | 363 | static DEFINE_SPINLOCK(dma_bufs_lock); |
364 | static LIST_HEAD(pending_free_dma_bufs); | ||
365 | |||
366 | static void free_buf(struct port_buffer *buf, bool can_sleep) | ||
340 | { | 367 | { |
341 | kfree(buf->buf); | 368 | unsigned int i; |
369 | |||
370 | for (i = 0; i < buf->sgpages; i++) { | ||
371 | struct page *page = sg_page(&buf->sg[i]); | ||
372 | if (!page) | ||
373 | break; | ||
374 | put_page(page); | ||
375 | } | ||
376 | |||
377 | if (!buf->dev) { | ||
378 | kfree(buf->buf); | ||
379 | } else if (is_rproc_enabled) { | ||
380 | unsigned long flags; | ||
381 | |||
382 | /* dma_free_coherent requires interrupts to be enabled. */ | ||
383 | if (!can_sleep) { | ||
384 | /* queue up dma-buffers to be freed later */ | ||
385 | spin_lock_irqsave(&dma_bufs_lock, flags); | ||
386 | list_add_tail(&buf->list, &pending_free_dma_bufs); | ||
387 | spin_unlock_irqrestore(&dma_bufs_lock, flags); | ||
388 | return; | ||
389 | } | ||
390 | dma_free_coherent(buf->dev, buf->size, buf->buf, buf->dma); | ||
391 | |||
392 | /* Release device refcnt and allow it to be freed */ | ||
393 | put_device(buf->dev); | ||
394 | } | ||
395 | |||
342 | kfree(buf); | 396 | kfree(buf); |
343 | } | 397 | } |
344 | 398 | ||
345 | static struct port_buffer *alloc_buf(size_t buf_size) | 399 | static void reclaim_dma_bufs(void) |
400 | { | ||
401 | unsigned long flags; | ||
402 | struct port_buffer *buf, *tmp; | ||
403 | LIST_HEAD(tmp_list); | ||
404 | |||
405 | if (list_empty(&pending_free_dma_bufs)) | ||
406 | return; | ||
407 | |||
408 | /* Create a copy of the pending_free_dma_bufs while holding the lock */ | ||
409 | spin_lock_irqsave(&dma_bufs_lock, flags); | ||
410 | list_cut_position(&tmp_list, &pending_free_dma_bufs, | ||
411 | pending_free_dma_bufs.prev); | ||
412 | spin_unlock_irqrestore(&dma_bufs_lock, flags); | ||
413 | |||
414 | /* Release the dma buffers, without irqs enabled */ | ||
415 | list_for_each_entry_safe(buf, tmp, &tmp_list, list) { | ||
416 | list_del(&buf->list); | ||
417 | free_buf(buf, true); | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size, | ||
422 | int pages) | ||
346 | { | 423 | { |
347 | struct port_buffer *buf; | 424 | struct port_buffer *buf; |
348 | 425 | ||
349 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); | 426 | reclaim_dma_bufs(); |
427 | |||
428 | /* | ||
429 | * Allocate buffer and the sg list. The sg list array is allocated | ||
430 | * directly after the port_buffer struct. | ||
431 | */ | ||
432 | buf = kmalloc(sizeof(*buf) + sizeof(struct scatterlist) * pages, | ||
433 | GFP_KERNEL); | ||
350 | if (!buf) | 434 | if (!buf) |
351 | goto fail; | 435 | goto fail; |
352 | buf->buf = kzalloc(buf_size, GFP_KERNEL); | 436 | |
437 | buf->sgpages = pages; | ||
438 | if (pages > 0) { | ||
439 | buf->dev = NULL; | ||
440 | buf->buf = NULL; | ||
441 | return buf; | ||
442 | } | ||
443 | |||
444 | if (is_rproc_serial(vq->vdev)) { | ||
445 | /* | ||
446 | * Allocate DMA memory from ancestor. When a virtio | ||
447 | * device is created by remoteproc, the DMA memory is | ||
448 | * associated with the grandparent device: | ||
449 | * vdev => rproc => platform-dev. | ||
450 | * The code here would have been less quirky if | ||
451 | * DMA_MEMORY_INCLUDES_CHILDREN had been supported | ||
452 | * in dma-coherent.c | ||
453 | */ | ||
454 | if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent) | ||
455 | goto free_buf; | ||
456 | buf->dev = vq->vdev->dev.parent->parent; | ||
457 | |||
458 | /* Increase device refcnt to avoid freeing it */ | ||
459 | get_device(buf->dev); | ||
460 | buf->buf = dma_alloc_coherent(buf->dev, buf_size, &buf->dma, | ||
461 | GFP_KERNEL); | ||
462 | } else { | ||
463 | buf->dev = NULL; | ||
464 | buf->buf = kmalloc(buf_size, GFP_KERNEL); | ||
465 | } | ||
466 | |||
353 | if (!buf->buf) | 467 | if (!buf->buf) |
354 | goto free_buf; | 468 | goto free_buf; |
355 | buf->len = 0; | 469 | buf->len = 0; |
@@ -396,6 +510,8 @@ static int add_inbuf(struct virtqueue *vq, struct port_buffer *buf) | |||
396 | 510 | ||
397 | ret = virtqueue_add_buf(vq, sg, 0, 1, buf, GFP_ATOMIC); | 511 | ret = virtqueue_add_buf(vq, sg, 0, 1, buf, GFP_ATOMIC); |
398 | virtqueue_kick(vq); | 512 | virtqueue_kick(vq); |
513 | if (!ret) | ||
514 | ret = vq->num_free; | ||
399 | return ret; | 515 | return ret; |
400 | } | 516 | } |
401 | 517 | ||
@@ -416,7 +532,7 @@ static void discard_port_data(struct port *port) | |||
416 | port->stats.bytes_discarded += buf->len - buf->offset; | 532 | port->stats.bytes_discarded += buf->len - buf->offset; |
417 | if (add_inbuf(port->in_vq, buf) < 0) { | 533 | if (add_inbuf(port->in_vq, buf) < 0) { |
418 | err++; | 534 | err++; |
419 | free_buf(buf); | 535 | free_buf(buf, false); |
420 | } | 536 | } |
421 | port->inbuf = NULL; | 537 | port->inbuf = NULL; |
422 | buf = get_inbuf(port); | 538 | buf = get_inbuf(port); |
@@ -459,7 +575,7 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, | |||
459 | vq = portdev->c_ovq; | 575 | vq = portdev->c_ovq; |
460 | 576 | ||
461 | sg_init_one(sg, &cpkt, sizeof(cpkt)); | 577 | sg_init_one(sg, &cpkt, sizeof(cpkt)); |
462 | if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) >= 0) { | 578 | if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) { |
463 | virtqueue_kick(vq); | 579 | virtqueue_kick(vq); |
464 | while (!virtqueue_get_buf(vq, &len)) | 580 | while (!virtqueue_get_buf(vq, &len)) |
465 | cpu_relax(); | 581 | cpu_relax(); |
@@ -476,55 +592,29 @@ static ssize_t send_control_msg(struct port *port, unsigned int event, | |||
476 | return 0; | 592 | return 0; |
477 | } | 593 | } |
478 | 594 | ||
479 | struct buffer_token { | ||
480 | union { | ||
481 | void *buf; | ||
482 | struct scatterlist *sg; | ||
483 | } u; | ||
484 | /* If sgpages == 0 then buf is used, else sg is used */ | ||
485 | unsigned int sgpages; | ||
486 | }; | ||
487 | |||
488 | static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages) | ||
489 | { | ||
490 | int i; | ||
491 | struct page *page; | ||
492 | |||
493 | for (i = 0; i < nrpages; i++) { | ||
494 | page = sg_page(&sg[i]); | ||
495 | if (!page) | ||
496 | break; | ||
497 | put_page(page); | ||
498 | } | ||
499 | kfree(sg); | ||
500 | } | ||
501 | 595 | ||
502 | /* Callers must take the port->outvq_lock */ | 596 | /* Callers must take the port->outvq_lock */ |
503 | static void reclaim_consumed_buffers(struct port *port) | 597 | static void reclaim_consumed_buffers(struct port *port) |
504 | { | 598 | { |
505 | struct buffer_token *tok; | 599 | struct port_buffer *buf; |
506 | unsigned int len; | 600 | unsigned int len; |
507 | 601 | ||
508 | if (!port->portdev) { | 602 | if (!port->portdev) { |
509 | /* Device has been unplugged. vqs are already gone. */ | 603 | /* Device has been unplugged. vqs are already gone. */ |
510 | return; | 604 | return; |
511 | } | 605 | } |
512 | while ((tok = virtqueue_get_buf(port->out_vq, &len))) { | 606 | while ((buf = virtqueue_get_buf(port->out_vq, &len))) { |
513 | if (tok->sgpages) | 607 | free_buf(buf, false); |
514 | reclaim_sg_pages(tok->u.sg, tok->sgpages); | ||
515 | else | ||
516 | kfree(tok->u.buf); | ||
517 | kfree(tok); | ||
518 | port->outvq_full = false; | 608 | port->outvq_full = false; |
519 | } | 609 | } |
520 | } | 610 | } |
521 | 611 | ||
522 | static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, | 612 | static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, |
523 | int nents, size_t in_count, | 613 | int nents, size_t in_count, |
524 | struct buffer_token *tok, bool nonblock) | 614 | void *data, bool nonblock) |
525 | { | 615 | { |
526 | struct virtqueue *out_vq; | 616 | struct virtqueue *out_vq; |
527 | ssize_t ret; | 617 | int err; |
528 | unsigned long flags; | 618 | unsigned long flags; |
529 | unsigned int len; | 619 | unsigned int len; |
530 | 620 | ||
@@ -534,17 +624,17 @@ static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, | |||
534 | 624 | ||
535 | reclaim_consumed_buffers(port); | 625 | reclaim_consumed_buffers(port); |
536 | 626 | ||
537 | ret = virtqueue_add_buf(out_vq, sg, nents, 0, tok, GFP_ATOMIC); | 627 | err = virtqueue_add_buf(out_vq, sg, nents, 0, data, GFP_ATOMIC); |
538 | 628 | ||
539 | /* Tell Host to go! */ | 629 | /* Tell Host to go! */ |
540 | virtqueue_kick(out_vq); | 630 | virtqueue_kick(out_vq); |
541 | 631 | ||
542 | if (ret < 0) { | 632 | if (err) { |
543 | in_count = 0; | 633 | in_count = 0; |
544 | goto done; | 634 | goto done; |
545 | } | 635 | } |
546 | 636 | ||
547 | if (ret == 0) | 637 | if (out_vq->num_free == 0) |
548 | port->outvq_full = true; | 638 | port->outvq_full = true; |
549 | 639 | ||
550 | if (nonblock) | 640 | if (nonblock) |
@@ -572,37 +662,6 @@ done: | |||
572 | return in_count; | 662 | return in_count; |
573 | } | 663 | } |
574 | 664 | ||
575 | static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count, | ||
576 | bool nonblock) | ||
577 | { | ||
578 | struct scatterlist sg[1]; | ||
579 | struct buffer_token *tok; | ||
580 | |||
581 | tok = kmalloc(sizeof(*tok), GFP_ATOMIC); | ||
582 | if (!tok) | ||
583 | return -ENOMEM; | ||
584 | tok->sgpages = 0; | ||
585 | tok->u.buf = in_buf; | ||
586 | |||
587 | sg_init_one(sg, in_buf, in_count); | ||
588 | |||
589 | return __send_to_port(port, sg, 1, in_count, tok, nonblock); | ||
590 | } | ||
591 | |||
592 | static ssize_t send_pages(struct port *port, struct scatterlist *sg, int nents, | ||
593 | size_t in_count, bool nonblock) | ||
594 | { | ||
595 | struct buffer_token *tok; | ||
596 | |||
597 | tok = kmalloc(sizeof(*tok), GFP_ATOMIC); | ||
598 | if (!tok) | ||
599 | return -ENOMEM; | ||
600 | tok->sgpages = nents; | ||
601 | tok->u.sg = sg; | ||
602 | |||
603 | return __send_to_port(port, sg, nents, in_count, tok, nonblock); | ||
604 | } | ||
605 | |||
606 | /* | 665 | /* |
607 | * Give out the data that's requested from the buffer that we have | 666 | * Give out the data that's requested from the buffer that we have |
608 | * queued up. | 667 | * queued up. |
@@ -748,9 +807,10 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | |||
748 | size_t count, loff_t *offp) | 807 | size_t count, loff_t *offp) |
749 | { | 808 | { |
750 | struct port *port; | 809 | struct port *port; |
751 | char *buf; | 810 | struct port_buffer *buf; |
752 | ssize_t ret; | 811 | ssize_t ret; |
753 | bool nonblock; | 812 | bool nonblock; |
813 | struct scatterlist sg[1]; | ||
754 | 814 | ||
755 | /* Userspace could be out to fool us */ | 815 | /* Userspace could be out to fool us */ |
756 | if (!count) | 816 | if (!count) |
@@ -766,11 +826,11 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | |||
766 | 826 | ||
767 | count = min((size_t)(32 * 1024), count); | 827 | count = min((size_t)(32 * 1024), count); |
768 | 828 | ||
769 | buf = kmalloc(count, GFP_KERNEL); | 829 | buf = alloc_buf(port->out_vq, count, 0); |
770 | if (!buf) | 830 | if (!buf) |
771 | return -ENOMEM; | 831 | return -ENOMEM; |
772 | 832 | ||
773 | ret = copy_from_user(buf, ubuf, count); | 833 | ret = copy_from_user(buf->buf, ubuf, count); |
774 | if (ret) { | 834 | if (ret) { |
775 | ret = -EFAULT; | 835 | ret = -EFAULT; |
776 | goto free_buf; | 836 | goto free_buf; |
@@ -784,13 +844,14 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | |||
784 | * through to the host. | 844 | * through to the host. |
785 | */ | 845 | */ |
786 | nonblock = true; | 846 | nonblock = true; |
787 | ret = send_buf(port, buf, count, nonblock); | 847 | sg_init_one(sg, buf->buf, count); |
848 | ret = __send_to_port(port, sg, 1, count, buf, nonblock); | ||
788 | 849 | ||
789 | if (nonblock && ret > 0) | 850 | if (nonblock && ret > 0) |
790 | goto out; | 851 | goto out; |
791 | 852 | ||
792 | free_buf: | 853 | free_buf: |
793 | kfree(buf); | 854 | free_buf(buf, true); |
794 | out: | 855 | out: |
795 | return ret; | 856 | return ret; |
796 | } | 857 | } |
@@ -856,6 +917,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe, | |||
856 | struct port *port = filp->private_data; | 917 | struct port *port = filp->private_data; |
857 | struct sg_list sgl; | 918 | struct sg_list sgl; |
858 | ssize_t ret; | 919 | ssize_t ret; |
920 | struct port_buffer *buf; | ||
859 | struct splice_desc sd = { | 921 | struct splice_desc sd = { |
860 | .total_len = len, | 922 | .total_len = len, |
861 | .flags = flags, | 923 | .flags = flags, |
@@ -863,22 +925,34 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe, | |||
863 | .u.data = &sgl, | 925 | .u.data = &sgl, |
864 | }; | 926 | }; |
865 | 927 | ||
928 | /* | ||
929 | * Rproc_serial does not yet support splice. To support splice | ||
930 | * pipe_to_sg() must allocate dma-buffers and copy content from | ||
931 | * regular pages to dma pages. And alloc_buf and free_buf must | ||
932 | * support allocating and freeing such a list of dma-buffers. | ||
933 | */ | ||
934 | if (is_rproc_serial(port->out_vq->vdev)) | ||
935 | return -EINVAL; | ||
936 | |||
866 | ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); | 937 | ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); |
867 | if (ret < 0) | 938 | if (ret < 0) |
868 | return ret; | 939 | return ret; |
869 | 940 | ||
941 | buf = alloc_buf(port->out_vq, 0, pipe->nrbufs); | ||
942 | if (!buf) | ||
943 | return -ENOMEM; | ||
944 | |||
870 | sgl.n = 0; | 945 | sgl.n = 0; |
871 | sgl.len = 0; | 946 | sgl.len = 0; |
872 | sgl.size = pipe->nrbufs; | 947 | sgl.size = pipe->nrbufs; |
873 | sgl.sg = kmalloc(sizeof(struct scatterlist) * sgl.size, GFP_KERNEL); | 948 | sgl.sg = buf->sg; |
874 | if (unlikely(!sgl.sg)) | ||
875 | return -ENOMEM; | ||
876 | |||
877 | sg_init_table(sgl.sg, sgl.size); | 949 | sg_init_table(sgl.sg, sgl.size); |
878 | ret = __splice_from_pipe(pipe, &sd, pipe_to_sg); | 950 | ret = __splice_from_pipe(pipe, &sd, pipe_to_sg); |
879 | if (likely(ret > 0)) | 951 | if (likely(ret > 0)) |
880 | ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true); | 952 | ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true); |
881 | 953 | ||
954 | if (unlikely(ret <= 0)) | ||
955 | free_buf(buf, true); | ||
882 | return ret; | 956 | return ret; |
883 | } | 957 | } |
884 | 958 | ||
@@ -927,6 +1001,7 @@ static int port_fops_release(struct inode *inode, struct file *filp) | |||
927 | reclaim_consumed_buffers(port); | 1001 | reclaim_consumed_buffers(port); |
928 | spin_unlock_irq(&port->outvq_lock); | 1002 | spin_unlock_irq(&port->outvq_lock); |
929 | 1003 | ||
1004 | reclaim_dma_bufs(); | ||
930 | /* | 1005 | /* |
931 | * Locks aren't necessary here as a port can't be opened after | 1006 | * Locks aren't necessary here as a port can't be opened after |
932 | * unplug, and if a port isn't unplugged, a kref would already | 1007 | * unplug, and if a port isn't unplugged, a kref would already |
@@ -1031,6 +1106,7 @@ static const struct file_operations port_fops = { | |||
1031 | static int put_chars(u32 vtermno, const char *buf, int count) | 1106 | static int put_chars(u32 vtermno, const char *buf, int count) |
1032 | { | 1107 | { |
1033 | struct port *port; | 1108 | struct port *port; |
1109 | struct scatterlist sg[1]; | ||
1034 | 1110 | ||
1035 | if (unlikely(early_put_chars)) | 1111 | if (unlikely(early_put_chars)) |
1036 | return early_put_chars(vtermno, buf, count); | 1112 | return early_put_chars(vtermno, buf, count); |
@@ -1039,7 +1115,8 @@ static int put_chars(u32 vtermno, const char *buf, int count) | |||
1039 | if (!port) | 1115 | if (!port) |
1040 | return -EPIPE; | 1116 | return -EPIPE; |
1041 | 1117 | ||
1042 | return send_buf(port, (void *)buf, count, false); | 1118 | sg_init_one(sg, buf, count); |
1119 | return __send_to_port(port, sg, 1, count, (void *)buf, false); | ||
1043 | } | 1120 | } |
1044 | 1121 | ||
1045 | /* | 1122 | /* |
@@ -1076,7 +1153,10 @@ static void resize_console(struct port *port) | |||
1076 | return; | 1153 | return; |
1077 | 1154 | ||
1078 | vdev = port->portdev->vdev; | 1155 | vdev = port->portdev->vdev; |
1079 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) | 1156 | |
1157 | /* Don't test F_SIZE at all if we're rproc: not a valid feature! */ | ||
1158 | if (!is_rproc_serial(vdev) && | ||
1159 | virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) | ||
1080 | hvc_resize(port->cons.hvc, port->cons.ws); | 1160 | hvc_resize(port->cons.hvc, port->cons.ws); |
1081 | } | 1161 | } |
1082 | 1162 | ||
@@ -1260,7 +1340,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) | |||
1260 | 1340 | ||
1261 | nr_added_bufs = 0; | 1341 | nr_added_bufs = 0; |
1262 | do { | 1342 | do { |
1263 | buf = alloc_buf(PAGE_SIZE); | 1343 | buf = alloc_buf(vq, PAGE_SIZE, 0); |
1264 | if (!buf) | 1344 | if (!buf) |
1265 | break; | 1345 | break; |
1266 | 1346 | ||
@@ -1268,7 +1348,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) | |||
1268 | ret = add_inbuf(vq, buf); | 1348 | ret = add_inbuf(vq, buf); |
1269 | if (ret < 0) { | 1349 | if (ret < 0) { |
1270 | spin_unlock_irq(lock); | 1350 | spin_unlock_irq(lock); |
1271 | free_buf(buf); | 1351 | free_buf(buf, true); |
1272 | break; | 1352 | break; |
1273 | } | 1353 | } |
1274 | nr_added_bufs++; | 1354 | nr_added_bufs++; |
@@ -1356,10 +1436,18 @@ static int add_port(struct ports_device *portdev, u32 id) | |||
1356 | goto free_device; | 1436 | goto free_device; |
1357 | } | 1437 | } |
1358 | 1438 | ||
1359 | /* | 1439 | if (is_rproc_serial(port->portdev->vdev)) |
1360 | * If we're not using multiport support, this has to be a console port | 1440 | /* |
1361 | */ | 1441 | * For rproc_serial assume remote processor is connected. |
1362 | if (!use_multiport(port->portdev)) { | 1442 | * rproc_serial does not want the console port, only |
1443 | * the generic port implementation. | ||
1444 | */ | ||
1445 | port->host_connected = true; | ||
1446 | else if (!use_multiport(port->portdev)) { | ||
1447 | /* | ||
1448 | * If we're not using multiport support, | ||
1449 | * this has to be a console port. | ||
1450 | */ | ||
1363 | err = init_port_console(port); | 1451 | err = init_port_console(port); |
1364 | if (err) | 1452 | if (err) |
1365 | goto free_inbufs; | 1453 | goto free_inbufs; |
@@ -1392,7 +1480,7 @@ static int add_port(struct ports_device *portdev, u32 id) | |||
1392 | 1480 | ||
1393 | free_inbufs: | 1481 | free_inbufs: |
1394 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) | 1482 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) |
1395 | free_buf(buf); | 1483 | free_buf(buf, true); |
1396 | free_device: | 1484 | free_device: |
1397 | device_destroy(pdrvdata.class, port->dev->devt); | 1485 | device_destroy(pdrvdata.class, port->dev->devt); |
1398 | free_cdev: | 1486 | free_cdev: |
@@ -1434,7 +1522,11 @@ static void remove_port_data(struct port *port) | |||
1434 | 1522 | ||
1435 | /* Remove buffers we queued up for the Host to send us data in. */ | 1523 | /* Remove buffers we queued up for the Host to send us data in. */ |
1436 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) | 1524 | while ((buf = virtqueue_detach_unused_buf(port->in_vq))) |
1437 | free_buf(buf); | 1525 | free_buf(buf, true); |
1526 | |||
1527 | /* Free pending buffers from the out-queue. */ | ||
1528 | while ((buf = virtqueue_detach_unused_buf(port->out_vq))) | ||
1529 | free_buf(buf, true); | ||
1438 | } | 1530 | } |
1439 | 1531 | ||
1440 | /* | 1532 | /* |
@@ -1636,7 +1728,7 @@ static void control_work_handler(struct work_struct *work) | |||
1636 | if (add_inbuf(portdev->c_ivq, buf) < 0) { | 1728 | if (add_inbuf(portdev->c_ivq, buf) < 0) { |
1637 | dev_warn(&portdev->vdev->dev, | 1729 | dev_warn(&portdev->vdev->dev, |
1638 | "Error adding buffer to queue\n"); | 1730 | "Error adding buffer to queue\n"); |
1639 | free_buf(buf); | 1731 | free_buf(buf, false); |
1640 | } | 1732 | } |
1641 | } | 1733 | } |
1642 | spin_unlock(&portdev->cvq_lock); | 1734 | spin_unlock(&portdev->cvq_lock); |
@@ -1832,10 +1924,10 @@ static void remove_controlq_data(struct ports_device *portdev) | |||
1832 | return; | 1924 | return; |
1833 | 1925 | ||
1834 | while ((buf = virtqueue_get_buf(portdev->c_ivq, &len))) | 1926 | while ((buf = virtqueue_get_buf(portdev->c_ivq, &len))) |
1835 | free_buf(buf); | 1927 | free_buf(buf, true); |
1836 | 1928 | ||
1837 | while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq))) | 1929 | while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq))) |
1838 | free_buf(buf); | 1930 | free_buf(buf, true); |
1839 | } | 1931 | } |
1840 | 1932 | ||
1841 | /* | 1933 | /* |
@@ -1882,11 +1974,15 @@ static int virtcons_probe(struct virtio_device *vdev) | |||
1882 | 1974 | ||
1883 | multiport = false; | 1975 | multiport = false; |
1884 | portdev->config.max_nr_ports = 1; | 1976 | portdev->config.max_nr_ports = 1; |
1885 | if (virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT, | 1977 | |
1886 | offsetof(struct virtio_console_config, | 1978 | /* Don't test MULTIPORT at all if we're rproc: not a valid feature! */ |
1887 | max_nr_ports), | 1979 | if (!is_rproc_serial(vdev) && |
1888 | &portdev->config.max_nr_ports) == 0) | 1980 | virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT, |
1981 | offsetof(struct virtio_console_config, | ||
1982 | max_nr_ports), | ||
1983 | &portdev->config.max_nr_ports) == 0) { | ||
1889 | multiport = true; | 1984 | multiport = true; |
1985 | } | ||
1890 | 1986 | ||
1891 | err = init_vqs(portdev); | 1987 | err = init_vqs(portdev); |
1892 | if (err < 0) { | 1988 | if (err < 0) { |
@@ -1996,6 +2092,16 @@ static unsigned int features[] = { | |||
1996 | VIRTIO_CONSOLE_F_MULTIPORT, | 2092 | VIRTIO_CONSOLE_F_MULTIPORT, |
1997 | }; | 2093 | }; |
1998 | 2094 | ||
2095 | static struct virtio_device_id rproc_serial_id_table[] = { | ||
2096 | #if IS_ENABLED(CONFIG_REMOTEPROC) | ||
2097 | { VIRTIO_ID_RPROC_SERIAL, VIRTIO_DEV_ANY_ID }, | ||
2098 | #endif | ||
2099 | { 0 }, | ||
2100 | }; | ||
2101 | |||
2102 | static unsigned int rproc_serial_features[] = { | ||
2103 | }; | ||
2104 | |||
1999 | #ifdef CONFIG_PM | 2105 | #ifdef CONFIG_PM |
2000 | static int virtcons_freeze(struct virtio_device *vdev) | 2106 | static int virtcons_freeze(struct virtio_device *vdev) |
2001 | { | 2107 | { |
@@ -2080,6 +2186,20 @@ static struct virtio_driver virtio_console = { | |||
2080 | #endif | 2186 | #endif |
2081 | }; | 2187 | }; |
2082 | 2188 | ||
2189 | /* | ||
2190 | * virtio_rproc_serial refers to __devinit function which causes | ||
2191 | * section mismatch warnings. So use __refdata to silence warnings. | ||
2192 | */ | ||
2193 | static struct virtio_driver __refdata virtio_rproc_serial = { | ||
2194 | .feature_table = rproc_serial_features, | ||
2195 | .feature_table_size = ARRAY_SIZE(rproc_serial_features), | ||
2196 | .driver.name = "virtio_rproc_serial", | ||
2197 | .driver.owner = THIS_MODULE, | ||
2198 | .id_table = rproc_serial_id_table, | ||
2199 | .probe = virtcons_probe, | ||
2200 | .remove = virtcons_remove, | ||
2201 | }; | ||
2202 | |||
2083 | static int __init init(void) | 2203 | static int __init init(void) |
2084 | { | 2204 | { |
2085 | int err; | 2205 | int err; |
@@ -2104,7 +2224,15 @@ static int __init init(void) | |||
2104 | pr_err("Error %d registering virtio driver\n", err); | 2224 | pr_err("Error %d registering virtio driver\n", err); |
2105 | goto free; | 2225 | goto free; |
2106 | } | 2226 | } |
2227 | err = register_virtio_driver(&virtio_rproc_serial); | ||
2228 | if (err < 0) { | ||
2229 | pr_err("Error %d registering virtio rproc serial driver\n", | ||
2230 | err); | ||
2231 | goto unregister; | ||
2232 | } | ||
2107 | return 0; | 2233 | return 0; |
2234 | unregister: | ||
2235 | unregister_virtio_driver(&virtio_console); | ||
2108 | free: | 2236 | free: |
2109 | if (pdrvdata.debugfs_dir) | 2237 | if (pdrvdata.debugfs_dir) |
2110 | debugfs_remove_recursive(pdrvdata.debugfs_dir); | 2238 | debugfs_remove_recursive(pdrvdata.debugfs_dir); |
@@ -2114,7 +2242,10 @@ free: | |||
2114 | 2242 | ||
2115 | static void __exit fini(void) | 2243 | static void __exit fini(void) |
2116 | { | 2244 | { |
2245 | reclaim_dma_bufs(); | ||
2246 | |||
2117 | unregister_virtio_driver(&virtio_console); | 2247 | unregister_virtio_driver(&virtio_console); |
2248 | unregister_virtio_driver(&virtio_rproc_serial); | ||
2118 | 2249 | ||
2119 | class_destroy(pdrvdata.class); | 2250 | class_destroy(pdrvdata.class); |
2120 | if (pdrvdata.debugfs_dir) | 2251 | if (pdrvdata.debugfs_dir) |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 9f26400713f0..89cfd64b3373 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -115,6 +115,12 @@ int vid_from_reg(int val, u8 vrm) | |||
115 | return (val < 32) ? 1550 - 25 * val | 115 | return (val < 32) ? 1550 - 25 * val |
116 | : 775 - (25 * (val - 31)) / 2; | 116 | : 775 - (25 * (val - 31)) / 2; |
117 | 117 | ||
118 | case 26: /* AMD family 10h to 15h, serial VID */ | ||
119 | val &= 0x7f; | ||
120 | if (val >= 0x7c) | ||
121 | return 0; | ||
122 | return DIV_ROUND_CLOSEST(15500 - 125 * val, 10); | ||
123 | |||
118 | case 91: /* VRM 9.1 */ | 124 | case 91: /* VRM 9.1 */ |
119 | case 90: /* VRM 9.0 */ | 125 | case 90: /* VRM 9.0 */ |
120 | val &= 0x1f; | 126 | val &= 0x1f; |
@@ -195,6 +201,10 @@ static struct vrm_model vrm_models[] = { | |||
195 | {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24}, /* NPT family 0Fh */ | 201 | {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24}, /* NPT family 0Fh */ |
196 | {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25}, /* future fam. 0Fh */ | 202 | {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25}, /* future fam. 0Fh */ |
197 | {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25}, /* NPT family 10h */ | 203 | {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25}, /* NPT family 10h */ |
204 | {X86_VENDOR_AMD, 0x11, 0x0, ANY, ANY, 26}, /* family 11h */ | ||
205 | {X86_VENDOR_AMD, 0x12, 0x0, ANY, ANY, 26}, /* family 12h */ | ||
206 | {X86_VENDOR_AMD, 0x14, 0x0, ANY, ANY, 26}, /* family 14h */ | ||
207 | {X86_VENDOR_AMD, 0x15, 0x0, ANY, ANY, 26}, /* family 15h */ | ||
198 | 208 | ||
199 | {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82}, /* Pentium Pro, | 209 | {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82}, /* Pentium Pro, |
200 | * Pentium II, Xeon, | 210 | * Pentium II, Xeon, |
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index c3c471ca202f..646314f7c839 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -84,19 +84,21 @@ static void __init hwmon_pci_quirks(void) | |||
84 | 84 | ||
85 | /* Open access to 0x295-0x296 on MSI MS-7031 */ | 85 | /* Open access to 0x295-0x296 on MSI MS-7031 */ |
86 | sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL); | 86 | sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL); |
87 | if (sb && | 87 | if (sb) { |
88 | (sb->subsystem_vendor == 0x1462 && /* MSI */ | 88 | if (sb->subsystem_vendor == 0x1462 && /* MSI */ |
89 | sb->subsystem_device == 0x0031)) { /* MS-7031 */ | 89 | sb->subsystem_device == 0x0031) { /* MS-7031 */ |
90 | 90 | pci_read_config_byte(sb, 0x48, &enable); | |
91 | pci_read_config_byte(sb, 0x48, &enable); | 91 | pci_read_config_word(sb, 0x64, &base); |
92 | pci_read_config_word(sb, 0x64, &base); | 92 | |
93 | 93 | if (base == 0 && !(enable & BIT(2))) { | |
94 | if (base == 0 && !(enable & BIT(2))) { | 94 | dev_info(&sb->dev, |
95 | dev_info(&sb->dev, | 95 | "Opening wide generic port at 0x295\n"); |
96 | "Opening wide generic port at 0x295\n"); | 96 | pci_write_config_word(sb, 0x64, 0x295); |
97 | pci_write_config_word(sb, 0x64, 0x295); | 97 | pci_write_config_byte(sb, 0x48, |
98 | pci_write_config_byte(sb, 0x48, enable | BIT(2)); | 98 | enable | BIT(2)); |
99 | } | ||
99 | } | 100 | } |
101 | pci_dev_put(sb); | ||
100 | } | 102 | } |
101 | #endif | 103 | #endif |
102 | } | 104 | } |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index d32aa354cbdf..117d66fcded6 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -203,6 +203,8 @@ static const u8 IT87_REG_FAN[] = { 0x0d, 0x0e, 0x0f, 0x80, 0x82 }; | |||
203 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; | 203 | static const u8 IT87_REG_FAN_MIN[] = { 0x10, 0x11, 0x12, 0x84, 0x86 }; |
204 | static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; | 204 | static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83 }; |
205 | static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; | 205 | static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; |
206 | static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59 }; | ||
207 | |||
206 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 208 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
207 | #define IT87_REG_FAN_CTL 0x14 | 209 | #define IT87_REG_FAN_CTL 0x14 |
208 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 210 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
@@ -226,6 +228,83 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; | |||
226 | #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i)) | 228 | #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i)) |
227 | #define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i)) | 229 | #define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i)) |
228 | 230 | ||
231 | struct it87_devices { | ||
232 | const char *name; | ||
233 | u16 features; | ||
234 | u8 peci_mask; | ||
235 | u8 old_peci_mask; | ||
236 | }; | ||
237 | |||
238 | #define FEAT_12MV_ADC (1 << 0) | ||
239 | #define FEAT_NEWER_AUTOPWM (1 << 1) | ||
240 | #define FEAT_OLD_AUTOPWM (1 << 2) | ||
241 | #define FEAT_16BIT_FANS (1 << 3) | ||
242 | #define FEAT_TEMP_OFFSET (1 << 4) | ||
243 | #define FEAT_TEMP_PECI (1 << 5) | ||
244 | #define FEAT_TEMP_OLD_PECI (1 << 6) | ||
245 | |||
246 | static const struct it87_devices it87_devices[] = { | ||
247 | [it87] = { | ||
248 | .name = "it87", | ||
249 | .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ | ||
250 | }, | ||
251 | [it8712] = { | ||
252 | .name = "it8712", | ||
253 | .features = FEAT_OLD_AUTOPWM, /* may need to overwrite */ | ||
254 | }, | ||
255 | [it8716] = { | ||
256 | .name = "it8716", | ||
257 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET, | ||
258 | }, | ||
259 | [it8718] = { | ||
260 | .name = "it8718", | ||
261 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | ||
262 | | FEAT_TEMP_OLD_PECI, | ||
263 | .old_peci_mask = 0x4, | ||
264 | }, | ||
265 | [it8720] = { | ||
266 | .name = "it8720", | ||
267 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | ||
268 | | FEAT_TEMP_OLD_PECI, | ||
269 | .old_peci_mask = 0x4, | ||
270 | }, | ||
271 | [it8721] = { | ||
272 | .name = "it8721", | ||
273 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | ||
274 | | FEAT_TEMP_OFFSET | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI, | ||
275 | .peci_mask = 0x05, | ||
276 | .old_peci_mask = 0x02, /* Actually reports PCH */ | ||
277 | }, | ||
278 | [it8728] = { | ||
279 | .name = "it8728", | ||
280 | .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS | ||
281 | | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI, | ||
282 | .peci_mask = 0x07, | ||
283 | }, | ||
284 | [it8782] = { | ||
285 | .name = "it8782", | ||
286 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | ||
287 | | FEAT_TEMP_OLD_PECI, | ||
288 | .old_peci_mask = 0x4, | ||
289 | }, | ||
290 | [it8783] = { | ||
291 | .name = "it8783", | ||
292 | .features = FEAT_16BIT_FANS | FEAT_TEMP_OFFSET | ||
293 | | FEAT_TEMP_OLD_PECI, | ||
294 | .old_peci_mask = 0x4, | ||
295 | }, | ||
296 | }; | ||
297 | |||
298 | #define has_16bit_fans(data) ((data)->features & FEAT_16BIT_FANS) | ||
299 | #define has_12mv_adc(data) ((data)->features & FEAT_12MV_ADC) | ||
300 | #define has_newer_autopwm(data) ((data)->features & FEAT_NEWER_AUTOPWM) | ||
301 | #define has_old_autopwm(data) ((data)->features & FEAT_OLD_AUTOPWM) | ||
302 | #define has_temp_offset(data) ((data)->features & FEAT_TEMP_OFFSET) | ||
303 | #define has_temp_peci(data, nr) (((data)->features & FEAT_TEMP_PECI) && \ | ||
304 | ((data)->peci_mask & (1 << nr))) | ||
305 | #define has_temp_old_peci(data, nr) \ | ||
306 | (((data)->features & FEAT_TEMP_OLD_PECI) && \ | ||
307 | ((data)->old_peci_mask & (1 << nr))) | ||
229 | 308 | ||
230 | struct it87_sio_data { | 309 | struct it87_sio_data { |
231 | enum chips type; | 310 | enum chips type; |
@@ -249,7 +328,9 @@ struct it87_sio_data { | |||
249 | struct it87_data { | 328 | struct it87_data { |
250 | struct device *hwmon_dev; | 329 | struct device *hwmon_dev; |
251 | enum chips type; | 330 | enum chips type; |
252 | u8 revision; | 331 | u16 features; |
332 | u8 peci_mask; | ||
333 | u8 old_peci_mask; | ||
253 | 334 | ||
254 | unsigned short addr; | 335 | unsigned short addr; |
255 | const char *name; | 336 | const char *name; |
@@ -258,17 +339,13 @@ struct it87_data { | |||
258 | unsigned long last_updated; /* In jiffies */ | 339 | unsigned long last_updated; /* In jiffies */ |
259 | 340 | ||
260 | u16 in_scaled; /* Internal voltage sensors are scaled */ | 341 | u16 in_scaled; /* Internal voltage sensors are scaled */ |
261 | u8 in[9]; /* Register value */ | 342 | u8 in[9][3]; /* [nr][0]=in, [1]=min, [2]=max */ |
262 | u8 in_max[8]; /* Register value */ | ||
263 | u8 in_min[8]; /* Register value */ | ||
264 | u8 has_fan; /* Bitfield, fans enabled */ | 343 | u8 has_fan; /* Bitfield, fans enabled */ |
265 | u16 fan[5]; /* Register values, possibly combined */ | 344 | u16 fan[5][2]; /* Register values, [nr][0]=fan, [1]=min */ |
266 | u16 fan_min[5]; /* Register values, possibly combined */ | ||
267 | u8 has_temp; /* Bitfield, temp sensors enabled */ | 345 | u8 has_temp; /* Bitfield, temp sensors enabled */ |
268 | s8 temp[3]; /* Register value */ | 346 | s8 temp[3][4]; /* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */ |
269 | s8 temp_high[3]; /* Register value */ | 347 | u8 sensor; /* Register value (IT87_REG_TEMP_ENABLE) */ |
270 | s8 temp_low[3]; /* Register value */ | 348 | u8 extra; /* Register value (IT87_REG_TEMP_EXTRA) */ |
271 | u8 sensor; /* Register value */ | ||
272 | u8 fan_div[3]; /* Register encoding, shifted right */ | 349 | u8 fan_div[3]; /* Register encoding, shifted right */ |
273 | u8 vid; /* Register encoding, combined */ | 350 | u8 vid; /* Register encoding, combined */ |
274 | u8 vrm; | 351 | u8 vrm; |
@@ -296,26 +373,6 @@ struct it87_data { | |||
296 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ | 373 | s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */ |
297 | }; | 374 | }; |
298 | 375 | ||
299 | static inline int has_12mv_adc(const struct it87_data *data) | ||
300 | { | ||
301 | /* | ||
302 | * IT8721F and later have a 12 mV ADC, also with internal scaling | ||
303 | * on selected inputs. | ||
304 | */ | ||
305 | return data->type == it8721 | ||
306 | || data->type == it8728; | ||
307 | } | ||
308 | |||
309 | static inline int has_newer_autopwm(const struct it87_data *data) | ||
310 | { | ||
311 | /* | ||
312 | * IT8721F and later have separate registers for the temperature | ||
313 | * mapping and the manual duty cycle. | ||
314 | */ | ||
315 | return data->type == it8721 | ||
316 | || data->type == it8728; | ||
317 | } | ||
318 | |||
319 | static int adc_lsb(const struct it87_data *data, int nr) | 376 | static int adc_lsb(const struct it87_data *data, int nr) |
320 | { | 377 | { |
321 | int lsb = has_12mv_adc(data) ? 12 : 16; | 378 | int lsb = has_12mv_adc(data) ? 12 : 16; |
@@ -398,35 +455,6 @@ static const unsigned int pwm_freq[8] = { | |||
398 | 750000 / 128, | 455 | 750000 / 128, |
399 | }; | 456 | }; |
400 | 457 | ||
401 | static inline int has_16bit_fans(const struct it87_data *data) | ||
402 | { | ||
403 | /* | ||
404 | * IT8705F Datasheet 0.4.1, 3h == Version G. | ||
405 | * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
406 | * These are the first revisions with 16-bit tachometer support. | ||
407 | */ | ||
408 | return (data->type == it87 && data->revision >= 0x03) | ||
409 | || (data->type == it8712 && data->revision >= 0x08) | ||
410 | || data->type == it8716 | ||
411 | || data->type == it8718 | ||
412 | || data->type == it8720 | ||
413 | || data->type == it8721 | ||
414 | || data->type == it8728 | ||
415 | || data->type == it8782 | ||
416 | || data->type == it8783; | ||
417 | } | ||
418 | |||
419 | static inline int has_old_autopwm(const struct it87_data *data) | ||
420 | { | ||
421 | /* | ||
422 | * The old automatic fan speed control interface is implemented | ||
423 | * by IT8705F chips up to revision F and IT8712F chips up to | ||
424 | * revision G. | ||
425 | */ | ||
426 | return (data->type == it87 && data->revision < 0x03) | ||
427 | || (data->type == it8712 && data->revision < 0x08); | ||
428 | } | ||
429 | |||
430 | static int it87_probe(struct platform_device *pdev); | 458 | static int it87_probe(struct platform_device *pdev); |
431 | static int it87_remove(struct platform_device *pdev); | 459 | static int it87_remove(struct platform_device *pdev); |
432 | 460 | ||
@@ -447,59 +475,22 @@ static struct platform_driver it87_driver = { | |||
447 | }; | 475 | }; |
448 | 476 | ||
449 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 477 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
450 | char *buf) | 478 | char *buf) |
451 | { | ||
452 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
453 | int nr = sensor_attr->index; | ||
454 | |||
455 | struct it87_data *data = it87_update_device(dev); | ||
456 | return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr])); | ||
457 | } | ||
458 | |||
459 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
460 | char *buf) | ||
461 | { | 479 | { |
462 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 480 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
463 | int nr = sensor_attr->index; | 481 | int nr = sattr->nr; |
482 | int index = sattr->index; | ||
464 | 483 | ||
465 | struct it87_data *data = it87_update_device(dev); | 484 | struct it87_data *data = it87_update_device(dev); |
466 | return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in_min[nr])); | 485 | return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in[nr][index])); |
467 | } | 486 | } |
468 | 487 | ||
469 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | 488 | static ssize_t set_in(struct device *dev, struct device_attribute *attr, |
470 | char *buf) | 489 | const char *buf, size_t count) |
471 | { | ||
472 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
473 | int nr = sensor_attr->index; | ||
474 | |||
475 | struct it87_data *data = it87_update_device(dev); | ||
476 | return sprintf(buf, "%d\n", in_from_reg(data, nr, data->in_max[nr])); | ||
477 | } | ||
478 | |||
479 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | ||
480 | const char *buf, size_t count) | ||
481 | { | ||
482 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
483 | int nr = sensor_attr->index; | ||
484 | |||
485 | struct it87_data *data = dev_get_drvdata(dev); | ||
486 | unsigned long val; | ||
487 | |||
488 | if (kstrtoul(buf, 10, &val) < 0) | ||
489 | return -EINVAL; | ||
490 | |||
491 | mutex_lock(&data->update_lock); | ||
492 | data->in_min[nr] = in_to_reg(data, nr, val); | ||
493 | it87_write_value(data, IT87_REG_VIN_MIN(nr), | ||
494 | data->in_min[nr]); | ||
495 | mutex_unlock(&data->update_lock); | ||
496 | return count; | ||
497 | } | ||
498 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | ||
499 | const char *buf, size_t count) | ||
500 | { | 490 | { |
501 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 491 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
502 | int nr = sensor_attr->index; | 492 | int nr = sattr->nr; |
493 | int index = sattr->index; | ||
503 | 494 | ||
504 | struct it87_data *data = dev_get_drvdata(dev); | 495 | struct it87_data *data = dev_get_drvdata(dev); |
505 | unsigned long val; | 496 | unsigned long val; |
@@ -508,140 +499,167 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
508 | return -EINVAL; | 499 | return -EINVAL; |
509 | 500 | ||
510 | mutex_lock(&data->update_lock); | 501 | mutex_lock(&data->update_lock); |
511 | data->in_max[nr] = in_to_reg(data, nr, val); | 502 | data->in[nr][index] = in_to_reg(data, nr, val); |
512 | it87_write_value(data, IT87_REG_VIN_MAX(nr), | 503 | it87_write_value(data, |
513 | data->in_max[nr]); | 504 | index == 1 ? IT87_REG_VIN_MIN(nr) |
505 | : IT87_REG_VIN_MAX(nr), | ||
506 | data->in[nr][index]); | ||
514 | mutex_unlock(&data->update_lock); | 507 | mutex_unlock(&data->update_lock); |
515 | return count; | 508 | return count; |
516 | } | 509 | } |
517 | 510 | ||
518 | #define show_in_offset(offset) \ | 511 | static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0); |
519 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | 512 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in, |
520 | show_in, NULL, offset); | 513 | 0, 1); |
521 | 514 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in, | |
522 | #define limit_in_offset(offset) \ | 515 | 0, 2); |
523 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | 516 | |
524 | show_in_min, set_in_min, offset); \ | 517 | static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, 0); |
525 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | 518 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in, |
526 | show_in_max, set_in_max, offset); | 519 | 1, 1); |
527 | 520 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in, | |
528 | show_in_offset(0); | 521 | 1, 2); |
529 | limit_in_offset(0); | 522 | |
530 | show_in_offset(1); | 523 | static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, 0); |
531 | limit_in_offset(1); | 524 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in, |
532 | show_in_offset(2); | 525 | 2, 1); |
533 | limit_in_offset(2); | 526 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in, |
534 | show_in_offset(3); | 527 | 2, 2); |
535 | limit_in_offset(3); | 528 | |
536 | show_in_offset(4); | 529 | static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, 0); |
537 | limit_in_offset(4); | 530 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in, |
538 | show_in_offset(5); | 531 | 3, 1); |
539 | limit_in_offset(5); | 532 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in, |
540 | show_in_offset(6); | 533 | 3, 2); |
541 | limit_in_offset(6); | 534 | |
542 | show_in_offset(7); | 535 | static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, 0); |
543 | limit_in_offset(7); | 536 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in, |
544 | show_in_offset(8); | 537 | 4, 1); |
538 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in, | ||
539 | 4, 2); | ||
540 | |||
541 | static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, 0); | ||
542 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in, | ||
543 | 5, 1); | ||
544 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in, | ||
545 | 5, 2); | ||
546 | |||
547 | static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 6, 0); | ||
548 | static SENSOR_DEVICE_ATTR_2(in6_min, S_IRUGO | S_IWUSR, show_in, set_in, | ||
549 | 6, 1); | ||
550 | static SENSOR_DEVICE_ATTR_2(in6_max, S_IRUGO | S_IWUSR, show_in, set_in, | ||
551 | 6, 2); | ||
552 | |||
553 | static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 7, 0); | ||
554 | static SENSOR_DEVICE_ATTR_2(in7_min, S_IRUGO | S_IWUSR, show_in, set_in, | ||
555 | 7, 1); | ||
556 | static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in, | ||
557 | 7, 2); | ||
558 | |||
559 | static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0); | ||
545 | 560 | ||
546 | /* 3 temperatures */ | 561 | /* 3 temperatures */ |
547 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | 562 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, |
548 | char *buf) | 563 | char *buf) |
549 | { | 564 | { |
550 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 565 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
551 | int nr = sensor_attr->index; | 566 | int nr = sattr->nr; |
552 | 567 | int index = sattr->index; | |
553 | struct it87_data *data = it87_update_device(dev); | 568 | struct it87_data *data = it87_update_device(dev); |
554 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); | ||
555 | } | ||
556 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
557 | char *buf) | ||
558 | { | ||
559 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
560 | int nr = sensor_attr->index; | ||
561 | 569 | ||
562 | struct it87_data *data = it87_update_device(dev); | 570 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr][index])); |
563 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])); | ||
564 | } | 571 | } |
565 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | ||
566 | char *buf) | ||
567 | { | ||
568 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
569 | int nr = sensor_attr->index; | ||
570 | 572 | ||
571 | struct it87_data *data = it87_update_device(dev); | 573 | static ssize_t set_temp(struct device *dev, struct device_attribute *attr, |
572 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr])); | 574 | const char *buf, size_t count) |
573 | } | ||
574 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | ||
575 | const char *buf, size_t count) | ||
576 | { | 575 | { |
577 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 576 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
578 | int nr = sensor_attr->index; | 577 | int nr = sattr->nr; |
579 | 578 | int index = sattr->index; | |
580 | struct it87_data *data = dev_get_drvdata(dev); | 579 | struct it87_data *data = dev_get_drvdata(dev); |
581 | long val; | 580 | long val; |
581 | u8 reg, regval; | ||
582 | 582 | ||
583 | if (kstrtol(buf, 10, &val) < 0) | 583 | if (kstrtol(buf, 10, &val) < 0) |
584 | return -EINVAL; | 584 | return -EINVAL; |
585 | 585 | ||
586 | mutex_lock(&data->update_lock); | 586 | mutex_lock(&data->update_lock); |
587 | data->temp_high[nr] = TEMP_TO_REG(val); | ||
588 | it87_write_value(data, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]); | ||
589 | mutex_unlock(&data->update_lock); | ||
590 | return count; | ||
591 | } | ||
592 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | ||
593 | const char *buf, size_t count) | ||
594 | { | ||
595 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
596 | int nr = sensor_attr->index; | ||
597 | 587 | ||
598 | struct it87_data *data = dev_get_drvdata(dev); | 588 | switch (index) { |
599 | long val; | 589 | default: |
600 | 590 | case 1: | |
601 | if (kstrtol(buf, 10, &val) < 0) | 591 | reg = IT87_REG_TEMP_LOW(nr); |
602 | return -EINVAL; | 592 | break; |
593 | case 2: | ||
594 | reg = IT87_REG_TEMP_HIGH(nr); | ||
595 | break; | ||
596 | case 3: | ||
597 | regval = it87_read_value(data, IT87_REG_BEEP_ENABLE); | ||
598 | if (!(regval & 0x80)) { | ||
599 | regval |= 0x80; | ||
600 | it87_write_value(data, IT87_REG_BEEP_ENABLE, regval); | ||
601 | } | ||
602 | data->valid = 0; | ||
603 | reg = IT87_REG_TEMP_OFFSET[nr]; | ||
604 | break; | ||
605 | } | ||
603 | 606 | ||
604 | mutex_lock(&data->update_lock); | 607 | data->temp[nr][index] = TEMP_TO_REG(val); |
605 | data->temp_low[nr] = TEMP_TO_REG(val); | 608 | it87_write_value(data, reg, data->temp[nr][index]); |
606 | it87_write_value(data, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]); | ||
607 | mutex_unlock(&data->update_lock); | 609 | mutex_unlock(&data->update_lock); |
608 | return count; | 610 | return count; |
609 | } | 611 | } |
610 | #define show_temp_offset(offset) \ | 612 | |
611 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | 613 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); |
612 | show_temp, NULL, offset - 1); \ | 614 | static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
613 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | 615 | 0, 1); |
614 | show_temp_max, set_temp_max, offset - 1); \ | 616 | static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
615 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | 617 | 0, 2); |
616 | show_temp_min, set_temp_min, offset - 1); | 618 | static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp, |
617 | 619 | set_temp, 0, 3); | |
618 | show_temp_offset(1); | 620 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0); |
619 | show_temp_offset(2); | 621 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
620 | show_temp_offset(3); | 622 | 1, 1); |
621 | 623 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | |
622 | static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, | 624 | 1, 2); |
623 | char *buf) | 625 | static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp, |
626 | set_temp, 1, 3); | ||
627 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0); | ||
628 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | ||
629 | 2, 1); | ||
630 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | ||
631 | 2, 2); | ||
632 | static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp, | ||
633 | set_temp, 2, 3); | ||
634 | |||
635 | static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr, | ||
636 | char *buf) | ||
624 | { | 637 | { |
625 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 638 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
626 | int nr = sensor_attr->index; | 639 | int nr = sensor_attr->index; |
627 | struct it87_data *data = it87_update_device(dev); | 640 | struct it87_data *data = it87_update_device(dev); |
628 | u8 reg = data->sensor; /* In case value is updated while used */ | 641 | u8 reg = data->sensor; /* In case value is updated while used */ |
642 | u8 extra = data->extra; | ||
629 | 643 | ||
644 | if ((has_temp_peci(data, nr) && (reg >> 6 == nr + 1)) | ||
645 | || (has_temp_old_peci(data, nr) && (extra & 0x80))) | ||
646 | return sprintf(buf, "6\n"); /* Intel PECI */ | ||
630 | if (reg & (1 << nr)) | 647 | if (reg & (1 << nr)) |
631 | return sprintf(buf, "3\n"); /* thermal diode */ | 648 | return sprintf(buf, "3\n"); /* thermal diode */ |
632 | if (reg & (8 << nr)) | 649 | if (reg & (8 << nr)) |
633 | return sprintf(buf, "4\n"); /* thermistor */ | 650 | return sprintf(buf, "4\n"); /* thermistor */ |
634 | return sprintf(buf, "0\n"); /* disabled */ | 651 | return sprintf(buf, "0\n"); /* disabled */ |
635 | } | 652 | } |
636 | static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | 653 | |
637 | const char *buf, size_t count) | 654 | static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr, |
655 | const char *buf, size_t count) | ||
638 | { | 656 | { |
639 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 657 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
640 | int nr = sensor_attr->index; | 658 | int nr = sensor_attr->index; |
641 | 659 | ||
642 | struct it87_data *data = dev_get_drvdata(dev); | 660 | struct it87_data *data = dev_get_drvdata(dev); |
643 | long val; | 661 | long val; |
644 | u8 reg; | 662 | u8 reg, extra; |
645 | 663 | ||
646 | if (kstrtol(buf, 10, &val) < 0) | 664 | if (kstrtol(buf, 10, &val) < 0) |
647 | return -EINVAL; | 665 | return -EINVAL; |
@@ -649,33 +667,45 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
649 | reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 667 | reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
650 | reg &= ~(1 << nr); | 668 | reg &= ~(1 << nr); |
651 | reg &= ~(8 << nr); | 669 | reg &= ~(8 << nr); |
670 | if (has_temp_peci(data, nr) && (reg >> 6 == nr + 1 || val == 6)) | ||
671 | reg &= 0x3f; | ||
672 | extra = it87_read_value(data, IT87_REG_TEMP_EXTRA); | ||
673 | if (has_temp_old_peci(data, nr) && ((extra & 0x80) || val == 6)) | ||
674 | extra &= 0x7f; | ||
652 | if (val == 2) { /* backwards compatibility */ | 675 | if (val == 2) { /* backwards compatibility */ |
653 | dev_warn(dev, "Sensor type 2 is deprecated, please use 4 " | 676 | dev_warn(dev, |
654 | "instead\n"); | 677 | "Sensor type 2 is deprecated, please use 4 instead\n"); |
655 | val = 4; | 678 | val = 4; |
656 | } | 679 | } |
657 | /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ | 680 | /* 3 = thermal diode; 4 = thermistor; 6 = Intel PECI; 0 = disabled */ |
658 | if (val == 3) | 681 | if (val == 3) |
659 | reg |= 1 << nr; | 682 | reg |= 1 << nr; |
660 | else if (val == 4) | 683 | else if (val == 4) |
661 | reg |= 8 << nr; | 684 | reg |= 8 << nr; |
685 | else if (has_temp_peci(data, nr) && val == 6) | ||
686 | reg |= (nr + 1) << 6; | ||
687 | else if (has_temp_old_peci(data, nr) && val == 6) | ||
688 | extra |= 0x80; | ||
662 | else if (val != 0) | 689 | else if (val != 0) |
663 | return -EINVAL; | 690 | return -EINVAL; |
664 | 691 | ||
665 | mutex_lock(&data->update_lock); | 692 | mutex_lock(&data->update_lock); |
666 | data->sensor = reg; | 693 | data->sensor = reg; |
694 | data->extra = extra; | ||
667 | it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); | 695 | it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); |
696 | if (has_temp_old_peci(data, nr)) | ||
697 | it87_write_value(data, IT87_REG_TEMP_EXTRA, data->extra); | ||
668 | data->valid = 0; /* Force cache refresh */ | 698 | data->valid = 0; /* Force cache refresh */ |
669 | mutex_unlock(&data->update_lock); | 699 | mutex_unlock(&data->update_lock); |
670 | return count; | 700 | return count; |
671 | } | 701 | } |
672 | #define show_sensor_offset(offset) \ | ||
673 | static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ | ||
674 | show_sensor, set_sensor, offset - 1); | ||
675 | 702 | ||
676 | show_sensor_offset(1); | 703 | static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type, |
677 | show_sensor_offset(2); | 704 | set_temp_type, 0); |
678 | show_sensor_offset(3); | 705 | static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type, |
706 | set_temp_type, 1); | ||
707 | static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type, | ||
708 | set_temp_type, 2); | ||
679 | 709 | ||
680 | /* 3 Fans */ | 710 | /* 3 Fans */ |
681 | 711 | ||
@@ -692,25 +722,21 @@ static int pwm_mode(const struct it87_data *data, int nr) | |||
692 | } | 722 | } |
693 | 723 | ||
694 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | 724 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, |
695 | char *buf) | 725 | char *buf) |
696 | { | 726 | { |
697 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 727 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
698 | int nr = sensor_attr->index; | 728 | int nr = sattr->nr; |
699 | 729 | int index = sattr->index; | |
730 | int speed; | ||
700 | struct it87_data *data = it87_update_device(dev); | 731 | struct it87_data *data = it87_update_device(dev); |
701 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | ||
702 | DIV_FROM_REG(data->fan_div[nr]))); | ||
703 | } | ||
704 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | ||
705 | char *buf) | ||
706 | { | ||
707 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
708 | int nr = sensor_attr->index; | ||
709 | 732 | ||
710 | struct it87_data *data = it87_update_device(dev); | 733 | speed = has_16bit_fans(data) ? |
711 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], | 734 | FAN16_FROM_REG(data->fan[nr][index]) : |
712 | DIV_FROM_REG(data->fan_div[nr]))); | 735 | FAN_FROM_REG(data->fan[nr][index], |
736 | DIV_FROM_REG(data->fan_div[nr])); | ||
737 | return sprintf(buf, "%d\n", speed); | ||
713 | } | 738 | } |
739 | |||
714 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, | 740 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, |
715 | char *buf) | 741 | char *buf) |
716 | { | 742 | { |
@@ -747,11 +773,13 @@ static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, | |||
747 | 773 | ||
748 | return sprintf(buf, "%u\n", pwm_freq[index]); | 774 | return sprintf(buf, "%u\n", pwm_freq[index]); |
749 | } | 775 | } |
750 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | 776 | |
751 | const char *buf, size_t count) | 777 | static ssize_t set_fan(struct device *dev, struct device_attribute *attr, |
778 | const char *buf, size_t count) | ||
752 | { | 779 | { |
753 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 780 | struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); |
754 | int nr = sensor_attr->index; | 781 | int nr = sattr->nr; |
782 | int index = sattr->index; | ||
755 | 783 | ||
756 | struct it87_data *data = dev_get_drvdata(dev); | 784 | struct it87_data *data = dev_get_drvdata(dev); |
757 | long val; | 785 | long val; |
@@ -761,24 +789,36 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
761 | return -EINVAL; | 789 | return -EINVAL; |
762 | 790 | ||
763 | mutex_lock(&data->update_lock); | 791 | mutex_lock(&data->update_lock); |
764 | reg = it87_read_value(data, IT87_REG_FAN_DIV); | 792 | |
765 | switch (nr) { | 793 | if (has_16bit_fans(data)) { |
766 | case 0: | 794 | data->fan[nr][index] = FAN16_TO_REG(val); |
767 | data->fan_div[nr] = reg & 0x07; | 795 | it87_write_value(data, IT87_REG_FAN_MIN[nr], |
768 | break; | 796 | data->fan[nr][index] & 0xff); |
769 | case 1: | 797 | it87_write_value(data, IT87_REG_FANX_MIN[nr], |
770 | data->fan_div[nr] = (reg >> 3) & 0x07; | 798 | data->fan[nr][index] >> 8); |
771 | break; | 799 | } else { |
772 | case 2: | 800 | reg = it87_read_value(data, IT87_REG_FAN_DIV); |
773 | data->fan_div[nr] = (reg & 0x40) ? 3 : 1; | 801 | switch (nr) { |
774 | break; | 802 | case 0: |
803 | data->fan_div[nr] = reg & 0x07; | ||
804 | break; | ||
805 | case 1: | ||
806 | data->fan_div[nr] = (reg >> 3) & 0x07; | ||
807 | break; | ||
808 | case 2: | ||
809 | data->fan_div[nr] = (reg & 0x40) ? 3 : 1; | ||
810 | break; | ||
811 | } | ||
812 | data->fan[nr][index] = | ||
813 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | ||
814 | it87_write_value(data, IT87_REG_FAN_MIN[nr], | ||
815 | data->fan[nr][index]); | ||
775 | } | 816 | } |
776 | 817 | ||
777 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | ||
778 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]); | ||
779 | mutex_unlock(&data->update_lock); | 818 | mutex_unlock(&data->update_lock); |
780 | return count; | 819 | return count; |
781 | } | 820 | } |
821 | |||
782 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | 822 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, |
783 | const char *buf, size_t count) | 823 | const char *buf, size_t count) |
784 | { | 824 | { |
@@ -797,7 +837,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
797 | old = it87_read_value(data, IT87_REG_FAN_DIV); | 837 | old = it87_read_value(data, IT87_REG_FAN_DIV); |
798 | 838 | ||
799 | /* Save fan min limit */ | 839 | /* Save fan min limit */ |
800 | min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); | 840 | min = FAN_FROM_REG(data->fan[nr][1], DIV_FROM_REG(data->fan_div[nr])); |
801 | 841 | ||
802 | switch (nr) { | 842 | switch (nr) { |
803 | case 0: | 843 | case 0: |
@@ -818,8 +858,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
818 | it87_write_value(data, IT87_REG_FAN_DIV, val); | 858 | it87_write_value(data, IT87_REG_FAN_DIV, val); |
819 | 859 | ||
820 | /* Restore fan min limit */ | 860 | /* Restore fan min limit */ |
821 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 861 | data->fan[nr][1] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
822 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]); | 862 | it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan[nr][1]); |
823 | 863 | ||
824 | mutex_unlock(&data->update_lock); | 864 | mutex_unlock(&data->update_lock); |
825 | return count; | 865 | return count; |
@@ -843,8 +883,8 @@ static int check_trip_points(struct device *dev, int nr) | |||
843 | } | 883 | } |
844 | 884 | ||
845 | if (err) { | 885 | if (err) { |
846 | dev_err(dev, "Inconsistent trip points, not switching to " | 886 | dev_err(dev, |
847 | "automatic mode\n"); | 887 | "Inconsistent trip points, not switching to automatic mode\n"); |
848 | dev_err(dev, "Adjust the trip points and try again\n"); | 888 | dev_err(dev, "Adjust the trip points and try again\n"); |
849 | } | 889 | } |
850 | return err; | 890 | return err; |
@@ -1092,118 +1132,106 @@ static ssize_t set_auto_temp(struct device *dev, | |||
1092 | return count; | 1132 | return count; |
1093 | } | 1133 | } |
1094 | 1134 | ||
1095 | #define show_fan_offset(offset) \ | 1135 | static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0); |
1096 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | 1136 | static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
1097 | show_fan, NULL, offset - 1); \ | 1137 | 0, 1); |
1098 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | 1138 | static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div, |
1099 | show_fan_min, set_fan_min, offset - 1); \ | 1139 | set_fan_div, 0); |
1100 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | 1140 | |
1101 | show_fan_div, set_fan_div, offset - 1); | 1141 | static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, 0); |
1102 | 1142 | static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | |
1103 | show_fan_offset(1); | 1143 | 1, 1); |
1104 | show_fan_offset(2); | 1144 | static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, show_fan_div, |
1105 | show_fan_offset(3); | 1145 | set_fan_div, 1); |
1106 | 1146 | ||
1107 | #define show_pwm_offset(offset) \ | 1147 | static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, 0); |
1108 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ | 1148 | static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
1109 | show_pwm_enable, set_pwm_enable, offset - 1); \ | 1149 | 2, 1); |
1110 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | 1150 | static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, show_fan_div, |
1111 | show_pwm, set_pwm, offset - 1); \ | 1151 | set_fan_div, 2); |
1112 | static DEVICE_ATTR(pwm##offset##_freq, \ | 1152 | |
1113 | (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \ | 1153 | static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, 0); |
1114 | show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); \ | 1154 | static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
1115 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels_temp, \ | 1155 | 3, 1); |
1116 | S_IRUGO | S_IWUSR, show_pwm_temp_map, set_pwm_temp_map, \ | 1156 | |
1117 | offset - 1); \ | 1157 | static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, 0); |
1118 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_pwm, \ | 1158 | static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
1119 | S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \ | 1159 | 4, 1); |
1120 | offset - 1, 0); \ | 1160 | |
1121 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_pwm, \ | 1161 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, |
1122 | S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \ | 1162 | show_pwm_enable, set_pwm_enable, 0); |
1123 | offset - 1, 1); \ | 1163 | static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0); |
1124 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_pwm, \ | 1164 | static DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq, set_pwm_freq); |
1125 | S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \ | 1165 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR, |
1126 | offset - 1, 2); \ | 1166 | show_pwm_temp_map, set_pwm_temp_map, 0); |
1127 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_pwm, \ | 1167 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, |
1128 | S_IRUGO, show_auto_pwm, NULL, offset - 1, 3); \ | 1168 | show_auto_pwm, set_auto_pwm, 0, 0); |
1129 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp, \ | 1169 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, |
1130 | S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \ | 1170 | show_auto_pwm, set_auto_pwm, 0, 1); |
1131 | offset - 1, 1); \ | 1171 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR, |
1132 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp_hyst, \ | 1172 | show_auto_pwm, set_auto_pwm, 0, 2); |
1133 | S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \ | 1173 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO, |
1134 | offset - 1, 0); \ | 1174 | show_auto_pwm, NULL, 0, 3); |
1135 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_temp, \ | 1175 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR, |
1136 | S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \ | 1176 | show_auto_temp, set_auto_temp, 0, 1); |
1137 | offset - 1, 2); \ | 1177 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, |
1138 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_temp, \ | 1178 | show_auto_temp, set_auto_temp, 0, 0); |
1139 | S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \ | 1179 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR, |
1140 | offset - 1, 3); \ | 1180 | show_auto_temp, set_auto_temp, 0, 2); |
1141 | static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_temp, \ | 1181 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR, |
1142 | S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \ | 1182 | show_auto_temp, set_auto_temp, 0, 3); |
1143 | offset - 1, 4); | 1183 | static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR, |
1144 | 1184 | show_auto_temp, set_auto_temp, 0, 4); | |
1145 | show_pwm_offset(1); | 1185 | |
1146 | show_pwm_offset(2); | 1186 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, |
1147 | show_pwm_offset(3); | 1187 | show_pwm_enable, set_pwm_enable, 1); |
1148 | 1188 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1); | |
1149 | /* A different set of callbacks for 16-bit fans */ | 1189 | static DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, NULL); |
1150 | static ssize_t show_fan16(struct device *dev, struct device_attribute *attr, | 1190 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR, |
1151 | char *buf) | 1191 | show_pwm_temp_map, set_pwm_temp_map, 1); |
1152 | { | 1192 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, |
1153 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1193 | show_auto_pwm, set_auto_pwm, 1, 0); |
1154 | int nr = sensor_attr->index; | 1194 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR, |
1155 | struct it87_data *data = it87_update_device(dev); | 1195 | show_auto_pwm, set_auto_pwm, 1, 1); |
1156 | return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan[nr])); | 1196 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO | S_IWUSR, |
1157 | } | 1197 | show_auto_pwm, set_auto_pwm, 1, 2); |
1158 | 1198 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO, | |
1159 | static ssize_t show_fan16_min(struct device *dev, struct device_attribute *attr, | 1199 | show_auto_pwm, NULL, 1, 3); |
1160 | char *buf) | 1200 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR, |
1161 | { | 1201 | show_auto_temp, set_auto_temp, 1, 1); |
1162 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1202 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, |
1163 | int nr = sensor_attr->index; | 1203 | show_auto_temp, set_auto_temp, 1, 0); |
1164 | struct it87_data *data = it87_update_device(dev); | 1204 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR, |
1165 | return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan_min[nr])); | 1205 | show_auto_temp, set_auto_temp, 1, 2); |
1166 | } | 1206 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR, |
1167 | 1207 | show_auto_temp, set_auto_temp, 1, 3); | |
1168 | static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, | 1208 | static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR, |
1169 | const char *buf, size_t count) | 1209 | show_auto_temp, set_auto_temp, 1, 4); |
1170 | { | 1210 | |
1171 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | 1211 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, |
1172 | int nr = sensor_attr->index; | 1212 | show_pwm_enable, set_pwm_enable, 2); |
1173 | struct it87_data *data = dev_get_drvdata(dev); | 1213 | static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2); |
1174 | long val; | 1214 | static DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL); |
1175 | 1215 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR, | |
1176 | if (kstrtol(buf, 10, &val) < 0) | 1216 | show_pwm_temp_map, set_pwm_temp_map, 2); |
1177 | return -EINVAL; | 1217 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, |
1178 | 1218 | show_auto_pwm, set_auto_pwm, 2, 0); | |
1179 | mutex_lock(&data->update_lock); | 1219 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, |
1180 | data->fan_min[nr] = FAN16_TO_REG(val); | 1220 | show_auto_pwm, set_auto_pwm, 2, 1); |
1181 | it87_write_value(data, IT87_REG_FAN_MIN[nr], | 1221 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO | S_IWUSR, |
1182 | data->fan_min[nr] & 0xff); | 1222 | show_auto_pwm, set_auto_pwm, 2, 2); |
1183 | it87_write_value(data, IT87_REG_FANX_MIN[nr], | 1223 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO, |
1184 | data->fan_min[nr] >> 8); | 1224 | show_auto_pwm, NULL, 2, 3); |
1185 | mutex_unlock(&data->update_lock); | 1225 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR, |
1186 | return count; | 1226 | show_auto_temp, set_auto_temp, 2, 1); |
1187 | } | 1227 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO | S_IWUSR, |
1188 | 1228 | show_auto_temp, set_auto_temp, 2, 0); | |
1189 | /* | 1229 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR, |
1190 | * We want to use the same sysfs file names as 8-bit fans, but we need | 1230 | show_auto_temp, set_auto_temp, 2, 2); |
1191 | * different variable names, so we have to use SENSOR_ATTR instead of | 1231 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR, |
1192 | * SENSOR_DEVICE_ATTR. | 1232 | show_auto_temp, set_auto_temp, 2, 3); |
1193 | */ | 1233 | static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR, |
1194 | #define show_fan16_offset(offset) \ | 1234 | show_auto_temp, set_auto_temp, 2, 4); |
1195 | static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \ | ||
1196 | = SENSOR_ATTR(fan##offset##_input, S_IRUGO, \ | ||
1197 | show_fan16, NULL, offset - 1); \ | ||
1198 | static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \ | ||
1199 | = SENSOR_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
1200 | show_fan16_min, set_fan16_min, offset - 1) | ||
1201 | |||
1202 | show_fan16_offset(1); | ||
1203 | show_fan16_offset(2); | ||
1204 | show_fan16_offset(3); | ||
1205 | show_fan16_offset(4); | ||
1206 | show_fan16_offset(5); | ||
1207 | 1235 | ||
1208 | /* Alarms */ | 1236 | /* Alarms */ |
1209 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | 1237 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, |
@@ -1471,6 +1499,12 @@ static const struct attribute_group it87_group_temp[3] = { | |||
1471 | { .attrs = it87_attributes_temp[2] }, | 1499 | { .attrs = it87_attributes_temp[2] }, |
1472 | }; | 1500 | }; |
1473 | 1501 | ||
1502 | static struct attribute *it87_attributes_temp_offset[] = { | ||
1503 | &sensor_dev_attr_temp1_offset.dev_attr.attr, | ||
1504 | &sensor_dev_attr_temp2_offset.dev_attr.attr, | ||
1505 | &sensor_dev_attr_temp3_offset.dev_attr.attr, | ||
1506 | }; | ||
1507 | |||
1474 | static struct attribute *it87_attributes[] = { | 1508 | static struct attribute *it87_attributes[] = { |
1475 | &dev_attr_alarms.attr, | 1509 | &dev_attr_alarms.attr, |
1476 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, | 1510 | &sensor_dev_attr_intrusion0_alarm.dev_attr.attr, |
@@ -1500,73 +1534,47 @@ static struct attribute *it87_attributes_temp_beep[] = { | |||
1500 | &sensor_dev_attr_temp3_beep.dev_attr.attr, | 1534 | &sensor_dev_attr_temp3_beep.dev_attr.attr, |
1501 | }; | 1535 | }; |
1502 | 1536 | ||
1503 | static struct attribute *it87_attributes_fan16[5][3+1] = { { | 1537 | static struct attribute *it87_attributes_fan[5][3+1] = { { |
1504 | &sensor_dev_attr_fan1_input16.dev_attr.attr, | 1538 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1505 | &sensor_dev_attr_fan1_min16.dev_attr.attr, | 1539 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1506 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | 1540 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
1507 | NULL | 1541 | NULL |
1508 | }, { | 1542 | }, { |
1509 | &sensor_dev_attr_fan2_input16.dev_attr.attr, | 1543 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1510 | &sensor_dev_attr_fan2_min16.dev_attr.attr, | 1544 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1511 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | 1545 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, |
1512 | NULL | 1546 | NULL |
1513 | }, { | 1547 | }, { |
1514 | &sensor_dev_attr_fan3_input16.dev_attr.attr, | 1548 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1515 | &sensor_dev_attr_fan3_min16.dev_attr.attr, | 1549 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1516 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | 1550 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, |
1517 | NULL | 1551 | NULL |
1518 | }, { | 1552 | }, { |
1519 | &sensor_dev_attr_fan4_input16.dev_attr.attr, | 1553 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1520 | &sensor_dev_attr_fan4_min16.dev_attr.attr, | 1554 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1521 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | 1555 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
1522 | NULL | 1556 | NULL |
1523 | }, { | 1557 | }, { |
1524 | &sensor_dev_attr_fan5_input16.dev_attr.attr, | 1558 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
1525 | &sensor_dev_attr_fan5_min16.dev_attr.attr, | 1559 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
1526 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | 1560 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, |
1527 | NULL | 1561 | NULL |
1528 | } }; | 1562 | } }; |
1529 | 1563 | ||
1530 | static const struct attribute_group it87_group_fan16[5] = { | 1564 | static const struct attribute_group it87_group_fan[5] = { |
1531 | { .attrs = it87_attributes_fan16[0] }, | 1565 | { .attrs = it87_attributes_fan[0] }, |
1532 | { .attrs = it87_attributes_fan16[1] }, | 1566 | { .attrs = it87_attributes_fan[1] }, |
1533 | { .attrs = it87_attributes_fan16[2] }, | 1567 | { .attrs = it87_attributes_fan[2] }, |
1534 | { .attrs = it87_attributes_fan16[3] }, | 1568 | { .attrs = it87_attributes_fan[3] }, |
1535 | { .attrs = it87_attributes_fan16[4] }, | 1569 | { .attrs = it87_attributes_fan[4] }, |
1536 | }; | 1570 | }; |
1537 | 1571 | ||
1538 | static struct attribute *it87_attributes_fan[3][4+1] = { { | 1572 | static const struct attribute *it87_attributes_fan_div[] = { |
1539 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
1540 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
1541 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 1573 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
1542 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
1543 | NULL | ||
1544 | }, { | ||
1545 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
1546 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
1547 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 1574 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
1548 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
1549 | NULL | ||
1550 | }, { | ||
1551 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
1552 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
1553 | &sensor_dev_attr_fan3_div.dev_attr.attr, | 1575 | &sensor_dev_attr_fan3_div.dev_attr.attr, |
1554 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
1555 | NULL | ||
1556 | } }; | ||
1557 | |||
1558 | static const struct attribute_group it87_group_fan[3] = { | ||
1559 | { .attrs = it87_attributes_fan[0] }, | ||
1560 | { .attrs = it87_attributes_fan[1] }, | ||
1561 | { .attrs = it87_attributes_fan[2] }, | ||
1562 | }; | 1576 | }; |
1563 | 1577 | ||
1564 | static const struct attribute_group * | ||
1565 | it87_get_fan_group(const struct it87_data *data) | ||
1566 | { | ||
1567 | return has_16bit_fans(data) ? it87_group_fan16 : it87_group_fan; | ||
1568 | } | ||
1569 | |||
1570 | static struct attribute *it87_attributes_pwm[3][4+1] = { { | 1578 | static struct attribute *it87_attributes_pwm[3][4+1] = { { |
1571 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 1579 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
1572 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1580 | &sensor_dev_attr_pwm1.dev_attr.attr, |
@@ -1925,7 +1933,6 @@ static void it87_remove_files(struct device *dev) | |||
1925 | { | 1933 | { |
1926 | struct it87_data *data = platform_get_drvdata(pdev); | 1934 | struct it87_data *data = platform_get_drvdata(pdev); |
1927 | struct it87_sio_data *sio_data = dev->platform_data; | 1935 | struct it87_sio_data *sio_data = dev->platform_data; |
1928 | const struct attribute_group *fan_group = it87_get_fan_group(data); | ||
1929 | int i; | 1936 | int i; |
1930 | 1937 | ||
1931 | sysfs_remove_group(&dev->kobj, &it87_group); | 1938 | sysfs_remove_group(&dev->kobj, &it87_group); |
@@ -1941,6 +1948,9 @@ static void it87_remove_files(struct device *dev) | |||
1941 | if (!(data->has_temp & (1 << i))) | 1948 | if (!(data->has_temp & (1 << i))) |
1942 | continue; | 1949 | continue; |
1943 | sysfs_remove_group(&dev->kobj, &it87_group_temp[i]); | 1950 | sysfs_remove_group(&dev->kobj, &it87_group_temp[i]); |
1951 | if (has_temp_offset(data)) | ||
1952 | sysfs_remove_file(&dev->kobj, | ||
1953 | it87_attributes_temp_offset[i]); | ||
1944 | if (sio_data->beep_pin) | 1954 | if (sio_data->beep_pin) |
1945 | sysfs_remove_file(&dev->kobj, | 1955 | sysfs_remove_file(&dev->kobj, |
1946 | it87_attributes_temp_beep[i]); | 1956 | it87_attributes_temp_beep[i]); |
@@ -1948,10 +1958,13 @@ static void it87_remove_files(struct device *dev) | |||
1948 | for (i = 0; i < 5; i++) { | 1958 | for (i = 0; i < 5; i++) { |
1949 | if (!(data->has_fan & (1 << i))) | 1959 | if (!(data->has_fan & (1 << i))) |
1950 | continue; | 1960 | continue; |
1951 | sysfs_remove_group(&dev->kobj, &fan_group[i]); | 1961 | sysfs_remove_group(&dev->kobj, &it87_group_fan[i]); |
1952 | if (sio_data->beep_pin) | 1962 | if (sio_data->beep_pin) |
1953 | sysfs_remove_file(&dev->kobj, | 1963 | sysfs_remove_file(&dev->kobj, |
1954 | it87_attributes_fan_beep[i]); | 1964 | it87_attributes_fan_beep[i]); |
1965 | if (i < 3 && !has_16bit_fans(data)) | ||
1966 | sysfs_remove_file(&dev->kobj, | ||
1967 | it87_attributes_fan_div[i]); | ||
1955 | } | 1968 | } |
1956 | for (i = 0; i < 3; i++) { | 1969 | for (i = 0; i < 3; i++) { |
1957 | if (sio_data->skip_pwm & (1 << 0)) | 1970 | if (sio_data->skip_pwm & (1 << 0)) |
@@ -1972,21 +1985,9 @@ static int it87_probe(struct platform_device *pdev) | |||
1972 | struct resource *res; | 1985 | struct resource *res; |
1973 | struct device *dev = &pdev->dev; | 1986 | struct device *dev = &pdev->dev; |
1974 | struct it87_sio_data *sio_data = dev->platform_data; | 1987 | struct it87_sio_data *sio_data = dev->platform_data; |
1975 | const struct attribute_group *fan_group; | ||
1976 | int err = 0, i; | 1988 | int err = 0, i; |
1977 | int enable_pwm_interface; | 1989 | int enable_pwm_interface; |
1978 | int fan_beep_need_rw; | 1990 | int fan_beep_need_rw; |
1979 | static const char * const names[] = { | ||
1980 | "it87", | ||
1981 | "it8712", | ||
1982 | "it8716", | ||
1983 | "it8718", | ||
1984 | "it8720", | ||
1985 | "it8721", | ||
1986 | "it8728", | ||
1987 | "it8782", | ||
1988 | "it8783", | ||
1989 | }; | ||
1990 | 1991 | ||
1991 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1992 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1992 | if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT, | 1993 | if (!devm_request_region(&pdev->dev, res->start, IT87_EC_EXTENT, |
@@ -2003,8 +2004,31 @@ static int it87_probe(struct platform_device *pdev) | |||
2003 | 2004 | ||
2004 | data->addr = res->start; | 2005 | data->addr = res->start; |
2005 | data->type = sio_data->type; | 2006 | data->type = sio_data->type; |
2006 | data->revision = sio_data->revision; | 2007 | data->features = it87_devices[sio_data->type].features; |
2007 | data->name = names[sio_data->type]; | 2008 | data->peci_mask = it87_devices[sio_data->type].peci_mask; |
2009 | data->old_peci_mask = it87_devices[sio_data->type].old_peci_mask; | ||
2010 | data->name = it87_devices[sio_data->type].name; | ||
2011 | /* | ||
2012 | * IT8705F Datasheet 0.4.1, 3h == Version G. | ||
2013 | * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. | ||
2014 | * These are the first revisions with 16-bit tachometer support. | ||
2015 | */ | ||
2016 | switch (data->type) { | ||
2017 | case it87: | ||
2018 | if (sio_data->revision >= 0x03) { | ||
2019 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
2020 | data->features |= FEAT_16BIT_FANS; | ||
2021 | } | ||
2022 | break; | ||
2023 | case it8712: | ||
2024 | if (sio_data->revision >= 0x08) { | ||
2025 | data->features &= ~FEAT_OLD_AUTOPWM; | ||
2026 | data->features |= FEAT_16BIT_FANS; | ||
2027 | } | ||
2028 | break; | ||
2029 | default: | ||
2030 | break; | ||
2031 | } | ||
2008 | 2032 | ||
2009 | /* Now, we do the remaining detection. */ | 2033 | /* Now, we do the remaining detection. */ |
2010 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) | 2034 | if ((it87_read_value(data, IT87_REG_CONFIG) & 0x80) |
@@ -2068,6 +2092,12 @@ static int it87_probe(struct platform_device *pdev) | |||
2068 | err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]); | 2092 | err = sysfs_create_group(&dev->kobj, &it87_group_temp[i]); |
2069 | if (err) | 2093 | if (err) |
2070 | goto error; | 2094 | goto error; |
2095 | if (has_temp_offset(data)) { | ||
2096 | err = sysfs_create_file(&dev->kobj, | ||
2097 | it87_attributes_temp_offset[i]); | ||
2098 | if (err) | ||
2099 | goto error; | ||
2100 | } | ||
2071 | if (sio_data->beep_pin) { | 2101 | if (sio_data->beep_pin) { |
2072 | err = sysfs_create_file(&dev->kobj, | 2102 | err = sysfs_create_file(&dev->kobj, |
2073 | it87_attributes_temp_beep[i]); | 2103 | it87_attributes_temp_beep[i]); |
@@ -2077,15 +2107,21 @@ static int it87_probe(struct platform_device *pdev) | |||
2077 | } | 2107 | } |
2078 | 2108 | ||
2079 | /* Do not create fan files for disabled fans */ | 2109 | /* Do not create fan files for disabled fans */ |
2080 | fan_group = it87_get_fan_group(data); | ||
2081 | fan_beep_need_rw = 1; | 2110 | fan_beep_need_rw = 1; |
2082 | for (i = 0; i < 5; i++) { | 2111 | for (i = 0; i < 5; i++) { |
2083 | if (!(data->has_fan & (1 << i))) | 2112 | if (!(data->has_fan & (1 << i))) |
2084 | continue; | 2113 | continue; |
2085 | err = sysfs_create_group(&dev->kobj, &fan_group[i]); | 2114 | err = sysfs_create_group(&dev->kobj, &it87_group_fan[i]); |
2086 | if (err) | 2115 | if (err) |
2087 | goto error; | 2116 | goto error; |
2088 | 2117 | ||
2118 | if (i < 3 && !has_16bit_fans(data)) { | ||
2119 | err = sysfs_create_file(&dev->kobj, | ||
2120 | it87_attributes_fan_div[i]); | ||
2121 | if (err) | ||
2122 | goto error; | ||
2123 | } | ||
2124 | |||
2089 | if (sio_data->beep_pin) { | 2125 | if (sio_data->beep_pin) { |
2090 | err = sysfs_create_file(&dev->kobj, | 2126 | err = sysfs_create_file(&dev->kobj, |
2091 | it87_attributes_fan_beep[i]); | 2127 | it87_attributes_fan_beep[i]); |
@@ -2221,8 +2257,8 @@ static int it87_check_pwm(struct device *dev) | |||
2221 | * PWM interface). | 2257 | * PWM interface). |
2222 | */ | 2258 | */ |
2223 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { | 2259 | if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { |
2224 | dev_info(dev, "Reconfiguring PWM to " | 2260 | dev_info(dev, |
2225 | "active high polarity\n"); | 2261 | "Reconfiguring PWM to active high polarity\n"); |
2226 | it87_write_value(data, IT87_REG_FAN_CTL, | 2262 | it87_write_value(data, IT87_REG_FAN_CTL, |
2227 | tmp | 0x87); | 2263 | tmp | 0x87); |
2228 | for (i = 0; i < 3; i++) | 2264 | for (i = 0; i < 3; i++) |
@@ -2232,16 +2268,16 @@ static int it87_check_pwm(struct device *dev) | |||
2232 | return 1; | 2268 | return 1; |
2233 | } | 2269 | } |
2234 | 2270 | ||
2235 | dev_info(dev, "PWM configuration is " | 2271 | dev_info(dev, |
2236 | "too broken to be fixed\n"); | 2272 | "PWM configuration is too broken to be fixed\n"); |
2237 | } | 2273 | } |
2238 | 2274 | ||
2239 | dev_info(dev, "Detected broken BIOS " | 2275 | dev_info(dev, |
2240 | "defaults, disabling PWM interface\n"); | 2276 | "Detected broken BIOS defaults, disabling PWM interface\n"); |
2241 | return 0; | 2277 | return 0; |
2242 | } else if (fix_pwm_polarity) { | 2278 | } else if (fix_pwm_polarity) { |
2243 | dev_info(dev, "PWM configuration looks " | 2279 | dev_info(dev, |
2244 | "sane, won't touch\n"); | 2280 | "PWM configuration looks sane, won't touch\n"); |
2245 | } | 2281 | } |
2246 | 2282 | ||
2247 | return 1; | 2283 | return 1; |
@@ -2389,42 +2425,46 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
2389 | it87_read_value(data, IT87_REG_CONFIG) | 0x40); | 2425 | it87_read_value(data, IT87_REG_CONFIG) | 0x40); |
2390 | } | 2426 | } |
2391 | for (i = 0; i <= 7; i++) { | 2427 | for (i = 0; i <= 7; i++) { |
2392 | data->in[i] = | 2428 | data->in[i][0] = |
2393 | it87_read_value(data, IT87_REG_VIN(i)); | 2429 | it87_read_value(data, IT87_REG_VIN(i)); |
2394 | data->in_min[i] = | 2430 | data->in[i][1] = |
2395 | it87_read_value(data, IT87_REG_VIN_MIN(i)); | 2431 | it87_read_value(data, IT87_REG_VIN_MIN(i)); |
2396 | data->in_max[i] = | 2432 | data->in[i][2] = |
2397 | it87_read_value(data, IT87_REG_VIN_MAX(i)); | 2433 | it87_read_value(data, IT87_REG_VIN_MAX(i)); |
2398 | } | 2434 | } |
2399 | /* in8 (battery) has no limit registers */ | 2435 | /* in8 (battery) has no limit registers */ |
2400 | data->in[8] = it87_read_value(data, IT87_REG_VIN(8)); | 2436 | data->in[8][0] = it87_read_value(data, IT87_REG_VIN(8)); |
2401 | 2437 | ||
2402 | for (i = 0; i < 5; i++) { | 2438 | for (i = 0; i < 5; i++) { |
2403 | /* Skip disabled fans */ | 2439 | /* Skip disabled fans */ |
2404 | if (!(data->has_fan & (1 << i))) | 2440 | if (!(data->has_fan & (1 << i))) |
2405 | continue; | 2441 | continue; |
2406 | 2442 | ||
2407 | data->fan_min[i] = | 2443 | data->fan[i][1] = |
2408 | it87_read_value(data, IT87_REG_FAN_MIN[i]); | 2444 | it87_read_value(data, IT87_REG_FAN_MIN[i]); |
2409 | data->fan[i] = it87_read_value(data, | 2445 | data->fan[i][0] = it87_read_value(data, |
2410 | IT87_REG_FAN[i]); | 2446 | IT87_REG_FAN[i]); |
2411 | /* Add high byte if in 16-bit mode */ | 2447 | /* Add high byte if in 16-bit mode */ |
2412 | if (has_16bit_fans(data)) { | 2448 | if (has_16bit_fans(data)) { |
2413 | data->fan[i] |= it87_read_value(data, | 2449 | data->fan[i][0] |= it87_read_value(data, |
2414 | IT87_REG_FANX[i]) << 8; | 2450 | IT87_REG_FANX[i]) << 8; |
2415 | data->fan_min[i] |= it87_read_value(data, | 2451 | data->fan[i][1] |= it87_read_value(data, |
2416 | IT87_REG_FANX_MIN[i]) << 8; | 2452 | IT87_REG_FANX_MIN[i]) << 8; |
2417 | } | 2453 | } |
2418 | } | 2454 | } |
2419 | for (i = 0; i < 3; i++) { | 2455 | for (i = 0; i < 3; i++) { |
2420 | if (!(data->has_temp & (1 << i))) | 2456 | if (!(data->has_temp & (1 << i))) |
2421 | continue; | 2457 | continue; |
2422 | data->temp[i] = | 2458 | data->temp[i][0] = |
2423 | it87_read_value(data, IT87_REG_TEMP(i)); | 2459 | it87_read_value(data, IT87_REG_TEMP(i)); |
2424 | data->temp_high[i] = | 2460 | data->temp[i][1] = |
2425 | it87_read_value(data, IT87_REG_TEMP_HIGH(i)); | ||
2426 | data->temp_low[i] = | ||
2427 | it87_read_value(data, IT87_REG_TEMP_LOW(i)); | 2461 | it87_read_value(data, IT87_REG_TEMP_LOW(i)); |
2462 | data->temp[i][2] = | ||
2463 | it87_read_value(data, IT87_REG_TEMP_HIGH(i)); | ||
2464 | if (has_temp_offset(data)) | ||
2465 | data->temp[i][3] = | ||
2466 | it87_read_value(data, | ||
2467 | IT87_REG_TEMP_OFFSET[i]); | ||
2428 | } | 2468 | } |
2429 | 2469 | ||
2430 | /* Newer chips don't have clock dividers */ | 2470 | /* Newer chips don't have clock dividers */ |
@@ -2448,6 +2488,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
2448 | it87_update_pwm_ctrl(data, i); | 2488 | it87_update_pwm_ctrl(data, i); |
2449 | 2489 | ||
2450 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 2490 | data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
2491 | data->extra = it87_read_value(data, IT87_REG_TEMP_EXTRA); | ||
2451 | /* | 2492 | /* |
2452 | * The IT8705F does not have VID capability. | 2493 | * The IT8705F does not have VID capability. |
2453 | * The IT8718F and later don't use IT87_REG_VID for the | 2494 | * The IT8718F and later don't use IT87_REG_VID for the |
@@ -2549,8 +2590,7 @@ static void __exit sm_it87_exit(void) | |||
2549 | } | 2590 | } |
2550 | 2591 | ||
2551 | 2592 | ||
2552 | MODULE_AUTHOR("Chris Gauthron, " | 2593 | MODULE_AUTHOR("Chris Gauthron, Jean Delvare <khali@linux-fr.org>"); |
2553 | "Jean Delvare <khali@linux-fr.org>"); | ||
2554 | MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver"); | 2594 | MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver"); |
2555 | module_param(update_vbat, bool, 0); | 2595 | module_param(update_vbat, bool, 0); |
2556 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); | 2596 | MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 55ac41c05561..0e8ffd6059a0 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * w83627ehf - Driver for the hardware monitoring functionality of | 2 | * w83627ehf - Driver for the hardware monitoring functionality of |
3 | * the Winbond W83627EHF Super-I/O chip | 3 | * the Winbond W83627EHF Super-I/O chip |
4 | * Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2005-2012 Jean Delvare <khali@linux-fr.org> |
5 | * Copyright (C) 2006 Yuan Mu (Winbond), | 5 | * Copyright (C) 2006 Yuan Mu (Winbond), |
6 | * Rudolf Marek <r.marek@assembler.cz> | 6 | * Rudolf Marek <r.marek@assembler.cz> |
7 | * David Hubbard <david.c.hubbard@gmail.com> | 7 | * David Hubbard <david.c.hubbard@gmail.com> |
@@ -502,6 +502,13 @@ struct w83627ehf_data { | |||
502 | u16 have_temp_offset; | 502 | u16 have_temp_offset; |
503 | u8 in6_skip:1; | 503 | u8 in6_skip:1; |
504 | u8 temp3_val_only:1; | 504 | u8 temp3_val_only:1; |
505 | |||
506 | #ifdef CONFIG_PM | ||
507 | /* Remember extra register values over suspend/resume */ | ||
508 | u8 vbat; | ||
509 | u8 fandiv1; | ||
510 | u8 fandiv2; | ||
511 | #endif | ||
505 | }; | 512 | }; |
506 | 513 | ||
507 | struct w83627ehf_sio_data { | 514 | struct w83627ehf_sio_data { |
@@ -898,6 +905,8 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
898 | data->temp_max_hyst[i] | 905 | data->temp_max_hyst[i] |
899 | = w83627ehf_read_temp(data, | 906 | = w83627ehf_read_temp(data, |
900 | data->reg_temp_hyst[i]); | 907 | data->reg_temp_hyst[i]); |
908 | if (i > 2) | ||
909 | continue; | ||
901 | if (data->have_temp_offset & (1 << i)) | 910 | if (data->have_temp_offset & (1 << i)) |
902 | data->temp_offset[i] | 911 | data->temp_offset[i] |
903 | = w83627ehf_read_value(data, | 912 | = w83627ehf_read_value(data, |
@@ -2608,10 +2617,98 @@ static int w83627ehf_remove(struct platform_device *pdev) | |||
2608 | return 0; | 2617 | return 0; |
2609 | } | 2618 | } |
2610 | 2619 | ||
2620 | #ifdef CONFIG_PM | ||
2621 | static int w83627ehf_suspend(struct device *dev) | ||
2622 | { | ||
2623 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | ||
2624 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | ||
2625 | |||
2626 | mutex_lock(&data->update_lock); | ||
2627 | data->vbat = w83627ehf_read_value(data, W83627EHF_REG_VBAT); | ||
2628 | if (sio_data->kind == nct6775) { | ||
2629 | data->fandiv1 = w83627ehf_read_value(data, NCT6775_REG_FANDIV1); | ||
2630 | data->fandiv2 = w83627ehf_read_value(data, NCT6775_REG_FANDIV2); | ||
2631 | } | ||
2632 | mutex_unlock(&data->update_lock); | ||
2633 | |||
2634 | return 0; | ||
2635 | } | ||
2636 | |||
2637 | static int w83627ehf_resume(struct device *dev) | ||
2638 | { | ||
2639 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
2640 | struct w83627ehf_sio_data *sio_data = dev->platform_data; | ||
2641 | int i; | ||
2642 | |||
2643 | mutex_lock(&data->update_lock); | ||
2644 | data->bank = 0xff; /* Force initial bank selection */ | ||
2645 | |||
2646 | /* Restore limits */ | ||
2647 | for (i = 0; i < data->in_num; i++) { | ||
2648 | if ((i == 6) && data->in6_skip) | ||
2649 | continue; | ||
2650 | |||
2651 | w83627ehf_write_value(data, W83627EHF_REG_IN_MIN(i), | ||
2652 | data->in_min[i]); | ||
2653 | w83627ehf_write_value(data, W83627EHF_REG_IN_MAX(i), | ||
2654 | data->in_max[i]); | ||
2655 | } | ||
2656 | |||
2657 | for (i = 0; i < 5; i++) { | ||
2658 | if (!(data->has_fan_min & (1 << i))) | ||
2659 | continue; | ||
2660 | |||
2661 | w83627ehf_write_value(data, data->REG_FAN_MIN[i], | ||
2662 | data->fan_min[i]); | ||
2663 | } | ||
2664 | |||
2665 | for (i = 0; i < NUM_REG_TEMP; i++) { | ||
2666 | if (!(data->have_temp & (1 << i))) | ||
2667 | continue; | ||
2668 | |||
2669 | if (data->reg_temp_over[i]) | ||
2670 | w83627ehf_write_temp(data, data->reg_temp_over[i], | ||
2671 | data->temp_max[i]); | ||
2672 | if (data->reg_temp_hyst[i]) | ||
2673 | w83627ehf_write_temp(data, data->reg_temp_hyst[i], | ||
2674 | data->temp_max_hyst[i]); | ||
2675 | if (i > 2) | ||
2676 | continue; | ||
2677 | if (data->have_temp_offset & (1 << i)) | ||
2678 | w83627ehf_write_value(data, | ||
2679 | W83627EHF_REG_TEMP_OFFSET[i], | ||
2680 | data->temp_offset[i]); | ||
2681 | } | ||
2682 | |||
2683 | /* Restore other settings */ | ||
2684 | w83627ehf_write_value(data, W83627EHF_REG_VBAT, data->vbat); | ||
2685 | if (sio_data->kind == nct6775) { | ||
2686 | w83627ehf_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1); | ||
2687 | w83627ehf_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); | ||
2688 | } | ||
2689 | |||
2690 | /* Force re-reading all values */ | ||
2691 | data->valid = 0; | ||
2692 | mutex_unlock(&data->update_lock); | ||
2693 | |||
2694 | return 0; | ||
2695 | } | ||
2696 | |||
2697 | static const struct dev_pm_ops w83627ehf_dev_pm_ops = { | ||
2698 | .suspend = w83627ehf_suspend, | ||
2699 | .resume = w83627ehf_resume, | ||
2700 | }; | ||
2701 | |||
2702 | #define W83627EHF_DEV_PM_OPS (&w83627ehf_dev_pm_ops) | ||
2703 | #else | ||
2704 | #define W83627EHF_DEV_PM_OPS NULL | ||
2705 | #endif /* CONFIG_PM */ | ||
2706 | |||
2611 | static struct platform_driver w83627ehf_driver = { | 2707 | static struct platform_driver w83627ehf_driver = { |
2612 | .driver = { | 2708 | .driver = { |
2613 | .owner = THIS_MODULE, | 2709 | .owner = THIS_MODULE, |
2614 | .name = DRVNAME, | 2710 | .name = DRVNAME, |
2711 | .pm = W83627EHF_DEV_PM_OPS, | ||
2615 | }, | 2712 | }, |
2616 | .probe = w83627ehf_probe, | 2713 | .probe = w83627ehf_probe, |
2617 | .remove = w83627ehf_remove, | 2714 | .remove = w83627ehf_remove, |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 7f68b8309d10..81f486520cea 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Philip Edelbrock <phil@netroedge.com>, | 5 | * Philip Edelbrock <phil@netroedge.com>, |
6 | * and Mark Studebaker <mdsxyz123@yahoo.com> | 6 | * and Mark Studebaker <mdsxyz123@yahoo.com> |
7 | * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org> | 7 | * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org> |
8 | * Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> | 8 | * Copyright (c) 2007 - 1012 Jean Delvare <khali@linux-fr.org> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -389,6 +389,12 @@ struct w83627hf_data { | |||
389 | */ | 389 | */ |
390 | u8 vrm; | 390 | u8 vrm; |
391 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ | 391 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ |
392 | |||
393 | #ifdef CONFIG_PM | ||
394 | /* Remember extra register values over suspend/resume */ | ||
395 | u8 scfg1; | ||
396 | u8 scfg2; | ||
397 | #endif | ||
392 | }; | 398 | }; |
393 | 399 | ||
394 | 400 | ||
@@ -401,10 +407,77 @@ static void w83627hf_update_fan_div(struct w83627hf_data *data); | |||
401 | static struct w83627hf_data *w83627hf_update_device(struct device *dev); | 407 | static struct w83627hf_data *w83627hf_update_device(struct device *dev); |
402 | static void w83627hf_init_device(struct platform_device *pdev); | 408 | static void w83627hf_init_device(struct platform_device *pdev); |
403 | 409 | ||
410 | #ifdef CONFIG_PM | ||
411 | static int w83627hf_suspend(struct device *dev) | ||
412 | { | ||
413 | struct w83627hf_data *data = w83627hf_update_device(dev); | ||
414 | |||
415 | mutex_lock(&data->update_lock); | ||
416 | data->scfg1 = w83627hf_read_value(data, W83781D_REG_SCFG1); | ||
417 | data->scfg2 = w83627hf_read_value(data, W83781D_REG_SCFG2); | ||
418 | mutex_unlock(&data->update_lock); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int w83627hf_resume(struct device *dev) | ||
424 | { | ||
425 | struct w83627hf_data *data = dev_get_drvdata(dev); | ||
426 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; | ||
427 | |||
428 | /* Restore limits */ | ||
429 | mutex_lock(&data->update_lock); | ||
430 | for (i = 0; i <= 8; i++) { | ||
431 | /* skip missing sensors */ | ||
432 | if (((data->type == w83697hf) && (i == 1)) || | ||
433 | ((data->type != w83627hf && data->type != w83697hf) | ||
434 | && (i == 5 || i == 6))) | ||
435 | continue; | ||
436 | w83627hf_write_value(data, W83781D_REG_IN_MAX(i), | ||
437 | data->in_max[i]); | ||
438 | w83627hf_write_value(data, W83781D_REG_IN_MIN(i), | ||
439 | data->in_min[i]); | ||
440 | } | ||
441 | for (i = 0; i <= 2; i++) | ||
442 | w83627hf_write_value(data, W83627HF_REG_FAN_MIN(i), | ||
443 | data->fan_min[i]); | ||
444 | for (i = 0; i < num_temps; i++) { | ||
445 | w83627hf_write_value(data, w83627hf_reg_temp_over[i], | ||
446 | data->temp_max[i]); | ||
447 | w83627hf_write_value(data, w83627hf_reg_temp_hyst[i], | ||
448 | data->temp_max_hyst[i]); | ||
449 | } | ||
450 | |||
451 | /* Fixup BIOS bugs */ | ||
452 | if (data->type == w83627thf || data->type == w83637hf || | ||
453 | data->type == w83687thf) | ||
454 | w83627hf_write_value(data, W83627THF_REG_VRM_OVT_CFG, | ||
455 | data->vrm_ovt); | ||
456 | w83627hf_write_value(data, W83781D_REG_SCFG1, data->scfg1); | ||
457 | w83627hf_write_value(data, W83781D_REG_SCFG2, data->scfg2); | ||
458 | |||
459 | /* Force re-reading all values */ | ||
460 | data->valid = 0; | ||
461 | mutex_unlock(&data->update_lock); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static const struct dev_pm_ops w83627hf_dev_pm_ops = { | ||
467 | .suspend = w83627hf_suspend, | ||
468 | .resume = w83627hf_resume, | ||
469 | }; | ||
470 | |||
471 | #define W83627HF_DEV_PM_OPS (&w83627hf_dev_pm_ops) | ||
472 | #else | ||
473 | #define W83627HF_DEV_PM_OPS NULL | ||
474 | #endif /* CONFIG_PM */ | ||
475 | |||
404 | static struct platform_driver w83627hf_driver = { | 476 | static struct platform_driver w83627hf_driver = { |
405 | .driver = { | 477 | .driver = { |
406 | .owner = THIS_MODULE, | 478 | .owner = THIS_MODULE, |
407 | .name = DRVNAME, | 479 | .name = DRVNAME, |
480 | .pm = W83627HF_DEV_PM_OPS, | ||
408 | }, | 481 | }, |
409 | .probe = w83627hf_probe, | 482 | .probe = w83627hf_probe, |
410 | .remove = w83627hf_remove, | 483 | .remove = w83627hf_remove, |
@@ -1659,8 +1732,10 @@ static void w83627hf_init_device(struct platform_device *pdev) | |||
1659 | /* Minimize conflicts with other winbond i2c-only clients... */ | 1732 | /* Minimize conflicts with other winbond i2c-only clients... */ |
1660 | /* disable i2c subclients... how to disable main i2c client?? */ | 1733 | /* disable i2c subclients... how to disable main i2c client?? */ |
1661 | /* force i2c address to relatively uncommon address */ | 1734 | /* force i2c address to relatively uncommon address */ |
1662 | w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89); | 1735 | if (type == w83627hf) { |
1663 | w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c); | 1736 | w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89); |
1737 | w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c); | ||
1738 | } | ||
1664 | 1739 | ||
1665 | /* Read VID only once */ | 1740 | /* Read VID only once */ |
1666 | if (type == w83627hf || type == w83637hf) { | 1741 | if (type == w83627hf || type == w83637hf) { |
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index b5fdcb78a75b..a5ebc0083d87 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c | |||
@@ -225,7 +225,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user) | |||
225 | * eventfd (ie. the appropriate virtqueue thread)? | 225 | * eventfd (ie. the appropriate virtqueue thread)? |
226 | */ | 226 | */ |
227 | if (!send_notify_to_eventfd(cpu)) { | 227 | if (!send_notify_to_eventfd(cpu)) { |
228 | /* OK, we tell the main Laucher. */ | 228 | /* OK, we tell the main Launcher. */ |
229 | if (put_user(cpu->pending_notify, user)) | 229 | if (put_user(cpu->pending_notify, user)) |
230 | return -EFAULT; | 230 | return -EFAULT; |
231 | return sizeof(cpu->pending_notify); | 231 | return sizeof(cpu->pending_notify); |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 770a0d01e0b9..05164d7f054b 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <plat/cpu.h> | ||
29 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
30 | #include <linux/platform_data/usb-omap.h> | 29 | #include <linux/platform_data/usb-omap.h> |
31 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
@@ -384,7 +383,7 @@ static void omap_usbhs_init(struct device *dev) | |||
384 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | 383 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; |
385 | 384 | ||
386 | /* Bypass the TLL module for PHY mode operation */ | 385 | /* Bypass the TLL module for PHY mode operation */ |
387 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { | 386 | if (pdata->single_ulpi_bypass) { |
388 | dev_dbg(dev, "OMAP3 ES version <= ES2.1\n"); | 387 | dev_dbg(dev, "OMAP3 ES version <= ES2.1\n"); |
389 | if (is_ehci_phy_mode(pdata->port_mode[0]) || | 388 | if (is_ehci_phy_mode(pdata->port_mode[0]) || |
390 | is_ehci_phy_mode(pdata->port_mode[1]) || | 389 | is_ehci_phy_mode(pdata->port_mode[1]) || |
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index fec406b4553d..c071d410488f 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c | |||
@@ -322,7 +322,6 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, | |||
322 | int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, | 322 | int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, |
323 | int pnum, const struct ubi_vid_hdr *vid_hdr) | 323 | int pnum, const struct ubi_vid_hdr *vid_hdr) |
324 | { | 324 | { |
325 | void *buf; | ||
326 | int len, err, second_is_newer, bitflips = 0, corrupted = 0; | 325 | int len, err, second_is_newer, bitflips = 0, corrupted = 0; |
327 | uint32_t data_crc, crc; | 326 | uint32_t data_crc, crc; |
328 | struct ubi_vid_hdr *vh = NULL; | 327 | struct ubi_vid_hdr *vh = NULL; |
@@ -393,18 +392,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, | |||
393 | /* Read the data of the copy and check the CRC */ | 392 | /* Read the data of the copy and check the CRC */ |
394 | 393 | ||
395 | len = be32_to_cpu(vid_hdr->data_size); | 394 | len = be32_to_cpu(vid_hdr->data_size); |
396 | buf = vmalloc(len); | ||
397 | if (!buf) { | ||
398 | err = -ENOMEM; | ||
399 | goto out_free_vidh; | ||
400 | } | ||
401 | 395 | ||
402 | err = ubi_io_read_data(ubi, buf, pnum, 0, len); | 396 | mutex_lock(&ubi->buf_mutex); |
397 | err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, len); | ||
403 | if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) | 398 | if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) |
404 | goto out_free_buf; | 399 | goto out_unlock; |
405 | 400 | ||
406 | data_crc = be32_to_cpu(vid_hdr->data_crc); | 401 | data_crc = be32_to_cpu(vid_hdr->data_crc); |
407 | crc = crc32(UBI_CRC32_INIT, buf, len); | 402 | crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, len); |
408 | if (crc != data_crc) { | 403 | if (crc != data_crc) { |
409 | dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", | 404 | dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", |
410 | pnum, crc, data_crc); | 405 | pnum, crc, data_crc); |
@@ -415,8 +410,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, | |||
415 | dbg_bld("PEB %d CRC is OK", pnum); | 410 | dbg_bld("PEB %d CRC is OK", pnum); |
416 | bitflips = !!err; | 411 | bitflips = !!err; |
417 | } | 412 | } |
413 | mutex_unlock(&ubi->buf_mutex); | ||
418 | 414 | ||
419 | vfree(buf); | ||
420 | ubi_free_vid_hdr(ubi, vh); | 415 | ubi_free_vid_hdr(ubi, vh); |
421 | 416 | ||
422 | if (second_is_newer) | 417 | if (second_is_newer) |
@@ -426,8 +421,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, | |||
426 | 421 | ||
427 | return second_is_newer | (bitflips << 1) | (corrupted << 2); | 422 | return second_is_newer | (bitflips << 1) | (corrupted << 2); |
428 | 423 | ||
429 | out_free_buf: | 424 | out_unlock: |
430 | vfree(buf); | 425 | mutex_unlock(&ubi->buf_mutex); |
431 | out_free_vidh: | 426 | out_free_vidh: |
432 | ubi_free_vid_hdr(ubi, vh); | 427 | ubi_free_vid_hdr(ubi, vh); |
433 | return err; | 428 | return err; |
@@ -1453,7 +1448,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) | |||
1453 | goto out_wl; | 1448 | goto out_wl; |
1454 | 1449 | ||
1455 | #ifdef CONFIG_MTD_UBI_FASTMAP | 1450 | #ifdef CONFIG_MTD_UBI_FASTMAP |
1456 | if (ubi->fm && ubi->dbg->chk_gen) { | 1451 | if (ubi->fm && ubi_dbg_chk_gen(ubi)) { |
1457 | struct ubi_attach_info *scan_ai; | 1452 | struct ubi_attach_info *scan_ai; |
1458 | 1453 | ||
1459 | scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); | 1454 | scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); |
@@ -1503,7 +1498,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) | |||
1503 | struct ubi_ainf_peb *aeb, *last_aeb; | 1498 | struct ubi_ainf_peb *aeb, *last_aeb; |
1504 | uint8_t *buf; | 1499 | uint8_t *buf; |
1505 | 1500 | ||
1506 | if (!ubi->dbg->chk_gen) | 1501 | if (!ubi_dbg_chk_gen(ubi)) |
1507 | return 0; | 1502 | return 0; |
1508 | 1503 | ||
1509 | /* | 1504 | /* |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 344b4cb49d4e..a56133585e92 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -825,8 +825,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) | |||
825 | * No available PEBs to re-size the volume, clear the flag on | 825 | * No available PEBs to re-size the volume, clear the flag on |
826 | * flash and exit. | 826 | * flash and exit. |
827 | */ | 827 | */ |
828 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], | 828 | vtbl_rec = ubi->vtbl[vol_id]; |
829 | sizeof(struct ubi_vtbl_record)); | ||
830 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); | 829 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); |
831 | if (err) | 830 | if (err) |
832 | ubi_err("cannot clean auto-resize flag for volume %d", | 831 | ubi_err("cannot clean auto-resize flag for volume %d", |
@@ -986,14 +985,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, | |||
986 | if (!ubi->fm_buf) | 985 | if (!ubi->fm_buf) |
987 | goto out_free; | 986 | goto out_free; |
988 | #endif | 987 | #endif |
989 | err = ubi_debugging_init_dev(ubi); | ||
990 | if (err) | ||
991 | goto out_free; | ||
992 | |||
993 | err = ubi_attach(ubi, 0); | 988 | err = ubi_attach(ubi, 0); |
994 | if (err) { | 989 | if (err) { |
995 | ubi_err("failed to attach mtd%d, error %d", mtd->index, err); | 990 | ubi_err("failed to attach mtd%d, error %d", mtd->index, err); |
996 | goto out_debugging; | 991 | goto out_free; |
997 | } | 992 | } |
998 | 993 | ||
999 | if (ubi->autoresize_vol_id != -1) { | 994 | if (ubi->autoresize_vol_id != -1) { |
@@ -1060,8 +1055,6 @@ out_detach: | |||
1060 | ubi_wl_close(ubi); | 1055 | ubi_wl_close(ubi); |
1061 | ubi_free_internal_volumes(ubi); | 1056 | ubi_free_internal_volumes(ubi); |
1062 | vfree(ubi->vtbl); | 1057 | vfree(ubi->vtbl); |
1063 | out_debugging: | ||
1064 | ubi_debugging_exit_dev(ubi); | ||
1065 | out_free: | 1058 | out_free: |
1066 | vfree(ubi->peb_buf); | 1059 | vfree(ubi->peb_buf); |
1067 | vfree(ubi->fm_buf); | 1060 | vfree(ubi->fm_buf); |
@@ -1139,7 +1132,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
1139 | ubi_free_internal_volumes(ubi); | 1132 | ubi_free_internal_volumes(ubi); |
1140 | vfree(ubi->vtbl); | 1133 | vfree(ubi->vtbl); |
1141 | put_mtd_device(ubi->mtd); | 1134 | put_mtd_device(ubi->mtd); |
1142 | ubi_debugging_exit_dev(ubi); | ||
1143 | vfree(ubi->peb_buf); | 1135 | vfree(ubi->peb_buf); |
1144 | vfree(ubi->fm_buf); | 1136 | vfree(ubi->fm_buf); |
1145 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); | 1137 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 26908a59506b..63cb1d7236ce 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
@@ -217,32 +217,6 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req) | |||
217 | pr_err("\t1st 16 characters of name: %s\n", nm); | 217 | pr_err("\t1st 16 characters of name: %s\n", nm); |
218 | } | 218 | } |
219 | 219 | ||
220 | /** | ||
221 | * ubi_debugging_init_dev - initialize debugging for an UBI device. | ||
222 | * @ubi: UBI device description object | ||
223 | * | ||
224 | * This function initializes debugging-related data for UBI device @ubi. | ||
225 | * Returns zero in case of success and a negative error code in case of | ||
226 | * failure. | ||
227 | */ | ||
228 | int ubi_debugging_init_dev(struct ubi_device *ubi) | ||
229 | { | ||
230 | ubi->dbg = kzalloc(sizeof(struct ubi_debug_info), GFP_KERNEL); | ||
231 | if (!ubi->dbg) | ||
232 | return -ENOMEM; | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | /** | ||
238 | * ubi_debugging_exit_dev - free debugging data for an UBI device. | ||
239 | * @ubi: UBI device description object | ||
240 | */ | ||
241 | void ubi_debugging_exit_dev(struct ubi_device *ubi) | ||
242 | { | ||
243 | kfree(ubi->dbg); | ||
244 | } | ||
245 | |||
246 | /* | 220 | /* |
247 | * Root directory for UBI stuff in debugfs. Contains sub-directories which | 221 | * Root directory for UBI stuff in debugfs. Contains sub-directories which |
248 | * contain the stuff specific to particular UBI devices. | 222 | * contain the stuff specific to particular UBI devices. |
@@ -295,7 +269,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf, | |||
295 | ubi = ubi_get_device(ubi_num); | 269 | ubi = ubi_get_device(ubi_num); |
296 | if (!ubi) | 270 | if (!ubi) |
297 | return -ENODEV; | 271 | return -ENODEV; |
298 | d = ubi->dbg; | 272 | d = &ubi->dbg; |
299 | 273 | ||
300 | if (dent == d->dfs_chk_gen) | 274 | if (dent == d->dfs_chk_gen) |
301 | val = d->chk_gen; | 275 | val = d->chk_gen; |
@@ -341,7 +315,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, | |||
341 | ubi = ubi_get_device(ubi_num); | 315 | ubi = ubi_get_device(ubi_num); |
342 | if (!ubi) | 316 | if (!ubi) |
343 | return -ENODEV; | 317 | return -ENODEV; |
344 | d = ubi->dbg; | 318 | d = &ubi->dbg; |
345 | 319 | ||
346 | buf_size = min_t(size_t, count, (sizeof(buf) - 1)); | 320 | buf_size = min_t(size_t, count, (sizeof(buf) - 1)); |
347 | if (copy_from_user(buf, user_buf, buf_size)) { | 321 | if (copy_from_user(buf, user_buf, buf_size)) { |
@@ -398,7 +372,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) | |||
398 | unsigned long ubi_num = ubi->ubi_num; | 372 | unsigned long ubi_num = ubi->ubi_num; |
399 | const char *fname; | 373 | const char *fname; |
400 | struct dentry *dent; | 374 | struct dentry *dent; |
401 | struct ubi_debug_info *d = ubi->dbg; | 375 | struct ubi_debug_info *d = &ubi->dbg; |
402 | 376 | ||
403 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) | 377 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) |
404 | return 0; | 378 | return 0; |
@@ -471,5 +445,5 @@ out: | |||
471 | void ubi_debugfs_exit_dev(struct ubi_device *ubi) | 445 | void ubi_debugfs_exit_dev(struct ubi_device *ubi) |
472 | { | 446 | { |
473 | if (IS_ENABLED(CONFIG_DEBUG_FS)) | 447 | if (IS_ENABLED(CONFIG_DEBUG_FS)) |
474 | debugfs_remove_recursive(ubi->dbg->dfs_dir); | 448 | debugfs_remove_recursive(ubi->dbg.dfs_dir); |
475 | } | 449 | } |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 3dbc877d9663..33f8f3b2c9b2 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -60,51 +60,11 @@ void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type); | |||
60 | void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); | 60 | void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); |
61 | int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | 61 | int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, |
62 | int len); | 62 | int len); |
63 | int ubi_debugging_init_dev(struct ubi_device *ubi); | ||
64 | void ubi_debugging_exit_dev(struct ubi_device *ubi); | ||
65 | int ubi_debugfs_init(void); | 63 | int ubi_debugfs_init(void); |
66 | void ubi_debugfs_exit(void); | 64 | void ubi_debugfs_exit(void); |
67 | int ubi_debugfs_init_dev(struct ubi_device *ubi); | 65 | int ubi_debugfs_init_dev(struct ubi_device *ubi); |
68 | void ubi_debugfs_exit_dev(struct ubi_device *ubi); | 66 | void ubi_debugfs_exit_dev(struct ubi_device *ubi); |
69 | 67 | ||
70 | /* | ||
71 | * The UBI debugfs directory name pattern and maximum name length (3 for "ubi" | ||
72 | * + 2 for the number plus 1 for the trailing zero byte. | ||
73 | */ | ||
74 | #define UBI_DFS_DIR_NAME "ubi%d" | ||
75 | #define UBI_DFS_DIR_LEN (3 + 2 + 1) | ||
76 | |||
77 | /** | ||
78 | * struct ubi_debug_info - debugging information for an UBI device. | ||
79 | * | ||
80 | * @chk_gen: if UBI general extra checks are enabled | ||
81 | * @chk_io: if UBI I/O extra checks are enabled | ||
82 | * @disable_bgt: disable the background task for testing purposes | ||
83 | * @emulate_bitflips: emulate bit-flips for testing purposes | ||
84 | * @emulate_io_failures: emulate write/erase failures for testing purposes | ||
85 | * @dfs_dir_name: name of debugfs directory containing files of this UBI device | ||
86 | * @dfs_dir: direntry object of the UBI device debugfs directory | ||
87 | * @dfs_chk_gen: debugfs knob to enable UBI general extra checks | ||
88 | * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks | ||
89 | * @dfs_disable_bgt: debugfs knob to disable the background task | ||
90 | * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips | ||
91 | * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures | ||
92 | */ | ||
93 | struct ubi_debug_info { | ||
94 | unsigned int chk_gen:1; | ||
95 | unsigned int chk_io:1; | ||
96 | unsigned int disable_bgt:1; | ||
97 | unsigned int emulate_bitflips:1; | ||
98 | unsigned int emulate_io_failures:1; | ||
99 | char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; | ||
100 | struct dentry *dfs_dir; | ||
101 | struct dentry *dfs_chk_gen; | ||
102 | struct dentry *dfs_chk_io; | ||
103 | struct dentry *dfs_disable_bgt; | ||
104 | struct dentry *dfs_emulate_bitflips; | ||
105 | struct dentry *dfs_emulate_io_failures; | ||
106 | }; | ||
107 | |||
108 | /** | 68 | /** |
109 | * ubi_dbg_is_bgt_disabled - if the background thread is disabled. | 69 | * ubi_dbg_is_bgt_disabled - if the background thread is disabled. |
110 | * @ubi: UBI device description object | 70 | * @ubi: UBI device description object |
@@ -114,7 +74,7 @@ struct ubi_debug_info { | |||
114 | */ | 74 | */ |
115 | static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) | 75 | static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) |
116 | { | 76 | { |
117 | return ubi->dbg->disable_bgt; | 77 | return ubi->dbg.disable_bgt; |
118 | } | 78 | } |
119 | 79 | ||
120 | /** | 80 | /** |
@@ -125,7 +85,7 @@ static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) | |||
125 | */ | 85 | */ |
126 | static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) | 86 | static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) |
127 | { | 87 | { |
128 | if (ubi->dbg->emulate_bitflips) | 88 | if (ubi->dbg.emulate_bitflips) |
129 | return !(random32() % 200); | 89 | return !(random32() % 200); |
130 | return 0; | 90 | return 0; |
131 | } | 91 | } |
@@ -139,7 +99,7 @@ static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) | |||
139 | */ | 99 | */ |
140 | static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) | 100 | static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) |
141 | { | 101 | { |
142 | if (ubi->dbg->emulate_io_failures) | 102 | if (ubi->dbg.emulate_io_failures) |
143 | return !(random32() % 500); | 103 | return !(random32() % 500); |
144 | return 0; | 104 | return 0; |
145 | } | 105 | } |
@@ -153,9 +113,18 @@ static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) | |||
153 | */ | 113 | */ |
154 | static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) | 114 | static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) |
155 | { | 115 | { |
156 | if (ubi->dbg->emulate_io_failures) | 116 | if (ubi->dbg.emulate_io_failures) |
157 | return !(random32() % 400); | 117 | return !(random32() % 400); |
158 | return 0; | 118 | return 0; |
159 | } | 119 | } |
160 | 120 | ||
121 | static inline int ubi_dbg_chk_io(const struct ubi_device *ubi) | ||
122 | { | ||
123 | return ubi->dbg.chk_io; | ||
124 | } | ||
125 | |||
126 | static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi) | ||
127 | { | ||
128 | return ubi->dbg.chk_gen; | ||
129 | } | ||
161 | #endif /* !__UBI_DEBUG_H__ */ | 130 | #endif /* !__UBI_DEBUG_H__ */ |
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 1a5f53c090d4..0648c6996d43 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
@@ -814,10 +814,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi, | |||
814 | if (max_sqnum > ai->max_sqnum) | 814 | if (max_sqnum > ai->max_sqnum) |
815 | ai->max_sqnum = max_sqnum; | 815 | ai->max_sqnum = max_sqnum; |
816 | 816 | ||
817 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { | 817 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) |
818 | list_del(&tmp_aeb->u.list); | 818 | list_move_tail(&tmp_aeb->u.list, &ai->free); |
819 | list_add_tail(&tmp_aeb->u.list, &ai->free); | ||
820 | } | ||
821 | 819 | ||
822 | /* | 820 | /* |
823 | * If fastmap is leaking PEBs (must not happen), raise a | 821 | * If fastmap is leaking PEBs (must not happen), raise a |
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 4bd4db8c84c9..b93807b4c459 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c | |||
@@ -171,17 +171,17 @@ static void gluebi_put_device(struct mtd_info *mtd) | |||
171 | static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, | 171 | static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, |
172 | size_t *retlen, unsigned char *buf) | 172 | size_t *retlen, unsigned char *buf) |
173 | { | 173 | { |
174 | int err = 0, lnum, offs, total_read; | 174 | int err = 0, lnum, offs, bytes_left; |
175 | struct gluebi_device *gluebi; | 175 | struct gluebi_device *gluebi; |
176 | 176 | ||
177 | gluebi = container_of(mtd, struct gluebi_device, mtd); | 177 | gluebi = container_of(mtd, struct gluebi_device, mtd); |
178 | lnum = div_u64_rem(from, mtd->erasesize, &offs); | 178 | lnum = div_u64_rem(from, mtd->erasesize, &offs); |
179 | total_read = len; | 179 | bytes_left = len; |
180 | while (total_read) { | 180 | while (bytes_left) { |
181 | size_t to_read = mtd->erasesize - offs; | 181 | size_t to_read = mtd->erasesize - offs; |
182 | 182 | ||
183 | if (to_read > total_read) | 183 | if (to_read > bytes_left) |
184 | to_read = total_read; | 184 | to_read = bytes_left; |
185 | 185 | ||
186 | err = ubi_read(gluebi->desc, lnum, buf, offs, to_read); | 186 | err = ubi_read(gluebi->desc, lnum, buf, offs, to_read); |
187 | if (err) | 187 | if (err) |
@@ -189,11 +189,11 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
189 | 189 | ||
190 | lnum += 1; | 190 | lnum += 1; |
191 | offs = 0; | 191 | offs = 0; |
192 | total_read -= to_read; | 192 | bytes_left -= to_read; |
193 | buf += to_read; | 193 | buf += to_read; |
194 | } | 194 | } |
195 | 195 | ||
196 | *retlen = len - total_read; | 196 | *retlen = len - bytes_left; |
197 | return err; | 197 | return err; |
198 | } | 198 | } |
199 | 199 | ||
@@ -211,7 +211,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
211 | static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, | 211 | static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, |
212 | size_t *retlen, const u_char *buf) | 212 | size_t *retlen, const u_char *buf) |
213 | { | 213 | { |
214 | int err = 0, lnum, offs, total_written; | 214 | int err = 0, lnum, offs, bytes_left; |
215 | struct gluebi_device *gluebi; | 215 | struct gluebi_device *gluebi; |
216 | 216 | ||
217 | gluebi = container_of(mtd, struct gluebi_device, mtd); | 217 | gluebi = container_of(mtd, struct gluebi_device, mtd); |
@@ -220,12 +220,12 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
220 | if (len % mtd->writesize || offs % mtd->writesize) | 220 | if (len % mtd->writesize || offs % mtd->writesize) |
221 | return -EINVAL; | 221 | return -EINVAL; |
222 | 222 | ||
223 | total_written = len; | 223 | bytes_left = len; |
224 | while (total_written) { | 224 | while (bytes_left) { |
225 | size_t to_write = mtd->erasesize - offs; | 225 | size_t to_write = mtd->erasesize - offs; |
226 | 226 | ||
227 | if (to_write > total_written) | 227 | if (to_write > bytes_left) |
228 | to_write = total_written; | 228 | to_write = bytes_left; |
229 | 229 | ||
230 | err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write); | 230 | err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write); |
231 | if (err) | 231 | if (err) |
@@ -233,11 +233,11 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
233 | 233 | ||
234 | lnum += 1; | 234 | lnum += 1; |
235 | offs = 0; | 235 | offs = 0; |
236 | total_written -= to_write; | 236 | bytes_left -= to_write; |
237 | buf += to_write; | 237 | buf += to_write; |
238 | } | 238 | } |
239 | 239 | ||
240 | *retlen = len - total_written; | 240 | *retlen = len - bytes_left; |
241 | return err; | 241 | return err; |
242 | } | 242 | } |
243 | 243 | ||
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 78a1dcbf2107..bf79def40126 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -1132,7 +1132,7 @@ static int self_check_not_bad(const struct ubi_device *ubi, int pnum) | |||
1132 | { | 1132 | { |
1133 | int err; | 1133 | int err; |
1134 | 1134 | ||
1135 | if (!ubi->dbg->chk_io) | 1135 | if (!ubi_dbg_chk_io(ubi)) |
1136 | return 0; | 1136 | return 0; |
1137 | 1137 | ||
1138 | err = ubi_io_is_bad(ubi, pnum); | 1138 | err = ubi_io_is_bad(ubi, pnum); |
@@ -1159,7 +1159,7 @@ static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
1159 | int err; | 1159 | int err; |
1160 | uint32_t magic; | 1160 | uint32_t magic; |
1161 | 1161 | ||
1162 | if (!ubi->dbg->chk_io) | 1162 | if (!ubi_dbg_chk_io(ubi)) |
1163 | return 0; | 1163 | return 0; |
1164 | 1164 | ||
1165 | magic = be32_to_cpu(ec_hdr->magic); | 1165 | magic = be32_to_cpu(ec_hdr->magic); |
@@ -1197,7 +1197,7 @@ static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) | |||
1197 | uint32_t crc, hdr_crc; | 1197 | uint32_t crc, hdr_crc; |
1198 | struct ubi_ec_hdr *ec_hdr; | 1198 | struct ubi_ec_hdr *ec_hdr; |
1199 | 1199 | ||
1200 | if (!ubi->dbg->chk_io) | 1200 | if (!ubi_dbg_chk_io(ubi)) |
1201 | return 0; | 1201 | return 0; |
1202 | 1202 | ||
1203 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 1203 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
@@ -1241,7 +1241,7 @@ static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
1241 | int err; | 1241 | int err; |
1242 | uint32_t magic; | 1242 | uint32_t magic; |
1243 | 1243 | ||
1244 | if (!ubi->dbg->chk_io) | 1244 | if (!ubi_dbg_chk_io(ubi)) |
1245 | return 0; | 1245 | return 0; |
1246 | 1246 | ||
1247 | magic = be32_to_cpu(vid_hdr->magic); | 1247 | magic = be32_to_cpu(vid_hdr->magic); |
@@ -1282,7 +1282,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) | |||
1282 | struct ubi_vid_hdr *vid_hdr; | 1282 | struct ubi_vid_hdr *vid_hdr; |
1283 | void *p; | 1283 | void *p; |
1284 | 1284 | ||
1285 | if (!ubi->dbg->chk_io) | 1285 | if (!ubi_dbg_chk_io(ubi)) |
1286 | return 0; | 1286 | return 0; |
1287 | 1287 | ||
1288 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); | 1288 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
@@ -1334,7 +1334,7 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
1334 | void *buf1; | 1334 | void *buf1; |
1335 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1335 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
1336 | 1336 | ||
1337 | if (!ubi->dbg->chk_io) | 1337 | if (!ubi_dbg_chk_io(ubi)) |
1338 | return 0; | 1338 | return 0; |
1339 | 1339 | ||
1340 | buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); | 1340 | buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); |
@@ -1398,7 +1398,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) | |||
1398 | void *buf; | 1398 | void *buf; |
1399 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1399 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
1400 | 1400 | ||
1401 | if (!ubi->dbg->chk_io) | 1401 | if (!ubi_dbg_chk_io(ubi)) |
1402 | return 0; | 1402 | return 0; |
1403 | 1403 | ||
1404 | buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); | 1404 | buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 7d57469723cf..8ea6297a208f 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -85,6 +85,13 @@ | |||
85 | #define UBI_UNKNOWN -1 | 85 | #define UBI_UNKNOWN -1 |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * The UBI debugfs directory name pattern and maximum name length (3 for "ubi" | ||
89 | * + 2 for the number plus 1 for the trailing zero byte. | ||
90 | */ | ||
91 | #define UBI_DFS_DIR_NAME "ubi%d" | ||
92 | #define UBI_DFS_DIR_LEN (3 + 2 + 1) | ||
93 | |||
94 | /* | ||
88 | * Error codes returned by the I/O sub-system. | 95 | * Error codes returned by the I/O sub-system. |
89 | * | 96 | * |
90 | * UBI_IO_FF: the read region of flash contains only 0xFFs | 97 | * UBI_IO_FF: the read region of flash contains only 0xFFs |
@@ -342,6 +349,37 @@ struct ubi_volume_desc { | |||
342 | struct ubi_wl_entry; | 349 | struct ubi_wl_entry; |
343 | 350 | ||
344 | /** | 351 | /** |
352 | * struct ubi_debug_info - debugging information for an UBI device. | ||
353 | * | ||
354 | * @chk_gen: if UBI general extra checks are enabled | ||
355 | * @chk_io: if UBI I/O extra checks are enabled | ||
356 | * @disable_bgt: disable the background task for testing purposes | ||
357 | * @emulate_bitflips: emulate bit-flips for testing purposes | ||
358 | * @emulate_io_failures: emulate write/erase failures for testing purposes | ||
359 | * @dfs_dir_name: name of debugfs directory containing files of this UBI device | ||
360 | * @dfs_dir: direntry object of the UBI device debugfs directory | ||
361 | * @dfs_chk_gen: debugfs knob to enable UBI general extra checks | ||
362 | * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks | ||
363 | * @dfs_disable_bgt: debugfs knob to disable the background task | ||
364 | * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips | ||
365 | * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures | ||
366 | */ | ||
367 | struct ubi_debug_info { | ||
368 | unsigned int chk_gen:1; | ||
369 | unsigned int chk_io:1; | ||
370 | unsigned int disable_bgt:1; | ||
371 | unsigned int emulate_bitflips:1; | ||
372 | unsigned int emulate_io_failures:1; | ||
373 | char dfs_dir_name[UBI_DFS_DIR_LEN + 1]; | ||
374 | struct dentry *dfs_dir; | ||
375 | struct dentry *dfs_chk_gen; | ||
376 | struct dentry *dfs_chk_io; | ||
377 | struct dentry *dfs_disable_bgt; | ||
378 | struct dentry *dfs_emulate_bitflips; | ||
379 | struct dentry *dfs_emulate_io_failures; | ||
380 | }; | ||
381 | |||
382 | /** | ||
345 | * struct ubi_device - UBI device description structure | 383 | * struct ubi_device - UBI device description structure |
346 | * @dev: UBI device object to use the the Linux device model | 384 | * @dev: UBI device object to use the the Linux device model |
347 | * @cdev: character device object to create character device | 385 | * @cdev: character device object to create character device |
@@ -545,7 +583,7 @@ struct ubi_device { | |||
545 | struct mutex buf_mutex; | 583 | struct mutex buf_mutex; |
546 | struct mutex ckvol_mutex; | 584 | struct mutex ckvol_mutex; |
547 | 585 | ||
548 | struct ubi_debug_info *dbg; | 586 | struct ubi_debug_info dbg; |
549 | }; | 587 | }; |
550 | 588 | ||
551 | /** | 589 | /** |
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 9f2ebd8750e7..ec2c2dc1c1ca 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c | |||
@@ -64,8 +64,7 @@ static int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol) | |||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], | 67 | vtbl_rec = ubi->vtbl[vol->vol_id]; |
68 | sizeof(struct ubi_vtbl_record)); | ||
69 | vtbl_rec.upd_marker = 1; | 68 | vtbl_rec.upd_marker = 1; |
70 | 69 | ||
71 | mutex_lock(&ubi->device_mutex); | 70 | mutex_lock(&ubi->device_mutex); |
@@ -93,8 +92,7 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, | |||
93 | 92 | ||
94 | dbg_gen("clear update marker for volume %d", vol->vol_id); | 93 | dbg_gen("clear update marker for volume %d", vol->vol_id); |
95 | 94 | ||
96 | memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], | 95 | vtbl_rec = ubi->vtbl[vol->vol_id]; |
97 | sizeof(struct ubi_vtbl_record)); | ||
98 | ubi_assert(vol->upd_marker && vtbl_rec.upd_marker); | 96 | ubi_assert(vol->upd_marker && vtbl_rec.upd_marker); |
99 | vtbl_rec.upd_marker = 0; | 97 | vtbl_rec.upd_marker = 0; |
100 | 98 | ||
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 9169e58c262e..8330703c098f 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -535,7 +535,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
535 | } | 535 | } |
536 | 536 | ||
537 | /* Change volume table record */ | 537 | /* Change volume table record */ |
538 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); | 538 | vtbl_rec = ubi->vtbl[vol_id]; |
539 | vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs); | 539 | vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs); |
540 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); | 540 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); |
541 | if (err) | 541 | if (err) |
@@ -847,7 +847,7 @@ static int self_check_volumes(struct ubi_device *ubi) | |||
847 | { | 847 | { |
848 | int i, err = 0; | 848 | int i, err = 0; |
849 | 849 | ||
850 | if (!ubi->dbg->chk_gen) | 850 | if (!ubi_dbg_chk_gen(ubi)) |
851 | return 0; | 851 | return 0; |
852 | 852 | ||
853 | for (i = 0; i < ubi->vtbl_slots; i++) { | 853 | for (i = 0; i < ubi->vtbl_slots; i++) { |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 926e3df14fb2..d77b1c1d7c72 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -858,7 +858,7 @@ out_free: | |||
858 | */ | 858 | */ |
859 | static void self_vtbl_check(const struct ubi_device *ubi) | 859 | static void self_vtbl_check(const struct ubi_device *ubi) |
860 | { | 860 | { |
861 | if (!ubi->dbg->chk_gen) | 861 | if (!ubi_dbg_chk_gen(ubi)) |
862 | return; | 862 | return; |
863 | 863 | ||
864 | if (vtbl_check(ubi, ubi->vtbl)) { | 864 | if (vtbl_check(ubi, ubi->vtbl)) { |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 2144f611196e..5df49d3cb5c7 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * @ubi: UBI device description object | ||
3 | * Copyright (c) International Business Machines Corp., 2006 | 2 | * Copyright (c) International Business Machines Corp., 2006 |
4 | * | 3 | * |
5 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
@@ -2050,7 +2049,7 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec) | |||
2050 | long long read_ec; | 2049 | long long read_ec; |
2051 | struct ubi_ec_hdr *ec_hdr; | 2050 | struct ubi_ec_hdr *ec_hdr; |
2052 | 2051 | ||
2053 | if (!ubi->dbg->chk_gen) | 2052 | if (!ubi_dbg_chk_gen(ubi)) |
2054 | return 0; | 2053 | return 0; |
2055 | 2054 | ||
2056 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 2055 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
@@ -2090,7 +2089,7 @@ out_free: | |||
2090 | static int self_check_in_wl_tree(const struct ubi_device *ubi, | 2089 | static int self_check_in_wl_tree(const struct ubi_device *ubi, |
2091 | struct ubi_wl_entry *e, struct rb_root *root) | 2090 | struct ubi_wl_entry *e, struct rb_root *root) |
2092 | { | 2091 | { |
2093 | if (!ubi->dbg->chk_gen) | 2092 | if (!ubi_dbg_chk_gen(ubi)) |
2094 | return 0; | 2093 | return 0; |
2095 | 2094 | ||
2096 | if (in_wl_tree(e, root)) | 2095 | if (in_wl_tree(e, root)) |
@@ -2116,7 +2115,7 @@ static int self_check_in_pq(const struct ubi_device *ubi, | |||
2116 | struct ubi_wl_entry *p; | 2115 | struct ubi_wl_entry *p; |
2117 | int i; | 2116 | int i; |
2118 | 2117 | ||
2119 | if (!ubi->dbg->chk_gen) | 2118 | if (!ubi_dbg_chk_gen(ubi)) |
2120 | return 0; | 2119 | return 0; |
2121 | 2120 | ||
2122 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) | 2121 | for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 68d64f0313ea..a6fcf15adc4f 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -130,7 +130,6 @@ struct skb_vnet_hdr { | |||
130 | struct virtio_net_hdr hdr; | 130 | struct virtio_net_hdr hdr; |
131 | struct virtio_net_hdr_mrg_rxbuf mhdr; | 131 | struct virtio_net_hdr_mrg_rxbuf mhdr; |
132 | }; | 132 | }; |
133 | unsigned int num_sg; | ||
134 | }; | 133 | }; |
135 | 134 | ||
136 | struct padded_vnet_hdr { | 135 | struct padded_vnet_hdr { |
@@ -530,10 +529,10 @@ static bool try_fill_recv(struct receive_queue *rq, gfp_t gfp) | |||
530 | err = add_recvbuf_small(rq, gfp); | 529 | err = add_recvbuf_small(rq, gfp); |
531 | 530 | ||
532 | oom = err == -ENOMEM; | 531 | oom = err == -ENOMEM; |
533 | if (err < 0) | 532 | if (err) |
534 | break; | 533 | break; |
535 | ++rq->num; | 534 | ++rq->num; |
536 | } while (err > 0); | 535 | } while (rq->vq->num_free); |
537 | if (unlikely(rq->num > rq->max)) | 536 | if (unlikely(rq->num > rq->max)) |
538 | rq->max = rq->num; | 537 | rq->max = rq->num; |
539 | virtqueue_kick(rq->vq); | 538 | virtqueue_kick(rq->vq); |
@@ -640,10 +639,10 @@ static int virtnet_open(struct net_device *dev) | |||
640 | return 0; | 639 | return 0; |
641 | } | 640 | } |
642 | 641 | ||
643 | static unsigned int free_old_xmit_skbs(struct send_queue *sq) | 642 | static void free_old_xmit_skbs(struct send_queue *sq) |
644 | { | 643 | { |
645 | struct sk_buff *skb; | 644 | struct sk_buff *skb; |
646 | unsigned int len, tot_sgs = 0; | 645 | unsigned int len; |
647 | struct virtnet_info *vi = sq->vq->vdev->priv; | 646 | struct virtnet_info *vi = sq->vq->vdev->priv; |
648 | struct virtnet_stats *stats = this_cpu_ptr(vi->stats); | 647 | struct virtnet_stats *stats = this_cpu_ptr(vi->stats); |
649 | 648 | ||
@@ -655,10 +654,8 @@ static unsigned int free_old_xmit_skbs(struct send_queue *sq) | |||
655 | stats->tx_packets++; | 654 | stats->tx_packets++; |
656 | u64_stats_update_end(&stats->tx_syncp); | 655 | u64_stats_update_end(&stats->tx_syncp); |
657 | 656 | ||
658 | tot_sgs += skb_vnet_hdr(skb)->num_sg; | ||
659 | dev_kfree_skb_any(skb); | 657 | dev_kfree_skb_any(skb); |
660 | } | 658 | } |
661 | return tot_sgs; | ||
662 | } | 659 | } |
663 | 660 | ||
664 | static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) | 661 | static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) |
@@ -666,6 +663,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) | |||
666 | struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb); | 663 | struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb); |
667 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | 664 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; |
668 | struct virtnet_info *vi = sq->vq->vdev->priv; | 665 | struct virtnet_info *vi = sq->vq->vdev->priv; |
666 | unsigned num_sg; | ||
669 | 667 | ||
670 | pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); | 668 | pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); |
671 | 669 | ||
@@ -704,8 +702,8 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) | |||
704 | else | 702 | else |
705 | sg_set_buf(sq->sg, &hdr->hdr, sizeof hdr->hdr); | 703 | sg_set_buf(sq->sg, &hdr->hdr, sizeof hdr->hdr); |
706 | 704 | ||
707 | hdr->num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1; | 705 | num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1; |
708 | return virtqueue_add_buf(sq->vq, sq->sg, hdr->num_sg, | 706 | return virtqueue_add_buf(sq->vq, sq->sg, num_sg, |
709 | 0, skb, GFP_ATOMIC); | 707 | 0, skb, GFP_ATOMIC); |
710 | } | 708 | } |
711 | 709 | ||
@@ -714,28 +712,20 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
714 | struct virtnet_info *vi = netdev_priv(dev); | 712 | struct virtnet_info *vi = netdev_priv(dev); |
715 | int qnum = skb_get_queue_mapping(skb); | 713 | int qnum = skb_get_queue_mapping(skb); |
716 | struct send_queue *sq = &vi->sq[qnum]; | 714 | struct send_queue *sq = &vi->sq[qnum]; |
717 | int capacity; | 715 | int err; |
718 | 716 | ||
719 | /* Free up any pending old buffers before queueing new ones. */ | 717 | /* Free up any pending old buffers before queueing new ones. */ |
720 | free_old_xmit_skbs(sq); | 718 | free_old_xmit_skbs(sq); |
721 | 719 | ||
722 | /* Try to transmit */ | 720 | /* Try to transmit */ |
723 | capacity = xmit_skb(sq, skb); | 721 | err = xmit_skb(sq, skb); |
724 | 722 | ||
725 | /* This can happen with OOM and indirect buffers. */ | 723 | /* This should not happen! */ |
726 | if (unlikely(capacity < 0)) { | 724 | if (unlikely(err)) { |
727 | if (likely(capacity == -ENOMEM)) { | 725 | dev->stats.tx_fifo_errors++; |
728 | if (net_ratelimit()) | 726 | if (net_ratelimit()) |
729 | dev_warn(&dev->dev, | 727 | dev_warn(&dev->dev, |
730 | "TXQ (%d) failure: out of memory\n", | 728 | "Unexpected TXQ (%d) queue failure: %d\n", qnum, err); |
731 | qnum); | ||
732 | } else { | ||
733 | dev->stats.tx_fifo_errors++; | ||
734 | if (net_ratelimit()) | ||
735 | dev_warn(&dev->dev, | ||
736 | "Unexpected TXQ (%d) failure: %d\n", | ||
737 | qnum, capacity); | ||
738 | } | ||
739 | dev->stats.tx_dropped++; | 729 | dev->stats.tx_dropped++; |
740 | kfree_skb(skb); | 730 | kfree_skb(skb); |
741 | return NETDEV_TX_OK; | 731 | return NETDEV_TX_OK; |
@@ -748,12 +738,12 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
748 | 738 | ||
749 | /* Apparently nice girls don't return TX_BUSY; stop the queue | 739 | /* Apparently nice girls don't return TX_BUSY; stop the queue |
750 | * before it gets out of hand. Naturally, this wastes entries. */ | 740 | * before it gets out of hand. Naturally, this wastes entries. */ |
751 | if (capacity < 2+MAX_SKB_FRAGS) { | 741 | if (sq->vq->num_free < 2+MAX_SKB_FRAGS) { |
752 | netif_stop_subqueue(dev, qnum); | 742 | netif_stop_subqueue(dev, qnum); |
753 | if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) { | 743 | if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) { |
754 | /* More just got used, free them then recheck. */ | 744 | /* More just got used, free them then recheck. */ |
755 | capacity += free_old_xmit_skbs(sq); | 745 | free_old_xmit_skbs(sq); |
756 | if (capacity >= 2+MAX_SKB_FRAGS) { | 746 | if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) { |
757 | netif_start_subqueue(dev, qnum); | 747 | netif_start_subqueue(dev, qnum); |
758 | virtqueue_disable_cb(sq->vq); | 748 | virtqueue_disable_cb(sq->vq); |
759 | } | 749 | } |
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 1859f71372e2..027096fe6a12 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -764,7 +764,7 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst, | |||
764 | 764 | ||
765 | /* add message to the remote processor's virtqueue */ | 765 | /* add message to the remote processor's virtqueue */ |
766 | err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL); | 766 | err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL); |
767 | if (err < 0) { | 767 | if (err) { |
768 | /* | 768 | /* |
769 | * need to reclaim the buffer here, otherwise it's lost | 769 | * need to reclaim the buffer here, otherwise it's lost |
770 | * (memory won't leak, but rpmsg won't use it again for TX). | 770 | * (memory won't leak, but rpmsg won't use it again for TX). |
@@ -776,8 +776,6 @@ int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst, | |||
776 | 776 | ||
777 | /* tell the remote processor it has a pending message to read */ | 777 | /* tell the remote processor it has a pending message to read */ |
778 | virtqueue_kick(vrp->svq); | 778 | virtqueue_kick(vrp->svq); |
779 | |||
780 | err = 0; | ||
781 | out: | 779 | out: |
782 | mutex_unlock(&vrp->tx_lock); | 780 | mutex_unlock(&vrp->tx_lock); |
783 | return err; | 781 | return err; |
@@ -980,7 +978,7 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
980 | 978 | ||
981 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr, | 979 | err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr, |
982 | GFP_KERNEL); | 980 | GFP_KERNEL); |
983 | WARN_ON(err < 0); /* sanity check; this can't really happen */ | 981 | WARN_ON(err); /* sanity check; this can't really happen */ |
984 | } | 982 | } |
985 | 983 | ||
986 | /* suppress "tx-complete" interrupts */ | 984 | /* suppress "tx-complete" interrupts */ |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index dd8dc27fa32c..74ab67a169ec 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -215,7 +215,7 @@ static void virtscsi_ctrl_done(struct virtqueue *vq) | |||
215 | static int virtscsi_kick_event(struct virtio_scsi *vscsi, | 215 | static int virtscsi_kick_event(struct virtio_scsi *vscsi, |
216 | struct virtio_scsi_event_node *event_node) | 216 | struct virtio_scsi_event_node *event_node) |
217 | { | 217 | { |
218 | int ret; | 218 | int err; |
219 | struct scatterlist sg; | 219 | struct scatterlist sg; |
220 | unsigned long flags; | 220 | unsigned long flags; |
221 | 221 | ||
@@ -223,13 +223,14 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi, | |||
223 | 223 | ||
224 | spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); | 224 | spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); |
225 | 225 | ||
226 | ret = virtqueue_add_buf(vscsi->event_vq.vq, &sg, 0, 1, event_node, GFP_ATOMIC); | 226 | err = virtqueue_add_buf(vscsi->event_vq.vq, &sg, 0, 1, event_node, |
227 | if (ret >= 0) | 227 | GFP_ATOMIC); |
228 | if (!err) | ||
228 | virtqueue_kick(vscsi->event_vq.vq); | 229 | virtqueue_kick(vscsi->event_vq.vq); |
229 | 230 | ||
230 | spin_unlock_irqrestore(&vscsi->event_vq.vq_lock, flags); | 231 | spin_unlock_irqrestore(&vscsi->event_vq.vq_lock, flags); |
231 | 232 | ||
232 | return ret; | 233 | return err; |
233 | } | 234 | } |
234 | 235 | ||
235 | static int virtscsi_kick_event_all(struct virtio_scsi *vscsi) | 236 | static int virtscsi_kick_event_all(struct virtio_scsi *vscsi) |
@@ -410,22 +411,23 @@ static int virtscsi_kick_cmd(struct virtio_scsi_target_state *tgt, | |||
410 | { | 411 | { |
411 | unsigned int out_num, in_num; | 412 | unsigned int out_num, in_num; |
412 | unsigned long flags; | 413 | unsigned long flags; |
413 | int ret; | 414 | int err; |
415 | bool needs_kick = false; | ||
414 | 416 | ||
415 | spin_lock_irqsave(&tgt->tgt_lock, flags); | 417 | spin_lock_irqsave(&tgt->tgt_lock, flags); |
416 | virtscsi_map_cmd(tgt, cmd, &out_num, &in_num, req_size, resp_size); | 418 | virtscsi_map_cmd(tgt, cmd, &out_num, &in_num, req_size, resp_size); |
417 | 419 | ||
418 | spin_lock(&vq->vq_lock); | 420 | spin_lock(&vq->vq_lock); |
419 | ret = virtqueue_add_buf(vq->vq, tgt->sg, out_num, in_num, cmd, gfp); | 421 | err = virtqueue_add_buf(vq->vq, tgt->sg, out_num, in_num, cmd, gfp); |
420 | spin_unlock(&tgt->tgt_lock); | 422 | spin_unlock(&tgt->tgt_lock); |
421 | if (ret >= 0) | 423 | if (!err) |
422 | ret = virtqueue_kick_prepare(vq->vq); | 424 | needs_kick = virtqueue_kick_prepare(vq->vq); |
423 | 425 | ||
424 | spin_unlock_irqrestore(&vq->vq_lock, flags); | 426 | spin_unlock_irqrestore(&vq->vq_lock, flags); |
425 | 427 | ||
426 | if (ret > 0) | 428 | if (needs_kick) |
427 | virtqueue_notify(vq->vq); | 429 | virtqueue_notify(vq->vq); |
428 | return ret; | 430 | return err; |
429 | } | 431 | } |
430 | 432 | ||
431 | static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) | 433 | static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) |
@@ -467,7 +469,7 @@ static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) | |||
467 | 469 | ||
468 | if (virtscsi_kick_cmd(tgt, &vscsi->req_vq, cmd, | 470 | if (virtscsi_kick_cmd(tgt, &vscsi->req_vq, cmd, |
469 | sizeof cmd->req.cmd, sizeof cmd->resp.cmd, | 471 | sizeof cmd->req.cmd, sizeof cmd->resp.cmd, |
470 | GFP_ATOMIC) >= 0) | 472 | GFP_ATOMIC) == 0) |
471 | ret = 0; | 473 | ret = 0; |
472 | else | 474 | else |
473 | mempool_free(cmd, virtscsi_cmd_pool); | 475 | mempool_free(cmd, virtscsi_cmd_pool); |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 23f797eb7a28..57d6b29c039c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -41,8 +41,7 @@ | |||
41 | #include <linux/of.h> | 41 | #include <linux/of.h> |
42 | #include <linux/gpio.h> | 42 | #include <linux/gpio.h> |
43 | #include <linux/pinctrl/consumer.h> | 43 | #include <linux/pinctrl/consumer.h> |
44 | 44 | #include <linux/platform_data/serial-omap.h> | |
45 | #include <plat/omap-serial.h> | ||
46 | 45 | ||
47 | #define OMAP_MAX_HSUART_PORTS 6 | 46 | #define OMAP_MAX_HSUART_PORTS 6 |
48 | 47 | ||
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 809b0de59c09..ee59b74768d9 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -10,33 +10,32 @@ static DEFINE_IDA(virtio_index_ida); | |||
10 | static ssize_t device_show(struct device *_d, | 10 | static ssize_t device_show(struct device *_d, |
11 | struct device_attribute *attr, char *buf) | 11 | struct device_attribute *attr, char *buf) |
12 | { | 12 | { |
13 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 13 | struct virtio_device *dev = dev_to_virtio(_d); |
14 | return sprintf(buf, "0x%04x\n", dev->id.device); | 14 | return sprintf(buf, "0x%04x\n", dev->id.device); |
15 | } | 15 | } |
16 | static ssize_t vendor_show(struct device *_d, | 16 | static ssize_t vendor_show(struct device *_d, |
17 | struct device_attribute *attr, char *buf) | 17 | struct device_attribute *attr, char *buf) |
18 | { | 18 | { |
19 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 19 | struct virtio_device *dev = dev_to_virtio(_d); |
20 | return sprintf(buf, "0x%04x\n", dev->id.vendor); | 20 | return sprintf(buf, "0x%04x\n", dev->id.vendor); |
21 | } | 21 | } |
22 | static ssize_t status_show(struct device *_d, | 22 | static ssize_t status_show(struct device *_d, |
23 | struct device_attribute *attr, char *buf) | 23 | struct device_attribute *attr, char *buf) |
24 | { | 24 | { |
25 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 25 | struct virtio_device *dev = dev_to_virtio(_d); |
26 | return sprintf(buf, "0x%08x\n", dev->config->get_status(dev)); | 26 | return sprintf(buf, "0x%08x\n", dev->config->get_status(dev)); |
27 | } | 27 | } |
28 | static ssize_t modalias_show(struct device *_d, | 28 | static ssize_t modalias_show(struct device *_d, |
29 | struct device_attribute *attr, char *buf) | 29 | struct device_attribute *attr, char *buf) |
30 | { | 30 | { |
31 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 31 | struct virtio_device *dev = dev_to_virtio(_d); |
32 | |||
33 | return sprintf(buf, "virtio:d%08Xv%08X\n", | 32 | return sprintf(buf, "virtio:d%08Xv%08X\n", |
34 | dev->id.device, dev->id.vendor); | 33 | dev->id.device, dev->id.vendor); |
35 | } | 34 | } |
36 | static ssize_t features_show(struct device *_d, | 35 | static ssize_t features_show(struct device *_d, |
37 | struct device_attribute *attr, char *buf) | 36 | struct device_attribute *attr, char *buf) |
38 | { | 37 | { |
39 | struct virtio_device *dev = container_of(_d, struct virtio_device, dev); | 38 | struct virtio_device *dev = dev_to_virtio(_d); |
40 | unsigned int i; | 39 | unsigned int i; |
41 | ssize_t len = 0; | 40 | ssize_t len = 0; |
42 | 41 | ||
@@ -71,10 +70,10 @@ static inline int virtio_id_match(const struct virtio_device *dev, | |||
71 | static int virtio_dev_match(struct device *_dv, struct device_driver *_dr) | 70 | static int virtio_dev_match(struct device *_dv, struct device_driver *_dr) |
72 | { | 71 | { |
73 | unsigned int i; | 72 | unsigned int i; |
74 | struct virtio_device *dev = container_of(_dv,struct virtio_device,dev); | 73 | struct virtio_device *dev = dev_to_virtio(_dv); |
75 | const struct virtio_device_id *ids; | 74 | const struct virtio_device_id *ids; |
76 | 75 | ||
77 | ids = container_of(_dr, struct virtio_driver, driver)->id_table; | 76 | ids = drv_to_virtio(_dr)->id_table; |
78 | for (i = 0; ids[i].device; i++) | 77 | for (i = 0; ids[i].device; i++) |
79 | if (virtio_id_match(dev, &ids[i])) | 78 | if (virtio_id_match(dev, &ids[i])) |
80 | return 1; | 79 | return 1; |
@@ -83,7 +82,7 @@ static int virtio_dev_match(struct device *_dv, struct device_driver *_dr) | |||
83 | 82 | ||
84 | static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env) | 83 | static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env) |
85 | { | 84 | { |
86 | struct virtio_device *dev = container_of(_dv,struct virtio_device,dev); | 85 | struct virtio_device *dev = dev_to_virtio(_dv); |
87 | 86 | ||
88 | return add_uevent_var(env, "MODALIAS=virtio:d%08Xv%08X", | 87 | return add_uevent_var(env, "MODALIAS=virtio:d%08Xv%08X", |
89 | dev->id.device, dev->id.vendor); | 88 | dev->id.device, dev->id.vendor); |
@@ -98,8 +97,7 @@ void virtio_check_driver_offered_feature(const struct virtio_device *vdev, | |||
98 | unsigned int fbit) | 97 | unsigned int fbit) |
99 | { | 98 | { |
100 | unsigned int i; | 99 | unsigned int i; |
101 | struct virtio_driver *drv = container_of(vdev->dev.driver, | 100 | struct virtio_driver *drv = drv_to_virtio(vdev->dev.driver); |
102 | struct virtio_driver, driver); | ||
103 | 101 | ||
104 | for (i = 0; i < drv->feature_table_size; i++) | 102 | for (i = 0; i < drv->feature_table_size; i++) |
105 | if (drv->feature_table[i] == fbit) | 103 | if (drv->feature_table[i] == fbit) |
@@ -111,9 +109,8 @@ EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature); | |||
111 | static int virtio_dev_probe(struct device *_d) | 109 | static int virtio_dev_probe(struct device *_d) |
112 | { | 110 | { |
113 | int err, i; | 111 | int err, i; |
114 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 112 | struct virtio_device *dev = dev_to_virtio(_d); |
115 | struct virtio_driver *drv = container_of(dev->dev.driver, | 113 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); |
116 | struct virtio_driver, driver); | ||
117 | u32 device_features; | 114 | u32 device_features; |
118 | 115 | ||
119 | /* We have a driver! */ | 116 | /* We have a driver! */ |
@@ -152,9 +149,8 @@ static int virtio_dev_probe(struct device *_d) | |||
152 | 149 | ||
153 | static int virtio_dev_remove(struct device *_d) | 150 | static int virtio_dev_remove(struct device *_d) |
154 | { | 151 | { |
155 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | 152 | struct virtio_device *dev = dev_to_virtio(_d); |
156 | struct virtio_driver *drv = container_of(dev->dev.driver, | 153 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); |
157 | struct virtio_driver, driver); | ||
158 | 154 | ||
159 | drv->remove(dev); | 155 | drv->remove(dev); |
160 | 156 | ||
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 2a70558b36ea..d19fe3e323b4 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -139,10 +139,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) | |||
139 | struct page *page = balloon_page_enqueue(vb_dev_info); | 139 | struct page *page = balloon_page_enqueue(vb_dev_info); |
140 | 140 | ||
141 | if (!page) { | 141 | if (!page) { |
142 | if (printk_ratelimit()) | 142 | dev_info_ratelimited(&vb->vdev->dev, |
143 | dev_printk(KERN_INFO, &vb->vdev->dev, | 143 | "Out of puff! Can't get %u pages\n", |
144 | "Out of puff! Can't get %u pages\n", | 144 | VIRTIO_BALLOON_PAGES_PER_PAGE); |
145 | VIRTIO_BALLOON_PAGES_PER_PAGE); | ||
146 | /* Sleep for at least 1/5 of a second before retry. */ | 145 | /* Sleep for at least 1/5 of a second before retry. */ |
147 | msleep(200); | 146 | msleep(200); |
148 | break; | 147 | break; |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 6b1b7e184939..634f80bcdbd7 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
@@ -225,7 +225,7 @@ static void vm_notify(struct virtqueue *vq) | |||
225 | 225 | ||
226 | /* We write the queue's selector into the notification register to | 226 | /* We write the queue's selector into the notification register to |
227 | * signal the other end */ | 227 | * signal the other end */ |
228 | writel(virtqueue_get_queue_index(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); | 228 | writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); |
229 | } | 229 | } |
230 | 230 | ||
231 | /* Notify all virtqueues on an interrupt. */ | 231 | /* Notify all virtqueues on an interrupt. */ |
@@ -266,7 +266,7 @@ static void vm_del_vq(struct virtqueue *vq) | |||
266 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); | 266 | struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); |
267 | struct virtio_mmio_vq_info *info = vq->priv; | 267 | struct virtio_mmio_vq_info *info = vq->priv; |
268 | unsigned long flags, size; | 268 | unsigned long flags, size; |
269 | unsigned int index = virtqueue_get_queue_index(vq); | 269 | unsigned int index = vq->index; |
270 | 270 | ||
271 | spin_lock_irqsave(&vm_dev->lock, flags); | 271 | spin_lock_irqsave(&vm_dev->lock, flags); |
272 | list_del(&info->node); | 272 | list_del(&info->node); |
@@ -521,25 +521,33 @@ static int vm_cmdline_set(const char *device, | |||
521 | int err; | 521 | int err; |
522 | struct resource resources[2] = {}; | 522 | struct resource resources[2] = {}; |
523 | char *str; | 523 | char *str; |
524 | long long int base; | 524 | long long int base, size; |
525 | unsigned int irq; | ||
525 | int processed, consumed = 0; | 526 | int processed, consumed = 0; |
526 | struct platform_device *pdev; | 527 | struct platform_device *pdev; |
527 | 528 | ||
528 | resources[0].flags = IORESOURCE_MEM; | 529 | /* Consume "size" part of the command line parameter */ |
529 | resources[1].flags = IORESOURCE_IRQ; | 530 | size = memparse(device, &str); |
530 | |||
531 | resources[0].end = memparse(device, &str) - 1; | ||
532 | 531 | ||
532 | /* Get "@<base>:<irq>[:<id>]" chunks */ | ||
533 | processed = sscanf(str, "@%lli:%u%n:%d%n", | 533 | processed = sscanf(str, "@%lli:%u%n:%d%n", |
534 | &base, &resources[1].start, &consumed, | 534 | &base, &irq, &consumed, |
535 | &vm_cmdline_id, &consumed); | 535 | &vm_cmdline_id, &consumed); |
536 | 536 | ||
537 | if (processed < 2 || processed > 3 || str[consumed]) | 537 | /* |
538 | * sscanf() must processes at least 2 chunks; also there | ||
539 | * must be no extra characters after the last chunk, so | ||
540 | * str[consumed] must be '\0' | ||
541 | */ | ||
542 | if (processed < 2 || str[consumed]) | ||
538 | return -EINVAL; | 543 | return -EINVAL; |
539 | 544 | ||
545 | resources[0].flags = IORESOURCE_MEM; | ||
540 | resources[0].start = base; | 546 | resources[0].start = base; |
541 | resources[0].end += base; | 547 | resources[0].end = base + size - 1; |
542 | resources[1].end = resources[1].start; | 548 | |
549 | resources[1].flags = IORESOURCE_IRQ; | ||
550 | resources[1].start = resources[1].end = irq; | ||
543 | 551 | ||
544 | if (!vm_cmdline_parent_registered) { | 552 | if (!vm_cmdline_parent_registered) { |
545 | err = device_register(&vm_cmdline_parent); | 553 | err = device_register(&vm_cmdline_parent); |
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index c33aea36598a..e3ecc94591ad 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -203,8 +203,7 @@ static void vp_notify(struct virtqueue *vq) | |||
203 | 203 | ||
204 | /* we write the queue's selector into the notification register to | 204 | /* we write the queue's selector into the notification register to |
205 | * signal the other end */ | 205 | * signal the other end */ |
206 | iowrite16(virtqueue_get_queue_index(vq), | 206 | iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); |
207 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); | ||
208 | } | 207 | } |
209 | 208 | ||
210 | /* Handle a configuration change: Tell driver if it wants to know. */ | 209 | /* Handle a configuration change: Tell driver if it wants to know. */ |
@@ -479,8 +478,7 @@ static void vp_del_vq(struct virtqueue *vq) | |||
479 | list_del(&info->node); | 478 | list_del(&info->node); |
480 | spin_unlock_irqrestore(&vp_dev->lock, flags); | 479 | spin_unlock_irqrestore(&vp_dev->lock, flags); |
481 | 480 | ||
482 | iowrite16(virtqueue_get_queue_index(vq), | 481 | iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); |
483 | vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); | ||
484 | 482 | ||
485 | if (vp_dev->msix_enabled) { | 483 | if (vp_dev->msix_enabled) { |
486 | iowrite16(VIRTIO_MSI_NO_VECTOR, | 484 | iowrite16(VIRTIO_MSI_NO_VECTOR, |
@@ -830,16 +828,4 @@ static struct pci_driver virtio_pci_driver = { | |||
830 | #endif | 828 | #endif |
831 | }; | 829 | }; |
832 | 830 | ||
833 | static int __init virtio_pci_init(void) | 831 | module_pci_driver(virtio_pci_driver); |
834 | { | ||
835 | return pci_register_driver(&virtio_pci_driver); | ||
836 | } | ||
837 | |||
838 | module_init(virtio_pci_init); | ||
839 | |||
840 | static void __exit virtio_pci_exit(void) | ||
841 | { | ||
842 | pci_unregister_driver(&virtio_pci_driver); | ||
843 | } | ||
844 | |||
845 | module_exit(virtio_pci_exit); | ||
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index e639584b2dbd..ffd7e7da5d3b 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -93,8 +93,6 @@ struct vring_virtqueue | |||
93 | /* Host publishes avail event idx */ | 93 | /* Host publishes avail event idx */ |
94 | bool event; | 94 | bool event; |
95 | 95 | ||
96 | /* Number of free buffers */ | ||
97 | unsigned int num_free; | ||
98 | /* Head of free buffer list. */ | 96 | /* Head of free buffer list. */ |
99 | unsigned int free_head; | 97 | unsigned int free_head; |
100 | /* Number we've added since last sync. */ | 98 | /* Number we've added since last sync. */ |
@@ -106,9 +104,6 @@ struct vring_virtqueue | |||
106 | /* How to notify other side. FIXME: commonalize hcalls! */ | 104 | /* How to notify other side. FIXME: commonalize hcalls! */ |
107 | void (*notify)(struct virtqueue *vq); | 105 | void (*notify)(struct virtqueue *vq); |
108 | 106 | ||
109 | /* Index of the queue */ | ||
110 | int queue_index; | ||
111 | |||
112 | #ifdef DEBUG | 107 | #ifdef DEBUG |
113 | /* They're supposed to lock for us. */ | 108 | /* They're supposed to lock for us. */ |
114 | unsigned int in_use; | 109 | unsigned int in_use; |
@@ -135,6 +130,13 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
135 | unsigned head; | 130 | unsigned head; |
136 | int i; | 131 | int i; |
137 | 132 | ||
133 | /* | ||
134 | * We require lowmem mappings for the descriptors because | ||
135 | * otherwise virt_to_phys will give us bogus addresses in the | ||
136 | * virtqueue. | ||
137 | */ | ||
138 | gfp &= ~(__GFP_HIGHMEM | __GFP_HIGH); | ||
139 | |||
138 | desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); | 140 | desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); |
139 | if (!desc) | 141 | if (!desc) |
140 | return -ENOMEM; | 142 | return -ENOMEM; |
@@ -160,7 +162,7 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
160 | desc[i-1].next = 0; | 162 | desc[i-1].next = 0; |
161 | 163 | ||
162 | /* We're about to use a buffer */ | 164 | /* We're about to use a buffer */ |
163 | vq->num_free--; | 165 | vq->vq.num_free--; |
164 | 166 | ||
165 | /* Use a single buffer which doesn't continue */ | 167 | /* Use a single buffer which doesn't continue */ |
166 | head = vq->free_head; | 168 | head = vq->free_head; |
@@ -174,13 +176,6 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
174 | return head; | 176 | return head; |
175 | } | 177 | } |
176 | 178 | ||
177 | int virtqueue_get_queue_index(struct virtqueue *_vq) | ||
178 | { | ||
179 | struct vring_virtqueue *vq = to_vvq(_vq); | ||
180 | return vq->queue_index; | ||
181 | } | ||
182 | EXPORT_SYMBOL_GPL(virtqueue_get_queue_index); | ||
183 | |||
184 | /** | 179 | /** |
185 | * virtqueue_add_buf - expose buffer to other end | 180 | * virtqueue_add_buf - expose buffer to other end |
186 | * @vq: the struct virtqueue we're talking about. | 181 | * @vq: the struct virtqueue we're talking about. |
@@ -193,10 +188,7 @@ EXPORT_SYMBOL_GPL(virtqueue_get_queue_index); | |||
193 | * Caller must ensure we don't call this with other virtqueue operations | 188 | * Caller must ensure we don't call this with other virtqueue operations |
194 | * at the same time (except where noted). | 189 | * at the same time (except where noted). |
195 | * | 190 | * |
196 | * Returns remaining capacity of queue or a negative error | 191 | * Returns zero or a negative error (ie. ENOSPC, ENOMEM). |
197 | * (ie. ENOSPC). Note that it only really makes sense to treat all | ||
198 | * positive return values as "available": indirect buffers mean that | ||
199 | * we can put an entire sg[] array inside a single queue entry. | ||
200 | */ | 192 | */ |
201 | int virtqueue_add_buf(struct virtqueue *_vq, | 193 | int virtqueue_add_buf(struct virtqueue *_vq, |
202 | struct scatterlist sg[], | 194 | struct scatterlist sg[], |
@@ -228,7 +220,7 @@ int virtqueue_add_buf(struct virtqueue *_vq, | |||
228 | 220 | ||
229 | /* If the host supports indirect descriptor tables, and we have multiple | 221 | /* If the host supports indirect descriptor tables, and we have multiple |
230 | * buffers, then go indirect. FIXME: tune this threshold */ | 222 | * buffers, then go indirect. FIXME: tune this threshold */ |
231 | if (vq->indirect && (out + in) > 1 && vq->num_free) { | 223 | if (vq->indirect && (out + in) > 1 && vq->vq.num_free) { |
232 | head = vring_add_indirect(vq, sg, out, in, gfp); | 224 | head = vring_add_indirect(vq, sg, out, in, gfp); |
233 | if (likely(head >= 0)) | 225 | if (likely(head >= 0)) |
234 | goto add_head; | 226 | goto add_head; |
@@ -237,9 +229,9 @@ int virtqueue_add_buf(struct virtqueue *_vq, | |||
237 | BUG_ON(out + in > vq->vring.num); | 229 | BUG_ON(out + in > vq->vring.num); |
238 | BUG_ON(out + in == 0); | 230 | BUG_ON(out + in == 0); |
239 | 231 | ||
240 | if (vq->num_free < out + in) { | 232 | if (vq->vq.num_free < out + in) { |
241 | pr_debug("Can't add buf len %i - avail = %i\n", | 233 | pr_debug("Can't add buf len %i - avail = %i\n", |
242 | out + in, vq->num_free); | 234 | out + in, vq->vq.num_free); |
243 | /* FIXME: for historical reasons, we force a notify here if | 235 | /* FIXME: for historical reasons, we force a notify here if |
244 | * there are outgoing parts to the buffer. Presumably the | 236 | * there are outgoing parts to the buffer. Presumably the |
245 | * host should service the ring ASAP. */ | 237 | * host should service the ring ASAP. */ |
@@ -250,7 +242,7 @@ int virtqueue_add_buf(struct virtqueue *_vq, | |||
250 | } | 242 | } |
251 | 243 | ||
252 | /* We're about to use some buffers from the free list. */ | 244 | /* We're about to use some buffers from the free list. */ |
253 | vq->num_free -= out + in; | 245 | vq->vq.num_free -= out + in; |
254 | 246 | ||
255 | head = vq->free_head; | 247 | head = vq->free_head; |
256 | for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { | 248 | for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) { |
@@ -296,7 +288,7 @@ add_head: | |||
296 | pr_debug("Added buffer head %i to %p\n", head, vq); | 288 | pr_debug("Added buffer head %i to %p\n", head, vq); |
297 | END_USE(vq); | 289 | END_USE(vq); |
298 | 290 | ||
299 | return vq->num_free; | 291 | return 0; |
300 | } | 292 | } |
301 | EXPORT_SYMBOL_GPL(virtqueue_add_buf); | 293 | EXPORT_SYMBOL_GPL(virtqueue_add_buf); |
302 | 294 | ||
@@ -393,13 +385,13 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head) | |||
393 | 385 | ||
394 | while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) { | 386 | while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) { |
395 | i = vq->vring.desc[i].next; | 387 | i = vq->vring.desc[i].next; |
396 | vq->num_free++; | 388 | vq->vq.num_free++; |
397 | } | 389 | } |
398 | 390 | ||
399 | vq->vring.desc[i].next = vq->free_head; | 391 | vq->vring.desc[i].next = vq->free_head; |
400 | vq->free_head = head; | 392 | vq->free_head = head; |
401 | /* Plus final descriptor */ | 393 | /* Plus final descriptor */ |
402 | vq->num_free++; | 394 | vq->vq.num_free++; |
403 | } | 395 | } |
404 | 396 | ||
405 | static inline bool more_used(const struct vring_virtqueue *vq) | 397 | static inline bool more_used(const struct vring_virtqueue *vq) |
@@ -599,7 +591,7 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq) | |||
599 | return buf; | 591 | return buf; |
600 | } | 592 | } |
601 | /* That should have freed everything. */ | 593 | /* That should have freed everything. */ |
602 | BUG_ON(vq->num_free != vq->vring.num); | 594 | BUG_ON(vq->vq.num_free != vq->vring.num); |
603 | 595 | ||
604 | END_USE(vq); | 596 | END_USE(vq); |
605 | return NULL; | 597 | return NULL; |
@@ -653,12 +645,13 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, | |||
653 | vq->vq.callback = callback; | 645 | vq->vq.callback = callback; |
654 | vq->vq.vdev = vdev; | 646 | vq->vq.vdev = vdev; |
655 | vq->vq.name = name; | 647 | vq->vq.name = name; |
648 | vq->vq.num_free = num; | ||
649 | vq->vq.index = index; | ||
656 | vq->notify = notify; | 650 | vq->notify = notify; |
657 | vq->weak_barriers = weak_barriers; | 651 | vq->weak_barriers = weak_barriers; |
658 | vq->broken = false; | 652 | vq->broken = false; |
659 | vq->last_used_idx = 0; | 653 | vq->last_used_idx = 0; |
660 | vq->num_added = 0; | 654 | vq->num_added = 0; |
661 | vq->queue_index = index; | ||
662 | list_add_tail(&vq->vq.list, &vdev->vqs); | 655 | list_add_tail(&vq->vq.list, &vdev->vqs); |
663 | #ifdef DEBUG | 656 | #ifdef DEBUG |
664 | vq->in_use = false; | 657 | vq->in_use = false; |
@@ -673,7 +666,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, | |||
673 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; | 666 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; |
674 | 667 | ||
675 | /* Put everything in free lists. */ | 668 | /* Put everything in free lists. */ |
676 | vq->num_free = num; | ||
677 | vq->free_head = 0; | 669 | vq->free_head = 0; |
678 | for (i = 0; i < num-1; i++) { | 670 | for (i = 0; i < num-1; i++) { |
679 | vq->vring.desc[i].next = i+1; | 671 | vq->vring.desc[i].next = i+1; |