All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-20  0:04 ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

Since we now have a proper Samsung PWM clocksource driver in place,
we can proceed with further cleanup of PWM timers support on Samsung SoCs.

This series attempts to achieve this goal by:
 1) fixing up few things in samsung_pwm_timer clocksource driver,
 2) moving remaining Samsung platforms to the new clocksource driver,
 3) removing old clocksource driver,
 4) adding new multiplatform- and DT-aware PWM driver,
 5) moving all Samsung platforms to use the new PWM driver,
 6) removing old PWM driver,
 7) removing all PWM-related code that is not used anymore.

Cleaning up the PWM driver is a bit tricky, because the design of current
driver makes it completely unsuitable for DT and multiplatform and would
require a heavy rework to make it usable, breaking any existing Samsung PWM
users by the way. To avoid any breakage this series first renames the old
driver, then adds new one using original name, migrates all platforms to
use it and then finally removes the old driver.

See particular patches for more detailed descriptions.

[On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper, SMDK6410
with PWM backlight and Exynos4210-based Origen board (with PWM0 attached
to a scope)]
Tested-by: Tomasz Figa <tomasz.figa@gmail.com>

[On S3C2440-based Mini2440 board]
Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>

[On a s3c2416 based machine]
Tested-by: Heiko Stuebner <heiko@sntech.de> 

[Also not sure on what boards, but still]
Tested-by: Mark Brown <broonie@linaro.org>

Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Heiko Stuebner <heiko@sntech.de> 

Changes since v3:
 - added two extra clocksource driver fixes to the series (patches 1, 2),
 - added comment explaining why only a simple synchronization is needed
   between clocksource and PWM drivers,
 - some stylistic fixes,
 - rebased to 3.11-rc1.
Changes since v2:
 - replaced __raw_{readl,writel} with {readl,writel},
 - corrected some commit messages,
 - used git format-patch -M to detect rename.
Changes since v1:
 - made sure that suspend/resume is handled correctly in both
   clocksource and PWM drivers,
 - fixed incorrect definition of AUTORELOAD bit for channel 4,
 - fixed order of registering PWM device and calling samsung_bl_set(),
   which assumes that PWM device has been already registered,
 - corrected commit messages of several patches,
 - addressed all the valid comments from reviewers, including cleanup
   of most code originally copied from previous PWM driver,
 - rebased on top of current Kgene's for-next,
 - tested on Exynos4210, verifying correct PWM output with a scope.

Tomasz Figa (20):
  clocksource: samsung_pwm_timer: Do not request PWM mem region
  clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  clocksource: samsung_pwm_timer: Cache clocksource register address
  clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  clocksource: samsung_pwm_timer: Handle suspend/resume correctly
  ARM: SAMSUNG: Unify base address definitions of timer block
  ARM: SAMSUNG: Add new PWM platform device
  ARM: SAMSUNG: Set PWM platform data
  ARM: SAMSUNG: Move all platforms to new clocksource driver
  ARM: SAMSUNG: Remove old samsung-time driver
  ARM: SAMSUNG: Remove unused PWM timer IRQ chip code
  pwm: samsung: Rename to pwm-samsung-legacy
  pwm: Add new pwm-samsung driver
  ARM: SAMSUNG: Rework private data handling in dev-backlight
  ARM: SAMSUNG: Modify board files to use new PWM platform device
  pwm: Remove superseded pwm-samsung-legacy driver
  ARM: SAMSUNG: Remove old PWM timer platform devices
  ARM: SAMSUNG: Remove pwm-clock infrastructure
  ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header
  ARM: SAMSUNG: Remove plat/regs-timer.h header

 arch/arm/Kconfig                                   |  11 +-
 arch/arm/mach-s3c24xx/Kconfig                      |   6 -
 arch/arm/mach-s3c24xx/clock-s3c2410.c              |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2412.c              |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2416.c              |   2 -
 arch/arm/mach-s3c24xx/clock-s3c2443.c              |   2 -
 arch/arm/mach-s3c24xx/common.c                     |  27 +
 arch/arm/mach-s3c24xx/include/mach/map.h           |   2 +
 arch/arm/mach-s3c24xx/mach-h1940.c                 |   4 +-
 arch/arm/mach-s3c24xx/mach-rx1950.c                |   5 +-
 arch/arm/mach-s3c64xx/Kconfig                      |   2 -
 arch/arm/mach-s3c64xx/clock.c                      |   2 -
 arch/arm/mach-s3c64xx/common.c                     |  32 +-
 arch/arm/mach-s3c64xx/include/mach/irqs.h          |   8 -
 arch/arm/mach-s3c64xx/include/mach/map.h           |   1 +
 arch/arm/mach-s3c64xx/irq-pm.c                     |   2 -
 arch/arm/mach-s3c64xx/mach-crag6410.c              |   4 +-
 arch/arm/mach-s3c64xx/mach-hmt.c                   |   4 +-
 arch/arm/mach-s3c64xx/mach-smartq.c                |   4 +-
 arch/arm/mach-s3c64xx/mach-smdk6410.c              |   5 +-
 arch/arm/mach-s5p64x0/Kconfig                      |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6440.c              |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6450.c              |   2 -
 arch/arm/mach-s5p64x0/common.c                     |  27 +
 arch/arm/mach-s5p64x0/include/mach/irqs.h          |   2 -
 arch/arm/mach-s5p64x0/include/mach/map.h           |   1 +
 arch/arm/mach-s5p64x0/mach-smdk6440.c              |   5 +-
 arch/arm/mach-s5p64x0/mach-smdk6450.c              |   5 +-
 arch/arm/mach-s5p64x0/pm.c                         |   3 -
 arch/arm/mach-s5pc100/Kconfig                      |   1 -
 arch/arm/mach-s5pc100/clock.c                      |   2 -
 arch/arm/mach-s5pc100/common.c                     |  28 +
 arch/arm/mach-s5pc100/include/mach/irqs.h          |   2 -
 arch/arm/mach-s5pc100/include/mach/map.h           |   1 +
 arch/arm/mach-s5pc100/mach-smdkc100.c              |   5 +-
 arch/arm/mach-s5pv210/Kconfig                      |   1 -
 arch/arm/mach-s5pv210/clock.c                      |   1 -
 arch/arm/mach-s5pv210/common.c                     |  28 +
 arch/arm/mach-s5pv210/include/mach/irqs.h          |   2 -
 arch/arm/mach-s5pv210/include/mach/map.h           |   1 +
 arch/arm/mach-s5pv210/mach-smdkv210.c              |   5 +-
 arch/arm/mach-s5pv210/pm.c                         |  10 -
 arch/arm/plat-samsung/Kconfig                      |  14 -
 arch/arm/plat-samsung/Makefile                     |   3 -
 arch/arm/plat-samsung/dev-backlight.c              |  61 +-
 arch/arm/plat-samsung/devs.c                       |  42 +-
 arch/arm/plat-samsung/include/plat/clock.h         |   4 -
 arch/arm/plat-samsung/include/plat/devs.h          |   1 +
 arch/arm/plat-samsung/include/plat/irq-vic-timer.h |  13 -
 arch/arm/plat-samsung/include/plat/irqs.h          |   9 -
 arch/arm/plat-samsung/include/plat/pwm-clock.h     |  81 ---
 arch/arm/plat-samsung/include/plat/pwm-core.h      |  24 +
 arch/arm/plat-samsung/include/plat/regs-timer.h    | 124 ----
 arch/arm/plat-samsung/include/plat/samsung-time.h  |  23 -
 arch/arm/plat-samsung/irq-vic-timer.c              |  98 ---
 arch/arm/plat-samsung/pwm-clock.c                  | 474 --------------
 arch/arm/plat-samsung/s5p-irq.c                    |   4 -
 arch/arm/plat-samsung/samsung-time.c               | 394 ------------
 drivers/clocksource/Kconfig                        |   1 -
 drivers/clocksource/samsung_pwm_timer.c            |  98 +--
 drivers/pwm/pwm-samsung.c                          | 701 ++++++++++++++-------
 61 files changed, 768 insertions(+), 1662 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/irq-vic-timer.h
 delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-clock.h
 create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
 delete mode 100644 arch/arm/plat-samsung/include/plat/regs-timer.h
 delete mode 100644 arch/arm/plat-samsung/irq-vic-timer.c
 delete mode 100644 arch/arm/plat-samsung/pwm-clock.c
 delete mode 100644 arch/arm/plat-samsung/samsung-time.c

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-20  0:04 ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

Since we now have a proper Samsung PWM clocksource driver in place,
we can proceed with further cleanup of PWM timers support on Samsung SoCs.

This series attempts to achieve this goal by:
 1) fixing up few things in samsung_pwm_timer clocksource driver,
 2) moving remaining Samsung platforms to the new clocksource driver,
 3) removing old clocksource driver,
 4) adding new multiplatform- and DT-aware PWM driver,
 5) moving all Samsung platforms to use the new PWM driver,
 6) removing old PWM driver,
 7) removing all PWM-related code that is not used anymore.

Cleaning up the PWM driver is a bit tricky, because the design of current
driver makes it completely unsuitable for DT and multiplatform and would
require a heavy rework to make it usable, breaking any existing Samsung PWM
users by the way. To avoid any breakage this series first renames the old
driver, then adds new one using original name, migrates all platforms to
use it and then finally removes the old driver.

See particular patches for more detailed descriptions.

[On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper, SMDK6410
with PWM backlight and Exynos4210-based Origen board (with PWM0 attached
to a scope)]
Tested-by: Tomasz Figa <tomasz.figa@gmail.com>

[On S3C2440-based Mini2440 board]
Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>

[On a s3c2416 based machine]
Tested-by: Heiko Stuebner <heiko@sntech.de> 

[Also not sure on what boards, but still]
Tested-by: Mark Brown <broonie@linaro.org>

Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Heiko Stuebner <heiko@sntech.de> 

Changes since v3:
 - added two extra clocksource driver fixes to the series (patches 1, 2),
 - added comment explaining why only a simple synchronization is needed
   between clocksource and PWM drivers,
 - some stylistic fixes,
 - rebased to 3.11-rc1.
Changes since v2:
 - replaced __raw_{readl,writel} with {readl,writel},
 - corrected some commit messages,
 - used git format-patch -M to detect rename.
Changes since v1:
 - made sure that suspend/resume is handled correctly in both
   clocksource and PWM drivers,
 - fixed incorrect definition of AUTORELOAD bit for channel 4,
 - fixed order of registering PWM device and calling samsung_bl_set(),
   which assumes that PWM device has been already registered,
 - corrected commit messages of several patches,
 - addressed all the valid comments from reviewers, including cleanup
   of most code originally copied from previous PWM driver,
 - rebased on top of current Kgene's for-next,
 - tested on Exynos4210, verifying correct PWM output with a scope.

Tomasz Figa (20):
  clocksource: samsung_pwm_timer: Do not request PWM mem region
  clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  clocksource: samsung_pwm_timer: Cache clocksource register address
  clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  clocksource: samsung_pwm_timer: Handle suspend/resume correctly
  ARM: SAMSUNG: Unify base address definitions of timer block
  ARM: SAMSUNG: Add new PWM platform device
  ARM: SAMSUNG: Set PWM platform data
  ARM: SAMSUNG: Move all platforms to new clocksource driver
  ARM: SAMSUNG: Remove old samsung-time driver
  ARM: SAMSUNG: Remove unused PWM timer IRQ chip code
  pwm: samsung: Rename to pwm-samsung-legacy
  pwm: Add new pwm-samsung driver
  ARM: SAMSUNG: Rework private data handling in dev-backlight
  ARM: SAMSUNG: Modify board files to use new PWM platform device
  pwm: Remove superseded pwm-samsung-legacy driver
  ARM: SAMSUNG: Remove old PWM timer platform devices
  ARM: SAMSUNG: Remove pwm-clock infrastructure
  ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header
  ARM: SAMSUNG: Remove plat/regs-timer.h header

 arch/arm/Kconfig                                   |  11 +-
 arch/arm/mach-s3c24xx/Kconfig                      |   6 -
 arch/arm/mach-s3c24xx/clock-s3c2410.c              |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2412.c              |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2416.c              |   2 -
 arch/arm/mach-s3c24xx/clock-s3c2443.c              |   2 -
 arch/arm/mach-s3c24xx/common.c                     |  27 +
 arch/arm/mach-s3c24xx/include/mach/map.h           |   2 +
 arch/arm/mach-s3c24xx/mach-h1940.c                 |   4 +-
 arch/arm/mach-s3c24xx/mach-rx1950.c                |   5 +-
 arch/arm/mach-s3c64xx/Kconfig                      |   2 -
 arch/arm/mach-s3c64xx/clock.c                      |   2 -
 arch/arm/mach-s3c64xx/common.c                     |  32 +-
 arch/arm/mach-s3c64xx/include/mach/irqs.h          |   8 -
 arch/arm/mach-s3c64xx/include/mach/map.h           |   1 +
 arch/arm/mach-s3c64xx/irq-pm.c                     |   2 -
 arch/arm/mach-s3c64xx/mach-crag6410.c              |   4 +-
 arch/arm/mach-s3c64xx/mach-hmt.c                   |   4 +-
 arch/arm/mach-s3c64xx/mach-smartq.c                |   4 +-
 arch/arm/mach-s3c64xx/mach-smdk6410.c              |   5 +-
 arch/arm/mach-s5p64x0/Kconfig                      |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6440.c              |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6450.c              |   2 -
 arch/arm/mach-s5p64x0/common.c                     |  27 +
 arch/arm/mach-s5p64x0/include/mach/irqs.h          |   2 -
 arch/arm/mach-s5p64x0/include/mach/map.h           |   1 +
 arch/arm/mach-s5p64x0/mach-smdk6440.c              |   5 +-
 arch/arm/mach-s5p64x0/mach-smdk6450.c              |   5 +-
 arch/arm/mach-s5p64x0/pm.c                         |   3 -
 arch/arm/mach-s5pc100/Kconfig                      |   1 -
 arch/arm/mach-s5pc100/clock.c                      |   2 -
 arch/arm/mach-s5pc100/common.c                     |  28 +
 arch/arm/mach-s5pc100/include/mach/irqs.h          |   2 -
 arch/arm/mach-s5pc100/include/mach/map.h           |   1 +
 arch/arm/mach-s5pc100/mach-smdkc100.c              |   5 +-
 arch/arm/mach-s5pv210/Kconfig                      |   1 -
 arch/arm/mach-s5pv210/clock.c                      |   1 -
 arch/arm/mach-s5pv210/common.c                     |  28 +
 arch/arm/mach-s5pv210/include/mach/irqs.h          |   2 -
 arch/arm/mach-s5pv210/include/mach/map.h           |   1 +
 arch/arm/mach-s5pv210/mach-smdkv210.c              |   5 +-
 arch/arm/mach-s5pv210/pm.c                         |  10 -
 arch/arm/plat-samsung/Kconfig                      |  14 -
 arch/arm/plat-samsung/Makefile                     |   3 -
 arch/arm/plat-samsung/dev-backlight.c              |  61 +-
 arch/arm/plat-samsung/devs.c                       |  42 +-
 arch/arm/plat-samsung/include/plat/clock.h         |   4 -
 arch/arm/plat-samsung/include/plat/devs.h          |   1 +
 arch/arm/plat-samsung/include/plat/irq-vic-timer.h |  13 -
 arch/arm/plat-samsung/include/plat/irqs.h          |   9 -
 arch/arm/plat-samsung/include/plat/pwm-clock.h     |  81 ---
 arch/arm/plat-samsung/include/plat/pwm-core.h      |  24 +
 arch/arm/plat-samsung/include/plat/regs-timer.h    | 124 ----
 arch/arm/plat-samsung/include/plat/samsung-time.h  |  23 -
 arch/arm/plat-samsung/irq-vic-timer.c              |  98 ---
 arch/arm/plat-samsung/pwm-clock.c                  | 474 --------------
 arch/arm/plat-samsung/s5p-irq.c                    |   4 -
 arch/arm/plat-samsung/samsung-time.c               | 394 ------------
 drivers/clocksource/Kconfig                        |   1 -
 drivers/clocksource/samsung_pwm_timer.c            |  98 +--
 drivers/pwm/pwm-samsung.c                          | 701 ++++++++++++++-------
 61 files changed, 768 insertions(+), 1662 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/irq-vic-timer.h
 delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-clock.h
 create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
 delete mode 100644 arch/arm/plat-samsung/include/plat/regs-timer.h
 delete mode 100644 arch/arm/plat-samsung/irq-vic-timer.c
 delete mode 100644 arch/arm/plat-samsung/pwm-clock.c
 delete mode 100644 arch/arm/plat-samsung/samsung-time.c

-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 01/20] clocksource: samsung_pwm_timer: Do not request PWM mem region
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

PWM registers are shared between clocksource and PWM drivers and so can
not be claimed for exclusive use.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 584b547..3fa5b07 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -404,7 +404,6 @@ void __init samsung_pwm_clocksource_init(void __iomem *base,
 static void __init samsung_pwm_alloc(struct device_node *np,
 				     const struct samsung_pwm_variant *variant)
 {
-	struct resource res;
 	struct property *prop;
 	const __be32 *cur;
 	u32 val;
@@ -423,17 +422,9 @@ static void __init samsung_pwm_alloc(struct device_node *np,
 		pwm.variant.output_mask |= 1 << val;
 	}
 
-	of_address_to_resource(np, 0, &res);
-	if (!request_mem_region(res.start,
-				resource_size(&res), "samsung-pwm")) {
-		pr_err("%s: failed to request IO mem region\n", __func__);
-		return;
-	}
-
-	pwm.base = ioremap(res.start, resource_size(&res));
+	pwm.base = of_iomap(np, 0);
 	if (!pwm.base) {
 		pr_err("%s: failed to map PWM registers\n", __func__);
-		release_mem_region(res.start, resource_size(&res));
 		return;
 	}
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 01/20] clocksource: samsung_pwm_timer: Do not request PWM mem region
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

PWM registers are shared between clocksource and PWM drivers and so can
not be claimed for exclusive use.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 584b547..3fa5b07 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -404,7 +404,6 @@ void __init samsung_pwm_clocksource_init(void __iomem *base,
 static void __init samsung_pwm_alloc(struct device_node *np,
 				     const struct samsung_pwm_variant *variant)
 {
-	struct resource res;
 	struct property *prop;
 	const __be32 *cur;
 	u32 val;
@@ -423,17 +422,9 @@ static void __init samsung_pwm_alloc(struct device_node *np,
 		pwm.variant.output_mask |= 1 << val;
 	}
 
-	of_address_to_resource(np, 0, &res);
-	if (!request_mem_region(res.start,
-				resource_size(&res), "samsung-pwm")) {
-		pr_err("%s: failed to request IO mem region\n", __func__);
-		return;
-	}
-
-	pwm.base = ioremap(res.start, resource_size(&res));
+	pwm.base = of_iomap(np, 0);
 	if (!pwm.base) {
 		pr_err("%s: failed to map PWM registers\n", __func__);
-		release_mem_region(res.start, resource_size(&res));
 		return;
 	}
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Tested-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..e238fb0 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -47,7 +47,8 @@
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
+						+ (((chan) < 5) ? 3 : 2)))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Tested-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..e238fb0 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -47,7 +47,8 @@
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
+						+ (((chan) < 5) ? 3 : 2)))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..e238fb0 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -47,7 +47,8 @@
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
+						+ (((chan) < 5) ? 3 : 2)))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..e238fb0 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -47,7 +47,8 @@
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
+						+ (((chan) < 5) ? 3 : 2)))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 03/20] clocksource: samsung_pwm_timer: Cache clocksource register address
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

Instead of calculating register every time the timer should be read,
we can just do it one time at initialization and store the address in
driver data.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 33 ++++++++-------------------------
 1 file changed, 8 insertions(+), 25 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index e238fb0..823279b 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -55,6 +55,7 @@ EXPORT_SYMBOL(samsung_pwm_lock);
 
 struct samsung_pwm_clocksource {
 	void __iomem *base;
+	void __iomem *source_reg;
 	unsigned int irq[SAMSUNG_PWM_NUM];
 	struct samsung_pwm_variant variant;
 
@@ -287,23 +288,6 @@ static void __init samsung_clockevent_init(void)
 	}
 }
 
-static void __iomem *samsung_timer_reg(void)
-{
-	switch (pwm.source_id) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-		return pwm.base + pwm.source_id * 0x0c + 0x14;
-
-	case 4:
-		return pwm.base + 0x40;
-
-	default:
-		BUG();
-	}
-}
-
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
@@ -313,17 +297,11 @@ static void __iomem *samsung_timer_reg(void)
  */
 static u32 notrace samsung_read_sched_clock(void)
 {
-	void __iomem *reg = samsung_timer_reg();
-
-	if (!reg)
-		return 0;
-
-	return ~__raw_readl(reg);
+	return ~__raw_readl(pwm.source_reg);
 }
 
 static void __init samsung_clocksource_init(void)
 {
-	void __iomem *reg = samsung_timer_reg();
 	unsigned long pclk;
 	unsigned long clock_rate;
 	int ret;
@@ -338,10 +316,15 @@ static void __init samsung_clocksource_init(void)
 	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
 	samsung_time_start(pwm.source_id, true);
 
+	if (pwm.source_id == 4)
+		pwm.source_reg = pwm.base + 0x40;
+	else
+		pwm.source_reg = pwm.base + pwm.source_id * 0x0c + 0x14;
+
 	setup_sched_clock(samsung_read_sched_clock,
 						pwm.variant.bits, clock_rate);
 
-	ret = clocksource_mmio_init(reg, "samsung_clocksource_timer",
+	ret = clocksource_mmio_init(pwm.source_reg, "samsung_clocksource_timer",
 					clock_rate, 250, pwm.variant.bits,
 					clocksource_mmio_readl_down);
 	if (ret)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 03/20] clocksource: samsung_pwm_timer: Cache clocksource register address
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of calculating register every time the timer should be read,
we can just do it one time at initialization and store the address in
driver data.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 33 ++++++++-------------------------
 1 file changed, 8 insertions(+), 25 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index e238fb0..823279b 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -55,6 +55,7 @@ EXPORT_SYMBOL(samsung_pwm_lock);
 
 struct samsung_pwm_clocksource {
 	void __iomem *base;
+	void __iomem *source_reg;
 	unsigned int irq[SAMSUNG_PWM_NUM];
 	struct samsung_pwm_variant variant;
 
@@ -287,23 +288,6 @@ static void __init samsung_clockevent_init(void)
 	}
 }
 
-static void __iomem *samsung_timer_reg(void)
-{
-	switch (pwm.source_id) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-		return pwm.base + pwm.source_id * 0x0c + 0x14;
-
-	case 4:
-		return pwm.base + 0x40;
-
-	default:
-		BUG();
-	}
-}
-
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
@@ -313,17 +297,11 @@ static void __iomem *samsung_timer_reg(void)
  */
 static u32 notrace samsung_read_sched_clock(void)
 {
-	void __iomem *reg = samsung_timer_reg();
-
-	if (!reg)
-		return 0;
-
-	return ~__raw_readl(reg);
+	return ~__raw_readl(pwm.source_reg);
 }
 
 static void __init samsung_clocksource_init(void)
 {
-	void __iomem *reg = samsung_timer_reg();
 	unsigned long pclk;
 	unsigned long clock_rate;
 	int ret;
@@ -338,10 +316,15 @@ static void __init samsung_clocksource_init(void)
 	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
 	samsung_time_start(pwm.source_id, true);
 
+	if (pwm.source_id == 4)
+		pwm.source_reg = pwm.base + 0x40;
+	else
+		pwm.source_reg = pwm.base + pwm.source_id * 0x0c + 0x14;
+
 	setup_sched_clock(samsung_read_sched_clock,
 						pwm.variant.bits, clock_rate);
 
-	ret = clocksource_mmio_init(reg, "samsung_clocksource_timer",
+	ret = clocksource_mmio_init(pwm.source_reg, "samsung_clocksource_timer",
 					clock_rate, 250, pwm.variant.bits,
 					clocksource_mmio_readl_down);
 	if (ret)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

In case of Samsung PWM timer, clocksource MMIO can not be used, because
custom suspend/resume callbacks are required.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/Kconfig             |  1 -
 drivers/clocksource/samsung_pwm_timer.c | 19 +++++++++++++++----
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index b7b9b04..41c6946 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -99,7 +99,6 @@ config CLKSRC_EXYNOS_MCT
 
 config CLKSRC_SAMSUNG_PWM
 	bool
-	select CLKSRC_MMIO
 	help
 	  This is a new clocksource driver for the PWM timer found in
 	  Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 823279b..753ffec 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -288,6 +288,18 @@ static void __init samsung_clockevent_init(void)
 	}
 }
 
+static cycle_t samsung_clocksource_read(struct clocksource *c)
+{
+	return ~readl_relaxed(pwm.source_reg);
+}
+
+static struct clocksource samsung_clocksource = {
+	.name		= "samsung_clocksource_timer",
+	.rating		= 250,
+	.read		= samsung_clocksource_read,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
@@ -297,7 +309,7 @@ static void __init samsung_clockevent_init(void)
  */
 static u32 notrace samsung_read_sched_clock(void)
 {
-	return ~__raw_readl(pwm.source_reg);
+	return samsung_clocksource_read(NULL);
 }
 
 static void __init samsung_clocksource_init(void)
@@ -324,9 +336,8 @@ static void __init samsung_clocksource_init(void)
 	setup_sched_clock(samsung_read_sched_clock,
 						pwm.variant.bits, clock_rate);
 
-	ret = clocksource_mmio_init(pwm.source_reg, "samsung_clocksource_timer",
-					clock_rate, 250, pwm.variant.bits,
-					clocksource_mmio_readl_down);
+	samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits);
+	ret = clocksource_register_hz(&samsung_clocksource, clock_rate);
 	if (ret)
 		panic("samsung_clocksource_timer: can't register clocksource\n");
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

In case of Samsung PWM timer, clocksource MMIO can not be used, because
custom suspend/resume callbacks are required.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/Kconfig             |  1 -
 drivers/clocksource/samsung_pwm_timer.c | 19 +++++++++++++++----
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index b7b9b04..41c6946 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -99,7 +99,6 @@ config CLKSRC_EXYNOS_MCT
 
 config CLKSRC_SAMSUNG_PWM
 	bool
-	select CLKSRC_MMIO
 	help
 	  This is a new clocksource driver for the PWM timer found in
 	  Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 823279b..753ffec 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -288,6 +288,18 @@ static void __init samsung_clockevent_init(void)
 	}
 }
 
+static cycle_t samsung_clocksource_read(struct clocksource *c)
+{
+	return ~readl_relaxed(pwm.source_reg);
+}
+
+static struct clocksource samsung_clocksource = {
+	.name		= "samsung_clocksource_timer",
+	.rating		= 250,
+	.read		= samsung_clocksource_read,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
@@ -297,7 +309,7 @@ static void __init samsung_clockevent_init(void)
  */
 static u32 notrace samsung_read_sched_clock(void)
 {
-	return ~__raw_readl(pwm.source_reg);
+	return samsung_clocksource_read(NULL);
 }
 
 static void __init samsung_clocksource_init(void)
@@ -324,9 +336,8 @@ static void __init samsung_clocksource_init(void)
 	setup_sched_clock(samsung_read_sched_clock,
 						pwm.variant.bits, clock_rate);
 
-	ret = clocksource_mmio_init(pwm.source_reg, "samsung_clocksource_timer",
-					clock_rate, 250, pwm.variant.bits,
-					clocksource_mmio_readl_down);
+	samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits);
+	ret = clocksource_register_hz(&samsung_clocksource, clock_rate);
 	if (ret)
 		panic("samsung_clocksource_timer: can't register clocksource\n");
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 05/20] clocksource: samsung_pwm_timer: Handle suspend/resume correctly
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

Current suspend/resume handling of the driver was broken, because:
 - periodic timer was being enabled in CLOCK_EVT_MODE_RESUME mode, which
   does not seem to be correct behavior looking at other platforms,
 - PWM divisors need to be restored, but they were not,
 - clockevent interrupt mask needs to be restored, but it was not,
 - clocksource was being restored in clockevent resume callback.

This patch fixes issues mentioned above, making suspend/resume handling
in the driver correct.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 42 ++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 753ffec..282e0e2 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -197,17 +197,6 @@ static int samsung_set_next_event(unsigned long cycles,
 	return 0;
 }
 
-static void samsung_timer_resume(void)
-{
-	/* event timer restart */
-	samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
-	samsung_time_start(pwm.event_id, true);
-
-	/* source timer restart */
-	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
-	samsung_time_start(pwm.source_id, true);
-}
-
 static void samsung_set_mode(enum clock_event_mode mode,
 				struct clock_event_device *evt)
 {
@@ -224,20 +213,29 @@ static void samsung_set_mode(enum clock_event_mode mode,
 
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
-		break;
-
 	case CLOCK_EVT_MODE_RESUME:
-		samsung_timer_resume();
 		break;
 	}
 }
 
+static void samsung_clockevent_resume(struct clock_event_device *cev)
+{
+	samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div);
+	samsung_timer_set_divisor(pwm.event_id, pwm.tdiv);
+
+	if (pwm.variant.has_tint_cstat) {
+		u32 mask = (1 << pwm.event_id);
+		writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT);
+	}
+}
+
 static struct clock_event_device time_event_device = {
 	.name		= "samsung_event_timer",
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.rating		= 200,
 	.set_next_event	= samsung_set_next_event,
 	.set_mode	= samsung_set_mode,
+	.resume		= samsung_clockevent_resume,
 };
 
 static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
@@ -288,6 +286,20 @@ static void __init samsung_clockevent_init(void)
 	}
 }
 
+static void samsung_clocksource_suspend(struct clocksource *cs)
+{
+	samsung_time_stop(pwm.source_id);
+}
+
+static void samsung_clocksource_resume(struct clocksource *cs)
+{
+	samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div);
+	samsung_timer_set_divisor(pwm.source_id, pwm.tdiv);
+
+	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
+	samsung_time_start(pwm.source_id, true);
+}
+
 static cycle_t samsung_clocksource_read(struct clocksource *c)
 {
 	return ~readl_relaxed(pwm.source_reg);
@@ -297,6 +309,8 @@ static struct clocksource samsung_clocksource = {
 	.name		= "samsung_clocksource_timer",
 	.rating		= 250,
 	.read		= samsung_clocksource_read,
+	.suspend	= samsung_clocksource_suspend,
+	.resume		= samsung_clocksource_resume,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 05/20] clocksource: samsung_pwm_timer: Handle suspend/resume correctly
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

Current suspend/resume handling of the driver was broken, because:
 - periodic timer was being enabled in CLOCK_EVT_MODE_RESUME mode, which
   does not seem to be correct behavior looking at other platforms,
 - PWM divisors need to be restored, but they were not,
 - clockevent interrupt mask needs to be restored, but it was not,
 - clocksource was being restored in clockevent resume callback.

This patch fixes issues mentioned above, making suspend/resume handling
in the driver correct.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 42 ++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 753ffec..282e0e2 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -197,17 +197,6 @@ static int samsung_set_next_event(unsigned long cycles,
 	return 0;
 }
 
-static void samsung_timer_resume(void)
-{
-	/* event timer restart */
-	samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
-	samsung_time_start(pwm.event_id, true);
-
-	/* source timer restart */
-	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
-	samsung_time_start(pwm.source_id, true);
-}
-
 static void samsung_set_mode(enum clock_event_mode mode,
 				struct clock_event_device *evt)
 {
@@ -224,20 +213,29 @@ static void samsung_set_mode(enum clock_event_mode mode,
 
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
-		break;
-
 	case CLOCK_EVT_MODE_RESUME:
-		samsung_timer_resume();
 		break;
 	}
 }
 
+static void samsung_clockevent_resume(struct clock_event_device *cev)
+{
+	samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div);
+	samsung_timer_set_divisor(pwm.event_id, pwm.tdiv);
+
+	if (pwm.variant.has_tint_cstat) {
+		u32 mask = (1 << pwm.event_id);
+		writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT);
+	}
+}
+
 static struct clock_event_device time_event_device = {
 	.name		= "samsung_event_timer",
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.rating		= 200,
 	.set_next_event	= samsung_set_next_event,
 	.set_mode	= samsung_set_mode,
+	.resume		= samsung_clockevent_resume,
 };
 
 static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
@@ -288,6 +286,20 @@ static void __init samsung_clockevent_init(void)
 	}
 }
 
+static void samsung_clocksource_suspend(struct clocksource *cs)
+{
+	samsung_time_stop(pwm.source_id);
+}
+
+static void samsung_clocksource_resume(struct clocksource *cs)
+{
+	samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div);
+	samsung_timer_set_divisor(pwm.source_id, pwm.tdiv);
+
+	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
+	samsung_time_start(pwm.source_id, true);
+}
+
 static cycle_t samsung_clocksource_read(struct clocksource *c)
 {
 	return ~readl_relaxed(pwm.source_reg);
@@ -297,6 +309,8 @@ static struct clocksource samsung_clocksource = {
 	.name		= "samsung_clocksource_timer",
 	.rating		= 250,
 	.read		= samsung_clocksource_read,
+	.suspend	= samsung_clocksource_suspend,
+	.resume		= samsung_clocksource_resume,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 06/20] ARM: SAMSUNG: Unify base address definitions of timer block
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa, Kyungmin Park

From: Tomasz Figa <t.figa@samsung.com>

This patch makes all defintions of timer block base address use the same
prefix to allow using the common name to define platform device
resource.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s3c24xx/include/mach/map.h | 2 ++
 arch/arm/mach-s3c64xx/include/mach/map.h | 1 +
 arch/arm/mach-s5p64x0/include/mach/map.h | 1 +
 arch/arm/mach-s5pc100/include/mach/map.h | 1 +
 arch/arm/mach-s5pv210/include/mach/map.h | 1 +
 5 files changed, 6 insertions(+)

diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
index 8ba381f..444793f 100644
--- a/arch/arm/mach-s3c24xx/include/mach/map.h
+++ b/arch/arm/mach-s3c24xx/include/mach/map.h
@@ -167,4 +167,6 @@
 #define S3C_PA_SPI0		S3C2443_PA_SPI0
 #define S3C_PA_SPI1		S3C2443_PA_SPI1
 
+#define SAMSUNG_PA_TIMER	S3C2410_PA_TIMER
+
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index 8e2097b..f55ccb1 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -121,5 +121,6 @@
 #define SAMSUNG_PA_ADC		S3C64XX_PA_ADC
 #define SAMSUNG_PA_CFCON	S3C64XX_PA_CFCON
 #define SAMSUNG_PA_KEYPAD	S3C64XX_PA_KEYPAD
+#define SAMSUNG_PA_TIMER	S3C64XX_PA_TIMER
 
 #endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 0c0175d..50a6e96 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -76,6 +76,7 @@
 #define S5P_PA_TIMER		S5P64X0_PA_TIMER
 
 #define SAMSUNG_PA_ADC		S5P64X0_PA_ADC
+#define SAMSUNG_PA_TIMER	S5P64X0_PA_TIMER
 
 /* UART */
 
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 54bc4f8..2550b61 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -116,6 +116,7 @@
 #define SAMSUNG_PA_ADC			S5PC100_PA_TSADC
 #define SAMSUNG_PA_CFCON		S5PC100_PA_CFCON
 #define SAMSUNG_PA_KEYPAD		S5PC100_PA_KEYPAD
+#define SAMSUNG_PA_TIMER		S5PC100_PA_TIMER
 
 #define S5PC100_VA_OTHERS		(S3C_VA_SYS + 0x10000)
 
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index b7c8a19..763929a 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -139,6 +139,7 @@
 #define SAMSUNG_PA_ADC			S5PV210_PA_ADC
 #define SAMSUNG_PA_CFCON		S5PV210_PA_CFCON
 #define SAMSUNG_PA_KEYPAD		S5PV210_PA_KEYPAD
+#define SAMSUNG_PA_TIMER		S5PV210_PA_TIMER
 
 /* UART */
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 06/20] ARM: SAMSUNG: Unify base address definitions of timer block
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Figa <t.figa@samsung.com>

This patch makes all defintions of timer block base address use the same
prefix to allow using the common name to define platform device
resource.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s3c24xx/include/mach/map.h | 2 ++
 arch/arm/mach-s3c64xx/include/mach/map.h | 1 +
 arch/arm/mach-s5p64x0/include/mach/map.h | 1 +
 arch/arm/mach-s5pc100/include/mach/map.h | 1 +
 arch/arm/mach-s5pv210/include/mach/map.h | 1 +
 5 files changed, 6 insertions(+)

diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
index 8ba381f..444793f 100644
--- a/arch/arm/mach-s3c24xx/include/mach/map.h
+++ b/arch/arm/mach-s3c24xx/include/mach/map.h
@@ -167,4 +167,6 @@
 #define S3C_PA_SPI0		S3C2443_PA_SPI0
 #define S3C_PA_SPI1		S3C2443_PA_SPI1
 
+#define SAMSUNG_PA_TIMER	S3C2410_PA_TIMER
+
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index 8e2097b..f55ccb1 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -121,5 +121,6 @@
 #define SAMSUNG_PA_ADC		S3C64XX_PA_ADC
 #define SAMSUNG_PA_CFCON	S3C64XX_PA_CFCON
 #define SAMSUNG_PA_KEYPAD	S3C64XX_PA_KEYPAD
+#define SAMSUNG_PA_TIMER	S3C64XX_PA_TIMER
 
 #endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 0c0175d..50a6e96 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -76,6 +76,7 @@
 #define S5P_PA_TIMER		S5P64X0_PA_TIMER
 
 #define SAMSUNG_PA_ADC		S5P64X0_PA_ADC
+#define SAMSUNG_PA_TIMER	S5P64X0_PA_TIMER
 
 /* UART */
 
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 54bc4f8..2550b61 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -116,6 +116,7 @@
 #define SAMSUNG_PA_ADC			S5PC100_PA_TSADC
 #define SAMSUNG_PA_CFCON		S5PC100_PA_CFCON
 #define SAMSUNG_PA_KEYPAD		S5PC100_PA_KEYPAD
+#define SAMSUNG_PA_TIMER		S5PC100_PA_TIMER
 
 #define S5PC100_VA_OTHERS		(S3C_VA_SYS + 0x10000)
 
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index b7c8a19..763929a 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -139,6 +139,7 @@
 #define SAMSUNG_PA_ADC			S5PV210_PA_ADC
 #define SAMSUNG_PA_CFCON		S5PV210_PA_CFCON
 #define SAMSUNG_PA_KEYPAD		S5PV210_PA_KEYPAD
+#define SAMSUNG_PA_TIMER		S5PV210_PA_TIMER
 
 /* UART */
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch adds new samsung_device_pwm platform device that represents
the whole PWM/timer block and includes memory and IRQ resources.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h     |  1 +
 arch/arm/plat-samsung/include/plat/pwm-core.h | 24 ++++++++++++++++++++++++
 3 files changed, 42 insertions(+)
 create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h

diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 0f9c3f4..bba6d78 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -58,6 +58,7 @@
 #include <plat/keypad.h>
 #include <linux/platform_data/mmc-s3cmci.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/pwm-core.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
@@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
 	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
 	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
 };
+
+static struct resource samsung_pwm_resource[] = {
+	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
+};
+
+struct platform_device samsung_device_pwm = {
+	.name		= "samsung-pwm",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
+	.resource	= samsung_pwm_resource,
+};
+
+void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
+{
+	samsung_device_pwm.dev.platform_data = pd;
+}
 #endif /* CONFIG_SAMSUNG_DEV_PWM */
 
 /* RTC */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 87d501f..0dc4ac4 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -134,6 +134,7 @@ extern struct platform_device exynos4_device_spdif;
 
 extern struct platform_device samsung_asoc_idma;
 extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_pwm;
 
 /* s3c2440 specific devices */
 
diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
new file mode 100644
index 0000000..df50f5c
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
@@ -0,0 +1,24 @@
+/*
+ * linux/arch/arm/plat-samsung/onenand-core.h
+ *
+ *  Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung PWM Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWM_CORE_H
+#define __ASM_ARCH_PWM_CORE_H __FILE__
+
+#include <clocksource/samsung_pwm.h>
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
+#else
+static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
+#endif
+
+#endif /* __ASM_ARCH_PWM_CORE_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds new samsung_device_pwm platform device that represents
the whole PWM/timer block and includes memory and IRQ resources.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h     |  1 +
 arch/arm/plat-samsung/include/plat/pwm-core.h | 24 ++++++++++++++++++++++++
 3 files changed, 42 insertions(+)
 create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h

diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 0f9c3f4..bba6d78 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -58,6 +58,7 @@
 #include <plat/keypad.h>
 #include <linux/platform_data/mmc-s3cmci.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/pwm-core.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
@@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
 	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
 	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
 };
+
+static struct resource samsung_pwm_resource[] = {
+	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
+};
+
+struct platform_device samsung_device_pwm = {
+	.name		= "samsung-pwm",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
+	.resource	= samsung_pwm_resource,
+};
+
+void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
+{
+	samsung_device_pwm.dev.platform_data = pd;
+}
 #endif /* CONFIG_SAMSUNG_DEV_PWM */
 
 /* RTC */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 87d501f..0dc4ac4 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -134,6 +134,7 @@ extern struct platform_device exynos4_device_spdif;
 
 extern struct platform_device samsung_asoc_idma;
 extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_pwm;
 
 /* s3c2440 specific devices */
 
diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
new file mode 100644
index 0000000..df50f5c
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
@@ -0,0 +1,24 @@
+/*
+ * linux/arch/arm/plat-samsung/onenand-core.h
+ *
+ *  Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung PWM Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWM_CORE_H
+#define __ASM_ARCH_PWM_CORE_H __FILE__
+
+#include <clocksource/samsung_pwm.h>
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
+#else
+static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
+#endif
+
+#endif /* __ASM_ARCH_PWM_CORE_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 08/20] ARM: SAMSUNG: Set PWM platform data
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa, Kyungmin Park

From: Tomasz Figa <t.figa@samsung.com>

This patch adds PWM platform data needed for legacy (non-DT) platforms
to handle SoC-specific bits of the PWM/timer block.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s3c24xx/common.c | 11 +++++++++++
 arch/arm/mach-s3c64xx/common.c | 11 +++++++++++
 arch/arm/mach-s5p64x0/common.c | 10 ++++++++++
 arch/arm/mach-s5pc100/common.c | 11 +++++++++++
 arch/arm/mach-s5pv210/common.c | 11 +++++++++++
 5 files changed, 54 insertions(+)

diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index c157103..e5e7d7d 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -49,6 +50,7 @@
 #include <plat/clock.h>
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
+#include <plat/pwm-core.h>
 
 #include "common.h"
 
@@ -216,6 +218,13 @@ static void s3c24xx_default_idle(void)
 		     S3C2410_CLKCON);
 }
 
+static struct samsung_pwm_variant s3c24xx_pwm_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= (1 << 4),
+};
+
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
 	arm_pm_idle = s3c24xx_default_idle;
@@ -232,6 +241,8 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 	s3c24xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
 }
 
 /* Serial port registrations */
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index 3f62e46..ca05e61 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -27,6 +27,7 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/irqchip/arm-vic.h>
+#include <clocksource/samsung_pwm.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -43,6 +44,7 @@
 #include <plat/gpio-cfg.h>
 #include <plat/irq-uart.h>
 #include <plat/irq-vic-timer.h>
+#include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
@@ -149,6 +151,13 @@ static struct device s3c64xx_dev = {
 	.bus	= &s3c64xx_subsys,
 };
 
+static struct samsung_pwm_variant s3c64xx_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
+};
+
 /* read cpu identification code */
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -161,6 +170,8 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 	s3c64xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
 }
 
 static __init int s3c64xx_dev_init(void)
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index dfdfdc3..49687f2 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
@@ -47,6 +48,7 @@
 #include <plat/fb-core.h>
 #include <plat/spi-core.h>
 #include <plat/gpio-cfg.h>
+#include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
@@ -157,6 +159,13 @@ static void s5p64x0_idle(void)
 	cpu_do_idle();
 }
 
+static struct samsung_pwm_variant s5p64x0_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= 0,
+};
+
 /*
  * s5p64x0_map_io
  *
@@ -176,6 +185,7 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 	samsung_wdt_reset_init(S3C_VA_WATCHDOG);
 
+	samsung_pwm_set_platdata(&s5p64x0_pwm_variant);
 }
 
 void __init s5p6440_map_io(void)
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index 4bdfecf..e0600af 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/reboot.h>
@@ -46,6 +47,7 @@
 #include <plat/fb-core.h>
 #include <plat/iic-core.h>
 #include <plat/onenand-core.h>
+#include <plat/pwm-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
@@ -132,6 +134,13 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
 	}
 };
 
+static struct samsung_pwm_variant s5pc100_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= (1 << 5),
+};
+
 /*
  * s5pc100_map_io
  *
@@ -149,6 +158,8 @@ void __init s5pc100_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s5pc100_pwm_variant);
 }
 
 void __init s5pc100_map_io(void)
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 023f1a7..306b29a 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/device.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
@@ -42,6 +43,7 @@
 #include <plat/fimc-core.h>
 #include <plat/iic-core.h>
 #include <plat/keypad-core.h>
+#include <plat/pwm-core.h>
 #include <plat/tv-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
@@ -148,6 +150,13 @@ void s5pv210_restart(enum reboot_mode mode, const char *cmd)
 	__raw_writel(0x1, S5P_SWRESET);
 }
 
+static struct samsung_pwm_variant s5pv210_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= (1 << 5),
+};
+
 /*
  * s5pv210_map_io
  *
@@ -165,6 +174,8 @@ void __init s5pv210_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s5pv210_pwm_variant);
 }
 
 void __init s5pv210_map_io(void)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 08/20] ARM: SAMSUNG: Set PWM platform data
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Figa <t.figa@samsung.com>

This patch adds PWM platform data needed for legacy (non-DT) platforms
to handle SoC-specific bits of the PWM/timer block.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s3c24xx/common.c | 11 +++++++++++
 arch/arm/mach-s3c64xx/common.c | 11 +++++++++++
 arch/arm/mach-s5p64x0/common.c | 10 ++++++++++
 arch/arm/mach-s5pc100/common.c | 11 +++++++++++
 arch/arm/mach-s5pv210/common.c | 11 +++++++++++
 5 files changed, 54 insertions(+)

diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index c157103..e5e7d7d 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -49,6 +50,7 @@
 #include <plat/clock.h>
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
+#include <plat/pwm-core.h>
 
 #include "common.h"
 
@@ -216,6 +218,13 @@ static void s3c24xx_default_idle(void)
 		     S3C2410_CLKCON);
 }
 
+static struct samsung_pwm_variant s3c24xx_pwm_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= (1 << 4),
+};
+
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
 	arm_pm_idle = s3c24xx_default_idle;
@@ -232,6 +241,8 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 	s3c24xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
 }
 
 /* Serial port registrations */
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index 3f62e46..ca05e61 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -27,6 +27,7 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/irqchip/arm-vic.h>
+#include <clocksource/samsung_pwm.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -43,6 +44,7 @@
 #include <plat/gpio-cfg.h>
 #include <plat/irq-uart.h>
 #include <plat/irq-vic-timer.h>
+#include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
@@ -149,6 +151,13 @@ static struct device s3c64xx_dev = {
 	.bus	= &s3c64xx_subsys,
 };
 
+static struct samsung_pwm_variant s3c64xx_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
+};
+
 /* read cpu identification code */
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -161,6 +170,8 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
 	s3c64xx_init_cpu();
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s3c64xx_pwm_variant);
 }
 
 static __init int s3c64xx_dev_init(void)
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index dfdfdc3..49687f2 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
@@ -47,6 +48,7 @@
 #include <plat/fb-core.h>
 #include <plat/spi-core.h>
 #include <plat/gpio-cfg.h>
+#include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
@@ -157,6 +159,13 @@ static void s5p64x0_idle(void)
 	cpu_do_idle();
 }
 
+static struct samsung_pwm_variant s5p64x0_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= 0,
+};
+
 /*
  * s5p64x0_map_io
  *
@@ -176,6 +185,7 @@ void __init s5p64x0_init_io(struct map_desc *mach_desc, int size)
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
 	samsung_wdt_reset_init(S3C_VA_WATCHDOG);
 
+	samsung_pwm_set_platdata(&s5p64x0_pwm_variant);
 }
 
 void __init s5p6440_map_io(void)
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index 4bdfecf..e0600af 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/serial_core.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/reboot.h>
@@ -46,6 +47,7 @@
 #include <plat/fb-core.h>
 #include <plat/iic-core.h>
 #include <plat/onenand-core.h>
+#include <plat/pwm-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
 #include <plat/watchdog-reset.h>
@@ -132,6 +134,13 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
 	}
 };
 
+static struct samsung_pwm_variant s5pc100_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= (1 << 5),
+};
+
 /*
  * s5pc100_map_io
  *
@@ -149,6 +158,8 @@ void __init s5pc100_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s5pc100_pwm_variant);
 }
 
 void __init s5pc100_map_io(void)
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 023f1a7..306b29a 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/device.h>
+#include <clocksource/samsung_pwm.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
@@ -42,6 +43,7 @@
 #include <plat/fimc-core.h>
 #include <plat/iic-core.h>
 #include <plat/keypad-core.h>
+#include <plat/pwm-core.h>
 #include <plat/tv-core.h>
 #include <plat/spi-core.h>
 #include <plat/regs-serial.h>
@@ -148,6 +150,13 @@ void s5pv210_restart(enum reboot_mode mode, const char *cmd)
 	__raw_writel(0x1, S5P_SWRESET);
 }
 
+static struct samsung_pwm_variant s5pv210_pwm_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= (1 << 5),
+};
+
 /*
  * s5pv210_map_io
  *
@@ -165,6 +174,8 @@ void __init s5pv210_init_io(struct map_desc *mach_desc, int size)
 	s5p_init_cpu(S5P_VA_CHIPID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+
+	samsung_pwm_set_platdata(&s5pv210_pwm_variant);
 }
 
 void __init s5pv210_map_io(void)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 09/20] ARM: SAMSUNG: Move all platforms to new clocksource driver
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch moves all Samsung platforms using PWM clocksource from legacy
samsung-time to new samsung-pwm-timer driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/Kconfig                | 10 +++++-----
 arch/arm/mach-s3c24xx/Kconfig   |  6 ------
 arch/arm/mach-s3c24xx/common.c  | 16 ++++++++++++++++
 arch/arm/mach-s3c64xx/Kconfig   |  2 --
 arch/arm/mach-s3c64xx/common.c  | 21 +++++++++++++++++----
 arch/arm/mach-s5p64x0/Kconfig   |  2 --
 arch/arm/mach-s5p64x0/common.c  | 17 +++++++++++++++++
 arch/arm/mach-s5pc100/Kconfig   |  1 -
 arch/arm/mach-s5pc100/common.c  | 17 +++++++++++++++++
 arch/arm/mach-s5pv210/Kconfig   |  1 -
 arch/arm/mach-s5pv210/common.c  | 17 +++++++++++++++++
 arch/arm/plat-samsung/s5p-irq.c |  3 ---
 12 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba412e0..486ab0a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -700,7 +700,7 @@ config ARCH_S3C24XX
 	select ARCH_HAS_CPUFREQ
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
 	select HAVE_CLK
@@ -723,7 +723,7 @@ config ARCH_S3C64XX
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_VIC
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
@@ -748,7 +748,7 @@ config ARCH_S3C64XX
 config ARCH_S5P64X0
 	bool "Samsung S5P6440 S5P6450"
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
@@ -767,7 +767,7 @@ config ARCH_S5PC100
 	bool "Samsung S5PC100"
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
@@ -787,7 +787,7 @@ config ARCH_S5PV210
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	select ARCH_SPARSEMEM_ENABLE
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 6d9252e..b8ec0ec 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -30,7 +30,6 @@ config CPU_S3C2410
 	select S3C2410_CLOCK
 	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
 	select S3C2410_PM if PM
-	select SAMSUNG_HRT
 	select SAMSUNG_WDT_RESET
 	help
 	  Support for S3C2410 and S3C2410A family from the S3C24XX line
@@ -42,7 +41,6 @@ config CPU_S3C2412
 	select CPU_LLSERIAL_S3C2440
 	select S3C2412_DMA if S3C24XX_DMA
 	select S3C2412_PM if PM
-	select SAMSUNG_HRT
 	help
 	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
 
@@ -54,7 +52,6 @@ config CPU_S3C2416
 	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
 	select SAMSUNG_CLKSRC
-	select SAMSUNG_HRT
 	help
 	  Support for the S3C2416 SoC from the S3C24XX line
 
@@ -65,7 +62,6 @@ config CPU_S3C2440
 	select S3C2410_CLOCK
 	select S3C2410_PM if PM
 	select S3C2440_DMA if S3C24XX_DMA
-	select SAMSUNG_HRT
 	help
 	  Support for S3C2440 Samsung Mobile CPU based systems.
 
@@ -75,7 +71,6 @@ config CPU_S3C2442
 	select CPU_LLSERIAL_S3C2440
 	select S3C2410_CLOCK
 	select S3C2410_PM if PM
-	select SAMSUNG_HRT
 	help
 	  Support for S3C2442 Samsung Mobile CPU based systems.
 
@@ -91,7 +86,6 @@ config CPU_S3C2443
 	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
 	select SAMSUNG_CLKSRC
-	select SAMSUNG_HRT
 	help
 	  Support for the S3C2443 SoC from the S3C24XX line
 
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index e5e7d7d..457261c 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -245,6 +245,22 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 	samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
 }
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s3c24xx_pwm_variant);
+}
+
 /* Serial port registrations */
 
 #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 2057853..041da51 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -17,13 +17,11 @@ config PLAT_S3C64XX
 # Configuration options for the S3C6410 CPU
 
 config CPU_S3C6400
-	select SAMSUNG_HRT
 	bool
 	help
 	  Enable S3C6400 CPU support
 
 config CPU_S3C6410
-	select SAMSUNG_HRT
 	bool
 	help
 	  Enable S3C6410 CPU support
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index ca05e61..73d79cf 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -43,7 +43,6 @@
 #include <plat/pm.h>
 #include <plat/gpio-cfg.h>
 #include <plat/irq-uart.h>
-#include <plat/irq-vic-timer.h>
 #include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
@@ -158,6 +157,23 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = {
 	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s3c64xx_pwm_variant);
+}
+
 /* read cpu identification code */
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -206,9 +222,6 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
 	/* initialise the pair of VICs */
 	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
 	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
-
-	/* add the timer sub-irqs */
-	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
 }
 
 #define eint_offset(irq)	((irq) - IRQ_EINT(0))
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 5a707bd..bb2111b 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -11,14 +11,12 @@ config CPU_S5P6440
 	bool
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
-	select SAMSUNG_HRT
 	select SAMSUNG_WAKEMASK if PM
 	help
 	  Enable S5P6440 CPU support
 
 config CPU_S5P6450
 	bool
-	select SAMSUNG_HRT
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
 	select SAMSUNG_WAKEMASK if PM
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 49687f2..42e14f2 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -166,6 +166,23 @@ static struct samsung_pwm_variant s5p64x0_pwm_variant = {
 	.tclk_mask	= 0,
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s5p64x0_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s5p64x0_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s5p64x0_pwm_variant);
+}
+
 /*
  * s5p64x0_map_io
  *
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 2f456a4..15170be 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -11,7 +11,6 @@ config CPU_S5PC100
 	bool
 	select S5P_EXT_INT
 	select SAMSUNG_DMADEV
-	select SAMSUNG_HRT
 	help
 	  Enable S5PC100 CPU support
 
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index e0600af..c5a8eea 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -141,6 +141,23 @@ static struct samsung_pwm_variant s5pc100_pwm_variant = {
 	.tclk_mask	= (1 << 5),
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s5pc100_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s5pc100_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s5pc100_pwm_variant);
+}
+
 /*
  * s5pc100_map_io
  *
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 0963283..caaedaf 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -15,7 +15,6 @@ config CPU_S5PV210
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
-	select SAMSUNG_HRT
 	help
 	  Enable S5PV210 CPU support
 
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 306b29a..26027a2 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -157,6 +157,23 @@ static struct samsung_pwm_variant s5pv210_pwm_variant = {
 	.tclk_mask	= (1 << 5),
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s5pv210_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s5pv210_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s5pv210_pwm_variant);
+}
+
 /*
  * s5pv210_map_io
  *
diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
index ff1a760..6729cb2 100644
--- a/arch/arm/plat-samsung/s5p-irq.c
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -19,7 +19,6 @@
 #include <mach/map.h>
 #include <plat/regs-timer.h>
 #include <plat/cpu.h>
-#include <plat/irq-vic-timer.h>
 
 void __init s5p_init_irq(u32 *vic, u32 num_vic)
 {
@@ -30,6 +29,4 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
 	for (irq = 0; irq < num_vic; irq++)
 		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
 #endif
-
-	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 09/20] ARM: SAMSUNG: Move all platforms to new clocksource driver
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch moves all Samsung platforms using PWM clocksource from legacy
samsung-time to new samsung-pwm-timer driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/Kconfig                | 10 +++++-----
 arch/arm/mach-s3c24xx/Kconfig   |  6 ------
 arch/arm/mach-s3c24xx/common.c  | 16 ++++++++++++++++
 arch/arm/mach-s3c64xx/Kconfig   |  2 --
 arch/arm/mach-s3c64xx/common.c  | 21 +++++++++++++++++----
 arch/arm/mach-s5p64x0/Kconfig   |  2 --
 arch/arm/mach-s5p64x0/common.c  | 17 +++++++++++++++++
 arch/arm/mach-s5pc100/Kconfig   |  1 -
 arch/arm/mach-s5pc100/common.c  | 17 +++++++++++++++++
 arch/arm/mach-s5pv210/Kconfig   |  1 -
 arch/arm/mach-s5pv210/common.c  | 17 +++++++++++++++++
 arch/arm/plat-samsung/s5p-irq.c |  3 ---
 12 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba412e0..486ab0a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -700,7 +700,7 @@ config ARCH_S3C24XX
 	select ARCH_HAS_CPUFREQ
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
 	select HAVE_CLK
@@ -723,7 +723,7 @@ config ARCH_S3C64XX
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_VIC
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
@@ -748,7 +748,7 @@ config ARCH_S3C64XX
 config ARCH_S5P64X0
 	bool "Samsung S5P6440 S5P6450"
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
@@ -767,7 +767,7 @@ config ARCH_S5PC100
 	bool "Samsung S5PC100"
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
@@ -787,7 +787,7 @@ config ARCH_S5PV210
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	select ARCH_SPARSEMEM_ENABLE
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_SAMSUNG_PWM
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select GPIO_SAMSUNG
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 6d9252e..b8ec0ec 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -30,7 +30,6 @@ config CPU_S3C2410
 	select S3C2410_CLOCK
 	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
 	select S3C2410_PM if PM
-	select SAMSUNG_HRT
 	select SAMSUNG_WDT_RESET
 	help
 	  Support for S3C2410 and S3C2410A family from the S3C24XX line
@@ -42,7 +41,6 @@ config CPU_S3C2412
 	select CPU_LLSERIAL_S3C2440
 	select S3C2412_DMA if S3C24XX_DMA
 	select S3C2412_PM if PM
-	select SAMSUNG_HRT
 	help
 	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
 
@@ -54,7 +52,6 @@ config CPU_S3C2416
 	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
 	select SAMSUNG_CLKSRC
-	select SAMSUNG_HRT
 	help
 	  Support for the S3C2416 SoC from the S3C24XX line
 
@@ -65,7 +62,6 @@ config CPU_S3C2440
 	select S3C2410_CLOCK
 	select S3C2410_PM if PM
 	select S3C2440_DMA if S3C24XX_DMA
-	select SAMSUNG_HRT
 	help
 	  Support for S3C2440 Samsung Mobile CPU based systems.
 
@@ -75,7 +71,6 @@ config CPU_S3C2442
 	select CPU_LLSERIAL_S3C2440
 	select S3C2410_CLOCK
 	select S3C2410_PM if PM
-	select SAMSUNG_HRT
 	help
 	  Support for S3C2442 Samsung Mobile CPU based systems.
 
@@ -91,7 +86,6 @@ config CPU_S3C2443
 	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
 	select SAMSUNG_CLKSRC
-	select SAMSUNG_HRT
 	help
 	  Support for the S3C2443 SoC from the S3C24XX line
 
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index e5e7d7d..457261c 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -245,6 +245,22 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 	samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
 }
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s3c24xx_pwm_variant);
+}
+
 /* Serial port registrations */
 
 #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 2057853..041da51 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -17,13 +17,11 @@ config PLAT_S3C64XX
 # Configuration options for the S3C6410 CPU
 
 config CPU_S3C6400
-	select SAMSUNG_HRT
 	bool
 	help
 	  Enable S3C6400 CPU support
 
 config CPU_S3C6410
-	select SAMSUNG_HRT
 	bool
 	help
 	  Enable S3C6410 CPU support
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index ca05e61..73d79cf 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -43,7 +43,6 @@
 #include <plat/pm.h>
 #include <plat/gpio-cfg.h>
 #include <plat/irq-uart.h>
-#include <plat/irq-vic-timer.h>
 #include <plat/pwm-core.h>
 #include <plat/regs-irqtype.h>
 #include <plat/regs-serial.h>
@@ -158,6 +157,23 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = {
 	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s3c64xx_pwm_variant);
+}
+
 /* read cpu identification code */
 
 void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
@@ -206,9 +222,6 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
 	/* initialise the pair of VICs */
 	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
 	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
-
-	/* add the timer sub-irqs */
-	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
 }
 
 #define eint_offset(irq)	((irq) - IRQ_EINT(0))
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 5a707bd..bb2111b 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -11,14 +11,12 @@ config CPU_S5P6440
 	bool
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
-	select SAMSUNG_HRT
 	select SAMSUNG_WAKEMASK if PM
 	help
 	  Enable S5P6440 CPU support
 
 config CPU_S5P6450
 	bool
-	select SAMSUNG_HRT
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
 	select SAMSUNG_WAKEMASK if PM
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 49687f2..42e14f2 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -166,6 +166,23 @@ static struct samsung_pwm_variant s5p64x0_pwm_variant = {
 	.tclk_mask	= 0,
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s5p64x0_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s5p64x0_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s5p64x0_pwm_variant);
+}
+
 /*
  * s5p64x0_map_io
  *
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 2f456a4..15170be 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -11,7 +11,6 @@ config CPU_S5PC100
 	bool
 	select S5P_EXT_INT
 	select SAMSUNG_DMADEV
-	select SAMSUNG_HRT
 	help
 	  Enable S5PC100 CPU support
 
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index e0600af..c5a8eea 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -141,6 +141,23 @@ static struct samsung_pwm_variant s5pc100_pwm_variant = {
 	.tclk_mask	= (1 << 5),
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s5pc100_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s5pc100_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s5pc100_pwm_variant);
+}
+
 /*
  * s5pc100_map_io
  *
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 0963283..caaedaf 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -15,7 +15,6 @@ config CPU_S5PV210
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
-	select SAMSUNG_HRT
 	help
 	  Enable S5PV210 CPU support
 
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 306b29a..26027a2 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -157,6 +157,23 @@ static struct samsung_pwm_variant s5pv210_pwm_variant = {
 	.tclk_mask	= (1 << 5),
 };
 
+void __init samsung_set_timer_source(unsigned int event, unsigned int source)
+{
+	s5pv210_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+	s5pv210_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
+}
+
+void __init samsung_timer_init(void)
+{
+	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
+		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
+	};
+
+	samsung_pwm_clocksource_init(S3C_VA_TIMER,
+					timer_irqs, &s5pv210_pwm_variant);
+}
+
 /*
  * s5pv210_map_io
  *
diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
index ff1a760..6729cb2 100644
--- a/arch/arm/plat-samsung/s5p-irq.c
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -19,7 +19,6 @@
 #include <mach/map.h>
 #include <plat/regs-timer.h>
 #include <plat/cpu.h>
-#include <plat/irq-vic-timer.h>
 
 void __init s5p_init_irq(u32 *vic, u32 num_vic)
 {
@@ -30,6 +29,4 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
 	for (irq = 0; irq < num_vic; irq++)
 		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
 #endif
-
-	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
 }
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 10/20] ARM: SAMSUNG: Remove old samsung-time driver
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch removes the old samsung-time driver, since all its users have
been migrated to the new samsung_pwm_timer clocksource driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/Kconfig                     |   8 -
 arch/arm/plat-samsung/Makefile                    |   1 -
 arch/arm/plat-samsung/include/plat/samsung-time.h |  23 --
 arch/arm/plat-samsung/samsung-time.c              | 394 ----------------------
 4 files changed, 426 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/samsung-time.c

diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 3dc5cbe..3e880b7 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -72,14 +72,6 @@ config SAMSUNG_ATAGS
 
 if SAMSUNG_ATAGS
 
-# timer options
-
-config SAMSUNG_HRT
-	bool
-	select SAMSUNG_DEV_PWM
-	help
-	  Use the High Resolution timer support
-
 # clock options
 
 config SAMSUNG_CLOCK
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 98d07d8..cf41bf9 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -12,7 +12,6 @@ obj-				:=
 # Objects we always build independent of SoC choice
 
 obj-y				+= init.o cpu.o
-obj-$(CONFIG_SAMSUNG_HRT) 	+= samsung-time.o
 
 obj-$(CONFIG_SAMSUNG_CLOCK)	+= clock.o
 obj-$(CONFIG_SAMSUNG_CLOCK)	+= pwm-clock.o
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
index 4cc99bb..209464a 100644
--- a/arch/arm/plat-samsung/include/plat/samsung-time.h
+++ b/arch/arm/plat-samsung/include/plat/samsung-time.h
@@ -22,29 +22,6 @@ enum samsung_timer_mode {
 	SAMSUNG_PWM4,
 };
 
-struct samsung_timer_source {
-	unsigned int event_id;
-	unsigned int source_id;
-};
-
-/* Be able to sleep for atleast 4 seconds (usually more) */
-#define SAMSUNG_TIMER_MIN_RANGE	4
-
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100)
-#define TCNT_MAX		0xffff
-#define TSCALER_DIV		25
-#define TDIV			50
-#define TSIZE			16
-#else
-#define TCNT_MAX		0xffffffff
-#define TSCALER_DIV		2
-#define TDIV			2
-#define TSIZE			32
-#endif
-
-#define NON_PERIODIC		0
-#define PERIODIC		1
-
 extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
 					enum samsung_timer_mode source);
 
diff --git a/arch/arm/plat-samsung/samsung-time.c b/arch/arm/plat-samsung/samsung-time.c
deleted file mode 100644
index 2957075..0000000
--- a/arch/arm/plat-samsung/samsung-time.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * samsung - Common hr-timer support (s3c and s5p)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/platform_device.h>
-#include <linux/sched_clock.h>
-
-#include <asm/smp_twd.h>
-#include <asm/mach/time.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/regs-timer.h>
-#include <plat/samsung-time.h>
-
-static struct clk *tin_event;
-static struct clk *tin_source;
-static struct clk *tdiv_event;
-static struct clk *tdiv_source;
-static struct clk *timerclk;
-static struct samsung_timer_source timer_source;
-static unsigned long clock_count_per_tick;
-static void samsung_timer_resume(void);
-
-static void samsung_time_stop(enum samsung_timer_mode mode)
-{
-	unsigned long tcon;
-
-	tcon = __raw_readl(S3C2410_TCON);
-
-	switch (mode) {
-	case SAMSUNG_PWM0:
-		tcon &= ~S3C2410_TCON_T0START;
-		break;
-
-	case SAMSUNG_PWM1:
-		tcon &= ~S3C2410_TCON_T1START;
-		break;
-
-	case SAMSUNG_PWM2:
-		tcon &= ~S3C2410_TCON_T2START;
-		break;
-
-	case SAMSUNG_PWM3:
-		tcon &= ~S3C2410_TCON_T3START;
-		break;
-
-	case SAMSUNG_PWM4:
-		tcon &= ~S3C2410_TCON_T4START;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", mode);
-		break;
-	}
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static void samsung_time_setup(enum samsung_timer_mode mode, unsigned long tcnt)
-{
-	unsigned long tcon;
-
-	tcon = __raw_readl(S3C2410_TCON);
-
-	tcnt--;
-
-	switch (mode) {
-	case SAMSUNG_PWM0:
-		tcon &= ~(0x0f << 0);
-		tcon |= S3C2410_TCON_T0MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM1:
-		tcon &= ~(0x0f << 8);
-		tcon |= S3C2410_TCON_T1MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM2:
-		tcon &= ~(0x0f << 12);
-		tcon |= S3C2410_TCON_T2MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM3:
-		tcon &= ~(0x0f << 16);
-		tcon |= S3C2410_TCON_T3MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM4:
-		tcon &= ~(0x07 << 20);
-		tcon |= S3C2410_TCON_T4MANUALUPD;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", mode);
-		break;
-	}
-
-	__raw_writel(tcnt, S3C2410_TCNTB(mode));
-	__raw_writel(tcnt, S3C2410_TCMPB(mode));
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static void samsung_time_start(enum samsung_timer_mode mode, bool periodic)
-{
-	unsigned long tcon;
-
-	tcon  = __raw_readl(S3C2410_TCON);
-
-	switch (mode) {
-	case SAMSUNG_PWM0:
-		tcon |= S3C2410_TCON_T0START;
-		tcon &= ~S3C2410_TCON_T0MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T0RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T0RELOAD;
-		break;
-
-	case SAMSUNG_PWM1:
-		tcon |= S3C2410_TCON_T1START;
-		tcon &= ~S3C2410_TCON_T1MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T1RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T1RELOAD;
-		break;
-
-	case SAMSUNG_PWM2:
-		tcon |= S3C2410_TCON_T2START;
-		tcon &= ~S3C2410_TCON_T2MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T2RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T2RELOAD;
-		break;
-
-	case SAMSUNG_PWM3:
-		tcon |= S3C2410_TCON_T3START;
-		tcon &= ~S3C2410_TCON_T3MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T3RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T3RELOAD;
-		break;
-
-	case SAMSUNG_PWM4:
-		tcon |= S3C2410_TCON_T4START;
-		tcon &= ~S3C2410_TCON_T4MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T4RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T4RELOAD;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", mode);
-		break;
-	}
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static int samsung_set_next_event(unsigned long cycles,
-				struct clock_event_device *evt)
-{
-	samsung_time_setup(timer_source.event_id, cycles);
-	samsung_time_start(timer_source.event_id, NON_PERIODIC);
-
-	return 0;
-}
-
-static void samsung_set_mode(enum clock_event_mode mode,
-				struct clock_event_device *evt)
-{
-	samsung_time_stop(timer_source.event_id);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		samsung_time_setup(timer_source.event_id, clock_count_per_tick);
-		samsung_time_start(timer_source.event_id, PERIODIC);
-		break;
-
-	case CLOCK_EVT_MODE_ONESHOT:
-		break;
-
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		break;
-
-	case CLOCK_EVT_MODE_RESUME:
-		samsung_timer_resume();
-		break;
-	}
-}
-
-static void samsung_timer_resume(void)
-{
-	/* event timer restart */
-	samsung_time_setup(timer_source.event_id, clock_count_per_tick);
-	samsung_time_start(timer_source.event_id, PERIODIC);
-
-	/* source timer restart */
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
-	samsung_time_start(timer_source.source_id, PERIODIC);
-}
-
-void __init samsung_set_timer_source(enum samsung_timer_mode event,
-				 enum samsung_timer_mode source)
-{
-	s3c_device_timer[event].dev.bus = &platform_bus_type;
-	s3c_device_timer[source].dev.bus = &platform_bus_type;
-
-	timer_source.event_id = event;
-	timer_source.source_id = source;
-}
-
-static struct clock_event_device time_event_device = {
-	.name		= "samsung_event_timer",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.rating		= 200,
-	.set_next_event	= samsung_set_next_event,
-	.set_mode	= samsung_set_mode,
-};
-
-static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction samsung_clock_event_irq = {
-	.name		= "samsung_time_irq",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= samsung_clock_event_isr,
-	.dev_id		= &time_event_device,
-};
-
-static void __init samsung_clockevent_init(void)
-{
-	unsigned long pclk;
-	unsigned long clock_rate;
-	unsigned int irq_number;
-	struct clk *tscaler;
-
-	pclk = clk_get_rate(timerclk);
-
-	tscaler = clk_get_parent(tdiv_event);
-
-	clk_set_rate(tscaler, pclk / TSCALER_DIV);
-	clk_set_rate(tdiv_event, pclk / TDIV);
-	clk_set_parent(tin_event, tdiv_event);
-
-	clock_rate = clk_get_rate(tin_event);
-	clock_count_per_tick = clock_rate / HZ;
-
-	time_event_device.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&time_event_device, clock_rate, 1, -1);
-
-	irq_number = timer_source.event_id + IRQ_TIMER0;
-	setup_irq(irq_number, &samsung_clock_event_irq);
-}
-
-static void __iomem *samsung_timer_reg(void)
-{
-	unsigned long offset = 0;
-
-	switch (timer_source.source_id) {
-	case SAMSUNG_PWM0:
-	case SAMSUNG_PWM1:
-	case SAMSUNG_PWM2:
-	case SAMSUNG_PWM3:
-		offset = (timer_source.source_id * 0x0c) + 0x14;
-		break;
-
-	case SAMSUNG_PWM4:
-		offset = 0x40;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
-		return NULL;
-	}
-
-	return S3C_TIMERREG(offset);
-}
-
-/*
- * Override the global weak sched_clock symbol with this
- * local implementation which uses the clocksource to get some
- * better resolution when scheduling the kernel. We accept that
- * this wraps around for now, since it is just a relative time
- * stamp. (Inspired by U300 implementation.)
- */
-static u32 notrace samsung_read_sched_clock(void)
-{
-	void __iomem *reg = samsung_timer_reg();
-
-	if (!reg)
-		return 0;
-
-	return ~__raw_readl(reg);
-}
-
-static void __init samsung_clocksource_init(void)
-{
-	unsigned long pclk;
-	unsigned long clock_rate;
-
-	pclk = clk_get_rate(timerclk);
-
-	clk_set_rate(tdiv_source, pclk / TDIV);
-	clk_set_parent(tin_source, tdiv_source);
-
-	clock_rate = clk_get_rate(tin_source);
-
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
-	samsung_time_start(timer_source.source_id, PERIODIC);
-
-	setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate);
-
-	if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer",
-			clock_rate, 250, TSIZE, clocksource_mmio_readl_down))
-		panic("samsung_clocksource_timer: can't register clocksource\n");
-}
-
-static void __init samsung_timer_resources(void)
-{
-
-	unsigned long event_id = timer_source.event_id;
-	unsigned long source_id = timer_source.source_id;
-	char devname[15];
-
-	timerclk = clk_get(NULL, "timers");
-	if (IS_ERR(timerclk))
-		panic("failed to get timers clock for timer");
-
-	clk_enable(timerclk);
-
-	sprintf(devname, "s3c24xx-pwm.%lu", event_id);
-	s3c_device_timer[event_id].id = event_id;
-	s3c_device_timer[event_id].dev.init_name = devname;
-
-	tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
-	if (IS_ERR(tin_event))
-		panic("failed to get pwm-tin clock for event timer");
-
-	tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
-	if (IS_ERR(tdiv_event))
-		panic("failed to get pwm-tdiv clock for event timer");
-
-	clk_enable(tin_event);
-
-	sprintf(devname, "s3c24xx-pwm.%lu", source_id);
-	s3c_device_timer[source_id].id = source_id;
-	s3c_device_timer[source_id].dev.init_name = devname;
-
-	tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
-	if (IS_ERR(tin_source))
-		panic("failed to get pwm-tin clock for source timer");
-
-	tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
-	if (IS_ERR(tdiv_source))
-		panic("failed to get pwm-tdiv clock for source timer");
-
-	clk_enable(tin_source);
-}
-
-void __init samsung_timer_init(void)
-{
-	samsung_timer_resources();
-	samsung_clockevent_init();
-	samsung_clocksource_init();
-}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 10/20] ARM: SAMSUNG: Remove old samsung-time driver
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes the old samsung-time driver, since all its users have
been migrated to the new samsung_pwm_timer clocksource driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/Kconfig                     |   8 -
 arch/arm/plat-samsung/Makefile                    |   1 -
 arch/arm/plat-samsung/include/plat/samsung-time.h |  23 --
 arch/arm/plat-samsung/samsung-time.c              | 394 ----------------------
 4 files changed, 426 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/samsung-time.c

diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 3dc5cbe..3e880b7 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -72,14 +72,6 @@ config SAMSUNG_ATAGS
 
 if SAMSUNG_ATAGS
 
-# timer options
-
-config SAMSUNG_HRT
-	bool
-	select SAMSUNG_DEV_PWM
-	help
-	  Use the High Resolution timer support
-
 # clock options
 
 config SAMSUNG_CLOCK
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 98d07d8..cf41bf9 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -12,7 +12,6 @@ obj-				:=
 # Objects we always build independent of SoC choice
 
 obj-y				+= init.o cpu.o
-obj-$(CONFIG_SAMSUNG_HRT) 	+= samsung-time.o
 
 obj-$(CONFIG_SAMSUNG_CLOCK)	+= clock.o
 obj-$(CONFIG_SAMSUNG_CLOCK)	+= pwm-clock.o
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
index 4cc99bb..209464a 100644
--- a/arch/arm/plat-samsung/include/plat/samsung-time.h
+++ b/arch/arm/plat-samsung/include/plat/samsung-time.h
@@ -22,29 +22,6 @@ enum samsung_timer_mode {
 	SAMSUNG_PWM4,
 };
 
-struct samsung_timer_source {
-	unsigned int event_id;
-	unsigned int source_id;
-};
-
-/* Be able to sleep for atleast 4 seconds (usually more) */
-#define SAMSUNG_TIMER_MIN_RANGE	4
-
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100)
-#define TCNT_MAX		0xffff
-#define TSCALER_DIV		25
-#define TDIV			50
-#define TSIZE			16
-#else
-#define TCNT_MAX		0xffffffff
-#define TSCALER_DIV		2
-#define TDIV			2
-#define TSIZE			32
-#endif
-
-#define NON_PERIODIC		0
-#define PERIODIC		1
-
 extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
 					enum samsung_timer_mode source);
 
diff --git a/arch/arm/plat-samsung/samsung-time.c b/arch/arm/plat-samsung/samsung-time.c
deleted file mode 100644
index 2957075..0000000
--- a/arch/arm/plat-samsung/samsung-time.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * samsung - Common hr-timer support (s3c and s5p)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/platform_device.h>
-#include <linux/sched_clock.h>
-
-#include <asm/smp_twd.h>
-#include <asm/mach/time.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/regs-timer.h>
-#include <plat/samsung-time.h>
-
-static struct clk *tin_event;
-static struct clk *tin_source;
-static struct clk *tdiv_event;
-static struct clk *tdiv_source;
-static struct clk *timerclk;
-static struct samsung_timer_source timer_source;
-static unsigned long clock_count_per_tick;
-static void samsung_timer_resume(void);
-
-static void samsung_time_stop(enum samsung_timer_mode mode)
-{
-	unsigned long tcon;
-
-	tcon = __raw_readl(S3C2410_TCON);
-
-	switch (mode) {
-	case SAMSUNG_PWM0:
-		tcon &= ~S3C2410_TCON_T0START;
-		break;
-
-	case SAMSUNG_PWM1:
-		tcon &= ~S3C2410_TCON_T1START;
-		break;
-
-	case SAMSUNG_PWM2:
-		tcon &= ~S3C2410_TCON_T2START;
-		break;
-
-	case SAMSUNG_PWM3:
-		tcon &= ~S3C2410_TCON_T3START;
-		break;
-
-	case SAMSUNG_PWM4:
-		tcon &= ~S3C2410_TCON_T4START;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", mode);
-		break;
-	}
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static void samsung_time_setup(enum samsung_timer_mode mode, unsigned long tcnt)
-{
-	unsigned long tcon;
-
-	tcon = __raw_readl(S3C2410_TCON);
-
-	tcnt--;
-
-	switch (mode) {
-	case SAMSUNG_PWM0:
-		tcon &= ~(0x0f << 0);
-		tcon |= S3C2410_TCON_T0MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM1:
-		tcon &= ~(0x0f << 8);
-		tcon |= S3C2410_TCON_T1MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM2:
-		tcon &= ~(0x0f << 12);
-		tcon |= S3C2410_TCON_T2MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM3:
-		tcon &= ~(0x0f << 16);
-		tcon |= S3C2410_TCON_T3MANUALUPD;
-		break;
-
-	case SAMSUNG_PWM4:
-		tcon &= ~(0x07 << 20);
-		tcon |= S3C2410_TCON_T4MANUALUPD;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", mode);
-		break;
-	}
-
-	__raw_writel(tcnt, S3C2410_TCNTB(mode));
-	__raw_writel(tcnt, S3C2410_TCMPB(mode));
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static void samsung_time_start(enum samsung_timer_mode mode, bool periodic)
-{
-	unsigned long tcon;
-
-	tcon  = __raw_readl(S3C2410_TCON);
-
-	switch (mode) {
-	case SAMSUNG_PWM0:
-		tcon |= S3C2410_TCON_T0START;
-		tcon &= ~S3C2410_TCON_T0MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T0RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T0RELOAD;
-		break;
-
-	case SAMSUNG_PWM1:
-		tcon |= S3C2410_TCON_T1START;
-		tcon &= ~S3C2410_TCON_T1MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T1RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T1RELOAD;
-		break;
-
-	case SAMSUNG_PWM2:
-		tcon |= S3C2410_TCON_T2START;
-		tcon &= ~S3C2410_TCON_T2MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T2RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T2RELOAD;
-		break;
-
-	case SAMSUNG_PWM3:
-		tcon |= S3C2410_TCON_T3START;
-		tcon &= ~S3C2410_TCON_T3MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T3RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T3RELOAD;
-		break;
-
-	case SAMSUNG_PWM4:
-		tcon |= S3C2410_TCON_T4START;
-		tcon &= ~S3C2410_TCON_T4MANUALUPD;
-
-		if (periodic)
-			tcon |= S3C2410_TCON_T4RELOAD;
-		else
-			tcon &= ~S3C2410_TCON_T4RELOAD;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", mode);
-		break;
-	}
-	__raw_writel(tcon, S3C2410_TCON);
-}
-
-static int samsung_set_next_event(unsigned long cycles,
-				struct clock_event_device *evt)
-{
-	samsung_time_setup(timer_source.event_id, cycles);
-	samsung_time_start(timer_source.event_id, NON_PERIODIC);
-
-	return 0;
-}
-
-static void samsung_set_mode(enum clock_event_mode mode,
-				struct clock_event_device *evt)
-{
-	samsung_time_stop(timer_source.event_id);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		samsung_time_setup(timer_source.event_id, clock_count_per_tick);
-		samsung_time_start(timer_source.event_id, PERIODIC);
-		break;
-
-	case CLOCK_EVT_MODE_ONESHOT:
-		break;
-
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		break;
-
-	case CLOCK_EVT_MODE_RESUME:
-		samsung_timer_resume();
-		break;
-	}
-}
-
-static void samsung_timer_resume(void)
-{
-	/* event timer restart */
-	samsung_time_setup(timer_source.event_id, clock_count_per_tick);
-	samsung_time_start(timer_source.event_id, PERIODIC);
-
-	/* source timer restart */
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
-	samsung_time_start(timer_source.source_id, PERIODIC);
-}
-
-void __init samsung_set_timer_source(enum samsung_timer_mode event,
-				 enum samsung_timer_mode source)
-{
-	s3c_device_timer[event].dev.bus = &platform_bus_type;
-	s3c_device_timer[source].dev.bus = &platform_bus_type;
-
-	timer_source.event_id = event;
-	timer_source.source_id = source;
-}
-
-static struct clock_event_device time_event_device = {
-	.name		= "samsung_event_timer",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.rating		= 200,
-	.set_next_event	= samsung_set_next_event,
-	.set_mode	= samsung_set_mode,
-};
-
-static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction samsung_clock_event_irq = {
-	.name		= "samsung_time_irq",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= samsung_clock_event_isr,
-	.dev_id		= &time_event_device,
-};
-
-static void __init samsung_clockevent_init(void)
-{
-	unsigned long pclk;
-	unsigned long clock_rate;
-	unsigned int irq_number;
-	struct clk *tscaler;
-
-	pclk = clk_get_rate(timerclk);
-
-	tscaler = clk_get_parent(tdiv_event);
-
-	clk_set_rate(tscaler, pclk / TSCALER_DIV);
-	clk_set_rate(tdiv_event, pclk / TDIV);
-	clk_set_parent(tin_event, tdiv_event);
-
-	clock_rate = clk_get_rate(tin_event);
-	clock_count_per_tick = clock_rate / HZ;
-
-	time_event_device.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&time_event_device, clock_rate, 1, -1);
-
-	irq_number = timer_source.event_id + IRQ_TIMER0;
-	setup_irq(irq_number, &samsung_clock_event_irq);
-}
-
-static void __iomem *samsung_timer_reg(void)
-{
-	unsigned long offset = 0;
-
-	switch (timer_source.source_id) {
-	case SAMSUNG_PWM0:
-	case SAMSUNG_PWM1:
-	case SAMSUNG_PWM2:
-	case SAMSUNG_PWM3:
-		offset = (timer_source.source_id * 0x0c) + 0x14;
-		break;
-
-	case SAMSUNG_PWM4:
-		offset = 0x40;
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
-		return NULL;
-	}
-
-	return S3C_TIMERREG(offset);
-}
-
-/*
- * Override the global weak sched_clock symbol with this
- * local implementation which uses the clocksource to get some
- * better resolution when scheduling the kernel. We accept that
- * this wraps around for now, since it is just a relative time
- * stamp. (Inspired by U300 implementation.)
- */
-static u32 notrace samsung_read_sched_clock(void)
-{
-	void __iomem *reg = samsung_timer_reg();
-
-	if (!reg)
-		return 0;
-
-	return ~__raw_readl(reg);
-}
-
-static void __init samsung_clocksource_init(void)
-{
-	unsigned long pclk;
-	unsigned long clock_rate;
-
-	pclk = clk_get_rate(timerclk);
-
-	clk_set_rate(tdiv_source, pclk / TDIV);
-	clk_set_parent(tin_source, tdiv_source);
-
-	clock_rate = clk_get_rate(tin_source);
-
-	samsung_time_setup(timer_source.source_id, TCNT_MAX);
-	samsung_time_start(timer_source.source_id, PERIODIC);
-
-	setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate);
-
-	if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer",
-			clock_rate, 250, TSIZE, clocksource_mmio_readl_down))
-		panic("samsung_clocksource_timer: can't register clocksource\n");
-}
-
-static void __init samsung_timer_resources(void)
-{
-
-	unsigned long event_id = timer_source.event_id;
-	unsigned long source_id = timer_source.source_id;
-	char devname[15];
-
-	timerclk = clk_get(NULL, "timers");
-	if (IS_ERR(timerclk))
-		panic("failed to get timers clock for timer");
-
-	clk_enable(timerclk);
-
-	sprintf(devname, "s3c24xx-pwm.%lu", event_id);
-	s3c_device_timer[event_id].id = event_id;
-	s3c_device_timer[event_id].dev.init_name = devname;
-
-	tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
-	if (IS_ERR(tin_event))
-		panic("failed to get pwm-tin clock for event timer");
-
-	tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
-	if (IS_ERR(tdiv_event))
-		panic("failed to get pwm-tdiv clock for event timer");
-
-	clk_enable(tin_event);
-
-	sprintf(devname, "s3c24xx-pwm.%lu", source_id);
-	s3c_device_timer[source_id].id = source_id;
-	s3c_device_timer[source_id].dev.init_name = devname;
-
-	tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
-	if (IS_ERR(tin_source))
-		panic("failed to get pwm-tin clock for source timer");
-
-	tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
-	if (IS_ERR(tdiv_source))
-		panic("failed to get pwm-tdiv clock for source timer");
-
-	clk_enable(tin_source);
-}
-
-void __init samsung_timer_init(void)
-{
-	samsung_timer_resources();
-	samsung_clockevent_init();
-	samsung_clocksource_init();
-}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 11/20] ARM: SAMSUNG: Remove unused PWM timer IRQ chip code
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa, Kyungmin Park

From: Tomasz Figa <t.figa@samsung.com>

As the need for an IRQ chip handling PWM timer interrupt chaining is
gone now, this patch removes all the code made unnecessary.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/Kconfig                                   |  1 -
 arch/arm/mach-s3c64xx/include/mach/irqs.h          |  8 --
 arch/arm/mach-s5p64x0/include/mach/irqs.h          |  2 -
 arch/arm/mach-s5pc100/include/mach/irqs.h          |  2 -
 arch/arm/mach-s5pv210/include/mach/irqs.h          |  2 -
 arch/arm/plat-samsung/Kconfig                      |  6 --
 arch/arm/plat-samsung/Makefile                     |  1 -
 arch/arm/plat-samsung/devs.c                       | 25 ++----
 arch/arm/plat-samsung/include/plat/irq-vic-timer.h | 13 ---
 arch/arm/plat-samsung/include/plat/irqs.h          |  9 --
 arch/arm/plat-samsung/irq-vic-timer.c              | 98 ----------------------
 11 files changed, 6 insertions(+), 161 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/irq-vic-timer.h
 delete mode 100644 arch/arm/plat-samsung/irq-vic-timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 486ab0a..fa7ffca 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -739,7 +739,6 @@ config ARCH_S3C64XX
 	select SAMSUNG_ATAGS
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_GPIOLIB_4BIT
-	select SAMSUNG_IRQ_VIC_TIMER
 	select SAMSUNG_WDT_RESET
 	select USB_ARCH_HAS_OHCI
 	help
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
index 96d60e0..67bbd1d 100644
--- a/arch/arm/mach-s3c64xx/include/mach/irqs.h
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -107,14 +107,6 @@
 #define IRQ_TC			IRQ_PENDN
 #define IRQ_ADC			S3C64XX_IRQ_VIC1(31)
 
-#define S3C64XX_TIMER_IRQ(x)	S3C_IRQ(64 + (x))
-
-#define IRQ_TIMER0		S3C64XX_TIMER_IRQ(0)
-#define IRQ_TIMER1		S3C64XX_TIMER_IRQ(1)
-#define IRQ_TIMER2		S3C64XX_TIMER_IRQ(2)
-#define IRQ_TIMER3		S3C64XX_TIMER_IRQ(3)
-#define IRQ_TIMER4		S3C64XX_TIMER_IRQ(4)
-
 /* compatibility for device defines */
 
 #define IRQ_IIC1		IRQ_S3C6410_IIC1
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 5b845e8..53982db 100644
--- a/arch/arm/mach-s5p64x0/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -141,8 +141,6 @@
 
 #define IRQ_EINT_GROUP(grp, x)	(IRQ_EINT_GROUP##grp##_BASE + (x))
 
-#define IRQ_TIMER_BASE		(11)
-
 /* Set the default NR_IRQS */
 
 #define NR_IRQS			(IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 2870f12..d2eb475 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -97,8 +97,6 @@
 #define IRQ_SDMFIQ		S5P_IRQ_VIC2(31)
 #define IRQ_VIC_END		S5P_IRQ_VIC2(31)
 
-#define IRQ_TIMER_BASE		(11)
-
 #define S5P_EINT_BASE1		(S5P_IRQ_VIC0(0))
 #define S5P_EINT_BASE2		(IRQ_VIC_END + 1)
 
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index e777e01..5e0de3a 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -118,8 +118,6 @@
 #define IRQ_MDNIE3		S5P_IRQ_VIC3(8)
 #define IRQ_VIC_END		S5P_IRQ_VIC3(31)
 
-#define IRQ_TIMER_BASE		(11)
-
 #define S5P_EINT_BASE1		(S5P_IRQ_VIC0(0))
 #define S5P_EINT_BASE2		(IRQ_VIC_END + 1)
 
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 3e880b7..b21d9d5 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -25,7 +25,6 @@ config PLAT_S5P
 	select S5P_GPIO_DRVSTR
 	select SAMSUNG_CLKSRC if !COMMON_CLK
 	select SAMSUNG_GPIOLIB_4BIT
-	select SAMSUNG_IRQ_VIC_TIMER
 	help
 	  Base platform code for Samsung's S5P series SoC.
 
@@ -91,11 +90,6 @@ config S5P_CLOCK
 
 # options for IRQ support
 
-config SAMSUNG_IRQ_VIC_TIMER
-       bool
-       help
-         Internal configuration to build the VIC timer interrupt code.
-
 config S5P_IRQ
 	def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index cf41bf9..aafbe56 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_SAMSUNG_CLOCK)	+= pwm-clock.o
 obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
 obj-$(CONFIG_S5P_CLOCK)		+= s5p-clock.o
 
-obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
 obj-$(CONFIG_S5P_IRQ)		+= s5p-irq.o
 obj-$(CONFIG_S5P_EXT_INT)	+= s5p-irq-eint.o
 obj-$(CONFIG_S5P_GPIO_INT)	+= s5p-irq-gpioint.o
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index bba6d78..290f63a 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1099,22 +1099,9 @@ arch_initcall(s5p_pmu_init);
 
 #ifdef CONFIG_SAMSUNG_DEV_PWM
 
-#define TIMER_RESOURCE_SIZE (1)
-
-#define TIMER_RESOURCE(_tmr, _irq)			\
-	(struct resource [TIMER_RESOURCE_SIZE]) {	\
-		[0] = {					\
-			.start	= _irq,			\
-			.end	= _irq,			\
-			.flags	= IORESOURCE_IRQ	\
-		}					\
-	}
-
-#define DEFINE_S3C_TIMER(_tmr_no, _irq)			\
+#define DEFINE_S3C_TIMER(_tmr_no)			\
 	.name		= "s3c24xx-pwm",		\
 	.id		= _tmr_no,			\
-	.num_resources	= TIMER_RESOURCE_SIZE,		\
-	.resource	= TIMER_RESOURCE(_tmr_no, _irq),	\
 
 /*
  * since we already have an static mapping for the timer,
@@ -1122,11 +1109,11 @@ arch_initcall(s5p_pmu_init);
  */
 
 struct platform_device s3c_device_timer[] = {
-	[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
-	[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
-	[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
-	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
-	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+	[0] = { DEFINE_S3C_TIMER(0) },
+	[1] = { DEFINE_S3C_TIMER(1) },
+	[2] = { DEFINE_S3C_TIMER(2) },
+	[3] = { DEFINE_S3C_TIMER(3) },
+	[4] = { DEFINE_S3C_TIMER(4) },
 };
 
 static struct resource samsung_pwm_resource[] = {
diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
deleted file mode 100644
index 5b9c42f..0000000
--- a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h
- *
- * Copyright (c) 2010 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for Samsung SoC IRQ VIC timer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq);
diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h
index df46b77..039001c 100644
--- a/arch/arm/plat-samsung/include/plat/irqs.h
+++ b/arch/arm/plat-samsung/include/plat/irqs.h
@@ -44,15 +44,6 @@
 #define S5P_IRQ_VIC2(x)		(S5P_VIC2_BASE + (x))
 #define S5P_IRQ_VIC3(x)		(S5P_VIC3_BASE + (x))
 
-#define S5P_TIMER_IRQ(x)	(IRQ_TIMER_BASE + (x))
-
-#define IRQ_TIMER0		S5P_TIMER_IRQ(0)
-#define IRQ_TIMER1		S5P_TIMER_IRQ(1)
-#define IRQ_TIMER2		S5P_TIMER_IRQ(2)
-#define IRQ_TIMER3		S5P_TIMER_IRQ(3)
-#define IRQ_TIMER4		S5P_TIMER_IRQ(4)
-#define IRQ_TIMER_COUNT		(5)
-
 #define IRQ_EINT(x)		((x) < 16 ? ((x) + S5P_EINT_BASE1) \
 					: ((x) - 16 + S5P_EINT_BASE2))
 
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
deleted file mode 100644
index 0fceb42..0000000
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* arch/arm/plat-samsung/irq-vic-timer.c
- *	originally part of arch/arm/plat-s3c64xx/irq.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <plat/cpu.h>
-#include <plat/irq-vic-timer.h>
-#include <plat/regs-timer.h>
-
-static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
-{
-	struct irq_chip *chip = irq_get_chip(irq);
-	chained_irq_enter(chip, desc);
-	generic_handle_irq((int)desc->irq_data.handler_data);
-	chained_irq_exit(chip, desc);
-}
-
-/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-static void s3c_irq_timer_ack(struct irq_data *d)
-{
-	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-	u32 mask = (1 << 5) << (d->irq - gc->irq_base);
-
-	irq_reg_writel(mask | gc->mask_cache, gc->reg_base);
-}
-
-/**
- * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\
- * @num: Number of timers to initialize
- * @timer_irq: Base IRQ number to be used for the timers.
- *
- * Register the necessary IRQ chaining and support for the timer IRQs
- * chained of the VIC.
- */
-void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq)
-{
-	unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
-				 IRQ_TIMER3_VIC, IRQ_TIMER4_VIC };
-	struct irq_chip_generic *s3c_tgc;
-	struct irq_chip_type *ct;
-	unsigned int i;
-
-#ifdef CONFIG_ARCH_EXYNOS
-	if (soc_is_exynos5250()) {
-		pirq[0] = EXYNOS5_IRQ_TIMER0_VIC;
-		pirq[1] = EXYNOS5_IRQ_TIMER1_VIC;
-		pirq[2] = EXYNOS5_IRQ_TIMER2_VIC;
-		pirq[3] = EXYNOS5_IRQ_TIMER3_VIC;
-		pirq[4] = EXYNOS5_IRQ_TIMER4_VIC;
-	} else {
-		pirq[0] = EXYNOS4_IRQ_TIMER0_VIC;
-		pirq[1] = EXYNOS4_IRQ_TIMER1_VIC;
-		pirq[2] = EXYNOS4_IRQ_TIMER2_VIC;
-		pirq[3] = EXYNOS4_IRQ_TIMER3_VIC;
-		pirq[4] = EXYNOS4_IRQ_TIMER4_VIC;
-	}
-#endif
-	s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq,
-					 S3C64XX_TINT_CSTAT, handle_level_irq);
-
-	if (!s3c_tgc) {
-		pr_err("%s: irq_alloc_generic_chip for IRQ %d failed\n",
-		       __func__, timer_irq);
-		return;
-	}
-
-	ct = s3c_tgc->chip_types;
-	ct->chip.irq_mask = irq_gc_mask_clr_bit;
-	ct->chip.irq_unmask = irq_gc_mask_set_bit;
-	ct->chip.irq_ack = s3c_irq_timer_ack;
-	irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
-			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
-	/* Clear the upper bits of the mask_cache*/
-	s3c_tgc->mask_cache &= 0x1f;
-
-	for (i = 0; i < num; i++, timer_irq++) {
-		irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer);
-		irq_set_handler_data(pirq[i], (void *)timer_irq);
-	}
-}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 11/20] ARM: SAMSUNG: Remove unused PWM timer IRQ chip code
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Tomasz Figa <t.figa@samsung.com>

As the need for an IRQ chip handling PWM timer interrupt chaining is
gone now, this patch removes all the code made unnecessary.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/Kconfig                                   |  1 -
 arch/arm/mach-s3c64xx/include/mach/irqs.h          |  8 --
 arch/arm/mach-s5p64x0/include/mach/irqs.h          |  2 -
 arch/arm/mach-s5pc100/include/mach/irqs.h          |  2 -
 arch/arm/mach-s5pv210/include/mach/irqs.h          |  2 -
 arch/arm/plat-samsung/Kconfig                      |  6 --
 arch/arm/plat-samsung/Makefile                     |  1 -
 arch/arm/plat-samsung/devs.c                       | 25 ++----
 arch/arm/plat-samsung/include/plat/irq-vic-timer.h | 13 ---
 arch/arm/plat-samsung/include/plat/irqs.h          |  9 --
 arch/arm/plat-samsung/irq-vic-timer.c              | 98 ----------------------
 11 files changed, 6 insertions(+), 161 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/irq-vic-timer.h
 delete mode 100644 arch/arm/plat-samsung/irq-vic-timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 486ab0a..fa7ffca 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -739,7 +739,6 @@ config ARCH_S3C64XX
 	select SAMSUNG_ATAGS
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_GPIOLIB_4BIT
-	select SAMSUNG_IRQ_VIC_TIMER
 	select SAMSUNG_WDT_RESET
 	select USB_ARCH_HAS_OHCI
 	help
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
index 96d60e0..67bbd1d 100644
--- a/arch/arm/mach-s3c64xx/include/mach/irqs.h
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -107,14 +107,6 @@
 #define IRQ_TC			IRQ_PENDN
 #define IRQ_ADC			S3C64XX_IRQ_VIC1(31)
 
-#define S3C64XX_TIMER_IRQ(x)	S3C_IRQ(64 + (x))
-
-#define IRQ_TIMER0		S3C64XX_TIMER_IRQ(0)
-#define IRQ_TIMER1		S3C64XX_TIMER_IRQ(1)
-#define IRQ_TIMER2		S3C64XX_TIMER_IRQ(2)
-#define IRQ_TIMER3		S3C64XX_TIMER_IRQ(3)
-#define IRQ_TIMER4		S3C64XX_TIMER_IRQ(4)
-
 /* compatibility for device defines */
 
 #define IRQ_IIC1		IRQ_S3C6410_IIC1
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 5b845e8..53982db 100644
--- a/arch/arm/mach-s5p64x0/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -141,8 +141,6 @@
 
 #define IRQ_EINT_GROUP(grp, x)	(IRQ_EINT_GROUP##grp##_BASE + (x))
 
-#define IRQ_TIMER_BASE		(11)
-
 /* Set the default NR_IRQS */
 
 #define NR_IRQS			(IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 2870f12..d2eb475 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -97,8 +97,6 @@
 #define IRQ_SDMFIQ		S5P_IRQ_VIC2(31)
 #define IRQ_VIC_END		S5P_IRQ_VIC2(31)
 
-#define IRQ_TIMER_BASE		(11)
-
 #define S5P_EINT_BASE1		(S5P_IRQ_VIC0(0))
 #define S5P_EINT_BASE2		(IRQ_VIC_END + 1)
 
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index e777e01..5e0de3a 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -118,8 +118,6 @@
 #define IRQ_MDNIE3		S5P_IRQ_VIC3(8)
 #define IRQ_VIC_END		S5P_IRQ_VIC3(31)
 
-#define IRQ_TIMER_BASE		(11)
-
 #define S5P_EINT_BASE1		(S5P_IRQ_VIC0(0))
 #define S5P_EINT_BASE2		(IRQ_VIC_END + 1)
 
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 3e880b7..b21d9d5 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -25,7 +25,6 @@ config PLAT_S5P
 	select S5P_GPIO_DRVSTR
 	select SAMSUNG_CLKSRC if !COMMON_CLK
 	select SAMSUNG_GPIOLIB_4BIT
-	select SAMSUNG_IRQ_VIC_TIMER
 	help
 	  Base platform code for Samsung's S5P series SoC.
 
@@ -91,11 +90,6 @@ config S5P_CLOCK
 
 # options for IRQ support
 
-config SAMSUNG_IRQ_VIC_TIMER
-       bool
-       help
-         Internal configuration to build the VIC timer interrupt code.
-
 config S5P_IRQ
 	def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index cf41bf9..aafbe56 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_SAMSUNG_CLOCK)	+= pwm-clock.o
 obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
 obj-$(CONFIG_S5P_CLOCK)		+= s5p-clock.o
 
-obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
 obj-$(CONFIG_S5P_IRQ)		+= s5p-irq.o
 obj-$(CONFIG_S5P_EXT_INT)	+= s5p-irq-eint.o
 obj-$(CONFIG_S5P_GPIO_INT)	+= s5p-irq-gpioint.o
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index bba6d78..290f63a 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1099,22 +1099,9 @@ arch_initcall(s5p_pmu_init);
 
 #ifdef CONFIG_SAMSUNG_DEV_PWM
 
-#define TIMER_RESOURCE_SIZE (1)
-
-#define TIMER_RESOURCE(_tmr, _irq)			\
-	(struct resource [TIMER_RESOURCE_SIZE]) {	\
-		[0] = {					\
-			.start	= _irq,			\
-			.end	= _irq,			\
-			.flags	= IORESOURCE_IRQ	\
-		}					\
-	}
-
-#define DEFINE_S3C_TIMER(_tmr_no, _irq)			\
+#define DEFINE_S3C_TIMER(_tmr_no)			\
 	.name		= "s3c24xx-pwm",		\
 	.id		= _tmr_no,			\
-	.num_resources	= TIMER_RESOURCE_SIZE,		\
-	.resource	= TIMER_RESOURCE(_tmr_no, _irq),	\
 
 /*
  * since we already have an static mapping for the timer,
@@ -1122,11 +1109,11 @@ arch_initcall(s5p_pmu_init);
  */
 
 struct platform_device s3c_device_timer[] = {
-	[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
-	[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
-	[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
-	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
-	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+	[0] = { DEFINE_S3C_TIMER(0) },
+	[1] = { DEFINE_S3C_TIMER(1) },
+	[2] = { DEFINE_S3C_TIMER(2) },
+	[3] = { DEFINE_S3C_TIMER(3) },
+	[4] = { DEFINE_S3C_TIMER(4) },
 };
 
 static struct resource samsung_pwm_resource[] = {
diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
deleted file mode 100644
index 5b9c42f..0000000
--- a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h
- *
- * Copyright (c) 2010 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for Samsung SoC IRQ VIC timer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq);
diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h
index df46b77..039001c 100644
--- a/arch/arm/plat-samsung/include/plat/irqs.h
+++ b/arch/arm/plat-samsung/include/plat/irqs.h
@@ -44,15 +44,6 @@
 #define S5P_IRQ_VIC2(x)		(S5P_VIC2_BASE + (x))
 #define S5P_IRQ_VIC3(x)		(S5P_VIC3_BASE + (x))
 
-#define S5P_TIMER_IRQ(x)	(IRQ_TIMER_BASE + (x))
-
-#define IRQ_TIMER0		S5P_TIMER_IRQ(0)
-#define IRQ_TIMER1		S5P_TIMER_IRQ(1)
-#define IRQ_TIMER2		S5P_TIMER_IRQ(2)
-#define IRQ_TIMER3		S5P_TIMER_IRQ(3)
-#define IRQ_TIMER4		S5P_TIMER_IRQ(4)
-#define IRQ_TIMER_COUNT		(5)
-
 #define IRQ_EINT(x)		((x) < 16 ? ((x) + S5P_EINT_BASE1) \
 					: ((x) - 16 + S5P_EINT_BASE2))
 
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
deleted file mode 100644
index 0fceb42..0000000
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* arch/arm/plat-samsung/irq-vic-timer.c
- *	originally part of arch/arm/plat-s3c64xx/irq.c
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C64XX - Interrupt handling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/io.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <plat/cpu.h>
-#include <plat/irq-vic-timer.h>
-#include <plat/regs-timer.h>
-
-static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
-{
-	struct irq_chip *chip = irq_get_chip(irq);
-	chained_irq_enter(chip, desc);
-	generic_handle_irq((int)desc->irq_data.handler_data);
-	chained_irq_exit(chip, desc);
-}
-
-/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-static void s3c_irq_timer_ack(struct irq_data *d)
-{
-	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
-	u32 mask = (1 << 5) << (d->irq - gc->irq_base);
-
-	irq_reg_writel(mask | gc->mask_cache, gc->reg_base);
-}
-
-/**
- * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\
- * @num: Number of timers to initialize
- * @timer_irq: Base IRQ number to be used for the timers.
- *
- * Register the necessary IRQ chaining and support for the timer IRQs
- * chained of the VIC.
- */
-void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq)
-{
-	unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
-				 IRQ_TIMER3_VIC, IRQ_TIMER4_VIC };
-	struct irq_chip_generic *s3c_tgc;
-	struct irq_chip_type *ct;
-	unsigned int i;
-
-#ifdef CONFIG_ARCH_EXYNOS
-	if (soc_is_exynos5250()) {
-		pirq[0] = EXYNOS5_IRQ_TIMER0_VIC;
-		pirq[1] = EXYNOS5_IRQ_TIMER1_VIC;
-		pirq[2] = EXYNOS5_IRQ_TIMER2_VIC;
-		pirq[3] = EXYNOS5_IRQ_TIMER3_VIC;
-		pirq[4] = EXYNOS5_IRQ_TIMER4_VIC;
-	} else {
-		pirq[0] = EXYNOS4_IRQ_TIMER0_VIC;
-		pirq[1] = EXYNOS4_IRQ_TIMER1_VIC;
-		pirq[2] = EXYNOS4_IRQ_TIMER2_VIC;
-		pirq[3] = EXYNOS4_IRQ_TIMER3_VIC;
-		pirq[4] = EXYNOS4_IRQ_TIMER4_VIC;
-	}
-#endif
-	s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq,
-					 S3C64XX_TINT_CSTAT, handle_level_irq);
-
-	if (!s3c_tgc) {
-		pr_err("%s: irq_alloc_generic_chip for IRQ %d failed\n",
-		       __func__, timer_irq);
-		return;
-	}
-
-	ct = s3c_tgc->chip_types;
-	ct->chip.irq_mask = irq_gc_mask_clr_bit;
-	ct->chip.irq_unmask = irq_gc_mask_set_bit;
-	ct->chip.irq_ack = s3c_irq_timer_ack;
-	irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
-			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
-	/* Clear the upper bits of the mask_cache*/
-	s3c_tgc->mask_cache &= 0x1f;
-
-	for (i = 0; i < num; i++, timer_irq++) {
-		irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer);
-		irq_set_handler_data(pirq[i], (void *)timer_irq);
-	}
-}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 12/20] pwm: samsung: Rename to pwm-samsung-legacy
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch renames the old pwm-samsung driver to pwm-samsung-legacy to
create place for the new, rewritten, DT-aware pwm-samsung driver using
Samsung PWM/timer master driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile                                | 2 +-
 drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} (100%)

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c18..aa94807 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
-obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung-legacy.c
similarity index 100%
rename from drivers/pwm/pwm-samsung.c
rename to drivers/pwm/pwm-samsung-legacy.c
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 12/20] pwm: samsung: Rename to pwm-samsung-legacy
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch renames the old pwm-samsung driver to pwm-samsung-legacy to
create place for the new, rewritten, DT-aware pwm-samsung driver using
Samsung PWM/timer master driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile                                | 2 +-
 drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} (100%)

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c18..aa94807 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
-obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung-legacy.c
similarity index 100%
rename from drivers/pwm/pwm-samsung.c
rename to drivers/pwm/pwm-samsung-legacy.c
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 13/20] pwm: Add new pwm-samsung driver
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch introduces new Samsung PWM driver, which uses Samsung
PWM/timer master driver to control shared parts of the hardware.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile      |   1 +
 drivers/pwm/pwm-samsung.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 607 insertions(+)
 create mode 100644 drivers/pwm/pwm-samsung.c

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index aa94807..86a5771 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
new file mode 100644
index 0000000..b9e5240
--- /dev/null
+++ b/drivers/pwm/pwm-samsung.c
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * PWM driver for Samsung SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+/* For struct samsung_timer_variant and samsung_pwm_lock. */
+#include <clocksource/samsung_pwm.h>
+
+#define REG_TCFG0			0x00
+#define REG_TCFG1			0x04
+#define REG_TCON			0x08
+
+#define REG_TCNTB(tmr)			(0x0c + ((tmr) * 0xc))
+#define REG_TCMPB(tmr)			(0x10 + ((tmr) * 0xc))
+
+#define TCFG0_PRESCALER_MASK		0xff
+#define TCFG0_PRESCALER1_SHIFT		8
+
+#define TCFG1_MUX_MASK			0xf
+#define TCFG1_SHIFT(x)			((x) * 4)
+
+#define TCON_START(chan)		(1 << (4 * (chan) + 0))
+#define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
+#define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
+#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
+						+ (((chan) < 5) ? 3 : 2)))
+
+/**
+ * struct samsung_pwm_channel - private data of PWM channel
+ * @period_ns:	current period in nanoseconds programmed to the hardware
+ * @duty_ns:	current duty time in nanoseconds programmed to the hardware
+ * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
+ */
+struct samsung_pwm_channel {
+	u32 period_ns;
+	u32 duty_ns;
+	u32 tin_ns;
+};
+
+/**
+ * struct samsung_pwm_chip - private data of PWM chip
+ * @chip:		generic PWM chip
+ * @variant:		local copy of hardware variant data
+ * @inverter_mask:	inverter status for all channels - one bit per channel
+ * @base:		base address of mapped PWM registers
+ * @base_clk:		base clock used to drive the timers
+ * @tclk0:		external clock 0 (can be ERR_PTR if not present)
+ * @tclk1:		external clock 1 (can be ERR_PTR if not present)
+ */
+struct samsung_pwm_chip {
+	struct pwm_chip chip;
+	struct samsung_pwm_variant variant;
+	u8 inverter_mask;
+
+	void __iomem *base;
+	struct clk *base_clk;
+	struct clk *tclk0;
+	struct clk *tclk1;
+};
+
+#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
+/*
+ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
+ * and some registers need access synchronization. If both drivers are
+ * compiled in, the spinlock is defined in the clocksource driver,
+ * otherwise following definition is used.
+ *
+ * Currently we do not need any more complex synchronization method
+ * because all the supported SoCs contain only one instance of the PWM
+ * IP. Should this change, both drivers will need to be modified to
+ * properly synchronize accesses to particular instances.
+ */
+static DEFINE_SPINLOCK(samsung_pwm_lock);
+#endif
+
+static inline
+struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct samsung_pwm_chip, chip);
+}
+
+static inline unsigned int to_tcon_channel(unsigned int channel)
+{
+	/* TCON register has a gap of 4 bits (1 channel) */
+	return (channel == 0) ? 0 : (channel + 1);
+}
+
+static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
+				    unsigned int channel, u8 divisor)
+{
+	u8 shift = TCFG1_SHIFT(channel);
+	unsigned long flags;
+	u32 reg;
+	u8 bits;
+
+	bits = (fls(divisor) - 1) - pwm->variant.div_base;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	reg = readl(pwm->base + REG_TCFG1);
+	reg &= ~(TCFG1_MUX_MASK << shift);
+	reg |= bits << shift;
+	writel(reg, pwm->base + REG_TCFG1);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	u32 reg;
+
+	reg = readl(chip->base + REG_TCFG1);
+	reg >>= TCFG1_SHIFT(chan);
+	reg &= TCFG1_MUX_MASK;
+
+	return (BIT(reg) & variant->tclk_mask) == 0;
+}
+
+static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
+					      unsigned int chan)
+{
+	unsigned long rate;
+	u32 reg;
+
+	rate = clk_get_rate(chip->base_clk);
+
+	reg = readl(chip->base + REG_TCFG0);
+	if (chan >= 2)
+		reg >>= TCFG0_PRESCALER1_SHIFT;
+	reg &= TCFG0_PRESCALER_MASK;
+
+	return rate / (reg + 1);
+}
+
+static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
+					  unsigned int chan, unsigned long freq)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	unsigned long rate;
+	struct clk *clk;
+	u8 div;
+
+	if (!pwm_samsung_is_tdiv(chip, chan)) {
+		clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
+		if (!IS_ERR(clk)) {
+			rate = clk_get_rate(clk);
+			if (rate)
+				return rate;
+		}
+
+		dev_warn(chip->chip.dev,
+			"tclk of PWM %d is inoperational, using tdiv\n", chan);
+	}
+
+	rate = pwm_samsung_get_tin_rate(chip, chan);
+	dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
+
+	/*
+	 * Compare minimum PWM frequency that can be achieved with possible
+	 * divider settings and choose the lowest divisor that can generate
+	 * frequencies lower than requested.
+	 */
+	for (div = variant->div_base; div < 4; ++div)
+		if ((rate >> (variant->bits + div)) < freq)
+			break;
+
+	pwm_samsung_set_divisor(chip, chan, BIT(div));
+
+	return rate >> div;
+}
+
+static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *our_chan;
+
+	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
+		dev_warn(chip->dev,
+			"tried to request PWM channel %d without output\n",
+			pwm->hwpwm);
+		return -EINVAL;
+	}
+
+	our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
+	if (!our_chan)
+		return -ENOMEM;
+
+	pwm_set_chip_data(pwm, our_chan);
+
+	return 0;
+}
+
+static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	pwm_set_chip_data(pwm, NULL);
+	devm_kfree(chip->dev, pwm_get_chip_data(pwm));
+}
+
+static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_START(tcon_chan);
+	tcon |= TCON_MANUALUPDATE(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_MANUALUPDATE(tcon_chan);
+	tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+
+	return 0;
+}
+
+static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+	tcon &= ~TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+	u32 tin_ns = chan->tin_ns, tcnt, tcmp;
+
+	/*
+	 * We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits.
+	 */
+	if (period_ns > NSEC_PER_SEC)
+		return -ERANGE;
+
+	if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
+		return 0;
+
+	tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
+
+	/* We need tick count for calculation, not last tick. */
+	++tcnt;
+
+	/* Check to see if we are changing the clock rate of the PWM. */
+	if (chan->period_ns != period_ns) {
+		unsigned long tin_rate;
+		u32 period;
+
+		period = NSEC_PER_SEC / period_ns;
+
+		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+						duty_ns, period_ns, period);
+
+		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+
+		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NSEC_PER_SEC / tin_rate;
+		tcnt = period_ns / tin_ns;
+	}
+
+	/* Period is too short. */
+	if (tcnt <= 1)
+		return -ERANGE;
+
+	/* Note that counters count down. */
+	tcmp = duty_ns / tin_ns;
+
+	/* 0% duty is not available */
+	if (!tcmp)
+		++tcmp;
+
+	tcmp = tcnt - tcmp;
+
+	/* Decrement to get tick numbers, instead of tick counts. */
+	--tcnt;
+	/* -1UL will give 100% duty. */
+	--tcmp;
+
+	dev_dbg(our_chip->chip.dev,
+				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+
+	/* Update PWM registers. */
+	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
+	writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		pwm_samsung_enable(chip, pwm);
+
+	chan->period_ns = period_ns;
+	chan->tin_ns = tin_ns;
+	chan->duty_ns = duty_ns;
+
+	return 0;
+}
+
+static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
+				   unsigned int channel, bool invert)
+{
+	unsigned int tcon_chan = to_tcon_channel(channel);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(chip->base + REG_TCON);
+
+	if (invert) {
+		chip->inverter_mask |= BIT(channel);
+		tcon |= TCON_INVERT(tcon_chan);
+	} else {
+		chip->inverter_mask &= ~BIT(channel);
+		tcon &= ~TCON_INVERT(tcon_chan);
+	}
+
+	writel(tcon, chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	bool invert = (polarity == PWM_POLARITY_NORMAL);
+
+	/* Inverted means normal in the hardware. */
+	pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_samsung_ops = {
+	.request	= pwm_samsung_request,
+	.free		= pwm_samsung_free,
+	.enable		= pwm_samsung_enable,
+	.disable	= pwm_samsung_disable,
+	.config		= pwm_samsung_config,
+	.set_polarity	= pwm_samsung_set_polarity,
+	.owner		= THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static const struct samsung_pwm_variant s3c24xx_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= BIT(4),
+};
+
+static const struct samsung_pwm_variant s3c64xx_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
+};
+
+static const struct samsung_pwm_variant s5p64x0_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+};
+
+static const struct samsung_pwm_variant s5p_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(5),
+};
+
+static const struct of_device_id samsung_pwm_matches[] = {
+	{ .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
+	{ .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
+	{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
+	{ .compatible = "samsung,s5pc100-pwm", .data = &s5p_variant },
+	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
+	{},
+};
+
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	struct device_node *np = chip->chip.dev->of_node;
+	const struct of_device_id *match;
+	struct property *prop;
+	const __be32 *cur;
+	u32 val;
+
+	match = of_match_node(samsung_pwm_matches, np);
+	if (!match)
+		return -ENODEV;
+
+	memcpy(&chip->variant, match->data, sizeof(chip->variant));
+
+	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+		if (val >= SAMSUNG_PWM_NUM) {
+			pr_warn("%s: invalid channel index in samsung,pwm-outputs property\n",
+								__func__);
+			continue;
+		}
+		chip->variant.output_mask |= BIT(val);
+	}
+
+	return 0;
+}
+#else
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int pwm_samsung_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct samsung_pwm_chip *chip;
+	struct resource *res;
+	unsigned int chan;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->chip.dev = &pdev->dev;
+	chip->chip.ops = &pwm_samsung_ops;
+	chip->chip.base = -1;
+	chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = pwm_samsung_parse_dt(chip);
+		if (ret)
+			return ret;
+
+		chip->chip.of_xlate = of_pwm_xlate_with_flags;
+		chip->chip.of_pwm_n_cells = 3;
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data specified\n");
+			return -EINVAL;
+		}
+
+		memcpy(&chip->variant, pdev->dev.platform_data,
+							sizeof(chip->variant));
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	if (IS_ERR(chip->base_clk)) {
+		dev_err(dev, "failed to get timer base clk\n");
+		return PTR_ERR(chip->base_clk);
+	}
+
+	ret = clk_prepare_enable(chip->base_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable base clock\n");
+		return ret;
+	}
+
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan, true);
+
+	/* Following clocks are optional. */
+	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
+	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
+
+	platform_set_drvdata(pdev, chip);
+
+	ret = pwmchip_add(&chip->chip);
+	if (ret < 0) {
+		dev_err(dev, "failed to register PWM chip\n");
+		clk_disable_unprepare(chip->base_clk);
+		return ret;
+	}
+
+	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
+		clk_get_rate(chip->base_clk),
+		!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
+		!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
+
+	return 0;
+}
+
+static int pwm_samsung_remove(struct platform_device *pdev)
+{
+	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&chip->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_disable_unprepare(chip->base_clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_samsung_suspend(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/*
+	 * No one preserves these values during suspend so reset them.
+	 * Otherwise driver leaves PWM unconfigured if same values are
+	 * passed to pwm_config() next time.
+	 */
+	for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
+		struct pwm_device *pwm = &chip->chip.pwms[i];
+		struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+
+		if (!chan)
+			continue;
+
+		chan->period_ns = 0;
+		chan->duty_ns = 0;
+	}
+
+	return 0;
+}
+
+static int pwm_samsung_resume(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int chan;
+
+	/*
+	 * Inverter setting must be preserved across suspend/resume
+	 * as nobody really seems to configure it more than once.
+	 */
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan,
+					chip->inverter_mask & BIT(chan));
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_samsung_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
+};
+
+static struct platform_driver pwm_samsung_driver = {
+	.driver		= {
+		.name	= "samsung-pwm",
+		.owner	= THIS_MODULE,
+		.pm	= &pwm_samsung_pm_ops,
+		.of_match_table = of_match_ptr(samsung_pwm_matches),
+	},
+	.probe		= pwm_samsung_probe,
+	.remove		= pwm_samsung_remove,
+};
+module_platform_driver(pwm_samsung_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_ALIAS("platform:samsung-pwm");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 13/20] pwm: Add new pwm-samsung driver
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduces new Samsung PWM driver, which uses Samsung
PWM/timer master driver to control shared parts of the hardware.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile      |   1 +
 drivers/pwm/pwm-samsung.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 607 insertions(+)
 create mode 100644 drivers/pwm/pwm-samsung.c

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index aa94807..86a5771 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
new file mode 100644
index 0000000..b9e5240
--- /dev/null
+++ b/drivers/pwm/pwm-samsung.c
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * PWM driver for Samsung SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+/* For struct samsung_timer_variant and samsung_pwm_lock. */
+#include <clocksource/samsung_pwm.h>
+
+#define REG_TCFG0			0x00
+#define REG_TCFG1			0x04
+#define REG_TCON			0x08
+
+#define REG_TCNTB(tmr)			(0x0c + ((tmr) * 0xc))
+#define REG_TCMPB(tmr)			(0x10 + ((tmr) * 0xc))
+
+#define TCFG0_PRESCALER_MASK		0xff
+#define TCFG0_PRESCALER1_SHIFT		8
+
+#define TCFG1_MUX_MASK			0xf
+#define TCFG1_SHIFT(x)			((x) * 4)
+
+#define TCON_START(chan)		(1 << (4 * (chan) + 0))
+#define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
+#define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
+#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
+						+ (((chan) < 5) ? 3 : 2)))
+
+/**
+ * struct samsung_pwm_channel - private data of PWM channel
+ * @period_ns:	current period in nanoseconds programmed to the hardware
+ * @duty_ns:	current duty time in nanoseconds programmed to the hardware
+ * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
+ */
+struct samsung_pwm_channel {
+	u32 period_ns;
+	u32 duty_ns;
+	u32 tin_ns;
+};
+
+/**
+ * struct samsung_pwm_chip - private data of PWM chip
+ * @chip:		generic PWM chip
+ * @variant:		local copy of hardware variant data
+ * @inverter_mask:	inverter status for all channels - one bit per channel
+ * @base:		base address of mapped PWM registers
+ * @base_clk:		base clock used to drive the timers
+ * @tclk0:		external clock 0 (can be ERR_PTR if not present)
+ * @tclk1:		external clock 1 (can be ERR_PTR if not present)
+ */
+struct samsung_pwm_chip {
+	struct pwm_chip chip;
+	struct samsung_pwm_variant variant;
+	u8 inverter_mask;
+
+	void __iomem *base;
+	struct clk *base_clk;
+	struct clk *tclk0;
+	struct clk *tclk1;
+};
+
+#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
+/*
+ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
+ * and some registers need access synchronization. If both drivers are
+ * compiled in, the spinlock is defined in the clocksource driver,
+ * otherwise following definition is used.
+ *
+ * Currently we do not need any more complex synchronization method
+ * because all the supported SoCs contain only one instance of the PWM
+ * IP. Should this change, both drivers will need to be modified to
+ * properly synchronize accesses to particular instances.
+ */
+static DEFINE_SPINLOCK(samsung_pwm_lock);
+#endif
+
+static inline
+struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct samsung_pwm_chip, chip);
+}
+
+static inline unsigned int to_tcon_channel(unsigned int channel)
+{
+	/* TCON register has a gap of 4 bits (1 channel) */
+	return (channel == 0) ? 0 : (channel + 1);
+}
+
+static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
+				    unsigned int channel, u8 divisor)
+{
+	u8 shift = TCFG1_SHIFT(channel);
+	unsigned long flags;
+	u32 reg;
+	u8 bits;
+
+	bits = (fls(divisor) - 1) - pwm->variant.div_base;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	reg = readl(pwm->base + REG_TCFG1);
+	reg &= ~(TCFG1_MUX_MASK << shift);
+	reg |= bits << shift;
+	writel(reg, pwm->base + REG_TCFG1);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	u32 reg;
+
+	reg = readl(chip->base + REG_TCFG1);
+	reg >>= TCFG1_SHIFT(chan);
+	reg &= TCFG1_MUX_MASK;
+
+	return (BIT(reg) & variant->tclk_mask) == 0;
+}
+
+static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
+					      unsigned int chan)
+{
+	unsigned long rate;
+	u32 reg;
+
+	rate = clk_get_rate(chip->base_clk);
+
+	reg = readl(chip->base + REG_TCFG0);
+	if (chan >= 2)
+		reg >>= TCFG0_PRESCALER1_SHIFT;
+	reg &= TCFG0_PRESCALER_MASK;
+
+	return rate / (reg + 1);
+}
+
+static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
+					  unsigned int chan, unsigned long freq)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	unsigned long rate;
+	struct clk *clk;
+	u8 div;
+
+	if (!pwm_samsung_is_tdiv(chip, chan)) {
+		clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
+		if (!IS_ERR(clk)) {
+			rate = clk_get_rate(clk);
+			if (rate)
+				return rate;
+		}
+
+		dev_warn(chip->chip.dev,
+			"tclk of PWM %d is inoperational, using tdiv\n", chan);
+	}
+
+	rate = pwm_samsung_get_tin_rate(chip, chan);
+	dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
+
+	/*
+	 * Compare minimum PWM frequency that can be achieved with possible
+	 * divider settings and choose the lowest divisor that can generate
+	 * frequencies lower than requested.
+	 */
+	for (div = variant->div_base; div < 4; ++div)
+		if ((rate >> (variant->bits + div)) < freq)
+			break;
+
+	pwm_samsung_set_divisor(chip, chan, BIT(div));
+
+	return rate >> div;
+}
+
+static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *our_chan;
+
+	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
+		dev_warn(chip->dev,
+			"tried to request PWM channel %d without output\n",
+			pwm->hwpwm);
+		return -EINVAL;
+	}
+
+	our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
+	if (!our_chan)
+		return -ENOMEM;
+
+	pwm_set_chip_data(pwm, our_chan);
+
+	return 0;
+}
+
+static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	pwm_set_chip_data(pwm, NULL);
+	devm_kfree(chip->dev, pwm_get_chip_data(pwm));
+}
+
+static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_START(tcon_chan);
+	tcon |= TCON_MANUALUPDATE(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_MANUALUPDATE(tcon_chan);
+	tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+
+	return 0;
+}
+
+static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+	tcon &= ~TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+	u32 tin_ns = chan->tin_ns, tcnt, tcmp;
+
+	/*
+	 * We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits.
+	 */
+	if (period_ns > NSEC_PER_SEC)
+		return -ERANGE;
+
+	if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
+		return 0;
+
+	tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
+
+	/* We need tick count for calculation, not last tick. */
+	++tcnt;
+
+	/* Check to see if we are changing the clock rate of the PWM. */
+	if (chan->period_ns != period_ns) {
+		unsigned long tin_rate;
+		u32 period;
+
+		period = NSEC_PER_SEC / period_ns;
+
+		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+						duty_ns, period_ns, period);
+
+		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+
+		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NSEC_PER_SEC / tin_rate;
+		tcnt = period_ns / tin_ns;
+	}
+
+	/* Period is too short. */
+	if (tcnt <= 1)
+		return -ERANGE;
+
+	/* Note that counters count down. */
+	tcmp = duty_ns / tin_ns;
+
+	/* 0% duty is not available */
+	if (!tcmp)
+		++tcmp;
+
+	tcmp = tcnt - tcmp;
+
+	/* Decrement to get tick numbers, instead of tick counts. */
+	--tcnt;
+	/* -1UL will give 100% duty. */
+	--tcmp;
+
+	dev_dbg(our_chip->chip.dev,
+				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+
+	/* Update PWM registers. */
+	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
+	writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		pwm_samsung_enable(chip, pwm);
+
+	chan->period_ns = period_ns;
+	chan->tin_ns = tin_ns;
+	chan->duty_ns = duty_ns;
+
+	return 0;
+}
+
+static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
+				   unsigned int channel, bool invert)
+{
+	unsigned int tcon_chan = to_tcon_channel(channel);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(chip->base + REG_TCON);
+
+	if (invert) {
+		chip->inverter_mask |= BIT(channel);
+		tcon |= TCON_INVERT(tcon_chan);
+	} else {
+		chip->inverter_mask &= ~BIT(channel);
+		tcon &= ~TCON_INVERT(tcon_chan);
+	}
+
+	writel(tcon, chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	bool invert = (polarity == PWM_POLARITY_NORMAL);
+
+	/* Inverted means normal in the hardware. */
+	pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_samsung_ops = {
+	.request	= pwm_samsung_request,
+	.free		= pwm_samsung_free,
+	.enable		= pwm_samsung_enable,
+	.disable	= pwm_samsung_disable,
+	.config		= pwm_samsung_config,
+	.set_polarity	= pwm_samsung_set_polarity,
+	.owner		= THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static const struct samsung_pwm_variant s3c24xx_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= BIT(4),
+};
+
+static const struct samsung_pwm_variant s3c64xx_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
+};
+
+static const struct samsung_pwm_variant s5p64x0_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+};
+
+static const struct samsung_pwm_variant s5p_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(5),
+};
+
+static const struct of_device_id samsung_pwm_matches[] = {
+	{ .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
+	{ .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
+	{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
+	{ .compatible = "samsung,s5pc100-pwm", .data = &s5p_variant },
+	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
+	{},
+};
+
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	struct device_node *np = chip->chip.dev->of_node;
+	const struct of_device_id *match;
+	struct property *prop;
+	const __be32 *cur;
+	u32 val;
+
+	match = of_match_node(samsung_pwm_matches, np);
+	if (!match)
+		return -ENODEV;
+
+	memcpy(&chip->variant, match->data, sizeof(chip->variant));
+
+	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+		if (val >= SAMSUNG_PWM_NUM) {
+			pr_warn("%s: invalid channel index in samsung,pwm-outputs property\n",
+								__func__);
+			continue;
+		}
+		chip->variant.output_mask |= BIT(val);
+	}
+
+	return 0;
+}
+#else
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int pwm_samsung_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct samsung_pwm_chip *chip;
+	struct resource *res;
+	unsigned int chan;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->chip.dev = &pdev->dev;
+	chip->chip.ops = &pwm_samsung_ops;
+	chip->chip.base = -1;
+	chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = pwm_samsung_parse_dt(chip);
+		if (ret)
+			return ret;
+
+		chip->chip.of_xlate = of_pwm_xlate_with_flags;
+		chip->chip.of_pwm_n_cells = 3;
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data specified\n");
+			return -EINVAL;
+		}
+
+		memcpy(&chip->variant, pdev->dev.platform_data,
+							sizeof(chip->variant));
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	if (IS_ERR(chip->base_clk)) {
+		dev_err(dev, "failed to get timer base clk\n");
+		return PTR_ERR(chip->base_clk);
+	}
+
+	ret = clk_prepare_enable(chip->base_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable base clock\n");
+		return ret;
+	}
+
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan, true);
+
+	/* Following clocks are optional. */
+	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
+	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
+
+	platform_set_drvdata(pdev, chip);
+
+	ret = pwmchip_add(&chip->chip);
+	if (ret < 0) {
+		dev_err(dev, "failed to register PWM chip\n");
+		clk_disable_unprepare(chip->base_clk);
+		return ret;
+	}
+
+	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
+		clk_get_rate(chip->base_clk),
+		!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
+		!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
+
+	return 0;
+}
+
+static int pwm_samsung_remove(struct platform_device *pdev)
+{
+	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&chip->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_disable_unprepare(chip->base_clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_samsung_suspend(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/*
+	 * No one preserves these values during suspend so reset them.
+	 * Otherwise driver leaves PWM unconfigured if same values are
+	 * passed to pwm_config() next time.
+	 */
+	for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
+		struct pwm_device *pwm = &chip->chip.pwms[i];
+		struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+
+		if (!chan)
+			continue;
+
+		chan->period_ns = 0;
+		chan->duty_ns = 0;
+	}
+
+	return 0;
+}
+
+static int pwm_samsung_resume(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int chan;
+
+	/*
+	 * Inverter setting must be preserved across suspend/resume
+	 * as nobody really seems to configure it more than once.
+	 */
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan,
+					chip->inverter_mask & BIT(chan));
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_samsung_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
+};
+
+static struct platform_driver pwm_samsung_driver = {
+	.driver		= {
+		.name	= "samsung-pwm",
+		.owner	= THIS_MODULE,
+		.pm	= &pwm_samsung_pm_ops,
+		.of_match_table = of_match_ptr(samsung_pwm_matches),
+	},
+	.probe		= pwm_samsung_probe,
+	.remove		= pwm_samsung_remove,
+};
+module_platform_driver(pwm_samsung_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_ALIAS("platform:samsung-pwm");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 14/20] ARM: SAMSUNG: Rework private data handling in dev-backlight
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch modifies dev-backlight helpers to get private data using
container_of instead of abusing platform_data field of PWM device.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/dev-backlight.c | 51 ++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index 5f197dc..e467a01 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -20,13 +20,18 @@
 #include <plat/gpio-cfg.h>
 #include <plat/backlight.h>
 
+struct samsung_bl_drvdata {
+	struct platform_pwm_backlight_data plat_data;
+	struct samsung_bl_gpio_info *gpio_info;
+};
+
 static int samsung_bl_init(struct device *dev)
 {
 	int ret = 0;
-	struct platform_device *timer_dev =
-			container_of(dev->parent, struct platform_device, dev);
-	struct samsung_bl_gpio_info *bl_gpio_info =
-			timer_dev->dev.platform_data;
+	struct platform_pwm_backlight_data *pdata = dev->platform_data;
+	struct samsung_bl_drvdata *drvdata = container_of(pdata,
+					struct samsung_bl_drvdata, plat_data);
+	struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
 
 	ret = gpio_request(bl_gpio_info->no, "Backlight");
 	if (ret) {
@@ -42,10 +47,10 @@ static int samsung_bl_init(struct device *dev)
 
 static void samsung_bl_exit(struct device *dev)
 {
-	struct platform_device *timer_dev =
-			container_of(dev->parent, struct platform_device, dev);
-	struct samsung_bl_gpio_info *bl_gpio_info =
-			timer_dev->dev.platform_data;
+	struct platform_pwm_backlight_data *pdata = dev->platform_data;
+	struct samsung_bl_drvdata *drvdata = container_of(pdata,
+					struct samsung_bl_drvdata, plat_data);
+	struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
 
 	s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT);
 	gpio_free(bl_gpio_info->no);
@@ -60,12 +65,14 @@ static void samsung_bl_exit(struct device *dev)
  * for their specific boards
  */
 
-static struct platform_pwm_backlight_data samsung_dfl_bl_data __initdata = {
-	.max_brightness = 255,
-	.dft_brightness = 255,
-	.pwm_period_ns  = 78770,
-	.init           = samsung_bl_init,
-	.exit           = samsung_bl_exit,
+static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = {
+	.plat_data = {
+		.max_brightness = 255,
+		.dft_brightness = 255,
+		.pwm_period_ns  = 78770,
+		.init           = samsung_bl_init,
+		.exit           = samsung_bl_exit,
+	},
 };
 
 static struct platform_device samsung_dfl_bl_device __initdata = {
@@ -82,6 +89,7 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 {
 	int ret = 0;
 	struct platform_device *samsung_bl_device;
+	struct samsung_bl_drvdata *samsung_bl_drvdata;
 	struct platform_pwm_backlight_data *samsung_bl_data;
 
 	samsung_bl_device = kmemdup(&samsung_dfl_bl_device,
@@ -91,17 +99,19 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 		return;
 	}
 
-	samsung_bl_data = s3c_set_platdata(&samsung_dfl_bl_data,
-		sizeof(struct platform_pwm_backlight_data), samsung_bl_device);
-	if (!samsung_bl_data) {
+	samsung_bl_drvdata = kmemdup(&samsung_dfl_bl_data,
+				sizeof(samsung_dfl_bl_data), GFP_KERNEL);
+	if (!samsung_bl_drvdata) {
 		printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
 		goto err_data;
 	}
+	samsung_bl_device->dev.platform_data = &samsung_bl_drvdata->plat_data;
+	samsung_bl_drvdata->gpio_info = gpio_info;
+	samsung_bl_data = &samsung_bl_drvdata->plat_data;
 
 	/* Copy board specific data provided by user */
 	samsung_bl_data->pwm_id = bl_data->pwm_id;
-	samsung_bl_device->dev.parent =
-			&s3c_device_timer[samsung_bl_data->pwm_id].dev;
+	samsung_bl_device->dev.parent = &samsung_device_pwm.dev;
 
 	if (bl_data->max_brightness)
 		samsung_bl_data->max_brightness = bl_data->max_brightness;
@@ -122,9 +132,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 	if (bl_data->check_fb)
 		samsung_bl_data->check_fb = bl_data->check_fb;
 
-	/* Keep the GPIO info for future use */
-	s3c_device_timer[samsung_bl_data->pwm_id].dev.platform_data = gpio_info;
-
 	/* Register the specific PWM timer dev for Backlight control */
 	ret = platform_device_register(
 			&s3c_device_timer[samsung_bl_data->pwm_id]);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 14/20] ARM: SAMSUNG: Rework private data handling in dev-backlight
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies dev-backlight helpers to get private data using
container_of instead of abusing platform_data field of PWM device.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/dev-backlight.c | 51 ++++++++++++++++++++---------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index 5f197dc..e467a01 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -20,13 +20,18 @@
 #include <plat/gpio-cfg.h>
 #include <plat/backlight.h>
 
+struct samsung_bl_drvdata {
+	struct platform_pwm_backlight_data plat_data;
+	struct samsung_bl_gpio_info *gpio_info;
+};
+
 static int samsung_bl_init(struct device *dev)
 {
 	int ret = 0;
-	struct platform_device *timer_dev =
-			container_of(dev->parent, struct platform_device, dev);
-	struct samsung_bl_gpio_info *bl_gpio_info =
-			timer_dev->dev.platform_data;
+	struct platform_pwm_backlight_data *pdata = dev->platform_data;
+	struct samsung_bl_drvdata *drvdata = container_of(pdata,
+					struct samsung_bl_drvdata, plat_data);
+	struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
 
 	ret = gpio_request(bl_gpio_info->no, "Backlight");
 	if (ret) {
@@ -42,10 +47,10 @@ static int samsung_bl_init(struct device *dev)
 
 static void samsung_bl_exit(struct device *dev)
 {
-	struct platform_device *timer_dev =
-			container_of(dev->parent, struct platform_device, dev);
-	struct samsung_bl_gpio_info *bl_gpio_info =
-			timer_dev->dev.platform_data;
+	struct platform_pwm_backlight_data *pdata = dev->platform_data;
+	struct samsung_bl_drvdata *drvdata = container_of(pdata,
+					struct samsung_bl_drvdata, plat_data);
+	struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
 
 	s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT);
 	gpio_free(bl_gpio_info->no);
@@ -60,12 +65,14 @@ static void samsung_bl_exit(struct device *dev)
  * for their specific boards
  */
 
-static struct platform_pwm_backlight_data samsung_dfl_bl_data __initdata = {
-	.max_brightness = 255,
-	.dft_brightness = 255,
-	.pwm_period_ns  = 78770,
-	.init           = samsung_bl_init,
-	.exit           = samsung_bl_exit,
+static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = {
+	.plat_data = {
+		.max_brightness = 255,
+		.dft_brightness = 255,
+		.pwm_period_ns  = 78770,
+		.init           = samsung_bl_init,
+		.exit           = samsung_bl_exit,
+	},
 };
 
 static struct platform_device samsung_dfl_bl_device __initdata = {
@@ -82,6 +89,7 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 {
 	int ret = 0;
 	struct platform_device *samsung_bl_device;
+	struct samsung_bl_drvdata *samsung_bl_drvdata;
 	struct platform_pwm_backlight_data *samsung_bl_data;
 
 	samsung_bl_device = kmemdup(&samsung_dfl_bl_device,
@@ -91,17 +99,19 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 		return;
 	}
 
-	samsung_bl_data = s3c_set_platdata(&samsung_dfl_bl_data,
-		sizeof(struct platform_pwm_backlight_data), samsung_bl_device);
-	if (!samsung_bl_data) {
+	samsung_bl_drvdata = kmemdup(&samsung_dfl_bl_data,
+				sizeof(samsung_dfl_bl_data), GFP_KERNEL);
+	if (!samsung_bl_drvdata) {
 		printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
 		goto err_data;
 	}
+	samsung_bl_device->dev.platform_data = &samsung_bl_drvdata->plat_data;
+	samsung_bl_drvdata->gpio_info = gpio_info;
+	samsung_bl_data = &samsung_bl_drvdata->plat_data;
 
 	/* Copy board specific data provided by user */
 	samsung_bl_data->pwm_id = bl_data->pwm_id;
-	samsung_bl_device->dev.parent =
-			&s3c_device_timer[samsung_bl_data->pwm_id].dev;
+	samsung_bl_device->dev.parent = &samsung_device_pwm.dev;
 
 	if (bl_data->max_brightness)
 		samsung_bl_data->max_brightness = bl_data->max_brightness;
@@ -122,9 +132,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 	if (bl_data->check_fb)
 		samsung_bl_data->check_fb = bl_data->check_fb;
 
-	/* Keep the GPIO info for future use */
-	s3c_device_timer[samsung_bl_data->pwm_id].dev.platform_data = gpio_info;
-
 	/* Register the specific PWM timer dev for Backlight control */
 	ret = platform_device_register(
 			&s3c_device_timer[samsung_bl_data->pwm_id]);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 15/20] ARM: SAMSUNG: Modify board files to use new PWM platform device
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch modifies any board files using the legacy PWM device to use
the new device instead.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c24xx/mach-h1940.c    |  4 ++--
 arch/arm/mach-s3c24xx/mach-rx1950.c   |  5 ++---
 arch/arm/mach-s3c64xx/mach-crag6410.c |  4 ++--
 arch/arm/mach-s3c64xx/mach-hmt.c      |  4 ++--
 arch/arm/mach-s3c64xx/mach-smartq.c   |  4 ++--
 arch/arm/mach-s3c64xx/mach-smdk6410.c |  5 +++--
 arch/arm/mach-s5p64x0/mach-smdk6440.c |  5 +++--
 arch/arm/mach-s5p64x0/mach-smdk6450.c |  5 +++--
 arch/arm/mach-s5pc100/mach-smdkc100.c |  5 +++--
 arch/arm/mach-s5pv210/mach-smdkv210.c |  5 +++--
 arch/arm/plat-samsung/dev-backlight.c | 10 ----------
 11 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index af4334d..74dd479 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -512,7 +512,7 @@ static struct platform_pwm_backlight_data backlight_data = {
 static struct platform_device h1940_backlight = {
 	.name = "pwm-backlight",
 	.dev  = {
-		.parent = &s3c_device_timer[0].dev,
+		.parent = &samsung_device_pwm.dev,
 		.platform_data = &backlight_data,
 	},
 	.id   = -1,
@@ -632,7 +632,7 @@ static struct platform_device *h1940_devices[] __initdata = {
 	&h1940_device_bluetooth,
 	&s3c_device_sdi,
 	&s3c_device_rtc,
-	&s3c_device_timer[0],
+	&samsung_device_pwm,
 	&h1940_backlight,
 	&h1940_lcd_powerdev,
 	&s3c_device_adc,
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 44ca018..206b1f7 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -530,7 +530,7 @@ static struct platform_pwm_backlight_data rx1950_backlight_data = {
 static struct platform_device rx1950_backlight = {
 	.name = "pwm-backlight",
 	.dev = {
-		.parent = &s3c_device_timer[0].dev,
+		.parent = &samsung_device_pwm.dev,
 		.platform_data = &rx1950_backlight_data,
 	},
 };
@@ -717,8 +717,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
 	&s3c_device_sdi,
 	&s3c_device_adc,
 	&s3c_device_ts,
-	&s3c_device_timer[0],
-	&s3c_device_timer[1],
+	&samsung_device_pwm,
 	&rx1950_backlight,
 	&rx1950_device_gpiokeys,
 	&power_supply,
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 8ad88ac..28889cc 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -120,7 +120,7 @@ static struct platform_device crag6410_backlight_device = {
 	.name		= "pwm-backlight",
 	.id		= -1,
 	.dev		= {
-		.parent	= &s3c_device_timer[0].dev,
+		.parent	= &samsung_device_pwm.dev,
 		.platform_data = &crag6410_backlight_data,
 	},
 };
@@ -375,7 +375,7 @@ static struct platform_device *crag6410_devices[] __initdata = {
 	&s3c_device_fb,
 	&s3c_device_ohci,
 	&s3c_device_usb_hsotg,
-	&s3c_device_timer[0],
+	&samsung_device_pwm,
 	&s3c64xx_device_iis0,
 	&s3c64xx_device_iis1,
 	&samsung_device_keypad,
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 5b7f357..f39569e 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -123,7 +123,7 @@ static struct platform_pwm_backlight_data hmt_backlight_data = {
 static struct platform_device hmt_backlight_device = {
 	.name		= "pwm-backlight",
 	.dev		= {
-		.parent	= &s3c_device_timer[1].dev,
+		.parent	= &samsung_device_pwm.dev,
 		.platform_data = &hmt_backlight_data,
 	},
 };
@@ -239,7 +239,7 @@ static struct platform_device *hmt_devices[] __initdata = {
 	&s3c_device_nand,
 	&s3c_device_fb,
 	&s3c_device_ohci,
-	&s3c_device_timer[1],
+	&samsung_device_pwm,
 	&hmt_backlight_device,
 	&hmt_leds_device,
 };
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 58ac990..86d980b 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -157,7 +157,7 @@ static struct platform_pwm_backlight_data smartq_backlight_data = {
 static struct platform_device smartq_backlight_device = {
 	.name		= "pwm-backlight",
 	.dev		= {
-		.parent	= &s3c_device_timer[1].dev,
+		.parent	= &samsung_device_pwm.dev,
 		.platform_data = &smartq_backlight_data,
 	},
 };
@@ -246,7 +246,7 @@ static struct platform_device *smartq_devices[] __initdata = {
 	&s3c_device_i2c0,
 	&s3c_device_ohci,
 	&s3c_device_rtc,
-	&s3c_device_timer[1],
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_usb_hsotg,
 	&s3c64xx_device_iis0,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index bd3295a..d90b450 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -274,6 +274,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
 	&s3c_device_i2c1,
 	&s3c_device_fb,
 	&s3c_device_ohci,
+	&samsung_device_pwm,
 	&s3c_device_usb_hsotg,
 	&s3c64xx_device_iisv4,
 	&samsung_device_keypad,
@@ -691,9 +692,9 @@ static void __init smdk6410_machine_init(void)
 
 	s3c_ide_set_platdata(&smdk6410_ide_pdata);
 
-	samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
-
 	platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+
+	samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
 }
 
 MACHINE_START(SMDK6410, "SMDK6410")
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 73f71a6..0b00304 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -162,6 +162,7 @@ static struct platform_device *smdk6440_devices[] __initdata = {
 	&s3c_device_rtc,
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&s5p6440_device_iis,
@@ -254,8 +255,6 @@ static void __init smdk6440_machine_init(void)
 	i2c_register_board_info(1, smdk6440_i2c_devs1,
 			ARRAY_SIZE(smdk6440_i2c_devs1));
 
-	samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
-
 	s5p6440_set_lcd_interface();
 	s3c_fb_set_platdata(&smdk6440_lcd_pdata);
 
@@ -264,6 +263,8 @@ static void __init smdk6440_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdk6440_hsmmc2_pdata);
 
 	platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
+
+	samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
 }
 
 MACHINE_START(SMDK6440, "SMDK6440")
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 18303e1..5949296 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -180,6 +180,7 @@ static struct platform_device *smdk6450_devices[] __initdata = {
 	&s3c_device_rtc,
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&s5p6450_device_iis0,
@@ -273,8 +274,6 @@ static void __init smdk6450_machine_init(void)
 	i2c_register_board_info(1, smdk6450_i2c_devs1,
 			ARRAY_SIZE(smdk6450_i2c_devs1));
 
-	samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
-
 	s5p6450_set_lcd_interface();
 	s3c_fb_set_platdata(&smdk6450_lcd_pdata);
 
@@ -283,6 +282,8 @@ static void __init smdk6450_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdk6450_hsmmc2_pdata);
 
 	platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
+
+	samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
 }
 
 MACHINE_START(SMDK6450, "SMDK6450")
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 8c880f7..7c57a22 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -194,6 +194,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc1,
 	&s3c_device_hsmmc2,
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&smdkc100_lcd_powerdev,
@@ -246,9 +247,9 @@ static void __init smdkc100_machine_init(void)
 	gpio_request(S5PC100_GPH0(6), "GPH0");
 	smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
 
-	samsung_bl_set(&smdkc100_bl_gpio_info, &smdkc100_bl_data);
-
 	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
+
+	samsung_bl_set(&smdkc100_bl_gpio_info, &smdkc100_bl_data);
 }
 
 MACHINE_START(SMDKC100, "SMDKC100")
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index d50b6f1..6d72bb99 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -218,6 +218,7 @@ static struct platform_device *smdkv210_devices[] __initdata = {
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
 	&s3c_device_i2c2,
+	&samsung_device_pwm,
 	&s3c_device_rtc,
 	&s3c_device_ts,
 	&s3c_device_usb_hsotg,
@@ -316,11 +317,11 @@ static void __init smdkv210_machine_init(void)
 
 	s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
 
-	samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);
-
 	s3c_hsotg_set_platdata(&smdkv210_hsotg_pdata);
 
 	platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
+
+	samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);
 }
 
 MACHINE_START(SMDKV210, "SMDKV210")
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index e467a01..d51f956 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -132,14 +132,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 	if (bl_data->check_fb)
 		samsung_bl_data->check_fb = bl_data->check_fb;
 
-	/* Register the specific PWM timer dev for Backlight control */
-	ret = platform_device_register(
-			&s3c_device_timer[samsung_bl_data->pwm_id]);
-	if (ret) {
-		printk(KERN_ERR "failed to register pwm timer for backlight: %d\n", ret);
-		goto err_plat_reg1;
-	}
-
 	/* Register the Backlight dev */
 	ret = platform_device_register(samsung_bl_device);
 	if (ret) {
@@ -150,8 +142,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 	return;
 
 err_plat_reg2:
-	platform_device_unregister(&s3c_device_timer[samsung_bl_data->pwm_id]);
-err_plat_reg1:
 	kfree(samsung_bl_data);
 err_data:
 	kfree(samsung_bl_device);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 15/20] ARM: SAMSUNG: Modify board files to use new PWM platform device
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies any board files using the legacy PWM device to use
the new device instead.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c24xx/mach-h1940.c    |  4 ++--
 arch/arm/mach-s3c24xx/mach-rx1950.c   |  5 ++---
 arch/arm/mach-s3c64xx/mach-crag6410.c |  4 ++--
 arch/arm/mach-s3c64xx/mach-hmt.c      |  4 ++--
 arch/arm/mach-s3c64xx/mach-smartq.c   |  4 ++--
 arch/arm/mach-s3c64xx/mach-smdk6410.c |  5 +++--
 arch/arm/mach-s5p64x0/mach-smdk6440.c |  5 +++--
 arch/arm/mach-s5p64x0/mach-smdk6450.c |  5 +++--
 arch/arm/mach-s5pc100/mach-smdkc100.c |  5 +++--
 arch/arm/mach-s5pv210/mach-smdkv210.c |  5 +++--
 arch/arm/plat-samsung/dev-backlight.c | 10 ----------
 11 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index af4334d..74dd479 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -512,7 +512,7 @@ static struct platform_pwm_backlight_data backlight_data = {
 static struct platform_device h1940_backlight = {
 	.name = "pwm-backlight",
 	.dev  = {
-		.parent = &s3c_device_timer[0].dev,
+		.parent = &samsung_device_pwm.dev,
 		.platform_data = &backlight_data,
 	},
 	.id   = -1,
@@ -632,7 +632,7 @@ static struct platform_device *h1940_devices[] __initdata = {
 	&h1940_device_bluetooth,
 	&s3c_device_sdi,
 	&s3c_device_rtc,
-	&s3c_device_timer[0],
+	&samsung_device_pwm,
 	&h1940_backlight,
 	&h1940_lcd_powerdev,
 	&s3c_device_adc,
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 44ca018..206b1f7 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -530,7 +530,7 @@ static struct platform_pwm_backlight_data rx1950_backlight_data = {
 static struct platform_device rx1950_backlight = {
 	.name = "pwm-backlight",
 	.dev = {
-		.parent = &s3c_device_timer[0].dev,
+		.parent = &samsung_device_pwm.dev,
 		.platform_data = &rx1950_backlight_data,
 	},
 };
@@ -717,8 +717,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
 	&s3c_device_sdi,
 	&s3c_device_adc,
 	&s3c_device_ts,
-	&s3c_device_timer[0],
-	&s3c_device_timer[1],
+	&samsung_device_pwm,
 	&rx1950_backlight,
 	&rx1950_device_gpiokeys,
 	&power_supply,
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 8ad88ac..28889cc 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -120,7 +120,7 @@ static struct platform_device crag6410_backlight_device = {
 	.name		= "pwm-backlight",
 	.id		= -1,
 	.dev		= {
-		.parent	= &s3c_device_timer[0].dev,
+		.parent	= &samsung_device_pwm.dev,
 		.platform_data = &crag6410_backlight_data,
 	},
 };
@@ -375,7 +375,7 @@ static struct platform_device *crag6410_devices[] __initdata = {
 	&s3c_device_fb,
 	&s3c_device_ohci,
 	&s3c_device_usb_hsotg,
-	&s3c_device_timer[0],
+	&samsung_device_pwm,
 	&s3c64xx_device_iis0,
 	&s3c64xx_device_iis1,
 	&samsung_device_keypad,
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 5b7f357..f39569e 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -123,7 +123,7 @@ static struct platform_pwm_backlight_data hmt_backlight_data = {
 static struct platform_device hmt_backlight_device = {
 	.name		= "pwm-backlight",
 	.dev		= {
-		.parent	= &s3c_device_timer[1].dev,
+		.parent	= &samsung_device_pwm.dev,
 		.platform_data = &hmt_backlight_data,
 	},
 };
@@ -239,7 +239,7 @@ static struct platform_device *hmt_devices[] __initdata = {
 	&s3c_device_nand,
 	&s3c_device_fb,
 	&s3c_device_ohci,
-	&s3c_device_timer[1],
+	&samsung_device_pwm,
 	&hmt_backlight_device,
 	&hmt_leds_device,
 };
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 58ac990..86d980b 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -157,7 +157,7 @@ static struct platform_pwm_backlight_data smartq_backlight_data = {
 static struct platform_device smartq_backlight_device = {
 	.name		= "pwm-backlight",
 	.dev		= {
-		.parent	= &s3c_device_timer[1].dev,
+		.parent	= &samsung_device_pwm.dev,
 		.platform_data = &smartq_backlight_data,
 	},
 };
@@ -246,7 +246,7 @@ static struct platform_device *smartq_devices[] __initdata = {
 	&s3c_device_i2c0,
 	&s3c_device_ohci,
 	&s3c_device_rtc,
-	&s3c_device_timer[1],
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_usb_hsotg,
 	&s3c64xx_device_iis0,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index bd3295a..d90b450 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -274,6 +274,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
 	&s3c_device_i2c1,
 	&s3c_device_fb,
 	&s3c_device_ohci,
+	&samsung_device_pwm,
 	&s3c_device_usb_hsotg,
 	&s3c64xx_device_iisv4,
 	&samsung_device_keypad,
@@ -691,9 +692,9 @@ static void __init smdk6410_machine_init(void)
 
 	s3c_ide_set_platdata(&smdk6410_ide_pdata);
 
-	samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
-
 	platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+
+	samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
 }
 
 MACHINE_START(SMDK6410, "SMDK6410")
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 73f71a6..0b00304 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -162,6 +162,7 @@ static struct platform_device *smdk6440_devices[] __initdata = {
 	&s3c_device_rtc,
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&s5p6440_device_iis,
@@ -254,8 +255,6 @@ static void __init smdk6440_machine_init(void)
 	i2c_register_board_info(1, smdk6440_i2c_devs1,
 			ARRAY_SIZE(smdk6440_i2c_devs1));
 
-	samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
-
 	s5p6440_set_lcd_interface();
 	s3c_fb_set_platdata(&smdk6440_lcd_pdata);
 
@@ -264,6 +263,8 @@ static void __init smdk6440_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdk6440_hsmmc2_pdata);
 
 	platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
+
+	samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
 }
 
 MACHINE_START(SMDK6440, "SMDK6440")
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 18303e1..5949296 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -180,6 +180,7 @@ static struct platform_device *smdk6450_devices[] __initdata = {
 	&s3c_device_rtc,
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&s5p6450_device_iis0,
@@ -273,8 +274,6 @@ static void __init smdk6450_machine_init(void)
 	i2c_register_board_info(1, smdk6450_i2c_devs1,
 			ARRAY_SIZE(smdk6450_i2c_devs1));
 
-	samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
-
 	s5p6450_set_lcd_interface();
 	s3c_fb_set_platdata(&smdk6450_lcd_pdata);
 
@@ -283,6 +282,8 @@ static void __init smdk6450_machine_init(void)
 	s3c_sdhci2_set_platdata(&smdk6450_hsmmc2_pdata);
 
 	platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
+
+	samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
 }
 
 MACHINE_START(SMDK6450, "SMDK6450")
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 8c880f7..7c57a22 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -194,6 +194,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc1,
 	&s3c_device_hsmmc2,
+	&samsung_device_pwm,
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&smdkc100_lcd_powerdev,
@@ -246,9 +247,9 @@ static void __init smdkc100_machine_init(void)
 	gpio_request(S5PC100_GPH0(6), "GPH0");
 	smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
 
-	samsung_bl_set(&smdkc100_bl_gpio_info, &smdkc100_bl_data);
-
 	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
+
+	samsung_bl_set(&smdkc100_bl_gpio_info, &smdkc100_bl_data);
 }
 
 MACHINE_START(SMDKC100, "SMDKC100")
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index d50b6f1..6d72bb99 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -218,6 +218,7 @@ static struct platform_device *smdkv210_devices[] __initdata = {
 	&s3c_device_i2c0,
 	&s3c_device_i2c1,
 	&s3c_device_i2c2,
+	&samsung_device_pwm,
 	&s3c_device_rtc,
 	&s3c_device_ts,
 	&s3c_device_usb_hsotg,
@@ -316,11 +317,11 @@ static void __init smdkv210_machine_init(void)
 
 	s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
 
-	samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);
-
 	s3c_hsotg_set_platdata(&smdkv210_hsotg_pdata);
 
 	platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
+
+	samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);
 }
 
 MACHINE_START(SMDKV210, "SMDKV210")
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index e467a01..d51f956 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -132,14 +132,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 	if (bl_data->check_fb)
 		samsung_bl_data->check_fb = bl_data->check_fb;
 
-	/* Register the specific PWM timer dev for Backlight control */
-	ret = platform_device_register(
-			&s3c_device_timer[samsung_bl_data->pwm_id]);
-	if (ret) {
-		printk(KERN_ERR "failed to register pwm timer for backlight: %d\n", ret);
-		goto err_plat_reg1;
-	}
-
 	/* Register the Backlight dev */
 	ret = platform_device_register(samsung_bl_device);
 	if (ret) {
@@ -150,8 +142,6 @@ void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 	return;
 
 err_plat_reg2:
-	platform_device_unregister(&s3c_device_timer[samsung_bl_data->pwm_id]);
-err_plat_reg1:
 	kfree(samsung_bl_data);
 err_data:
 	kfree(samsung_bl_device);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 16/20] pwm: Remove superseded pwm-samsung-legacy driver
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch removes the now unused pwm-samsung-legacy driver, which was
replaced by new pwm-samsung driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile             |   1 -
 drivers/pwm/pwm-samsung-legacy.c | 353 ---------------------------------------
 2 files changed, 354 deletions(-)
 delete mode 100644 drivers/pwm/pwm-samsung-legacy.c

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 86a5771..77a8c18 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
-obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
diff --git a/drivers/pwm/pwm-samsung-legacy.c b/drivers/pwm/pwm-samsung-legacy.c
deleted file mode 100644
index a0ece50..0000000
--- a/drivers/pwm/pwm-samsung-legacy.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* drivers/pwm/pwm-samsung.c
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C series PWM device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#define pr_fmt(fmt) "pwm-samsung: " fmt
-
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <mach/map.h>
-
-#include <plat/regs-timer.h>
-
-struct s3c_chip {
-	struct platform_device	*pdev;
-
-	struct clk		*clk_div;
-	struct clk		*clk;
-	const char		*label;
-
-	unsigned int		 period_ns;
-	unsigned int		 duty_ns;
-
-	unsigned char		 tcon_base;
-	unsigned char		 pwm_id;
-	struct pwm_chip		 chip;
-};
-
-#define to_s3c_chip(chip)	container_of(chip, struct s3c_chip, chip)
-
-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
-
-static struct clk *clk_scaler[2];
-
-static inline int pwm_is_tdiv(struct s3c_chip *chip)
-{
-	return clk_get_parent(chip->clk) == chip->clk_div;
-}
-
-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
-
-static int s3c_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct s3c_chip *s3c = to_s3c_chip(chip);
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_start(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static void s3c_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct s3c_chip *s3c = to_s3c_chip(chip);
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon &= ~pwm_tcon_start(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-}
-
-static unsigned long pwm_calc_tin(struct s3c_chip *s3c, unsigned long freq)
-{
-	unsigned long tin_parent_rate;
-	unsigned int div;
-
-	tin_parent_rate = clk_get_rate(clk_get_parent(s3c->clk_div));
-	pwm_dbg(s3c, "tin parent at %lu\n", tin_parent_rate);
-
-	for (div = 2; div <= 16; div *= 2) {
-		if ((tin_parent_rate / (div << 16)) < freq)
-			return tin_parent_rate / div;
-	}
-
-	return tin_parent_rate / 16;
-}
-
-#define NS_IN_HZ (1000000000UL)
-
-static int s3c_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-		int duty_ns, int period_ns)
-{
-	struct s3c_chip *s3c = to_s3c_chip(chip);
-	unsigned long tin_rate;
-	unsigned long tin_ns;
-	unsigned long period;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned long tcnt;
-	long tcmp;
-
-	/* We currently avoid using 64bit arithmetic by using the
-	 * fact that anything faster than 1Hz is easily representable
-	 * by 32bits. */
-
-	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
-		return -ERANGE;
-
-	if (period_ns == s3c->period_ns &&
-	    duty_ns == s3c->duty_ns)
-		return 0;
-
-	/* The TCMP and TCNT can be read without a lock, they're not
-	 * shared between the timers. */
-
-	tcmp = __raw_readl(S3C2410_TCMPB(s3c->pwm_id));
-	tcnt = __raw_readl(S3C2410_TCNTB(s3c->pwm_id));
-
-	period = NS_IN_HZ / period_ns;
-
-	pwm_dbg(s3c, "duty_ns=%d, period_ns=%d (%lu)\n",
-		duty_ns, period_ns, period);
-
-	/* Check to see if we are changing the clock rate of the PWM */
-
-	if (s3c->period_ns != period_ns) {
-		if (pwm_is_tdiv(s3c)) {
-			tin_rate = pwm_calc_tin(s3c, period);
-			clk_set_rate(s3c->clk_div, tin_rate);
-		} else
-			tin_rate = clk_get_rate(s3c->clk);
-
-		s3c->period_ns = period_ns;
-
-		pwm_dbg(s3c, "tin_rate=%lu\n", tin_rate);
-
-		tin_ns = NS_IN_HZ / tin_rate;
-		tcnt = period_ns / tin_ns;
-	} else
-		tin_ns = NS_IN_HZ / clk_get_rate(s3c->clk);
-
-	/* Note, counters count down */
-
-	tcmp = duty_ns / tin_ns;
-	tcmp = tcnt - tcmp;
-	/* the pwm hw only checks the compare register after a decrement,
-	   so the pin never toggles if tcmp = tcnt */
-	if (tcmp == tcnt)
-		tcmp--;
-
-	pwm_dbg(s3c, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
-
-	if (tcmp < 0)
-		tcmp = 0;
-
-	/* Update the PWM register block. */
-
-	local_irq_save(flags);
-
-	__raw_writel(tcmp, S3C2410_TCMPB(s3c->pwm_id));
-	__raw_writel(tcnt, S3C2410_TCNTB(s3c->pwm_id));
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_manulupdate(s3c);
-	tcon |= pwm_tcon_autoreload(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	tcon &= ~pwm_tcon_manulupdate(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct pwm_ops s3c_pwm_ops = {
-	.enable = s3c_pwm_enable,
-	.disable = s3c_pwm_disable,
-	.config = s3c_pwm_config,
-	.owner = THIS_MODULE,
-};
-
-static int s3c_pwm_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct s3c_chip *s3c;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned int id = pdev->id;
-	int ret;
-
-	if (id == 4) {
-		dev_err(dev, "TIMER4 is currently not supported\n");
-		return -ENXIO;
-	}
-
-	s3c = devm_kzalloc(&pdev->dev, sizeof(*s3c), GFP_KERNEL);
-	if (s3c == NULL) {
-		dev_err(dev, "failed to allocate pwm_device\n");
-		return -ENOMEM;
-	}
-
-	/* calculate base of control bits in TCON */
-	s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
-	s3c->pwm_id = id;
-	s3c->chip.dev = &pdev->dev;
-	s3c->chip.ops = &s3c_pwm_ops;
-	s3c->chip.base = -1;
-	s3c->chip.npwm = 1;
-
-	s3c->clk = devm_clk_get(dev, "pwm-tin");
-	if (IS_ERR(s3c->clk)) {
-		dev_err(dev, "failed to get pwm tin clk\n");
-		return PTR_ERR(s3c->clk);
-	}
-
-	s3c->clk_div = devm_clk_get(dev, "pwm-tdiv");
-	if (IS_ERR(s3c->clk_div)) {
-		dev_err(dev, "failed to get pwm tdiv clk\n");
-		return PTR_ERR(s3c->clk_div);
-	}
-
-	clk_enable(s3c->clk);
-	clk_enable(s3c->clk_div);
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_invert(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	ret = pwmchip_add(&s3c->chip);
-	if (ret < 0) {
-		dev_err(dev, "failed to register pwm\n");
-		goto err_clk_tdiv;
-	}
-
-	pwm_dbg(s3c, "config bits %02x\n",
-		(__raw_readl(S3C2410_TCON) >> s3c->tcon_base) & 0x0f);
-
-	dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
-		 clk_get_rate(s3c->clk),
-		 clk_get_rate(s3c->clk_div),
-		 pwm_is_tdiv(s3c) ? "div" : "ext", s3c->tcon_base);
-
-	platform_set_drvdata(pdev, s3c);
-	return 0;
-
- err_clk_tdiv:
-	clk_disable(s3c->clk_div);
-	clk_disable(s3c->clk);
-	return ret;
-}
-
-static int s3c_pwm_remove(struct platform_device *pdev)
-{
-	struct s3c_chip *s3c = platform_get_drvdata(pdev);
-	int err;
-
-	err = pwmchip_remove(&s3c->chip);
-	if (err < 0)
-		return err;
-
-	clk_disable(s3c->clk_div);
-	clk_disable(s3c->clk);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int s3c_pwm_suspend(struct device *dev)
-{
-	struct s3c_chip *s3c = dev_get_drvdata(dev);
-
-	/* No one preserve these values during suspend so reset them
-	 * Otherwise driver leaves PWM unconfigured if same values
-	 * passed to pwm_config
-	 */
-	s3c->period_ns = 0;
-	s3c->duty_ns = 0;
-
-	return 0;
-}
-
-static int s3c_pwm_resume(struct device *dev)
-{
-	struct s3c_chip *s3c = dev_get_drvdata(dev);
-	unsigned long tcon;
-
-	/* Restore invertion */
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_invert(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(s3c_pwm_pm_ops, s3c_pwm_suspend,
-			s3c_pwm_resume);
-
-static struct platform_driver s3c_pwm_driver = {
-	.driver		= {
-		.name	= "s3c24xx-pwm",
-		.owner	= THIS_MODULE,
-		.pm	= &s3c_pwm_pm_ops,
-	},
-	.probe		= s3c_pwm_probe,
-	.remove		= s3c_pwm_remove,
-};
-
-static int __init pwm_init(void)
-{
-	int ret;
-
-	clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
-	clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
-
-	if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
-		pr_err("failed to get scaler clocks\n");
-		return -EINVAL;
-	}
-
-	ret = platform_driver_register(&s3c_pwm_driver);
-	if (ret)
-		pr_err("failed to add pwm driver\n");
-
-	return ret;
-}
-
-arch_initcall(pwm_init);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 16/20] pwm: Remove superseded pwm-samsung-legacy driver
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes the now unused pwm-samsung-legacy driver, which was
replaced by new pwm-samsung driver.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile             |   1 -
 drivers/pwm/pwm-samsung-legacy.c | 353 ---------------------------------------
 2 files changed, 354 deletions(-)
 delete mode 100644 drivers/pwm/pwm-samsung-legacy.c

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 86a5771..77a8c18 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
-obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
diff --git a/drivers/pwm/pwm-samsung-legacy.c b/drivers/pwm/pwm-samsung-legacy.c
deleted file mode 100644
index a0ece50..0000000
--- a/drivers/pwm/pwm-samsung-legacy.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/* drivers/pwm/pwm-samsung.c
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C series PWM device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#define pr_fmt(fmt) "pwm-samsung: " fmt
-
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <mach/map.h>
-
-#include <plat/regs-timer.h>
-
-struct s3c_chip {
-	struct platform_device	*pdev;
-
-	struct clk		*clk_div;
-	struct clk		*clk;
-	const char		*label;
-
-	unsigned int		 period_ns;
-	unsigned int		 duty_ns;
-
-	unsigned char		 tcon_base;
-	unsigned char		 pwm_id;
-	struct pwm_chip		 chip;
-};
-
-#define to_s3c_chip(chip)	container_of(chip, struct s3c_chip, chip)
-
-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
-
-static struct clk *clk_scaler[2];
-
-static inline int pwm_is_tdiv(struct s3c_chip *chip)
-{
-	return clk_get_parent(chip->clk) == chip->clk_div;
-}
-
-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
-
-static int s3c_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct s3c_chip *s3c = to_s3c_chip(chip);
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_start(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static void s3c_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct s3c_chip *s3c = to_s3c_chip(chip);
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon &= ~pwm_tcon_start(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-}
-
-static unsigned long pwm_calc_tin(struct s3c_chip *s3c, unsigned long freq)
-{
-	unsigned long tin_parent_rate;
-	unsigned int div;
-
-	tin_parent_rate = clk_get_rate(clk_get_parent(s3c->clk_div));
-	pwm_dbg(s3c, "tin parent at %lu\n", tin_parent_rate);
-
-	for (div = 2; div <= 16; div *= 2) {
-		if ((tin_parent_rate / (div << 16)) < freq)
-			return tin_parent_rate / div;
-	}
-
-	return tin_parent_rate / 16;
-}
-
-#define NS_IN_HZ (1000000000UL)
-
-static int s3c_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-		int duty_ns, int period_ns)
-{
-	struct s3c_chip *s3c = to_s3c_chip(chip);
-	unsigned long tin_rate;
-	unsigned long tin_ns;
-	unsigned long period;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned long tcnt;
-	long tcmp;
-
-	/* We currently avoid using 64bit arithmetic by using the
-	 * fact that anything faster than 1Hz is easily representable
-	 * by 32bits. */
-
-	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
-		return -ERANGE;
-
-	if (period_ns == s3c->period_ns &&
-	    duty_ns == s3c->duty_ns)
-		return 0;
-
-	/* The TCMP and TCNT can be read without a lock, they're not
-	 * shared between the timers. */
-
-	tcmp = __raw_readl(S3C2410_TCMPB(s3c->pwm_id));
-	tcnt = __raw_readl(S3C2410_TCNTB(s3c->pwm_id));
-
-	period = NS_IN_HZ / period_ns;
-
-	pwm_dbg(s3c, "duty_ns=%d, period_ns=%d (%lu)\n",
-		duty_ns, period_ns, period);
-
-	/* Check to see if we are changing the clock rate of the PWM */
-
-	if (s3c->period_ns != period_ns) {
-		if (pwm_is_tdiv(s3c)) {
-			tin_rate = pwm_calc_tin(s3c, period);
-			clk_set_rate(s3c->clk_div, tin_rate);
-		} else
-			tin_rate = clk_get_rate(s3c->clk);
-
-		s3c->period_ns = period_ns;
-
-		pwm_dbg(s3c, "tin_rate=%lu\n", tin_rate);
-
-		tin_ns = NS_IN_HZ / tin_rate;
-		tcnt = period_ns / tin_ns;
-	} else
-		tin_ns = NS_IN_HZ / clk_get_rate(s3c->clk);
-
-	/* Note, counters count down */
-
-	tcmp = duty_ns / tin_ns;
-	tcmp = tcnt - tcmp;
-	/* the pwm hw only checks the compare register after a decrement,
-	   so the pin never toggles if tcmp = tcnt */
-	if (tcmp == tcnt)
-		tcmp--;
-
-	pwm_dbg(s3c, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
-
-	if (tcmp < 0)
-		tcmp = 0;
-
-	/* Update the PWM register block. */
-
-	local_irq_save(flags);
-
-	__raw_writel(tcmp, S3C2410_TCMPB(s3c->pwm_id));
-	__raw_writel(tcnt, S3C2410_TCNTB(s3c->pwm_id));
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_manulupdate(s3c);
-	tcon |= pwm_tcon_autoreload(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	tcon &= ~pwm_tcon_manulupdate(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct pwm_ops s3c_pwm_ops = {
-	.enable = s3c_pwm_enable,
-	.disable = s3c_pwm_disable,
-	.config = s3c_pwm_config,
-	.owner = THIS_MODULE,
-};
-
-static int s3c_pwm_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct s3c_chip *s3c;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned int id = pdev->id;
-	int ret;
-
-	if (id == 4) {
-		dev_err(dev, "TIMER4 is currently not supported\n");
-		return -ENXIO;
-	}
-
-	s3c = devm_kzalloc(&pdev->dev, sizeof(*s3c), GFP_KERNEL);
-	if (s3c == NULL) {
-		dev_err(dev, "failed to allocate pwm_device\n");
-		return -ENOMEM;
-	}
-
-	/* calculate base of control bits in TCON */
-	s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4;
-	s3c->pwm_id = id;
-	s3c->chip.dev = &pdev->dev;
-	s3c->chip.ops = &s3c_pwm_ops;
-	s3c->chip.base = -1;
-	s3c->chip.npwm = 1;
-
-	s3c->clk = devm_clk_get(dev, "pwm-tin");
-	if (IS_ERR(s3c->clk)) {
-		dev_err(dev, "failed to get pwm tin clk\n");
-		return PTR_ERR(s3c->clk);
-	}
-
-	s3c->clk_div = devm_clk_get(dev, "pwm-tdiv");
-	if (IS_ERR(s3c->clk_div)) {
-		dev_err(dev, "failed to get pwm tdiv clk\n");
-		return PTR_ERR(s3c->clk_div);
-	}
-
-	clk_enable(s3c->clk);
-	clk_enable(s3c->clk_div);
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_invert(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	ret = pwmchip_add(&s3c->chip);
-	if (ret < 0) {
-		dev_err(dev, "failed to register pwm\n");
-		goto err_clk_tdiv;
-	}
-
-	pwm_dbg(s3c, "config bits %02x\n",
-		(__raw_readl(S3C2410_TCON) >> s3c->tcon_base) & 0x0f);
-
-	dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
-		 clk_get_rate(s3c->clk),
-		 clk_get_rate(s3c->clk_div),
-		 pwm_is_tdiv(s3c) ? "div" : "ext", s3c->tcon_base);
-
-	platform_set_drvdata(pdev, s3c);
-	return 0;
-
- err_clk_tdiv:
-	clk_disable(s3c->clk_div);
-	clk_disable(s3c->clk);
-	return ret;
-}
-
-static int s3c_pwm_remove(struct platform_device *pdev)
-{
-	struct s3c_chip *s3c = platform_get_drvdata(pdev);
-	int err;
-
-	err = pwmchip_remove(&s3c->chip);
-	if (err < 0)
-		return err;
-
-	clk_disable(s3c->clk_div);
-	clk_disable(s3c->clk);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int s3c_pwm_suspend(struct device *dev)
-{
-	struct s3c_chip *s3c = dev_get_drvdata(dev);
-
-	/* No one preserve these values during suspend so reset them
-	 * Otherwise driver leaves PWM unconfigured if same values
-	 * passed to pwm_config
-	 */
-	s3c->period_ns = 0;
-	s3c->duty_ns = 0;
-
-	return 0;
-}
-
-static int s3c_pwm_resume(struct device *dev)
-{
-	struct s3c_chip *s3c = dev_get_drvdata(dev);
-	unsigned long tcon;
-
-	/* Restore invertion */
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_invert(s3c);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(s3c_pwm_pm_ops, s3c_pwm_suspend,
-			s3c_pwm_resume);
-
-static struct platform_driver s3c_pwm_driver = {
-	.driver		= {
-		.name	= "s3c24xx-pwm",
-		.owner	= THIS_MODULE,
-		.pm	= &s3c_pwm_pm_ops,
-	},
-	.probe		= s3c_pwm_probe,
-	.remove		= s3c_pwm_remove,
-};
-
-static int __init pwm_init(void)
-{
-	int ret;
-
-	clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
-	clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
-
-	if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
-		pr_err("failed to get scaler clocks\n");
-		return -EINVAL;
-	}
-
-	ret = platform_driver_register(&s3c_pwm_driver);
-	if (ret)
-		pr_err("failed to add pwm driver\n");
-
-	return ret;
-}
-
-arch_initcall(pwm_init);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 17/20] ARM: SAMSUNG: Remove old PWM timer platform devices
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch removes old Samsung PWM timer platform devices that are not
used any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/devs.c | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 290f63a..8ce0ac0 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1098,24 +1098,6 @@ arch_initcall(s5p_pmu_init);
 /* PWM Timer */
 
 #ifdef CONFIG_SAMSUNG_DEV_PWM
-
-#define DEFINE_S3C_TIMER(_tmr_no)			\
-	.name		= "s3c24xx-pwm",		\
-	.id		= _tmr_no,			\
-
-/*
- * since we already have an static mapping for the timer,
- * we do not bother setting any IO resource for the base.
- */
-
-struct platform_device s3c_device_timer[] = {
-	[0] = { DEFINE_S3C_TIMER(0) },
-	[1] = { DEFINE_S3C_TIMER(1) },
-	[2] = { DEFINE_S3C_TIMER(2) },
-	[3] = { DEFINE_S3C_TIMER(3) },
-	[4] = { DEFINE_S3C_TIMER(4) },
-};
-
 static struct resource samsung_pwm_resource[] = {
 	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
 };
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 17/20] ARM: SAMSUNG: Remove old PWM timer platform devices
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes old Samsung PWM timer platform devices that are not
used any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/devs.c | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 290f63a..8ce0ac0 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1098,24 +1098,6 @@ arch_initcall(s5p_pmu_init);
 /* PWM Timer */
 
 #ifdef CONFIG_SAMSUNG_DEV_PWM
-
-#define DEFINE_S3C_TIMER(_tmr_no)			\
-	.name		= "s3c24xx-pwm",		\
-	.id		= _tmr_no,			\
-
-/*
- * since we already have an static mapping for the timer,
- * we do not bother setting any IO resource for the base.
- */
-
-struct platform_device s3c_device_timer[] = {
-	[0] = { DEFINE_S3C_TIMER(0) },
-	[1] = { DEFINE_S3C_TIMER(1) },
-	[2] = { DEFINE_S3C_TIMER(2) },
-	[3] = { DEFINE_S3C_TIMER(3) },
-	[4] = { DEFINE_S3C_TIMER(4) },
-};
-
 static struct resource samsung_pwm_resource[] = {
 	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
 };
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 18/20] ARM: SAMSUNG: Remove pwm-clock infrastructure
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

Since all the used PWM prescalers and dividers configuration has been
moved to appropriate drivers, the pwm-clock infrastructure is now
unused and so this patch removes it.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c24xx/clock-s3c2410.c          |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2412.c          |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2416.c          |   2 -
 arch/arm/mach-s3c24xx/clock-s3c2443.c          |   2 -
 arch/arm/mach-s3c64xx/clock.c                  |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6440.c          |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6450.c          |   2 -
 arch/arm/mach-s5pc100/clock.c                  |   2 -
 arch/arm/mach-s5pv210/clock.c                  |   1 -
 arch/arm/plat-samsung/Makefile                 |   1 -
 arch/arm/plat-samsung/include/plat/clock.h     |   4 -
 arch/arm/plat-samsung/include/plat/pwm-clock.h |  81 -----
 arch/arm/plat-samsung/pwm-clock.c              | 474 -------------------------
 13 files changed, 575 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-clock.h
 delete mode 100644 arch/arm/plat-samsung/pwm-clock.c

diff --git a/arch/arm/mach-s3c24xx/clock-s3c2410.c b/arch/arm/mach-s3c24xx/clock-s3c2410.c
index 34fffdf..afa0267 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2410.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2410.c
@@ -246,6 +246,5 @@ int __init s3c2410_baseclk_add(void)
 	       (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
 	       (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
 
-	s3c_pwmclk_init();
 	return 0;
 }
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2412.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c
index 2cc017d..d8f253f 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2412.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2412.c
@@ -757,6 +757,5 @@ int __init s3c2412_baseclk_add(void)
 	}
 
 	clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
-	s3c_pwmclk_init();
 	return 0;
 }
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c
index 036056ce..d421a72 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2416.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c
@@ -168,6 +168,4 @@ void __init s3c2416_init_clocks(int xtal)
 	s3c24xx_register_clock(&hsmmc0_clk);
 	clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
 
-	s3c_pwmclk_init();
-
 }
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c
index 0a53051..76cd31f 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c
@@ -209,6 +209,4 @@ void __init s3c2443_init_clocks(int xtal)
 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 8499415..c1bcc4a 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -1004,6 +1004,4 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
 	for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
 		s3c_register_clksrc(clksrc_cdev[cnt], 1);
 	clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index 35378152..ae34a1d 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -629,6 +629,4 @@ void __init s5p6440_register_clocks(void)
 	clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
 
 	s3c24xx_register_clock(&dummy_apb_pclk);
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index af384dd..0b3ca2e 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -698,6 +698,4 @@ void __init s5p6450_register_clocks(void)
 	clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
 
 	s3c24xx_register_clock(&dummy_apb_pclk);
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index a206dc3..d0dc10e 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -1358,6 +1358,4 @@ void __init s5pc100_register_clocks(void)
 		s3c_disable_clocks(clk_cdev[ptr], 1);
 
 	s3c24xx_register_clock(&dummy_apb_pclk);
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index f051f53..ca46372 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -1362,5 +1362,4 @@ void __init s5pv210_register_clocks(void)
 	for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
 		s3c_disable_clocks(clk_cdev[ptr], 1);
 
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index aafbe56..5d7f839 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -14,7 +14,6 @@ obj-				:=
 obj-y				+= init.o cpu.o
 
 obj-$(CONFIG_SAMSUNG_CLOCK)	+= clock.o
-obj-$(CONFIG_SAMSUNG_CLOCK)	+= pwm-clock.o
 
 obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
 obj-$(CONFIG_S5P_CLOCK)		+= s5p-clock.o
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index a62753d..254c3dd 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -140,10 +140,6 @@ extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
 
 extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
 
-/* Init for pwm clock code */
-
-extern void s3c_pwmclk_init(void);
-
 /* Global watchdog clock used by arch_wtd_reset() callback */
 
 extern struct clk *s3c2410_wdtclk;
diff --git a/arch/arm/plat-samsung/include/plat/pwm-clock.h b/arch/arm/plat-samsung/include/plat/pwm-clock.h
deleted file mode 100644
index bf6a60e..0000000
--- a/arch/arm/plat-samsung/include/plat/pwm-clock.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/pwm-clock.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * SAMSUNG - pwm clock and timer support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_PWM_CLOCK_H
-#define __ASM_PLAT_PWM_CLOCK_H __FILE__
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-	if (soc_is_s3c24xx())
-		return tcfg == S3C2410_TCFG1_MUX_TCLK;
-	else if (soc_is_s3c64xx() || soc_is_s5pc100())
-		return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
-	else if (soc_is_s5p6440() || soc_is_s5p6450())
-		return 0;
-	else
-		return tcfg == S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-	if (soc_is_s3c24xx())
-		return 1 << (tcfg1 + 1);
-	else
-		return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-	if (soc_is_s3c24xx())
-		return 0;
-	else
-		return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-	if (soc_is_s3c24xx())
-		return ilog2(div) - 1;
-	else
-		return ilog2(div);
-}
-#endif /* __ASM_PLAT_PWM_CLOCK_H */
diff --git a/arch/arm/plat-samsung/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c
deleted file mode 100644
index a35ff3b..0000000
--- a/arch/arm/plat-samsung/pwm-clock.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
- *
- * Copyright (c) 2007 Simtec Electronics
- * Copyright (c) 2007, 2008 Ben Dooks
- *	Ben Dooks <ben-linux@fluff.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/log2.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/irq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-timer.h>
-#include <plat/pwm-clock.h>
-
-/* Each of the timers 0 through 5 go through the following
- * clock tree, with the inputs depending on the timers.
- *
- * pclk ---- [ prescaler 0 ] -+---> timer 0
- *			      +---> timer 1
- *
- * pclk ---- [ prescaler 1 ] -+---> timer 2
- *			      +---> timer 3
- *			      \---> timer 4
- *
- * Which are fed into the timers as so:
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 0
- * tclk 0 ------------------------------/
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 1
- * tclk 0 ------------------------------/
- *
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 2
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 3
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8, 16 ] --\
- *				       [mux] -> timer 4
- * tclk 1 ------------------------------/
- *
- * Since the mux and the divider are tied together in the
- * same register space, it is impossible to set the parent
- * and the rate at the same time. To avoid this, we add an
- * intermediate 'prescaled-and-divided' clock to select
- * as the parent for the timer input clock called tdiv.
- *
- * prescaled clk --> pwm-tdiv ---\
- *                             [ mux ] --> timer X
- * tclk -------------------------/
-*/
-
-static struct clk clk_timer_scaler[];
-
-static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
-{
-	unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-	if (clk == &clk_timer_scaler[1]) {
-		tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
-		tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
-	} else {
-		tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
-	}
-
-	return clk_get_rate(clk->parent) / (tcfg0 + 1);
-}
-
-static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
-					       unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long divisor = parent_rate / rate;
-
-	if (divisor > 256)
-		divisor = 256;
-	else if (divisor < 2)
-		divisor = 2;
-
-	return parent_rate / divisor;
-}
-
-static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
-	unsigned long tcfg0;
-	unsigned long divisor;
-	unsigned long flags;
-
-	divisor = clk_get_rate(clk->parent) / round;
-	divisor--;
-
-	local_irq_save(flags);
-	tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-	if (clk == &clk_timer_scaler[1]) {
-		tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
-		tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
-	} else {
-		tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
-		tcfg0 |= divisor;
-	}
-
-	__raw_writel(tcfg0, S3C2410_TCFG0);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct clk_ops clk_pwm_scaler_ops = {
-	.get_rate	= clk_pwm_scaler_get_rate,
-	.set_rate	= clk_pwm_scaler_set_rate,
-	.round_rate	= clk_pwm_scaler_round_rate,
-};
-
-static struct clk clk_timer_scaler[] = {
-	[0]	= {
-		.name		= "pwm-scaler0",
-		.id		= -1,
-		.ops		= &clk_pwm_scaler_ops,
-	},
-	[1]	= {
-		.name		= "pwm-scaler1",
-		.id		= -1,
-		.ops		= &clk_pwm_scaler_ops,
-	},
-};
-
-static struct clk clk_timer_tclk[] = {
-	[0]	= {
-		.name		= "pwm-tclk0",
-		.id		= -1,
-	},
-	[1]	= {
-		.name		= "pwm-tclk1",
-		.id		= -1,
-	},
-};
-
-struct pwm_tdiv_clk {
-	struct clk	clk;
-	unsigned int	divisor;
-};
-
-static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
-{
-	return container_of(clk, struct pwm_tdiv_clk, clk);
-}
-
-static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned int divisor;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	if (pwm_cfg_src_is_tclk(tcfg1))
-		divisor = to_tdiv(clk)->divisor;
-	else
-		divisor = tcfg_to_divisor(tcfg1);
-
-	return clk_get_rate(clk->parent) / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
-					     unsigned long rate)
-{
-	unsigned long parent_rate;
-	unsigned long divisor;
-
-	parent_rate = clk_get_rate(clk->parent);
-	divisor = parent_rate / rate;
-
-	if (divisor <= 1 && pwm_tdiv_has_div1())
-		divisor = 1;
-	else if (divisor <= 2)
-		divisor = 2;
-	else if (divisor <= 4)
-		divisor = 4;
-	else if (divisor <= 8)
-		divisor = 8;
-	else
-		divisor = 16;
-
-	return parent_rate / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
-{
-	return pwm_tdiv_div_bits(divclk->divisor);
-}
-
-static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned long bits = clk_pwm_tdiv_bits(divclk);
-	unsigned long flags;
-	unsigned long shift =  S3C2410_TCFG1_SHIFT(divclk->clk.id);
-
-	local_irq_save(flags);
-
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
-	tcfg1 |= bits << shift;
-	__raw_writel(tcfg1, S3C2410_TCFG1);
-
-	local_irq_restore(flags);
-}
-
-static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct pwm_tdiv_clk *divclk = to_tdiv(clk);
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long divisor;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	rate = clk_round_rate(clk, rate);
-	divisor = parent_rate / rate;
-
-	if (divisor > 16)
-		return -EINVAL;
-
-	divclk->divisor = divisor;
-
-	/* Update the current MUX settings if we are currently
-	 * selected as the clock source for this clock. */
-
-	if (!pwm_cfg_src_is_tclk(tcfg1))
-		clk_pwm_tdiv_update(divclk);
-
-	return 0;
-}
-
-static struct clk_ops clk_tdiv_ops = {
-	.get_rate	= clk_pwm_tdiv_get_rate,
-	.set_rate	= clk_pwm_tdiv_set_rate,
-	.round_rate	= clk_pwm_tdiv_round_rate,
-};
-
-static struct pwm_tdiv_clk clk_timer_tdiv[] = {
-	[0]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.0",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[0],
-		},
-	},
-	[1]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.1",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[0],
-		}
-	},
-	[2]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.2",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[1],
-		},
-	},
-	[3]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.3",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[1],
-		},
-	},
-	[4]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.4",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[1],
-		},
-	},
-};
-
-static int __init clk_pwm_tdiv_register(unsigned int id)
-{
-	struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	divclk->clk.id = id;
-	divclk->divisor = tcfg_to_divisor(tcfg1);
-
-	return s3c24xx_register_clock(&divclk->clk);
-}
-
-static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
-{
-	return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
-}
-
-static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
-{
-	return &clk_timer_tdiv[id].clk;
-}
-
-static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
-{
-	unsigned int id = clk->id;
-	unsigned long tcfg1;
-	unsigned long flags;
-	unsigned long bits;
-	unsigned long shift = S3C2410_TCFG1_SHIFT(id);
-
-	unsigned long mux_tclk;
-
-	if (soc_is_s3c24xx())
-		mux_tclk = S3C2410_TCFG1_MUX_TCLK;
-	else if (soc_is_s5p6440() || soc_is_s5p6450())
-		mux_tclk = 0;
-	else
-		mux_tclk = S3C64XX_TCFG1_MUX_TCLK;
-
-	if (parent == s3c24xx_pwmclk_tclk(id))
-		bits = mux_tclk << shift;
-	else if (parent == s3c24xx_pwmclk_tdiv(id))
-		bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	local_irq_save(flags);
-
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
-	__raw_writel(tcfg1 | bits, S3C2410_TCFG1);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct clk_ops clk_tin_ops = {
-	.set_parent	= clk_pwm_tin_set_parent,
-};
-
-static struct clk clk_tin[] = {
-	[0]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.0",
-		.id	= 0,
-		.ops	= &clk_tin_ops,
-	},
-	[1]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.1",
-		.id	= 1,
-		.ops	= &clk_tin_ops,
-	},
-	[2]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.2",
-		.id	= 2,
-		.ops	= &clk_tin_ops,
-	},
-	[3]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.3",
-		.id	= 3,
-		.ops	= &clk_tin_ops,
-	},
-	[4]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.4",
-		.id	= 4,
-		.ops	= &clk_tin_ops,
-	},
-};
-
-static __init int clk_pwm_tin_register(struct clk *pwm)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned int id = pwm->id;
-
-	struct clk *parent;
-	int ret;
-
-	ret = s3c24xx_register_clock(pwm);
-	if (ret < 0)
-		return ret;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	if (pwm_cfg_src_is_tclk(tcfg1))
-		parent = s3c24xx_pwmclk_tclk(id);
-	else
-		parent = s3c24xx_pwmclk_tdiv(id);
-
-	return clk_set_parent(pwm, parent);
-}
-
-/**
- * s3c_pwmclk_init() - initialise pwm clocks
- *
- * Initialise and register the clocks which provide the inputs for the
- * pwm timer blocks.
- *
- * Note, this call is required by the time core, so must be called after
- * the base clocks are added and before any of the initcalls are run.
- */
-__init void s3c_pwmclk_init(void)
-{
-	struct clk *clk_timers;
-	unsigned int clk;
-	int ret;
-
-	clk_timers = clk_get(NULL, "timers");
-	if (IS_ERR(clk_timers)) {
-		printk(KERN_ERR "%s: no parent clock\n", __func__);
-		return;
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++)
-		clk_timer_scaler[clk].parent = clk_timers;
-
-	s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler));
-	s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk));
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
-		ret = clk_pwm_tdiv_register(clk);
-
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
-			return;
-		}
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
-		ret = clk_pwm_tin_register(&clk_tin[clk]);
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
-			return;
-		}
-	}
-}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 18/20] ARM: SAMSUNG: Remove pwm-clock infrastructure
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

Since all the used PWM prescalers and dividers configuration has been
moved to appropriate drivers, the pwm-clock infrastructure is now
unused and so this patch removes it.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c24xx/clock-s3c2410.c          |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2412.c          |   1 -
 arch/arm/mach-s3c24xx/clock-s3c2416.c          |   2 -
 arch/arm/mach-s3c24xx/clock-s3c2443.c          |   2 -
 arch/arm/mach-s3c64xx/clock.c                  |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6440.c          |   2 -
 arch/arm/mach-s5p64x0/clock-s5p6450.c          |   2 -
 arch/arm/mach-s5pc100/clock.c                  |   2 -
 arch/arm/mach-s5pv210/clock.c                  |   1 -
 arch/arm/plat-samsung/Makefile                 |   1 -
 arch/arm/plat-samsung/include/plat/clock.h     |   4 -
 arch/arm/plat-samsung/include/plat/pwm-clock.h |  81 -----
 arch/arm/plat-samsung/pwm-clock.c              | 474 -------------------------
 13 files changed, 575 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-clock.h
 delete mode 100644 arch/arm/plat-samsung/pwm-clock.c

diff --git a/arch/arm/mach-s3c24xx/clock-s3c2410.c b/arch/arm/mach-s3c24xx/clock-s3c2410.c
index 34fffdf..afa0267 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2410.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2410.c
@@ -246,6 +246,5 @@ int __init s3c2410_baseclk_add(void)
 	       (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
 	       (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
 
-	s3c_pwmclk_init();
 	return 0;
 }
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2412.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c
index 2cc017d..d8f253f 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2412.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2412.c
@@ -757,6 +757,5 @@ int __init s3c2412_baseclk_add(void)
 	}
 
 	clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
-	s3c_pwmclk_init();
 	return 0;
 }
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c
index 036056ce..d421a72 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2416.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c
@@ -168,6 +168,4 @@ void __init s3c2416_init_clocks(int xtal)
 	s3c24xx_register_clock(&hsmmc0_clk);
 	clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
 
-	s3c_pwmclk_init();
-
 }
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c
index 0a53051..76cd31f 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c
@@ -209,6 +209,4 @@ void __init s3c2443_init_clocks(int xtal)
 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 	clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 8499415..c1bcc4a 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -1004,6 +1004,4 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
 	for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
 		s3c_register_clksrc(clksrc_cdev[cnt], 1);
 	clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index 35378152..ae34a1d 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -629,6 +629,4 @@ void __init s5p6440_register_clocks(void)
 	clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
 
 	s3c24xx_register_clock(&dummy_apb_pclk);
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index af384dd..0b3ca2e 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -698,6 +698,4 @@ void __init s5p6450_register_clocks(void)
 	clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
 
 	s3c24xx_register_clock(&dummy_apb_pclk);
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index a206dc3..d0dc10e 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -1358,6 +1358,4 @@ void __init s5pc100_register_clocks(void)
 		s3c_disable_clocks(clk_cdev[ptr], 1);
 
 	s3c24xx_register_clock(&dummy_apb_pclk);
-
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index f051f53..ca46372 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -1362,5 +1362,4 @@ void __init s5pv210_register_clocks(void)
 	for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
 		s3c_disable_clocks(clk_cdev[ptr], 1);
 
-	s3c_pwmclk_init();
 }
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index aafbe56..5d7f839 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -14,7 +14,6 @@ obj-				:=
 obj-y				+= init.o cpu.o
 
 obj-$(CONFIG_SAMSUNG_CLOCK)	+= clock.o
-obj-$(CONFIG_SAMSUNG_CLOCK)	+= pwm-clock.o
 
 obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
 obj-$(CONFIG_S5P_CLOCK)		+= s5p-clock.o
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index a62753d..254c3dd 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -140,10 +140,6 @@ extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
 
 extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
 
-/* Init for pwm clock code */
-
-extern void s3c_pwmclk_init(void);
-
 /* Global watchdog clock used by arch_wtd_reset() callback */
 
 extern struct clk *s3c2410_wdtclk;
diff --git a/arch/arm/plat-samsung/include/plat/pwm-clock.h b/arch/arm/plat-samsung/include/plat/pwm-clock.h
deleted file mode 100644
index bf6a60e..0000000
--- a/arch/arm/plat-samsung/include/plat/pwm-clock.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/pwm-clock.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * SAMSUNG - pwm clock and timer support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_PWM_CLOCK_H
-#define __ASM_PLAT_PWM_CLOCK_H __FILE__
-
-/**
- * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @tcfg: The timer TCFG1 register bits shifted down to 0.
- *
- * Return true if the given configuration from TCFG1 is a TCLK instead
- * any of the TDIV clocks.
- */
-static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
-{
-	if (soc_is_s3c24xx())
-		return tcfg == S3C2410_TCFG1_MUX_TCLK;
-	else if (soc_is_s3c64xx() || soc_is_s5pc100())
-		return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
-	else if (soc_is_s5p6440() || soc_is_s5p6450())
-		return 0;
-	else
-		return tcfg == S3C64XX_TCFG1_MUX_TCLK;
-}
-
-/**
- * tcfg_to_divisor() - convert tcfg1 setting to a divisor
- * @tcfg1: The tcfg1 setting, shifted down.
- *
- * Get the divisor value for the given tcfg1 setting. We assume the
- * caller has already checked to see if this is not a TCLK source.
- */
-static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
-{
-	if (soc_is_s3c24xx())
-		return 1 << (tcfg1 + 1);
-	else
-		return 1 << tcfg1;
-}
-
-/**
- * pwm_tdiv_has_div1() - does the tdiv setting have a /1
- *
- * Return true if we have a /1 in the tdiv setting.
- */
-static inline unsigned int pwm_tdiv_has_div1(void)
-{
-	if (soc_is_s3c24xx())
-		return 0;
-	else
-		return 1;
-}
-
-/**
- * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
- * @div: The divisor to calculate the bit information for.
- *
- * Turn a divisor into the necessary bit field for TCFG1.
- */
-static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
-{
-	if (soc_is_s3c24xx())
-		return ilog2(div) - 1;
-	else
-		return ilog2(div);
-}
-#endif /* __ASM_PLAT_PWM_CLOCK_H */
diff --git a/arch/arm/plat-samsung/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c
deleted file mode 100644
index a35ff3b..0000000
--- a/arch/arm/plat-samsung/pwm-clock.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
- *
- * Copyright (c) 2007 Simtec Electronics
- * Copyright (c) 2007, 2008 Ben Dooks
- *	Ben Dooks <ben-linux@fluff.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/log2.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <asm/irq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-#include <plat/regs-timer.h>
-#include <plat/pwm-clock.h>
-
-/* Each of the timers 0 through 5 go through the following
- * clock tree, with the inputs depending on the timers.
- *
- * pclk ---- [ prescaler 0 ] -+---> timer 0
- *			      +---> timer 1
- *
- * pclk ---- [ prescaler 1 ] -+---> timer 2
- *			      +---> timer 3
- *			      \---> timer 4
- *
- * Which are fed into the timers as so:
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 0
- * tclk 0 ------------------------------/
- *
- * prescaled 0 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 1
- * tclk 0 ------------------------------/
- *
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 2
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8,16 ] ---\
- *				       [mux] -> timer 3
- * tclk 1 ------------------------------/
- *
- * prescaled 1 ---- [ div 2,4,8, 16 ] --\
- *				       [mux] -> timer 4
- * tclk 1 ------------------------------/
- *
- * Since the mux and the divider are tied together in the
- * same register space, it is impossible to set the parent
- * and the rate at the same time. To avoid this, we add an
- * intermediate 'prescaled-and-divided' clock to select
- * as the parent for the timer input clock called tdiv.
- *
- * prescaled clk --> pwm-tdiv ---\
- *                             [ mux ] --> timer X
- * tclk -------------------------/
-*/
-
-static struct clk clk_timer_scaler[];
-
-static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
-{
-	unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-	if (clk == &clk_timer_scaler[1]) {
-		tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
-		tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
-	} else {
-		tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
-	}
-
-	return clk_get_rate(clk->parent) / (tcfg0 + 1);
-}
-
-static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
-					       unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long divisor = parent_rate / rate;
-
-	if (divisor > 256)
-		divisor = 256;
-	else if (divisor < 2)
-		divisor = 2;
-
-	return parent_rate / divisor;
-}
-
-static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
-	unsigned long tcfg0;
-	unsigned long divisor;
-	unsigned long flags;
-
-	divisor = clk_get_rate(clk->parent) / round;
-	divisor--;
-
-	local_irq_save(flags);
-	tcfg0 = __raw_readl(S3C2410_TCFG0);
-
-	if (clk == &clk_timer_scaler[1]) {
-		tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
-		tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
-	} else {
-		tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
-		tcfg0 |= divisor;
-	}
-
-	__raw_writel(tcfg0, S3C2410_TCFG0);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct clk_ops clk_pwm_scaler_ops = {
-	.get_rate	= clk_pwm_scaler_get_rate,
-	.set_rate	= clk_pwm_scaler_set_rate,
-	.round_rate	= clk_pwm_scaler_round_rate,
-};
-
-static struct clk clk_timer_scaler[] = {
-	[0]	= {
-		.name		= "pwm-scaler0",
-		.id		= -1,
-		.ops		= &clk_pwm_scaler_ops,
-	},
-	[1]	= {
-		.name		= "pwm-scaler1",
-		.id		= -1,
-		.ops		= &clk_pwm_scaler_ops,
-	},
-};
-
-static struct clk clk_timer_tclk[] = {
-	[0]	= {
-		.name		= "pwm-tclk0",
-		.id		= -1,
-	},
-	[1]	= {
-		.name		= "pwm-tclk1",
-		.id		= -1,
-	},
-};
-
-struct pwm_tdiv_clk {
-	struct clk	clk;
-	unsigned int	divisor;
-};
-
-static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
-{
-	return container_of(clk, struct pwm_tdiv_clk, clk);
-}
-
-static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned int divisor;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	if (pwm_cfg_src_is_tclk(tcfg1))
-		divisor = to_tdiv(clk)->divisor;
-	else
-		divisor = tcfg_to_divisor(tcfg1);
-
-	return clk_get_rate(clk->parent) / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
-					     unsigned long rate)
-{
-	unsigned long parent_rate;
-	unsigned long divisor;
-
-	parent_rate = clk_get_rate(clk->parent);
-	divisor = parent_rate / rate;
-
-	if (divisor <= 1 && pwm_tdiv_has_div1())
-		divisor = 1;
-	else if (divisor <= 2)
-		divisor = 2;
-	else if (divisor <= 4)
-		divisor = 4;
-	else if (divisor <= 8)
-		divisor = 8;
-	else
-		divisor = 16;
-
-	return parent_rate / divisor;
-}
-
-static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
-{
-	return pwm_tdiv_div_bits(divclk->divisor);
-}
-
-static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned long bits = clk_pwm_tdiv_bits(divclk);
-	unsigned long flags;
-	unsigned long shift =  S3C2410_TCFG1_SHIFT(divclk->clk.id);
-
-	local_irq_save(flags);
-
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
-	tcfg1 |= bits << shift;
-	__raw_writel(tcfg1, S3C2410_TCFG1);
-
-	local_irq_restore(flags);
-}
-
-static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct pwm_tdiv_clk *divclk = to_tdiv(clk);
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long divisor;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	rate = clk_round_rate(clk, rate);
-	divisor = parent_rate / rate;
-
-	if (divisor > 16)
-		return -EINVAL;
-
-	divclk->divisor = divisor;
-
-	/* Update the current MUX settings if we are currently
-	 * selected as the clock source for this clock. */
-
-	if (!pwm_cfg_src_is_tclk(tcfg1))
-		clk_pwm_tdiv_update(divclk);
-
-	return 0;
-}
-
-static struct clk_ops clk_tdiv_ops = {
-	.get_rate	= clk_pwm_tdiv_get_rate,
-	.set_rate	= clk_pwm_tdiv_set_rate,
-	.round_rate	= clk_pwm_tdiv_round_rate,
-};
-
-static struct pwm_tdiv_clk clk_timer_tdiv[] = {
-	[0]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.0",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[0],
-		},
-	},
-	[1]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.1",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[0],
-		}
-	},
-	[2]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.2",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[1],
-		},
-	},
-	[3]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.3",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[1],
-		},
-	},
-	[4]	= {
-		.clk	= {
-			.name	= "pwm-tdiv",
-			.devname	= "s3c24xx-pwm.4",
-			.ops	= &clk_tdiv_ops,
-			.parent	= &clk_timer_scaler[1],
-		},
-	},
-};
-
-static int __init clk_pwm_tdiv_register(unsigned int id)
-{
-	struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	divclk->clk.id = id;
-	divclk->divisor = tcfg_to_divisor(tcfg1);
-
-	return s3c24xx_register_clock(&divclk->clk);
-}
-
-static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
-{
-	return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
-}
-
-static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
-{
-	return &clk_timer_tdiv[id].clk;
-}
-
-static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
-{
-	unsigned int id = clk->id;
-	unsigned long tcfg1;
-	unsigned long flags;
-	unsigned long bits;
-	unsigned long shift = S3C2410_TCFG1_SHIFT(id);
-
-	unsigned long mux_tclk;
-
-	if (soc_is_s3c24xx())
-		mux_tclk = S3C2410_TCFG1_MUX_TCLK;
-	else if (soc_is_s5p6440() || soc_is_s5p6450())
-		mux_tclk = 0;
-	else
-		mux_tclk = S3C64XX_TCFG1_MUX_TCLK;
-
-	if (parent == s3c24xx_pwmclk_tclk(id))
-		bits = mux_tclk << shift;
-	else if (parent == s3c24xx_pwmclk_tdiv(id))
-		bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	local_irq_save(flags);
-
-	tcfg1 = __raw_readl(S3C2410_TCFG1);
-	tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
-	__raw_writel(tcfg1 | bits, S3C2410_TCFG1);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static struct clk_ops clk_tin_ops = {
-	.set_parent	= clk_pwm_tin_set_parent,
-};
-
-static struct clk clk_tin[] = {
-	[0]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.0",
-		.id	= 0,
-		.ops	= &clk_tin_ops,
-	},
-	[1]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.1",
-		.id	= 1,
-		.ops	= &clk_tin_ops,
-	},
-	[2]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.2",
-		.id	= 2,
-		.ops	= &clk_tin_ops,
-	},
-	[3]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.3",
-		.id	= 3,
-		.ops	= &clk_tin_ops,
-	},
-	[4]	= {
-		.name	= "pwm-tin",
-		.devname	= "s3c24xx-pwm.4",
-		.id	= 4,
-		.ops	= &clk_tin_ops,
-	},
-};
-
-static __init int clk_pwm_tin_register(struct clk *pwm)
-{
-	unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
-	unsigned int id = pwm->id;
-
-	struct clk *parent;
-	int ret;
-
-	ret = s3c24xx_register_clock(pwm);
-	if (ret < 0)
-		return ret;
-
-	tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
-	tcfg1 &= S3C2410_TCFG1_MUX_MASK;
-
-	if (pwm_cfg_src_is_tclk(tcfg1))
-		parent = s3c24xx_pwmclk_tclk(id);
-	else
-		parent = s3c24xx_pwmclk_tdiv(id);
-
-	return clk_set_parent(pwm, parent);
-}
-
-/**
- * s3c_pwmclk_init() - initialise pwm clocks
- *
- * Initialise and register the clocks which provide the inputs for the
- * pwm timer blocks.
- *
- * Note, this call is required by the time core, so must be called after
- * the base clocks are added and before any of the initcalls are run.
- */
-__init void s3c_pwmclk_init(void)
-{
-	struct clk *clk_timers;
-	unsigned int clk;
-	int ret;
-
-	clk_timers = clk_get(NULL, "timers");
-	if (IS_ERR(clk_timers)) {
-		printk(KERN_ERR "%s: no parent clock\n", __func__);
-		return;
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++)
-		clk_timer_scaler[clk].parent = clk_timers;
-
-	s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler));
-	s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk));
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
-		ret = clk_pwm_tdiv_register(clk);
-
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
-			return;
-		}
-	}
-
-	for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
-		ret = clk_pwm_tin_register(&clk_tin[clk]);
-		if (ret < 0) {
-			printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
-			return;
-		}
-	}
-}
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 19/20] ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

This patch removes remaining inclusions of plat/regs-timer.h as
a preparation to remove the header.

As a part of this, things like save and restore of PWM registers are
removed from SoC-specific code, because it is handled in appropriate
drivers now.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/irq-pm.c  |  2 --
 arch/arm/mach-s5p64x0/pm.c      |  3 ---
 arch/arm/mach-s5pv210/pm.c      | 10 ----------
 arch/arm/plat-samsung/s5p-irq.c |  1 -
 4 files changed, 16 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
index 0c7e1d9..c3da1b6 100644
--- a/arch/arm/mach-s3c64xx/irq-pm.c
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -22,7 +22,6 @@
 #include <mach/map.h>
 
 #include <plat/regs-serial.h>
-#include <plat/regs-timer.h>
 #include <mach/regs-gpio.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
@@ -43,7 +42,6 @@ static struct sleep_save irq_save[] = {
 	SAVE_ITEM(S3C64XX_EINT0FLTCON2),
 	SAVE_ITEM(S3C64XX_EINT0FLTCON3),
 	SAVE_ITEM(S3C64XX_EINT0MASK),
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
 };
 
 static struct irq_grp_save {
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
index 97c2a08a..861e15c 100644
--- a/arch/arm/mach-s5p64x0/pm.c
+++ b/arch/arm/mach-s5p64x0/pm.c
@@ -18,7 +18,6 @@
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/regs-timer.h>
 #include <plat/wakeup-mask.h>
 
 #include <mach/regs-clock.h>
@@ -48,8 +47,6 @@ static struct sleep_save s5p64x0_misc_save[] = {
 	SAVE_ITEM(S5P64X0_MEM0CONSLP1),
 	SAVE_ITEM(S5P64X0_MEM0DRVCON),
 	SAVE_ITEM(S5P64X0_MEM1DRVCON),
-
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
 };
 
 /* DPLL is present only in S5P6450 */
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
index 2b68a67..3cf3f9c 100644
--- a/arch/arm/mach-s5pv210/pm.c
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -21,7 +21,6 @@
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/regs-timer.h>
 
 #include <mach/regs-irq.h>
 #include <mach/regs-clock.h>
@@ -77,15 +76,6 @@ static struct sleep_save s5pv210_core_save[] = {
 	/* Clock ETC */
 	SAVE_ITEM(S5P_CLK_OUT),
 	SAVE_ITEM(S5P_MDNIE_SEL),
-
-	/* PWM Register */
-	SAVE_ITEM(S3C2410_TCFG0),
-	SAVE_ITEM(S3C2410_TCFG1),
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
-	SAVE_ITEM(S3C2410_TCON),
-	SAVE_ITEM(S3C2410_TCNTB(0)),
-	SAVE_ITEM(S3C2410_TCMPB(0)),
-	SAVE_ITEM(S3C2410_TCNTO(0)),
 };
 
 static int s5pv210_cpu_suspend(unsigned long arg)
diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
index 6729cb2..ddfaca9 100644
--- a/arch/arm/plat-samsung/s5p-irq.c
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -17,7 +17,6 @@
 
 #include <mach/irqs.h>
 #include <mach/map.h>
-#include <plat/regs-timer.h>
 #include <plat/cpu.h>
 
 void __init s5p_init_irq(u32 *vic, u32 num_vic)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 19/20] ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes remaining inclusions of plat/regs-timer.h as
a preparation to remove the header.

As a part of this, things like save and restore of PWM registers are
removed from SoC-specific code, because it is handled in appropriate
drivers now.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/mach-s3c64xx/irq-pm.c  |  2 --
 arch/arm/mach-s5p64x0/pm.c      |  3 ---
 arch/arm/mach-s5pv210/pm.c      | 10 ----------
 arch/arm/plat-samsung/s5p-irq.c |  1 -
 4 files changed, 16 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
index 0c7e1d9..c3da1b6 100644
--- a/arch/arm/mach-s3c64xx/irq-pm.c
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -22,7 +22,6 @@
 #include <mach/map.h>
 
 #include <plat/regs-serial.h>
-#include <plat/regs-timer.h>
 #include <mach/regs-gpio.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
@@ -43,7 +42,6 @@ static struct sleep_save irq_save[] = {
 	SAVE_ITEM(S3C64XX_EINT0FLTCON2),
 	SAVE_ITEM(S3C64XX_EINT0FLTCON3),
 	SAVE_ITEM(S3C64XX_EINT0MASK),
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
 };
 
 static struct irq_grp_save {
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
index 97c2a08a..861e15c 100644
--- a/arch/arm/mach-s5p64x0/pm.c
+++ b/arch/arm/mach-s5p64x0/pm.c
@@ -18,7 +18,6 @@
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/regs-timer.h>
 #include <plat/wakeup-mask.h>
 
 #include <mach/regs-clock.h>
@@ -48,8 +47,6 @@ static struct sleep_save s5p64x0_misc_save[] = {
 	SAVE_ITEM(S5P64X0_MEM0CONSLP1),
 	SAVE_ITEM(S5P64X0_MEM0DRVCON),
 	SAVE_ITEM(S5P64X0_MEM1DRVCON),
-
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
 };
 
 /* DPLL is present only in S5P6450 */
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
index 2b68a67..3cf3f9c 100644
--- a/arch/arm/mach-s5pv210/pm.c
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -21,7 +21,6 @@
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/regs-timer.h>
 
 #include <mach/regs-irq.h>
 #include <mach/regs-clock.h>
@@ -77,15 +76,6 @@ static struct sleep_save s5pv210_core_save[] = {
 	/* Clock ETC */
 	SAVE_ITEM(S5P_CLK_OUT),
 	SAVE_ITEM(S5P_MDNIE_SEL),
-
-	/* PWM Register */
-	SAVE_ITEM(S3C2410_TCFG0),
-	SAVE_ITEM(S3C2410_TCFG1),
-	SAVE_ITEM(S3C64XX_TINT_CSTAT),
-	SAVE_ITEM(S3C2410_TCON),
-	SAVE_ITEM(S3C2410_TCNTB(0)),
-	SAVE_ITEM(S3C2410_TCMPB(0)),
-	SAVE_ITEM(S3C2410_TCNTO(0)),
 };
 
 static int s5pv210_cpu_suspend(unsigned long arg)
diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
index 6729cb2..ddfaca9 100644
--- a/arch/arm/plat-samsung/s5p-irq.c
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -17,7 +17,6 @@
 
 #include <mach/irqs.h>
 #include <mach/map.h>
-#include <plat/regs-timer.h>
 #include <plat/cpu.h>
 
 void __init s5p_init_irq(u32 *vic, u32 num_vic)
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 20/20] ARM: SAMSUNG: Remove plat/regs-timer.h header
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-20  0:04   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding, Tomasz Figa

Since all uses of the header has been removed by previous patches it can
be removed safely.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/include/plat/regs-timer.h | 124 ------------------------
 1 file changed, 124 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/regs-timer.h

diff --git a/arch/arm/plat-samsung/include/plat/regs-timer.h b/arch/arm/plat-samsung/include/plat/regs-timer.h
deleted file mode 100644
index d097d92..0000000
--- a/arch/arm/plat-samsung/include/plat/regs-timer.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-timer.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *		      http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 Timer configuration
-*/
-
-#ifndef __ASM_ARCH_REGS_TIMER_H
-#define __ASM_ARCH_REGS_TIMER_H
-
-#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
-#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
-
-#define S3C2410_TCFG0	      S3C_TIMERREG(0x00)
-#define S3C2410_TCFG1	      S3C_TIMERREG(0x04)
-#define S3C2410_TCON	      S3C_TIMERREG(0x08)
-
-#define S3C64XX_TINT_CSTAT    S3C_TIMERREG(0x44)
-
-#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
-#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
-#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
-#define S3C2410_TCFG_DEADZONE_MASK   (255<<16)
-#define S3C2410_TCFG_DEADZONE_SHIFT  (16)
-
-#define S3C2410_TCFG1_MUX4_DIV2	  (0<<16)
-#define S3C2410_TCFG1_MUX4_DIV4	  (1<<16)
-#define S3C2410_TCFG1_MUX4_DIV8	  (2<<16)
-#define S3C2410_TCFG1_MUX4_DIV16  (3<<16)
-#define S3C2410_TCFG1_MUX4_TCLK1  (4<<16)
-#define S3C2410_TCFG1_MUX4_MASK	  (15<<16)
-#define S3C2410_TCFG1_MUX4_SHIFT  (16)
-
-#define S3C2410_TCFG1_MUX3_DIV2	  (0<<12)
-#define S3C2410_TCFG1_MUX3_DIV4	  (1<<12)
-#define S3C2410_TCFG1_MUX3_DIV8	  (2<<12)
-#define S3C2410_TCFG1_MUX3_DIV16  (3<<12)
-#define S3C2410_TCFG1_MUX3_TCLK1  (4<<12)
-#define S3C2410_TCFG1_MUX3_MASK	  (15<<12)
-
-
-#define S3C2410_TCFG1_MUX2_DIV2	  (0<<8)
-#define S3C2410_TCFG1_MUX2_DIV4	  (1<<8)
-#define S3C2410_TCFG1_MUX2_DIV8	  (2<<8)
-#define S3C2410_TCFG1_MUX2_DIV16  (3<<8)
-#define S3C2410_TCFG1_MUX2_TCLK1  (4<<8)
-#define S3C2410_TCFG1_MUX2_MASK	  (15<<8)
-
-
-#define S3C2410_TCFG1_MUX1_DIV2	  (0<<4)
-#define S3C2410_TCFG1_MUX1_DIV4	  (1<<4)
-#define S3C2410_TCFG1_MUX1_DIV8	  (2<<4)
-#define S3C2410_TCFG1_MUX1_DIV16  (3<<4)
-#define S3C2410_TCFG1_MUX1_TCLK0  (4<<4)
-#define S3C2410_TCFG1_MUX1_MASK	  (15<<4)
-
-#define S3C2410_TCFG1_MUX0_DIV2	  (0<<0)
-#define S3C2410_TCFG1_MUX0_DIV4	  (1<<0)
-#define S3C2410_TCFG1_MUX0_DIV8	  (2<<0)
-#define S3C2410_TCFG1_MUX0_DIV16  (3<<0)
-#define S3C2410_TCFG1_MUX0_TCLK0  (4<<0)
-#define S3C2410_TCFG1_MUX0_MASK	  (15<<0)
-
-#define S3C2410_TCFG1_MUX_DIV2	  (0<<0)
-#define S3C2410_TCFG1_MUX_DIV4	  (1<<0)
-#define S3C2410_TCFG1_MUX_DIV8	  (2<<0)
-#define S3C2410_TCFG1_MUX_DIV16   (3<<0)
-#define S3C2410_TCFG1_MUX_TCLK    (4<<0)
-#define S3C2410_TCFG1_MUX_MASK	  (15<<0)
-
-#define S3C64XX_TCFG1_MUX_DIV1	  (0<<0)
-#define S3C64XX_TCFG1_MUX_DIV2	  (1<<0)
-#define S3C64XX_TCFG1_MUX_DIV4	  (2<<0)
-#define S3C64XX_TCFG1_MUX_DIV8    (3<<0)
-#define S3C64XX_TCFG1_MUX_DIV16   (4<<0)
-#define S3C64XX_TCFG1_MUX_TCLK    (5<<0)  /* 3 sets of TCLK */
-#define S3C64XX_TCFG1_MUX_MASK	  (15<<0)
-
-#define S3C2410_TCFG1_SHIFT(x)	  ((x) * 4)
-
-/* for each timer, we have an count buffer, an compare buffer and
- * an observation buffer
-*/
-
-/* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */
-
-#define S3C2410_TCNTB(tmr)    S3C_TIMERREG2(tmr, 0x00)
-#define S3C2410_TCMPB(tmr)    S3C_TIMERREG2(tmr, 0x04)
-#define S3C2410_TCNTO(tmr)    S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
-
-#define S3C2410_TCON_T4RELOAD	  (1<<22)
-#define S3C2410_TCON_T4MANUALUPD  (1<<21)
-#define S3C2410_TCON_T4START	  (1<<20)
-
-#define S3C2410_TCON_T3RELOAD	  (1<<19)
-#define S3C2410_TCON_T3INVERT	  (1<<18)
-#define S3C2410_TCON_T3MANUALUPD  (1<<17)
-#define S3C2410_TCON_T3START	  (1<<16)
-
-#define S3C2410_TCON_T2RELOAD	  (1<<15)
-#define S3C2410_TCON_T2INVERT	  (1<<14)
-#define S3C2410_TCON_T2MANUALUPD  (1<<13)
-#define S3C2410_TCON_T2START	  (1<<12)
-
-#define S3C2410_TCON_T1RELOAD	  (1<<11)
-#define S3C2410_TCON_T1INVERT	  (1<<10)
-#define S3C2410_TCON_T1MANUALUPD  (1<<9)
-#define S3C2410_TCON_T1START	  (1<<8)
-
-#define S3C2410_TCON_T0DEADZONE	  (1<<4)
-#define S3C2410_TCON_T0RELOAD	  (1<<3)
-#define S3C2410_TCON_T0INVERT	  (1<<2)
-#define S3C2410_TCON_T0MANUALUPD  (1<<1)
-#define S3C2410_TCON_T0START	  (1<<0)
-
-#endif /*  __ASM_ARCH_REGS_TIMER_H */
-
-
-
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v4 20/20] ARM: SAMSUNG: Remove plat/regs-timer.h header
@ 2013-07-20  0:04   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-20  0:04 UTC (permalink / raw)
  To: linux-arm-kernel

Since all uses of the header has been removed by previous patches it can
be removed safely.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/include/plat/regs-timer.h | 124 ------------------------
 1 file changed, 124 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/include/plat/regs-timer.h

diff --git a/arch/arm/plat-samsung/include/plat/regs-timer.h b/arch/arm/plat-samsung/include/plat/regs-timer.h
deleted file mode 100644
index d097d92..0000000
--- a/arch/arm/plat-samsung/include/plat/regs-timer.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-timer.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *		      http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 Timer configuration
-*/
-
-#ifndef __ASM_ARCH_REGS_TIMER_H
-#define __ASM_ARCH_REGS_TIMER_H
-
-#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
-#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
-
-#define S3C2410_TCFG0	      S3C_TIMERREG(0x00)
-#define S3C2410_TCFG1	      S3C_TIMERREG(0x04)
-#define S3C2410_TCON	      S3C_TIMERREG(0x08)
-
-#define S3C64XX_TINT_CSTAT    S3C_TIMERREG(0x44)
-
-#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
-#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
-#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
-#define S3C2410_TCFG_DEADZONE_MASK   (255<<16)
-#define S3C2410_TCFG_DEADZONE_SHIFT  (16)
-
-#define S3C2410_TCFG1_MUX4_DIV2	  (0<<16)
-#define S3C2410_TCFG1_MUX4_DIV4	  (1<<16)
-#define S3C2410_TCFG1_MUX4_DIV8	  (2<<16)
-#define S3C2410_TCFG1_MUX4_DIV16  (3<<16)
-#define S3C2410_TCFG1_MUX4_TCLK1  (4<<16)
-#define S3C2410_TCFG1_MUX4_MASK	  (15<<16)
-#define S3C2410_TCFG1_MUX4_SHIFT  (16)
-
-#define S3C2410_TCFG1_MUX3_DIV2	  (0<<12)
-#define S3C2410_TCFG1_MUX3_DIV4	  (1<<12)
-#define S3C2410_TCFG1_MUX3_DIV8	  (2<<12)
-#define S3C2410_TCFG1_MUX3_DIV16  (3<<12)
-#define S3C2410_TCFG1_MUX3_TCLK1  (4<<12)
-#define S3C2410_TCFG1_MUX3_MASK	  (15<<12)
-
-
-#define S3C2410_TCFG1_MUX2_DIV2	  (0<<8)
-#define S3C2410_TCFG1_MUX2_DIV4	  (1<<8)
-#define S3C2410_TCFG1_MUX2_DIV8	  (2<<8)
-#define S3C2410_TCFG1_MUX2_DIV16  (3<<8)
-#define S3C2410_TCFG1_MUX2_TCLK1  (4<<8)
-#define S3C2410_TCFG1_MUX2_MASK	  (15<<8)
-
-
-#define S3C2410_TCFG1_MUX1_DIV2	  (0<<4)
-#define S3C2410_TCFG1_MUX1_DIV4	  (1<<4)
-#define S3C2410_TCFG1_MUX1_DIV8	  (2<<4)
-#define S3C2410_TCFG1_MUX1_DIV16  (3<<4)
-#define S3C2410_TCFG1_MUX1_TCLK0  (4<<4)
-#define S3C2410_TCFG1_MUX1_MASK	  (15<<4)
-
-#define S3C2410_TCFG1_MUX0_DIV2	  (0<<0)
-#define S3C2410_TCFG1_MUX0_DIV4	  (1<<0)
-#define S3C2410_TCFG1_MUX0_DIV8	  (2<<0)
-#define S3C2410_TCFG1_MUX0_DIV16  (3<<0)
-#define S3C2410_TCFG1_MUX0_TCLK0  (4<<0)
-#define S3C2410_TCFG1_MUX0_MASK	  (15<<0)
-
-#define S3C2410_TCFG1_MUX_DIV2	  (0<<0)
-#define S3C2410_TCFG1_MUX_DIV4	  (1<<0)
-#define S3C2410_TCFG1_MUX_DIV8	  (2<<0)
-#define S3C2410_TCFG1_MUX_DIV16   (3<<0)
-#define S3C2410_TCFG1_MUX_TCLK    (4<<0)
-#define S3C2410_TCFG1_MUX_MASK	  (15<<0)
-
-#define S3C64XX_TCFG1_MUX_DIV1	  (0<<0)
-#define S3C64XX_TCFG1_MUX_DIV2	  (1<<0)
-#define S3C64XX_TCFG1_MUX_DIV4	  (2<<0)
-#define S3C64XX_TCFG1_MUX_DIV8    (3<<0)
-#define S3C64XX_TCFG1_MUX_DIV16   (4<<0)
-#define S3C64XX_TCFG1_MUX_TCLK    (5<<0)  /* 3 sets of TCLK */
-#define S3C64XX_TCFG1_MUX_MASK	  (15<<0)
-
-#define S3C2410_TCFG1_SHIFT(x)	  ((x) * 4)
-
-/* for each timer, we have an count buffer, an compare buffer and
- * an observation buffer
-*/
-
-/* WARNING - timer 4 has no buffer reg, and it's observation is@+4 */
-
-#define S3C2410_TCNTB(tmr)    S3C_TIMERREG2(tmr, 0x00)
-#define S3C2410_TCMPB(tmr)    S3C_TIMERREG2(tmr, 0x04)
-#define S3C2410_TCNTO(tmr)    S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
-
-#define S3C2410_TCON_T4RELOAD	  (1<<22)
-#define S3C2410_TCON_T4MANUALUPD  (1<<21)
-#define S3C2410_TCON_T4START	  (1<<20)
-
-#define S3C2410_TCON_T3RELOAD	  (1<<19)
-#define S3C2410_TCON_T3INVERT	  (1<<18)
-#define S3C2410_TCON_T3MANUALUPD  (1<<17)
-#define S3C2410_TCON_T3START	  (1<<16)
-
-#define S3C2410_TCON_T2RELOAD	  (1<<15)
-#define S3C2410_TCON_T2INVERT	  (1<<14)
-#define S3C2410_TCON_T2MANUALUPD  (1<<13)
-#define S3C2410_TCON_T2START	  (1<<12)
-
-#define S3C2410_TCON_T1RELOAD	  (1<<11)
-#define S3C2410_TCON_T1INVERT	  (1<<10)
-#define S3C2410_TCON_T1MANUALUPD  (1<<9)
-#define S3C2410_TCON_T1START	  (1<<8)
-
-#define S3C2410_TCON_T0DEADZONE	  (1<<4)
-#define S3C2410_TCON_T0RELOAD	  (1<<3)
-#define S3C2410_TCON_T0INVERT	  (1<<2)
-#define S3C2410_TCON_T0MANUALUPD  (1<<1)
-#define S3C2410_TCON_T0START	  (1<<0)
-
-#endif /*  __ASM_ARCH_REGS_TIMER_H */
-
-
-
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-21 19:46     ` Sylwester Nawrocki
  -1 siblings, 0 replies; 124+ messages in thread
From: Sylwester Nawrocki @ 2013-07-21 19:46 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Heiko Stübner, Mark Brown,
	Thierry Reding

Hi Tomasz,

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> This patch adds new samsung_device_pwm platform device that represents
> the whole PWM/timer block and includes memory and IRQ resources.
>
> Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> ---
>   arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
>   arch/arm/plat-samsung/include/plat/devs.h     |  1 +
>   arch/arm/plat-samsung/include/plat/pwm-core.h | 24 ++++++++++++++++++++++++
>   3 files changed, 42 insertions(+)
>   create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
>
> diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
> index 0f9c3f4..bba6d78 100644
> --- a/arch/arm/plat-samsung/devs.c
> +++ b/arch/arm/plat-samsung/devs.c
> @@ -58,6 +58,7 @@
>   #include<plat/keypad.h>
>   #include<linux/platform_data/mmc-s3cmci.h>
>   #include<linux/platform_data/mtd-nand-s3c2410.h>
> +#include<plat/pwm-core.h>
>   #include<plat/sdhci.h>
>   #include<linux/platform_data/touchscreen-s3c2410.h>
>   #include<linux/platform_data/usb-s3c2410_udc.h>
> @@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
>   	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
>   	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
>   };
> +
> +static struct resource samsung_pwm_resource[] = {
> +	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
> +};
> +
> +struct platform_device samsung_device_pwm = {
> +	.name		= "samsung-pwm",
> +	.id		= -1,
> +	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
> +	.resource	= samsung_pwm_resource,
> +};
> +
> +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
> +{
> +	samsung_device_pwm.dev.platform_data = pd;
> +}
>   #endif /* CONFIG_SAMSUNG_DEV_PWM */
>
>   /* RTC */
> diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
> index 87d501f..0dc4ac4 100644
> --- a/arch/arm/plat-samsung/include/plat/devs.h
> +++ b/arch/arm/plat-samsung/include/plat/devs.h
> @@ -134,6 +134,7 @@ extern struct platform_device exynos4_device_spdif;
>
>   extern struct platform_device samsung_asoc_idma;
>   extern struct platform_device samsung_device_keypad;
> +extern struct platform_device samsung_device_pwm;
>
>   /* s3c2440 specific devices */
>
> diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
> new file mode 100644
> index 0000000..df50f5c
> --- /dev/null
> +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
> @@ -0,0 +1,24 @@
> +/*
> + * linux/arch/arm/plat-samsung/onenand-core.h

Are such full file path names really useful, especially we are never
sure they are up to date ? I guess this line could be removed.

> + *  Copyright (c) 2013 Tomasz Figa<tomasz.figa@gmail.com>
> + *
> + * Samsung PWM Controller core functions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#ifndef __ASM_ARCH_PWM_CORE_H
> +#define __ASM_ARCH_PWM_CORE_H __FILE__
> +
> +#include<clocksource/samsung_pwm.h>
> +
> +#ifdef CONFIG_SAMSUNG_DEV_PWM
> +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);

nit: 'extern' is implicit for function declarations, it could be omitted 
here.

> +#else
> +static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
> +#endif
> +
> +#endif /* __ASM_ARCH_PWM_CORE_H */

Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
@ 2013-07-21 19:46     ` Sylwester Nawrocki
  0 siblings, 0 replies; 124+ messages in thread
From: Sylwester Nawrocki @ 2013-07-21 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> This patch adds new samsung_device_pwm platform device that represents
> the whole PWM/timer block and includes memory and IRQ resources.
>
> Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> ---
>   arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
>   arch/arm/plat-samsung/include/plat/devs.h     |  1 +
>   arch/arm/plat-samsung/include/plat/pwm-core.h | 24 ++++++++++++++++++++++++
>   3 files changed, 42 insertions(+)
>   create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
>
> diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
> index 0f9c3f4..bba6d78 100644
> --- a/arch/arm/plat-samsung/devs.c
> +++ b/arch/arm/plat-samsung/devs.c
> @@ -58,6 +58,7 @@
>   #include<plat/keypad.h>
>   #include<linux/platform_data/mmc-s3cmci.h>
>   #include<linux/platform_data/mtd-nand-s3c2410.h>
> +#include<plat/pwm-core.h>
>   #include<plat/sdhci.h>
>   #include<linux/platform_data/touchscreen-s3c2410.h>
>   #include<linux/platform_data/usb-s3c2410_udc.h>
> @@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
>   	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
>   	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
>   };
> +
> +static struct resource samsung_pwm_resource[] = {
> +	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
> +};
> +
> +struct platform_device samsung_device_pwm = {
> +	.name		= "samsung-pwm",
> +	.id		= -1,
> +	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
> +	.resource	= samsung_pwm_resource,
> +};
> +
> +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
> +{
> +	samsung_device_pwm.dev.platform_data = pd;
> +}
>   #endif /* CONFIG_SAMSUNG_DEV_PWM */
>
>   /* RTC */
> diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
> index 87d501f..0dc4ac4 100644
> --- a/arch/arm/plat-samsung/include/plat/devs.h
> +++ b/arch/arm/plat-samsung/include/plat/devs.h
> @@ -134,6 +134,7 @@ extern struct platform_device exynos4_device_spdif;
>
>   extern struct platform_device samsung_asoc_idma;
>   extern struct platform_device samsung_device_keypad;
> +extern struct platform_device samsung_device_pwm;
>
>   /* s3c2440 specific devices */
>
> diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
> new file mode 100644
> index 0000000..df50f5c
> --- /dev/null
> +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
> @@ -0,0 +1,24 @@
> +/*
> + * linux/arch/arm/plat-samsung/onenand-core.h

Are such full file path names really useful, especially we are never
sure they are up to date ? I guess this line could be removed.

> + *  Copyright (c) 2013 Tomasz Figa<tomasz.figa@gmail.com>
> + *
> + * Samsung PWM Controller core functions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#ifndef __ASM_ARCH_PWM_CORE_H
> +#define __ASM_ARCH_PWM_CORE_H __FILE__
> +
> +#include<clocksource/samsung_pwm.h>
> +
> +#ifdef CONFIG_SAMSUNG_DEV_PWM
> +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);

nit: 'extern' is implicit for function declarations, it could be omitted 
here.

> +#else
> +static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
> +#endif
> +
> +#endif /* __ASM_ARCH_PWM_CORE_H */

Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 13/20] pwm: Add new pwm-samsung driver
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-21 19:50     ` Sylwester Nawrocki
  -1 siblings, 0 replies; 124+ messages in thread
From: Sylwester Nawrocki @ 2013-07-21 19:50 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> This patch introduces new Samsung PWM driver, which uses Samsung
> PWM/timer master driver to control shared parts of the hardware.
>
> Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> ---
>   drivers/pwm/Makefile      |   1 +
>   drivers/pwm/pwm-samsung.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 607 insertions(+)
>   create mode 100644 drivers/pwm/pwm-samsung.c
[...]
> +static const struct samsung_pwm_variant s3c64xx_variant = {
> +	.bits		= 32,
> +	.div_base	= 0,

Initialization to 0 could be omitted, since it is implicit.

> +	.has_tint_cstat	= true,
> +	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
> +};
> +
> +static const struct samsung_pwm_variant s5p64x0_variant = {
> +	.bits		= 32,
> +	.div_base	= 0,

Ditto.

> +	.has_tint_cstat	= true,
> +};
> +
> +static const struct samsung_pwm_variant s5p_variant = {
> +	.bits		= 32,
> +	.div_base	= 0,

Ditto.

> +	.has_tint_cstat	= true,
> +	.tclk_mask	= BIT(5),
> +};
> +
[...]
> +static int pwm_samsung_remove(struct platform_device *pdev)
> +{
> +	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
> +	int ret;
> +
> +	ret = pwmchip_remove(&chip->chip);
> +	if (ret<  0)
> +		return ret;

Since return value of the remove() callback is happily ignored by
the driver core I think there is no point in returning an error
here like this. Wouldn't it be more sensible to just call all the
cleanup functions unconditionally ? At least potentially wrong state
of the clock could be avoided.

> +
> +	clk_disable_unprepare(chip->base_clk);
> +
> +	return 0;
> +}

--
Regards,
Sylwester

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 13/20] pwm: Add new pwm-samsung driver
@ 2013-07-21 19:50     ` Sylwester Nawrocki
  0 siblings, 0 replies; 124+ messages in thread
From: Sylwester Nawrocki @ 2013-07-21 19:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> This patch introduces new Samsung PWM driver, which uses Samsung
> PWM/timer master driver to control shared parts of the hardware.
>
> Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> ---
>   drivers/pwm/Makefile      |   1 +
>   drivers/pwm/pwm-samsung.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 607 insertions(+)
>   create mode 100644 drivers/pwm/pwm-samsung.c
[...]
> +static const struct samsung_pwm_variant s3c64xx_variant = {
> +	.bits		= 32,
> +	.div_base	= 0,

Initialization to 0 could be omitted, since it is implicit.

> +	.has_tint_cstat	= true,
> +	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
> +};
> +
> +static const struct samsung_pwm_variant s5p64x0_variant = {
> +	.bits		= 32,
> +	.div_base	= 0,

Ditto.

> +	.has_tint_cstat	= true,
> +};
> +
> +static const struct samsung_pwm_variant s5p_variant = {
> +	.bits		= 32,
> +	.div_base	= 0,

Ditto.

> +	.has_tint_cstat	= true,
> +	.tclk_mask	= BIT(5),
> +};
> +
[...]
> +static int pwm_samsung_remove(struct platform_device *pdev)
> +{
> +	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
> +	int ret;
> +
> +	ret = pwmchip_remove(&chip->chip);
> +	if (ret<  0)
> +		return ret;

Since return value of the remove() callback is happily ignored by
the driver core I think there is no point in returning an error
here like this. Wouldn't it be more sensible to just call all the
cleanup functions unconditionally ? At least potentially wrong state
of the clock could be avoided.

> +
> +	clk_disable_unprepare(chip->base_clk);
> +
> +	return 0;
> +}

--
Regards,
Sylwester

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
  2013-07-21 19:46     ` Sylwester Nawrocki
@ 2013-07-21 21:51       ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 21:51 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Heiko Stübner, Mark Brown,
	Thierry Reding

Hi Sylwester,

On Sunday 21 of July 2013 21:46:09 Sylwester Nawrocki wrote:
> Hi Tomasz,
> 
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > This patch adds new samsung_device_pwm platform device that represents
> > the whole PWM/timer block and includes memory and IRQ resources.
> > 
> > Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> > ---
> > 
> >   arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
> >   arch/arm/plat-samsung/include/plat/devs.h     |  1 +
> >   arch/arm/plat-samsung/include/plat/pwm-core.h | 24
> >   ++++++++++++++++++++++++ 3 files changed, 42 insertions(+)
> >   create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
> > 
> > diff --git a/arch/arm/plat-samsung/devs.c
> > b/arch/arm/plat-samsung/devs.c index 0f9c3f4..bba6d78 100644
> > --- a/arch/arm/plat-samsung/devs.c
> > +++ b/arch/arm/plat-samsung/devs.c
> > @@ -58,6 +58,7 @@
> > 
> >   #include<plat/keypad.h>
> >   #include<linux/platform_data/mmc-s3cmci.h>
> >   #include<linux/platform_data/mtd-nand-s3c2410.h>
> > 
> > +#include<plat/pwm-core.h>
> > 
> >   #include<plat/sdhci.h>
> >   #include<linux/platform_data/touchscreen-s3c2410.h>
> >   #include<linux/platform_data/usb-s3c2410_udc.h>
> > 
> > @@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
> > 
> >   	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
> >   	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
> >   
> >   };
> > 
> > +
> > +static struct resource samsung_pwm_resource[] = {
> > +	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
> > +};
> > +
> > +struct platform_device samsung_device_pwm = {
> > +	.name		= "samsung-pwm",
> > +	.id		= -1,
> > +	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
> > +	.resource	= samsung_pwm_resource,
> > +};
> > +
> > +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
> > +{
> > +	samsung_device_pwm.dev.platform_data = pd;
> > +}
> > 
> >   #endif /* CONFIG_SAMSUNG_DEV_PWM */
> >   
> >   /* RTC */
> > 
> > diff --git a/arch/arm/plat-samsung/include/plat/devs.h
> > b/arch/arm/plat-samsung/include/plat/devs.h index 87d501f..0dc4ac4
> > 100644
> > --- a/arch/arm/plat-samsung/include/plat/devs.h
> > +++ b/arch/arm/plat-samsung/include/plat/devs.h
> > @@ -134,6 +134,7 @@ extern struct platform_device
> > exynos4_device_spdif;
> > 
> >   extern struct platform_device samsung_asoc_idma;
> >   extern struct platform_device samsung_device_keypad;
> > 
> > +extern struct platform_device samsung_device_pwm;
> > 
> >   /* s3c2440 specific devices */
> > 
> > diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h
> > b/arch/arm/plat-samsung/include/plat/pwm-core.h new file mode 100644
> > index 0000000..df50f5c
> > --- /dev/null
> > +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
> > @@ -0,0 +1,24 @@
> > +/*
> > + * linux/arch/arm/plat-samsung/onenand-core.h
> 
> Are such full file path names really useful, especially we are never
> sure they are up to date ? I guess this line could be removed.

No, they are not. This is a copy-pasto I missed (notice onenand-core...).

> > + *  Copyright (c) 2013 Tomasz Figa<tomasz.figa@gmail.com>
> > + *
> > + * Samsung PWM Controller core functions
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify + * it under the terms of the GNU General Public License
> > version 2 as + * published by the Free Software Foundation.
> > +*/
> > +
> > +#ifndef __ASM_ARCH_PWM_CORE_H
> > +#define __ASM_ARCH_PWM_CORE_H __FILE__
> > +
> > +#include<clocksource/samsung_pwm.h>
> > +
> > +#ifdef CONFIG_SAMSUNG_DEV_PWM
> > +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
> 
> nit: 'extern' is implicit for function declarations, it could be omitted
> here.

The extern kernel is used widely over the kernel (including headers in 
plat-samsung) and I prefer adding it for clarity.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
@ 2013-07-21 21:51       ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 21:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sylwester,

On Sunday 21 of July 2013 21:46:09 Sylwester Nawrocki wrote:
> Hi Tomasz,
> 
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > This patch adds new samsung_device_pwm platform device that represents
> > the whole PWM/timer block and includes memory and IRQ resources.
> > 
> > Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> > ---
> > 
> >   arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
> >   arch/arm/plat-samsung/include/plat/devs.h     |  1 +
> >   arch/arm/plat-samsung/include/plat/pwm-core.h | 24
> >   ++++++++++++++++++++++++ 3 files changed, 42 insertions(+)
> >   create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
> > 
> > diff --git a/arch/arm/plat-samsung/devs.c
> > b/arch/arm/plat-samsung/devs.c index 0f9c3f4..bba6d78 100644
> > --- a/arch/arm/plat-samsung/devs.c
> > +++ b/arch/arm/plat-samsung/devs.c
> > @@ -58,6 +58,7 @@
> > 
> >   #include<plat/keypad.h>
> >   #include<linux/platform_data/mmc-s3cmci.h>
> >   #include<linux/platform_data/mtd-nand-s3c2410.h>
> > 
> > +#include<plat/pwm-core.h>
> > 
> >   #include<plat/sdhci.h>
> >   #include<linux/platform_data/touchscreen-s3c2410.h>
> >   #include<linux/platform_data/usb-s3c2410_udc.h>
> > 
> > @@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
> > 
> >   	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
> >   	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
> >   
> >   };
> > 
> > +
> > +static struct resource samsung_pwm_resource[] = {
> > +	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
> > +};
> > +
> > +struct platform_device samsung_device_pwm = {
> > +	.name		= "samsung-pwm",
> > +	.id		= -1,
> > +	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
> > +	.resource	= samsung_pwm_resource,
> > +};
> > +
> > +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
> > +{
> > +	samsung_device_pwm.dev.platform_data = pd;
> > +}
> > 
> >   #endif /* CONFIG_SAMSUNG_DEV_PWM */
> >   
> >   /* RTC */
> > 
> > diff --git a/arch/arm/plat-samsung/include/plat/devs.h
> > b/arch/arm/plat-samsung/include/plat/devs.h index 87d501f..0dc4ac4
> > 100644
> > --- a/arch/arm/plat-samsung/include/plat/devs.h
> > +++ b/arch/arm/plat-samsung/include/plat/devs.h
> > @@ -134,6 +134,7 @@ extern struct platform_device
> > exynos4_device_spdif;
> > 
> >   extern struct platform_device samsung_asoc_idma;
> >   extern struct platform_device samsung_device_keypad;
> > 
> > +extern struct platform_device samsung_device_pwm;
> > 
> >   /* s3c2440 specific devices */
> > 
> > diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h
> > b/arch/arm/plat-samsung/include/plat/pwm-core.h new file mode 100644
> > index 0000000..df50f5c
> > --- /dev/null
> > +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
> > @@ -0,0 +1,24 @@
> > +/*
> > + * linux/arch/arm/plat-samsung/onenand-core.h
> 
> Are such full file path names really useful, especially we are never
> sure they are up to date ? I guess this line could be removed.

No, they are not. This is a copy-pasto I missed (notice onenand-core...).

> > + *  Copyright (c) 2013 Tomasz Figa<tomasz.figa@gmail.com>
> > + *
> > + * Samsung PWM Controller core functions
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify + * it under the terms of the GNU General Public License
> > version 2 as + * published by the Free Software Foundation.
> > +*/
> > +
> > +#ifndef __ASM_ARCH_PWM_CORE_H
> > +#define __ASM_ARCH_PWM_CORE_H __FILE__
> > +
> > +#include<clocksource/samsung_pwm.h>
> > +
> > +#ifdef CONFIG_SAMSUNG_DEV_PWM
> > +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
> 
> nit: 'extern' is implicit for function declarations, it could be omitted
> here.

The extern kernel is used widely over the kernel (including headers in 
plat-samsung) and I prefer adding it for clarity.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 13/20] pwm: Add new pwm-samsung driver
  2013-07-21 19:50     ` Sylwester Nawrocki
@ 2013-07-21 21:58       ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 21:58 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Heiko Stübner, Mark Brown,
	Thierry Reding

On Sunday 21 of July 2013 21:50:47 Sylwester Nawrocki wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > This patch introduces new Samsung PWM driver, which uses Samsung
> > PWM/timer master driver to control shared parts of the hardware.
> > 
> > Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> > ---
> > 
> >   drivers/pwm/Makefile      |   1 +
> >   drivers/pwm/pwm-samsung.c | 606
> >   ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 607
> >   insertions(+)
> >   create mode 100644 drivers/pwm/pwm-samsung.c
> 
> [...]
> 
> > +static const struct samsung_pwm_variant s3c64xx_variant = {
> > +	.bits		= 32,
> > +	.div_base	= 0,
> 
> Initialization to 0 could be omitted, since it is implicit.

Well, I'd prefer keeping this as is, for clarity. It improves code 
readability, because you don't have to look at struct definition to see 
all the fields.

> > +	.has_tint_cstat	= true,
> > +	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
> > +};
> > +
> > +static const struct samsung_pwm_variant s5p64x0_variant = {
> > +	.bits		= 32,
> > +	.div_base	= 0,
> 
> Ditto.
> 
> > +	.has_tint_cstat	= true,
> > +};
> > +
> > +static const struct samsung_pwm_variant s5p_variant = {
> > +	.bits		= 32,
> > +	.div_base	= 0,
> 
> Ditto.
> 
> > +	.has_tint_cstat	= true,
> > +	.tclk_mask	= BIT(5),
> > +};
> > +
> 
> [...]
> 
> > +static int pwm_samsung_remove(struct platform_device *pdev)
> > +{
> > +	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
> > +	int ret;
> > +
> > +	ret = pwmchip_remove(&chip->chip);
> > +	if (ret < 0)
> > +		return ret;
> 
> Since return value of the remove() callback is happily ignored by
> the driver core I think there is no point in returning an error
> here like this. Wouldn't it be more sensible to just call all the
> cleanup functions unconditionally ? At least potentially wrong state
> of the clock could be avoided.

IMHO handling the errors correctly here is more future-proof. Driver core 
might be modified to handle errors in future and this driver will not need 
to be modified.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 13/20] pwm: Add new pwm-samsung driver
@ 2013-07-21 21:58       ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 of July 2013 21:50:47 Sylwester Nawrocki wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > This patch introduces new Samsung PWM driver, which uses Samsung
> > PWM/timer master driver to control shared parts of the hardware.
> > 
> > Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> > ---
> > 
> >   drivers/pwm/Makefile      |   1 +
> >   drivers/pwm/pwm-samsung.c | 606
> >   ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 607
> >   insertions(+)
> >   create mode 100644 drivers/pwm/pwm-samsung.c
> 
> [...]
> 
> > +static const struct samsung_pwm_variant s3c64xx_variant = {
> > +	.bits		= 32,
> > +	.div_base	= 0,
> 
> Initialization to 0 could be omitted, since it is implicit.

Well, I'd prefer keeping this as is, for clarity. It improves code 
readability, because you don't have to look at struct definition to see 
all the fields.

> > +	.has_tint_cstat	= true,
> > +	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
> > +};
> > +
> > +static const struct samsung_pwm_variant s5p64x0_variant = {
> > +	.bits		= 32,
> > +	.div_base	= 0,
> 
> Ditto.
> 
> > +	.has_tint_cstat	= true,
> > +};
> > +
> > +static const struct samsung_pwm_variant s5p_variant = {
> > +	.bits		= 32,
> > +	.div_base	= 0,
> 
> Ditto.
> 
> > +	.has_tint_cstat	= true,
> > +	.tclk_mask	= BIT(5),
> > +};
> > +
> 
> [...]
> 
> > +static int pwm_samsung_remove(struct platform_device *pdev)
> > +{
> > +	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
> > +	int ret;
> > +
> > +	ret = pwmchip_remove(&chip->chip);
> > +	if (ret < 0)
> > +		return ret;
> 
> Since return value of the remove() callback is happily ignored by
> the driver core I think there is no point in returning an error
> here like this. Wouldn't it be more sensible to just call all the
> cleanup functions unconditionally ? At least potentially wrong state
> of the clock could be avoided.

IMHO handling the errors correctly here is more future-proof. Driver core 
might be modified to handle errors in future and this driver will not need 
to be modified.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-21 22:22   ` Sylwester Nawrocki
  -1 siblings, 0 replies; 124+ messages in thread
From: Sylwester Nawrocki @ 2013-07-21 22:22 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Heiko Stübner, Mark Brown,
	Thierry Reding

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> Since we now have a proper Samsung PWM clocksource driver in place,
> we can proceed with further cleanup of PWM timers support on Samsung SoCs.
>
> This series attempts to achieve this goal by:
>   1) fixing up few things in samsung_pwm_timer clocksource driver,
>   2) moving remaining Samsung platforms to the new clocksource driver,
>   3) removing old clocksource driver,
>   4) adding new multiplatform- and DT-aware PWM driver,
>   5) moving all Samsung platforms to use the new PWM driver,
>   6) removing old PWM driver,
>   7) removing all PWM-related code that is not used anymore.
>
> Cleaning up the PWM driver is a bit tricky, because the design of current
> driver makes it completely unsuitable for DT and multiplatform and would
> require a heavy rework to make it usable, breaking any existing Samsung PWM
> users by the way. To avoid any breakage this series first renames the old
> driver, then adds new one using original name, migrates all platforms to
> use it and then finally removes the old driver.
>
> See particular patches for more detailed descriptions.
>
> [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper, SMDK6410
> with PWM backlight and Exynos4210-based Origen board (with PWM0 attached
> to a scope)]
> Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
>
> [On S3C2440-based Mini2440 board]
> Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>

I have retested this series on top of v3.11-rc1 with pwm-backlight (and 
buzzer
as the output :)) on Mini2440. It seems to work well - generated frequencies
are correct. I'll check pulse widths with a scope tomorrow, as it's a 
bit late
now. FWIW you can add to this series my:

Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

> [On a s3c2416 based machine]
> Tested-by: Heiko Stuebner<heiko@sntech.de>
>
> [Also not sure on what boards, but still]
> Tested-by: Mark Brown<broonie@linaro.org>
>
> Acked-by: Arnd Bergmann<arnd@arndb.de>
> Acked-by: Thierry Reding<thierry.reding@gmail.com>
> Acked-by: Heiko Stuebner<heiko@sntech.de>

Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-21 22:22   ` Sylwester Nawrocki
  0 siblings, 0 replies; 124+ messages in thread
From: Sylwester Nawrocki @ 2013-07-21 22:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> Since we now have a proper Samsung PWM clocksource driver in place,
> we can proceed with further cleanup of PWM timers support on Samsung SoCs.
>
> This series attempts to achieve this goal by:
>   1) fixing up few things in samsung_pwm_timer clocksource driver,
>   2) moving remaining Samsung platforms to the new clocksource driver,
>   3) removing old clocksource driver,
>   4) adding new multiplatform- and DT-aware PWM driver,
>   5) moving all Samsung platforms to use the new PWM driver,
>   6) removing old PWM driver,
>   7) removing all PWM-related code that is not used anymore.
>
> Cleaning up the PWM driver is a bit tricky, because the design of current
> driver makes it completely unsuitable for DT and multiplatform and would
> require a heavy rework to make it usable, breaking any existing Samsung PWM
> users by the way. To avoid any breakage this series first renames the old
> driver, then adds new one using original name, migrates all platforms to
> use it and then finally removes the old driver.
>
> See particular patches for more detailed descriptions.
>
> [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper, SMDK6410
> with PWM backlight and Exynos4210-based Origen board (with PWM0 attached
> to a scope)]
> Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
>
> [On S3C2440-based Mini2440 board]
> Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>

I have retested this series on top of v3.11-rc1 with pwm-backlight (and 
buzzer
as the output :)) on Mini2440. It seems to work well - generated frequencies
are correct. I'll check pulse widths with a scope tomorrow, as it's a 
bit late
now. FWIW you can add to this series my:

Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

> [On a s3c2416 based machine]
> Tested-by: Heiko Stuebner<heiko@sntech.de>
>
> [Also not sure on what boards, but still]
> Tested-by: Mark Brown<broonie@linaro.org>
>
> Acked-by: Arnd Bergmann<arnd@arndb.de>
> Acked-by: Thierry Reding<thierry.reding@gmail.com>
> Acked-by: Heiko Stuebner<heiko@sntech.de>

Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
  2013-07-21 21:51       ` Tomasz Figa
@ 2013-07-21 22:24         ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 22:24 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Heiko Stübner, Mark Brown,
	Thierry Reding

On Sunday 21 of July 2013 23:51:24 Tomasz Figa wrote:
> Hi Sylwester,
> 
> On Sunday 21 of July 2013 21:46:09 Sylwester Nawrocki wrote:
> > Hi Tomasz,
> > 
> > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > This patch adds new samsung_device_pwm platform device that
> > > represents
> > > the whole PWM/timer block and includes memory and IRQ resources.
> > > 
> > > Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > ---
> > > 
> > >   arch/arm/plat-samsung/devs.c                  | 17
> > >   +++++++++++++++++
> > >   arch/arm/plat-samsung/include/plat/devs.h     |  1 +
> > >   arch/arm/plat-samsung/include/plat/pwm-core.h | 24
> > >   ++++++++++++++++++++++++ 3 files changed, 42 insertions(+)
> > >   create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
> > > 
> > > diff --git a/arch/arm/plat-samsung/devs.c
> > > b/arch/arm/plat-samsung/devs.c index 0f9c3f4..bba6d78 100644
> > > --- a/arch/arm/plat-samsung/devs.c
> > > +++ b/arch/arm/plat-samsung/devs.c
> > > @@ -58,6 +58,7 @@
> > > 
> > >   #include<plat/keypad.h>
> > >   #include<linux/platform_data/mmc-s3cmci.h>
> > >   #include<linux/platform_data/mtd-nand-s3c2410.h>
> > > 
> > > +#include<plat/pwm-core.h>
> > > 
> > >   #include<plat/sdhci.h>
> > >   #include<linux/platform_data/touchscreen-s3c2410.h>
> > >   #include<linux/platform_data/usb-s3c2410_udc.h>
> > > 
> > > @@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
> > > 
> > >   	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
> > >   	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
> > >   
> > >   };
> > > 
> > > +
> > > +static struct resource samsung_pwm_resource[] = {
> > > +	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
> > > +};
> > > +
> > > +struct platform_device samsung_device_pwm = {
> > > +	.name		= "samsung-pwm",
> > > +	.id		= -1,
> > > +	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
> > > +	.resource	= samsung_pwm_resource,
> > > +};
> > > +
> > > +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant
> > > *pd)
> > > +{
> > > +	samsung_device_pwm.dev.platform_data = pd;
> > > +}
> > > 
> > >   #endif /* CONFIG_SAMSUNG_DEV_PWM */
> > >   
> > >   /* RTC */
> > > 
> > > diff --git a/arch/arm/plat-samsung/include/plat/devs.h
> > > b/arch/arm/plat-samsung/include/plat/devs.h index 87d501f..0dc4ac4
> > > 100644
> > > --- a/arch/arm/plat-samsung/include/plat/devs.h
> > > +++ b/arch/arm/plat-samsung/include/plat/devs.h
> > > @@ -134,6 +134,7 @@ extern struct platform_device
> > > exynos4_device_spdif;
> > > 
> > >   extern struct platform_device samsung_asoc_idma;
> > >   extern struct platform_device samsung_device_keypad;
> > > 
> > > +extern struct platform_device samsung_device_pwm;
> > > 
> > >   /* s3c2440 specific devices */
> > > 
> > > diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h
> > > b/arch/arm/plat-samsung/include/plat/pwm-core.h new file mode 100644
> > > index 0000000..df50f5c
> > > --- /dev/null
> > > +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
> > > @@ -0,0 +1,24 @@
> > > +/*
> > > + * linux/arch/arm/plat-samsung/onenand-core.h
> > 
> > Are such full file path names really useful, especially we are never
> > sure they are up to date ? I guess this line could be removed.
> 
> No, they are not. This is a copy-pasto I missed (notice
> onenand-core...).
> > > + *  Copyright (c) 2013 Tomasz Figa<tomasz.figa@gmail.com>
> > > + *
> > > + * Samsung PWM Controller core functions
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > modify + * it under the terms of the GNU General Public License
> > > version 2 as + * published by the Free Software Foundation.
> > > +*/
> > > +
> > > +#ifndef __ASM_ARCH_PWM_CORE_H
> > > +#define __ASM_ARCH_PWM_CORE_H __FILE__
> > > +
> > > +#include<clocksource/samsung_pwm.h>
> > > +
> > > +#ifdef CONFIG_SAMSUNG_DEV_PWM
> > > +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant
> > > *pd);
> > 
> > nit: 'extern' is implicit for function declarations, it could be
> > omitted here.
> 
> The extern kernel is used widely over the kernel (including headers in
> plat-samsung) and I prefer adding it for clarity.

s/extern kernel/extern keyword/

I guess it's time to sleep.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device
@ 2013-07-21 22:24         ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 21 of July 2013 23:51:24 Tomasz Figa wrote:
> Hi Sylwester,
> 
> On Sunday 21 of July 2013 21:46:09 Sylwester Nawrocki wrote:
> > Hi Tomasz,
> > 
> > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > This patch adds new samsung_device_pwm platform device that
> > > represents
> > > the whole PWM/timer block and includes memory and IRQ resources.
> > > 
> > > Signed-off-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > ---
> > > 
> > >   arch/arm/plat-samsung/devs.c                  | 17
> > >   +++++++++++++++++
> > >   arch/arm/plat-samsung/include/plat/devs.h     |  1 +
> > >   arch/arm/plat-samsung/include/plat/pwm-core.h | 24
> > >   ++++++++++++++++++++++++ 3 files changed, 42 insertions(+)
> > >   create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
> > > 
> > > diff --git a/arch/arm/plat-samsung/devs.c
> > > b/arch/arm/plat-samsung/devs.c index 0f9c3f4..bba6d78 100644
> > > --- a/arch/arm/plat-samsung/devs.c
> > > +++ b/arch/arm/plat-samsung/devs.c
> > > @@ -58,6 +58,7 @@
> > > 
> > >   #include<plat/keypad.h>
> > >   #include<linux/platform_data/mmc-s3cmci.h>
> > >   #include<linux/platform_data/mtd-nand-s3c2410.h>
> > > 
> > > +#include<plat/pwm-core.h>
> > > 
> > >   #include<plat/sdhci.h>
> > >   #include<linux/platform_data/touchscreen-s3c2410.h>
> > >   #include<linux/platform_data/usb-s3c2410_udc.h>
> > > 
> > > @@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
> > > 
> > >   	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
> > >   	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
> > >   
> > >   };
> > > 
> > > +
> > > +static struct resource samsung_pwm_resource[] = {
> > > +	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
> > > +};
> > > +
> > > +struct platform_device samsung_device_pwm = {
> > > +	.name		= "samsung-pwm",
> > > +	.id		= -1,
> > > +	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
> > > +	.resource	= samsung_pwm_resource,
> > > +};
> > > +
> > > +void __init samsung_pwm_set_platdata(struct samsung_pwm_variant
> > > *pd)
> > > +{
> > > +	samsung_device_pwm.dev.platform_data = pd;
> > > +}
> > > 
> > >   #endif /* CONFIG_SAMSUNG_DEV_PWM */
> > >   
> > >   /* RTC */
> > > 
> > > diff --git a/arch/arm/plat-samsung/include/plat/devs.h
> > > b/arch/arm/plat-samsung/include/plat/devs.h index 87d501f..0dc4ac4
> > > 100644
> > > --- a/arch/arm/plat-samsung/include/plat/devs.h
> > > +++ b/arch/arm/plat-samsung/include/plat/devs.h
> > > @@ -134,6 +134,7 @@ extern struct platform_device
> > > exynos4_device_spdif;
> > > 
> > >   extern struct platform_device samsung_asoc_idma;
> > >   extern struct platform_device samsung_device_keypad;
> > > 
> > > +extern struct platform_device samsung_device_pwm;
> > > 
> > >   /* s3c2440 specific devices */
> > > 
> > > diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h
> > > b/arch/arm/plat-samsung/include/plat/pwm-core.h new file mode 100644
> > > index 0000000..df50f5c
> > > --- /dev/null
> > > +++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
> > > @@ -0,0 +1,24 @@
> > > +/*
> > > + * linux/arch/arm/plat-samsung/onenand-core.h
> > 
> > Are such full file path names really useful, especially we are never
> > sure they are up to date ? I guess this line could be removed.
> 
> No, they are not. This is a copy-pasto I missed (notice
> onenand-core...).
> > > + *  Copyright (c) 2013 Tomasz Figa<tomasz.figa@gmail.com>
> > > + *
> > > + * Samsung PWM Controller core functions
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > modify + * it under the terms of the GNU General Public License
> > > version 2 as + * published by the Free Software Foundation.
> > > +*/
> > > +
> > > +#ifndef __ASM_ARCH_PWM_CORE_H
> > > +#define __ASM_ARCH_PWM_CORE_H __FILE__
> > > +
> > > +#include<clocksource/samsung_pwm.h>
> > > +
> > > +#ifdef CONFIG_SAMSUNG_DEV_PWM
> > > +extern void samsung_pwm_set_platdata(struct samsung_pwm_variant
> > > *pd);
> > 
> > nit: 'extern' is implicit for function declarations, it could be
> > omitted here.
> 
> The extern kernel is used widely over the kernel (including headers in
> plat-samsung) and I prefer adding it for clarity.

s/extern kernel/extern keyword/

I guess it's time to sleep.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-21 22:22   ` Sylwester Nawrocki
@ 2013-07-21 22:25     ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 22:25 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Heiko Stübner, Mark Brown,
	Thierry Reding

On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > Since we now have a proper Samsung PWM clocksource driver in place,
> > we can proceed with further cleanup of PWM timers support on Samsung
> > SoCs.> 
> > This series attempts to achieve this goal by:
> >   1) fixing up few things in samsung_pwm_timer clocksource driver,
> >   2) moving remaining Samsung platforms to the new clocksource driver,
> >   3) removing old clocksource driver,
> >   4) adding new multiplatform- and DT-aware PWM driver,
> >   5) moving all Samsung platforms to use the new PWM driver,
> >   6) removing old PWM driver,
> >   7) removing all PWM-related code that is not used anymore.
> > 
> > Cleaning up the PWM driver is a bit tricky, because the design of
> > current driver makes it completely unsuitable for DT and
> > multiplatform and would require a heavy rework to make it usable,
> > breaking any existing Samsung PWM users by the way. To avoid any
> > breakage this series first renames the old driver, then adds new one
> > using original name, migrates all platforms to use it and then
> > finally removes the old driver.
> > 
> > See particular patches for more detailed descriptions.
> > 
> > [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> > SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> > PWM0 attached to a scope)]
> > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > 
> > [On S3C2440-based Mini2440 board]
> > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> 
> I have retested this series on top of v3.11-rc1 with pwm-backlight (and
> buzzer
> as the output :)) on Mini2440. It seems to work well - generated
> frequencies are correct. I'll check pulse widths with a scope tomorrow,
> as it's a bit late
> now. FWIW you can add to this series my:
> 
> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

Thanks. I hope we can finally get this series merged soon.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-21 22:25     ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-21 22:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > Since we now have a proper Samsung PWM clocksource driver in place,
> > we can proceed with further cleanup of PWM timers support on Samsung
> > SoCs.> 
> > This series attempts to achieve this goal by:
> >   1) fixing up few things in samsung_pwm_timer clocksource driver,
> >   2) moving remaining Samsung platforms to the new clocksource driver,
> >   3) removing old clocksource driver,
> >   4) adding new multiplatform- and DT-aware PWM driver,
> >   5) moving all Samsung platforms to use the new PWM driver,
> >   6) removing old PWM driver,
> >   7) removing all PWM-related code that is not used anymore.
> > 
> > Cleaning up the PWM driver is a bit tricky, because the design of
> > current driver makes it completely unsuitable for DT and
> > multiplatform and would require a heavy rework to make it usable,
> > breaking any existing Samsung PWM users by the way. To avoid any
> > breakage this series first renames the old driver, then adds new one
> > using original name, migrates all platforms to use it and then
> > finally removes the old driver.
> > 
> > See particular patches for more detailed descriptions.
> > 
> > [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> > SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> > PWM0 attached to a scope)]
> > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > 
> > [On S3C2440-based Mini2440 board]
> > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> 
> I have retested this series on top of v3.11-rc1 with pwm-backlight (and
> buzzer
> as the output :)) on Mini2440. It seems to work well - generated
> frequencies are correct. I'll check pulse widths with a scope tomorrow,
> as it's a bit late
> now. FWIW you can add to this series my:
> 
> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>

Thanks. I hope we can finally get this series merged soon.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* RE: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-21 22:25     ` Tomasz Figa
@ 2013-07-22  1:55       ` Kukjin Kim
  -1 siblings, 0 replies; 124+ messages in thread
From: Kukjin Kim @ 2013-07-22  1:55 UTC (permalink / raw)
  To: 'Tomasz Figa', 'Sylwester Nawrocki'
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm,
	'Arnd Bergmann', 'Olof Johansson',
	'Heiko Stübner', 'Mark Brown',
	'Thierry Reding'

Tomasz Figa wrote:
> 
> On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > Since we now have a proper Samsung PWM clocksource driver in place,
> > > we can proceed with further cleanup of PWM timers support on Samsung
> > > SoCs.>
> > > This series attempts to achieve this goal by:
> > >   1) fixing up few things in samsung_pwm_timer clocksource driver,
> > >   2) moving remaining Samsung platforms to the new clocksource driver,
> > >   3) removing old clocksource driver,
> > >   4) adding new multiplatform- and DT-aware PWM driver,
> > >   5) moving all Samsung platforms to use the new PWM driver,
> > >   6) removing old PWM driver,
> > >   7) removing all PWM-related code that is not used anymore.
> > >
> > > Cleaning up the PWM driver is a bit tricky, because the design of
> > > current driver makes it completely unsuitable for DT and
> > > multiplatform and would require a heavy rework to make it usable,
> > > breaking any existing Samsung PWM users by the way. To avoid any
> > > breakage this series first renames the old driver, then adds new one
> > > using original name, migrates all platforms to use it and then
> > > finally removes the old driver.
> > >
> > > See particular patches for more detailed descriptions.
> > >
> > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> > > SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> > > PWM0 attached to a scope)]
> > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > >
> > > [On S3C2440-based Mini2440 board]
> > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> >
> > I have retested this series on top of v3.11-rc1 with pwm-backlight (and
> > buzzer
> > as the output :)) on Mini2440. It seems to work well - generated
> > frequencies are correct. I'll check pulse widths with a scope tomorrow,
> > as it's a bit late
> > now. FWIW you can add to this series my:
> >
> > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> 
> Thanks. I hope we can finally get this series merged soon.
> 
Yes, this whole patches look good to me, and I'd like to take this whole
patches into the samsung tree...but need to get any response from PWM guy,
Thierry Reding. Let's wait for his response...

Thanks,
Kukjin


^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-22  1:55       ` Kukjin Kim
  0 siblings, 0 replies; 124+ messages in thread
From: Kukjin Kim @ 2013-07-22  1:55 UTC (permalink / raw)
  To: linux-arm-kernel

Tomasz Figa wrote:
> 
> On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > Since we now have a proper Samsung PWM clocksource driver in place,
> > > we can proceed with further cleanup of PWM timers support on Samsung
> > > SoCs.>
> > > This series attempts to achieve this goal by:
> > >   1) fixing up few things in samsung_pwm_timer clocksource driver,
> > >   2) moving remaining Samsung platforms to the new clocksource driver,
> > >   3) removing old clocksource driver,
> > >   4) adding new multiplatform- and DT-aware PWM driver,
> > >   5) moving all Samsung platforms to use the new PWM driver,
> > >   6) removing old PWM driver,
> > >   7) removing all PWM-related code that is not used anymore.
> > >
> > > Cleaning up the PWM driver is a bit tricky, because the design of
> > > current driver makes it completely unsuitable for DT and
> > > multiplatform and would require a heavy rework to make it usable,
> > > breaking any existing Samsung PWM users by the way. To avoid any
> > > breakage this series first renames the old driver, then adds new one
> > > using original name, migrates all platforms to use it and then
> > > finally removes the old driver.
> > >
> > > See particular patches for more detailed descriptions.
> > >
> > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> > > SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> > > PWM0 attached to a scope)]
> > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > >
> > > [On S3C2440-based Mini2440 board]
> > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> >
> > I have retested this series on top of v3.11-rc1 with pwm-backlight (and
> > buzzer
> > as the output :)) on Mini2440. It seems to work well - generated
> > frequencies are correct. I'll check pulse widths with a scope tomorrow,
> > as it's a bit late
> > now. FWIW you can add to this series my:
> >
> > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> 
> Thanks. I hope we can finally get this series merged soon.
> 
Yes, this whole patches look good to me, and I'd like to take this whole
patches into the samsung tree...but need to get any response from PWM guy,
Thierry Reding. Let's wait for his response...

Thanks,
Kukjin

^ permalink raw reply	[flat|nested] 124+ messages in thread

* RE: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-21 22:25     ` Tomasz Figa
@ 2013-07-22  2:01       ` Kukjin Kim
  -1 siblings, 0 replies; 124+ messages in thread
From: Kukjin Kim @ 2013-07-22  2:01 UTC (permalink / raw)
  To: 'Kukjin Kim', 'Tomasz Figa',
	'Sylwester Nawrocki'
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm,
	'Arnd Bergmann', 'Olof Johansson',
	'Heiko Stübner', 'Mark Brown',
	'Thierry Reding'

Kukjin Kim wrote:
> 
> Tomasz Figa wrote:
> >
> > On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > > Since we now have a proper Samsung PWM clocksource driver in place,
> > > > we can proceed with further cleanup of PWM timers support on Samsung
> > > > SoCs.>
> > > > This series attempts to achieve this goal by:
> > > >   1) fixing up few things in samsung_pwm_timer clocksource driver,
> > > >   2) moving remaining Samsung platforms to the new clocksource
> driver,
> > > >   3) removing old clocksource driver,
> > > >   4) adding new multiplatform- and DT-aware PWM driver,
> > > >   5) moving all Samsung platforms to use the new PWM driver,
> > > >   6) removing old PWM driver,
> > > >   7) removing all PWM-related code that is not used anymore.
> > > >
> > > > Cleaning up the PWM driver is a bit tricky, because the design of
> > > > current driver makes it completely unsuitable for DT and
> > > > multiplatform and would require a heavy rework to make it usable,
> > > > breaking any existing Samsung PWM users by the way. To avoid any
> > > > breakage this series first renames the old driver, then adds new one
> > > > using original name, migrates all platforms to use it and then
> > > > finally removes the old driver.
> > > >
> > > > See particular patches for more detailed descriptions.
> > > >
> > > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> > > > SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> > > > PWM0 attached to a scope)]
> > > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > >
> > > > [On S3C2440-based Mini2440 board]
> > > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> > >
> > > I have retested this series on top of v3.11-rc1 with pwm-backlight
> (and
> > > buzzer
> > > as the output :)) on Mini2440. It seems to work well - generated
> > > frequencies are correct. I'll check pulse widths with a scope
tomorrow,
> > > as it's a bit late
> > > now. FWIW you can add to this series my:
> > >
> > > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> >
> > Thanks. I hope we can finally get this series merged soon.
> >
> Yes, this whole patches look good to me, and I'd like to take this whole
> patches into the samsung tree...but need to get any response from PWM guy,
> Thierry Reding. Let's wait for his response...
> 
To be clarify, because his ack was on v3 and I remember he had a comment. So
would be better if we could get his ack on pwm change again.

Thanks,
Kukjin

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-22  2:01       ` Kukjin Kim
  0 siblings, 0 replies; 124+ messages in thread
From: Kukjin Kim @ 2013-07-22  2:01 UTC (permalink / raw)
  To: linux-arm-kernel

Kukjin Kim wrote:
> 
> Tomasz Figa wrote:
> >
> > On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > > Since we now have a proper Samsung PWM clocksource driver in place,
> > > > we can proceed with further cleanup of PWM timers support on Samsung
> > > > SoCs.>
> > > > This series attempts to achieve this goal by:
> > > >   1) fixing up few things in samsung_pwm_timer clocksource driver,
> > > >   2) moving remaining Samsung platforms to the new clocksource
> driver,
> > > >   3) removing old clocksource driver,
> > > >   4) adding new multiplatform- and DT-aware PWM driver,
> > > >   5) moving all Samsung platforms to use the new PWM driver,
> > > >   6) removing old PWM driver,
> > > >   7) removing all PWM-related code that is not used anymore.
> > > >
> > > > Cleaning up the PWM driver is a bit tricky, because the design of
> > > > current driver makes it completely unsuitable for DT and
> > > > multiplatform and would require a heavy rework to make it usable,
> > > > breaking any existing Samsung PWM users by the way. To avoid any
> > > > breakage this series first renames the old driver, then adds new one
> > > > using original name, migrates all platforms to use it and then
> > > > finally removes the old driver.
> > > >
> > > > See particular patches for more detailed descriptions.
> > > >
> > > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> > > > SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> > > > PWM0 attached to a scope)]
> > > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > >
> > > > [On S3C2440-based Mini2440 board]
> > > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> > >
> > > I have retested this series on top of v3.11-rc1 with pwm-backlight
> (and
> > > buzzer
> > > as the output :)) on Mini2440. It seems to work well - generated
> > > frequencies are correct. I'll check pulse widths with a scope
tomorrow,
> > > as it's a bit late
> > > now. FWIW you can add to this series my:
> > >
> > > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> >
> > Thanks. I hope we can finally get this series merged soon.
> >
> Yes, this whole patches look good to me, and I'd like to take this whole
> patches into the samsung tree...but need to get any response from PWM guy,
> Thierry Reding. Let's wait for his response...
> 
To be clarify, because his ack was on v3 and I remember he had a comment. So
would be better if we could get his ack on pwm change again.

Thanks,
Kukjin

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22  3:50     ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:50 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> PWM channel 4 has its autoreload bit located at different position. This
> patch fixes the driver to account for that.
> 
> This fixes a problem with the clocksource hanging after it overflows because
> it is not reloaded any more.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 3fa5b07..e238fb0 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -47,7 +47,8 @@
>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
> +						+ (((chan) < 5) ? 3 : 2)))

This macro is not readable. Please, fix it up with a comment please.

>  
>  DEFINE_SPINLOCK(samsung_pwm_lock);
>  EXPORT_SYMBOL(samsung_pwm_lock);
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-22  3:50     ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> PWM channel 4 has its autoreload bit located at different position. This
> patch fixes the driver to account for that.
> 
> This fixes a problem with the clocksource hanging after it overflows because
> it is not reloaded any more.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 3fa5b07..e238fb0 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -47,7 +47,8 @@
>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
> +						+ (((chan) < 5) ? 3 : 2)))

This macro is not readable. Please, fix it up with a comment please.

>  
>  DEFINE_SPINLOCK(samsung_pwm_lock);
>  EXPORT_SYMBOL(samsung_pwm_lock);
> 


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22  3:56     ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:56 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> In case of Samsung PWM timer, clocksource MMIO can not be used, because
> custom suspend/resume callbacks are required.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---

Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Please in the future Cc me and Thomas Gleixner (clocksource/clockevent
maintainers).

Thanks
  -- Daniel

>  drivers/clocksource/Kconfig             |  1 -
>  drivers/clocksource/samsung_pwm_timer.c | 19 +++++++++++++++----
>  2 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index b7b9b04..41c6946 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -99,7 +99,6 @@ config CLKSRC_EXYNOS_MCT
>  
>  config CLKSRC_SAMSUNG_PWM
>  	bool
> -	select CLKSRC_MMIO
>  	help
>  	  This is a new clocksource driver for the PWM timer found in
>  	  Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 823279b..753ffec 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -288,6 +288,18 @@ static void __init samsung_clockevent_init(void)
>  	}
>  }
>  
> +static cycle_t samsung_clocksource_read(struct clocksource *c)
> +{
> +	return ~readl_relaxed(pwm.source_reg);
> +}
> +
> +static struct clocksource samsung_clocksource = {
> +	.name		= "samsung_clocksource_timer",
> +	.rating		= 250,
> +	.read		= samsung_clocksource_read,
> +	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
>  /*
>   * Override the global weak sched_clock symbol with this
>   * local implementation which uses the clocksource to get some
> @@ -297,7 +309,7 @@ static void __init samsung_clockevent_init(void)
>   */
>  static u32 notrace samsung_read_sched_clock(void)
>  {
> -	return ~__raw_readl(pwm.source_reg);
> +	return samsung_clocksource_read(NULL);
>  }
>  
>  static void __init samsung_clocksource_init(void)
> @@ -324,9 +336,8 @@ static void __init samsung_clocksource_init(void)
>  	setup_sched_clock(samsung_read_sched_clock,
>  						pwm.variant.bits, clock_rate);
>  
> -	ret = clocksource_mmio_init(pwm.source_reg, "samsung_clocksource_timer",
> -					clock_rate, 250, pwm.variant.bits,
> -					clocksource_mmio_readl_down);
> +	samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits);
> +	ret = clocksource_register_hz(&samsung_clocksource, clock_rate);
>  	if (ret)
>  		panic("samsung_clocksource_timer: can't register clocksource\n");
>  }
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
@ 2013-07-22  3:56     ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> In case of Samsung PWM timer, clocksource MMIO can not be used, because
> custom suspend/resume callbacks are required.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---

Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Please in the future Cc me and Thomas Gleixner (clocksource/clockevent
maintainers).

Thanks
  -- Daniel

>  drivers/clocksource/Kconfig             |  1 -
>  drivers/clocksource/samsung_pwm_timer.c | 19 +++++++++++++++----
>  2 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index b7b9b04..41c6946 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -99,7 +99,6 @@ config CLKSRC_EXYNOS_MCT
>  
>  config CLKSRC_SAMSUNG_PWM
>  	bool
> -	select CLKSRC_MMIO
>  	help
>  	  This is a new clocksource driver for the PWM timer found in
>  	  Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 823279b..753ffec 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -288,6 +288,18 @@ static void __init samsung_clockevent_init(void)
>  	}
>  }
>  
> +static cycle_t samsung_clocksource_read(struct clocksource *c)
> +{
> +	return ~readl_relaxed(pwm.source_reg);
> +}
> +
> +static struct clocksource samsung_clocksource = {
> +	.name		= "samsung_clocksource_timer",
> +	.rating		= 250,
> +	.read		= samsung_clocksource_read,
> +	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
>  /*
>   * Override the global weak sched_clock symbol with this
>   * local implementation which uses the clocksource to get some
> @@ -297,7 +309,7 @@ static void __init samsung_clockevent_init(void)
>   */
>  static u32 notrace samsung_read_sched_clock(void)
>  {
> -	return ~__raw_readl(pwm.source_reg);
> +	return samsung_clocksource_read(NULL);
>  }
>  
>  static void __init samsung_clocksource_init(void)
> @@ -324,9 +336,8 @@ static void __init samsung_clocksource_init(void)
>  	setup_sched_clock(samsung_read_sched_clock,
>  						pwm.variant.bits, clock_rate);
>  
> -	ret = clocksource_mmio_init(pwm.source_reg, "samsung_clocksource_timer",
> -					clock_rate, 250, pwm.variant.bits,
> -					clocksource_mmio_readl_down);
> +	samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits);
> +	ret = clocksource_register_hz(&samsung_clocksource, clock_rate);
>  	if (ret)
>  		panic("samsung_clocksource_timer: can't register clocksource\n");
>  }
> 


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 05/20] clocksource: samsung_pwm_timer: Handle suspend/resume correctly
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22  3:57     ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:57 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding, Thomas Gleixner

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> Current suspend/resume handling of the driver was broken, because:
>  - periodic timer was being enabled in CLOCK_EVT_MODE_RESUME mode, which
>    does not seem to be correct behavior looking at other platforms,
>  - PWM divisors need to be restored, but they were not,
>  - clockevent interrupt mask needs to be restored, but it was not,
>  - clocksource was being restored in clockevent resume callback.
> 
> This patch fixes issues mentioned above, making suspend/resume handling
> in the driver correct.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

>  drivers/clocksource/samsung_pwm_timer.c | 42 ++++++++++++++++++++++-----------
>  1 file changed, 28 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 753ffec..282e0e2 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -197,17 +197,6 @@ static int samsung_set_next_event(unsigned long cycles,
>  	return 0;
>  }
>  
> -static void samsung_timer_resume(void)
> -{
> -	/* event timer restart */
> -	samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
> -	samsung_time_start(pwm.event_id, true);
> -
> -	/* source timer restart */
> -	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
> -	samsung_time_start(pwm.source_id, true);
> -}
> -
>  static void samsung_set_mode(enum clock_event_mode mode,
>  				struct clock_event_device *evt)
>  {
> @@ -224,20 +213,29 @@ static void samsung_set_mode(enum clock_event_mode mode,
>  
>  	case CLOCK_EVT_MODE_UNUSED:
>  	case CLOCK_EVT_MODE_SHUTDOWN:
> -		break;
> -
>  	case CLOCK_EVT_MODE_RESUME:
> -		samsung_timer_resume();
>  		break;
>  	}
>  }
>  
> +static void samsung_clockevent_resume(struct clock_event_device *cev)
> +{
> +	samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div);
> +	samsung_timer_set_divisor(pwm.event_id, pwm.tdiv);
> +
> +	if (pwm.variant.has_tint_cstat) {
> +		u32 mask = (1 << pwm.event_id);
> +		writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT);
> +	}
> +}
> +
>  static struct clock_event_device time_event_device = {
>  	.name		= "samsung_event_timer",
>  	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
>  	.rating		= 200,
>  	.set_next_event	= samsung_set_next_event,
>  	.set_mode	= samsung_set_mode,
> +	.resume		= samsung_clockevent_resume,
>  };
>  
>  static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
> @@ -288,6 +286,20 @@ static void __init samsung_clockevent_init(void)
>  	}
>  }
>  
> +static void samsung_clocksource_suspend(struct clocksource *cs)
> +{
> +	samsung_time_stop(pwm.source_id);
> +}
> +
> +static void samsung_clocksource_resume(struct clocksource *cs)
> +{
> +	samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div);
> +	samsung_timer_set_divisor(pwm.source_id, pwm.tdiv);
> +
> +	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
> +	samsung_time_start(pwm.source_id, true);
> +}
> +
>  static cycle_t samsung_clocksource_read(struct clocksource *c)
>  {
>  	return ~readl_relaxed(pwm.source_reg);
> @@ -297,6 +309,8 @@ static struct clocksource samsung_clocksource = {
>  	.name		= "samsung_clocksource_timer",
>  	.rating		= 250,
>  	.read		= samsung_clocksource_read,
> +	.suspend	= samsung_clocksource_suspend,
> +	.resume		= samsung_clocksource_resume,
>  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
>  };
>  
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 05/20] clocksource: samsung_pwm_timer: Handle suspend/resume correctly
@ 2013-07-22  3:57     ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> Current suspend/resume handling of the driver was broken, because:
>  - periodic timer was being enabled in CLOCK_EVT_MODE_RESUME mode, which
>    does not seem to be correct behavior looking at other platforms,
>  - PWM divisors need to be restored, but they were not,
>  - clockevent interrupt mask needs to be restored, but it was not,
>  - clocksource was being restored in clockevent resume callback.
> 
> This patch fixes issues mentioned above, making suspend/resume handling
> in the driver correct.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

>  drivers/clocksource/samsung_pwm_timer.c | 42 ++++++++++++++++++++++-----------
>  1 file changed, 28 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 753ffec..282e0e2 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -197,17 +197,6 @@ static int samsung_set_next_event(unsigned long cycles,
>  	return 0;
>  }
>  
> -static void samsung_timer_resume(void)
> -{
> -	/* event timer restart */
> -	samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
> -	samsung_time_start(pwm.event_id, true);
> -
> -	/* source timer restart */
> -	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
> -	samsung_time_start(pwm.source_id, true);
> -}
> -
>  static void samsung_set_mode(enum clock_event_mode mode,
>  				struct clock_event_device *evt)
>  {
> @@ -224,20 +213,29 @@ static void samsung_set_mode(enum clock_event_mode mode,
>  
>  	case CLOCK_EVT_MODE_UNUSED:
>  	case CLOCK_EVT_MODE_SHUTDOWN:
> -		break;
> -
>  	case CLOCK_EVT_MODE_RESUME:
> -		samsung_timer_resume();
>  		break;
>  	}
>  }
>  
> +static void samsung_clockevent_resume(struct clock_event_device *cev)
> +{
> +	samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div);
> +	samsung_timer_set_divisor(pwm.event_id, pwm.tdiv);
> +
> +	if (pwm.variant.has_tint_cstat) {
> +		u32 mask = (1 << pwm.event_id);
> +		writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT);
> +	}
> +}
> +
>  static struct clock_event_device time_event_device = {
>  	.name		= "samsung_event_timer",
>  	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
>  	.rating		= 200,
>  	.set_next_event	= samsung_set_next_event,
>  	.set_mode	= samsung_set_mode,
> +	.resume		= samsung_clockevent_resume,
>  };
>  
>  static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
> @@ -288,6 +286,20 @@ static void __init samsung_clockevent_init(void)
>  	}
>  }
>  
> +static void samsung_clocksource_suspend(struct clocksource *cs)
> +{
> +	samsung_time_stop(pwm.source_id);
> +}
> +
> +static void samsung_clocksource_resume(struct clocksource *cs)
> +{
> +	samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div);
> +	samsung_timer_set_divisor(pwm.source_id, pwm.tdiv);
> +
> +	samsung_time_setup(pwm.source_id, pwm.tcnt_max);
> +	samsung_time_start(pwm.source_id, true);
> +}
> +
>  static cycle_t samsung_clocksource_read(struct clocksource *c)
>  {
>  	return ~readl_relaxed(pwm.source_reg);
> @@ -297,6 +309,8 @@ static struct clocksource samsung_clocksource = {
>  	.name		= "samsung_clocksource_timer",
>  	.rating		= 250,
>  	.read		= samsung_clocksource_read,
> +	.suspend	= samsung_clocksource_suspend,
> +	.resume		= samsung_clocksource_resume,
>  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
>  };
>  
> 


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 09/20] ARM: SAMSUNG: Move all platforms to new clocksource driver
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22  3:59     ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:59 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding, Thomas Gleixner

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> This patch moves all Samsung platforms using PWM clocksource from legacy
> samsung-time to new samsung-pwm-timer driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---

Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>

>  arch/arm/Kconfig                | 10 +++++-----
>  arch/arm/mach-s3c24xx/Kconfig   |  6 ------
>  arch/arm/mach-s3c24xx/common.c  | 16 ++++++++++++++++
>  arch/arm/mach-s3c64xx/Kconfig   |  2 --
>  arch/arm/mach-s3c64xx/common.c  | 21 +++++++++++++++++----
>  arch/arm/mach-s5p64x0/Kconfig   |  2 --
>  arch/arm/mach-s5p64x0/common.c  | 17 +++++++++++++++++
>  arch/arm/mach-s5pc100/Kconfig   |  1 -
>  arch/arm/mach-s5pc100/common.c  | 17 +++++++++++++++++
>  arch/arm/mach-s5pv210/Kconfig   |  1 -
>  arch/arm/mach-s5pv210/common.c  | 17 +++++++++++++++++
>  arch/arm/plat-samsung/s5p-irq.c |  3 ---
>  12 files changed, 89 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index ba412e0..486ab0a 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -700,7 +700,7 @@ config ARCH_S3C24XX
>  	select ARCH_HAS_CPUFREQ
>  	select ARCH_REQUIRE_GPIOLIB
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
>  	select HAVE_CLK
> @@ -723,7 +723,7 @@ config ARCH_S3C64XX
>  	select ARCH_REQUIRE_GPIOLIB
>  	select ARM_VIC
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V6
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> @@ -748,7 +748,7 @@ config ARCH_S3C64XX
>  config ARCH_S5P64X0
>  	bool "Samsung S5P6440 S5P6450"
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V6
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> @@ -767,7 +767,7 @@ config ARCH_S5PC100
>  	bool "Samsung S5PC100"
>  	select ARCH_REQUIRE_GPIOLIB
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V7
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> @@ -787,7 +787,7 @@ config ARCH_S5PV210
>  	select ARCH_HAS_HOLES_MEMORYMODEL
>  	select ARCH_SPARSEMEM_ENABLE
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V7
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
> index 6d9252e..b8ec0ec 100644
> --- a/arch/arm/mach-s3c24xx/Kconfig
> +++ b/arch/arm/mach-s3c24xx/Kconfig
> @@ -30,7 +30,6 @@ config CPU_S3C2410
>  	select S3C2410_CLOCK
>  	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
>  	select S3C2410_PM if PM
> -	select SAMSUNG_HRT
>  	select SAMSUNG_WDT_RESET
>  	help
>  	  Support for S3C2410 and S3C2410A family from the S3C24XX line
> @@ -42,7 +41,6 @@ config CPU_S3C2412
>  	select CPU_LLSERIAL_S3C2440
>  	select S3C2412_DMA if S3C24XX_DMA
>  	select S3C2412_PM if PM
> -	select SAMSUNG_HRT
>  	help
>  	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
>  
> @@ -54,7 +52,6 @@ config CPU_S3C2416
>  	select S3C2443_COMMON
>  	select S3C2443_DMA if S3C24XX_DMA
>  	select SAMSUNG_CLKSRC
> -	select SAMSUNG_HRT
>  	help
>  	  Support for the S3C2416 SoC from the S3C24XX line
>  
> @@ -65,7 +62,6 @@ config CPU_S3C2440
>  	select S3C2410_CLOCK
>  	select S3C2410_PM if PM
>  	select S3C2440_DMA if S3C24XX_DMA
> -	select SAMSUNG_HRT
>  	help
>  	  Support for S3C2440 Samsung Mobile CPU based systems.
>  
> @@ -75,7 +71,6 @@ config CPU_S3C2442
>  	select CPU_LLSERIAL_S3C2440
>  	select S3C2410_CLOCK
>  	select S3C2410_PM if PM
> -	select SAMSUNG_HRT
>  	help
>  	  Support for S3C2442 Samsung Mobile CPU based systems.
>  
> @@ -91,7 +86,6 @@ config CPU_S3C2443
>  	select S3C2443_COMMON
>  	select S3C2443_DMA if S3C24XX_DMA
>  	select SAMSUNG_CLKSRC
> -	select SAMSUNG_HRT
>  	help
>  	  Support for the S3C2443 SoC from the S3C24XX line
>  
> diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
> index e5e7d7d..457261c 100644
> --- a/arch/arm/mach-s3c24xx/common.c
> +++ b/arch/arm/mach-s3c24xx/common.c
> @@ -245,6 +245,22 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
>  	samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
>  }
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s3c24xx_pwm_variant);
> +}
> +
>  /* Serial port registrations */
>  
>  #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
> index 2057853..041da51 100644
> --- a/arch/arm/mach-s3c64xx/Kconfig
> +++ b/arch/arm/mach-s3c64xx/Kconfig
> @@ -17,13 +17,11 @@ config PLAT_S3C64XX
>  # Configuration options for the S3C6410 CPU
>  
>  config CPU_S3C6400
> -	select SAMSUNG_HRT
>  	bool
>  	help
>  	  Enable S3C6400 CPU support
>  
>  config CPU_S3C6410
> -	select SAMSUNG_HRT
>  	bool
>  	help
>  	  Enable S3C6410 CPU support
> diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
> index ca05e61..73d79cf 100644
> --- a/arch/arm/mach-s3c64xx/common.c
> +++ b/arch/arm/mach-s3c64xx/common.c
> @@ -43,7 +43,6 @@
>  #include <plat/pm.h>
>  #include <plat/gpio-cfg.h>
>  #include <plat/irq-uart.h>
> -#include <plat/irq-vic-timer.h>
>  #include <plat/pwm-core.h>
>  #include <plat/regs-irqtype.h>
>  #include <plat/regs-serial.h>
> @@ -158,6 +157,23 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = {
>  	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s3c64xx_pwm_variant);
> +}
> +
>  /* read cpu identification code */
>  
>  void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
> @@ -206,9 +222,6 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
>  	/* initialise the pair of VICs */
>  	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
>  	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
> -
> -	/* add the timer sub-irqs */
> -	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
>  }
>  
>  #define eint_offset(irq)	((irq) - IRQ_EINT(0))
> diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
> index 5a707bd..bb2111b 100644
> --- a/arch/arm/mach-s5p64x0/Kconfig
> +++ b/arch/arm/mach-s5p64x0/Kconfig
> @@ -11,14 +11,12 @@ config CPU_S5P6440
>  	bool
>  	select S5P_SLEEP if PM
>  	select SAMSUNG_DMADEV
> -	select SAMSUNG_HRT
>  	select SAMSUNG_WAKEMASK if PM
>  	help
>  	  Enable S5P6440 CPU support
>  
>  config CPU_S5P6450
>  	bool
> -	select SAMSUNG_HRT
>  	select S5P_SLEEP if PM
>  	select SAMSUNG_DMADEV
>  	select SAMSUNG_WAKEMASK if PM
> diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
> index 49687f2..42e14f2 100644
> --- a/arch/arm/mach-s5p64x0/common.c
> +++ b/arch/arm/mach-s5p64x0/common.c
> @@ -166,6 +166,23 @@ static struct samsung_pwm_variant s5p64x0_pwm_variant = {
>  	.tclk_mask	= 0,
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s5p64x0_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s5p64x0_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s5p64x0_pwm_variant);
> +}
> +
>  /*
>   * s5p64x0_map_io
>   *
> diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
> index 2f456a4..15170be 100644
> --- a/arch/arm/mach-s5pc100/Kconfig
> +++ b/arch/arm/mach-s5pc100/Kconfig
> @@ -11,7 +11,6 @@ config CPU_S5PC100
>  	bool
>  	select S5P_EXT_INT
>  	select SAMSUNG_DMADEV
> -	select SAMSUNG_HRT
>  	help
>  	  Enable S5PC100 CPU support
>  
> diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
> index e0600af..c5a8eea 100644
> --- a/arch/arm/mach-s5pc100/common.c
> +++ b/arch/arm/mach-s5pc100/common.c
> @@ -141,6 +141,23 @@ static struct samsung_pwm_variant s5pc100_pwm_variant = {
>  	.tclk_mask	= (1 << 5),
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s5pc100_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s5pc100_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s5pc100_pwm_variant);
> +}
> +
>  /*
>   * s5pc100_map_io
>   *
> diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
> index 0963283..caaedaf 100644
> --- a/arch/arm/mach-s5pv210/Kconfig
> +++ b/arch/arm/mach-s5pv210/Kconfig
> @@ -15,7 +15,6 @@ config CPU_S5PV210
>  	select S5P_PM if PM
>  	select S5P_SLEEP if PM
>  	select SAMSUNG_DMADEV
> -	select SAMSUNG_HRT
>  	help
>  	  Enable S5PV210 CPU support
>  
> diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
> index 306b29a..26027a2 100644
> --- a/arch/arm/mach-s5pv210/common.c
> +++ b/arch/arm/mach-s5pv210/common.c
> @@ -157,6 +157,23 @@ static struct samsung_pwm_variant s5pv210_pwm_variant = {
>  	.tclk_mask	= (1 << 5),
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s5pv210_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s5pv210_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s5pv210_pwm_variant);
> +}
> +
>  /*
>   * s5pv210_map_io
>   *
> diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
> index ff1a760..6729cb2 100644
> --- a/arch/arm/plat-samsung/s5p-irq.c
> +++ b/arch/arm/plat-samsung/s5p-irq.c
> @@ -19,7 +19,6 @@
>  #include <mach/map.h>
>  #include <plat/regs-timer.h>
>  #include <plat/cpu.h>
> -#include <plat/irq-vic-timer.h>
>  
>  void __init s5p_init_irq(u32 *vic, u32 num_vic)
>  {
> @@ -30,6 +29,4 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
>  	for (irq = 0; irq < num_vic; irq++)
>  		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
>  #endif
> -
> -	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
>  }
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 09/20] ARM: SAMSUNG: Move all platforms to new clocksource driver
@ 2013-07-22  3:59     ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22  3:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> This patch moves all Samsung platforms using PWM clocksource from legacy
> samsung-time to new samsung-pwm-timer driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---

Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>

>  arch/arm/Kconfig                | 10 +++++-----
>  arch/arm/mach-s3c24xx/Kconfig   |  6 ------
>  arch/arm/mach-s3c24xx/common.c  | 16 ++++++++++++++++
>  arch/arm/mach-s3c64xx/Kconfig   |  2 --
>  arch/arm/mach-s3c64xx/common.c  | 21 +++++++++++++++++----
>  arch/arm/mach-s5p64x0/Kconfig   |  2 --
>  arch/arm/mach-s5p64x0/common.c  | 17 +++++++++++++++++
>  arch/arm/mach-s5pc100/Kconfig   |  1 -
>  arch/arm/mach-s5pc100/common.c  | 17 +++++++++++++++++
>  arch/arm/mach-s5pv210/Kconfig   |  1 -
>  arch/arm/mach-s5pv210/common.c  | 17 +++++++++++++++++
>  arch/arm/plat-samsung/s5p-irq.c |  3 ---
>  12 files changed, 89 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index ba412e0..486ab0a 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -700,7 +700,7 @@ config ARCH_S3C24XX
>  	select ARCH_HAS_CPUFREQ
>  	select ARCH_REQUIRE_GPIOLIB
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
>  	select HAVE_CLK
> @@ -723,7 +723,7 @@ config ARCH_S3C64XX
>  	select ARCH_REQUIRE_GPIOLIB
>  	select ARM_VIC
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V6
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> @@ -748,7 +748,7 @@ config ARCH_S3C64XX
>  config ARCH_S5P64X0
>  	bool "Samsung S5P6440 S5P6450"
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V6
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> @@ -767,7 +767,7 @@ config ARCH_S5PC100
>  	bool "Samsung S5PC100"
>  	select ARCH_REQUIRE_GPIOLIB
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V7
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> @@ -787,7 +787,7 @@ config ARCH_S5PV210
>  	select ARCH_HAS_HOLES_MEMORYMODEL
>  	select ARCH_SPARSEMEM_ENABLE
>  	select CLKDEV_LOOKUP
> -	select CLKSRC_MMIO
> +	select CLKSRC_SAMSUNG_PWM
>  	select CPU_V7
>  	select GENERIC_CLOCKEVENTS
>  	select GPIO_SAMSUNG
> diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
> index 6d9252e..b8ec0ec 100644
> --- a/arch/arm/mach-s3c24xx/Kconfig
> +++ b/arch/arm/mach-s3c24xx/Kconfig
> @@ -30,7 +30,6 @@ config CPU_S3C2410
>  	select S3C2410_CLOCK
>  	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
>  	select S3C2410_PM if PM
> -	select SAMSUNG_HRT
>  	select SAMSUNG_WDT_RESET
>  	help
>  	  Support for S3C2410 and S3C2410A family from the S3C24XX line
> @@ -42,7 +41,6 @@ config CPU_S3C2412
>  	select CPU_LLSERIAL_S3C2440
>  	select S3C2412_DMA if S3C24XX_DMA
>  	select S3C2412_PM if PM
> -	select SAMSUNG_HRT
>  	help
>  	  Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
>  
> @@ -54,7 +52,6 @@ config CPU_S3C2416
>  	select S3C2443_COMMON
>  	select S3C2443_DMA if S3C24XX_DMA
>  	select SAMSUNG_CLKSRC
> -	select SAMSUNG_HRT
>  	help
>  	  Support for the S3C2416 SoC from the S3C24XX line
>  
> @@ -65,7 +62,6 @@ config CPU_S3C2440
>  	select S3C2410_CLOCK
>  	select S3C2410_PM if PM
>  	select S3C2440_DMA if S3C24XX_DMA
> -	select SAMSUNG_HRT
>  	help
>  	  Support for S3C2440 Samsung Mobile CPU based systems.
>  
> @@ -75,7 +71,6 @@ config CPU_S3C2442
>  	select CPU_LLSERIAL_S3C2440
>  	select S3C2410_CLOCK
>  	select S3C2410_PM if PM
> -	select SAMSUNG_HRT
>  	help
>  	  Support for S3C2442 Samsung Mobile CPU based systems.
>  
> @@ -91,7 +86,6 @@ config CPU_S3C2443
>  	select S3C2443_COMMON
>  	select S3C2443_DMA if S3C24XX_DMA
>  	select SAMSUNG_CLKSRC
> -	select SAMSUNG_HRT
>  	help
>  	  Support for the S3C2443 SoC from the S3C24XX line
>  
> diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
> index e5e7d7d..457261c 100644
> --- a/arch/arm/mach-s3c24xx/common.c
> +++ b/arch/arm/mach-s3c24xx/common.c
> @@ -245,6 +245,22 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
>  	samsung_pwm_set_platdata(&s3c24xx_pwm_variant);
>  }
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s3c24xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s3c24xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0, IRQ_TIMER1, IRQ_TIMER2, IRQ_TIMER3, IRQ_TIMER4,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s3c24xx_pwm_variant);
> +}
> +
>  /* Serial port registrations */
>  
>  #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
> index 2057853..041da51 100644
> --- a/arch/arm/mach-s3c64xx/Kconfig
> +++ b/arch/arm/mach-s3c64xx/Kconfig
> @@ -17,13 +17,11 @@ config PLAT_S3C64XX
>  # Configuration options for the S3C6410 CPU
>  
>  config CPU_S3C6400
> -	select SAMSUNG_HRT
>  	bool
>  	help
>  	  Enable S3C6400 CPU support
>  
>  config CPU_S3C6410
> -	select SAMSUNG_HRT
>  	bool
>  	help
>  	  Enable S3C6410 CPU support
> diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
> index ca05e61..73d79cf 100644
> --- a/arch/arm/mach-s3c64xx/common.c
> +++ b/arch/arm/mach-s3c64xx/common.c
> @@ -43,7 +43,6 @@
>  #include <plat/pm.h>
>  #include <plat/gpio-cfg.h>
>  #include <plat/irq-uart.h>
> -#include <plat/irq-vic-timer.h>
>  #include <plat/pwm-core.h>
>  #include <plat/regs-irqtype.h>
>  #include <plat/regs-serial.h>
> @@ -158,6 +157,23 @@ static struct samsung_pwm_variant s3c64xx_pwm_variant = {
>  	.tclk_mask	= (1 << 7) | (1 << 6) | (1 << 5),
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s3c64xx_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s3c64xx_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s3c64xx_pwm_variant);
> +}
> +
>  /* read cpu identification code */
>  
>  void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
> @@ -206,9 +222,6 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
>  	/* initialise the pair of VICs */
>  	vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
>  	vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
> -
> -	/* add the timer sub-irqs */
> -	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
>  }
>  
>  #define eint_offset(irq)	((irq) - IRQ_EINT(0))
> diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
> index 5a707bd..bb2111b 100644
> --- a/arch/arm/mach-s5p64x0/Kconfig
> +++ b/arch/arm/mach-s5p64x0/Kconfig
> @@ -11,14 +11,12 @@ config CPU_S5P6440
>  	bool
>  	select S5P_SLEEP if PM
>  	select SAMSUNG_DMADEV
> -	select SAMSUNG_HRT
>  	select SAMSUNG_WAKEMASK if PM
>  	help
>  	  Enable S5P6440 CPU support
>  
>  config CPU_S5P6450
>  	bool
> -	select SAMSUNG_HRT
>  	select S5P_SLEEP if PM
>  	select SAMSUNG_DMADEV
>  	select SAMSUNG_WAKEMASK if PM
> diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
> index 49687f2..42e14f2 100644
> --- a/arch/arm/mach-s5p64x0/common.c
> +++ b/arch/arm/mach-s5p64x0/common.c
> @@ -166,6 +166,23 @@ static struct samsung_pwm_variant s5p64x0_pwm_variant = {
>  	.tclk_mask	= 0,
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s5p64x0_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s5p64x0_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s5p64x0_pwm_variant);
> +}
> +
>  /*
>   * s5p64x0_map_io
>   *
> diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
> index 2f456a4..15170be 100644
> --- a/arch/arm/mach-s5pc100/Kconfig
> +++ b/arch/arm/mach-s5pc100/Kconfig
> @@ -11,7 +11,6 @@ config CPU_S5PC100
>  	bool
>  	select S5P_EXT_INT
>  	select SAMSUNG_DMADEV
> -	select SAMSUNG_HRT
>  	help
>  	  Enable S5PC100 CPU support
>  
> diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
> index e0600af..c5a8eea 100644
> --- a/arch/arm/mach-s5pc100/common.c
> +++ b/arch/arm/mach-s5pc100/common.c
> @@ -141,6 +141,23 @@ static struct samsung_pwm_variant s5pc100_pwm_variant = {
>  	.tclk_mask	= (1 << 5),
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s5pc100_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s5pc100_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s5pc100_pwm_variant);
> +}
> +
>  /*
>   * s5pc100_map_io
>   *
> diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
> index 0963283..caaedaf 100644
> --- a/arch/arm/mach-s5pv210/Kconfig
> +++ b/arch/arm/mach-s5pv210/Kconfig
> @@ -15,7 +15,6 @@ config CPU_S5PV210
>  	select S5P_PM if PM
>  	select S5P_SLEEP if PM
>  	select SAMSUNG_DMADEV
> -	select SAMSUNG_HRT
>  	help
>  	  Enable S5PV210 CPU support
>  
> diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
> index 306b29a..26027a2 100644
> --- a/arch/arm/mach-s5pv210/common.c
> +++ b/arch/arm/mach-s5pv210/common.c
> @@ -157,6 +157,23 @@ static struct samsung_pwm_variant s5pv210_pwm_variant = {
>  	.tclk_mask	= (1 << 5),
>  };
>  
> +void __init samsung_set_timer_source(unsigned int event, unsigned int source)
> +{
> +	s5pv210_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
> +	s5pv210_pwm_variant.output_mask &= ~(BIT(event) | BIT(source));
> +}
> +
> +void __init samsung_timer_init(void)
> +{
> +	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
> +		IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
> +		IRQ_TIMER3_VIC, IRQ_TIMER4_VIC,
> +	};
> +
> +	samsung_pwm_clocksource_init(S3C_VA_TIMER,
> +					timer_irqs, &s5pv210_pwm_variant);
> +}
> +
>  /*
>   * s5pv210_map_io
>   *
> diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c
> index ff1a760..6729cb2 100644
> --- a/arch/arm/plat-samsung/s5p-irq.c
> +++ b/arch/arm/plat-samsung/s5p-irq.c
> @@ -19,7 +19,6 @@
>  #include <mach/map.h>
>  #include <plat/regs-timer.h>
>  #include <plat/cpu.h>
> -#include <plat/irq-vic-timer.h>
>  
>  void __init s5p_init_irq(u32 *vic, u32 num_vic)
>  {
> @@ -30,6 +29,4 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
>  	for (irq = 0; irq < num_vic; irq++)
>  		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
>  #endif
> -
> -	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
>  }
> 


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-22  3:50     ` Daniel Lezcano
@ 2013-07-22  7:43       ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22  7:43 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > PWM channel 4 has its autoreload bit located at different position.
> > This patch fixes the driver to account for that.
> > 
> > This fixes a problem with the clocksource hanging after it overflows
> > because it is not reloaded any more.
> > 
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > ---
> > 
> >  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clocksource/samsung_pwm_timer.c
> > b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
> > 100644
> > --- a/drivers/clocksource/samsung_pwm_timer.c
> > +++ b/drivers/clocksource/samsung_pwm_timer.c
> > @@ -47,7 +47,8 @@
> > 
> >  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
> >  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
> >  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> > 
> > -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> > +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
> > +						+ (((chan) < 5) ? 3 : 2)))
> 
> This macro is not readable. Please, fix it up with a comment please.

/*
 * Channel 4 (logically 5 in TCON register) has different position
 * of autoreload bit.
 */
#define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) + 3))
#define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) + 2))
#define TCON_AUTORELOAD(chan)			((chan < 5) ? 
		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))

What do you think?

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-22  7:43       ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22  7:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > PWM channel 4 has its autoreload bit located at different position.
> > This patch fixes the driver to account for that.
> > 
> > This fixes a problem with the clocksource hanging after it overflows
> > because it is not reloaded any more.
> > 
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > ---
> > 
> >  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clocksource/samsung_pwm_timer.c
> > b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
> > 100644
> > --- a/drivers/clocksource/samsung_pwm_timer.c
> > +++ b/drivers/clocksource/samsung_pwm_timer.c
> > @@ -47,7 +47,8 @@
> > 
> >  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
> >  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
> >  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> > 
> > -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> > +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
> > +						+ (((chan) < 5) ? 3 : 2)))
> 
> This macro is not readable. Please, fix it up with a comment please.

/*
 * Channel 4 (logically 5 in TCON register) has different position
 * of autoreload bit.
 */
#define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) + 3))
#define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) + 2))
#define TCON_AUTORELOAD(chan)			((chan < 5) ? 
		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))

What do you think?

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  2013-07-22  3:56     ` Daniel Lezcano
@ 2013-07-22  7:47       ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22  7:47 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

Hi Daniel,

On Monday 22 of July 2013 05:56:16 Daniel Lezcano wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > In case of Samsung PWM timer, clocksource MMIO can not be used,
> > because
> > custom suspend/resume callbacks are required.
> > 
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > ---
> 
> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Thanks for review.

> Please in the future Cc me and Thomas Gleixner (clocksource/clockevent
> maintainers).

Oh, right, sorry. This series originally was not touching the clocksource 
driver and I just kept original recipient list.

Btw. Have you updated MAINTAINERS file? In latest linux-next I can still 
see only John Stultz and Thomas Gleixner as maintainers of 
drivers/clocksource.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
@ 2013-07-22  7:47       ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22  7:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On Monday 22 of July 2013 05:56:16 Daniel Lezcano wrote:
> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > In case of Samsung PWM timer, clocksource MMIO can not be used,
> > because
> > custom suspend/resume callbacks are required.
> > 
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > ---
> 
> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Thanks for review.

> Please in the future Cc me and Thomas Gleixner (clocksource/clockevent
> maintainers).

Oh, right, sorry. This series originally was not touching the clocksource 
driver and I just kept original recipient list.

Btw. Have you updated MAINTAINERS file? In latest linux-next I can still 
see only John Stultz and Thomas Gleixner as maintainers of 
drivers/clocksource.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-22  2:01       ` Kukjin Kim
@ 2013-07-22  7:49         ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22  7:49 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: 'Kukjin Kim', 'Sylwester Nawrocki',
	linux-samsung-soc, linux-arm-kernel, linux-pwm,
	'Arnd Bergmann', 'Olof Johansson',
	'Heiko Stübner', 'Mark Brown',
	'Thierry Reding'

On Monday 22 of July 2013 11:01:32 Kukjin Kim wrote:
> Kukjin Kim wrote:
> > Tomasz Figa wrote:
> > > On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > > > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > > > Since we now have a proper Samsung PWM clocksource driver in
> > > > > place,
> > > > > we can proceed with further cleanup of PWM timers support on
> > > > > Samsung
> > > > > SoCs.>
> > > > > 
> > > > > This series attempts to achieve this goal by:
> > > > >   1) fixing up few things in samsung_pwm_timer clocksource
> > > > >   driver,
> > > > >   2) moving remaining Samsung platforms to the new clocksource
> > 
> > driver,
> > 
> > > > >   3) removing old clocksource driver,
> > > > >   4) adding new multiplatform- and DT-aware PWM driver,
> > > > >   5) moving all Samsung platforms to use the new PWM driver,
> > > > >   6) removing old PWM driver,
> > > > >   7) removing all PWM-related code that is not used anymore.
> > > > > 
> > > > > Cleaning up the PWM driver is a bit tricky, because the design
> > > > > of
> > > > > current driver makes it completely unsuitable for DT and
> > > > > multiplatform and would require a heavy rework to make it
> > > > > usable,
> > > > > breaking any existing Samsung PWM users by the way. To avoid any
> > > > > breakage this series first renames the old driver, then adds new
> > > > > one
> > > > > using original name, migrates all platforms to use it and then
> > > > > finally removes the old driver.
> > > > > 
> > > > > See particular patches for more detailed descriptions.
> > > > > 
> > > > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with
> > > > > pwm-beeper,
> > > > > SMDK6410 with PWM backlight and Exynos4210-based Origen board
> > > > > (with
> > > > > PWM0 attached to a scope)]
> > > > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > > > 
> > > > > [On S3C2440-based Mini2440 board]
> > > > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> > > > 
> > > > I have retested this series on top of v3.11-rc1 with pwm-backlight
> > 
> > (and
> > 
> > > > buzzer
> > > > as the output :)) on Mini2440. It seems to work well - generated
> > > > frequencies are correct. I'll check pulse widths with a scope
> 
> tomorrow,
> 
> > > > as it's a bit late
> > > > now. FWIW you can add to this series my:
> > > > 
> > > > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > 
> > > Thanks. I hope we can finally get this series merged soon.
> > 
> > Yes, this whole patches look good to me, and I'd like to take this
> > whole patches into the samsung tree...but need to get any response
> > from PWM guy, Thierry Reding. Let's wait for his response...
> 
> To be clarify, because his ack was on v3 and I remember he had a
> comment. So would be better if we could get his ack on pwm change
> again.

Sure.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-22  7:49         ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 22 of July 2013 11:01:32 Kukjin Kim wrote:
> Kukjin Kim wrote:
> > Tomasz Figa wrote:
> > > On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > > > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > > > Since we now have a proper Samsung PWM clocksource driver in
> > > > > place,
> > > > > we can proceed with further cleanup of PWM timers support on
> > > > > Samsung
> > > > > SoCs.>
> > > > > 
> > > > > This series attempts to achieve this goal by:
> > > > >   1) fixing up few things in samsung_pwm_timer clocksource
> > > > >   driver,
> > > > >   2) moving remaining Samsung platforms to the new clocksource
> > 
> > driver,
> > 
> > > > >   3) removing old clocksource driver,
> > > > >   4) adding new multiplatform- and DT-aware PWM driver,
> > > > >   5) moving all Samsung platforms to use the new PWM driver,
> > > > >   6) removing old PWM driver,
> > > > >   7) removing all PWM-related code that is not used anymore.
> > > > > 
> > > > > Cleaning up the PWM driver is a bit tricky, because the design
> > > > > of
> > > > > current driver makes it completely unsuitable for DT and
> > > > > multiplatform and would require a heavy rework to make it
> > > > > usable,
> > > > > breaking any existing Samsung PWM users by the way. To avoid any
> > > > > breakage this series first renames the old driver, then adds new
> > > > > one
> > > > > using original name, migrates all platforms to use it and then
> > > > > finally removes the old driver.
> > > > > 
> > > > > See particular patches for more detailed descriptions.
> > > > > 
> > > > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with
> > > > > pwm-beeper,
> > > > > SMDK6410 with PWM backlight and Exynos4210-based Origen board
> > > > > (with
> > > > > PWM0 attached to a scope)]
> > > > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > > > 
> > > > > [On S3C2440-based Mini2440 board]
> > > > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> > > > 
> > > > I have retested this series on top of v3.11-rc1 with pwm-backlight
> > 
> > (and
> > 
> > > > buzzer
> > > > as the output :)) on Mini2440. It seems to work well - generated
> > > > frequencies are correct. I'll check pulse widths with a scope
> 
> tomorrow,
> 
> > > > as it's a bit late
> > > > now. FWIW you can add to this series my:
> > > > 
> > > > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > 
> > > Thanks. I hope we can finally get this series merged soon.
> > 
> > Yes, this whole patches look good to me, and I'd like to take this
> > whole patches into the samsung tree...but need to get any response
> > from PWM guy, Thierry Reding. Let's wait for his response...
> 
> To be clarify, because his ack was on v3 and I remember he had a
> comment. So would be better if we could get his ack on pwm change
> again.

Sure.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-22  2:01       ` Kukjin Kim
@ 2013-07-22 19:34         ` Olof Johansson
  -1 siblings, 0 replies; 124+ messages in thread
From: Olof Johansson @ 2013-07-22 19:34 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: Kukjin Kim, Tomasz Figa, Sylwester Nawrocki, linux-samsung-soc,
	linux-arm-kernel, linux-pwm, Arnd Bergmann, Heiko Stübner,
	Mark Brown, Thierry Reding

On Sun, Jul 21, 2013 at 7:01 PM, Kukjin Kim <kgene@kernel.org> wrote:

>> Yes, this whole patches look good to me, and I'd like to take this whole
>> patches into the samsung tree...but need to get any response from PWM guy,
>> Thierry Reding. Let's wait for his response...
>>
> To be clarify, because his ack was on v3 and I remember he had a comment. So
> would be better if we could get his ack on pwm change again.
>
> Thanks,
> Kukjin
>

This is a nice cleanup series indeed.

Given the volume of changes coming from Tomasz, it seems appropriate
that he just sends you pull requests with this as a branch when they
are ready to go (i.e. have the appropriate acks), instead of you
having to apply them by hand, Kukjin.


-Olof

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-22 19:34         ` Olof Johansson
  0 siblings, 0 replies; 124+ messages in thread
From: Olof Johansson @ 2013-07-22 19:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jul 21, 2013 at 7:01 PM, Kukjin Kim <kgene@kernel.org> wrote:

>> Yes, this whole patches look good to me, and I'd like to take this whole
>> patches into the samsung tree...but need to get any response from PWM guy,
>> Thierry Reding. Let's wait for his response...
>>
> To be clarify, because his ack was on v3 and I remember he had a comment. So
> would be better if we could get his ack on pwm change again.
>
> Thanks,
> Kukjin
>

This is a nice cleanup series indeed.

Given the volume of changes coming from Tomasz, it seems appropriate
that he just sends you pull requests with this as a branch when they
are ready to go (i.e. have the appropriate acks), instead of you
having to apply them by hand, Kukjin.


-Olof

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  2013-07-22  7:47       ` Tomasz Figa
@ 2013-07-22 20:13         ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22 20:13 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/22/2013 09:47 AM, Tomasz Figa wrote:
> Hi Daniel,
> 
> On Monday 22 of July 2013 05:56:16 Daniel Lezcano wrote:
>> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
>>> In case of Samsung PWM timer, clocksource MMIO can not be used,
>>> because
>>> custom suspend/resume callbacks are required.
>>>
>>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>>> ---
>>
>> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> 
> Thanks for review.
> 
>> Please in the future Cc me and Thomas Gleixner (clocksource/clockevent
>> maintainers).
> 
> Oh, right, sorry. This series originally was not touching the clocksource 
> driver and I just kept original recipient list.
> 
> Btw. Have you updated MAINTAINERS file? In latest linux-next I can still 
> see only John Stultz and Thomas Gleixner as maintainers of 
> drivers/clocksource.

Yes, right last week :)

https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=timers/core&id=9222d247bcbaacc40fe15549158f9d67523c1ace

Thanks
  -- Daniel

-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
@ 2013-07-22 20:13         ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22 20:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/22/2013 09:47 AM, Tomasz Figa wrote:
> Hi Daniel,
> 
> On Monday 22 of July 2013 05:56:16 Daniel Lezcano wrote:
>> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
>>> In case of Samsung PWM timer, clocksource MMIO can not be used,
>>> because
>>> custom suspend/resume callbacks are required.
>>>
>>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>>> ---
>>
>> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> 
> Thanks for review.
> 
>> Please in the future Cc me and Thomas Gleixner (clocksource/clockevent
>> maintainers).
> 
> Oh, right, sorry. This series originally was not touching the clocksource 
> driver and I just kept original recipient list.
> 
> Btw. Have you updated MAINTAINERS file? In latest linux-next I can still 
> see only John Stultz and Thomas Gleixner as maintainers of 
> drivers/clocksource.

Yes, right last week :)

https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=timers/core&id=9222d247bcbaacc40fe15549158f9d67523c1ace

Thanks
  -- Daniel

-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
  2013-07-22 20:13         ` Daniel Lezcano
@ 2013-07-22 20:17           ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:17 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On Monday 22 of July 2013 22:13:17 Daniel Lezcano wrote:
> On 07/22/2013 09:47 AM, Tomasz Figa wrote:
> > Hi Daniel,
> > 
> > On Monday 22 of July 2013 05:56:16 Daniel Lezcano wrote:
> >> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> >>> In case of Samsung PWM timer, clocksource MMIO can not be used,
> >>> because
> >>> custom suspend/resume callbacks are required.
> >>> 
> >>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> >>> ---
> >> 
> >> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > 
> > Thanks for review.
> > 
> >> Please in the future Cc me and Thomas Gleixner
> >> (clocksource/clockevent
> >> maintainers).
> > 
> > Oh, right, sorry. This series originally was not touching the
> > clocksource driver and I just kept original recipient list.
> > 
> > Btw. Have you updated MAINTAINERS file? In latest linux-next I can
> > still see only John Stultz and Thomas Gleixner as maintainers of
> > drivers/clocksource.
> 
> Yes, right last week :)
> 
> https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=timer
> s/core&id=9222d247bcbaacc40fe15549158f9d67523c1ace

OK, great, just wanted to make sure. Apparently linux-next did not pick 
this up.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio
@ 2013-07-22 20:17           ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 22 of July 2013 22:13:17 Daniel Lezcano wrote:
> On 07/22/2013 09:47 AM, Tomasz Figa wrote:
> > Hi Daniel,
> > 
> > On Monday 22 of July 2013 05:56:16 Daniel Lezcano wrote:
> >> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> >>> In case of Samsung PWM timer, clocksource MMIO can not be used,
> >>> because
> >>> custom suspend/resume callbacks are required.
> >>> 
> >>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> >>> ---
> >> 
> >> Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> > 
> > Thanks for review.
> > 
> >> Please in the future Cc me and Thomas Gleixner
> >> (clocksource/clockevent
> >> maintainers).
> > 
> > Oh, right, sorry. This series originally was not touching the
> > clocksource driver and I just kept original recipient list.
> > 
> > Btw. Have you updated MAINTAINERS file? In latest linux-next I can
> > still see only John Stultz and Thomas Gleixner as maintainers of
> > drivers/clocksource.
> 
> Yes, right last week :)
> 
> https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=timer
> s/core&id=9222d247bcbaacc40fe15549158f9d67523c1ace

OK, great, just wanted to make sure. Apparently linux-next did not pick 
this up.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v5 13/20] pwm: Add new pwm-samsung driver
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22 20:50     ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:50 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding

This patch introduces new Samsung PWM driver, which uses Samsung
PWM/timer master driver to control shared parts of the hardware.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile      |   1 +
 drivers/pwm/pwm-samsung.c | 611 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 612 insertions(+)
 create mode 100644 drivers/pwm/pwm-samsung.c

Changes since v4:
 - made definition of TCON_AUTORELOAD macro more readable,
 - renamed s5p_variant to s5pc100_variant,
 - replaced overlooked pr_err() with dev_err().

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index aa94807..86a5771 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
new file mode 100644
index 0000000..9836a98
--- /dev/null
+++ b/drivers/pwm/pwm-samsung.c
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * PWM driver for Samsung SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+/* For struct samsung_timer_variant and samsung_pwm_lock. */
+#include <clocksource/samsung_pwm.h>
+
+#define REG_TCFG0			0x00
+#define REG_TCFG1			0x04
+#define REG_TCON			0x08
+
+#define REG_TCNTB(tmr)			(0x0c + ((tmr) * 0xc))
+#define REG_TCMPB(tmr)			(0x10 + ((tmr) * 0xc))
+
+#define TCFG0_PRESCALER_MASK		0xff
+#define TCFG0_PRESCALER1_SHIFT		8
+
+#define TCFG1_MUX_MASK			0xf
+#define TCFG1_SHIFT(x)			((x) * 4)
+
+#define TCON_START(chan)		(1 << (4 * (chan) + 0))
+#define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
+#define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
+#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
+/* Position of autoreload bit of channel 4 (5 in TCON reg.) is different. */
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
+
+/**
+ * struct samsung_pwm_channel - private data of PWM channel
+ * @period_ns:	current period in nanoseconds programmed to the hardware
+ * @duty_ns:	current duty time in nanoseconds programmed to the hardware
+ * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
+ */
+struct samsung_pwm_channel {
+	u32 period_ns;
+	u32 duty_ns;
+	u32 tin_ns;
+};
+
+/**
+ * struct samsung_pwm_chip - private data of PWM chip
+ * @chip:		generic PWM chip
+ * @variant:		local copy of hardware variant data
+ * @inverter_mask:	inverter status for all channels - one bit per channel
+ * @base:		base address of mapped PWM registers
+ * @base_clk:		base clock used to drive the timers
+ * @tclk0:		external clock 0 (can be ERR_PTR if not present)
+ * @tclk1:		external clock 1 (can be ERR_PTR if not present)
+ */
+struct samsung_pwm_chip {
+	struct pwm_chip chip;
+	struct samsung_pwm_variant variant;
+	u8 inverter_mask;
+
+	void __iomem *base;
+	struct clk *base_clk;
+	struct clk *tclk0;
+	struct clk *tclk1;
+};
+
+#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
+/*
+ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
+ * and some registers need access synchronization. If both drivers are
+ * compiled in, the spinlock is defined in the clocksource driver,
+ * otherwise following definition is used.
+ *
+ * Currently we do not need any more complex synchronization method
+ * because all the supported SoCs contain only one instance of the PWM
+ * IP. Should this change, both drivers will need to be modified to
+ * properly synchronize accesses to particular instances.
+ */
+static DEFINE_SPINLOCK(samsung_pwm_lock);
+#endif
+
+static inline
+struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct samsung_pwm_chip, chip);
+}
+
+static inline unsigned int to_tcon_channel(unsigned int channel)
+{
+	/* TCON register has a gap of 4 bits (1 channel) */
+	return (channel == 0) ? 0 : (channel + 1);
+}
+
+static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
+				    unsigned int channel, u8 divisor)
+{
+	u8 shift = TCFG1_SHIFT(channel);
+	unsigned long flags;
+	u32 reg;
+	u8 bits;
+
+	bits = (fls(divisor) - 1) - pwm->variant.div_base;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	reg = readl(pwm->base + REG_TCFG1);
+	reg &= ~(TCFG1_MUX_MASK << shift);
+	reg |= bits << shift;
+	writel(reg, pwm->base + REG_TCFG1);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	u32 reg;
+
+	reg = readl(chip->base + REG_TCFG1);
+	reg >>= TCFG1_SHIFT(chan);
+	reg &= TCFG1_MUX_MASK;
+
+	return (BIT(reg) & variant->tclk_mask) == 0;
+}
+
+static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
+					      unsigned int chan)
+{
+	unsigned long rate;
+	u32 reg;
+
+	rate = clk_get_rate(chip->base_clk);
+
+	reg = readl(chip->base + REG_TCFG0);
+	if (chan >= 2)
+		reg >>= TCFG0_PRESCALER1_SHIFT;
+	reg &= TCFG0_PRESCALER_MASK;
+
+	return rate / (reg + 1);
+}
+
+static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
+					  unsigned int chan, unsigned long freq)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	unsigned long rate;
+	struct clk *clk;
+	u8 div;
+
+	if (!pwm_samsung_is_tdiv(chip, chan)) {
+		clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
+		if (!IS_ERR(clk)) {
+			rate = clk_get_rate(clk);
+			if (rate)
+				return rate;
+		}
+
+		dev_warn(chip->chip.dev,
+			"tclk of PWM %d is inoperational, using tdiv\n", chan);
+	}
+
+	rate = pwm_samsung_get_tin_rate(chip, chan);
+	dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
+
+	/*
+	 * Compare minimum PWM frequency that can be achieved with possible
+	 * divider settings and choose the lowest divisor that can generate
+	 * frequencies lower than requested.
+	 */
+	for (div = variant->div_base; div < 4; ++div)
+		if ((rate >> (variant->bits + div)) < freq)
+			break;
+
+	pwm_samsung_set_divisor(chip, chan, BIT(div));
+
+	return rate >> div;
+}
+
+static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *our_chan;
+
+	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
+		dev_warn(chip->dev,
+			"tried to request PWM channel %d without output\n",
+			pwm->hwpwm);
+		return -EINVAL;
+	}
+
+	our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
+	if (!our_chan)
+		return -ENOMEM;
+
+	pwm_set_chip_data(pwm, our_chan);
+
+	return 0;
+}
+
+static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	pwm_set_chip_data(pwm, NULL);
+	devm_kfree(chip->dev, pwm_get_chip_data(pwm));
+}
+
+static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_START(tcon_chan);
+	tcon |= TCON_MANUALUPDATE(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_MANUALUPDATE(tcon_chan);
+	tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+
+	return 0;
+}
+
+static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+	tcon &= ~TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+	u32 tin_ns = chan->tin_ns, tcnt, tcmp;
+
+	/*
+	 * We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits.
+	 */
+	if (period_ns > NSEC_PER_SEC)
+		return -ERANGE;
+
+	if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
+		return 0;
+
+	tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
+
+	/* We need tick count for calculation, not last tick. */
+	++tcnt;
+
+	/* Check to see if we are changing the clock rate of the PWM. */
+	if (chan->period_ns != period_ns) {
+		unsigned long tin_rate;
+		u32 period;
+
+		period = NSEC_PER_SEC / period_ns;
+
+		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+						duty_ns, period_ns, period);
+
+		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+
+		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NSEC_PER_SEC / tin_rate;
+		tcnt = period_ns / tin_ns;
+	}
+
+	/* Period is too short. */
+	if (tcnt <= 1)
+		return -ERANGE;
+
+	/* Note that counters count down. */
+	tcmp = duty_ns / tin_ns;
+
+	/* 0% duty is not available */
+	if (!tcmp)
+		++tcmp;
+
+	tcmp = tcnt - tcmp;
+
+	/* Decrement to get tick numbers, instead of tick counts. */
+	--tcnt;
+	/* -1UL will give 100% duty. */
+	--tcmp;
+
+	dev_dbg(our_chip->chip.dev,
+				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+
+	/* Update PWM registers. */
+	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
+	writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		pwm_samsung_enable(chip, pwm);
+
+	chan->period_ns = period_ns;
+	chan->tin_ns = tin_ns;
+	chan->duty_ns = duty_ns;
+
+	return 0;
+}
+
+static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
+				   unsigned int channel, bool invert)
+{
+	unsigned int tcon_chan = to_tcon_channel(channel);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(chip->base + REG_TCON);
+
+	if (invert) {
+		chip->inverter_mask |= BIT(channel);
+		tcon |= TCON_INVERT(tcon_chan);
+	} else {
+		chip->inverter_mask &= ~BIT(channel);
+		tcon &= ~TCON_INVERT(tcon_chan);
+	}
+
+	writel(tcon, chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	bool invert = (polarity == PWM_POLARITY_NORMAL);
+
+	/* Inverted means normal in the hardware. */
+	pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_samsung_ops = {
+	.request	= pwm_samsung_request,
+	.free		= pwm_samsung_free,
+	.enable		= pwm_samsung_enable,
+	.disable	= pwm_samsung_disable,
+	.config		= pwm_samsung_config,
+	.set_polarity	= pwm_samsung_set_polarity,
+	.owner		= THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static const struct samsung_pwm_variant s3c24xx_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= BIT(4),
+};
+
+static const struct samsung_pwm_variant s3c64xx_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
+};
+
+static const struct samsung_pwm_variant s5p64x0_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= 0,
+};
+
+static const struct samsung_pwm_variant s5pc100_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(5),
+};
+
+static const struct of_device_id samsung_pwm_matches[] = {
+	{ .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
+	{ .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
+	{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
+	{ .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
+	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
+	{},
+};
+
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	struct device_node *np = chip->chip.dev->of_node;
+	const struct of_device_id *match;
+	struct property *prop;
+	const __be32 *cur;
+	u32 val;
+
+	match = of_match_node(samsung_pwm_matches, np);
+	if (!match)
+		return -ENODEV;
+
+	memcpy(&chip->variant, match->data, sizeof(chip->variant));
+
+	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+		if (val >= SAMSUNG_PWM_NUM) {
+			dev_err(chip->chip.dev,
+				"%s: invalid channel index in samsung,pwm-outputs property\n",
+								__func__);
+			continue;
+		}
+		chip->variant.output_mask |= BIT(val);
+	}
+
+	return 0;
+}
+#else
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int pwm_samsung_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct samsung_pwm_chip *chip;
+	struct resource *res;
+	unsigned int chan;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->chip.dev = &pdev->dev;
+	chip->chip.ops = &pwm_samsung_ops;
+	chip->chip.base = -1;
+	chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = pwm_samsung_parse_dt(chip);
+		if (ret)
+			return ret;
+
+		chip->chip.of_xlate = of_pwm_xlate_with_flags;
+		chip->chip.of_pwm_n_cells = 3;
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data specified\n");
+			return -EINVAL;
+		}
+
+		memcpy(&chip->variant, pdev->dev.platform_data,
+							sizeof(chip->variant));
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	if (IS_ERR(chip->base_clk)) {
+		dev_err(dev, "failed to get timer base clk\n");
+		return PTR_ERR(chip->base_clk);
+	}
+
+	ret = clk_prepare_enable(chip->base_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable base clock\n");
+		return ret;
+	}
+
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan, true);
+
+	/* Following clocks are optional. */
+	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
+	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
+
+	platform_set_drvdata(pdev, chip);
+
+	ret = pwmchip_add(&chip->chip);
+	if (ret < 0) {
+		dev_err(dev, "failed to register PWM chip\n");
+		clk_disable_unprepare(chip->base_clk);
+		return ret;
+	}
+
+	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
+		clk_get_rate(chip->base_clk),
+		!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
+		!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
+
+	return 0;
+}
+
+static int pwm_samsung_remove(struct platform_device *pdev)
+{
+	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&chip->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_disable_unprepare(chip->base_clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_samsung_suspend(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/*
+	 * No one preserves these values during suspend so reset them.
+	 * Otherwise driver leaves PWM unconfigured if same values are
+	 * passed to pwm_config() next time.
+	 */
+	for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
+		struct pwm_device *pwm = &chip->chip.pwms[i];
+		struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+
+		if (!chan)
+			continue;
+
+		chan->period_ns = 0;
+		chan->duty_ns = 0;
+	}
+
+	return 0;
+}
+
+static int pwm_samsung_resume(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int chan;
+
+	/*
+	 * Inverter setting must be preserved across suspend/resume
+	 * as nobody really seems to configure it more than once.
+	 */
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan,
+					chip->inverter_mask & BIT(chan));
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_samsung_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
+};
+
+static struct platform_driver pwm_samsung_driver = {
+	.driver		= {
+		.name	= "samsung-pwm",
+		.owner	= THIS_MODULE,
+		.pm	= &pwm_samsung_pm_ops,
+		.of_match_table = of_match_ptr(samsung_pwm_matches),
+	},
+	.probe		= pwm_samsung_probe,
+	.remove		= pwm_samsung_remove,
+};
+module_platform_driver(pwm_samsung_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_ALIAS("platform:samsung-pwm");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v5 13/20] pwm: Add new pwm-samsung driver
@ 2013-07-22 20:50     ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:50 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduces new Samsung PWM driver, which uses Samsung
PWM/timer master driver to control shared parts of the hardware.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/pwm/Makefile      |   1 +
 drivers/pwm/pwm-samsung.c | 611 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 612 insertions(+)
 create mode 100644 drivers/pwm/pwm-samsung.c

Changes since v4:
 - made definition of TCON_AUTORELOAD macro more readable,
 - renamed s5p_variant to s5pc100_variant,
 - replaced overlooked pr_err() with dev_err().

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index aa94807..86a5771 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
new file mode 100644
index 0000000..9836a98
--- /dev/null
+++ b/drivers/pwm/pwm-samsung.c
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * PWM driver for Samsung SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+/* For struct samsung_timer_variant and samsung_pwm_lock. */
+#include <clocksource/samsung_pwm.h>
+
+#define REG_TCFG0			0x00
+#define REG_TCFG1			0x04
+#define REG_TCON			0x08
+
+#define REG_TCNTB(tmr)			(0x0c + ((tmr) * 0xc))
+#define REG_TCMPB(tmr)			(0x10 + ((tmr) * 0xc))
+
+#define TCFG0_PRESCALER_MASK		0xff
+#define TCFG0_PRESCALER1_SHIFT		8
+
+#define TCFG1_MUX_MASK			0xf
+#define TCFG1_SHIFT(x)			((x) * 4)
+
+#define TCON_START(chan)		(1 << (4 * (chan) + 0))
+#define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
+#define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
+#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
+/* Position of autoreload bit of channel 4 (5 in TCON reg.) is different. */
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
+
+/**
+ * struct samsung_pwm_channel - private data of PWM channel
+ * @period_ns:	current period in nanoseconds programmed to the hardware
+ * @duty_ns:	current duty time in nanoseconds programmed to the hardware
+ * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
+ */
+struct samsung_pwm_channel {
+	u32 period_ns;
+	u32 duty_ns;
+	u32 tin_ns;
+};
+
+/**
+ * struct samsung_pwm_chip - private data of PWM chip
+ * @chip:		generic PWM chip
+ * @variant:		local copy of hardware variant data
+ * @inverter_mask:	inverter status for all channels - one bit per channel
+ * @base:		base address of mapped PWM registers
+ * @base_clk:		base clock used to drive the timers
+ * @tclk0:		external clock 0 (can be ERR_PTR if not present)
+ * @tclk1:		external clock 1 (can be ERR_PTR if not present)
+ */
+struct samsung_pwm_chip {
+	struct pwm_chip chip;
+	struct samsung_pwm_variant variant;
+	u8 inverter_mask;
+
+	void __iomem *base;
+	struct clk *base_clk;
+	struct clk *tclk0;
+	struct clk *tclk1;
+};
+
+#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
+/*
+ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
+ * and some registers need access synchronization. If both drivers are
+ * compiled in, the spinlock is defined in the clocksource driver,
+ * otherwise following definition is used.
+ *
+ * Currently we do not need any more complex synchronization method
+ * because all the supported SoCs contain only one instance of the PWM
+ * IP. Should this change, both drivers will need to be modified to
+ * properly synchronize accesses to particular instances.
+ */
+static DEFINE_SPINLOCK(samsung_pwm_lock);
+#endif
+
+static inline
+struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct samsung_pwm_chip, chip);
+}
+
+static inline unsigned int to_tcon_channel(unsigned int channel)
+{
+	/* TCON register has a gap of 4 bits (1 channel) */
+	return (channel == 0) ? 0 : (channel + 1);
+}
+
+static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
+				    unsigned int channel, u8 divisor)
+{
+	u8 shift = TCFG1_SHIFT(channel);
+	unsigned long flags;
+	u32 reg;
+	u8 bits;
+
+	bits = (fls(divisor) - 1) - pwm->variant.div_base;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	reg = readl(pwm->base + REG_TCFG1);
+	reg &= ~(TCFG1_MUX_MASK << shift);
+	reg |= bits << shift;
+	writel(reg, pwm->base + REG_TCFG1);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	u32 reg;
+
+	reg = readl(chip->base + REG_TCFG1);
+	reg >>= TCFG1_SHIFT(chan);
+	reg &= TCFG1_MUX_MASK;
+
+	return (BIT(reg) & variant->tclk_mask) == 0;
+}
+
+static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
+					      unsigned int chan)
+{
+	unsigned long rate;
+	u32 reg;
+
+	rate = clk_get_rate(chip->base_clk);
+
+	reg = readl(chip->base + REG_TCFG0);
+	if (chan >= 2)
+		reg >>= TCFG0_PRESCALER1_SHIFT;
+	reg &= TCFG0_PRESCALER_MASK;
+
+	return rate / (reg + 1);
+}
+
+static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
+					  unsigned int chan, unsigned long freq)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	unsigned long rate;
+	struct clk *clk;
+	u8 div;
+
+	if (!pwm_samsung_is_tdiv(chip, chan)) {
+		clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
+		if (!IS_ERR(clk)) {
+			rate = clk_get_rate(clk);
+			if (rate)
+				return rate;
+		}
+
+		dev_warn(chip->chip.dev,
+			"tclk of PWM %d is inoperational, using tdiv\n", chan);
+	}
+
+	rate = pwm_samsung_get_tin_rate(chip, chan);
+	dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
+
+	/*
+	 * Compare minimum PWM frequency that can be achieved with possible
+	 * divider settings and choose the lowest divisor that can generate
+	 * frequencies lower than requested.
+	 */
+	for (div = variant->div_base; div < 4; ++div)
+		if ((rate >> (variant->bits + div)) < freq)
+			break;
+
+	pwm_samsung_set_divisor(chip, chan, BIT(div));
+
+	return rate >> div;
+}
+
+static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *our_chan;
+
+	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
+		dev_warn(chip->dev,
+			"tried to request PWM channel %d without output\n",
+			pwm->hwpwm);
+		return -EINVAL;
+	}
+
+	our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
+	if (!our_chan)
+		return -ENOMEM;
+
+	pwm_set_chip_data(pwm, our_chan);
+
+	return 0;
+}
+
+static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	pwm_set_chip_data(pwm, NULL);
+	devm_kfree(chip->dev, pwm_get_chip_data(pwm));
+}
+
+static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_START(tcon_chan);
+	tcon |= TCON_MANUALUPDATE(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_MANUALUPDATE(tcon_chan);
+	tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+
+	return 0;
+}
+
+static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+	tcon &= ~TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+	u32 tin_ns = chan->tin_ns, tcnt, tcmp;
+
+	/*
+	 * We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits.
+	 */
+	if (period_ns > NSEC_PER_SEC)
+		return -ERANGE;
+
+	if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
+		return 0;
+
+	tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
+
+	/* We need tick count for calculation, not last tick. */
+	++tcnt;
+
+	/* Check to see if we are changing the clock rate of the PWM. */
+	if (chan->period_ns != period_ns) {
+		unsigned long tin_rate;
+		u32 period;
+
+		period = NSEC_PER_SEC / period_ns;
+
+		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+						duty_ns, period_ns, period);
+
+		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+
+		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NSEC_PER_SEC / tin_rate;
+		tcnt = period_ns / tin_ns;
+	}
+
+	/* Period is too short. */
+	if (tcnt <= 1)
+		return -ERANGE;
+
+	/* Note that counters count down. */
+	tcmp = duty_ns / tin_ns;
+
+	/* 0% duty is not available */
+	if (!tcmp)
+		++tcmp;
+
+	tcmp = tcnt - tcmp;
+
+	/* Decrement to get tick numbers, instead of tick counts. */
+	--tcnt;
+	/* -1UL will give 100% duty. */
+	--tcmp;
+
+	dev_dbg(our_chip->chip.dev,
+				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+
+	/* Update PWM registers. */
+	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
+	writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		pwm_samsung_enable(chip, pwm);
+
+	chan->period_ns = period_ns;
+	chan->tin_ns = tin_ns;
+	chan->duty_ns = duty_ns;
+
+	return 0;
+}
+
+static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
+				   unsigned int channel, bool invert)
+{
+	unsigned int tcon_chan = to_tcon_channel(channel);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(chip->base + REG_TCON);
+
+	if (invert) {
+		chip->inverter_mask |= BIT(channel);
+		tcon |= TCON_INVERT(tcon_chan);
+	} else {
+		chip->inverter_mask &= ~BIT(channel);
+		tcon &= ~TCON_INVERT(tcon_chan);
+	}
+
+	writel(tcon, chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	bool invert = (polarity == PWM_POLARITY_NORMAL);
+
+	/* Inverted means normal in the hardware. */
+	pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_samsung_ops = {
+	.request	= pwm_samsung_request,
+	.free		= pwm_samsung_free,
+	.enable		= pwm_samsung_enable,
+	.disable	= pwm_samsung_disable,
+	.config		= pwm_samsung_config,
+	.set_polarity	= pwm_samsung_set_polarity,
+	.owner		= THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static const struct samsung_pwm_variant s3c24xx_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= BIT(4),
+};
+
+static const struct samsung_pwm_variant s3c64xx_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
+};
+
+static const struct samsung_pwm_variant s5p64x0_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= 0,
+};
+
+static const struct samsung_pwm_variant s5pc100_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(5),
+};
+
+static const struct of_device_id samsung_pwm_matches[] = {
+	{ .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
+	{ .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
+	{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
+	{ .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
+	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
+	{},
+};
+
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	struct device_node *np = chip->chip.dev->of_node;
+	const struct of_device_id *match;
+	struct property *prop;
+	const __be32 *cur;
+	u32 val;
+
+	match = of_match_node(samsung_pwm_matches, np);
+	if (!match)
+		return -ENODEV;
+
+	memcpy(&chip->variant, match->data, sizeof(chip->variant));
+
+	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+		if (val >= SAMSUNG_PWM_NUM) {
+			dev_err(chip->chip.dev,
+				"%s: invalid channel index in samsung,pwm-outputs property\n",
+								__func__);
+			continue;
+		}
+		chip->variant.output_mask |= BIT(val);
+	}
+
+	return 0;
+}
+#else
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int pwm_samsung_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct samsung_pwm_chip *chip;
+	struct resource *res;
+	unsigned int chan;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->chip.dev = &pdev->dev;
+	chip->chip.ops = &pwm_samsung_ops;
+	chip->chip.base = -1;
+	chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = pwm_samsung_parse_dt(chip);
+		if (ret)
+			return ret;
+
+		chip->chip.of_xlate = of_pwm_xlate_with_flags;
+		chip->chip.of_pwm_n_cells = 3;
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data specified\n");
+			return -EINVAL;
+		}
+
+		memcpy(&chip->variant, pdev->dev.platform_data,
+							sizeof(chip->variant));
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	if (IS_ERR(chip->base_clk)) {
+		dev_err(dev, "failed to get timer base clk\n");
+		return PTR_ERR(chip->base_clk);
+	}
+
+	ret = clk_prepare_enable(chip->base_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable base clock\n");
+		return ret;
+	}
+
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan, true);
+
+	/* Following clocks are optional. */
+	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
+	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
+
+	platform_set_drvdata(pdev, chip);
+
+	ret = pwmchip_add(&chip->chip);
+	if (ret < 0) {
+		dev_err(dev, "failed to register PWM chip\n");
+		clk_disable_unprepare(chip->base_clk);
+		return ret;
+	}
+
+	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
+		clk_get_rate(chip->base_clk),
+		!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
+		!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
+
+	return 0;
+}
+
+static int pwm_samsung_remove(struct platform_device *pdev)
+{
+	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&chip->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_disable_unprepare(chip->base_clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_samsung_suspend(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/*
+	 * No one preserves these values during suspend so reset them.
+	 * Otherwise driver leaves PWM unconfigured if same values are
+	 * passed to pwm_config() next time.
+	 */
+	for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
+		struct pwm_device *pwm = &chip->chip.pwms[i];
+		struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+
+		if (!chan)
+			continue;
+
+		chan->period_ns = 0;
+		chan->duty_ns = 0;
+	}
+
+	return 0;
+}
+
+static int pwm_samsung_resume(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int chan;
+
+	/*
+	 * Inverter setting must be preserved across suspend/resume
+	 * as nobody really seems to configure it more than once.
+	 */
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan,
+					chip->inverter_mask & BIT(chan));
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_samsung_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
+};
+
+static struct platform_driver pwm_samsung_driver = {
+	.driver		= {
+		.name	= "samsung-pwm",
+		.owner	= THIS_MODULE,
+		.pm	= &pwm_samsung_pm_ops,
+		.of_match_table = of_match_ptr(samsung_pwm_matches),
+	},
+	.probe		= pwm_samsung_probe,
+	.remove		= pwm_samsung_remove,
+};
+module_platform_driver(pwm_samsung_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_ALIAS("platform:samsung-pwm");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v5 07/20] ARM: SAMSUNG: Add new PWM platform device
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22 20:52     ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:52 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding

This patch adds new samsung_device_pwm platform device that represents
the whole PWM/timer block and includes memory and IRQ resources.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h     |  1 +
 arch/arm/plat-samsung/include/plat/pwm-core.h | 22 ++++++++++++++++++++++
 3 files changed, 40 insertions(+)
 create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h

Changes since v4:
 - cleaned up header of pwm-core.h file.

diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 0f9c3f4..bba6d78 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -58,6 +58,7 @@
 #include <plat/keypad.h>
 #include <linux/platform_data/mmc-s3cmci.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/pwm-core.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
@@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
 	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
 	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
 };
+
+static struct resource samsung_pwm_resource[] = {
+	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
+};
+
+struct platform_device samsung_device_pwm = {
+	.name		= "samsung-pwm",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
+	.resource	= samsung_pwm_resource,
+};
+
+void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
+{
+	samsung_device_pwm.dev.platform_data = pd;
+}
 #endif /* CONFIG_SAMSUNG_DEV_PWM */
 
 /* RTC */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 87d501f..0dc4ac4 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -134,6 +134,7 @@ extern struct platform_device exynos4_device_spdif;
 
 extern struct platform_device samsung_asoc_idma;
 extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_pwm;
 
 /* s3c2440 specific devices */
 
diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
new file mode 100644
index 0000000..77269a7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung PWM controller platform data helpers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_PWM_CORE_H
+#define __ASM_ARCH_PWM_CORE_H __FILE__
+
+#include <clocksource/samsung_pwm.h>
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
+#else
+static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
+#endif
+
+#endif /* __ASM_ARCH_PWM_CORE_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v5 07/20] ARM: SAMSUNG: Add new PWM platform device
@ 2013-07-22 20:52     ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:52 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds new samsung_device_pwm platform device that represents
the whole PWM/timer block and includes memory and IRQ resources.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 arch/arm/plat-samsung/devs.c                  | 17 +++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h     |  1 +
 arch/arm/plat-samsung/include/plat/pwm-core.h | 22 ++++++++++++++++++++++
 3 files changed, 40 insertions(+)
 create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h

Changes since v4:
 - cleaned up header of pwm-core.h file.

diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 0f9c3f4..bba6d78 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -58,6 +58,7 @@
 #include <plat/keypad.h>
 #include <linux/platform_data/mmc-s3cmci.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
+#include <plat/pwm-core.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
@@ -1127,6 +1128,22 @@ struct platform_device s3c_device_timer[] = {
 	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
 	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
 };
+
+static struct resource samsung_pwm_resource[] = {
+	DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K),
+};
+
+struct platform_device samsung_device_pwm = {
+	.name		= "samsung-pwm",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(samsung_pwm_resource),
+	.resource	= samsung_pwm_resource,
+};
+
+void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd)
+{
+	samsung_device_pwm.dev.platform_data = pd;
+}
 #endif /* CONFIG_SAMSUNG_DEV_PWM */
 
 /* RTC */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 87d501f..0dc4ac4 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -134,6 +134,7 @@ extern struct platform_device exynos4_device_spdif;
 
 extern struct platform_device samsung_asoc_idma;
 extern struct platform_device samsung_device_keypad;
+extern struct platform_device samsung_device_pwm;
 
 /* s3c2440 specific devices */
 
diff --git a/arch/arm/plat-samsung/include/plat/pwm-core.h b/arch/arm/plat-samsung/include/plat/pwm-core.h
new file mode 100644
index 0000000..77269a7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pwm-core.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Samsung PWM controller platform data helpers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_PWM_CORE_H
+#define __ASM_ARCH_PWM_CORE_H __FILE__
+
+#include <clocksource/samsung_pwm.h>
+
+#ifdef CONFIG_SAMSUNG_DEV_PWM
+extern void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd);
+#else
+static inline void samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) { }
+#endif
+
+#endif /* __ASM_ARCH_PWM_CORE_H */
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v5 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-22 20:54     ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:54 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Changes since v4:
 - made the new definition more readable.

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..89947c3 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -47,7 +47,11 @@
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
+/* Position of autoreload bit of channel 4 (5 in TCON reg.) is different. */
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v5 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-22 20:54     ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 20:54 UTC (permalink / raw)
  To: linux-arm-kernel

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Changes since v4:
 - made the new definition more readable.

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..89947c3 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -47,7 +47,11 @@
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
+/* Position of autoreload bit of channel 4 (5 in TCON reg.) is different. */
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-22  7:43       ` Tomasz Figa
@ 2013-07-22 20:56         ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22 20:56 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/22/2013 09:43 AM, Tomasz Figa wrote:
> On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
>> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
>>> PWM channel 4 has its autoreload bit located at different position.
>>> This patch fixes the driver to account for that.
>>>
>>> This fixes a problem with the clocksource hanging after it overflows
>>> because it is not reloaded any more.
>>>
>>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>>> ---
>>>
>>>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/clocksource/samsung_pwm_timer.c
>>> b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
>>> 100644
>>> --- a/drivers/clocksource/samsung_pwm_timer.c
>>> +++ b/drivers/clocksource/samsung_pwm_timer.c
>>> @@ -47,7 +47,8 @@
>>>
>>>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>>>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>>>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
>>>
>>> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
>>> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
>>> +						+ (((chan) < 5) ? 3 : 2)))
>>
>> This macro is not readable. Please, fix it up with a comment please.
> 
> /*
>  * Channel 4 (logically 5 in TCON register) has different position
>  * of autoreload bit.
>  */
> #define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) + 3))
> #define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) + 2))
> #define TCON_AUTORELOAD(chan)			((chan < 5) ? 
> 		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
> 
> What do you think?

I don't get the arithmetic here and the code is poor in comment. A nice
comment would valuable here.

May be you can replace 1 << bla by BIT(bla) ?


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-22 20:56         ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22 20:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/22/2013 09:43 AM, Tomasz Figa wrote:
> On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
>> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
>>> PWM channel 4 has its autoreload bit located at different position.
>>> This patch fixes the driver to account for that.
>>>
>>> This fixes a problem with the clocksource hanging after it overflows
>>> because it is not reloaded any more.
>>>
>>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>>> ---
>>>
>>>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/clocksource/samsung_pwm_timer.c
>>> b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
>>> 100644
>>> --- a/drivers/clocksource/samsung_pwm_timer.c
>>> +++ b/drivers/clocksource/samsung_pwm_timer.c
>>> @@ -47,7 +47,8 @@
>>>
>>>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>>>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>>>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
>>>
>>> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
>>> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
>>> +						+ (((chan) < 5) ? 3 : 2)))
>>
>> This macro is not readable. Please, fix it up with a comment please.
> 
> /*
>  * Channel 4 (logically 5 in TCON register) has different position
>  * of autoreload bit.
>  */
> #define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) + 3))
> #define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) + 2))
> #define TCON_AUTORELOAD(chan)			((chan < 5) ? 
> 		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
> 
> What do you think?

I don't get the arithmetic here and the code is poor in comment. A nice
comment would valuable here.

May be you can replace 1 << bla by BIT(bla) ?


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-22 20:56         ` Daniel Lezcano
@ 2013-07-22 21:11           ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 21:11 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On Monday 22 of July 2013 22:56:44 Daniel Lezcano wrote:
> On 07/22/2013 09:43 AM, Tomasz Figa wrote:
> > On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
> >> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> >>> PWM channel 4 has its autoreload bit located at different position.
> >>> This patch fixes the driver to account for that.
> >>> 
> >>> This fixes a problem with the clocksource hanging after it overflows
> >>> because it is not reloaded any more.
> >>> 
> >>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> >>> ---
> >>> 
> >>>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
> >>>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>> 
> >>> diff --git a/drivers/clocksource/samsung_pwm_timer.c
> >>> b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
> >>> 100644
> >>> --- a/drivers/clocksource/samsung_pwm_timer.c
> >>> +++ b/drivers/clocksource/samsung_pwm_timer.c
> >>> @@ -47,7 +47,8 @@
> >>> 
> >>>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
> >>>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
> >>>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> >>> 
> >>> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> >>> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
> >>> +						+ (((chan) < 5) ? 3 : 2)))
> >> 
> >> This macro is not readable. Please, fix it up with a comment please.
> > 
> > /*
> > 
> >  * Channel 4 (logically 5 in TCON register) has different position
> >  * of autoreload bit.
> >  */
> > 
> > #define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) 
+ 3))
> > #define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) 
+ 2))
> > #define TCON_AUTORELOAD(chan)			((chan < 5) ?
> > 
> > 		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
> > 
> > What do you think?
> 
> I don't get the arithmetic here and the code is poor in comment. A nice
> comment would valuable here.

Each channel occupies 4 bits in TCON register, but there is a gap of 4 
bits after channel 0. In addition for channel 4 the location of autoreload 
bit in its set of bits is 2 as opposed to 3 for other channels. Here's the 
layout of the register, for reference:

Timer 4 Auto Reload on/off	[22]
Timer 4 Manual Update		[21]
Timer 4 Start/Stop		[20]

Timer 3 Auto Reload on/off	[19]
Reserved			[18]
Timer 3 Manual Update		[17]
Timer 3 Start/Stop		[16]

Timer 2 Auto Reload on/off	[15]
Reserved			[14]
Timer 2 Manual Update		[13]
Timer 2 Start/Stop		[12]

Timer 1 Auto Reload on/off	[11]
Timer 1 Output Inverter on/off	[10]
Timer 1 Manual Update		[9]
Timer 1 Start/Stop		[8]

Reserved			[7:5]
Dead zone enable/disable	[4]

Timer 0 Auto Reload on/off	[3]
Timer 0 Output Inverter on/off	[2]
Timer 0 Manual Update		[1]
Timer 0 Start/Stop		[0]

> May be you can replace 1 << bla by BIT(bla) ?

Yes, BIT() would be nice here, but IMHO this is material for separate 
patch as all the macros in this driver already use 1 << bla.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-22 21:11           ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-22 21:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 22 of July 2013 22:56:44 Daniel Lezcano wrote:
> On 07/22/2013 09:43 AM, Tomasz Figa wrote:
> > On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
> >> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> >>> PWM channel 4 has its autoreload bit located at different position.
> >>> This patch fixes the driver to account for that.
> >>> 
> >>> This fixes a problem with the clocksource hanging after it overflows
> >>> because it is not reloaded any more.
> >>> 
> >>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> >>> ---
> >>> 
> >>>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
> >>>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>> 
> >>> diff --git a/drivers/clocksource/samsung_pwm_timer.c
> >>> b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
> >>> 100644
> >>> --- a/drivers/clocksource/samsung_pwm_timer.c
> >>> +++ b/drivers/clocksource/samsung_pwm_timer.c
> >>> @@ -47,7 +47,8 @@
> >>> 
> >>>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
> >>>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
> >>>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> >>> 
> >>> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> >>> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
> >>> +						+ (((chan) < 5) ? 3 : 2)))
> >> 
> >> This macro is not readable. Please, fix it up with a comment please.
> > 
> > /*
> > 
> >  * Channel 4 (logically 5 in TCON register) has different position
> >  * of autoreload bit.
> >  */
> > 
> > #define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) 
+ 3))
> > #define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) 
+ 2))
> > #define TCON_AUTORELOAD(chan)			((chan < 5) ?
> > 
> > 		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
> > 
> > What do you think?
> 
> I don't get the arithmetic here and the code is poor in comment. A nice
> comment would valuable here.

Each channel occupies 4 bits in TCON register, but there is a gap of 4 
bits after channel 0. In addition for channel 4 the location of autoreload 
bit in its set of bits is 2 as opposed to 3 for other channels. Here's the 
layout of the register, for reference:

Timer 4 Auto Reload on/off	[22]
Timer 4 Manual Update		[21]
Timer 4 Start/Stop		[20]

Timer 3 Auto Reload on/off	[19]
Reserved			[18]
Timer 3 Manual Update		[17]
Timer 3 Start/Stop		[16]

Timer 2 Auto Reload on/off	[15]
Reserved			[14]
Timer 2 Manual Update		[13]
Timer 2 Start/Stop		[12]

Timer 1 Auto Reload on/off	[11]
Timer 1 Output Inverter on/off	[10]
Timer 1 Manual Update		[9]
Timer 1 Start/Stop		[8]

Reserved			[7:5]
Dead zone enable/disable	[4]

Timer 0 Auto Reload on/off	[3]
Timer 0 Output Inverter on/off	[2]
Timer 0 Manual Update		[1]
Timer 0 Start/Stop		[0]

> May be you can replace 1 << bla by BIT(bla) ?

Yes, BIT() would be nice here, but IMHO this is material for separate 
patch as all the macros in this driver already use 1 << bla.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-22 21:11           ` Tomasz Figa
@ 2013-07-22 21:28             ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22 21:28 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/22/2013 11:11 PM, Tomasz Figa wrote:
> On Monday 22 of July 2013 22:56:44 Daniel Lezcano wrote:
>> On 07/22/2013 09:43 AM, Tomasz Figa wrote:
>>> On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
>>>> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
>>>>> PWM channel 4 has its autoreload bit located at different position.
>>>>> This patch fixes the driver to account for that.
>>>>>
>>>>> This fixes a problem with the clocksource hanging after it overflows
>>>>> because it is not reloaded any more.
>>>>>
>>>>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>>>>> ---
>>>>>
>>>>>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
>>>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/clocksource/samsung_pwm_timer.c
>>>>> b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
>>>>> 100644
>>>>> --- a/drivers/clocksource/samsung_pwm_timer.c
>>>>> +++ b/drivers/clocksource/samsung_pwm_timer.c
>>>>> @@ -47,7 +47,8 @@
>>>>>
>>>>>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>>>>>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>>>>>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
>>>>>
>>>>> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
>>>>> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
>>>>> +						+ (((chan) < 5) ? 3 : 2)))
>>>>
>>>> This macro is not readable. Please, fix it up with a comment please.
>>>
>>> /*
>>>
>>>  * Channel 4 (logically 5 in TCON register) has different position
>>>  * of autoreload bit.
>>>  */
>>>
>>> #define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) 
> + 3))
>>> #define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) 
> + 2))
>>> #define TCON_AUTORELOAD(chan)			((chan < 5) ?
>>>
>>> 		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
>>>
>>> What do you think?
>>
>> I don't get the arithmetic here and the code is poor in comment. A nice
>> comment would valuable here.
> 
> Each channel occupies 4 bits in TCON register, but there is a gap of 4 
> bits after channel 0. In addition for channel 4 the location of autoreload 
> bit in its set of bits is 2 as opposed to 3 for other channels. Here's the 
> layout of the register, for reference:
> 
> Timer 4 Auto Reload on/off	[22]
> Timer 4 Manual Update		[21]
> Timer 4 Start/Stop		[20]
> 
> Timer 3 Auto Reload on/off	[19]
> Reserved			[18]
> Timer 3 Manual Update		[17]
> Timer 3 Start/Stop		[16]
> 
> Timer 2 Auto Reload on/off	[15]
> Reserved			[14]
> Timer 2 Manual Update		[13]
> Timer 2 Start/Stop		[12]
> 
> Timer 1 Auto Reload on/off	[11]
> Timer 1 Output Inverter on/off	[10]
> Timer 1 Manual Update		[9]
> Timer 1 Start/Stop		[8]
> 
> Reserved			[7:5]
> Dead zone enable/disable	[4]
> 
> Timer 0 Auto Reload on/off	[3]
> Timer 0 Output Inverter on/off	[2]
> Timer 0 Manual Update		[1]
> Timer 0 Start/Stop		[0]

Ok, I understand now. Thanks for the clarification.

IMHO, the description you gave above (without layout) will fit well for
a comment :)

>> May be you can replace 1 << bla by BIT(bla) ?
> 
> Yes, BIT() would be nice here, but IMHO this is material for separate 
> patch as all the macros in this driver already use 1 << bla.

Yes, I agree.

Thanks
  -- Daniel

-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-22 21:28             ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-22 21:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/22/2013 11:11 PM, Tomasz Figa wrote:
> On Monday 22 of July 2013 22:56:44 Daniel Lezcano wrote:
>> On 07/22/2013 09:43 AM, Tomasz Figa wrote:
>>> On Monday 22 of July 2013 05:50:09 Daniel Lezcano wrote:
>>>> On 07/20/2013 02:04 AM, Tomasz Figa wrote:
>>>>> PWM channel 4 has its autoreload bit located at different position.
>>>>> This patch fixes the driver to account for that.
>>>>>
>>>>> This fixes a problem with the clocksource hanging after it overflows
>>>>> because it is not reloaded any more.
>>>>>
>>>>> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
>>>>> ---
>>>>>
>>>>>  drivers/clocksource/samsung_pwm_timer.c | 3 ++-
>>>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/clocksource/samsung_pwm_timer.c
>>>>> b/drivers/clocksource/samsung_pwm_timer.c index 3fa5b07..e238fb0
>>>>> 100644
>>>>> --- a/drivers/clocksource/samsung_pwm_timer.c
>>>>> +++ b/drivers/clocksource/samsung_pwm_timer.c
>>>>> @@ -47,7 +47,8 @@
>>>>>
>>>>>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>>>>>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>>>>>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
>>>>>
>>>>> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
>>>>> +#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) \
>>>>> +						+ (((chan) < 5) ? 3 : 2)))
>>>>
>>>> This macro is not readable. Please, fix it up with a comment please.
>>>
>>> /*
>>>
>>>  * Channel 4 (logically 5 in TCON register) has different position
>>>  * of autoreload bit.
>>>  */
>>>
>>> #define _TCON_AUTORELOAD(chan)			(1 << (4 * (chan) 
> + 3))
>>> #define _TCON_AUTORELOAD4(chan)			(1 << (4 * (chan) 
> + 2))
>>> #define TCON_AUTORELOAD(chan)			((chan < 5) ?
>>>
>>> 		_TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
>>>
>>> What do you think?
>>
>> I don't get the arithmetic here and the code is poor in comment. A nice
>> comment would valuable here.
> 
> Each channel occupies 4 bits in TCON register, but there is a gap of 4 
> bits after channel 0. In addition for channel 4 the location of autoreload 
> bit in its set of bits is 2 as opposed to 3 for other channels. Here's the 
> layout of the register, for reference:
> 
> Timer 4 Auto Reload on/off	[22]
> Timer 4 Manual Update		[21]
> Timer 4 Start/Stop		[20]
> 
> Timer 3 Auto Reload on/off	[19]
> Reserved			[18]
> Timer 3 Manual Update		[17]
> Timer 3 Start/Stop		[16]
> 
> Timer 2 Auto Reload on/off	[15]
> Reserved			[14]
> Timer 2 Manual Update		[13]
> Timer 2 Start/Stop		[12]
> 
> Timer 1 Auto Reload on/off	[11]
> Timer 1 Output Inverter on/off	[10]
> Timer 1 Manual Update		[9]
> Timer 1 Start/Stop		[8]
> 
> Reserved			[7:5]
> Dead zone enable/disable	[4]
> 
> Timer 0 Auto Reload on/off	[3]
> Timer 0 Output Inverter on/off	[2]
> Timer 0 Manual Update		[1]
> Timer 0 Start/Stop		[0]

Ok, I understand now. Thanks for the clarification.

IMHO, the description you gave above (without layout) will fit well for
a comment :)

>> May be you can replace 1 << bla by BIT(bla) ?
> 
> Yes, BIT() would be nice here, but IMHO this is material for separate 
> patch as all the macros in this driver already use 1 << bla.

Yes, I agree.

Thanks
  -- Daniel

-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-22  7:49         ` Tomasz Figa
@ 2013-07-23 15:30           ` Thierry Reding
  -1 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-23 15:30 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Kukjin Kim, 'Kukjin Kim', 'Sylwester Nawrocki',
	linux-samsung-soc, linux-arm-kernel, linux-pwm,
	'Arnd Bergmann', 'Olof Johansson',
	'Heiko Stübner', 'Mark Brown'

[-- Attachment #1: Type: text/plain, Size: 3192 bytes --]

On Mon, Jul 22, 2013 at 09:49:49AM +0200, Tomasz Figa wrote:
> On Monday 22 of July 2013 11:01:32 Kukjin Kim wrote:
> > Kukjin Kim wrote:
> > > Tomasz Figa wrote:
> > > > On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > > > > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > > > > Since we now have a proper Samsung PWM clocksource driver in
> > > > > > place,
> > > > > > we can proceed with further cleanup of PWM timers support on
> > > > > > Samsung
> > > > > > SoCs.>
> > > > > > 
> > > > > > This series attempts to achieve this goal by:
> > > > > >   1) fixing up few things in samsung_pwm_timer clocksource
> > > > > >   driver,
> > > > > >   2) moving remaining Samsung platforms to the new clocksource
> > > 
> > > driver,
> > > 
> > > > > >   3) removing old clocksource driver,
> > > > > >   4) adding new multiplatform- and DT-aware PWM driver,
> > > > > >   5) moving all Samsung platforms to use the new PWM driver,
> > > > > >   6) removing old PWM driver,
> > > > > >   7) removing all PWM-related code that is not used anymore.
> > > > > > 
> > > > > > Cleaning up the PWM driver is a bit tricky, because the design
> > > > > > of
> > > > > > current driver makes it completely unsuitable for DT and
> > > > > > multiplatform and would require a heavy rework to make it
> > > > > > usable,
> > > > > > breaking any existing Samsung PWM users by the way. To avoid any
> > > > > > breakage this series first renames the old driver, then adds new
> > > > > > one
> > > > > > using original name, migrates all platforms to use it and then
> > > > > > finally removes the old driver.
> > > > > > 
> > > > > > See particular patches for more detailed descriptions.
> > > > > > 
> > > > > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with
> > > > > > pwm-beeper,
> > > > > > SMDK6410 with PWM backlight and Exynos4210-based Origen board
> > > > > > (with
> > > > > > PWM0 attached to a scope)]
> > > > > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > > > > 
> > > > > > [On S3C2440-based Mini2440 board]
> > > > > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> > > > > 
> > > > > I have retested this series on top of v3.11-rc1 with pwm-backlight
> > > 
> > > (and
> > > 
> > > > > buzzer
> > > > > as the output :)) on Mini2440. It seems to work well - generated
> > > > > frequencies are correct. I'll check pulse widths with a scope
> > 
> > tomorrow,
> > 
> > > > > as it's a bit late
> > > > > now. FWIW you can add to this series my:
> > > > > 
> > > > > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > > 
> > > > Thanks. I hope we can finally get this series merged soon.
> > > 
> > > Yes, this whole patches look good to me, and I'd like to take this
> > > whole patches into the samsung tree...but need to get any response
> > > from PWM guy, Thierry Reding. Let's wait for his response...
> > 
> > To be clarify, because his ack was on v3 and I remember he had a
> > comment. So would be better if we could get his ack on pwm change
> > again.
> 
> Sure.

Patches 12, 13 and 16:

Acked-by: Thierry Reding <thierry.reding@gmail.com>

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-23 15:30           ` Thierry Reding
  0 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-23 15:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 22, 2013 at 09:49:49AM +0200, Tomasz Figa wrote:
> On Monday 22 of July 2013 11:01:32 Kukjin Kim wrote:
> > Kukjin Kim wrote:
> > > Tomasz Figa wrote:
> > > > On Monday 22 of July 2013 00:22:16 Sylwester Nawrocki wrote:
> > > > > On 07/20/2013 02:04 AM, Tomasz Figa wrote:
> > > > > > Since we now have a proper Samsung PWM clocksource driver in
> > > > > > place,
> > > > > > we can proceed with further cleanup of PWM timers support on
> > > > > > Samsung
> > > > > > SoCs.>
> > > > > > 
> > > > > > This series attempts to achieve this goal by:
> > > > > >   1) fixing up few things in samsung_pwm_timer clocksource
> > > > > >   driver,
> > > > > >   2) moving remaining Samsung platforms to the new clocksource
> > > 
> > > driver,
> > > 
> > > > > >   3) removing old clocksource driver,
> > > > > >   4) adding new multiplatform- and DT-aware PWM driver,
> > > > > >   5) moving all Samsung platforms to use the new PWM driver,
> > > > > >   6) removing old PWM driver,
> > > > > >   7) removing all PWM-related code that is not used anymore.
> > > > > > 
> > > > > > Cleaning up the PWM driver is a bit tricky, because the design
> > > > > > of
> > > > > > current driver makes it completely unsuitable for DT and
> > > > > > multiplatform and would require a heavy rework to make it
> > > > > > usable,
> > > > > > breaking any existing Samsung PWM users by the way. To avoid any
> > > > > > breakage this series first renames the old driver, then adds new
> > > > > > one
> > > > > > using original name, migrates all platforms to use it and then
> > > > > > finally removes the old driver.
> > > > > > 
> > > > > > See particular patches for more detailed descriptions.
> > > > > > 
> > > > > > [On S3C6410-based Tiny6410 (Mini6410-compatible) with
> > > > > > pwm-beeper,
> > > > > > SMDK6410 with PWM backlight and Exynos4210-based Origen board
> > > > > > (with
> > > > > > PWM0 attached to a scope)]
> > > > > > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> > > > > > 
> > > > > > [On S3C2440-based Mini2440 board]
> > > > > > Tested-by: Sylwester Nawrocki<sylvester.nawrocki@gmail.com>
> > > > > 
> > > > > I have retested this series on top of v3.11-rc1 with pwm-backlight
> > > 
> > > (and
> > > 
> > > > > buzzer
> > > > > as the output :)) on Mini2440. It seems to work well - generated
> > > > > frequencies are correct. I'll check pulse widths with a scope
> > 
> > tomorrow,
> > 
> > > > > as it's a bit late
> > > > > now. FWIW you can add to this series my:
> > > > > 
> > > > > Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> > > > 
> > > > Thanks. I hope we can finally get this series merged soon.
> > > 
> > > Yes, this whole patches look good to me, and I'd like to take this
> > > whole patches into the samsung tree...but need to get any response
> > > from PWM guy, Thierry Reding. Let's wait for his response...
> > 
> > To be clarify, because his ack was on v3 and I remember he had a
> > comment. So would be better if we could get his ack on pwm change
> > again.
> 
> Sure.

Patches 12, 13 and 16:

Acked-by: Thierry Reding <thierry.reding@gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130723/6a086acb/attachment.sig>

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v6 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-22 21:28             ` Daniel Lezcano
@ 2013-07-23 23:32               ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-23 23:32 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Changes since v5:
 - Added more detailed comment about bit layout in TCON register.

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..5d0049f 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -44,10 +44,21 @@
 #define TCFG1_SHIFT(x)	  		((x) * 4)
 #define TCFG1_MUX_MASK	  		0xf
 
+/*
+ * Each channel occupies 4 bits in TCON register, but there is a gap of 4
+ * bits (one channel) after channel 0, so channels have different numbering
+ * when accessing TCON register.
+ *
+ * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
+ * in its set of bits is 2 as opposed to 3 for other channels.
+ */
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v6 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-23 23:32               ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-23 23:32 UTC (permalink / raw)
  To: linux-arm-kernel

PWM channel 4 has its autoreload bit located at different position. This
patch fixes the driver to account for that.

This fixes a problem with the clocksource hanging after it overflows because
it is not reloaded any more.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
 drivers/clocksource/samsung_pwm_timer.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Changes since v5:
 - Added more detailed comment about bit layout in TCON register.

diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
index 3fa5b07..5d0049f 100644
--- a/drivers/clocksource/samsung_pwm_timer.c
+++ b/drivers/clocksource/samsung_pwm_timer.c
@@ -44,10 +44,21 @@
 #define TCFG1_SHIFT(x)	  		((x) * 4)
 #define TCFG1_MUX_MASK	  		0xf
 
+/*
+ * Each channel occupies 4 bits in TCON register, but there is a gap of 4
+ * bits (one channel) after channel 0, so channels have different numbering
+ * when accessing TCON register.
+ *
+ * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
+ * in its set of bits is 2 as opposed to 3 for other channels.
+ */
 #define TCON_START(chan)		(1 << (4 * (chan) + 0))
 #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
 #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
-#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
+#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
 
 DEFINE_SPINLOCK(samsung_pwm_lock);
 EXPORT_SYMBOL(samsung_pwm_lock);
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v6 13/20] pwm: Add new pwm-samsung driver
  2013-07-22 20:50     ` Tomasz Figa
@ 2013-07-23 23:43       ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-23 23:43 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding

This patch introduces new Samsung PWM driver, which is completely
rewritten to be multiplatform- and DeviceTree-aware.

In addition, remaining problems of old driver are fixed, such as:
 - proper handling of hardware variants,
 - synchronization on SMP systems,
 - handling of boundary parameter values,
 - hardware sharing with PWM clocksource driver,
 - undefined state of PWM output after stopping PWM channel.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
---
 drivers/pwm/Makefile      |   1 +
 drivers/pwm/pwm-samsung.c | 618 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 619 insertions(+)
 create mode 100644 drivers/pwm/pwm-samsung.c

Changes since v5:
 - No functional changes, just following cosmetic improvements.
 - Used BIT() macro to define bits instead of shifting 1s directly.
 - Added comment about bit layout in TCON register.
 - Made macros used to define bits have more meaningful parameter names.
 - Updated commit message.

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index aa94807..86a5771 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
new file mode 100644
index 0000000..fcc8b9a
--- /dev/null
+++ b/drivers/pwm/pwm-samsung.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * PWM driver for Samsung SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+/* For struct samsung_timer_variant and samsung_pwm_lock. */
+#include <clocksource/samsung_pwm.h>
+
+#define REG_TCFG0			0x00
+#define REG_TCFG1			0x04
+#define REG_TCON			0x08
+
+#define REG_TCNTB(chan)			(0x0c + ((chan) * 0xc))
+#define REG_TCMPB(chan)			(0x10 + ((chan) * 0xc))
+
+#define TCFG0_PRESCALER_MASK		0xff
+#define TCFG0_PRESCALER1_SHIFT		8
+
+#define TCFG1_MUX_MASK			0xf
+#define TCFG1_SHIFT(chan)		(4 * (chan))
+
+/*
+ * Each channel occupies 4 bits in TCON register, but there is a gap of 4
+ * bits (one channel) after channel 0, so channels have different numbering
+ * when accessing TCON register. See to_tcon_channel() function.
+ *
+ * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
+ * in its set of bits is 2 as opposed to 3 for other channels.
+ */
+#define TCON_START(chan)		BIT(4 * (chan) + 0)
+#define TCON_MANUALUPDATE(chan)		BIT(4 * (chan) + 1)
+#define TCON_INVERT(chan)		BIT(4 * (chan) + 2)
+#define _TCON_AUTORELOAD(chan)		BIT(4 * (chan) + 3)
+#define _TCON_AUTORELOAD4(chan)		BIT(4 * (chan) + 2)
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
+
+/**
+ * struct samsung_pwm_channel - private data of PWM channel
+ * @period_ns:	current period in nanoseconds programmed to the hardware
+ * @duty_ns:	current duty time in nanoseconds programmed to the hardware
+ * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
+ */
+struct samsung_pwm_channel {
+	u32 period_ns;
+	u32 duty_ns;
+	u32 tin_ns;
+};
+
+/**
+ * struct samsung_pwm_chip - private data of PWM chip
+ * @chip:		generic PWM chip
+ * @variant:		local copy of hardware variant data
+ * @inverter_mask:	inverter status for all channels - one bit per channel
+ * @base:		base address of mapped PWM registers
+ * @base_clk:		base clock used to drive the timers
+ * @tclk0:		external clock 0 (can be ERR_PTR if not present)
+ * @tclk1:		external clock 1 (can be ERR_PTR if not present)
+ */
+struct samsung_pwm_chip {
+	struct pwm_chip chip;
+	struct samsung_pwm_variant variant;
+	u8 inverter_mask;
+
+	void __iomem *base;
+	struct clk *base_clk;
+	struct clk *tclk0;
+	struct clk *tclk1;
+};
+
+#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
+/*
+ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
+ * and some registers need access synchronization. If both drivers are
+ * compiled in, the spinlock is defined in the clocksource driver,
+ * otherwise following definition is used.
+ *
+ * Currently we do not need any more complex synchronization method
+ * because all the supported SoCs contain only one instance of the PWM
+ * IP. Should this change, both drivers will need to be modified to
+ * properly synchronize accesses to particular instances.
+ */
+static DEFINE_SPINLOCK(samsung_pwm_lock);
+#endif
+
+static inline
+struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct samsung_pwm_chip, chip);
+}
+
+static inline unsigned int to_tcon_channel(unsigned int channel)
+{
+	/* TCON register has a gap of 4 bits (1 channel) after channel 0 */
+	return (channel == 0) ? 0 : (channel + 1);
+}
+
+static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
+				    unsigned int channel, u8 divisor)
+{
+	u8 shift = TCFG1_SHIFT(channel);
+	unsigned long flags;
+	u32 reg;
+	u8 bits;
+
+	bits = (fls(divisor) - 1) - pwm->variant.div_base;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	reg = readl(pwm->base + REG_TCFG1);
+	reg &= ~(TCFG1_MUX_MASK << shift);
+	reg |= bits << shift;
+	writel(reg, pwm->base + REG_TCFG1);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	u32 reg;
+
+	reg = readl(chip->base + REG_TCFG1);
+	reg >>= TCFG1_SHIFT(chan);
+	reg &= TCFG1_MUX_MASK;
+
+	return (BIT(reg) & variant->tclk_mask) == 0;
+}
+
+static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
+					      unsigned int chan)
+{
+	unsigned long rate;
+	u32 reg;
+
+	rate = clk_get_rate(chip->base_clk);
+
+	reg = readl(chip->base + REG_TCFG0);
+	if (chan >= 2)
+		reg >>= TCFG0_PRESCALER1_SHIFT;
+	reg &= TCFG0_PRESCALER_MASK;
+
+	return rate / (reg + 1);
+}
+
+static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
+					  unsigned int chan, unsigned long freq)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	unsigned long rate;
+	struct clk *clk;
+	u8 div;
+
+	if (!pwm_samsung_is_tdiv(chip, chan)) {
+		clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
+		if (!IS_ERR(clk)) {
+			rate = clk_get_rate(clk);
+			if (rate)
+				return rate;
+		}
+
+		dev_warn(chip->chip.dev,
+			"tclk of PWM %d is inoperational, using tdiv\n", chan);
+	}
+
+	rate = pwm_samsung_get_tin_rate(chip, chan);
+	dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
+
+	/*
+	 * Compare minimum PWM frequency that can be achieved with possible
+	 * divider settings and choose the lowest divisor that can generate
+	 * frequencies lower than requested.
+	 */
+	for (div = variant->div_base; div < 4; ++div)
+		if ((rate >> (variant->bits + div)) < freq)
+			break;
+
+	pwm_samsung_set_divisor(chip, chan, BIT(div));
+
+	return rate >> div;
+}
+
+static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *our_chan;
+
+	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
+		dev_warn(chip->dev,
+			"tried to request PWM channel %d without output\n",
+			pwm->hwpwm);
+		return -EINVAL;
+	}
+
+	our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
+	if (!our_chan)
+		return -ENOMEM;
+
+	pwm_set_chip_data(pwm, our_chan);
+
+	return 0;
+}
+
+static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	pwm_set_chip_data(pwm, NULL);
+	devm_kfree(chip->dev, pwm_get_chip_data(pwm));
+}
+
+static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_START(tcon_chan);
+	tcon |= TCON_MANUALUPDATE(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_MANUALUPDATE(tcon_chan);
+	tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+
+	return 0;
+}
+
+static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+	tcon &= ~TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+	u32 tin_ns = chan->tin_ns, tcnt, tcmp;
+
+	/*
+	 * We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits.
+	 */
+	if (period_ns > NSEC_PER_SEC)
+		return -ERANGE;
+
+	if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
+		return 0;
+
+	tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
+
+	/* We need tick count for calculation, not last tick. */
+	++tcnt;
+
+	/* Check to see if we are changing the clock rate of the PWM. */
+	if (chan->period_ns != period_ns) {
+		unsigned long tin_rate;
+		u32 period;
+
+		period = NSEC_PER_SEC / period_ns;
+
+		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+						duty_ns, period_ns, period);
+
+		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+
+		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NSEC_PER_SEC / tin_rate;
+		tcnt = period_ns / tin_ns;
+	}
+
+	/* Period is too short. */
+	if (tcnt <= 1)
+		return -ERANGE;
+
+	/* Note that counters count down. */
+	tcmp = duty_ns / tin_ns;
+
+	/* 0% duty is not available */
+	if (!tcmp)
+		++tcmp;
+
+	tcmp = tcnt - tcmp;
+
+	/* Decrement to get tick numbers, instead of tick counts. */
+	--tcnt;
+	/* -1UL will give 100% duty. */
+	--tcmp;
+
+	dev_dbg(our_chip->chip.dev,
+				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+
+	/* Update PWM registers. */
+	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
+	writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		pwm_samsung_enable(chip, pwm);
+
+	chan->period_ns = period_ns;
+	chan->tin_ns = tin_ns;
+	chan->duty_ns = duty_ns;
+
+	return 0;
+}
+
+static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
+				   unsigned int channel, bool invert)
+{
+	unsigned int tcon_chan = to_tcon_channel(channel);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(chip->base + REG_TCON);
+
+	if (invert) {
+		chip->inverter_mask |= BIT(channel);
+		tcon |= TCON_INVERT(tcon_chan);
+	} else {
+		chip->inverter_mask &= ~BIT(channel);
+		tcon &= ~TCON_INVERT(tcon_chan);
+	}
+
+	writel(tcon, chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	bool invert = (polarity == PWM_POLARITY_NORMAL);
+
+	/* Inverted means normal in the hardware. */
+	pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_samsung_ops = {
+	.request	= pwm_samsung_request,
+	.free		= pwm_samsung_free,
+	.enable		= pwm_samsung_enable,
+	.disable	= pwm_samsung_disable,
+	.config		= pwm_samsung_config,
+	.set_polarity	= pwm_samsung_set_polarity,
+	.owner		= THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static const struct samsung_pwm_variant s3c24xx_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= BIT(4),
+};
+
+static const struct samsung_pwm_variant s3c64xx_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
+};
+
+static const struct samsung_pwm_variant s5p64x0_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= 0,
+};
+
+static const struct samsung_pwm_variant s5pc100_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(5),
+};
+
+static const struct of_device_id samsung_pwm_matches[] = {
+	{ .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
+	{ .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
+	{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
+	{ .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
+	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
+	{},
+};
+
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	struct device_node *np = chip->chip.dev->of_node;
+	const struct of_device_id *match;
+	struct property *prop;
+	const __be32 *cur;
+	u32 val;
+
+	match = of_match_node(samsung_pwm_matches, np);
+	if (!match)
+		return -ENODEV;
+
+	memcpy(&chip->variant, match->data, sizeof(chip->variant));
+
+	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+		if (val >= SAMSUNG_PWM_NUM) {
+			dev_err(chip->chip.dev,
+				"%s: invalid channel index in samsung,pwm-outputs property\n",
+								__func__);
+			continue;
+		}
+		chip->variant.output_mask |= BIT(val);
+	}
+
+	return 0;
+}
+#else
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int pwm_samsung_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct samsung_pwm_chip *chip;
+	struct resource *res;
+	unsigned int chan;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->chip.dev = &pdev->dev;
+	chip->chip.ops = &pwm_samsung_ops;
+	chip->chip.base = -1;
+	chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = pwm_samsung_parse_dt(chip);
+		if (ret)
+			return ret;
+
+		chip->chip.of_xlate = of_pwm_xlate_with_flags;
+		chip->chip.of_pwm_n_cells = 3;
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data specified\n");
+			return -EINVAL;
+		}
+
+		memcpy(&chip->variant, pdev->dev.platform_data,
+							sizeof(chip->variant));
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	if (IS_ERR(chip->base_clk)) {
+		dev_err(dev, "failed to get timer base clk\n");
+		return PTR_ERR(chip->base_clk);
+	}
+
+	ret = clk_prepare_enable(chip->base_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable base clock\n");
+		return ret;
+	}
+
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan, true);
+
+	/* Following clocks are optional. */
+	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
+	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
+
+	platform_set_drvdata(pdev, chip);
+
+	ret = pwmchip_add(&chip->chip);
+	if (ret < 0) {
+		dev_err(dev, "failed to register PWM chip\n");
+		clk_disable_unprepare(chip->base_clk);
+		return ret;
+	}
+
+	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
+		clk_get_rate(chip->base_clk),
+		!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
+		!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
+
+	return 0;
+}
+
+static int pwm_samsung_remove(struct platform_device *pdev)
+{
+	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&chip->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_disable_unprepare(chip->base_clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_samsung_suspend(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/*
+	 * No one preserves these values during suspend so reset them.
+	 * Otherwise driver leaves PWM unconfigured if same values are
+	 * passed to pwm_config() next time.
+	 */
+	for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
+		struct pwm_device *pwm = &chip->chip.pwms[i];
+		struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+
+		if (!chan)
+			continue;
+
+		chan->period_ns = 0;
+		chan->duty_ns = 0;
+	}
+
+	return 0;
+}
+
+static int pwm_samsung_resume(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int chan;
+
+	/*
+	 * Inverter setting must be preserved across suspend/resume
+	 * as nobody really seems to configure it more than once.
+	 */
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan,
+					chip->inverter_mask & BIT(chan));
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_samsung_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
+};
+
+static struct platform_driver pwm_samsung_driver = {
+	.driver		= {
+		.name	= "samsung-pwm",
+		.owner	= THIS_MODULE,
+		.pm	= &pwm_samsung_pm_ops,
+		.of_match_table = of_match_ptr(samsung_pwm_matches),
+	},
+	.probe		= pwm_samsung_probe,
+	.remove		= pwm_samsung_remove,
+};
+module_platform_driver(pwm_samsung_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_ALIAS("platform:samsung-pwm");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* [PATCH v6 13/20] pwm: Add new pwm-samsung driver
@ 2013-07-23 23:43       ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-23 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch introduces new Samsung PWM driver, which is completely
rewritten to be multiplatform- and DeviceTree-aware.

In addition, remaining problems of old driver are fixed, such as:
 - proper handling of hardware variants,
 - synchronization on SMP systems,
 - handling of boundary parameter values,
 - hardware sharing with PWM clocksource driver,
 - undefined state of PWM output after stopping PWM channel.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
---
 drivers/pwm/Makefile      |   1 +
 drivers/pwm/pwm-samsung.c | 618 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 619 insertions(+)
 create mode 100644 drivers/pwm/pwm-samsung.c

Changes since v5:
 - No functional changes, just following cosmetic improvements.
 - Used BIT() macro to define bits instead of shifting 1s directly.
 - Added comment about bit layout in TCON register.
 - Made macros used to define bits have more meaningful parameter names.
 - Updated commit message.

diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index aa94807..86a5771 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung-legacy.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
new file mode 100644
index 0000000..fcc8b9a
--- /dev/null
+++ b/drivers/pwm/pwm-samsung.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * PWM driver for Samsung SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+
+/* For struct samsung_timer_variant and samsung_pwm_lock. */
+#include <clocksource/samsung_pwm.h>
+
+#define REG_TCFG0			0x00
+#define REG_TCFG1			0x04
+#define REG_TCON			0x08
+
+#define REG_TCNTB(chan)			(0x0c + ((chan) * 0xc))
+#define REG_TCMPB(chan)			(0x10 + ((chan) * 0xc))
+
+#define TCFG0_PRESCALER_MASK		0xff
+#define TCFG0_PRESCALER1_SHIFT		8
+
+#define TCFG1_MUX_MASK			0xf
+#define TCFG1_SHIFT(chan)		(4 * (chan))
+
+/*
+ * Each channel occupies 4 bits in TCON register, but there is a gap of 4
+ * bits (one channel) after channel 0, so channels have different numbering
+ * when accessing TCON register. See to_tcon_channel() function.
+ *
+ * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
+ * in its set of bits is 2 as opposed to 3 for other channels.
+ */
+#define TCON_START(chan)		BIT(4 * (chan) + 0)
+#define TCON_MANUALUPDATE(chan)		BIT(4 * (chan) + 1)
+#define TCON_INVERT(chan)		BIT(4 * (chan) + 2)
+#define _TCON_AUTORELOAD(chan)		BIT(4 * (chan) + 3)
+#define _TCON_AUTORELOAD4(chan)		BIT(4 * (chan) + 2)
+#define TCON_AUTORELOAD(chan)		\
+	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
+
+/**
+ * struct samsung_pwm_channel - private data of PWM channel
+ * @period_ns:	current period in nanoseconds programmed to the hardware
+ * @duty_ns:	current duty time in nanoseconds programmed to the hardware
+ * @tin_ns:	time of one timer tick in nanoseconds with current timer rate
+ */
+struct samsung_pwm_channel {
+	u32 period_ns;
+	u32 duty_ns;
+	u32 tin_ns;
+};
+
+/**
+ * struct samsung_pwm_chip - private data of PWM chip
+ * @chip:		generic PWM chip
+ * @variant:		local copy of hardware variant data
+ * @inverter_mask:	inverter status for all channels - one bit per channel
+ * @base:		base address of mapped PWM registers
+ * @base_clk:		base clock used to drive the timers
+ * @tclk0:		external clock 0 (can be ERR_PTR if not present)
+ * @tclk1:		external clock 1 (can be ERR_PTR if not present)
+ */
+struct samsung_pwm_chip {
+	struct pwm_chip chip;
+	struct samsung_pwm_variant variant;
+	u8 inverter_mask;
+
+	void __iomem *base;
+	struct clk *base_clk;
+	struct clk *tclk0;
+	struct clk *tclk1;
+};
+
+#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
+/*
+ * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
+ * and some registers need access synchronization. If both drivers are
+ * compiled in, the spinlock is defined in the clocksource driver,
+ * otherwise following definition is used.
+ *
+ * Currently we do not need any more complex synchronization method
+ * because all the supported SoCs contain only one instance of the PWM
+ * IP. Should this change, both drivers will need to be modified to
+ * properly synchronize accesses to particular instances.
+ */
+static DEFINE_SPINLOCK(samsung_pwm_lock);
+#endif
+
+static inline
+struct samsung_pwm_chip *to_samsung_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct samsung_pwm_chip, chip);
+}
+
+static inline unsigned int to_tcon_channel(unsigned int channel)
+{
+	/* TCON register has a gap of 4 bits (1 channel) after channel 0 */
+	return (channel == 0) ? 0 : (channel + 1);
+}
+
+static void pwm_samsung_set_divisor(struct samsung_pwm_chip *pwm,
+				    unsigned int channel, u8 divisor)
+{
+	u8 shift = TCFG1_SHIFT(channel);
+	unsigned long flags;
+	u32 reg;
+	u8 bits;
+
+	bits = (fls(divisor) - 1) - pwm->variant.div_base;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	reg = readl(pwm->base + REG_TCFG1);
+	reg &= ~(TCFG1_MUX_MASK << shift);
+	reg |= bits << shift;
+	writel(reg, pwm->base + REG_TCFG1);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *chip, unsigned int chan)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	u32 reg;
+
+	reg = readl(chip->base + REG_TCFG1);
+	reg >>= TCFG1_SHIFT(chan);
+	reg &= TCFG1_MUX_MASK;
+
+	return (BIT(reg) & variant->tclk_mask) == 0;
+}
+
+static unsigned long pwm_samsung_get_tin_rate(struct samsung_pwm_chip *chip,
+					      unsigned int chan)
+{
+	unsigned long rate;
+	u32 reg;
+
+	rate = clk_get_rate(chip->base_clk);
+
+	reg = readl(chip->base + REG_TCFG0);
+	if (chan >= 2)
+		reg >>= TCFG0_PRESCALER1_SHIFT;
+	reg &= TCFG0_PRESCALER_MASK;
+
+	return rate / (reg + 1);
+}
+
+static unsigned long pwm_samsung_calc_tin(struct samsung_pwm_chip *chip,
+					  unsigned int chan, unsigned long freq)
+{
+	struct samsung_pwm_variant *variant = &chip->variant;
+	unsigned long rate;
+	struct clk *clk;
+	u8 div;
+
+	if (!pwm_samsung_is_tdiv(chip, chan)) {
+		clk = (chan < 2) ? chip->tclk0 : chip->tclk1;
+		if (!IS_ERR(clk)) {
+			rate = clk_get_rate(clk);
+			if (rate)
+				return rate;
+		}
+
+		dev_warn(chip->chip.dev,
+			"tclk of PWM %d is inoperational, using tdiv\n", chan);
+	}
+
+	rate = pwm_samsung_get_tin_rate(chip, chan);
+	dev_dbg(chip->chip.dev, "tin parent at %lu\n", rate);
+
+	/*
+	 * Compare minimum PWM frequency that can be achieved with possible
+	 * divider settings and choose the lowest divisor that can generate
+	 * frequencies lower than requested.
+	 */
+	for (div = variant->div_base; div < 4; ++div)
+		if ((rate >> (variant->bits + div)) < freq)
+			break;
+
+	pwm_samsung_set_divisor(chip, chan, BIT(div));
+
+	return rate >> div;
+}
+
+static int pwm_samsung_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *our_chan;
+
+	if (!(our_chip->variant.output_mask & BIT(pwm->hwpwm))) {
+		dev_warn(chip->dev,
+			"tried to request PWM channel %d without output\n",
+			pwm->hwpwm);
+		return -EINVAL;
+	}
+
+	our_chan = devm_kzalloc(chip->dev, sizeof(*our_chan), GFP_KERNEL);
+	if (!our_chan)
+		return -ENOMEM;
+
+	pwm_set_chip_data(pwm, our_chan);
+
+	return 0;
+}
+
+static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	pwm_set_chip_data(pwm, NULL);
+	devm_kfree(chip->dev, pwm_get_chip_data(pwm));
+}
+
+static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_START(tcon_chan);
+	tcon |= TCON_MANUALUPDATE(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	tcon &= ~TCON_MANUALUPDATE(tcon_chan);
+	tcon |= TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+
+	return 0;
+}
+
+static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	unsigned int tcon_chan = to_tcon_channel(pwm->hwpwm);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(our_chip->base + REG_TCON);
+	tcon &= ~TCON_AUTORELOAD(tcon_chan);
+	writel(tcon, our_chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+	u32 tin_ns = chan->tin_ns, tcnt, tcmp;
+
+	/*
+	 * We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits.
+	 */
+	if (period_ns > NSEC_PER_SEC)
+		return -ERANGE;
+
+	if (period_ns == chan->period_ns && duty_ns == chan->duty_ns)
+		return 0;
+
+	tcnt = readl(our_chip->base + REG_TCNTB(pwm->hwpwm));
+
+	/* We need tick count for calculation, not last tick. */
+	++tcnt;
+
+	/* Check to see if we are changing the clock rate of the PWM. */
+	if (chan->period_ns != period_ns) {
+		unsigned long tin_rate;
+		u32 period;
+
+		period = NSEC_PER_SEC / period_ns;
+
+		dev_dbg(our_chip->chip.dev, "duty_ns=%d, period_ns=%d (%u)\n",
+						duty_ns, period_ns, period);
+
+		tin_rate = pwm_samsung_calc_tin(our_chip, pwm->hwpwm, period);
+
+		dev_dbg(our_chip->chip.dev, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NSEC_PER_SEC / tin_rate;
+		tcnt = period_ns / tin_ns;
+	}
+
+	/* Period is too short. */
+	if (tcnt <= 1)
+		return -ERANGE;
+
+	/* Note that counters count down. */
+	tcmp = duty_ns / tin_ns;
+
+	/* 0% duty is not available */
+	if (!tcmp)
+		++tcmp;
+
+	tcmp = tcnt - tcmp;
+
+	/* Decrement to get tick numbers, instead of tick counts. */
+	--tcnt;
+	/* -1UL will give 100% duty. */
+	--tcmp;
+
+	dev_dbg(our_chip->chip.dev,
+				"tin_ns=%u, tcmp=%u/%u\n", tin_ns, tcmp, tcnt);
+
+	/* Update PWM registers. */
+	writel(tcnt, our_chip->base + REG_TCNTB(pwm->hwpwm));
+	writel(tcmp, our_chip->base + REG_TCMPB(pwm->hwpwm));
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		pwm_samsung_enable(chip, pwm);
+
+	chan->period_ns = period_ns;
+	chan->tin_ns = tin_ns;
+	chan->duty_ns = duty_ns;
+
+	return 0;
+}
+
+static void pwm_samsung_set_invert(struct samsung_pwm_chip *chip,
+				   unsigned int channel, bool invert)
+{
+	unsigned int tcon_chan = to_tcon_channel(channel);
+	unsigned long flags;
+	u32 tcon;
+
+	spin_lock_irqsave(&samsung_pwm_lock, flags);
+
+	tcon = readl(chip->base + REG_TCON);
+
+	if (invert) {
+		chip->inverter_mask |= BIT(channel);
+		tcon |= TCON_INVERT(tcon_chan);
+	} else {
+		chip->inverter_mask &= ~BIT(channel);
+		tcon &= ~TCON_INVERT(tcon_chan);
+	}
+
+	writel(tcon, chip->base + REG_TCON);
+
+	spin_unlock_irqrestore(&samsung_pwm_lock, flags);
+}
+
+static int pwm_samsung_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	struct samsung_pwm_chip *our_chip = to_samsung_pwm_chip(chip);
+	bool invert = (polarity == PWM_POLARITY_NORMAL);
+
+	/* Inverted means normal in the hardware. */
+	pwm_samsung_set_invert(our_chip, pwm->hwpwm, invert);
+
+	return 0;
+}
+
+static const struct pwm_ops pwm_samsung_ops = {
+	.request	= pwm_samsung_request,
+	.free		= pwm_samsung_free,
+	.enable		= pwm_samsung_enable,
+	.disable	= pwm_samsung_disable,
+	.config		= pwm_samsung_config,
+	.set_polarity	= pwm_samsung_set_polarity,
+	.owner		= THIS_MODULE,
+};
+
+#ifdef CONFIG_OF
+static const struct samsung_pwm_variant s3c24xx_variant = {
+	.bits		= 16,
+	.div_base	= 1,
+	.has_tint_cstat	= false,
+	.tclk_mask	= BIT(4),
+};
+
+static const struct samsung_pwm_variant s3c64xx_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(7) | BIT(6) | BIT(5),
+};
+
+static const struct samsung_pwm_variant s5p64x0_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= 0,
+};
+
+static const struct samsung_pwm_variant s5pc100_variant = {
+	.bits		= 32,
+	.div_base	= 0,
+	.has_tint_cstat	= true,
+	.tclk_mask	= BIT(5),
+};
+
+static const struct of_device_id samsung_pwm_matches[] = {
+	{ .compatible = "samsung,s3c2410-pwm", .data = &s3c24xx_variant },
+	{ .compatible = "samsung,s3c6400-pwm", .data = &s3c64xx_variant },
+	{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
+	{ .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
+	{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
+	{},
+};
+
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	struct device_node *np = chip->chip.dev->of_node;
+	const struct of_device_id *match;
+	struct property *prop;
+	const __be32 *cur;
+	u32 val;
+
+	match = of_match_node(samsung_pwm_matches, np);
+	if (!match)
+		return -ENODEV;
+
+	memcpy(&chip->variant, match->data, sizeof(chip->variant));
+
+	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+		if (val >= SAMSUNG_PWM_NUM) {
+			dev_err(chip->chip.dev,
+				"%s: invalid channel index in samsung,pwm-outputs property\n",
+								__func__);
+			continue;
+		}
+		chip->variant.output_mask |= BIT(val);
+	}
+
+	return 0;
+}
+#else
+static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int pwm_samsung_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct samsung_pwm_chip *chip;
+	struct resource *res;
+	unsigned int chan;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->chip.dev = &pdev->dev;
+	chip->chip.ops = &pwm_samsung_ops;
+	chip->chip.base = -1;
+	chip->chip.npwm = SAMSUNG_PWM_NUM;
+	chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
+
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = pwm_samsung_parse_dt(chip);
+		if (ret)
+			return ret;
+
+		chip->chip.of_xlate = of_pwm_xlate_with_flags;
+		chip->chip.of_pwm_n_cells = 3;
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data specified\n");
+			return -EINVAL;
+		}
+
+		memcpy(&chip->variant, pdev->dev.platform_data,
+							sizeof(chip->variant));
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	chip->base_clk = devm_clk_get(&pdev->dev, "timers");
+	if (IS_ERR(chip->base_clk)) {
+		dev_err(dev, "failed to get timer base clk\n");
+		return PTR_ERR(chip->base_clk);
+	}
+
+	ret = clk_prepare_enable(chip->base_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable base clock\n");
+		return ret;
+	}
+
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan)
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan, true);
+
+	/* Following clocks are optional. */
+	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
+	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
+
+	platform_set_drvdata(pdev, chip);
+
+	ret = pwmchip_add(&chip->chip);
+	if (ret < 0) {
+		dev_err(dev, "failed to register PWM chip\n");
+		clk_disable_unprepare(chip->base_clk);
+		return ret;
+	}
+
+	dev_dbg(dev, "base_clk at %lu, tclk0 at %lu, tclk1 at %lu\n",
+		clk_get_rate(chip->base_clk),
+		!IS_ERR(chip->tclk0) ? clk_get_rate(chip->tclk0) : 0,
+		!IS_ERR(chip->tclk1) ? clk_get_rate(chip->tclk1) : 0);
+
+	return 0;
+}
+
+static int pwm_samsung_remove(struct platform_device *pdev)
+{
+	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&chip->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_disable_unprepare(chip->base_clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_samsung_suspend(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int i;
+
+	/*
+	 * No one preserves these values during suspend so reset them.
+	 * Otherwise driver leaves PWM unconfigured if same values are
+	 * passed to pwm_config() next time.
+	 */
+	for (i = 0; i < SAMSUNG_PWM_NUM; ++i) {
+		struct pwm_device *pwm = &chip->chip.pwms[i];
+		struct samsung_pwm_channel *chan = pwm_get_chip_data(pwm);
+
+		if (!chan)
+			continue;
+
+		chan->period_ns = 0;
+		chan->duty_ns = 0;
+	}
+
+	return 0;
+}
+
+static int pwm_samsung_resume(struct device *dev)
+{
+	struct samsung_pwm_chip *chip = dev_get_drvdata(dev);
+	unsigned int chan;
+
+	/*
+	 * Inverter setting must be preserved across suspend/resume
+	 * as nobody really seems to configure it more than once.
+	 */
+	for (chan = 0; chan < SAMSUNG_PWM_NUM; ++chan) {
+		if (chip->variant.output_mask & BIT(chan))
+			pwm_samsung_set_invert(chip, chan,
+					chip->inverter_mask & BIT(chan));
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_samsung_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pwm_samsung_suspend, pwm_samsung_resume)
+};
+
+static struct platform_driver pwm_samsung_driver = {
+	.driver		= {
+		.name	= "samsung-pwm",
+		.owner	= THIS_MODULE,
+		.pm	= &pwm_samsung_pm_ops,
+		.of_match_table = of_match_ptr(samsung_pwm_matches),
+	},
+	.probe		= pwm_samsung_probe,
+	.remove		= pwm_samsung_remove,
+};
+module_platform_driver(pwm_samsung_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tomasz Figa <tomasz.figa@gmail.com>");
+MODULE_ALIAS("platform:samsung-pwm");
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-28 12:22   ` Mark Brown
  -1 siblings, 0 replies; 124+ messages in thread
From: Mark Brown @ 2013-07-28 12:22 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Thierry Reding

[-- Attachment #1: Type: text/plain, Size: 207 bytes --]

On Sat, Jul 20, 2013 at 02:04:12AM +0200, Tomasz Figa wrote:

> [Also not sure on what boards, but still]
> Tested-by: Mark Brown <broonie@linaro.org>

Just retested this (on Cragganmore), still works fine.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-28 12:22   ` Mark Brown
  0 siblings, 0 replies; 124+ messages in thread
From: Mark Brown @ 2013-07-28 12:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 20, 2013 at 02:04:12AM +0200, Tomasz Figa wrote:

> [Also not sure on what boards, but still]
> Tested-by: Mark Brown <broonie@linaro.org>

Just retested this (on Cragganmore), still works fine.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130728/2ccd1f43/attachment.sig>

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 12/20] pwm: samsung: Rename to pwm-samsung-legacy
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-29 11:44     ` Thierry Reding
  -1 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-29 11:44 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 610 bytes --]

On Sat, Jul 20, 2013 at 02:04:25AM +0200, Tomasz Figa wrote:
> This patch renames the old pwm-samsung driver to pwm-samsung-legacy to
> create place for the new, rewritten, DT-aware pwm-samsung driver using
> Samsung PWM/timer master driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/pwm/Makefile                                | 2 +-
>  drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} | 0
>  2 files changed, 1 insertion(+), 1 deletion(-)
>  rename drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} (100%)

Acked-by: Thierry Reding <thierry.reding@gmail.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 12/20] pwm: samsung: Rename to pwm-samsung-legacy
@ 2013-07-29 11:44     ` Thierry Reding
  0 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-29 11:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 20, 2013 at 02:04:25AM +0200, Tomasz Figa wrote:
> This patch renames the old pwm-samsung driver to pwm-samsung-legacy to
> create place for the new, rewritten, DT-aware pwm-samsung driver using
> Samsung PWM/timer master driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/pwm/Makefile                                | 2 +-
>  drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} | 0
>  2 files changed, 1 insertion(+), 1 deletion(-)
>  rename drivers/pwm/{pwm-samsung.c => pwm-samsung-legacy.c} (100%)

Acked-by: Thierry Reding <thierry.reding@gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130729/b9cc565c/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 13/20] pwm: Add new pwm-samsung driver
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-29 11:44     ` Thierry Reding
  -1 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-29 11:44 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 527 bytes --]

On Sat, Jul 20, 2013 at 02:04:26AM +0200, Tomasz Figa wrote:
> This patch introduces new Samsung PWM driver, which uses Samsung
> PWM/timer master driver to control shared parts of the hardware.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/pwm/Makefile      |   1 +
>  drivers/pwm/pwm-samsung.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 607 insertions(+)
>  create mode 100644 drivers/pwm/pwm-samsung.c

Acked-by: Thierry Reding <thierry.reding@gmail.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 13/20] pwm: Add new pwm-samsung driver
@ 2013-07-29 11:44     ` Thierry Reding
  0 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-29 11:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 20, 2013 at 02:04:26AM +0200, Tomasz Figa wrote:
> This patch introduces new Samsung PWM driver, which uses Samsung
> PWM/timer master driver to control shared parts of the hardware.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/pwm/Makefile      |   1 +
>  drivers/pwm/pwm-samsung.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 607 insertions(+)
>  create mode 100644 drivers/pwm/pwm-samsung.c

Acked-by: Thierry Reding <thierry.reding@gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130729/87153f83/attachment.sig>

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 16/20] pwm: Remove superseded pwm-samsung-legacy driver
  2013-07-20  0:04   ` Tomasz Figa
@ 2013-07-29 11:45     ` Thierry Reding
  -1 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-29 11:45 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown

[-- Attachment #1: Type: text/plain, Size: 517 bytes --]

On Sat, Jul 20, 2013 at 02:04:29AM +0200, Tomasz Figa wrote:
> This patch removes the now unused pwm-samsung-legacy driver, which was
> replaced by new pwm-samsung driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/pwm/Makefile             |   1 -
>  drivers/pwm/pwm-samsung-legacy.c | 353 ---------------------------------------
>  2 files changed, 354 deletions(-)
>  delete mode 100644 drivers/pwm/pwm-samsung-legacy.c

Acked-by: Thierry Reding <thierry.reding@gmail.com>

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 16/20] pwm: Remove superseded pwm-samsung-legacy driver
@ 2013-07-29 11:45     ` Thierry Reding
  0 siblings, 0 replies; 124+ messages in thread
From: Thierry Reding @ 2013-07-29 11:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 20, 2013 at 02:04:29AM +0200, Tomasz Figa wrote:
> This patch removes the now unused pwm-samsung-legacy driver, which was
> replaced by new pwm-samsung driver.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
>  drivers/pwm/Makefile             |   1 -
>  drivers/pwm/pwm-samsung-legacy.c | 353 ---------------------------------------
>  2 files changed, 354 deletions(-)
>  delete mode 100644 drivers/pwm/pwm-samsung-legacy.c

Acked-by: Thierry Reding <thierry.reding@gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130729/74f9e49b/attachment.sig>

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v6 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
  2013-07-23 23:32               ` Tomasz Figa
@ 2013-07-29 13:08                 ` Daniel Lezcano
  -1 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-29 13:08 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 07/24/2013 01:32 AM, Tomasz Figa wrote:
> PWM channel 4 has its autoreload bit located at different position. This
> patch fixes the driver to account for that.
> 
> This fixes a problem with the clocksource hanging after it overflows because
> it is not reloaded any more.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>


>  drivers/clocksource/samsung_pwm_timer.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> Changes since v5:
>  - Added more detailed comment about bit layout in TCON register.
> 
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 3fa5b07..5d0049f 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -44,10 +44,21 @@
>  #define TCFG1_SHIFT(x)	  		((x) * 4)
>  #define TCFG1_MUX_MASK	  		0xf
>  
> +/*
> + * Each channel occupies 4 bits in TCON register, but there is a gap of 4
> + * bits (one channel) after channel 0, so channels have different numbering
> + * when accessing TCON register.
> + *
> + * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
> + * in its set of bits is 2 as opposed to 3 for other channels.
> + */
>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> +#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> +#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
> +#define TCON_AUTORELOAD(chan)		\
> +	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
>  
>  DEFINE_SPINLOCK(samsung_pwm_lock);
>  EXPORT_SYMBOL(samsung_pwm_lock);
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v6 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
@ 2013-07-29 13:08                 ` Daniel Lezcano
  0 siblings, 0 replies; 124+ messages in thread
From: Daniel Lezcano @ 2013-07-29 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/24/2013 01:32 AM, Tomasz Figa wrote:
> PWM channel 4 has its autoreload bit located at different position. This
> patch fixes the driver to account for that.
> 
> This fixes a problem with the clocksource hanging after it overflows because
> it is not reloaded any more.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>


>  drivers/clocksource/samsung_pwm_timer.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> Changes since v5:
>  - Added more detailed comment about bit layout in TCON register.
> 
> diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c
> index 3fa5b07..5d0049f 100644
> --- a/drivers/clocksource/samsung_pwm_timer.c
> +++ b/drivers/clocksource/samsung_pwm_timer.c
> @@ -44,10 +44,21 @@
>  #define TCFG1_SHIFT(x)	  		((x) * 4)
>  #define TCFG1_MUX_MASK	  		0xf
>  
> +/*
> + * Each channel occupies 4 bits in TCON register, but there is a gap of 4
> + * bits (one channel) after channel 0, so channels have different numbering
> + * when accessing TCON register.
> + *
> + * In addition, the location of autoreload bit for channel 4 (TCON channel 5)
> + * in its set of bits is 2 as opposed to 3 for other channels.
> + */
>  #define TCON_START(chan)		(1 << (4 * (chan) + 0))
>  #define TCON_MANUALUPDATE(chan)		(1 << (4 * (chan) + 1))
>  #define TCON_INVERT(chan)		(1 << (4 * (chan) + 2))
> -#define TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> +#define _TCON_AUTORELOAD(chan)		(1 << (4 * (chan) + 3))
> +#define _TCON_AUTORELOAD4(chan)		(1 << (4 * (chan) + 2))
> +#define TCON_AUTORELOAD(chan)		\
> +	((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan))
>  
>  DEFINE_SPINLOCK(samsung_pwm_lock);
>  EXPORT_SYMBOL(samsung_pwm_lock);
> 


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-20  0:04 ` Tomasz Figa
@ 2013-07-31 19:03   ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-31 19:03 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, linux-pwm, Kukjin Kim, Arnd Bergmann,
	Olof Johansson, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding

Hi Kukjin,

Since I think we already got all the necessary Acks, do you want me to 
send you a pull request or you already have this series applied (I can't 
see it in your tree on kernel.org)?

Best regards,
Tomasz

On Saturday 20 of July 2013 02:04:12 Tomasz Figa wrote:
> Since we now have a proper Samsung PWM clocksource driver in place,
> we can proceed with further cleanup of PWM timers support on Samsung
> SoCs.
> 
> This series attempts to achieve this goal by:
>  1) fixing up few things in samsung_pwm_timer clocksource driver,
>  2) moving remaining Samsung platforms to the new clocksource driver,
>  3) removing old clocksource driver,
>  4) adding new multiplatform- and DT-aware PWM driver,
>  5) moving all Samsung platforms to use the new PWM driver,
>  6) removing old PWM driver,
>  7) removing all PWM-related code that is not used anymore.
> 
> Cleaning up the PWM driver is a bit tricky, because the design of
> current driver makes it completely unsuitable for DT and multiplatform
> and would require a heavy rework to make it usable, breaking any
> existing Samsung PWM users by the way. To avoid any breakage this
> series first renames the old driver, then adds new one using original
> name, migrates all platforms to use it and then finally removes the old
> driver.
> 
> See particular patches for more detailed descriptions.
> 
> [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> PWM0 attached to a scope)]
> Tested-by: Tomasz Figa <tomasz.figa@gmail.com>
> 
> [On S3C2440-based Mini2440 board]
> Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
> 
> [On a s3c2416 based machine]
> Tested-by: Heiko Stuebner <heiko@sntech.de>
> 
> [Also not sure on what boards, but still]
> Tested-by: Mark Brown <broonie@linaro.org>
> 
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Thierry Reding <thierry.reding@gmail.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
> 
> Changes since v3:
>  - added two extra clocksource driver fixes to the series (patches 1,
> 2), - added comment explaining why only a simple synchronization is
> needed between clocksource and PWM drivers,
>  - some stylistic fixes,
>  - rebased to 3.11-rc1.
> Changes since v2:
>  - replaced __raw_{readl,writel} with {readl,writel},
>  - corrected some commit messages,
>  - used git format-patch -M to detect rename.
> Changes since v1:
>  - made sure that suspend/resume is handled correctly in both
>    clocksource and PWM drivers,
>  - fixed incorrect definition of AUTORELOAD bit for channel 4,
>  - fixed order of registering PWM device and calling samsung_bl_set(),
>    which assumes that PWM device has been already registered,
>  - corrected commit messages of several patches,
>  - addressed all the valid comments from reviewers, including cleanup
>    of most code originally copied from previous PWM driver,
>  - rebased on top of current Kgene's for-next,
>  - tested on Exynos4210, verifying correct PWM output with a scope.
> 
> Tomasz Figa (20):
>   clocksource: samsung_pwm_timer: Do not request PWM mem region
>   clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
>   clocksource: samsung_pwm_timer: Cache clocksource register address
>   clocksource: samsung_pwm_timer: Do not use clocksource_mmio
>   clocksource: samsung_pwm_timer: Handle suspend/resume correctly
>   ARM: SAMSUNG: Unify base address definitions of timer block
>   ARM: SAMSUNG: Add new PWM platform device
>   ARM: SAMSUNG: Set PWM platform data
>   ARM: SAMSUNG: Move all platforms to new clocksource driver
>   ARM: SAMSUNG: Remove old samsung-time driver
>   ARM: SAMSUNG: Remove unused PWM timer IRQ chip code
>   pwm: samsung: Rename to pwm-samsung-legacy
>   pwm: Add new pwm-samsung driver
>   ARM: SAMSUNG: Rework private data handling in dev-backlight
>   ARM: SAMSUNG: Modify board files to use new PWM platform device
>   pwm: Remove superseded pwm-samsung-legacy driver
>   ARM: SAMSUNG: Remove old PWM timer platform devices
>   ARM: SAMSUNG: Remove pwm-clock infrastructure
>   ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header
>   ARM: SAMSUNG: Remove plat/regs-timer.h header
> 
>  arch/arm/Kconfig                                   |  11 +-
>  arch/arm/mach-s3c24xx/Kconfig                      |   6 -
>  arch/arm/mach-s3c24xx/clock-s3c2410.c              |   1 -
>  arch/arm/mach-s3c24xx/clock-s3c2412.c              |   1 -
>  arch/arm/mach-s3c24xx/clock-s3c2416.c              |   2 -
>  arch/arm/mach-s3c24xx/clock-s3c2443.c              |   2 -
>  arch/arm/mach-s3c24xx/common.c                     |  27 +
>  arch/arm/mach-s3c24xx/include/mach/map.h           |   2 +
>  arch/arm/mach-s3c24xx/mach-h1940.c                 |   4 +-
>  arch/arm/mach-s3c24xx/mach-rx1950.c                |   5 +-
>  arch/arm/mach-s3c64xx/Kconfig                      |   2 -
>  arch/arm/mach-s3c64xx/clock.c                      |   2 -
>  arch/arm/mach-s3c64xx/common.c                     |  32 +-
>  arch/arm/mach-s3c64xx/include/mach/irqs.h          |   8 -
>  arch/arm/mach-s3c64xx/include/mach/map.h           |   1 +
>  arch/arm/mach-s3c64xx/irq-pm.c                     |   2 -
>  arch/arm/mach-s3c64xx/mach-crag6410.c              |   4 +-
>  arch/arm/mach-s3c64xx/mach-hmt.c                   |   4 +-
>  arch/arm/mach-s3c64xx/mach-smartq.c                |   4 +-
>  arch/arm/mach-s3c64xx/mach-smdk6410.c              |   5 +-
>  arch/arm/mach-s5p64x0/Kconfig                      |   2 -
>  arch/arm/mach-s5p64x0/clock-s5p6440.c              |   2 -
>  arch/arm/mach-s5p64x0/clock-s5p6450.c              |   2 -
>  arch/arm/mach-s5p64x0/common.c                     |  27 +
>  arch/arm/mach-s5p64x0/include/mach/irqs.h          |   2 -
>  arch/arm/mach-s5p64x0/include/mach/map.h           |   1 +
>  arch/arm/mach-s5p64x0/mach-smdk6440.c              |   5 +-
>  arch/arm/mach-s5p64x0/mach-smdk6450.c              |   5 +-
>  arch/arm/mach-s5p64x0/pm.c                         |   3 -
>  arch/arm/mach-s5pc100/Kconfig                      |   1 -
>  arch/arm/mach-s5pc100/clock.c                      |   2 -
>  arch/arm/mach-s5pc100/common.c                     |  28 +
>  arch/arm/mach-s5pc100/include/mach/irqs.h          |   2 -
>  arch/arm/mach-s5pc100/include/mach/map.h           |   1 +
>  arch/arm/mach-s5pc100/mach-smdkc100.c              |   5 +-
>  arch/arm/mach-s5pv210/Kconfig                      |   1 -
>  arch/arm/mach-s5pv210/clock.c                      |   1 -
>  arch/arm/mach-s5pv210/common.c                     |  28 +
>  arch/arm/mach-s5pv210/include/mach/irqs.h          |   2 -
>  arch/arm/mach-s5pv210/include/mach/map.h           |   1 +
>  arch/arm/mach-s5pv210/mach-smdkv210.c              |   5 +-
>  arch/arm/mach-s5pv210/pm.c                         |  10 -
>  arch/arm/plat-samsung/Kconfig                      |  14 -
>  arch/arm/plat-samsung/Makefile                     |   3 -
>  arch/arm/plat-samsung/dev-backlight.c              |  61 +-
>  arch/arm/plat-samsung/devs.c                       |  42 +-
>  arch/arm/plat-samsung/include/plat/clock.h         |   4 -
>  arch/arm/plat-samsung/include/plat/devs.h          |   1 +
>  arch/arm/plat-samsung/include/plat/irq-vic-timer.h |  13 -
>  arch/arm/plat-samsung/include/plat/irqs.h          |   9 -
>  arch/arm/plat-samsung/include/plat/pwm-clock.h     |  81 ---
>  arch/arm/plat-samsung/include/plat/pwm-core.h      |  24 +
>  arch/arm/plat-samsung/include/plat/regs-timer.h    | 124 ----
>  arch/arm/plat-samsung/include/plat/samsung-time.h  |  23 -
>  arch/arm/plat-samsung/irq-vic-timer.c              |  98 ---
>  arch/arm/plat-samsung/pwm-clock.c                  | 474 --------------
> arch/arm/plat-samsung/s5p-irq.c                    |   4 -
>  arch/arm/plat-samsung/samsung-time.c               | 394 ------------
>  drivers/clocksource/Kconfig                        |   1 -
>  drivers/clocksource/samsung_pwm_timer.c            |  98 +--
>  drivers/pwm/pwm-samsung.c                          | 701
> ++++++++++++++------- 61 files changed, 768 insertions(+), 1662
> deletions(-)
>  delete mode 100644 arch/arm/plat-samsung/include/plat/irq-vic-timer.h
>  delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-clock.h
>  create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
>  delete mode 100644 arch/arm/plat-samsung/include/plat/regs-timer.h
>  delete mode 100644 arch/arm/plat-samsung/irq-vic-timer.c
>  delete mode 100644 arch/arm/plat-samsung/pwm-clock.c
>  delete mode 100644 arch/arm/plat-samsung/samsung-time.c

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-07-31 19:03   ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-07-31 19:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kukjin,

Since I think we already got all the necessary Acks, do you want me to 
send you a pull request or you already have this series applied (I can't 
see it in your tree on kernel.org)?

Best regards,
Tomasz

On Saturday 20 of July 2013 02:04:12 Tomasz Figa wrote:
> Since we now have a proper Samsung PWM clocksource driver in place,
> we can proceed with further cleanup of PWM timers support on Samsung
> SoCs.
> 
> This series attempts to achieve this goal by:
>  1) fixing up few things in samsung_pwm_timer clocksource driver,
>  2) moving remaining Samsung platforms to the new clocksource driver,
>  3) removing old clocksource driver,
>  4) adding new multiplatform- and DT-aware PWM driver,
>  5) moving all Samsung platforms to use the new PWM driver,
>  6) removing old PWM driver,
>  7) removing all PWM-related code that is not used anymore.
> 
> Cleaning up the PWM driver is a bit tricky, because the design of
> current driver makes it completely unsuitable for DT and multiplatform
> and would require a heavy rework to make it usable, breaking any
> existing Samsung PWM users by the way. To avoid any breakage this
> series first renames the old driver, then adds new one using original
> name, migrates all platforms to use it and then finally removes the old
> driver.
> 
> See particular patches for more detailed descriptions.
> 
> [On S3C6410-based Tiny6410 (Mini6410-compatible) with pwm-beeper,
> SMDK6410 with PWM backlight and Exynos4210-based Origen board (with
> PWM0 attached to a scope)]
> Tested-by: Tomasz Figa <tomasz.figa@gmail.com>
> 
> [On S3C2440-based Mini2440 board]
> Tested-by: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
> 
> [On a s3c2416 based machine]
> Tested-by: Heiko Stuebner <heiko@sntech.de>
> 
> [Also not sure on what boards, but still]
> Tested-by: Mark Brown <broonie@linaro.org>
> 
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Thierry Reding <thierry.reding@gmail.com>
> Acked-by: Heiko Stuebner <heiko@sntech.de>
> 
> Changes since v3:
>  - added two extra clocksource driver fixes to the series (patches 1,
> 2), - added comment explaining why only a simple synchronization is
> needed between clocksource and PWM drivers,
>  - some stylistic fixes,
>  - rebased to 3.11-rc1.
> Changes since v2:
>  - replaced __raw_{readl,writel} with {readl,writel},
>  - corrected some commit messages,
>  - used git format-patch -M to detect rename.
> Changes since v1:
>  - made sure that suspend/resume is handled correctly in both
>    clocksource and PWM drivers,
>  - fixed incorrect definition of AUTORELOAD bit for channel 4,
>  - fixed order of registering PWM device and calling samsung_bl_set(),
>    which assumes that PWM device has been already registered,
>  - corrected commit messages of several patches,
>  - addressed all the valid comments from reviewers, including cleanup
>    of most code originally copied from previous PWM driver,
>  - rebased on top of current Kgene's for-next,
>  - tested on Exynos4210, verifying correct PWM output with a scope.
> 
> Tomasz Figa (20):
>   clocksource: samsung_pwm_timer: Do not request PWM mem region
>   clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit
>   clocksource: samsung_pwm_timer: Cache clocksource register address
>   clocksource: samsung_pwm_timer: Do not use clocksource_mmio
>   clocksource: samsung_pwm_timer: Handle suspend/resume correctly
>   ARM: SAMSUNG: Unify base address definitions of timer block
>   ARM: SAMSUNG: Add new PWM platform device
>   ARM: SAMSUNG: Set PWM platform data
>   ARM: SAMSUNG: Move all platforms to new clocksource driver
>   ARM: SAMSUNG: Remove old samsung-time driver
>   ARM: SAMSUNG: Remove unused PWM timer IRQ chip code
>   pwm: samsung: Rename to pwm-samsung-legacy
>   pwm: Add new pwm-samsung driver
>   ARM: SAMSUNG: Rework private data handling in dev-backlight
>   ARM: SAMSUNG: Modify board files to use new PWM platform device
>   pwm: Remove superseded pwm-samsung-legacy driver
>   ARM: SAMSUNG: Remove old PWM timer platform devices
>   ARM: SAMSUNG: Remove pwm-clock infrastructure
>   ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header
>   ARM: SAMSUNG: Remove plat/regs-timer.h header
> 
>  arch/arm/Kconfig                                   |  11 +-
>  arch/arm/mach-s3c24xx/Kconfig                      |   6 -
>  arch/arm/mach-s3c24xx/clock-s3c2410.c              |   1 -
>  arch/arm/mach-s3c24xx/clock-s3c2412.c              |   1 -
>  arch/arm/mach-s3c24xx/clock-s3c2416.c              |   2 -
>  arch/arm/mach-s3c24xx/clock-s3c2443.c              |   2 -
>  arch/arm/mach-s3c24xx/common.c                     |  27 +
>  arch/arm/mach-s3c24xx/include/mach/map.h           |   2 +
>  arch/arm/mach-s3c24xx/mach-h1940.c                 |   4 +-
>  arch/arm/mach-s3c24xx/mach-rx1950.c                |   5 +-
>  arch/arm/mach-s3c64xx/Kconfig                      |   2 -
>  arch/arm/mach-s3c64xx/clock.c                      |   2 -
>  arch/arm/mach-s3c64xx/common.c                     |  32 +-
>  arch/arm/mach-s3c64xx/include/mach/irqs.h          |   8 -
>  arch/arm/mach-s3c64xx/include/mach/map.h           |   1 +
>  arch/arm/mach-s3c64xx/irq-pm.c                     |   2 -
>  arch/arm/mach-s3c64xx/mach-crag6410.c              |   4 +-
>  arch/arm/mach-s3c64xx/mach-hmt.c                   |   4 +-
>  arch/arm/mach-s3c64xx/mach-smartq.c                |   4 +-
>  arch/arm/mach-s3c64xx/mach-smdk6410.c              |   5 +-
>  arch/arm/mach-s5p64x0/Kconfig                      |   2 -
>  arch/arm/mach-s5p64x0/clock-s5p6440.c              |   2 -
>  arch/arm/mach-s5p64x0/clock-s5p6450.c              |   2 -
>  arch/arm/mach-s5p64x0/common.c                     |  27 +
>  arch/arm/mach-s5p64x0/include/mach/irqs.h          |   2 -
>  arch/arm/mach-s5p64x0/include/mach/map.h           |   1 +
>  arch/arm/mach-s5p64x0/mach-smdk6440.c              |   5 +-
>  arch/arm/mach-s5p64x0/mach-smdk6450.c              |   5 +-
>  arch/arm/mach-s5p64x0/pm.c                         |   3 -
>  arch/arm/mach-s5pc100/Kconfig                      |   1 -
>  arch/arm/mach-s5pc100/clock.c                      |   2 -
>  arch/arm/mach-s5pc100/common.c                     |  28 +
>  arch/arm/mach-s5pc100/include/mach/irqs.h          |   2 -
>  arch/arm/mach-s5pc100/include/mach/map.h           |   1 +
>  arch/arm/mach-s5pc100/mach-smdkc100.c              |   5 +-
>  arch/arm/mach-s5pv210/Kconfig                      |   1 -
>  arch/arm/mach-s5pv210/clock.c                      |   1 -
>  arch/arm/mach-s5pv210/common.c                     |  28 +
>  arch/arm/mach-s5pv210/include/mach/irqs.h          |   2 -
>  arch/arm/mach-s5pv210/include/mach/map.h           |   1 +
>  arch/arm/mach-s5pv210/mach-smdkv210.c              |   5 +-
>  arch/arm/mach-s5pv210/pm.c                         |  10 -
>  arch/arm/plat-samsung/Kconfig                      |  14 -
>  arch/arm/plat-samsung/Makefile                     |   3 -
>  arch/arm/plat-samsung/dev-backlight.c              |  61 +-
>  arch/arm/plat-samsung/devs.c                       |  42 +-
>  arch/arm/plat-samsung/include/plat/clock.h         |   4 -
>  arch/arm/plat-samsung/include/plat/devs.h          |   1 +
>  arch/arm/plat-samsung/include/plat/irq-vic-timer.h |  13 -
>  arch/arm/plat-samsung/include/plat/irqs.h          |   9 -
>  arch/arm/plat-samsung/include/plat/pwm-clock.h     |  81 ---
>  arch/arm/plat-samsung/include/plat/pwm-core.h      |  24 +
>  arch/arm/plat-samsung/include/plat/regs-timer.h    | 124 ----
>  arch/arm/plat-samsung/include/plat/samsung-time.h  |  23 -
>  arch/arm/plat-samsung/irq-vic-timer.c              |  98 ---
>  arch/arm/plat-samsung/pwm-clock.c                  | 474 --------------
> arch/arm/plat-samsung/s5p-irq.c                    |   4 -
>  arch/arm/plat-samsung/samsung-time.c               | 394 ------------
>  drivers/clocksource/Kconfig                        |   1 -
>  drivers/clocksource/samsung_pwm_timer.c            |  98 +--
>  drivers/pwm/pwm-samsung.c                          | 701
> ++++++++++++++------- 61 files changed, 768 insertions(+), 1662
> deletions(-)
>  delete mode 100644 arch/arm/plat-samsung/include/plat/irq-vic-timer.h
>  delete mode 100644 arch/arm/plat-samsung/include/plat/pwm-clock.h
>  create mode 100644 arch/arm/plat-samsung/include/plat/pwm-core.h
>  delete mode 100644 arch/arm/plat-samsung/include/plat/regs-timer.h
>  delete mode 100644 arch/arm/plat-samsung/irq-vic-timer.c
>  delete mode 100644 arch/arm/plat-samsung/pwm-clock.c
>  delete mode 100644 arch/arm/plat-samsung/samsung-time.c

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-07-31 19:03   ` Tomasz Figa
@ 2013-08-04 19:28     ` Olof Johansson
  -1 siblings, 0 replies; 124+ messages in thread
From: Olof Johansson @ 2013-08-04 19:28 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Sylwester Nawrocki, Heiko Stübner,
	Mark Brown, Thierry Reding

On Wed, Jul 31, 2013 at 12:03 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Kukjin,
>
> Since I think we already got all the necessary Acks, do you want me to
> send you a pull request or you already have this series applied (I can't
> see it in your tree on kernel.org)?

I'll take it directly. Please send me a pull request.


Thanks,

-Olof

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-08-04 19:28     ` Olof Johansson
  0 siblings, 0 replies; 124+ messages in thread
From: Olof Johansson @ 2013-08-04 19:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 31, 2013 at 12:03 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Kukjin,
>
> Since I think we already got all the necessary Acks, do you want me to
> send you a pull request or you already have this series applied (I can't
> see it in your tree on kernel.org)?

I'll take it directly. Please send me a pull request.


Thanks,

-Olof

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v4 00/20] Samsung PWM support cleanup
  2013-08-04 19:28     ` Olof Johansson
@ 2013-08-05 16:51       ` Kukjin Kim
  -1 siblings, 0 replies; 124+ messages in thread
From: Kukjin Kim @ 2013-08-05 16:51 UTC (permalink / raw)
  To: Olof Johansson
  Cc: Tomasz Figa, linux-samsung-soc, linux-arm-kernel, linux-pwm,
	Kukjin Kim, Arnd Bergmann, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On 08/05/13 04:28, Olof Johansson wrote:
> On Wed, Jul 31, 2013 at 12:03 PM, Tomasz Figa<tomasz.figa@gmail.com>  wrote:
>> Hi Kukjin,
>>
>> Since I think we already got all the necessary Acks, do you want me to
>> send you a pull request or you already have this series applied (I can't
>> see it in your tree on kernel.org)?
>
> I'll take it directly. Please send me a pull request.
>
Sorry for late response :(

Yes, I'm OK either way, my pulling or Olof's taking in this case. So 
Tomasz, please send a pull request for this series, it should be fine to me.

Thanks,
Kukjin

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v4 00/20] Samsung PWM support cleanup
@ 2013-08-05 16:51       ` Kukjin Kim
  0 siblings, 0 replies; 124+ messages in thread
From: Kukjin Kim @ 2013-08-05 16:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/05/13 04:28, Olof Johansson wrote:
> On Wed, Jul 31, 2013 at 12:03 PM, Tomasz Figa<tomasz.figa@gmail.com>  wrote:
>> Hi Kukjin,
>>
>> Since I think we already got all the necessary Acks, do you want me to
>> send you a pull request or you already have this series applied (I can't
>> see it in your tree on kernel.org)?
>
> I'll take it directly. Please send me a pull request.
>
Sorry for late response :(

Yes, I'm OK either way, my pulling or Olof's taking in this case. So 
Tomasz, please send a pull request for this series, it should be fine to me.

Thanks,
Kukjin

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v6 13/20] pwm: Add new pwm-samsung driver
  2013-07-23 23:43       ` Tomasz Figa
@ 2013-08-07 19:35         ` Andrew Bresticker
  -1 siblings, 0 replies; 124+ messages in thread
From: Andrew Bresticker @ 2013-08-07 19:35 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

Hi Tomasz,

> +#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
> +/*
> + * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
> + * and some registers need access synchronization. If both drivers are
> + * compiled in, the spinlock is defined in the clocksource driver,
> + * otherwise following definition is used.
> + *
> + * Currently we do not need any more complex synchronization method
> + * because all the supported SoCs contain only one instance of the PWM
> + * IP. Should this change, both drivers will need to be modified to
> + * properly synchronize accesses to particular instances.
> + */
> +static DEFINE_SPINLOCK(samsung_pwm_lock);

Shouldn't this not be static?  It's declared in
clocksource/samsung_pwm.h whether or not the samsung_pwm_timer is
compiled in or not.

Thanks,
Andrew

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v6 13/20] pwm: Add new pwm-samsung driver
@ 2013-08-07 19:35         ` Andrew Bresticker
  0 siblings, 0 replies; 124+ messages in thread
From: Andrew Bresticker @ 2013-08-07 19:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

> +#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
> +/*
> + * PWM block is shared between pwm-samsung and samsung_pwm_timer drivers
> + * and some registers need access synchronization. If both drivers are
> + * compiled in, the spinlock is defined in the clocksource driver,
> + * otherwise following definition is used.
> + *
> + * Currently we do not need any more complex synchronization method
> + * because all the supported SoCs contain only one instance of the PWM
> + * IP. Should this change, both drivers will need to be modified to
> + * properly synchronize accesses to particular instances.
> + */
> +static DEFINE_SPINLOCK(samsung_pwm_lock);

Shouldn't this not be static?  It's declared in
clocksource/samsung_pwm.h whether or not the samsung_pwm_timer is
compiled in or not.

Thanks,
Andrew

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v6 13/20] pwm: Add new pwm-samsung driver
  2013-08-07 19:35         ` Andrew Bresticker
@ 2013-08-07 19:49           ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-08-07 19:49 UTC (permalink / raw)
  To: Andrew Bresticker
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On Wednesday 07 of August 2013 12:35:42 Andrew Bresticker wrote:
> Hi Tomasz,
> 
> > +#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
> > +/*
> > + * PWM block is shared between pwm-samsung and samsung_pwm_timer
> > drivers + * and some registers need access synchronization. If both
> > drivers are + * compiled in, the spinlock is defined in the
> > clocksource driver, + * otherwise following definition is used.
> > + *
> > + * Currently we do not need any more complex synchronization method
> > + * because all the supported SoCs contain only one instance of the
> > PWM
> > + * IP. Should this change, both drivers will need to be modified to
> > + * properly synchronize accesses to particular instances.
> > + */
> > +static DEFINE_SPINLOCK(samsung_pwm_lock);
> 
> Shouldn't this not be static?

It should be static, when the clocksource driver is not used, but...

> It's declared in
> clocksource/samsung_pwm.h whether or not the samsung_pwm_timer is
> compiled in or not.

..it should not be defined as non-static in this case (= an ifdef is 
needed in this header). I believe I had this already fixed, not sure what 
happened with the fix...

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v6 13/20] pwm: Add new pwm-samsung driver
@ 2013-08-07 19:49           ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-08-07 19:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 07 of August 2013 12:35:42 Andrew Bresticker wrote:
> Hi Tomasz,
> 
> > +#ifndef CONFIG_CLKSRC_SAMSUNG_PWM
> > +/*
> > + * PWM block is shared between pwm-samsung and samsung_pwm_timer
> > drivers + * and some registers need access synchronization. If both
> > drivers are + * compiled in, the spinlock is defined in the
> > clocksource driver, + * otherwise following definition is used.
> > + *
> > + * Currently we do not need any more complex synchronization method
> > + * because all the supported SoCs contain only one instance of the
> > PWM
> > + * IP. Should this change, both drivers will need to be modified to
> > + * properly synchronize accesses to particular instances.
> > + */
> > +static DEFINE_SPINLOCK(samsung_pwm_lock);
> 
> Shouldn't this not be static?

It should be static, when the clocksource driver is not used, but...

> It's declared in
> clocksource/samsung_pwm.h whether or not the samsung_pwm_timer is
> compiled in or not.

..it should not be defined as non-static in this case (= an ifdef is 
needed in this header). I believe I had this already fixed, not sure what 
happened with the fix...

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v6 13/20] pwm: Add new pwm-samsung driver
  2013-08-07 19:49           ` Tomasz Figa
@ 2013-08-08 17:13             ` Andrew Bresticker
  -1 siblings, 0 replies; 124+ messages in thread
From: Andrew Bresticker @ 2013-08-08 17:13 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

> ..it should not be defined as non-static in this case (= an ifdef is
> needed in this header). I believe I had this already fixed, not sure what
> happened with the fix...

Perhaps this is it: https://patchwork.kernel.org/patch/2787271/.  That
should probably land with this patchset too.

Thanks,
Andrew

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v6 13/20] pwm: Add new pwm-samsung driver
@ 2013-08-08 17:13             ` Andrew Bresticker
  0 siblings, 0 replies; 124+ messages in thread
From: Andrew Bresticker @ 2013-08-08 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

> ..it should not be defined as non-static in this case (= an ifdef is
> needed in this header). I believe I had this already fixed, not sure what
> happened with the fix...

Perhaps this is it: https://patchwork.kernel.org/patch/2787271/.  That
should probably land with this patchset too.

Thanks,
Andrew

^ permalink raw reply	[flat|nested] 124+ messages in thread

* Re: [PATCH v6 13/20] pwm: Add new pwm-samsung driver
  2013-08-08 17:13             ` Andrew Bresticker
@ 2013-08-08 21:27               ` Tomasz Figa
  -1 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-08-08 21:27 UTC (permalink / raw)
  To: Andrew Bresticker
  Cc: linux-samsung-soc, linux-arm-kernel, linux-pwm, Kukjin Kim,
	Arnd Bergmann, Olof Johansson, Sylwester Nawrocki,
	Heiko Stübner, Mark Brown, Thierry Reding

On Thursday 08 of August 2013 10:13:27 Andrew Bresticker wrote:
> > ..it should not be defined as non-static in this case (= an ifdef is
> > needed in this header). I believe I had this already fixed, not sure
> > what happened with the fix...
> 
> Perhaps this is it: https://patchwork.kernel.org/patch/2787271/.  That
> should probably land with this patchset too.

Oh yes, this is it.

I know what happened now. This series was already queued for 3.11 in 
Samsung tree. After a bit of testing in linux-next Bart found the build 
error and sent a fix, which was going to be merged for 3.11 as well. 
However since there have been some problems just before merge window 
started, this series had to be dropped, including the fixup patch.

Thanks for reporting. Let me try to sort this out.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

* [PATCH v6 13/20] pwm: Add new pwm-samsung driver
@ 2013-08-08 21:27               ` Tomasz Figa
  0 siblings, 0 replies; 124+ messages in thread
From: Tomasz Figa @ 2013-08-08 21:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 08 of August 2013 10:13:27 Andrew Bresticker wrote:
> > ..it should not be defined as non-static in this case (= an ifdef is
> > needed in this header). I believe I had this already fixed, not sure
> > what happened with the fix...
> 
> Perhaps this is it: https://patchwork.kernel.org/patch/2787271/.  That
> should probably land with this patchset too.

Oh yes, this is it.

I know what happened now. This series was already queued for 3.11 in 
Samsung tree. After a bit of testing in linux-next Bart found the build 
error and sent a fix, which was going to be merged for 3.11 as well. 
However since there have been some problems just before merge window 
started, this series had to be dropped, including the fixup patch.

Thanks for reporting. Let me try to sort this out.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 124+ messages in thread

end of thread, other threads:[~2013-08-08 21:27 UTC | newest]

Thread overview: 124+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-20  0:04 [PATCH v4 00/20] Samsung PWM support cleanup Tomasz Figa
2013-07-20  0:04 ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 01/20] clocksource: samsung_pwm_timer: Do not request PWM mem region Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 02/20] clocksource: samsung_pwm_timer: Correct definition of AUTORELOAD bit Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-22  3:50   ` Daniel Lezcano
2013-07-22  3:50     ` Daniel Lezcano
2013-07-22  7:43     ` Tomasz Figa
2013-07-22  7:43       ` Tomasz Figa
2013-07-22 20:56       ` Daniel Lezcano
2013-07-22 20:56         ` Daniel Lezcano
2013-07-22 21:11         ` Tomasz Figa
2013-07-22 21:11           ` Tomasz Figa
2013-07-22 21:28           ` Daniel Lezcano
2013-07-22 21:28             ` Daniel Lezcano
2013-07-23 23:32             ` [PATCH v6 " Tomasz Figa
2013-07-23 23:32               ` Tomasz Figa
2013-07-29 13:08               ` Daniel Lezcano
2013-07-29 13:08                 ` Daniel Lezcano
2013-07-22 20:54   ` [PATCH v5 " Tomasz Figa
2013-07-22 20:54     ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 03/20] clocksource: samsung_pwm_timer: Cache clocksource register address Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 04/20] clocksource: samsung_pwm_timer: Do not use clocksource_mmio Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-22  3:56   ` Daniel Lezcano
2013-07-22  3:56     ` Daniel Lezcano
2013-07-22  7:47     ` Tomasz Figa
2013-07-22  7:47       ` Tomasz Figa
2013-07-22 20:13       ` Daniel Lezcano
2013-07-22 20:13         ` Daniel Lezcano
2013-07-22 20:17         ` Tomasz Figa
2013-07-22 20:17           ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 05/20] clocksource: samsung_pwm_timer: Handle suspend/resume correctly Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-22  3:57   ` Daniel Lezcano
2013-07-22  3:57     ` Daniel Lezcano
2013-07-20  0:04 ` [PATCH v4 06/20] ARM: SAMSUNG: Unify base address definitions of timer block Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 07/20] ARM: SAMSUNG: Add new PWM platform device Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-21 19:46   ` Sylwester Nawrocki
2013-07-21 19:46     ` Sylwester Nawrocki
2013-07-21 21:51     ` Tomasz Figa
2013-07-21 21:51       ` Tomasz Figa
2013-07-21 22:24       ` Tomasz Figa
2013-07-21 22:24         ` Tomasz Figa
2013-07-22 20:52   ` [PATCH v5 " Tomasz Figa
2013-07-22 20:52     ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 08/20] ARM: SAMSUNG: Set PWM platform data Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 09/20] ARM: SAMSUNG: Move all platforms to new clocksource driver Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-22  3:59   ` Daniel Lezcano
2013-07-22  3:59     ` Daniel Lezcano
2013-07-20  0:04 ` [PATCH v4 10/20] ARM: SAMSUNG: Remove old samsung-time driver Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 11/20] ARM: SAMSUNG: Remove unused PWM timer IRQ chip code Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 12/20] pwm: samsung: Rename to pwm-samsung-legacy Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-29 11:44   ` Thierry Reding
2013-07-29 11:44     ` Thierry Reding
2013-07-20  0:04 ` [PATCH v4 13/20] pwm: Add new pwm-samsung driver Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-21 19:50   ` Sylwester Nawrocki
2013-07-21 19:50     ` Sylwester Nawrocki
2013-07-21 21:58     ` Tomasz Figa
2013-07-21 21:58       ` Tomasz Figa
2013-07-22 20:50   ` [PATCH v5 " Tomasz Figa
2013-07-22 20:50     ` Tomasz Figa
2013-07-23 23:43     ` [PATCH v6 " Tomasz Figa
2013-07-23 23:43       ` Tomasz Figa
2013-08-07 19:35       ` Andrew Bresticker
2013-08-07 19:35         ` Andrew Bresticker
2013-08-07 19:49         ` Tomasz Figa
2013-08-07 19:49           ` Tomasz Figa
2013-08-08 17:13           ` Andrew Bresticker
2013-08-08 17:13             ` Andrew Bresticker
2013-08-08 21:27             ` Tomasz Figa
2013-08-08 21:27               ` Tomasz Figa
2013-07-29 11:44   ` [PATCH v4 " Thierry Reding
2013-07-29 11:44     ` Thierry Reding
2013-07-20  0:04 ` [PATCH v4 14/20] ARM: SAMSUNG: Rework private data handling in dev-backlight Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 15/20] ARM: SAMSUNG: Modify board files to use new PWM platform device Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 16/20] pwm: Remove superseded pwm-samsung-legacy driver Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-29 11:45   ` Thierry Reding
2013-07-29 11:45     ` Thierry Reding
2013-07-20  0:04 ` [PATCH v4 17/20] ARM: SAMSUNG: Remove old PWM timer platform devices Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 18/20] ARM: SAMSUNG: Remove pwm-clock infrastructure Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 19/20] ARM: SAMSUNG: Remove remaining uses of plat/regs-timer.h header Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-20  0:04 ` [PATCH v4 20/20] ARM: SAMSUNG: Remove " Tomasz Figa
2013-07-20  0:04   ` Tomasz Figa
2013-07-21 22:22 ` [PATCH v4 00/20] Samsung PWM support cleanup Sylwester Nawrocki
2013-07-21 22:22   ` Sylwester Nawrocki
2013-07-21 22:25   ` Tomasz Figa
2013-07-21 22:25     ` Tomasz Figa
2013-07-22  1:55     ` Kukjin Kim
2013-07-22  1:55       ` Kukjin Kim
2013-07-22  2:01     ` Kukjin Kim
2013-07-22  2:01       ` Kukjin Kim
2013-07-22  7:49       ` Tomasz Figa
2013-07-22  7:49         ` Tomasz Figa
2013-07-23 15:30         ` Thierry Reding
2013-07-23 15:30           ` Thierry Reding
2013-07-22 19:34       ` Olof Johansson
2013-07-22 19:34         ` Olof Johansson
2013-07-28 12:22 ` Mark Brown
2013-07-28 12:22   ` Mark Brown
2013-07-31 19:03 ` Tomasz Figa
2013-07-31 19:03   ` Tomasz Figa
2013-08-04 19:28   ` Olof Johansson
2013-08-04 19:28     ` Olof Johansson
2013-08-05 16:51     ` Kukjin Kim
2013-08-05 16:51       ` Kukjin Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.