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

w1-gpio: add external pull-up enable callback

On embedded devices, sleep mode conditions can be tricky to handle,
Especially when processors tend to pull-down the w1 bus during sleep. Bus
slaves (such as the ds2760) may interpret this as a reason for power-down
conditions and entirely switch off the device.

This patch adds a callback function pointer to let users switch on and off
the external pull-up resistor. This lets the outside world know whether
the processor is currently actively driving the bus or not.

When this callback is not provided, the code behaviour won't change.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Acked-by: Ville Syrjala <syrjala@sci.fi>
Acked-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

Daniel Mack and committed by
Linus Torvalds
c8a06c1e 99162195

+36
+35
drivers/w1/masters/w1-gpio.c
··· 74 74 if (err) 75 75 goto free_gpio; 76 76 77 + if (pdata->enable_external_pullup) 78 + pdata->enable_external_pullup(1); 79 + 77 80 platform_set_drvdata(pdev, master); 78 81 79 82 return 0; ··· 94 91 struct w1_bus_master *master = platform_get_drvdata(pdev); 95 92 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; 96 93 94 + if (pdata->enable_external_pullup) 95 + pdata->enable_external_pullup(0); 96 + 97 97 w1_remove_master_device(master); 98 98 gpio_free(pdata->pin); 99 99 kfree(master); ··· 104 98 return 0; 105 99 } 106 100 101 + #ifdef CONFIG_PM 102 + 103 + static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state) 104 + { 105 + struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; 106 + 107 + if (pdata->enable_external_pullup) 108 + pdata->enable_external_pullup(0); 109 + 110 + return 0; 111 + } 112 + 113 + static int w1_gpio_resume(struct platform_device *pdev) 114 + { 115 + struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; 116 + 117 + if (pdata->enable_external_pullup) 118 + pdata->enable_external_pullup(1); 119 + 120 + return 0; 121 + } 122 + 123 + #else 124 + #define w1_gpio_suspend NULL 125 + #define w1_gpio_resume NULL 126 + #endif 127 + 107 128 static struct platform_driver w1_gpio_driver = { 108 129 .driver = { 109 130 .name = "w1-gpio", 110 131 .owner = THIS_MODULE, 111 132 }, 112 133 .remove = __exit_p(w1_gpio_remove), 134 + .suspend = w1_gpio_suspend, 135 + .resume = w1_gpio_resume, 113 136 }; 114 137 115 138 static int __init w1_gpio_init(void)
+1
include/linux/w1-gpio.h
··· 18 18 struct w1_gpio_platform_data { 19 19 unsigned int pin; 20 20 unsigned int is_open_drain:1; 21 + void (*enable_external_pullup)(int enable); 21 22 }; 22 23 23 24 #endif /* _LINUX_W1_GPIO_H */