Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

W1: ds2490.c optimize ds_set_pullup

Optimize the ds_set_pullup function. For a strong pullup to be sent the
ds2490 has to have both the strong pullup mode enabled, and the specific
write operation has to have the SPU bit enabled. Previously the write
always had the SPU bit enabled and both the duration and model was set
when a strong pullup was requested. Now the strong pullup mode is enabled
at initialization time, the delay is updated only when the value changes,
and the write SPU bit is set only when a strong pullup is required. This
removes two or three bus transactions per strong pullup request.

Signed-off-by: David Fries <david@fries.net>
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Fries and committed by
Linus Torvalds
ade6d810 3823ee44

+45 -19
+45 -19
drivers/w1/masters/ds2490.c
··· 141 141 * 0: pullup not active, else duration in milliseconds 142 142 */ 143 143 int spu_sleep; 144 + /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup 145 + * should be active or not for writes. 146 + */ 147 + u16 spu_bit; 144 148 145 149 struct w1_bus_master master; 146 150 }; ··· 315 311 } 316 312 } 317 313 314 + static void ds_reset_device(struct ds_device *dev) 315 + { 316 + ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); 317 + /* Always allow strong pullup which allow individual writes to use 318 + * the strong pullup. 319 + */ 320 + if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE)) 321 + printk(KERN_ERR "ds_reset_device: " 322 + "Error allowing strong pullup\n"); 323 + /* Chip strong pullup time was cleared. */ 324 + if (dev->spu_sleep) { 325 + /* lower 4 bits are 0, see ds_set_pullup */ 326 + u8 del = dev->spu_sleep>>4; 327 + if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del)) 328 + printk(KERN_ERR "ds_reset_device: " 329 + "Error setting duration\n"); 330 + } 331 + } 332 + 318 333 static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size) 319 334 { 320 335 int count, err; ··· 467 444 468 445 if (err >= 16 && st->status & ST_EPOF) { 469 446 printk(KERN_INFO "Resetting device after ST_EPOF.\n"); 470 - ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); 447 + ds_reset_device(dev); 471 448 /* Always dump the device status. */ 472 449 count = 101; 473 450 } ··· 532 509 533 510 static int ds_set_pullup(struct ds_device *dev, int delay) 534 511 { 535 - int err; 512 + int err = 0; 536 513 u8 del = 1 + (u8)(delay >> 4); 514 + /* Just storing delay would not get the trunication and roundup. */ 515 + int ms = del<<4; 537 516 538 - dev->spu_sleep = 0; 539 - err = ds_send_control_mode(dev, MOD_PULSE_EN, delay ? PULSE_SPUE : 0); 517 + /* Enable spu_bit if a delay is set. */ 518 + dev->spu_bit = delay ? COMM_SPU : 0; 519 + /* If delay is zero, it has already been disabled, if the time is 520 + * the same as the hardware was last programmed to, there is also 521 + * nothing more to do. Compare with the recalculated value ms 522 + * rather than del or delay which can have a different value. 523 + */ 524 + if (delay == 0 || ms == dev->spu_sleep) 525 + return err; 526 + 527 + err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); 540 528 if (err) 541 529 return err; 542 530 543 - if (delay) { 544 - err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del); 545 - if (err) 546 - return err; 547 - 548 - /* Just storing delay would not get the trunication and 549 - * roundup. 550 - */ 551 - dev->spu_sleep = del<<4; 552 - } 531 + dev->spu_sleep = ms; 553 532 554 533 return err; 555 534 } ··· 602 577 struct ds_status st; 603 578 u8 rbyte; 604 579 605 - err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte); 580 + err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte); 606 581 if (err) 607 582 return err; 608 583 609 - if (dev->spu_sleep) 584 + if (dev->spu_bit) 610 585 msleep(dev->spu_sleep); 611 586 612 587 err = ds_wait_status(dev, &st); ··· 673 648 if (err < 0) 674 649 return err; 675 650 676 - err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len); 651 + err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len); 677 652 if (err) 678 653 return err; 679 654 680 - if (dev->spu_sleep) 655 + if (dev->spu_bit) 681 656 msleep(dev->spu_sleep); 682 657 683 658 ds_wait_status(dev, &st); ··· 874 849 * the input buffer. This will cause the next read to fail 875 850 * see the note in ds_recv_data. 876 851 */ 877 - ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0); 852 + ds_reset_device(dev); 878 853 879 854 dev->master.data = dev; 880 855 dev->master.touch_bit = &ds9490r_touch_bit; ··· 917 892 return -ENOMEM; 918 893 } 919 894 dev->spu_sleep = 0; 895 + dev->spu_bit = 0; 920 896 dev->udev = usb_get_dev(udev); 921 897 if (!dev->udev) { 922 898 err = -ENOMEM;