aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-lpss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-lpss.c')
-rw-r--r--drivers/pwm/pwm-lpss.c137
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
24static 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
42struct pwm_lpss_boardinfo { 38/* BayTrail */
43 unsigned long clk_rate; 39const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
40 .clk_rate = 25000000
44}; 41};
42EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
45 43
46/* BayTrail */ 44/* Braswell */
47static const struct pwm_lpss_boardinfo byt_info = { 45const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
48 25000000 46 .clk_rate = 19200000
49}; 47};
48EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
50 49
51static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip) 50static 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
121static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, 120struct 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}
148EXPORT_SYMBOL_GPL(pwm_lpss_probe);
150 149
151static int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) 150int 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 159EXPORT_SYMBOL_GPL(pwm_lpss_remove);
161static 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
181static 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
189static 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};
194MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
195
196static 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
203static 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
225static 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
232static const struct acpi_device_id pwm_lpss_acpi_match[] = {
233 { "80860F09", (unsigned long)&byt_info },
234 { },
235};
236MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
237
238static 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
247static 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}
256module_init(pwm_init);
257
258static 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}
265module_exit(pwm_exit);
266 160
267MODULE_DESCRIPTION("PWM driver for Intel LPSS"); 161MODULE_DESCRIPTION("PWM driver for Intel LPSS");
268MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 162MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
269MODULE_LICENSE("GPL v2"); 163MODULE_LICENSE("GPL v2");
270MODULE_ALIAS("platform:pwm-lpss");