aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm
diff options
context:
space:
mode:
authorCooper Jr., Franklin <fcooper@ti.com>2016-03-07 14:33:56 -0500
committerThierry Reding <thierry.reding@gmail.com>2016-07-11 06:07:18 -0400
commitcc37655e6bbf83ded1e4d1d7ffd977786a845a67 (patch)
tree2edeb564a96d7694122764fa745546a4519465af /drivers/pwm
parentae5200d2271691b28aff8d0409fbefd4644ff507 (diff)
pwm: pwm-ti*: Remove support for local clock gating
The PWMSS local clock gating registers have no real purpose on OMAP ARM devices. These registers were left over registers from DSP IP where the PRCM doesn't exist. There is a silicon bug where gating and ungating clocks don't function properly. TRMs will be update to indicate that these registers shouldn't be touched. Therefore, all code that accesses the PWMSS_CLKCONFIG or PWMSS_CLKSTATUS will be removed by this patch with zero loss of functionality by the ECAP and EPWM drivers. Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r--drivers/pwm/pwm-tiecap.c28
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c29
-rw-r--r--drivers/pwm/pwm-tipwmss.c49
-rw-r--r--drivers/pwm/pwm-tipwmss.h39
4 files changed, 0 insertions, 145 deletions
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index 0dc5b97a7524..6ec342dd3eea 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -27,8 +27,6 @@
27#include <linux/pwm.h> 27#include <linux/pwm.h>
28#include <linux/of_device.h> 28#include <linux/of_device.h>
29 29
30#include "pwm-tipwmss.h"
31
32/* ECAP registers and bits definitions */ 30/* ECAP registers and bits definitions */
33#define CAP1 0x08 31#define CAP1 0x08
34#define CAP2 0x0C 32#define CAP2 0x0C
@@ -208,7 +206,6 @@ static int ecap_pwm_probe(struct platform_device *pdev)
208 struct resource *r; 206 struct resource *r;
209 struct clk *clk; 207 struct clk *clk;
210 struct ecap_pwm_chip *pc; 208 struct ecap_pwm_chip *pc;
211 u16 status;
212 209
213 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); 210 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
214 if (!pc) 211 if (!pc)
@@ -252,40 +249,15 @@ static int ecap_pwm_probe(struct platform_device *pdev)
252 } 249 }
253 250
254 pm_runtime_enable(&pdev->dev); 251 pm_runtime_enable(&pdev->dev);
255 pm_runtime_get_sync(&pdev->dev);
256
257 status = pwmss_submodule_state_change(pdev->dev.parent,
258 PWMSS_ECAPCLK_EN);
259 if (!(status & PWMSS_ECAPCLK_EN_ACK)) {
260 dev_err(&pdev->dev, "PWMSS config space clock enable failed\n");
261 ret = -EINVAL;
262 goto pwmss_clk_failure;
263 }
264
265 pm_runtime_put_sync(&pdev->dev);
266 252
267 platform_set_drvdata(pdev, pc); 253 platform_set_drvdata(pdev, pc);
268 return 0; 254 return 0;
269
270pwmss_clk_failure:
271 pm_runtime_put_sync(&pdev->dev);
272 pm_runtime_disable(&pdev->dev);
273 pwmchip_remove(&pc->chip);
274 return ret;
275} 255}
276 256
277static int ecap_pwm_remove(struct platform_device *pdev) 257static int ecap_pwm_remove(struct platform_device *pdev)
278{ 258{
279 struct ecap_pwm_chip *pc = platform_get_drvdata(pdev); 259 struct ecap_pwm_chip *pc = platform_get_drvdata(pdev);
280 260
281 pm_runtime_get_sync(&pdev->dev);
282 /*
283 * Due to hardware misbehaviour, acknowledge of the stop_req
284 * is missing. Hence checking of the status bit skipped.
285 */
286 pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ);
287 pm_runtime_put_sync(&pdev->dev);
288
289 pm_runtime_disable(&pdev->dev); 261 pm_runtime_disable(&pdev->dev);
290 return pwmchip_remove(&pc->chip); 262 return pwmchip_remove(&pc->chip);
291} 263}
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index c791720d27b0..b5c6b0636893 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -27,8 +27,6 @@
27#include <linux/pm_runtime.h> 27#include <linux/pm_runtime.h>
28#include <linux/of_device.h> 28#include <linux/of_device.h>
29 29
30#include "pwm-tipwmss.h"
31
32/* EHRPWM registers and bits definitions */ 30/* EHRPWM registers and bits definitions */
33 31
34/* Time base module registers */ 32/* Time base module registers */
@@ -439,7 +437,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
439 struct resource *r; 437 struct resource *r;
440 struct clk *clk; 438 struct clk *clk;
441 struct ehrpwm_pwm_chip *pc; 439 struct ehrpwm_pwm_chip *pc;
442 u16 status;
443 440
444 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); 441 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
445 if (!pc) 442 if (!pc)
@@ -496,27 +493,9 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
496 } 493 }
497 494
498 pm_runtime_enable(&pdev->dev); 495 pm_runtime_enable(&pdev->dev);
499 pm_runtime_get_sync(&pdev->dev);
500
501 status = pwmss_submodule_state_change(pdev->dev.parent,
502 PWMSS_EPWMCLK_EN);
503 if (!(status & PWMSS_EPWMCLK_EN_ACK)) {
504 dev_err(&pdev->dev, "PWMSS config space clock enable failed\n");
505 ret = -EINVAL;
506 goto pwmss_clk_failure;
507 }
508
509 pm_runtime_put_sync(&pdev->dev);
510 496
511 platform_set_drvdata(pdev, pc); 497 platform_set_drvdata(pdev, pc);
512 return 0; 498 return 0;
513
514pwmss_clk_failure:
515 pm_runtime_put_sync(&pdev->dev);
516 pm_runtime_disable(&pdev->dev);
517 pwmchip_remove(&pc->chip);
518 clk_unprepare(pc->tbclk);
519 return ret;
520} 499}
521 500
522static int ehrpwm_pwm_remove(struct platform_device *pdev) 501static int ehrpwm_pwm_remove(struct platform_device *pdev)
@@ -525,14 +504,6 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev)
525 504
526 clk_unprepare(pc->tbclk); 505 clk_unprepare(pc->tbclk);
527 506
528 pm_runtime_get_sync(&pdev->dev);
529 /*
530 * Due to hardware misbehaviour, acknowledge of the stop_req
531 * is missing. Hence checking of the status bit skipped.
532 */
533 pwmss_submodule_state_change(pdev->dev.parent, PWMSS_EPWMCLK_STOP_REQ);
534 pm_runtime_put_sync(&pdev->dev);
535
536 pm_runtime_put_sync(&pdev->dev); 507 pm_runtime_put_sync(&pdev->dev);
537 pm_runtime_disable(&pdev->dev); 508 pm_runtime_disable(&pdev->dev);
538 return pwmchip_remove(&pc->chip); 509 return pwmchip_remove(&pc->chip);
diff --git a/drivers/pwm/pwm-tipwmss.c b/drivers/pwm/pwm-tipwmss.c
index 5cf65a15d021..829f4991c96f 100644
--- a/drivers/pwm/pwm-tipwmss.c
+++ b/drivers/pwm/pwm-tipwmss.c
@@ -22,32 +22,6 @@
22#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23#include <linux/of_device.h> 23#include <linux/of_device.h>
24 24
25#include "pwm-tipwmss.h"
26
27#define PWMSS_CLKCONFIG 0x8 /* Clock gating reg */
28#define PWMSS_CLKSTATUS 0xc /* Clock gating status reg */
29
30struct pwmss_info {
31 void __iomem *mmio_base;
32 struct mutex pwmss_lock;
33 u16 pwmss_clkconfig;
34};
35
36u16 pwmss_submodule_state_change(struct device *dev, int set)
37{
38 struct pwmss_info *info = dev_get_drvdata(dev);
39 u16 val;
40
41 mutex_lock(&info->pwmss_lock);
42 val = readw(info->mmio_base + PWMSS_CLKCONFIG);
43 val |= set;
44 writew(val , info->mmio_base + PWMSS_CLKCONFIG);
45 mutex_unlock(&info->pwmss_lock);
46
47 return readw(info->mmio_base + PWMSS_CLKSTATUS);
48}
49EXPORT_SYMBOL(pwmss_submodule_state_change);
50
51static const struct of_device_id pwmss_of_match[] = { 25static const struct of_device_id pwmss_of_match[] = {
52 { .compatible = "ti,am33xx-pwmss" }, 26 { .compatible = "ti,am33xx-pwmss" },
53 {}, 27 {},
@@ -57,24 +31,10 @@ MODULE_DEVICE_TABLE(of, pwmss_of_match);
57static int pwmss_probe(struct platform_device *pdev) 31static int pwmss_probe(struct platform_device *pdev)
58{ 32{
59 int ret; 33 int ret;
60 struct resource *r;
61 struct pwmss_info *info;
62 struct device_node *node = pdev->dev.of_node; 34 struct device_node *node = pdev->dev.of_node;
63 35
64 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
65 if (!info)
66 return -ENOMEM;
67
68 mutex_init(&info->pwmss_lock);
69
70 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
71 info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
72 if (IS_ERR(info->mmio_base))
73 return PTR_ERR(info->mmio_base);
74
75 pm_runtime_enable(&pdev->dev); 36 pm_runtime_enable(&pdev->dev);
76 pm_runtime_get_sync(&pdev->dev); 37 pm_runtime_get_sync(&pdev->dev);
77 platform_set_drvdata(pdev, info);
78 38
79 /* Populate all the child nodes here... */ 39 /* Populate all the child nodes here... */
80 ret = of_platform_populate(node, NULL, NULL, &pdev->dev); 40 ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
@@ -86,30 +46,21 @@ static int pwmss_probe(struct platform_device *pdev)
86 46
87static int pwmss_remove(struct platform_device *pdev) 47static int pwmss_remove(struct platform_device *pdev)
88{ 48{
89 struct pwmss_info *info = platform_get_drvdata(pdev);
90
91 pm_runtime_put_sync(&pdev->dev); 49 pm_runtime_put_sync(&pdev->dev);
92 pm_runtime_disable(&pdev->dev); 50 pm_runtime_disable(&pdev->dev);
93 mutex_destroy(&info->pwmss_lock);
94 return 0; 51 return 0;
95} 52}
96 53
97#ifdef CONFIG_PM_SLEEP 54#ifdef CONFIG_PM_SLEEP
98static int pwmss_suspend(struct device *dev) 55static int pwmss_suspend(struct device *dev)
99{ 56{
100 struct pwmss_info *info = dev_get_drvdata(dev);
101
102 info->pwmss_clkconfig = readw(info->mmio_base + PWMSS_CLKCONFIG);
103 pm_runtime_put_sync(dev); 57 pm_runtime_put_sync(dev);
104 return 0; 58 return 0;
105} 59}
106 60
107static int pwmss_resume(struct device *dev) 61static int pwmss_resume(struct device *dev)
108{ 62{
109 struct pwmss_info *info = dev_get_drvdata(dev);
110
111 pm_runtime_get_sync(dev); 63 pm_runtime_get_sync(dev);
112 writew(info->pwmss_clkconfig, info->mmio_base + PWMSS_CLKCONFIG);
113 return 0; 64 return 0;
114} 65}
115#endif 66#endif
diff --git a/drivers/pwm/pwm-tipwmss.h b/drivers/pwm/pwm-tipwmss.h
deleted file mode 100644
index 10ad8040408b..000000000000
--- a/drivers/pwm/pwm-tipwmss.h
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * TI PWM Subsystem driver
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef __TIPWMSS_H
19#define __TIPWMSS_H
20
21/* PWM substem clock gating */
22#define PWMSS_ECAPCLK_EN BIT(0)
23#define PWMSS_ECAPCLK_STOP_REQ BIT(1)
24#define PWMSS_EPWMCLK_EN BIT(8)
25#define PWMSS_EPWMCLK_STOP_REQ BIT(9)
26
27#define PWMSS_ECAPCLK_EN_ACK BIT(0)
28#define PWMSS_EPWMCLK_EN_ACK BIT(8)
29
30#ifdef CONFIG_PWM_TIPWMSS
31extern u16 pwmss_submodule_state_change(struct device *dev, int set);
32#else
33static inline u16 pwmss_submodule_state_change(struct device *dev, int set)
34{
35 /* return success status value */
36 return 0xFFFF;
37}
38#endif
39#endif /* __TIPWMSS_H */