diff options
author | Daniel Mack <daniel@caiaq.de> | 2009-06-17 19:28:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 16:03:58 -0400 |
commit | c8a06c1ef0bc45915fc45a170c7c60426971304c (patch) | |
tree | 9e8f5d3890766bca481c15aac69ef96f52612874 /drivers/w1 | |
parent | 9916219579d078c80377dd3988c2cc213536d868 (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>
Diffstat (limited to 'drivers/w1')
-rw-r--r-- | drivers/w1/masters/w1-gpio.c | 35 |
1 files changed, 35 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 | |||
109 | static 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 | |||
119 | static 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 | |||
101 | static struct platform_driver w1_gpio_driver = { | 134 | static 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 | ||
109 | static int __init w1_gpio_init(void) | 144 | static int __init w1_gpio_init(void) |