diff options
Diffstat (limited to 'drivers/pwm/pwm-pxa.c')
-rw-r--r-- | drivers/pwm/pwm-pxa.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index a4d2164aaf55..8d995731cef8 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * 2008-02-13 initial version | 10 | * 2008-02-13 initial version |
11 | * eric miao <eric.miao@marvell.com> | 11 | * eric miao <eric.miao@marvell.com> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/pwm.h> | 21 | #include <linux/pwm.h> |
22 | #include <linux/of_device.h> | ||
22 | 23 | ||
23 | #include <asm/div64.h> | 24 | #include <asm/div64.h> |
24 | 25 | ||
@@ -124,6 +125,46 @@ static struct pwm_ops pxa_pwm_ops = { | |||
124 | .owner = THIS_MODULE, | 125 | .owner = THIS_MODULE, |
125 | }; | 126 | }; |
126 | 127 | ||
128 | #ifdef CONFIG_OF | ||
129 | /* | ||
130 | * Device tree users must create one device instance for each pwm channel. | ||
131 | * Hence we dispense with the HAS_SECONDARY_PWM and "tell" the original driver | ||
132 | * code that this is a single channel pxa25x-pwm. Currently all devices are | ||
133 | * supported identically. | ||
134 | */ | ||
135 | static struct of_device_id pwm_of_match[] = { | ||
136 | { .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0]}, | ||
137 | { .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0]}, | ||
138 | { .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0]}, | ||
139 | { .compatible = "marvell,pxa910-pwm", .data = &pwm_id_table[0]}, | ||
140 | { } | ||
141 | }; | ||
142 | MODULE_DEVICE_TABLE(of, pwm_of_match); | ||
143 | #else | ||
144 | #define pwm_of_match NULL | ||
145 | #endif | ||
146 | |||
147 | static const struct platform_device_id *pxa_pwm_get_id_dt(struct device *dev) | ||
148 | { | ||
149 | const struct of_device_id *id = of_match_device(pwm_of_match, dev); | ||
150 | |||
151 | return id ? id->data : NULL; | ||
152 | } | ||
153 | |||
154 | static struct pwm_device * | ||
155 | pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) | ||
156 | { | ||
157 | struct pwm_device *pwm; | ||
158 | |||
159 | pwm = pwm_request_from_chip(pc, 0, NULL); | ||
160 | if (IS_ERR(pwm)) | ||
161 | return pwm; | ||
162 | |||
163 | pwm_set_period(pwm, args->args[0]); | ||
164 | |||
165 | return pwm; | ||
166 | } | ||
167 | |||
127 | static int pwm_probe(struct platform_device *pdev) | 168 | static int pwm_probe(struct platform_device *pdev) |
128 | { | 169 | { |
129 | const struct platform_device_id *id = platform_get_device_id(pdev); | 170 | const struct platform_device_id *id = platform_get_device_id(pdev); |
@@ -131,6 +172,12 @@ static int pwm_probe(struct platform_device *pdev) | |||
131 | struct resource *r; | 172 | struct resource *r; |
132 | int ret = 0; | 173 | int ret = 0; |
133 | 174 | ||
175 | if (IS_ENABLED(CONFIG_OF) && id == NULL) | ||
176 | id = pxa_pwm_get_id_dt(&pdev->dev); | ||
177 | |||
178 | if (id == NULL) | ||
179 | return -EINVAL; | ||
180 | |||
134 | pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); | 181 | pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); |
135 | if (pwm == NULL) { | 182 | if (pwm == NULL) { |
136 | dev_err(&pdev->dev, "failed to allocate memory\n"); | 183 | dev_err(&pdev->dev, "failed to allocate memory\n"); |
@@ -146,6 +193,11 @@ static int pwm_probe(struct platform_device *pdev) | |||
146 | pwm->chip.base = -1; | 193 | pwm->chip.base = -1; |
147 | pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; | 194 | pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; |
148 | 195 | ||
196 | if (IS_ENABLED(CONFIG_OF)) { | ||
197 | pwm->chip.of_xlate = pxa_pwm_of_xlate; | ||
198 | pwm->chip.of_pwm_n_cells = 1; | ||
199 | } | ||
200 | |||
149 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 201 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
150 | pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); | 202 | pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); |
151 | if (IS_ERR(pwm->mmio_base)) | 203 | if (IS_ERR(pwm->mmio_base)) |
@@ -176,6 +228,7 @@ static struct platform_driver pwm_driver = { | |||
176 | .driver = { | 228 | .driver = { |
177 | .name = "pxa25x-pwm", | 229 | .name = "pxa25x-pwm", |
178 | .owner = THIS_MODULE, | 230 | .owner = THIS_MODULE, |
231 | .of_match_table = pwm_of_match, | ||
179 | }, | 232 | }, |
180 | .probe = pwm_probe, | 233 | .probe = pwm_probe, |
181 | .remove = pwm_remove, | 234 | .remove = pwm_remove, |