diff options
Diffstat (limited to 'drivers/pwm/pwm-lpss.c')
-rw-r--r-- | drivers/pwm/pwm-lpss.c | 137 |
1 files changed, 15 insertions, 122 deletions
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c index 4df994f72d96..e9798253a16f 100644 --- a/drivers/pwm/pwm-lpss.c +++ b/drivers/pwm/pwm-lpss.c | |||
@@ -13,15 +13,11 @@ | |||
13 | * published by the Free Software Foundation. | 13 | * published by the Free Software Foundation. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/acpi.h> | 16 | #include <linux/io.h> |
17 | #include <linux/device.h> | ||
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
20 | #include <linux/pwm.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/pci.h> | ||
23 | 19 | ||
24 | static int pci_drv, plat_drv; /* So we know which drivers registered */ | 20 | #include "pwm-lpss.h" |
25 | 21 | ||
26 | #define PWM 0x00000000 | 22 | #define PWM 0x00000000 |
27 | #define PWM_ENABLE BIT(31) | 23 | #define PWM_ENABLE BIT(31) |
@@ -39,14 +35,17 @@ struct pwm_lpss_chip { | |||
39 | unsigned long clk_rate; | 35 | unsigned long clk_rate; |
40 | }; | 36 | }; |
41 | 37 | ||
42 | struct pwm_lpss_boardinfo { | 38 | /* BayTrail */ |
43 | unsigned long clk_rate; | 39 | const struct pwm_lpss_boardinfo pwm_lpss_byt_info = { |
40 | .clk_rate = 25000000 | ||
44 | }; | 41 | }; |
42 | EXPORT_SYMBOL_GPL(pwm_lpss_byt_info); | ||
45 | 43 | ||
46 | /* BayTrail */ | 44 | /* Braswell */ |
47 | static const struct pwm_lpss_boardinfo byt_info = { | 45 | const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = { |
48 | 25000000 | 46 | .clk_rate = 19200000 |
49 | }; | 47 | }; |
48 | EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info); | ||
50 | 49 | ||
51 | static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) | 50 | static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) |
52 | { | 51 | { |
@@ -118,9 +117,8 @@ static const struct pwm_ops pwm_lpss_ops = { | |||
118 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
119 | }; | 118 | }; |
120 | 119 | ||
121 | static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, | 120 | struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r, |
122 | struct resource *r, | 121 | const struct pwm_lpss_boardinfo *info) |
123 | const struct pwm_lpss_boardinfo *info) | ||
124 | { | 122 | { |
125 | struct pwm_lpss_chip *lpwm; | 123 | struct pwm_lpss_chip *lpwm; |
126 | int ret; | 124 | int ret; |
@@ -147,8 +145,9 @@ static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, | |||
147 | 145 | ||
148 | return lpwm; | 146 | return lpwm; |
149 | } | 147 | } |
148 | EXPORT_SYMBOL_GPL(pwm_lpss_probe); | ||
150 | 149 | ||
151 | static int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) | 150 | int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) |
152 | { | 151 | { |
153 | u32 ctrl; | 152 | u32 ctrl; |
154 | 153 | ||
@@ -157,114 +156,8 @@ static int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) | |||
157 | 156 | ||
158 | return pwmchip_remove(&lpwm->chip); | 157 | return pwmchip_remove(&lpwm->chip); |
159 | } | 158 | } |
160 | 159 | EXPORT_SYMBOL_GPL(pwm_lpss_remove); | |
161 | static int pwm_lpss_probe_pci(struct pci_dev *pdev, | ||
162 | const struct pci_device_id *id) | ||
163 | { | ||
164 | const struct pwm_lpss_boardinfo *info; | ||
165 | struct pwm_lpss_chip *lpwm; | ||
166 | int err; | ||
167 | |||
168 | err = pci_enable_device(pdev); | ||
169 | if (err < 0) | ||
170 | return err; | ||
171 | |||
172 | info = (struct pwm_lpss_boardinfo *)id->driver_data; | ||
173 | lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info); | ||
174 | if (IS_ERR(lpwm)) | ||
175 | return PTR_ERR(lpwm); | ||
176 | |||
177 | pci_set_drvdata(pdev, lpwm); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static void pwm_lpss_remove_pci(struct pci_dev *pdev) | ||
182 | { | ||
183 | struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev); | ||
184 | |||
185 | pwm_lpss_remove(lpwm); | ||
186 | pci_disable_device(pdev); | ||
187 | } | ||
188 | |||
189 | static struct pci_device_id pwm_lpss_pci_ids[] = { | ||
190 | { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&byt_info}, | ||
191 | { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&byt_info}, | ||
192 | { }, | ||
193 | }; | ||
194 | MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids); | ||
195 | |||
196 | static struct pci_driver pwm_lpss_driver_pci = { | ||
197 | .name = "pwm-lpss", | ||
198 | .id_table = pwm_lpss_pci_ids, | ||
199 | .probe = pwm_lpss_probe_pci, | ||
200 | .remove = pwm_lpss_remove_pci, | ||
201 | }; | ||
202 | |||
203 | static int pwm_lpss_probe_platform(struct platform_device *pdev) | ||
204 | { | ||
205 | const struct pwm_lpss_boardinfo *info; | ||
206 | const struct acpi_device_id *id; | ||
207 | struct pwm_lpss_chip *lpwm; | ||
208 | struct resource *r; | ||
209 | |||
210 | id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); | ||
211 | if (!id) | ||
212 | return -ENODEV; | ||
213 | |||
214 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
215 | |||
216 | info = (struct pwm_lpss_boardinfo *)id->driver_data; | ||
217 | lpwm = pwm_lpss_probe(&pdev->dev, r, info); | ||
218 | if (IS_ERR(lpwm)) | ||
219 | return PTR_ERR(lpwm); | ||
220 | |||
221 | platform_set_drvdata(pdev, lpwm); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int pwm_lpss_remove_platform(struct platform_device *pdev) | ||
226 | { | ||
227 | struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev); | ||
228 | |||
229 | return pwm_lpss_remove(lpwm); | ||
230 | } | ||
231 | |||
232 | static const struct acpi_device_id pwm_lpss_acpi_match[] = { | ||
233 | { "80860F09", (unsigned long)&byt_info }, | ||
234 | { }, | ||
235 | }; | ||
236 | MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match); | ||
237 | |||
238 | static struct platform_driver pwm_lpss_driver_platform = { | ||
239 | .driver = { | ||
240 | .name = "pwm-lpss", | ||
241 | .acpi_match_table = pwm_lpss_acpi_match, | ||
242 | }, | ||
243 | .probe = pwm_lpss_probe_platform, | ||
244 | .remove = pwm_lpss_remove_platform, | ||
245 | }; | ||
246 | |||
247 | static int __init pwm_init(void) | ||
248 | { | ||
249 | pci_drv = pci_register_driver(&pwm_lpss_driver_pci); | ||
250 | plat_drv = platform_driver_register(&pwm_lpss_driver_platform); | ||
251 | if (pci_drv && plat_drv) | ||
252 | return pci_drv; | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | module_init(pwm_init); | ||
257 | |||
258 | static void __exit pwm_exit(void) | ||
259 | { | ||
260 | if (!pci_drv) | ||
261 | pci_unregister_driver(&pwm_lpss_driver_pci); | ||
262 | if (!plat_drv) | ||
263 | platform_driver_unregister(&pwm_lpss_driver_platform); | ||
264 | } | ||
265 | module_exit(pwm_exit); | ||
266 | 160 | ||
267 | MODULE_DESCRIPTION("PWM driver for Intel LPSS"); | 161 | MODULE_DESCRIPTION("PWM driver for Intel LPSS"); |
268 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | 162 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); |
269 | MODULE_LICENSE("GPL v2"); | 163 | MODULE_LICENSE("GPL v2"); |
270 | MODULE_ALIAS("platform:pwm-lpss"); | ||