Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] davinci: changed SRAM allocator to shared ram.
From: Subhasish Ghosh @ 2011-02-26 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB593024BE49711@dbde02.ent.ti.com>

Hi Sekhar,

I tried this using MMC and Kelvin's suggestions, but it never came back. 
Here is a log:

root at arago:~# rtcwake -d /dev/rtc0 -s 20 -m mem
wakeup from "mem" at Tue Apr 21 14:31:13 2009
PM: Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.01 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
Suspending console(s) (use no_console_suspend to debug)

^ permalink raw reply

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
From: Linus Walleij @ 2011-02-26  9:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298688357-20775-2-git-send-email-sbkim73@samsung.com>

2011/2/26 Sangbeom Kim <sbkim73@samsung.com>:
> (...)
> +static void s5p_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 / 2);
> + ? ? ? clk_set_rate(tdiv_event, pclk / 2);
> + ? ? ? clk_set_parent(tin_event, tdiv_event);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_event);
> + ? ? ? clock_count_per_tick = clock_rate / HZ;
> +
> + ? ? ? time_event_device.mult =
> + ? ? ? ? ? ? ? div_sc(clock_rate, NSEC_PER_SEC, time_event_device.shift);
> + ? ? ? time_event_device.max_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(-1, &time_event_device);
> + ? ? ? time_event_device.min_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(1, &time_event_device);

This is a very complicated and inprecise way of doing this nowadays.
Skip hardcoding the shift value and calculating mult like that and use

/* Be able to sleep for atleast 4 seconds (usually more) */
#define EVT_MIN_RANGE 4

clockevents_calc_mult_shift(&time_event_device,
                                    clock_rate, EVT_MIN_RANGE);

> (...)
> +static void s5p_clocksource_init(void)
> +{
> + ? ? ? unsigned long pclk;
> + ? ? ? unsigned long clock_rate;
> +
> + ? ? ? pclk = clk_get_rate(timerclk);
> +
> + ? ? ? clk_set_rate(tdiv_source, pclk / 2);
> + ? ? ? clk_set_parent(tin_source, tdiv_source);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_source);
> +
> + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> +
> + ? ? ? if (clocksource_register_hz(&time_clocksource, clock_rate))
> + ? ? ? ? ? ? ? panic("%s: can't register clocksource\n", time_clocksource.name);
> +}

This is more like it :-)

But you probably also want to add a sched_clock hook for this
platform too, so you get some nice scheduling resolution.

I suggest you look at the simple straight-forward driver
for U300 in arch/arm/mach-u300/timer.c for inspiration.
It's using the same timer that is used for clocksource for
sched_clock().


Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 2/4] msm: scm: Fix improper register assignment
From: Russell King - ARM Linux @ 2011-02-26  8:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D688AF1.1090607@codeaurora.org>

On Fri, Feb 25, 2011 at 09:09:05PM -0800, Saravana Kannan wrote:
> Yeah, Stephen and I spent quite a bit of time discussing this and  
> experimenting to figure out what the heck GCC was doing. But it kept  
> optimizing the fake code we put in trying to force GCC to use a specific  
> register.

One way to look at it is that if you specify a value for r0, assign it,
and then call a function, how do you expect the r0 value to be preserved?
r0 will be corrupted by the called function as its used to pass arg0 and
the return value.

I'm surprised the compiler didn't spit out an error.

^ permalink raw reply

* [PATCH] OMAP4: PandaBoard: Adding DVI support
From: Koen Kooi @ 2011-02-26  8:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTikQ25tLoRSynp6xjaJPO0sPpY3RFFS52UsgBuvU@mail.gmail.com>


Op 25 feb 2011, om 19:57 heeft Jan, Sebastien het volgende geschreven:

> On Fri, Feb 11, 2011 at 4:38 PM, Koen Kooi <koen@dominion.thruhere.net> wrote:
>>> I fetched this branch which contains 35 patches on top of 2.6.38-rc4.
>>> After fixing some conflict, I applied these 35 patches on our Ubuntu
>>> ti-omap-dev kernel. With built-in the DSS2 driver and GENERIC_DPI
>>> driver, kernel boots fine on my Panda with Ubuntu GUI. But I have to
>>> set the kernel boot command args with omapfb.mode=dvi:1024x768MR-24 at 60
>>> omapdss.def_disp=dvi, pointed out by Sebastien. Without this bootargs,
>>> no graphic at all. so as Robert concerned, EDID detection doesn't
>>> work. Does that related to I2C driver? I2C driver always tell me
>>> timeout in dmesg.
>> 
>> AIUI the i2c bus is only hooked up to the HDMI port, so unless you plug in something there, no dice.
> 
> Are you sure? According to the pandaboard user manual, there seem to
> be an i2c connection (i2c3): page 31, fig 9:
> http://pandaboard.org/sites/default/files/board_reference/A1/Panda_Board_Spec_DOC-21010_REV0_6.pdf

And so it does, it's nice to have a DDC bus on each port. I guess I got confused by the fact no kernel is using that currently :)

regards,

Koen

^ permalink raw reply

* [PATCH] ARM: mxs: Initial support for Ka-Ro TX28
From: Shawn Guo @ 2011-02-26  7:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298581480-15585-1-git-send-email-u.kleine-koenig@pengutronix.de>

On Thu, Feb 24, 2011 at 10:04:40PM +0100, Uwe Kleine-K?nig wrote:
> From: Lothar Wa?mann <LW@KARO-electronics.de>
> 
> Based on code created by Lothar Wa?mann, Sascha Hauer, Wolfram Sang and
> me.
> 
> Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
> ---
>  arch/arm/mach-mxs/Kconfig                   |   12 ++
>  arch/arm/mach-mxs/Makefile                  |    2 +
>  arch/arm/mach-mxs/include/mach/mxs.h        |    9 +-
>  arch/arm/mach-mxs/include/mach/uncompress.h |    1 +
>  arch/arm/mach-mxs/mach-tx28.c               |  175 +++++++++++++++++++++++++++
>  arch/arm/mach-mxs/module-tx28.c             |  131 ++++++++++++++++++++
>  arch/arm/mach-mxs/module-tx28.h             |    9 ++
>  7 files changed, 337 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/mach-tx28.c
>  create mode 100644 arch/arm/mach-mxs/module-tx28.c
>  create mode 100644 arch/arm/mach-mxs/module-tx28.h
> 
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> index 836cc81..895d066 100644
> --- a/arch/arm/mach-mxs/Kconfig
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -39,4 +39,16 @@ config MACH_MX28EVK
>  	  Include support for MX28EVK platform. This includes specific
>  	  configurations for the board and its peripherals.
>  
> +config MODULE_TX28
> +	bool
> +	select SOC_IMX28
> +	select MXS_HAVE_AMBA_DUART
> +	select MXS_HAVE_PLATFORM_AUART
> +	select MXS_HAVE_PLATFORM_FEC
> +	select MXS_HAVE_PLATFORM_MXS_PWM
> +
> +config MACH_TX28
> +	bool "Ka-Ro TX28 module"
> +	select MODULE_TX28
> +
>  endif
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> index 6b26f02..2f1f614 100644
> --- a/arch/arm/mach-mxs/Makefile
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -9,5 +9,7 @@ obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
>  
>  obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
>  obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
> +obj-$(CONFIG_MODULE_TX28) += module-tx28.o
> +obj-$(CONFIG_MACH_TX28)    += mach-tx28.o
>  
>  obj-y += devices/
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> index f186c08..35a89dd 100644
> --- a/arch/arm/mach-mxs/include/mach/mxs.h
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -28,8 +28,13 @@
>  /*
>   * MXS CPU types
>   */
> -#define cpu_is_mx23()		(machine_is_mx23evk())
> -#define cpu_is_mx28()		(machine_is_mx28evk())
> +#define cpu_is_mx23()		(					\
> +		machine_is_mx23evk() ||					\
> +		0)
> +#define cpu_is_mx28()		(					\
> +		machine_is_mx28evk() ||					\
> +		machine_is_tx28() ||					\
> +		0)
>  
>  /*
>   * IO addresses common to MXS-based
> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
> index a005e76..f12a173 100644
> --- a/arch/arm/mach-mxs/include/mach/uncompress.h
> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
> @@ -63,6 +63,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
>  		mxs_duart_base = MX23_DUART_BASE_ADDR;
>  		break;
>  	case MACH_TYPE_MX28EVK:
> +	case MACH_TYPE_TX28:
>  		mxs_duart_base = MX28_DUART_BASE_ADDR;
>  		break;
>  	default:
> diff --git a/arch/arm/mach-mxs/mach-tx28.c b/arch/arm/mach-mxs/mach-tx28.c
> new file mode 100644
> index 0000000..540d6ea
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-tx28.c
> @@ -0,0 +1,175 @@
> +/*
> + * Copyright (C) 2010 <LW@KARO-electronics.de>
> + *
> + * based on: mach-mx28_evk.c

mach-mx28evk.c?

> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * 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
> + */

-- 
Regards,
Shawn

^ permalink raw reply

* [PATCH] EDB93xx: Add support for CS4271 SPI-connected CODEC
From: Alexander Sverdlin @ 2011-02-26  7:43 UTC (permalink / raw)
  To: linux-arm-kernel

From: Alexander Sverdlin <subaparts@yandex.ru>

Add support for CS4271 SPI-connected CODEC to EDB93xx.
        
Signed-off-by: Alexander Sverdlin <subaparts@yandex.ru>

Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: liam Girdwood <lrg@slimlogic.co.uk>

---
 arch/arm/mach-ep93xx/edb93xx.c |   83 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 3f37567..2c2f84d 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -30,9 +30,13 @@
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+
+#include <sound/cs4271.h>
 
 #include <mach/hardware.h>
 #include <mach/fb.h>
+#include <mach/ep93xx_spi.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -94,6 +98,83 @@ static void __init edb93xx_register_i2c(void)
 

 /*************************************************************************
+ * EDB93xx SPI peripheral handling
+ *************************************************************************/
+static struct cs4271_platform_data edb93xx_cs4271_data = {
+	.gpio_nreset	= -EINVAL,	/* filled in later */
+};
+
+static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
+{
+	return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
+				GPIOF_OUT_INIT_HIGH, spi->modalias);
+}
+
+static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
+{
+	gpio_free(EP93XX_GPIO_LINE_EGPIO6);
+}
+
+static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
+{
+	gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
+}
+
+static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
+	.setup		= edb93xx_cs4271_hw_setup,
+	.cleanup	= edb93xx_cs4271_hw_cleanup,
+	.cs_control	= edb93xx_cs4271_hw_cs_control,
+};
+
+static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
+	{
+		.modalias		= "cs4271",
+		.platform_data		= &edb93xx_cs4271_data,
+		.controller_data	= &edb93xx_cs4271_hw,
+		.max_speed_hz		= 6000000,
+		.bus_num		= 0,
+		.chip_select		= 0,
+		.mode			= SPI_MODE_3,
+	},
+};
+
+static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
+	.num_chipselect	= ARRAY_SIZE(edb93xx_spi_board_info),
+};
+
+static void __init edb93xx_register_spi(void)
+{
+	if (machine_is_edb9301() || machine_is_edb9302())
+		edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
+	else if (machine_is_edb9302a() || machine_is_edb9307a())
+		edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
+	else if (machine_is_edb9315a())
+		edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
+
+	ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
+			    ARRAY_SIZE(edb93xx_spi_board_info));
+}
+
+
+/*************************************************************************
+ * EDB93xx I2S
+ *************************************************************************/
+static int __init edb93xx_has_audio(void)
+{
+	return (machine_is_edb9301() || machine_is_edb9302() ||
+		machine_is_edb9302a() || machine_is_edb9307a() ||
+		machine_is_edb9315a());
+}
+
+static void __init edb93xx_register_i2s(void)
+{
+	if (edb93xx_has_audio()) {
+		ep93xx_register_i2s();
+	}
+}
+
+
+/*************************************************************************
  * EDB93xx pwm
  *************************************************************************/
 static void __init edb93xx_register_pwm(void)
@@ -149,6 +230,8 @@ static void __init edb93xx_init_machine(void)
 	edb93xx_register_flash();
 	ep93xx_register_eth(&edb93xx_eth_data, 1);
 	edb93xx_register_i2c();
+	edb93xx_register_spi();
+	edb93xx_register_i2s();
 	edb93xx_register_pwm();
 	edb93xx_register_fb();
 }

^ permalink raw reply related

* [PATCH] msm: gpiomux: Remove GPIOMUX_VALID and merge config enums
From: Saravana Kannan @ 2011-02-26  5:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTinZCtbQnAk_OX92jqbW_GjH5wpxvbeoMkHV1inn@mail.gmail.com>

On 02/25/2011 05:20 PM, Dima Zavin wrote:
> On Fri, Feb 25, 2011 at 12:19 PM, Rohit Vaswani<rvaswani@codeaurora.org>  wrote:
>> diff --git a/arch/arm/mach-msm/board-qsd8x50.c
>> b/arch/arm/mach-msm/board-qsd8x50.c
>> index 33ab1fe..d665b0e 100644
>> --- a/arch/arm/mach-msm/board-qsd8x50.c
>> +++ b/arch/arm/mach-msm/board-qsd8x50.c
>> @@ -38,19 +38,26 @@
>>   #include "devices.h"
>>   #include "gpiomux.h"
>>
>> -#define UART3_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
>> -            GPIOMUX_FUNC_1 | GPIOMUX_VALID)
>> +static struct gpiomux_setting uart3_suspended = {
>> +    .drv = GPIOMUX_DRV_2MA,
>> +    .pull = GPIOMUX_PULL_DOWN,
>> +    .func = GPIOMUX_FUNC_1,
>> +};
>>
>>   extern struct sys_timer msm_timer;
>>
>> -struct msm_gpiomux_config qsd8x50_uart3_configs[] __initdata = {
>> +struct msm_gpiomux_config qsd8x50_uart3_configs[] = {
>>      {
>>          .gpio = 86, /* UART3 RX */
>> -        .suspended = UART3_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart3_suspended,
>> +        },
>>      },
>>      {
>>          .gpio = 87, /* UART3 TX */
>> -        .suspended = UART3_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart3_suspended,
>> +        },
>>      },
>>   };
>
> I think this new interface is way too verbose and will quickly get
> unwieldy for configurations that have more than a few pins. For
> instance, imagine what the above would look like when muxing a 24bit
> LCD pin list...
>
> How about adding a "bool valid" to gpiomux_setting, and convert the
> "sets" array to an array of settings and not pointers to settings.
> This will allow us to do (in gpiomux.h):
>
> struct msm_gpiomux_rec {
>      struct gpiomux_setting sets[GPIOMUX_NSETTINGS];
>      int ref;
> };
>
> struct gpiomux_setting {
>      enum gpiomux_func func;
>      enum gpiomux_drv  drv;
>      enum gpiomux_pull pull;
>      bool valid;
> };
>
> This way, I can do something like (very rough):
>
> #define GPIOMUX_SET(func,drv,pull) { \
>      .func = GPIOMUX_##func, \
>      .drv = GPIOMUX_##drv, \
>      .pull = GPIOMUX_##pull, \
>      .valid = true, \
>    }
>
> #define GPIOMUX_SET_NONE { .valid = false, }
>
> #define GPIOMUX_CFG(g, active, suspended) { \
>       .gpio = g, \
>       .sets = { \
>           [GPIOMUX_ACTIVE] = active, \
>           [GPIOMUX_SUSPENDED] = suspended, \
>        }, \
>   }
>
> This will then allow me to define the uart3 pinmuxing in my board file
> as follows:
>
> struct msm_gpiomux_rec uart3_mux_cfg[] = {
>      GPIOMUX_CFG(86, GPIOMUX_SET_NONE,
>                             GPIOMUX_SET(FUNC_1, DRV_2MA, PULL_DOWN)),
>      GPIOMUX_CFG(87, GPIOMUX_SET_NONE,
>                             GPIOMUX_SET(FUNC_1, DRV_2MA, PULL_DOWN)),
> };
>
> Thoughts?
>

I haven't read this GPIO code thoroughly, but by looking just at the 
diff, I think you can still have these type of macros with the structure 
definition Rohit chose. I have no opinion one which struct definition is 
better (not enough context). Just trying to help with writing helper macros.

The trick is to use pointers to anonymous struct. A very rough macro:

#define GPIOMUX_SET(f, d, p) \
&(struct gpiomux_setting) {
	.func = f,
	.drv = d,
	.pull = p,
}

#define GPIOMUX_CFG(g, active, suspended) { \
	.gpio = g,
	.settings = {
		[ACTIVE] = active,
		[SUSPENDED] = suspended,
	}
}

struct msm_gpiomux_config foo_bar[] = {
	GPIOMUX_CFG(10, GPIOMUX_SET(FUNC, 2MA, PULL_UP), NULL),
	GPIOMUX_CFG(11, GPIOMUX_SET(FUNC, 2MA, PULL_UP), NULL),
};

I'm certain the pointer to anonymous struct stuff works. You might have 
to tweak the macros a bit though. Hope this help.

-Saravana

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* [PATCH 2/4] msm: scm: Fix improper register assignment
From: Saravana Kannan @ 2011-02-26  5:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298640219.958.74.camel@e102144-lin.cambridge.arm.com>

On 02/25/2011 05:23 AM, Will Deacon wrote:
> On Thu, 2011-02-24 at 18:44 +0000, Stephen Boyd wrote:
>> Assign the registers used in the inline assembly immediately
>> before the inline assembly block. This ensures the compiler
>> doesn't optimize away dead register assignments when it
>> shouldn't.
>>
>> Signed-off-by: Stephen Boyd<sboyd@codeaurora.org>
>> ---
>>   arch/arm/mach-msm/scm.c |    7 +++++--
>>   1 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
>> index ba57b5a..5eddf54 100644
>> --- a/arch/arm/mach-msm/scm.c
>> +++ b/arch/arm/mach-msm/scm.c
>> @@ -264,13 +264,16 @@ u32 scm_get_version(void)
>>   {
>>          int context_id;
>>          static u32 version = -1;
>> -       register u32 r0 asm("r0") = 0x1<<  8;
>> -       register u32 r1 asm("r1") = (u32)&context_id;
>> +       register u32 r0 asm("r0");
>> +       register u32 r1 asm("r1");
>>
>>          if (version != -1)
>>                  return version;
>>
>>          mutex_lock(&scm_lock);
>> +
>> +       r0 = 0x1<<  8;
>> +       r1 = (u32)&context_id;
>>          asm volatile(
>>                  __asmeq("%0", "r1")
>>                  __asmeq("%1", "r0")
>
>
> Whoa, have you seen the compiler `optimise' the original assignments
> away? Since there is a use in the asm block, the definition shouldn't
> be omitted. What toolchain are you using?
>

Yeah, Stephen and I spent quite a bit of time discussing this and 
experimenting to figure out what the heck GCC was doing. But it kept 
optimizing the fake code we put in trying to force GCC to use a specific 
register.

My hypothesis at this point is that the "register xx asm("rx")" 
declarations are just for giving a symbolic name to refer to the 
specific register in C code. I doesn't tell GCC to reserve away the 
register and make sure the value is preserved. And the assignments to 
these said variables seem to translate to a pure "mov rx, 5" kinda 
instruction with no further preservation of rx either.

That's the only hypothesis I/we could come up with as to how this got 
optimized away.

I would be great if someone explains the exact meaning of these 
"register asm" declarations and the assignments in C code.

-Saravana

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
From: Kyungmin Park @ 2011-02-26  4:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298688357-20775-2-git-send-email-sbkim73@samsung.com>

On Sat, Feb 26, 2011 at 11:45 AM, Sangbeom Kim <sbkim73@samsung.com> wrote:
> This patch adds support HR-Timer(High Resolution Timer) and dynamic
> tick system for S5P SoCs. There are many clock sources for HR-Timer
> on S5P SoCs. The PWM timer, RTC, System Timer, and MCT can be used
> for clock source.
> This patch can only support PWM timer for clocksource of
> S5P64x0 and S5PV210.
>
> Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
> ---
> ?arch/arm/plat-s5p/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
> ?arch/arm/plat-s5p/include/plat/s5p-time.h | ? 37 +++
> ?arch/arm/plat-s5p/s5p-time.c ? ? ? ? ? ? ?| ?395 +++++++++++++++++++++++++++++
> ?3 files changed, 433 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/plat-s5p/include/plat/s5p-time.h
> ?create mode 100644 arch/arm/plat-s5p/s5p-time.c
>
> diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
> index 4bd5cf9..3b8cc2f 100644
> --- a/arch/arm/plat-s5p/Makefile
> +++ b/arch/arm/plat-s5p/Makefile
> @@ -22,6 +22,7 @@ obj-$(CONFIG_S5P_GPIO_INT) ? ?+= irq-gpioint.o
> ?obj-$(CONFIG_S5P_SYSTEM_MMU) ? += sysmmu.o
> ?obj-$(CONFIG_PM) ? ? ? ? ? ? ? += pm.o
> ?obj-$(CONFIG_PM) ? ? ? ? ? ? ? += irq-pm.o
> +obj-$(CONFIG_GENERIC_CLOCKEVENTS) += s5p-time.o
>
> ?# devices
>
> diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
> new file mode 100644
> index 0000000..e478f0c
> --- /dev/null
> +++ b/arch/arm/plat-s5p/include/plat/s5p-time.h
> @@ -0,0 +1,37 @@
> +/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
> + *
> + * Copyright 2011 Samsung Electronics Co., Ltd.
> + * ? ? ? ? ? ? http://www.samsung.com/
> + *
> + * Header file for s5p time 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_S5P_TIME_H
> +#define __ASM_PLAT_S5P_TIME_H __FILE__
> +
> +/* S5P HR-Timer Clock mode */
> +enum s5p_timer_mode {
> + ? ? ? S5P_PWM0,
> + ? ? ? S5P_PWM1,
> + ? ? ? S5P_PWM2,
> + ? ? ? S5P_PWM3,
> + ? ? ? S5P_PWM4,
> +};
> +
> +struct s5p_timer_source {
> + ? ? ? unsigned int event_id;
> + ? ? ? unsigned int source_id;
> +};
> +
> +#define TCNT_MAX ? ? ? ? ? ? ? 0xffffffff
> +#define NON_PERIODIC ? ? ? ? ? 0
> +#define PERIODIC ? ? ? ? ? ? ? 1
> +
> +extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enum s5p_timer_mode source);
> +extern struct sys_timer s5p_timer;
> +#endif /* __ASM_PLAT_S5P_TIME_H */
> diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
> new file mode 100644
> index 0000000..4691728
> --- /dev/null
> +++ b/arch/arm/plat-s5p/s5p-time.c
> @@ -0,0 +1,395 @@
> +/* linux/arch/arm/plat-s5p/s5p-time.c
> + *
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + * ? ? ? ? ? ? http://www.samsung.com/
> + *
> + * S5P - Common hr-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.
> +*/
> +
> +#include <linux/sched.h>
> +#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 <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/regs-timer.h>
> +#include <plat/s5p-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 s5p_timer_source timer_source;
> +static unsigned long clock_count_per_tick;
> +static void s5p_timer_resume(void);
> +
> +static void s5p_time_stop(enum s5p_timer_mode mode)
> +{
> + ? ? ? unsigned long tcon;
> +
> + ? ? ? tcon = __raw_readl(S3C2410_TCON);
> +
> + ? ? ? switch (mode) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T0START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM1:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T1START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM2:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T2START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T3START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T4START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? printk(KERN_ERR "Invalid Timer %d\n", mode);
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> + ? ? ? __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
> +{
> + ? ? ? unsigned long tcon;
> +
> + ? ? ? tcon = __raw_readl(S3C2410_TCON);
> +
> + ? ? ? tcnt--;
> +
> + ? ? ? switch (mode) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? ? ? ? ? tcon &= ~(0x0f << 0);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T0MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM1:
> + ? ? ? ? ? ? ? tcon &= ~(0x0f << 8);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T1MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM2:
> + ? ? ? ? ? ? ? tcon &= ~(0x0f << 0x0c);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T2MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? tcon &= ~(0xf << 0x10);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T3MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? tcon &= ~(7 << 0x14);
> + ? ? ? ? ? ? ? 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 s5p_time_start(enum s5p_timer_mode mode, bool periodic)
> +{
> + ? ? ? unsigned long tcon;
> +
> + ? ? ? tcon ?= __raw_readl(S3C2410_TCON);
> +
> + ? ? ? switch (mode) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T0START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T0MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T0RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T0RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM1:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T1START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T1MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T1RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T1RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM2:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T2START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T2MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T2RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T2RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T3START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T3MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T3RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T3RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_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 s5p_set_next_event(unsigned long cycles,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *evt)
> +{
> + ? ? ? s5p_time_setup(timer_source.event_id, cycles);
> + ? ? ? s5p_time_start(timer_source.event_id, NON_PERIODIC);
> +
> + ? ? ? return 0;
> +}
> +
> +static void s5p_set_mode(enum clock_event_mode mode,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *evt)
> +{
> +
> + ? ? ? s5p_time_stop(timer_source.event_id);
> +
> + ? ? ? switch (mode) {
> + ? ? ? case CLOCK_EVT_MODE_PERIODIC:
> + ? ? ? ? ? ? ? s5p_time_setup(timer_source.event_id, clock_count_per_tick);
> + ? ? ? ? ? ? ? s5p_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:
> + ? ? ? ? ? ? ? s5p_timer_resume();
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +}
> +
> +static void s5p_timer_resume(void)
> +{
> + ? ? ? /* event timer restart */
> + ? ? ? s5p_time_setup(timer_source.event_id, clock_count_per_tick);
> + ? ? ? s5p_time_start(timer_source.event_id, PERIODIC);
> +
> + ? ? ? /* source timer restart */
> + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> +}
> +
> +void __init s5p_set_timer_source(enum s5p_timer_mode event,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?enum s5p_timer_mode source)
> +{
> + ? ? ? timer_source.event_id = event;
> + ? ? ? timer_source.source_id = source;
> +}
> +
> +static struct clock_event_device time_event_device = {
> + ? ? ? .name ? ? ? ? ? = "s5p_event_timer",
> + ? ? ? .features ? ? ? = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> + ? ? ? .rating ? ? ? ? = 200,
> + ? ? ? .shift ? ? ? ? ?= 32,
Please use the new clock event function. I can't remember the exact
function name, but there's function set the proper shift value instead
of hard-coded.
> + ? ? ? .set_next_event = s5p_set_next_event,
> + ? ? ? .set_mode ? ? ? = s5p_set_mode,
> +};
> +
> +static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
> +{
> + ? ? ? struct clock_event_device *evt = &time_event_device;
> +
> + ? ? ? evt->event_handler(evt);
> +
> + ? ? ? return IRQ_HANDLED;
> +}
> +
> +static struct irqaction s5p_clock_event_irq = {
> + ? ? ? .name ? ? ? ? ? = "s5p_time_irq",
> + ? ? ? .flags ? ? ? ? ?= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> + ? ? ? .handler ? ? ? ?= s5p_clock_event_isr,
> +};
> +
> +static void s5p_clockevent_init(void)

Please add __init since it's only used at __init function.
> +{
> + ? ? ? 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 / 2);
> + ? ? ? clk_set_rate(tdiv_event, pclk / 2);
> + ? ? ? clk_set_parent(tin_event, tdiv_event);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_event);
> + ? ? ? clock_count_per_tick = clock_rate / HZ;
> +
> + ? ? ? time_event_device.mult =
> + ? ? ? ? ? ? ? div_sc(clock_rate, NSEC_PER_SEC, time_event_device.shift);
> + ? ? ? time_event_device.max_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(-1, &time_event_device);
> + ? ? ? time_event_device.min_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(1, &time_event_device);
> +
> + ? ? ? time_event_device.cpumask = cpumask_of(0);
> + ? ? ? clockevents_register_device(&time_event_device);
> +
> + ? ? ? irq_number = timer_source.event_id + IRQ_TIMER0;
> +
> + ? ? ? setup_irq(irq_number, &s5p_clock_event_irq);
> +}
> +
> +static cycle_t s5p_timer_read(struct clocksource *cs)
> +{
> + ? ? ? unsigned long offset = 0;
> +
> + ? ? ? switch (timer_source.source_id) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? case S5P_PWM1:
> + ? ? ? case S5P_PWM2:
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? offset = (timer_source.source_id * 0x0c) + 0x14;
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? offset = 0x40;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
> + ? ? ? ? ? ? ? return 0;
> + ? ? ? }
> +
> + ? ? ? return (cycle_t) ~__raw_readl(S3C_TIMERREG(offset));
> +}
> +
> +struct clocksource time_clocksource = {
> + ? ? ? .name ? ? ? ? ? = "s5p_clocksource_timer",
> + ? ? ? .rating ? ? ? ? = 250,
> + ? ? ? .read ? ? ? ? ? = s5p_timer_read,
> + ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32),
> + ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static void s5p_clocksource_init(void)
ditto.
> +{
> + ? ? ? unsigned long pclk;
> + ? ? ? unsigned long clock_rate;
> +
> + ? ? ? pclk = clk_get_rate(timerclk);
> +
> + ? ? ? clk_set_rate(tdiv_source, pclk / 2);
> + ? ? ? clk_set_parent(tin_source, tdiv_source);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_source);
> +
> + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> +
> + ? ? ? if (clocksource_register_hz(&time_clocksource, clock_rate))
> + ? ? ? ? ? ? ? panic("%s: can't register clocksource\n", time_clocksource.name);
> +}
> +
> +static void __init s5p_timer_resources(void)
> +{
> + ? ? ? struct platform_device tmpdev;
> +
> + ? ? ? tmpdev.dev.bus = &platform_bus_type;
> +
> + ? ? ? timerclk = clk_get(NULL, "timers");
> + ? ? ? if (IS_ERR(timerclk))
> + ? ? ? ? ? ? ? panic("failed to get timers clock for system timer");
> +
> + ? ? ? clk_enable(timerclk);
> +
> + ? ? ? tmpdev.id = timer_source.event_id;
> + ? ? ? tin_event = clk_get(&tmpdev.dev, "pwm-tin");
> + ? ? ? if (IS_ERR(tin_event)) {
> + ? ? ? ? ? ? ? clk_put(tin_event);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tin2 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? tdiv_event = clk_get(&tmpdev.dev, "pwm-tdiv");
> + ? ? ? if (IS_ERR(tdiv_event)) {
> + ? ? ? ? ? ? ? clk_put(tdiv_event);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tdiv2 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? clk_enable(tin_event);
> +
> + ? ? ? tmpdev.id = timer_source.source_id;
> + ? ? ? tin_source = clk_get(&tmpdev.dev, "pwm-tin");
> + ? ? ? if (IS_ERR(tin_source)) {
> + ? ? ? ? ? ? ? clk_put(tin_source);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tin4 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? tdiv_source = clk_get(&tmpdev.dev, "pwm-tdiv");
> + ? ? ? if (IS_ERR(tdiv_source)) {
> + ? ? ? ? ? ? ? clk_put(tdiv_source);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tdiv4 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? clk_enable(tin_source);
> +}
> +
> +static void __init s5p_timer_init(void)
> +{
> +#ifdef CONFIG_LOCAL_TIMERS
> + ? ? ? twd_base = S5P_VA_TWD;
> +#endif
> +
> + ? ? ? s5p_timer_resources();
> + ? ? ? s5p_clockevent_init();
> + ? ? ? s5p_clocksource_init();
> +}
> +
> +struct sys_timer s5p_timer = {
> + ? ? ? .init ? ? ? ? ? = s5p_timer_init,
> +};
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH 6/6] ARM: S5PV210: Add PWM backlight support on SMDKV210
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-1-git-send-email-banajit.g@samsung.com>

This patch adds support for LCD backlight control using PWM timer
for Samsung's SMDKV210 board.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig         |    1 +
 arch/arm/mach-s5pv210/mach-smdkv210.c |   46 +++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 53aabef..d7fd031 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -130,6 +130,7 @@ config MACH_SMDKV210
 	select SAMSUNG_DEV_ADC
 	select SAMSUNG_DEV_IDE
 	select SAMSUNG_DEV_KEYPAD
+	select SAMSUNG_DEV_PWM
 	select SAMSUNG_DEV_TS
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_I2C1
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index bc9fdb5..8833e7b 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -18,6 +18,7 @@
 #include <linux/fb.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
+#include <linux/pwm_backlight.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -43,6 +44,7 @@
 #include <plat/keypad.h>
 #include <plat/pm.h>
 #include <plat/fb.h>
+#include <plat/gpio-cfg.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -208,6 +210,45 @@ static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
 	.setup_gpio	= s5pv210_fb_gpio_setup_24bpp,
 };
 
+static int smdkv210_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S5PV210_GPD0(3), "Backlight");
+	if (ret) {
+		printk(KERN_ERR "failed to request GPD for PWM-OUT 3\n");
+		return ret;
+	}
+
+	/* Configure GPIO pin with S5PV210_GPD_0_3_TOUT_3 */
+	s3c_gpio_cfgpin(S5PV210_GPD0(3), (0x2 << 12));
+
+	return 0;
+}
+
+static void smdkv210_backlight_exit(struct device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_OUTPUT);
+	gpio_free(S5PV210_GPD0(3));
+}
+
+static struct platform_pwm_backlight_data smdkv210_backlight_data = {
+	.pwm_id		= 3,
+	.max_brightness	= 255,
+	.dft_brightness	= 255,
+	.pwm_period_ns	= 78770,
+	.init		= smdkv210_backlight_init,
+	.exit		= smdkv210_backlight_exit,
+};
+
+static struct platform_device smdkv210_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent		= &s3c_device_timer[3].dev,
+		.platform_data	= &smdkv210_backlight_data,
+	},
+};
+
 static struct platform_device *smdkv210_devices[] __initdata = {
 	&s3c_device_adc,
 	&s3c_device_cfcon,
@@ -229,6 +270,11 @@ static struct platform_device *smdkv210_devices[] __initdata = {
 	&samsung_device_keypad,
 	&smdkv210_dm9000,
 	&smdkv210_lcd_lte480wv,
+	&s3c_device_timer[0],
+	&s3c_device_timer[1],
+	&s3c_device_timer[2],
+	&s3c_device_timer[3],
+	&smdkv210_backlight_device,
 };
 
 static void __init smdkv210_dm9000_init(void)
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 5/6] ARM: S5PC100: Add PWM backlight support on SMDKC100
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-1-git-send-email-banajit.g@samsung.com>

This patch adds support for LCD backlight using PWM timer for
Samsung SMDKC100 board.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s5pc100/Kconfig         |    1 +
 arch/arm/mach-s5pc100/mach-smdkc100.c |   48 ++++++++++++++++++++++++++++++---
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index b8fbf2f..608722f 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -58,6 +58,7 @@ config MACH_SMDKC100
 	select SAMSUNG_DEV_ADC
 	select SAMSUNG_DEV_IDE
 	select SAMSUNG_DEV_KEYPAD
+	select SAMSUNG_DEV_PWM
 	select SAMSUNG_DEV_TS
 	select S5PC100_SETUP_FB_24BPP
 	select S5PC100_SETUP_I2C1
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index dd192a2..22d5348 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -23,12 +23,15 @@
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/pwm_backlight.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include <mach/map.h>
 #include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+
 #include <video/platform_lcd.h>
 
 #include <asm/irq.h>
@@ -107,9 +110,6 @@ static struct i2c_board_info i2c_devs1[] __initdata = {
 static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
 				   unsigned int power)
 {
-	/* backlight */
-	gpio_direction_output(S5PC100_GPD(0), power);
-
 	if (power) {
 		/* module reset */
 		gpio_direction_output(S5PC100_GPH0(6), 1);
@@ -178,6 +178,44 @@ static struct samsung_keypad_platdata smdkc100_keypad_data __initdata = {
 	.rows		= 2,
 	.cols		= 8,
 };
+
+static int smdkc100_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S5PC100_GPD(0), "Backlight");
+	if (ret) {
+		printk(KERN_ERR "failed to request GPF for PWM-OUT0\n");
+		return ret;
+	}
+
+	/* Configure GPIO pin with S5PC100_GPD_TOUT_0 */
+	s3c_gpio_cfgpin(S5PC100_GPD(0), (0x2 << 0));
+
+	return 0;
+}
+
+static void smdkc100_backlight_exit(struct device *dev)
+{
+	s3c_gpio_cfgpin(S5PC100_GPD(0), S3C_GPIO_OUTPUT);
+	gpio_free(S5PC100_GPD(0));
+}
+
+static struct platform_pwm_backlight_data smdkc100_backlight_data = {
+	.pwm_id		= 0,
+	.max_brightness	= 255,
+	.dft_brightness	= 255,
+	.pwm_period_ns	= 78770,
+	.init		= smdkc100_backlight_init,
+	.exit		= smdkc100_backlight_exit,
+};
+
+static struct platform_device smdkc100_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent		= &s3c_device_timer[0].dev,
+		.platform_data	= &smdkc100_backlight_data,
+	},
+};
 
 static struct platform_device *smdkc100_devices[] __initdata = {
 	&s3c_device_adc,
@@ -200,6 +238,9 @@ static struct platform_device *smdkc100_devices[] __initdata = {
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
 	&s5pc100_device_spdif,
+	&s3c_device_timer[0],
+	&s3c_device_timer[1],
+	&smdkc100_backlight_device,
 };
 
 static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
@@ -233,7 +274,6 @@ static void __init smdkc100_machine_init(void)
 	s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
 
 	/* LCD init */
-	gpio_request(S5PC100_GPD(0), "GPD");
 	gpio_request(S5PC100_GPH0(6), "GPH0");
 	smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
 	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 4/6] ARM: S5P64X0: Add PWM backlight support on SMDK6450
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-1-git-send-email-banajit.g@samsung.com>

This patch adds support for LCD backlight control using PWM timer
for Samsung SMDK6450 board.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s5p64x0/Kconfig         |    1 +
 arch/arm/mach-s5p64x0/mach-smdk6450.c |   44 +++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index be5888a..08b0a5b 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -48,6 +48,7 @@ config MACH_SMDK6450
 	select S3C_DEV_WDT
 	select S3C64XX_DEV_SPI
 	select SAMSUNG_DEV_ADC
+	select SAMSUNG_DEV_PWM
 	select SAMSUNG_DEV_TS
 	select S5P64X0_SETUP_I2C1
 	help
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 3a20de0..296cc0f 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,6 +33,7 @@
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 #include <mach/i2c.h>
+#include <mach/regs-gpio.h>
 
 #include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
@@ -106,6 +108,45 @@ static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
 #endif
 };
 
+static int smdk6450_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S5P6450_GPF(15), "Backlight");
+	if (ret) {
+		printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
+		return ret;
+	}
+
+	/* Configure GPIO pin with S5P6450_GPF15_PWM_TOUT1 */
+	s3c_gpio_cfgpin(S5P6450_GPF(15), (0x02 << 30));
+
+	return 0;
+}
+
+static void smdk6450_backlight_exit(struct device *dev)
+{
+	s3c_gpio_cfgpin(S5P6450_GPF(15), S3C_GPIO_OUTPUT);
+	gpio_free(S5P6450_GPF(15));
+}
+
+static struct platform_pwm_backlight_data smdk6450_backlight_data = {
+	.pwm_id		= 1,
+	.max_brightness	= 255,
+	.dft_brightness	= 255,
+	.pwm_period_ns	= 78770,
+	.init		= smdk6450_backlight_init,
+	.exit		= smdk6450_backlight_exit,
+};
+
+static struct platform_device smdk6450_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent		= &s3c_device_timer[1].dev,
+		.platform_data	= &smdk6450_backlight_data,
+	},
+};
+
 static struct platform_device *smdk6450_devices[] __initdata = {
 	&s3c_device_adc,
 	&s3c_device_rtc,
@@ -115,6 +156,9 @@ static struct platform_device *smdk6450_devices[] __initdata = {
 	&s3c_device_wdt,
 	&samsung_asoc_dma,
 	&s5p6450_device_iis0,
+	&s3c_device_timer[0],
+	&s3c_device_timer[1],
+	&smdk6450_backlight_device,
 	/* s5p6450_device_spi0 will be added */
 };
 
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 3/6] ARM: S5P64X0: Add PWM backlight support on SMDK6440
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-1-git-send-email-banajit.g@samsung.com>

This patch adds support for LCD backlight control using PWM timer
for Samsung SMDK6440 board.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s5p64x0/Kconfig         |    1 +
 arch/arm/mach-s5p64x0/mach-smdk6440.c |   44 +++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 164d278..be5888a 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -34,6 +34,7 @@ config MACH_SMDK6440
 	select S3C_DEV_WDT
 	select S3C64XX_DEV_SPI
 	select SAMSUNG_DEV_ADC
+	select SAMSUNG_DEV_PWM
 	select SAMSUNG_DEV_TS
 	select S5P64X0_SETUP_I2C1
 	help
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index e5beb84..58941d7 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,6 +33,7 @@
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 #include <mach/i2c.h>
+#include <mach/regs-gpio.h>
 
 #include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
@@ -88,6 +90,45 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
 	},
 };
 
+static int smdk6440_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S5P6440_GPF(15), "Backlight");
+	if (ret) {
+		printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
+		return ret;
+	}
+
+	/* Configure GPIO pin with S5P6440_GPF15_PWM_TOUT1 */
+	s3c_gpio_cfgpin(S5P6440_GPF(15), (0x02 << 30));
+
+	return 0;
+}
+
+static void smdk6440_backlight_exit(struct device *dev)
+{
+	s3c_gpio_cfgpin(S5P6440_GPF(15), S3C_GPIO_OUTPUT);
+	gpio_free(S5P6440_GPF(15));
+}
+
+static struct platform_pwm_backlight_data smdk6440_backlight_data = {
+	.pwm_id		= 1,
+	.max_brightness	= 255,
+	.dft_brightness	= 255,
+	.pwm_period_ns	= 78770,
+	.init		= smdk6440_backlight_init,
+	.exit		= smdk6440_backlight_exit,
+};
+
+static struct platform_device smdk6440_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent		= &s3c_device_timer[1].dev,
+		.platform_data	= &smdk6440_backlight_data,
+	},
+};
+
 static struct platform_device *smdk6440_devices[] __initdata = {
 	&s3c_device_adc,
 	&s3c_device_rtc,
@@ -97,6 +138,9 @@ static struct platform_device *smdk6440_devices[] __initdata = {
 	&s3c_device_wdt,
 	&samsung_asoc_dma,
 	&s5p6440_device_iis,
+	&s3c_device_timer[0],
+	&s3c_device_timer[1],
+	&smdk6440_backlight_device,
 };
 
 static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 2/6] ARM: S3C64XX: Add PWM backlight support on SMDK6410
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-1-git-send-email-banajit.g@samsung.com>

This patch adds support for LCD backlight using PWM timer for
Samsung SMDK6410 board.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s3c64xx/Kconfig         |    1 +
 arch/arm/mach-s3c64xx/mach-smdk6410.c |   46 ++++++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index f3a953f..e4177e2 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -143,6 +143,7 @@ config MACH_SMDK6410
 	select S3C_DEV_USB_HSOTG
 	select S3C_DEV_WDT
 	select SAMSUNG_DEV_KEYPAD
+	select SAMSUNG_DEV_PWM
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select S3C64XX_SETUP_SDHCI
 	select S3C64XX_SETUP_I2C1
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index e85192a..4a3fe0c 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/smsc911x.h>
 #include <linux/regulator/fixed.h>
+#include <linux/pwm_backlight.h>
 
 #ifdef CONFIG_SMDK6410_WM1190_EV1
 #include <linux/mfd/wm8350/core.h>
@@ -48,6 +49,7 @@
 #include <mach/hardware.h>
 #include <mach/regs-fb.h>
 #include <mach/map.h>
+#include <mach/gpio-bank-f.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -118,7 +120,6 @@ static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
 {
 	if (power) {
 		gpio_direction_output(S3C64XX_GPF(13), 1);
-		gpio_direction_output(S3C64XX_GPF(15), 1);
 
 		/* fire nRESET on power up */
 		gpio_direction_output(S3C64XX_GPN(5), 0);
@@ -126,7 +127,6 @@ static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
 		gpio_direction_output(S3C64XX_GPN(5), 1);
 		msleep(1);
 	} else {
-		gpio_direction_output(S3C64XX_GPF(15), 0);
 		gpio_direction_output(S3C64XX_GPF(13), 0);
 	}
 }
@@ -269,6 +269,45 @@ static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
 	.cols		= 8,
 };
 
+static int smdk6410_backlight_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S3C64XX_GPF(15), "Backlight");
+	if (ret) {
+		printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
+		return ret;
+	}
+
+	/* Configure GPIO pin with S3C64XX_GPF15_PWM_TOUT1 */
+	s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C64XX_GPF15_PWM_TOUT1);
+
+	return 0;
+}
+
+static void smdk6410_backlight_exit(struct device *dev)
+{
+	s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_OUTPUT);
+	gpio_free(S3C64XX_GPF(15));
+}
+
+static struct platform_pwm_backlight_data smdk6410_backlight_data = {
+	.pwm_id		= 1,
+	.max_brightness	= 255,
+	.dft_brightness	= 255,
+	.pwm_period_ns	= 78770,
+	.init		= smdk6410_backlight_init,
+	.exit		= smdk6410_backlight_exit,
+};
+
+static struct platform_device smdk6410_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent		= &s3c_device_timer[1].dev,
+		.platform_data	= &smdk6410_backlight_data,
+	},
+};
+
 static struct map_desc smdk6410_iodesc[] = {};
 
 static struct platform_device *smdk6410_devices[] __initdata = {
@@ -298,6 +337,9 @@ static struct platform_device *smdk6410_devices[] __initdata = {
 	&s3c_device_rtc,
 	&s3c_device_ts,
 	&s3c_device_wdt,
+	&s3c_device_timer[0],
+	&s3c_device_timer[1],
+	&smdk6410_backlight_device,
 };
 
 #ifdef CONFIG_REGULATOR
@@ -693,7 +735,6 @@ static void __init smdk6410_machine_init(void)
 
 	gpio_request(S3C64XX_GPN(5), "LCD power");
 	gpio_request(S3C64XX_GPF(13), "LCD power");
-	gpio_request(S3C64XX_GPF(15), "LCD power");
 
 	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
 	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 1/6] ARM: SAMSUNG: Move PWM device definition from plat-s3c24xx to plat-samsung
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-1-git-send-email-banajit.g@samsung.com>

This patch does the following:
1. It moves file pwm.c from plat-s3c24xx to plat-samsung. This will
   enable all machines with Samsung SoCs to make use of the same code.
2. The device definitions have been separated to a new file dev-pwm.c
   for better clarity and structure.
3. It will enable all Samsung S3C and S5P series SoC's to use common
   PWM Kconfig definition.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s3c64xx/Kconfig   |    4 +-
 arch/arm/plat-s3c24xx/Kconfig   |    7 -----
 arch/arm/plat-samsung/Kconfig   |   13 +++++++++
 arch/arm/plat-samsung/Makefile  |    1 +
 arch/arm/plat-samsung/dev-pwm.c |   52 +++++++++++++++++++++++++++++++++++++++
 arch/arm/plat-samsung/pwm.c     |   33 ------------------------
 6 files changed, 68 insertions(+), 42 deletions(-)
 create mode 100644 arch/arm/plat-samsung/dev-pwm.c

diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 579d2f0..f3a953f 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -231,7 +231,7 @@ config MACH_HMT
 	select S3C_DEV_NAND
 	select S3C_DEV_USB_HOST
 	select S3C64XX_SETUP_FB_24BPP
-	select HAVE_PWM
+	select SAMSUNG_DEV_PWM
 	help
 	  Machine support for the Airgoo HMT
 
@@ -249,8 +249,8 @@ config MACH_SMARTQ
 	select S3C64XX_SETUP_SDHCI
 	select S3C64XX_SETUP_FB_24BPP
 	select SAMSUNG_DEV_ADC
+	select SAMSUNG_DEV_PWM
 	select SAMSUNG_DEV_TS
-	select HAVE_PWM
 	help
 	    Shared machine support for SmartQ 5/7
 
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index eb105e6..d9c4096 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -56,13 +56,6 @@ config S3C24XX_DCLK
 	help
 	  Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
 
-config S3C24XX_PWM
-	bool "PWM device support"
-	select HAVE_PWM
-	help
-	  Support for exporting the PWM timer blocks via the pwm device
-	  system.
-
 # gpio configurations
 
 config S3C24XX_GPIO_EXTRA
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 32be05c..184a85a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -273,6 +273,19 @@ config SAMSUNG_DEV_KEYPAD
 	help
 	  Compile in platform device definitions for keypad
 
+config SAMSUNG_DEV_PWM
+	bool
+	default y if ARCH_S3C2410
+	help
+	  Compile in platform device definition for PWM Timer
+
+config S3C24XX_PWM
+	bool "PWM device support"
+	select HAVE_PWM
+	help
+	  Support for exporting the PWM timer blocks via the pwm device
+	  system.
+
 # DMA
 
 config S3C_DMA
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 29932f8..e9de58a 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_SAMSUNG_DEV_ADC)	+= dev-adc.o
 obj-$(CONFIG_SAMSUNG_DEV_IDE)	+= dev-ide.o
 obj-$(CONFIG_SAMSUNG_DEV_TS)	+= dev-ts.o
 obj-$(CONFIG_SAMSUNG_DEV_KEYPAD)	+= dev-keypad.o
+obj-$(CONFIG_SAMSUNG_DEV_PWM)	+= dev-pwm.o
 
 # DMA support
 
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
new file mode 100644
index 0000000..68c5986
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-pwm.c
@@ -0,0 +1,53 @@
+/* linux/arch/arm/plat-samsung/dev-pwm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C series device definition for the PWM 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+
+#include <plat/devs.h>
+
+#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)			\
+	.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,
+ * we do not bother setting any IO resource for the base.
+ */
+
+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) },
+};
+EXPORT_SYMBOL(s3c_device_timer);
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
index 2eeb49f..f37457c 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -20,10 +20,8 @@
 #include <linux/io.h>
 #include <linux/pwm.h>
 
-#include <mach/irqs.h>
 #include <mach/map.h>
 
-#include <plat/devs.h>
 #include <plat/regs-timer.h>
 
 struct pwm_device {
@@ -47,37 +45,6 @@ struct pwm_device {
 
 static struct clk *clk_scaler[2];
 
-/* Standard setup for a timer block. */
-
-#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)			\
-	.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, we do not
- * bother setting any IO resource for the base.
- */
-
-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) },
-};
-
 static inline int pwm_is_tdiv(struct pwm_device *pwm)
 {
 	return clk_get_parent(pwm->clk) == pwm->clk_div;
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH 0/6] ARM: SAMSUNG: Add support PWM backlight
From: Banajit Goswami @ 2011-02-26  4:29 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support PWM backlight for S5P SoCs.

1. Move PWM timer code from plat-s3c24xx to plat-samsung for common useability
2. Add PWM backlight support for SMDK6410/6440/6450/C100 and SMDKV210

Note: The modification of GPIO F for S5P64X0 patch should be merged first as
there is a dependency for PWM on S5P64X0.

[PATCH 1/6] ARM: SAMSUNG: Move PWM device definition from plat-s3c24xx to plat-samsung
[PATCH 2/6] ARM: S3C64XX: Add PWM backlight support on SMDK6410
[PATCH 3/6] ARM: S5P64X0: Add PWM backlight support on SMDK6440
[PATCH 4/6] ARM: S5P64X0: Add PWM backlight support on SMDK6450
[PATCH 5/6] ARM: S5PC100: Add PWM backlight support on SMDKC100
[PATCH 6/6] ARM: S5PV210: Add PWM backlight support on SMDKV210

^ permalink raw reply

* [PATCH 2/3] ARM: S5P: Update machine initialization for HRT
From: Kyungmin Park @ 2011-02-26  4:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298688357-20775-3-git-send-email-sbkim73@samsung.com>

Acked-by: Kyungmin Park <kyungmin.park@samsung.com>

It's just curious. Are there any reason to use PWM2 & 4. Theoretically
it's possible to use PWM2 for other purpose as it's connected with
external devices such as haptic or PWM backlight.

But in case of PWM3 doesn't, it's only used for internal purpose. no
external output pin.

I just wonder it.
If you know the history reason, please let me know.

Thank you,
Kyungmin Park

On Sat, Feb 26, 2011 at 11:45 AM, Sangbeom Kim <sbkim73@samsung.com> wrote:
> This patch update mach-s5p64x0 and mach-s5pv210
> machine ?initialization for hrt support
>
> Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
> ---
> ?arch/arm/mach-s5p64x0/mach-smdk6440.c | ? ?4 +++-
> ?arch/arm/mach-s5p64x0/mach-smdk6450.c | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-aquila.c ? | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-goni.c ? ? | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-smdkc110.c | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-smdkv210.c | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-torbreck.c | ? ?4 +++-
> ?7 files changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
> index e5beb84..f967736 100644
> --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
> +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
> @@ -43,6 +43,7 @@
> ?#include <plat/pll.h>
> ?#include <plat/adc.h>
> ?#include <plat/ts.h>
> +#include <plat/s5p-time.h>
>
> ?#define SMDK6440_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_UCON_RXILEVEL | ? ? ? ? \
> @@ -136,6 +137,7 @@ static void __init smdk6440_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
> ? ? ? ?s3c24xx_init_clocks(12000000);
> ? ? ? ?s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdk6440_machine_init(void)
> @@ -159,5 +161,5 @@ MACHINE_START(SMDK6440, "SMDK6440")
> ? ? ? ?.init_irq ? ? ? = s5p6440_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdk6440_map_io,
> ? ? ? ?.init_machine ? = smdk6440_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
> index 3a20de0..686ec56 100644
> --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
> +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
> @@ -43,6 +43,7 @@
> ?#include <plat/pll.h>
> ?#include <plat/adc.h>
> ?#include <plat/ts.h>
> +#include <plat/s5p-time.h>
>
> ?#define SMDK6450_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_UCON_RXILEVEL | ? ? ? ? \
> @@ -155,6 +156,7 @@ static void __init smdk6450_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
> ? ? ? ?s3c24xx_init_clocks(19200000);
> ? ? ? ?s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdk6450_machine_init(void)
> @@ -178,5 +180,5 @@ MACHINE_START(SMDK6450, "SMDK6450")
> ? ? ? ?.init_irq ? ? ? = s5p6450_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdk6450_map_io,
> ? ? ? ?.init_machine ? = smdk6450_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
> index 557add4..fab84f3 100644
> --- a/arch/arm/mach-s5pv210/mach-aquila.c
> +++ b/arch/arm/mach-s5pv210/mach-aquila.c
> @@ -39,6 +39,7 @@
> ?#include <plat/fb.h>
> ?#include <plat/fimc-core.h>
> ?#include <plat/sdhci.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define AQUILA_UCON_DEFAULT ? ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -664,6 +665,7 @@ static void __init aquila_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init aquila_machine_init(void)
> @@ -698,5 +700,5 @@ MACHINE_START(AQUILA, "Aquila")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = aquila_map_io,
> ? ? ? ?.init_machine ? = aquila_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
> index 056f5c7..5eda4a1 100644
> --- a/arch/arm/mach-s5pv210/mach-goni.c
> +++ b/arch/arm/mach-s5pv210/mach-goni.c
> @@ -45,6 +45,7 @@
> ?#include <plat/keypad.h>
> ?#include <plat/sdhci.h>
> ?#include <plat/clock.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define GONI_UCON_DEFAULT ? ? ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -823,6 +824,7 @@ static void __init goni_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init goni_machine_init(void)
> @@ -873,5 +875,5 @@ MACHINE_START(GONI, "GONI")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = goni_map_io,
> ? ? ? ?.init_machine ? = goni_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
> index ce11a02..f304383 100644
> --- a/arch/arm/mach-s5pv210/mach-smdkc110.c
> +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
> @@ -30,6 +30,7 @@
> ?#include <plat/ata.h>
> ?#include <plat/iic.h>
> ?#include <plat/pm.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define SMDKC110_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -111,6 +112,7 @@ static void __init smdkc110_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdkc110_machine_init(void)
> @@ -138,5 +140,5 @@ MACHINE_START(SMDKC110, "SMDKC110")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdkc110_map_io,
> ? ? ? ?.init_machine ? = smdkc110_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
> index bc9fdb5..41080bf 100644
> --- a/arch/arm/mach-s5pv210/mach-smdkv210.c
> +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
> @@ -43,6 +43,7 @@
> ?#include <plat/keypad.h>
> ?#include <plat/pm.h>
> ?#include <plat/fb.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define SMDKV210_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -272,6 +273,7 @@ static void __init smdkv210_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdkv210_machine_init(void)
> @@ -306,5 +308,5 @@ MACHINE_START(SMDKV210, "SMDKV210")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdkv210_map_io,
> ? ? ? ?.init_machine ? = smdkv210_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
> index 043c938..b3516a1 100644
> --- a/arch/arm/mach-s5pv210/mach-torbreck.c
> +++ b/arch/arm/mach-s5pv210/mach-torbreck.c
> @@ -27,6 +27,7 @@
> ?#include <plat/devs.h>
> ?#include <plat/cpu.h>
> ?#include <plat/iic.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define TORBRECK_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -104,6 +105,7 @@ static void __init torbreck_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init torbreck_machine_init(void)
> @@ -127,5 +129,5 @@ MACHINE_START(TORBRECK, "TORBRECK")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = torbreck_map_io,
> ? ? ? ?.init_machine ? = torbreck_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH] ARM: S5P64X0: Modify number of GPIO lines in Bank F
From: Banajit Goswami @ 2011-02-26  4:25 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modifies the number of total GPIO lines for Bank F
for Samsung S5P6440 and S5P6450 SoCs from 2 to 16.
This is necessary as the GPIO lines from 0 to 13 are reserved
and only lines 14 and 15 are used. As during initialization,
the line number starts at 0, putting 2 does not solve the
intended purpose.

Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
---
 arch/arm/mach-s5p64x0/include/mach/gpio.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-s5p64x0/include/mach/gpio.h b/arch/arm/mach-s5p64x0/include/mach/gpio.h
index 5486c8f..adb5f29 100644
--- a/arch/arm/mach-s5p64x0/include/mach/gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/gpio.h
@@ -23,7 +23,7 @@
 #define S5P6440_GPIO_A_NR	(6)
 #define S5P6440_GPIO_B_NR	(7)
 #define S5P6440_GPIO_C_NR	(8)
-#define S5P6440_GPIO_F_NR	(2)
+#define S5P6440_GPIO_F_NR	(16)
 #define S5P6440_GPIO_G_NR	(7)
 #define S5P6440_GPIO_H_NR	(10)
 #define S5P6440_GPIO_I_NR	(16)
@@ -36,7 +36,7 @@
 #define S5P6450_GPIO_B_NR	(7)
 #define S5P6450_GPIO_C_NR	(8)
 #define S5P6450_GPIO_D_NR	(8)
-#define S5P6450_GPIO_F_NR	(2)
+#define S5P6450_GPIO_F_NR	(16)
 #define S5P6450_GPIO_G_NR	(14)
 #define S5P6450_GPIO_H_NR	(10)
 #define S5P6450_GPIO_I_NR	(16)
-- 
1.6.5.2

^ permalink raw reply related

* [PATCH] ARM: hw_breakpoint: Fix newlines in WARNings
From: Stephen Boyd @ 2011-02-26  4:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298633466.32588.1.camel@e102144-lin.cambridge.arm.com>

These warnings are missing newlines and spaces causing confusing
looking output when they trigger.

Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---

Will Deacon wrote:
> > I'd prefer the message text not to be line wrapped, even if it
> > violates the general line length rule, because that makes it easier to
> > grep for the message in the source code.
>
> Ok, that's understandable. Moving the text onto its own line will limit
> the damage to the line length too. Stephen - are you happy to make these
> changes as part of your previous patch?

Sure.

 arch/arm/kernel/hw_breakpoint.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index d600bd3..6da9132 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -238,8 +238,8 @@ static int enable_monitor_mode(void)
 	ARM_DBG_READ(c1, 0, dscr);
 
 	/* Ensure that halting mode is disabled. */
-	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled."
-				"Unable to access hardware resources.")) {
+	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
+			"halting debug mode enabled. Unable to access hardware resources.\n")) {
 		ret = -EPERM;
 		goto out;
 	}
@@ -377,7 +377,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
 		}
 	}
 
-	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) {
+	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -423,7 +423,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
 		}
 	}
 
-	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot"))
+	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
 		return;
 
 	/* Reset the control register. */
@@ -635,7 +635,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	if (WARN_ONCE(!bp->overflow_handler &&
 		(arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
 		 || !bp->hw.bp_target),
-			"overflow handler required but none found")) {
+			"overflow handler required but none found\n")) {
 		ret = -EINVAL;
 	}
 out:
@@ -916,8 +916,8 @@ static int __init arch_hw_breakpoint_init(void)
 	ARM_DBG_READ(c1, 0, dscr);
 	if (dscr & ARM_DSCR_HDBGEN) {
 		max_watchpoint_len = 4;
-		pr_warning("halting debug mode enabled. Assuming maximum "
-			   "watchpoint size of %u bytes.", max_watchpoint_len);
+		pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
+			   max_watchpoint_len);
 	} else {
 		/* Work out the maximum supported watchpoint length. */
 		max_watchpoint_len = get_max_wp_len();
-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 3/3] ARM: S5P: Update defconfig for HRT support
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298688357-20775-1-git-send-email-sbkim73@samsung.com>

This patch modify s5pv210_defconfig and s5p64x0_defconfig
for HRT support

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 arch/arm/Kconfig                   |    4 ++--
 arch/arm/configs/s5p64x0_defconfig |    2 ++
 arch/arm/configs/s5pv210_defconfig |    2 ++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 166efa2..8b959e1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -715,7 +715,7 @@ config ARCH_S5P64X0
 	select GENERIC_GPIO
 	select HAVE_CLK
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
-	select ARCH_USES_GETTIMEOFFSET
+	select GENERIC_CLOCKEVENTS
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	help
@@ -753,7 +753,7 @@ config ARCH_S5PV210
 	select HAVE_CLK
 	select ARM_L1_CACHE_SHIFT_6
 	select ARCH_HAS_CPUFREQ
-	select ARCH_USES_GETTIMEOFFSET
+	select GENERIC_CLOCKEVENTS
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
diff --git a/arch/arm/configs/s5p64x0_defconfig b/arch/arm/configs/s5p64x0_defconfig
index 2993ecd..ad6b61b 100644
--- a/arch/arm/configs/s5p64x0_defconfig
+++ b/arch/arm/configs/s5p64x0_defconfig
@@ -10,6 +10,8 @@ CONFIG_S3C_BOOT_ERROR_RESET=y
 CONFIG_S3C_LOWLEVEL_UART_PORT=1
 CONFIG_MACH_SMDK6440=y
 CONFIG_MACH_SMDK6450=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_CPU_32v6K=y
 CONFIG_AEABI=y
 CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
diff --git a/arch/arm/configs/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
index 0488a1e..fa98990 100644
--- a/arch/arm/configs/s5pv210_defconfig
+++ b/arch/arm/configs/s5pv210_defconfig
@@ -13,6 +13,8 @@ CONFIG_MACH_AQUILA=y
 CONFIG_MACH_GONI=y
 CONFIG_MACH_SMDKC110=y
 CONFIG_MACH_SMDKV210=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/3] ARM: S5P: Update machine initialization for HRT
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298688357-20775-1-git-send-email-sbkim73@samsung.com>

This patch update mach-s5p64x0 and mach-s5pv210
machine  initialization for hrt support

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 arch/arm/mach-s5p64x0/mach-smdk6440.c |    4 +++-
 arch/arm/mach-s5p64x0/mach-smdk6450.c |    4 +++-
 arch/arm/mach-s5pv210/mach-aquila.c   |    4 +++-
 arch/arm/mach-s5pv210/mach-goni.c     |    4 +++-
 arch/arm/mach-s5pv210/mach-smdkc110.c |    4 +++-
 arch/arm/mach-s5pv210/mach-smdkv210.c |    4 +++-
 arch/arm/mach-s5pv210/mach-torbreck.c |    4 +++-
 7 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index e5beb84..f967736 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -43,6 +43,7 @@
 #include <plat/pll.h>
 #include <plat/adc.h>
 #include <plat/ts.h>
+#include <plat/s5p-time.h>
 
 #define SMDK6440_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
 				S3C2410_UCON_RXILEVEL |		\
@@ -136,6 +137,7 @@ static void __init smdk6440_map_io(void)
 	s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdk6440_machine_init(void)
@@ -159,5 +161,5 @@ MACHINE_START(SMDK6440, "SMDK6440")
 	.init_irq	= s5p6440_init_irq,
 	.map_io		= smdk6440_map_io,
 	.init_machine	= smdk6440_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 3a20de0..686ec56 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -43,6 +43,7 @@
 #include <plat/pll.h>
 #include <plat/adc.h>
 #include <plat/ts.h>
+#include <plat/s5p-time.h>
 
 #define SMDK6450_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
 				S3C2410_UCON_RXILEVEL |		\
@@ -155,6 +156,7 @@ static void __init smdk6450_map_io(void)
 	s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
 	s3c24xx_init_clocks(19200000);
 	s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdk6450_machine_init(void)
@@ -178,5 +180,5 @@ MACHINE_START(SMDK6450, "SMDK6450")
 	.init_irq	= s5p6450_init_irq,
 	.map_io		= smdk6450_map_io,
 	.init_machine	= smdk6450_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 557add4..fab84f3 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -39,6 +39,7 @@
 #include <plat/fb.h>
 #include <plat/fimc-core.h>
 #include <plat/sdhci.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define AQUILA_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -664,6 +665,7 @@ static void __init aquila_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init aquila_machine_init(void)
@@ -698,5 +700,5 @@ MACHINE_START(AQUILA, "Aquila")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= aquila_map_io,
 	.init_machine	= aquila_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 056f5c7..5eda4a1 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -45,6 +45,7 @@
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/clock.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define GONI_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -823,6 +824,7 @@ static void __init goni_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init goni_machine_init(void)
@@ -873,5 +875,5 @@ MACHINE_START(GONI, "GONI")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= goni_map_io,
 	.init_machine	= goni_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index ce11a02..f304383 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -30,6 +30,7 @@
 #include <plat/ata.h>
 #include <plat/iic.h>
 #include <plat/pm.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC110_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -111,6 +112,7 @@ static void __init smdkc110_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdkc110_machine_init(void)
@@ -138,5 +140,5 @@ MACHINE_START(SMDKC110, "SMDKC110")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= smdkc110_map_io,
 	.init_machine	= smdkc110_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index bc9fdb5..41080bf 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -43,6 +43,7 @@
 #include <plat/keypad.h>
 #include <plat/pm.h>
 #include <plat/fb.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -272,6 +273,7 @@ static void __init smdkv210_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdkv210_machine_init(void)
@@ -306,5 +308,5 @@ MACHINE_START(SMDKV210, "SMDKV210")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= smdkv210_map_io,
 	.init_machine	= smdkv210_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
index 043c938..b3516a1 100644
--- a/arch/arm/mach-s5pv210/mach-torbreck.c
+++ b/arch/arm/mach-s5pv210/mach-torbreck.c
@@ -27,6 +27,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/iic.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define TORBRECK_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -104,6 +105,7 @@ static void __init torbreck_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init torbreck_machine_init(void)
@@ -127,5 +129,5 @@ MACHINE_START(TORBRECK, "TORBRECK")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= torbreck_map_io,
 	.init_machine	= torbreck_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
-- 
1.7.1

^ permalink raw reply related

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298688357-20775-1-git-send-email-sbkim73@samsung.com>

This patch adds support HR-Timer(High Resolution Timer) and dynamic
tick system for S5P SoCs. There are many clock sources for HR-Timer
on S5P SoCs. The PWM timer, RTC, System Timer, and MCT can be used
for clock source.
This patch can only support PWM timer for clocksource of
S5P64x0 and S5PV210.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 arch/arm/plat-s5p/Makefile                |    1 +
 arch/arm/plat-s5p/include/plat/s5p-time.h |   37 +++
 arch/arm/plat-s5p/s5p-time.c              |  395 +++++++++++++++++++++++++++++
 3 files changed, 433 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-s5p/include/plat/s5p-time.h
 create mode 100644 arch/arm/plat-s5p/s5p-time.c

diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 4bd5cf9..3b8cc2f 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_S5P_GPIO_INT)	+= irq-gpioint.o
 obj-$(CONFIG_S5P_SYSTEM_MMU)	+= sysmmu.o
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM)		+= irq-pm.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS) += s5p-time.o
 
 # devices
 
diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
new file mode 100644
index 0000000..e478f0c
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-time.h
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Header file for s5p time 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_S5P_TIME_H
+#define __ASM_PLAT_S5P_TIME_H __FILE__
+
+/* S5P HR-Timer Clock mode */
+enum s5p_timer_mode {
+	S5P_PWM0,
+	S5P_PWM1,
+	S5P_PWM2,
+	S5P_PWM3,
+	S5P_PWM4,
+};
+
+struct s5p_timer_source {
+	unsigned int event_id;
+	unsigned int source_id;
+};
+
+#define TCNT_MAX		0xffffffff
+#define NON_PERIODIC		0
+#define PERIODIC		1
+
+extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
+					enum s5p_timer_mode source);
+extern	struct sys_timer s5p_timer;
+#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
new file mode 100644
index 0000000..4691728
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p-time.c
@@ -0,0 +1,395 @@
+/* linux/arch/arm/plat-s5p/s5p-time.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P - Common hr-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.
+*/
+
+#include <linux/sched.h>
+#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 <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/regs-timer.h>
+#include <plat/s5p-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 s5p_timer_source timer_source;
+static unsigned long clock_count_per_tick;
+static void s5p_timer_resume(void);
+
+static void s5p_time_stop(enum s5p_timer_mode mode)
+{
+	unsigned long tcon;
+
+	tcon = __raw_readl(S3C2410_TCON);
+
+	switch (mode) {
+	case S5P_PWM0:
+		tcon &= ~S3C2410_TCON_T0START;
+		break;
+
+	case S5P_PWM1:
+		tcon &= ~S3C2410_TCON_T1START;
+		break;
+
+	case S5P_PWM2:
+		tcon &= ~S3C2410_TCON_T2START;
+		break;
+
+	case S5P_PWM3:
+		tcon &= ~S3C2410_TCON_T3START;
+		break;
+
+	case S5P_PWM4:
+		tcon &= ~S3C2410_TCON_T4START;
+		break;
+
+	default:
+		printk(KERN_ERR "Invalid Timer %d\n", mode);
+		break;
+	}
+	__raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
+{
+	unsigned long tcon;
+
+	tcon = __raw_readl(S3C2410_TCON);
+
+	tcnt--;
+
+	switch (mode) {
+	case S5P_PWM0:
+		tcon &= ~(0x0f << 0);
+		tcon |= S3C2410_TCON_T0MANUALUPD;
+		break;
+
+	case S5P_PWM1:
+		tcon &= ~(0x0f << 8);
+		tcon |= S3C2410_TCON_T1MANUALUPD;
+		break;
+
+	case S5P_PWM2:
+		tcon &= ~(0x0f << 0x0c);
+		tcon |= S3C2410_TCON_T2MANUALUPD;
+		break;
+
+	case S5P_PWM3:
+		tcon &= ~(0xf << 0x10);
+		tcon |= S3C2410_TCON_T3MANUALUPD;
+		break;
+
+	case S5P_PWM4:
+		tcon &= ~(7 << 0x14);
+		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 s5p_time_start(enum s5p_timer_mode mode, bool periodic)
+{
+	unsigned long tcon;
+
+	tcon  = __raw_readl(S3C2410_TCON);
+
+	switch (mode) {
+	case S5P_PWM0:
+		tcon |= S3C2410_TCON_T0START;
+		tcon &= ~S3C2410_TCON_T0MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T0RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T0RELOAD;
+		break;
+
+	case S5P_PWM1:
+		tcon |= S3C2410_TCON_T1START;
+		tcon &= ~S3C2410_TCON_T1MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T1RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T1RELOAD;
+		break;
+
+	case S5P_PWM2:
+		tcon |= S3C2410_TCON_T2START;
+		tcon &= ~S3C2410_TCON_T2MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T2RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T2RELOAD;
+		break;
+
+	case S5P_PWM3:
+		tcon |= S3C2410_TCON_T3START;
+		tcon &= ~S3C2410_TCON_T3MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T3RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T3RELOAD;
+		break;
+
+	case S5P_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 s5p_set_next_event(unsigned long cycles,
+				struct clock_event_device *evt)
+{
+	s5p_time_setup(timer_source.event_id, cycles);
+	s5p_time_start(timer_source.event_id, NON_PERIODIC);
+
+	return 0;
+}
+
+static void s5p_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+
+	s5p_time_stop(timer_source.event_id);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+		s5p_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:
+		s5p_timer_resume();
+		break;
+	}
+}
+
+static void s5p_timer_resume(void)
+{
+	/* event timer restart */
+	s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+	s5p_time_start(timer_source.event_id, PERIODIC);
+
+	/* source timer restart */
+	s5p_time_setup(timer_source.source_id, TCNT_MAX);
+	s5p_time_start(timer_source.source_id, PERIODIC);
+}
+
+void __init s5p_set_timer_source(enum s5p_timer_mode event,
+				 enum s5p_timer_mode source)
+{
+	timer_source.event_id = event;
+	timer_source.source_id = source;
+}
+
+static struct clock_event_device time_event_device = {
+	.name		= "s5p_event_timer",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.rating		= 200,
+	.shift		= 32,
+	.set_next_event	= s5p_set_next_event,
+	.set_mode	= s5p_set_mode,
+};
+
+static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &time_event_device;
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction s5p_clock_event_irq = {
+	.name		= "s5p_time_irq",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= s5p_clock_event_isr,
+};
+
+static void s5p_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 / 2);
+	clk_set_rate(tdiv_event, pclk / 2);
+	clk_set_parent(tin_event, tdiv_event);
+
+	clock_rate = clk_get_rate(tin_event);
+	clock_count_per_tick = clock_rate / HZ;
+
+	time_event_device.mult =
+		div_sc(clock_rate, NSEC_PER_SEC, time_event_device.shift);
+	time_event_device.max_delta_ns =
+		clockevent_delta2ns(-1, &time_event_device);
+	time_event_device.min_delta_ns =
+		clockevent_delta2ns(1, &time_event_device);
+
+	time_event_device.cpumask = cpumask_of(0);
+	clockevents_register_device(&time_event_device);
+
+	irq_number = timer_source.event_id + IRQ_TIMER0;
+
+	setup_irq(irq_number, &s5p_clock_event_irq);
+}
+
+static cycle_t s5p_timer_read(struct clocksource *cs)
+{
+	unsigned long offset = 0;
+
+	switch (timer_source.source_id) {
+	case S5P_PWM0:
+	case S5P_PWM1:
+	case S5P_PWM2:
+	case S5P_PWM3:
+		offset = (timer_source.source_id * 0x0c) + 0x14;
+	case S5P_PWM4:
+		offset = 0x40;
+		break;
+
+	default:
+		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+		return 0;
+	}
+
+	return (cycle_t) ~__raw_readl(S3C_TIMERREG(offset));
+}
+
+struct clocksource time_clocksource = {
+	.name		= "s5p_clocksource_timer",
+	.rating		= 250,
+	.read		= s5p_timer_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void s5p_clocksource_init(void)
+{
+	unsigned long pclk;
+	unsigned long clock_rate;
+
+	pclk = clk_get_rate(timerclk);
+
+	clk_set_rate(tdiv_source, pclk / 2);
+	clk_set_parent(tin_source, tdiv_source);
+
+	clock_rate = clk_get_rate(tin_source);
+
+	s5p_time_setup(timer_source.source_id, TCNT_MAX);
+	s5p_time_start(timer_source.source_id, PERIODIC);
+
+	if (clocksource_register_hz(&time_clocksource, clock_rate))
+		panic("%s: can't register clocksource\n", time_clocksource.name);
+}
+
+static void __init s5p_timer_resources(void)
+{
+	struct platform_device tmpdev;
+
+	tmpdev.dev.bus = &platform_bus_type;
+
+	timerclk = clk_get(NULL, "timers");
+	if (IS_ERR(timerclk))
+		panic("failed to get timers clock for system timer");
+
+	clk_enable(timerclk);
+
+	tmpdev.id = timer_source.event_id;
+	tin_event = clk_get(&tmpdev.dev, "pwm-tin");
+	if (IS_ERR(tin_event)) {
+		clk_put(tin_event);
+		panic("failed to get pwm-tin2 clock for system timer");
+	}
+
+	tdiv_event = clk_get(&tmpdev.dev, "pwm-tdiv");
+	if (IS_ERR(tdiv_event)) {
+		clk_put(tdiv_event);
+		panic("failed to get pwm-tdiv2 clock for system timer");
+	}
+
+	clk_enable(tin_event);
+
+	tmpdev.id = timer_source.source_id;
+	tin_source = clk_get(&tmpdev.dev, "pwm-tin");
+	if (IS_ERR(tin_source)) {
+		clk_put(tin_source);
+		panic("failed to get pwm-tin4 clock for system timer");
+	}
+
+	tdiv_source = clk_get(&tmpdev.dev, "pwm-tdiv");
+	if (IS_ERR(tdiv_source)) {
+		clk_put(tdiv_source);
+		panic("failed to get pwm-tdiv4 clock for system timer");
+	}
+
+	clk_enable(tin_source);
+}
+
+static void __init s5p_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+	twd_base = S5P_VA_TWD;
+#endif
+
+	s5p_timer_resources();
+	s5p_clockevent_init();
+	s5p_clocksource_init();
+}
+
+struct sys_timer s5p_timer = {
+	.init		= s5p_timer_init,
+};
-- 
1.7.1

^ permalink raw reply related

* [PATCH 0/3] ARM: S5P: Add high resolution timer support
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch-set adds support for HRT(High Resolution Timer).
In Samsung SoCs, there is many HRT timer sources.
PWM Timer, System Timer, MCT, RTC can be used for that.
In this patches, Only support PWM Timer.
But All kind of pwm timer can be used for clock source.
This patch is tested on SMDKC110, SMDK6450.
APM is only tested on SMDKC110.
Next version will support System Timer, RTC, MCT.

[PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
[PATCH 2/3] ARM: S5P: Update machine initialization for HRT
[PATCH 3/3] ARM: S5P: Update defconfig for HRT support

^ permalink raw reply

* [PATCH] msm: gpiomux: Remove GPIOMUX_VALID and merge config enums
From: Rohit Vaswani @ 2011-02-26  2:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AANLkTinZCtbQnAk_OX92jqbW_GjH5wpxvbeoMkHV1inn@mail.gmail.com>

On 2/25/2011 5:20 PM, Dima Zavin wrote:
> On Fri, Feb 25, 2011 at 12:19 PM, Rohit Vaswani<rvaswani@codeaurora.org>  wrote:
>> Remove GPIOMUX_VALID, simplify the API, and absorb the complexity
>> of determining which gpiomux configs are used and which are
>> not back into the gpiomux implementation where it belongs.
>> Allow NULL settings to be represented appropriately.
>> The configuration enumerations represent a single abstraction
>> and were needlessly split. As such, collapse the conflicting
>> abstractions into a consistent one and move the implementation
>> complexity down into the implementation (where it belongs) and
>> away from the interface (where it doesn't belong).
>>
>> Signed-off-by: Rohit Vaswani<rvaswani@codeaurora.org>
>> ---
>>   arch/arm/mach-msm/board-msm7x30.c |   23 +++++++--
>>   arch/arm/mach-msm/board-qsd8x50.c |   17 +++++--
>>   arch/arm/mach-msm/gpiomux-v1.c    |    9 ++-
>>   arch/arm/mach-msm/gpiomux-v1.h    |   59 ----------------------
>>   arch/arm/mach-msm/gpiomux-v2.c    |    8 ++-
>>   arch/arm/mach-msm/gpiomux-v2.h    |   59 ----------------------
>>   arch/arm/mach-msm/gpiomux.c       |   77 +++++++++++++++++-------------
>>   arch/arm/mach-msm/gpiomux.h       |   96
>> +++++++++++++++++++++++-------------
>>   8 files changed, 145 insertions(+), 203 deletions(-)
>>   delete mode 100644 arch/arm/mach-msm/gpiomux-v1.h
>>   delete mode 100644 arch/arm/mach-msm/gpiomux-v2.h
>>
>> diff --git a/arch/arm/mach-msm/board-msm7x30.c
>> b/arch/arm/mach-msm/board-msm7x30.c
>> index 59b91de..4223329 100644
>> --- a/arch/arm/mach-msm/board-msm7x30.c
>> +++ b/arch/arm/mach-msm/board-msm7x30.c
>> @@ -39,8 +39,11 @@
>>   #include "gpiomux.h"
>>   #include "proc_comm.h"
>>
>> -#define UART2_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
>> -            GPIOMUX_FUNC_2 | GPIOMUX_VALID)
>> +static struct gpiomux_setting uart2_suspended = {
>> +    .func = GPIOMUX_FUNC_2,
>> +    .drv = GPIOMUX_DRV_2MA,
>> +    .pull = GPIOMUX_PULL_DOWN,
>> +};
>>
>>   extern struct sys_timer msm_timer;
>>
>> @@ -59,19 +62,27 @@ static struct msm_otg_platform_data msm_otg_pdata = {
>>   struct msm_gpiomux_config msm7x30_uart2_configs[] __initdata = {
>>      {
>>          .gpio = 49, /* UART2 RFR */
>> -        .suspended = UART2_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart2_suspended,
>> +        },
>>      },
>>      {
>>          .gpio = 50, /* UART2 CTS */
>> -        .suspended = UART2_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart2_suspended,
>> +        },
>>      },
>>      {
>>          .gpio = 51, /* UART2 RX */
>> -        .suspended = UART2_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart2_suspended,
>> +        },
>>      },
>>      {
>>          .gpio = 52, /* UART2 TX */
>> -        .suspended = UART2_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart2_suspended,
>> +        },
>>      },
>>   };
>>
>> diff --git a/arch/arm/mach-msm/board-qsd8x50.c
>> b/arch/arm/mach-msm/board-qsd8x50.c
>> index 33ab1fe..d665b0e 100644
>> --- a/arch/arm/mach-msm/board-qsd8x50.c
>> +++ b/arch/arm/mach-msm/board-qsd8x50.c
>> @@ -38,19 +38,26 @@
>>   #include "devices.h"
>>   #include "gpiomux.h"
>>
>> -#define UART3_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
>> -            GPIOMUX_FUNC_1 | GPIOMUX_VALID)
>> +static struct gpiomux_setting uart3_suspended = {
>> +    .drv = GPIOMUX_DRV_2MA,
>> +    .pull = GPIOMUX_PULL_DOWN,
>> +    .func = GPIOMUX_FUNC_1,
>> +};
>>
>>   extern struct sys_timer msm_timer;
>>
>> -struct msm_gpiomux_config qsd8x50_uart3_configs[] __initdata = {
>> +struct msm_gpiomux_config qsd8x50_uart3_configs[] = {
>>      {
>>          .gpio = 86, /* UART3 RX */
>> -        .suspended = UART3_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart3_suspended,
>> +        },
>>      },
>>      {
>>          .gpio = 87, /* UART3 TX */
>> -        .suspended = UART3_SUSPENDED,
>> +        .settings = {
>> +            [GPIOMUX_SUSPENDED] =&uart3_suspended,
>> +        },
>>      },
>>   };
> I think this new interface is way too verbose and will quickly get
> unwieldy for configurations that have more than a few pins. For
> instance, imagine what the above would look like when muxing a 24bit
> LCD pin list...
>
> How about adding a "bool valid" to gpiomux_setting, and convert the
> "sets" array to an array of settings and not pointers to settings.
> This will allow us to do (in gpiomux.h):
>
> struct msm_gpiomux_rec {
>      struct gpiomux_setting sets[GPIOMUX_NSETTINGS];
>      int ref;
> };
>
> struct gpiomux_setting {
>      enum gpiomux_func func;
>      enum gpiomux_drv  drv;
>      enum gpiomux_pull pull;
>      bool valid;
> };
>
> This way, I can do something like (very rough):
>
> #define GPIOMUX_SET(func,drv,pull) { \
>      .func = GPIOMUX_##func, \
>      .drv = GPIOMUX_##drv, \
>      .pull = GPIOMUX_##pull, \
>      .valid = true, \
>    }
>
> #define GPIOMUX_SET_NONE { .valid = false, }
>
> #define GPIOMUX_CFG(g, active, suspended) { \
>       .gpio = g, \
>       .sets = { \
>           [GPIOMUX_ACTIVE] = active, \
>           [GPIOMUX_SUSPENDED] = suspended, \
>        }, \
>   }
>
> This will then allow me to define the uart3 pinmuxing in my board file
> as follows:
>
> struct msm_gpiomux_rec uart3_mux_cfg[] = {
>      GPIOMUX_CFG(86, GPIOMUX_SET_NONE,
>                             GPIOMUX_SET(FUNC_1, DRV_2MA, PULL_DOWN)),
>      GPIOMUX_CFG(87, GPIOMUX_SET_NONE,
>                             GPIOMUX_SET(FUNC_1, DRV_2MA, PULL_DOWN)),
> };
>
> Thoughts?
>
> --Dima
>

Thanks for you feedback Dima. I agree that the above change makes the 
pin configurations verbose - but its neither too verbose to so as to 
become cumbersome to use nor typically unmanageable. We did think about 
adding a valid/invalid bool to the configurations - but the fact was 
that they it simply did not belong there. The gpiomux configurations are 
never "invalid" as such. Another important part to this decision was 
that - with adding another variable as a part of the gpiomux 
configurations meant that we were transferring responsibility of 
maintaining something that belongs to the "gpiomux internals" to the 
user. We felt that having the user to append a valid/invalid flag with 
every configuration to was not a step in the right direction.
On the contrary, the explicit structures improved readability and kept 
things pretty simple. Thinking about it more - it doesn't even make it 
verbose - but it just may seem that way because we expand it into a 
structure instead of hiding behind a macro.
Also, we currently use this same design for a number of GPIOs far 
greater than 24 and my/our experience has never been bothersome.
Hope that answers your query.

  Thanks,
Rohit Vaswani

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply

* [PATCH V2] arm: mach-mmp: brownstone.c support multiple sd slots
From: Philip Rakity @ 2011-02-26  1:50 UTC (permalink / raw)
  To: linux-arm-kernel

Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3.
mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device.
mmc1 is used for Wifi and slot is marked PERMANENT

Note: eMMC (mmc2) is set to initialize first to workaround a problem
where booting in logical order requires mmc create work queue
to be multi-threaded otherwise boot process hangs.  BUG report
send to linux-mmc and linux-kernel mailing list.

Wifi (mmc1) requires we enable power on the device by toggling
the gpio lines for power and reset.

Signed-off-by: Philip Rakity <prakity@marvell.com>
---
 arch/arm/mach-mmp/brownstone.c |   42 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 7bb78fd..36d5b82 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -19,6 +19,7 @@
 #include <linux/regulator/max8649.h>
 #include <linux/regulator/fixed.h>
 #include <linux/mfd/max8925.h>
+#include <linux/delay.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -180,6 +181,45 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
 	.max_speed	= 25000000,
 };
 
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
+	.flags		= PXA_FLAG_CARD_PERMANENT,
+};
+
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
+	.flags		= PXA_FLAG_CARD_PERMANENT |
+				PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
+};
+
+static void __init mmc_sdio_wifi(void)
+{
+	int poweron;
+	int reset;
+
+	poweron = mfp_to_gpio(GPIO57_GPIO);
+	reset = mfp_to_gpio(GPIO58_GPIO);
+
+	if(gpio_request(reset, "sd8xxx reset")) {
+		printk(KERN_INFO "gpio %d request failed\n", reset);
+		return;
+	}
+
+	if(gpio_request(poweron, "sd8xxx PDn")) {
+		gpio_free(reset);
+		printk(KERN_INFO "gpio %d request failed\n", poweron);
+		return;
+	}
+
+	gpio_direction_output(poweron, 1);
+	msleep (1);
+	gpio_direction_output(reset, 0);
+	msleep (1);
+	gpio_direction_output(reset, 1);
+	gpio_free(reset);
+	gpio_free(poweron);
+
+	mmp2_add_sdhost(1, &mmp2_sdh_platdata_mmc1); /* Wifi */
+}
+
 static void __init brownstone_init(void)
 {
 	mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
@@ -188,7 +228,9 @@ static void __init brownstone_init(void)
 	mmp2_add_uart(1);
 	mmp2_add_uart(3);
 	mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
+	mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
 	mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
+	mmc_sdio_wifi();
 
 	/* enable 5v regulator */
 	platform_device_register(&brownstone_v_5vp_device);
-- 
1.7.0.4

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox