aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2009-06-17 19:28:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:03:58 -0400
commitc8a06c1ef0bc45915fc45a170c7c60426971304c (patch)
tree9e8f5d3890766bca481c15aac69ef96f52612874
parent9916219579d078c80377dd3988c2cc213536d868 (diff)
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>
-rw-r--r--drivers/w1/masters/w1-gpio.c35
-rw-r--r--include/linux/w1-gpio.h1
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index a411702413d6..6f8866d6a905 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -74,6 +74,9 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
74 if (err) 74 if (err)
75 goto free_gpio; 75 goto free_gpio;
76 76
77 if (pdata->enable_external_pullup)
78 pdata->enable_external_pullup(1);
79
77 platform_set_drvdata(pdev, master); 80 platform_set_drvdata(pdev, master);
78 81
79 return 0; 82 return 0;
@@ -91,6 +94,9 @@ static int __exit w1_gpio_remove(struct platform_device *pdev)
91 struct w1_bus_master *master = platform_get_drvdata(pdev); 94 struct w1_bus_master *master = platform_get_drvdata(pdev);
92 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; 95 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
93 96
97 if (pdata->enable_external_pullup)
98 pdata->enable_external_pullup(0);
99
94 w1_remove_master_device(master); 100 w1_remove_master_device(master);
95 gpio_free(pdata->pin); 101 gpio_free(pdata->pin);
96 kfree(master); 102 kfree(master);
@@ -98,12 +104,41 @@ static int __exit w1_gpio_remove(struct platform_device *pdev)
98 return 0; 104 return 0;
99} 105}
100 106
107#ifdef CONFIG_PM
108
109static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)
110{
111 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
112
113 if (pdata->enable_external_pullup)
114 pdata->enable_external_pullup(0);
115
116 return 0;
117}
118
119static int w1_gpio_resume(struct platform_device *pdev)
120{
121 struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
122
123 if (pdata->enable_external_pullup)
124 pdata->enable_external_pullup(1);
125
126 return 0;
127}
128
129#else
130#define w1_gpio_suspend NULL
131#define w1_gpio_resume NULL
132#endif
133
101static struct platform_driver w1_gpio_driver = { 134static struct platform_driver w1_gpio_driver = {
102 .driver = { 135 .driver = {
103 .name = "w1-gpio", 136 .name = "w1-gpio",
104 .owner = THIS_MODULE, 137 .owner = THIS_MODULE,
105 }, 138 },
106 .remove = __exit_p(w1_gpio_remove), 139 .remove = __exit_p(w1_gpio_remove),
140 .suspend = w1_gpio_suspend,
141 .resume = w1_gpio_resume,
107}; 142};
108 143
109static int __init w1_gpio_init(void) 144static int __init w1_gpio_init(void)
diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h
index 9797fec7748a..3adeff82212f 100644
--- a/include/linux/w1-gpio.h
+++ b/include/linux/w1-gpio.h
@@ -18,6 +18,7 @@
18struct w1_gpio_platform_data { 18struct w1_gpio_platform_data {
19 unsigned int pin; 19 unsigned int pin;
20 unsigned int is_open_drain:1; 20 unsigned int is_open_drain:1;
21 void (*enable_external_pullup)(int enable);
21}; 22};
22 23
23#endif /* _LINUX_W1_GPIO_H */ 24#endif /* _LINUX_W1_GPIO_H */