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