Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] gpio: exynos4: Add device tree support
From: Rob Herring @ 2011-10-11 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318320974-9879-1-git-send-email-thomas.abraham@linaro.org>

Thomas,

On 10/11/2011 03:16 AM, Thomas Abraham wrote:
> As gpio chips get registered, a device tree node which represents the
> gpio chip is searched and attached to it. A translate function is also
> provided to convert the gpio specifier into actual platform settings
> for pin function selection, pull up/down and driver strength settings.
> 
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> This patch is based on the latest consolidated Samsung GPIO driver available
> in the following tree:
>   https://github.com/kgene/linux-samsung.git  branch: for-next
> 
>  .../devicetree/bindings/gpio/gpio-samsung.txt      |   30 +++++++++++
>  drivers/gpio/gpio-samsung.c                        |   53 ++++++++++++++++++++
>  2 files changed, 83 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-samsung.txt
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt
> new file mode 100644
> index 0000000..883faeb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt
> @@ -0,0 +1,30 @@
> +Samsung Exynos4 GPIO Controller
> +
> +Required properties:
> +- compatible: Format of compatible property value should be
> +  "samsung,exynos4-gpio-<controller_name>". Example: For GPA0 controller, the
> +  compatible property value should be "samsung,exynos4-gpio-gpa0".

Isn't gpa0 an instance of the h/w, not a version?

> +
> +- reg: Physical base address of the controller and length of memory mapped region.
> +
> +- #gpio-cells: Should be 4. The syntax of the gpio specifier used by client nodes
> +  should be the following with values derived from the SoC user manual.
> +     <[phandle of the gpio controller node] <pin number within the gpio controller]
> +      [mux function] [pull up/down] [drive strength]>

It would be better to list out the values here.

> +
> +- gpio-controller: Specifies that the node is a gpio controller.
> +
> +- #address-cells: should be 1.
> +
> +- #size-cells: should be 1. 
> +
> +Example:
> +
> +	gpa0: gpio-controller at 11400000 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "samsung,exynos4-gpio-gpa0";
> +		reg = <0x11400000 0x20>;
> +		#gpio-cells = <4>;
> +		gpio-controller;
> +	};
> diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
> index b6be77a..037d3bb 100644
> --- a/drivers/gpio/gpio-samsung.c
> +++ b/drivers/gpio/gpio-samsung.c
> @@ -24,6 +24,10 @@
>  #include <linux/interrupt.h>
>  #include <linux/sysdev.h>
>  #include <linux/ioport.h>
> +#ifdef CONFIG_OF
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#endif

Don't need the ifdef here.

>  
>  #include <asm/irq.h>
>  
> @@ -2353,6 +2357,52 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
>  #endif
>  };
>  
> +#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
> +int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,

static

> +			 const void *gpio_spec, u32 *flags)
> +{
> +	const __be32 *gpio = gpio_spec;
> +	const u32 n = be32_to_cpup(gpio);
> +	unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
> +
> +	if (gc->of_gpio_n_cells < 4) {
> +		WARN_ON(1);
> +		return -EINVAL;
> +	}
> +
> +	if (n > gc->ngpio)
> +		return -EINVAL;
> +
> +	s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1])));
> +	s3c_gpio_setpull(pin, be32_to_cpu(gpio[2]));
> +	s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3]));
> +	return n;
> +}
> +
> +static __init void exynos4_gpiolib_attach_ofnode(struct gpio_chip *gc)
> +{
> +	const char exynos4_gpio_compat_base[] = "samsung,exynos4-gpio-";
> +	char *exynos4_gpio_compat;
> +
> +	exynos4_gpio_compat = kzalloc(strlen(exynos4_gpio_compat_base) +
> +				strlen(gc->label), GFP_KERNEL);
> +	if (!exynos4_gpio_compat)
> +		return;
> +
> +	strcpy(exynos4_gpio_compat, exynos4_gpio_compat_base);
> +	strcat(exynos4_gpio_compat, gc->label);
> +	gc->of_node = of_find_compatible_node(NULL, NULL, exynos4_gpio_compat);
> +	gc->of_gpio_n_cells = 4;
> +	gc->of_xlate = exynos4_gpio_xlate;
> +	kfree(exynos4_gpio_compat);
> +}
> +#else
> +static __init void exynos4_gpiolib_attach_ofnode(struct gpio_chip *chip)
> +{
> +	return;
> +}
> +#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */
> +
>  /* TODO: cleanup soc_is_* */
>  static __init int samsung_gpiolib_init(void)
>  {
> @@ -2434,6 +2484,7 @@ static __init int samsung_gpiolib_init(void)
>  				chip->config = &exynos4_gpio_cfg;
>  				chip->group = group++;
>  			}
> +			exynos4_gpiolib_attach_ofnode(&chip->chip);
>  		}
>  		samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
>  
> @@ -2446,6 +2497,7 @@ static __init int samsung_gpiolib_init(void)
>  				chip->config = &exynos4_gpio_cfg;
>  				chip->group = group++;
>  			}
> +			exynos4_gpiolib_attach_ofnode(&chip->chip);
>  		}
>  		samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
>  
> @@ -2458,6 +2510,7 @@ static __init int samsung_gpiolib_init(void)
>  				chip->config = &exynos4_gpio_cfg;
>  				chip->group = group++;
>  			}
> +			exynos4_gpiolib_attach_ofnode(&chip->chip);
>  		}
>  		samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
>  

This code is really ugly, but I guess you inherited it. Converting to a
platform driver and using id table would be much cleaner.

Rob

^ permalink raw reply

* [GIT PULL] DEBUG_LL platform updates for 3.2
From: Will Deacon @ 2011-10-11 15:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201110111533.50768.arnd@arndb.de>

On Tue, Oct 11, 2011 at 02:33:50PM +0100, Arnd Bergmann wrote:
> On Monday 10 October 2011, Will Deacon wrote:
> > I don't think asking Russell to maintain a stable branch for each series
> > scales very well if multiple people are doing cross-platform work at the
> > same time. If he's happy merging platform code via his tree, then I'd prefer
> > to go down that route. In this case, it might make sense to try and catch
> > conflicts between his tree and arm-soc before they hit Linus (I guess -next
> > will take care of this?).
> 
> Yes, we can definitely spot the conflicts in linux-next, and it gives us
> the chance to fix them up, e.g. I can wait with sending the arm-soc
> branches upstream until Russell's branches are merged, at which point
> I just pull in the branch that was merged into Linus' tree and resolve
> all conflicts I get.

Ok, that sounds good to me.

> > > Can you check if the devel-stable branch in his tree already contains the
> > > dependencies?
> > 
> > I just had a quick look and I can't seem them outside of the unstable for-next
> > branch.
> 
> Ok. I think I'll drop the cpu-mapping branch from arm-soc as well then.

Sure, I'll resubmit it to Russell via the patch system with your ack. I'll
do the same for the DEBUG_LL platform updates too.

> Are the patches in Russell's tree true dependencies for your work, or just
> patches touching the same files? If you can send me a branch that contains
> only your work without any of the patches that are in an unstable branch
> on Russell's side, I could also take them into arm-soc and take care
> of the conflicts together with Stephen.

For the cpu-mapping, I depend on:

ARM: 7011/1: Add ARM cpu topology definition
ARM: 7060/1: smp: populate logical CPU mapping during boot
ARM: 7061/1: gic: convert logical CPU numbers into physical numbers

which I can only see in Russell's for-next branch.

For the debug-ll stuff, I depend on:

ARM: 7072/1: debug: use kconfig choice for selecting DEBUG_LL UART

and conflict with:

ARM: 7097/1: debug: Move DEBUG_ICEDCC into the DEBUG_LL choice
ARM: 7096/1: debug: Add UART1 config choices
ARM: 7116/1: debug: provide dummy default option for DEBUG_LL UART choice
ARM: 7073/1: debug: augment DEBUG_LL Kconfig help to clarify behaviour

so it's probably easier to go via Russell this time.

Cheers,

Will

^ permalink raw reply

* [PATCH v6 00/10] Add device tree support for PL330 dma controller driver
From: Thomas Abraham @ 2011-10-11 15:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <057401cc880e$41e30b20$c5a92160$%kim@samsung.com>

Hi Vinod,

On 11 October 2011 17:36, Kukjin Kim <kgene.kim@samsung.com> wrote:
> Thomas Abraham wrote:
>>
>> Changes since v5:
>> - Added alias clocks for pdma clocks on Exynos4.
>> - Modified platform data for s5p64x0, s5pc100 and s5pv210.
>> - Rebased on the tip of for-next branch of linux-samsung kernel and
> tested.
>>
>> Changes since v4:
>> - Rebased with Samsung maintainer's for-next branch which is at
> linux-3.1-rc7
>> ? - Modified Patch 6/6 to apply cleanly.
>>
>> Changes since v3:
>> - In Patch 4/6, a recommendation is added in the pl330 binding
> documentation
>> ? for the name of the property which specifies the dma channel in the
> client
>> ? device node.
>> - In Patch 6/6, dropped #ifdef around of_have_populated_dt.
>>
>> Changes since v2:
>> - Only the sixth patch is changed, to make dma platform data conditionally
>> ? selectable.
>> - Tested with v8 version of pl330 dma driver update patches from Boojin
> Kim.
>>
>> Changes since v1:
>> - Removed "arm,pl330-pdma" and "arm,pl330-mdma" compatible values.
>> - Removed "arm,primecell-periphid" and "arm,pl330-peri-reqs"
>> ? property requirements.
>>
>> This patchset adds device tree support for PL330 driver and uses it to add
>> device tree support for Samsung platforms, specifically Exynos4.
>>
>> Patch 1 moves the pl330_filter function from Samsung specific wrappers to
> pl330
>> dma driver and also adds a check to ensure that the filter function
> proceeds
>> only if it the dma channel being investigated belongs to pl330 dma
> controller
>> instance.
>>
>> Patch 2 adds support to infer the direction of the dma transfer using the
>> direction specified with the transfer request instead of including this
>> information in the platform data. This simlifies the addition of device
> tree
>> support. Patch 3 simplifies the platform data for Exynos4 pl330 dma
> controllers.
>>
>> Patch 4 adds device tree support for pl330 dma controller driver. A dma
> channel
>> is represented using a phandle of the dma controller node and the channel
> id
>> within that controller. Client driver request a dma channel using the
> phandle
>> and channel id pair. Correspondingly, the pl330 filter function has been
>> modified to lookup a channel based on this value.
>>
>> Patch 5 adds device tree support for Samsung's DMA engine wrappers. Client
>> drivers retrive the channel property from their device node and pass it to
> the
>> wrappers. The wrapper functions use the property value as the filter
> function
>> parameter. Patch 6 restricts the usage of pl330 device and platform data
>> instances to non-dt platforms.
>>
>> Patch 7 adds clock alias for both the pdma clocks. When pdma controllers
> are
>> instantiated from device tree, the amba device registration process
> enables
>> clock to the controllers to read the peripheral id of the PDMA amba
> device. In
>> case of Exynos4, the clocks to the PDMA controllers are named as 'dma' but
>> amba_device_register() looks up the clock using the name 'apb_pclk'.
> Hence,
>> alias clocks with name 'apb_pclk' clock are created for clocks with name
> 'dma'.
>>
>> Patch 8 to 10 simplifies the pdma platform data for s5p64x0, s5pc100 and
>> s5pv210.
>>
>> This patchset is based on the following tree:
>> https://github.com/kgene/linux-samsung.git ? branch: for-next
>>
>> and tested tested for both device-tree and non-device-tree kernel on
> smdkv310.
>>
>> This patchset has dependency on the following patchset.
>> [PATCH V2 0/2] Add a common macro for creating struct clk_lookup entries.
>>
>>
>> Thomas Abraham (10):
>> ? DMA: PL330: move filter function into driver
>> ? DMA: PL330: Infer transfer direction from transfer request instead of
> platform
>> data
>> ? ARM: EXYNOS4: Modify platform data for pl330 driver
>> ? DMA: PL330: Add device tree support
>> ? ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers
>> ? ARM: EXYNOS4: Limit usage of pl330 device instance to non-dt build
>> ? ARM: Exynos4: Add a alias for pdma clocks
>> ? ARM: S5P64x0: Modify platform data for pl330 driver
>> ? ARM: S5PC100: Modify platform data for pl330 driver
>> ? ARM: S5PV210: Modify platform data for pl330 driver
>>
>> ?.../devicetree/bindings/dma/arm-pl330.txt ? ? ? ? ?| ? 30 +++
>> ?arch/arm/mach-exynos4/Kconfig ? ? ? ? ? ? ? ? ? ? ?| ? 10 +
>> ?arch/arm/mach-exynos4/Makefile ? ? ? ? ? ? ? ? ? ? | ? ?3 +-
>> ?arch/arm/mach-exynos4/clock.c ? ? ? ? ? ? ? ? ? ? ?| ? 35 ++-
>> ?arch/arm/mach-exynos4/dma.c ? ? ? ? ? ? ? ? ? ? ? ?| ?227
> ++++++-----------
>> --
>> ?arch/arm/mach-s5p64x0/dma.c ? ? ? ? ? ? ? ? ? ? ? ?| ?227
> +++++-------------
>> ?arch/arm/mach-s5pc100/dma.c ? ? ? ? ? ? ? ? ? ? ? ?| ?247
> ++++++-----------
>> ---
>> ?arch/arm/mach-s5pv210/dma.c ? ? ? ? ? ? ? ? ? ? ? ?| ?241
> ++++++-----------
>> ---
>> ?arch/arm/plat-samsung/dma-ops.c ? ? ? ? ? ? ? ? ? ?| ? 15 +-
>> ?arch/arm/plat-samsung/include/plat/dma-ops.h ? ? ? | ? ?1 +
>> ?arch/arm/plat-samsung/include/plat/dma-pl330.h ? ? | ? ?3 +-
>> ?drivers/dma/pl330.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 99 +++++----
>> ?include/linux/amba/pl330.h ? ? ? ? ? ? ? ? ? ? ? ? | ? 15 +-
>> ?13 files changed, 405 insertions(+), 748 deletions(-)
>> ?create mode 100644 Documentation/devicetree/bindings/dma/arm-pl330.txt
>
> Hi,
>
> Looks ok to me and if required,
> Acked-by: Kukjin Kim <kgene.kim@samsung.com>
>
> And I hope since this includes many changes of arch/arm/Samsung stuff, this
> would be sent to upstream via Samsung tree after ack from Vinod for dma
> stuff.

All the comments for this patchset that adds device tree support for
pl330 dma controller driver have been addressed. This patchset is
based on the linux-samsung kernel since there are many changes in the
samsung platform code included in this patchset.

If there are no other changes required, can this patchset be
considered for merge in 3.2 ?

Thanks,
Thomas.


>
> Thanks.
>
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
>
> --
> 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 v3 1/6] iommu/core: split mapping to page sizes as supported by the hardware
From: KyongHo Cho @ 2011-10-11 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAK=WgbbnuO67X46sqS87q2vw2TWq3Ekvw5p1PmXvXinQXMyowg@mail.gmail.com>

On Tue, Oct 11, 2011 at 7:49 AM, Ohad Ben-Cohen <ohad@wizery.com> wrote:
> ?int iommu_map(struct iommu_domain *domain, unsigned long iova,
> - ? ? ? ? ? ? phys_addr_t paddr, int gfp_order, int prot)
> + ? ? ? ? ? ? phys_addr_t paddr, int size, int prot)
> ?{
Even though it is not realistic that size becomes larger than 1 <<
((sizeof(int) * 8) - 1),
I think the type of size should be size_t.

> - ? ? ? size_t size;
> + ? ? ? unsigned long orig_iova = iova;
> + ? ? ? int ret = 0, orig_size = size;
>
> ? ? ? ?if (unlikely(domain->ops->map == NULL))
> ? ? ? ? ? ? ? ?return -ENODEV;
>
> - ? ? ? size ? ? ? ? = PAGE_SIZE << gfp_order;
> + ? ? ? /*
> + ? ? ? ?* both the virtual address and the physical one, as well as
> + ? ? ? ?* the size of the mapping, must be aligned (at least) to the
> + ? ? ? ?* size of the smallest page supported by the hardware
> + ? ? ? ?*/
> + ? ? ? if (!IS_ALIGNED(iova | paddr | size, domain->ops->min_pagesz)) {
> + ? ? ? ? ? ? ? pr_err("unaligned: iova 0x%lx pa 0x%lx size 0x%x min_pagesz "
> + ? ? ? ? ? ? ? ? ? ? ? "0x%x\n", iova, (unsigned long)paddr,
> + ? ? ? ? ? ? ? ? ? ? ? size, domain->ops->min_pagesz);
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? pr_debug("map: iova 0x%lx pa 0x%lx size 0x%x\n", iova,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (unsigned long)paddr, size);
> +
> + ? ? ? while (size) {
> + ? ? ? ? ? ? ? unsigned long pgsize, addr_merge = iova | paddr;
> + ? ? ? ? ? ? ? unsigned int pgsize_idx;
> +
> + ? ? ? ? ? ? ? /* Max page size that still fits into 'size' */
> + ? ? ? ? ? ? ? pgsize_idx = __fls(size);
> +
> + ? ? ? ? ? ? ? /* need to consider alignment requirements ? */
> + ? ? ? ? ? ? ? if (likely(addr_merge)) {
> + ? ? ? ? ? ? ? ? ? ? ? /* Max page size allowed by both iova and paddr */
> + ? ? ? ? ? ? ? ? ? ? ? unsigned int align_pgsize_idx = __ffs(addr_merge);
> +
> + ? ? ? ? ? ? ? ? ? ? ? pgsize_idx = min(pgsize_idx, align_pgsize_idx);
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* build a mask of acceptable page sizes */
> + ? ? ? ? ? ? ? pgsize = (1UL << (pgsize_idx + 1)) - 1;
> +
> + ? ? ? ? ? ? ? /* throw away page sizes not supported by the hardware */
> + ? ? ? ? ? ? ? pgsize &= domain->ops->pgsize_bitmap;
> +
> + ? ? ? ? ? ? ? /* make sure we're still sane */
> + ? ? ? ? ? ? ? BUG_ON(!pgsize);
>
> - ? ? ? BUG_ON(!IS_ALIGNED(iova | paddr, size));
> + ? ? ? ? ? ? ? /* pick the biggest page */
> + ? ? ? ? ? ? ? pgsize_idx = __fls(pgsize);
> + ? ? ? ? ? ? ? pgsize = 1UL << pgsize_idx;
>
> - ? ? ? return domain->ops->map(domain, iova, paddr, gfp_order, prot);
> + ? ? ? ? ? ? ? /* convert index to page order */
> + ? ? ? ? ? ? ? pgsize_idx -= PAGE_SHIFT;
> +
> + ? ? ? ? ? ? ? pr_debug("mapping: iova 0x%lx pa 0x%lx order %u\n", iova,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (unsigned long)paddr, pgsize_idx);
> +
> + ? ? ? ? ? ? ? ret = domain->ops->map(domain, iova, paddr, pgsize_idx, prot);
> + ? ? ? ? ? ? ? if (ret)
> + ? ? ? ? ? ? ? ? ? ? ? break;
> +
> + ? ? ? ? ? ? ? iova += pgsize;
> + ? ? ? ? ? ? ? paddr += pgsize;
> + ? ? ? ? ? ? ? size -= pgsize;
> + ? ? ? }
> +
> + ? ? ? /* unroll mapping in case something went wrong */
> + ? ? ? if (ret)
> + ? ? ? ? ? ? ? iommu_unmap(domain, orig_iova, orig_size);
> +
domain->ops->map() might return error because a mapping already exists
in the range from iova until iova + size.
Thus, it should be
iommu_unmap(domain, orig_iova, orig_size - size)

Regards,

KyongHo

^ permalink raw reply

* Add support for the SPMP8000 SoC and Letcool board
From: Arnd Bergmann @ 2011-10-11 14:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318178172-7965-1-git-send-email-zoss@devai.org>

On Sunday 09 October 2011, Zoltan Devai wrote:
> This series adds support for the Sunplus SPMP8000 SoC, an ARM926EJ-S based
> MCU, which is most commonly found in handheld game consoles and digital cams.
> Most of the work was done during GSoC 2011, with Greg KH as my mentor.
> 
> The board I'm using for development is the Letcool N350JP handheld.
> 
> The patches are based on Arnds for-next branch with Jamie Iles' vic-dt patches
> on top.
> 
> No static platform devices are used, everything is inited from DT, with some
> hacks for drivers that don't have any bindings yet.
> (Documentation for own, custom bindings will follow in next version.)
> 
> So far, these peripherals are supported, with drivers not submitted yet:
> gpio, fb, cpufreq, slave-dma, mmc, ASoC (i2s, codec, pcm, card).
> 
> Reviews, instructions for mainlining it are very welcome.

Hi Zoltan,

Looks basically ok, but there are the usual smaller things I found that
are worth improving. I like very much seeing an ARM926 port done in the
new style, especially since these tend to be much simpler than the
cortex-a9 platforms that most people are working on these days. This
gives us the chance to experiment with a complete port without having
to do heaps of new device tree bindings etc. It will also be valuable
to have this when working on single-zimage patches for ARMv5.

I would however prefer to leave the port for linux-3.3 at this point,
since we are close to the merge window and there are a lot of details
for you to work on still.
In particular, I would hope that by the time of the 3.3 merge window
we will have a proper common clockdev layer that can simplify a
significant portion of your code.

As Linus Walleij mentioned already, it would be good to move the
device drivers out of the platform directory into subsystems
below drivers/ and I hope that by 3.3 that also includes the pinmux,
clkdev, and timer drivers, possibly also pwm and adc.

My hope is that in the long run, a relatively simple platform like
this can become a single core.c file plus the optional debug_ll
support, after all the header files are consolidated and the drivers
are moved out. You won't have to wait for that though: If the code
looks ok, we can merge it in whatever the closest is we get to
the ideal at the time.

	Arnd

^ permalink raw reply

* [PATCH 1/2] iommu/core: stop converting bytes to page order
From: Ohad Ben-Cohen @ 2011-10-11 14:50 UTC (permalink / raw)
  To: linux-arm-kernel

back and forth

Express sizes in bytes rather than in page order, to eliminate the
size->order->size conversions we have whenever the IOMMU API is calling
the low level drivers' map/unmap methods.

Adopt all existing drivers.

Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
---
 drivers/iommu/amd_iommu.c   |   13 +++++--------
 drivers/iommu/intel-iommu.c |   11 ++++-------
 drivers/iommu/iommu.c       |    8 +++++---
 drivers/iommu/msm_iommu.c   |   19 +++++++------------
 drivers/iommu/omap-iommu.c  |   14 +++++---------
 include/linux/iommu.h       |    6 +++---
 6 files changed, 29 insertions(+), 42 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 764e3da..32d502e 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2702,9 +2702,8 @@ static int amd_iommu_attach_device(struct
iommu_domain *dom,
 }

 static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
-			 phys_addr_t paddr, int gfp_order, int iommu_prot)
+			 phys_addr_t paddr, size_t page_size, int iommu_prot)
 {
-	unsigned long page_size = 0x1000UL << gfp_order;
 	struct protection_domain *domain = dom->priv;
 	int prot = 0;
 	int ret;
@@ -2721,13 +2720,11 @@ static int amd_iommu_map(struct iommu_domain
*dom, unsigned long iova,
 	return ret;
 }

-static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
-			   int gfp_order)
+static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
+			   size_t page_size)
 {
 	struct protection_domain *domain = dom->priv;
-	unsigned long page_size, unmap_size;
-
-	page_size  = 0x1000UL << gfp_order;
+	size_t unmap_size;

 	mutex_lock(&domain->api_lock);
 	unmap_size = iommu_unmap_page(domain, iova, page_size);
@@ -2735,7 +2732,7 @@ static int amd_iommu_unmap(struct iommu_domain
*dom, unsigned long iova,

 	domain_flush_tlb_pde(domain);

-	return get_order(unmap_size);
+	return unmap_size;
 }

 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 2d53c3d..96a9bd4 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3821,12 +3821,11 @@ static void intel_iommu_detach_device(struct
iommu_domain *domain,

 static int intel_iommu_map(struct iommu_domain *domain,
 			   unsigned long iova, phys_addr_t hpa,
-			   int gfp_order, int iommu_prot)
+			   size_t size, int iommu_prot)
 {
 	struct dmar_domain *dmar_domain = domain->priv;
 	u64 max_addr;
 	int prot = 0;
-	size_t size;
 	int ret;

 	if (iommu_prot & IOMMU_READ)
@@ -3836,7 +3835,6 @@ static int intel_iommu_map(struct iommu_domain *domain,
 	if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
 		prot |= DMA_PTE_SNP;

-	size     = PAGE_SIZE << gfp_order;
 	max_addr = iova + size;
 	if (dmar_domain->max_addr < max_addr) {
 		u64 end;
@@ -3859,11 +3857,10 @@ static int intel_iommu_map(struct iommu_domain *domain,
 	return ret;
 }

-static int intel_iommu_unmap(struct iommu_domain *domain,
-			     unsigned long iova, int gfp_order)
+static size_t intel_iommu_unmap(struct iommu_domain *domain,
+			     unsigned long iova, size_t size)
 {
 	struct dmar_domain *dmar_domain = domain->priv;
-	size_t size = PAGE_SIZE << gfp_order;

 	dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
 			    (iova + size - 1) >> VTD_PAGE_SHIFT);
@@ -3871,7 +3868,7 @@ static int intel_iommu_unmap(struct iommu_domain *domain,
 	if (dmar_domain->max_addr == iova + size)
 		dmar_domain->max_addr = iova;

-	return gfp_order;
+	return size;
 }

 static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 63ca9ba..5d042e8 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -168,13 +168,13 @@ int iommu_map(struct iommu_domain *domain,
unsigned long iova,

 	BUG_ON(!IS_ALIGNED(iova | paddr, size));

-	return domain->ops->map(domain, iova, paddr, gfp_order, prot);
+	return domain->ops->map(domain, iova, paddr, size, prot);
 }
 EXPORT_SYMBOL_GPL(iommu_map);

 int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)
 {
-	size_t size;
+	size_t size, unmapped;

 	if (unlikely(domain->ops->unmap == NULL))
 		return -ENODEV;
@@ -183,7 +183,9 @@ int iommu_unmap(struct iommu_domain *domain,
unsigned long iova, int gfp_order)

 	BUG_ON(!IS_ALIGNED(iova, size));

-	return domain->ops->unmap(domain, iova, gfp_order);
+	unmapped = domain->ops->unmap(domain, iova, size);
+
+	return get_order(unmapped);
 }
 EXPORT_SYMBOL_GPL(iommu_unmap);

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 5865dd2..13718d9 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -352,7 +352,7 @@ fail:
 }

 static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
-			 phys_addr_t pa, int order, int prot)
+			 phys_addr_t pa, size_t len, int prot)
 {
 	struct msm_priv *priv;
 	unsigned long flags;
@@ -363,7 +363,6 @@ static int msm_iommu_map(struct iommu_domain
*domain, unsigned long va,
 	unsigned long *sl_pte;
 	unsigned long sl_offset;
 	unsigned int pgprot;
-	size_t len = 0x1000UL << order;
 	int ret = 0, tex, sh;

 	spin_lock_irqsave(&msm_iommu_lock, flags);
@@ -463,8 +462,8 @@ fail:
 	return ret;
 }

-static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
-			    int order)
+static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
+			    size_t len)
 {
 	struct msm_priv *priv;
 	unsigned long flags;
@@ -474,7 +473,6 @@ static int msm_iommu_unmap(struct iommu_domain
*domain, unsigned long va,
 	unsigned long *sl_table;
 	unsigned long *sl_pte;
 	unsigned long sl_offset;
-	size_t len = 0x1000UL << order;
 	int i, ret = 0;

 	spin_lock_irqsave(&msm_iommu_lock, flags);
@@ -544,15 +542,12 @@ static int msm_iommu_unmap(struct iommu_domain
*domain, unsigned long va,

 	ret = __flush_iotlb(domain);

-	/*
-	 * the IOMMU API requires us to return the order of the unmapped
-	 * page (on success).
-	 */
-	if (!ret)
-		ret = order;
 fail:
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
-	return ret;
+
+	/* the IOMMU API requires us to return how many bytes were unmapped */
+	len = ret ? 0 : len;
+	return len;
 }

 static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 9ee2c38..1bb2971 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1019,12 +1019,11 @@ static void iopte_cachep_ctor(void *iopte)
 }

 static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
-			 phys_addr_t pa, int order, int prot)
+			 phys_addr_t pa, size_t bytes, int prot)
 {
 	struct omap_iommu_domain *omap_domain = domain->priv;
 	struct omap_iommu *oiommu = omap_domain->iommu_dev;
 	struct device *dev = oiommu->dev;
-	size_t bytes = PAGE_SIZE << order;
 	struct iotlb_entry e;
 	int omap_pgsz;
 	u32 ret, flags;
@@ -1049,19 +1048,16 @@ static int omap_iommu_map(struct iommu_domain
*domain, unsigned long da,
 	return ret;
 }

-static int omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
-			    int order)
+static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
+			    size_t size)
 {
 	struct omap_iommu_domain *omap_domain = domain->priv;
 	struct omap_iommu *oiommu = omap_domain->iommu_dev;
 	struct device *dev = oiommu->dev;
-	size_t unmap_size;

-	dev_dbg(dev, "unmapping da 0x%lx order %d\n", da, order);
+	dev_dbg(dev, "unmapping da 0x%lx size %u\n", da, size);

-	unmap_size = iopgtable_clear_entry(oiommu, da);
-
-	return unmap_size ? get_order(unmap_size) : -EINVAL;
+	return iopgtable_clear_entry(oiommu, da);
 }

 static int
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 710291f..6b6ed21 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -54,9 +54,9 @@ struct iommu_ops {
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
 	int (*map)(struct iommu_domain *domain, unsigned long iova,
-		   phys_addr_t paddr, int gfp_order, int prot);
-	int (*unmap)(struct iommu_domain *domain, unsigned long iova,
-		     int gfp_order);
+		   phys_addr_t paddr, size_t size, int prot);
+	size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
+		     size_t size);
 	phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
 				    unsigned long iova);
 	int (*domain_has_cap)(struct iommu_domain *domain,
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH 2/9] ARM: SPMP8000: Add machine base files
From: Arnd Bergmann @ 2011-10-11 14:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318178172-7965-3-git-send-email-zoss@devai.org>

On Sunday 09 October 2011, Zoltan Devai wrote:

> +
> +/* Static mappings:
> + * SCU: timer needs clk support which is inited in init_early
> + * UART: needed for earlyprintk
> + */
> +static struct map_desc io_desc[] __initdata = {
> +	{
> +		.virtual	= IO_ADDRESS(SPMP8000_SCU_A_BASE),
> +		.pfn		= __phys_to_pfn(SPMP8000_SCU_A_BASE),
> +		.length		= SPMP8000_SCU_A_SIZE,
> +		.type		= MT_DEVICE,
> +	}, {
> +		.virtual	= IO_ADDRESS(SPMP8000_SCU_B_BASE),
> +		.pfn		= __phys_to_pfn(SPMP8000_SCU_B_BASE),
> +		.length		= SPMP8000_SCU_B_SIZE,
> +		.type		= MT_DEVICE,
> +	}, {
> +		.virtual	= IO_ADDRESS(SPMP8000_SCU_C_BASE),
> +		.pfn		= __phys_to_pfn(SPMP8000_SCU_C_BASE),
> +		.length		= SPMP8000_SCU_C_SIZE,
> +		.type		= MT_DEVICE,
> +	},

With Nicolas Pitre's rework of the MMIO space handling, I think it
would be nice to just use a single area that spans all of the devices
so you can do an optimized ioremap and huge TLBs. Unfortunately
that series won't make it into 3.2, but if you just set up a large
area now, it will automatically work.

> +#ifdef CONFIG_DEBUG_LL
> +	{
> +		.virtual	= IO_ADDRESS(SPMP8000_UARTC0_BASE),
> +		.pfn		= __phys_to_pfn(SPMP8000_UARTC0_BASE),
> +		.length		= SPMP8000_UARTC0_SIZE,
> +		.type		= MT_DEVICE,
> +	},
> +#endif
> +};
>

And it would be nice to move this into a separate file that handles the
early debug code, as prima2 does.

> +#ifndef __MACH_SPMP8000_DMA_H__
> +#define __MACH_SPMP8000_DMA_H__
> +
> +enum spmp8000_dma_controller {
> +	SPMP8000_APBDMA_A	= 0,
> +	SPMP8000_APBDMA_C,
> +};
> +
> +extern char *spmp8000_dma_controller_names[];
> +
> +struct spmp8000_dma_params {
> +	char				*dma_controller;
> +	dma_addr_t			dma_address;
> +	enum dma_slave_buswidth		dma_width;
> +	int				maxburst;
> +};
> +
> +/* Driver parameters */
> +#define SPMP8000_APBDMA_MAX_PERIODS	64
> +
> +static bool spmp8000_dma_filter(struct dma_chan *chan, const char *name)
> +{
> +	int ret;
> +
> +	ret = strcmp(dev_name(chan->device->dev), name);
> +
> +	if (ret)
> +		return false;
> +
> +	return true;
> +}
> +
> +#endif /* __MACH_SPMP8000_DMA_H__ */

Please separate the dma controller out for now into a separate patch.
We really need to have proper device tree bindings so we can avoid the
silly filter functions and do something better. That needs some more
discussion and any help on the interface is very much appreciated.


> diff --git a/arch/arm/mach-spmp8000/include/mach/gpio.h b/arch/arm/mach-spmp8000/include/mach/gpio.h
> new file mode 100644

> +#ifndef __MACH_SPMP8000_GPIO_H__
> +#define __MACH_SPMP8000_GPIO_H__
> +
> +#include <asm-generic/gpio.h>
> +
> +#define gpio_get_value		__gpio_get_value
> +#define gpio_set_value		__gpio_set_value
> +#define gpio_cansleep		__gpio_cansleep
> +#define gpio_to_irq		__gpio_to_irq
> +
> +#endif /* __MACH_SPMP8000_GPIO_H__ */

I think this can become an empty file now, with Russell's latest cleanup
going into 3.2.

> +/* Vitual to physical translation of statically mapped space */
> +#define IO_ADDRESS(x)		((x) | 0xF0000000)

Better make this return a 'void __iomem *', e.g. by doing

#define IO_ADDRESS(x)	(((x) & 0x0fffffff) + ((void __iomem *)0xf0000000)

> +/* Needed for the static mappings and uncompress.h */
> +#define SPMP8000_UARTC0_BASE	0x92B04000
> +#define SPMP8000_UARTC0_SIZE	SZ_4K
> +#define SPMP8000_SCU_C_BASE	0x92005000
> +#define SPMP8000_SCU_C_SIZE	SZ_4K
> +#define SPMP8000_SCU_A_BASE	0x93007000
> +#define SPMP8000_SCU_A_SIZE	SZ_4K
> +#define SPMP8000_SCU_B_BASE	0x90005000
> +#define SPMP8000_SCU_B_SIZE	SZ_4K

Do you need these all so early that you cannot get the location from the device
tree?

> +/* FIXME This should go away */
> +#define IO_SPACE_LIMIT  0
> +
> +#define __mem_pci(a)    (a)
> +#define __io(a)         __typesafe_io(a)
> +

I think you should better define __io() to NULL.
> +++ b/arch/arm/mach-spmp8000/include/mach/regs-timer.h
> @@ -0,0 +1,32 @@
> +/*
> + * SPMP8000 timer support
> + *
> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + *
> + * These timer reg definitions are used by the timer and pwm drivers
> + */
> +#ifndef __MACH_SPMP8000_REGS_TIMER_H__
> +#define __MACH_SPMP8000_REGS_TIMER_H__
> +
> +#define SPMP8000_TMRB(tnum)	(tnum * 0x20)
> +#define SPMP8000_TMRB_CTR	0x00
> +#define SPMP8000_TMRB_CTR_TE	BIT(0)
> +#define SPMP8000_TMRB_CTR_IE	BIT(1)
> +#define SPMP8000_TMRB_CTR_OE	BIT(2)
> +#define SPMP8000_TMRB_CTR_PWMON	BIT(3)
> +#define SPMP8000_TMRB_CTR_UD	BIT(4)
> +#define SPMP8000_TMRB_CTR_UDS	BIT(5)
> +#define SPMP8000_TMRB_CTR_OM	BIT(6)
> +#define SPMP8000_TMRB_CTR_ES_SH	8
> +#define SPMP8000_TMRB_CTR_M_SH	10
> +#define SPMP8000_TMRB_PSR	0x04
> +#define SPMP8000_TMRB_LDR	0x08
> +#define SPMP8000_TMRB_VLR	0x08
> +#define SPMP8000_TMRB_ISR	0x0C
> +#define SPMP8000_TMRB_CMP	0x10
> +
> +#endif /* __MACH_SPMP8000_REGS_TIMER_H__ */

No need for this header, just move the definitions into the timer driver.

> diff --git a/arch/arm/mach-spmp8000/include/mach/scu.h b/arch/arm/mach-spmp8000/include/mach/scu.h
> new file mode 100644
> index 0000000..e3a98d4
> --- /dev/null
> +++ b/arch/arm/mach-spmp8000/include/mach/scu.h
> @@ -0,0 +1,146 @@
> +/*
> + * SPMP8000 System Control Unit register definitions
> + * SCUs are a random collection of reset, clock, gpio, pinmux, etc. controllers
> + * so that these definitions are needed at several places.

> +struct scu_reg_t {
> +	void *base;
> +	void *clken;
> +};
> +
> +extern struct scu_reg_t scu_regs[];
> +
> +#define REG_SCU_BASE(x)		scu_regs[x].base
> +#define REG_SCU_CLKEN(x)	scu_regs[x].clken
> +#define REG_SCU_A_ID		0
> +#define REG_SCU_B_ID		1
> +#define REG_SCU_C_ID		2
> +#define REG_SCU_A(x)		(scu_regs[REG_SCU_A_ID].base + x)
> +#define REG_SCU_B(x)		(scu_regs[REG_SCU_B_ID].base + x)
> +#define REG_SCU_C(x)		(scu_regs[REG_SCU_C_ID].base + x)

I would prefer having  this in core.c, so the base addresses can
remain private to that file instead of exporting them to
all of the kernel.

> +#define SCU_A_PERI_RST		0x00
> +#define SCU_A_PERI_CLKEN	0x04
> +#define SCU_A_PERI_DGCLKEN	0x0C
> +
> +#define SCU_A_APLL_CFG		0x44
> +#define APLL_CFG_P		BIT(0)
> +#define APLL_CFG_S		BIT(1)
> +#define APLL_CFG_F		BIT(2)
> +#define APLL_CFG_E		BIT(3)

The BIT() definition is really just mean for kernel-internal bitops,
not so much for device registers.

My recommended style of this is

#define APLL_CFG_P		0x00000001
#define APLL_CFG_S		0x00000002
#define APLL_CFG_F		0x00000004
#define APLL_CFG_E		0x00000008

> diff --git a/arch/arm/mach-spmp8000/include/mach/system.h b/arch/arm/mach-spmp8000/include/mach/system.h
> new file mode 100644
> index 0000000..be53ff3
> --- /dev/null
> +++ b/arch/arm/mach-spmp8000/include/mach/system.h
> @@ -0,0 +1,45 @@
> +/*
> + * SPMP8000 system.h
> + *
> + * Copyright (C) 2011 Zoltan Devai <zoss@devai.org>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#ifndef __MACH_SPMP8000_SYSTEM_H__
> +#define __MACH_SPMP8000_SYSTEM_H__
> +
> +#include <linux/kernel.h>
> +#include <linux/io.h>
> +
> +#define SPMP8000_WDT_BASE	0x90001000
> +#define SPMP8000_WDT_SIZE	0x1000

These have to be removed. For device drivers, you should normally
use of_iomap to get at the registers.

> +#define SPMP8000_WDT_CTR	0x00
> +#define SPMP8000_WDT_CTR_TE	BIT(0)
> +#define SPMP8000_WDT_CTR_RE	BIT(3)
> +
> +static inline void arch_idle(void)
> +{
> +	cpu_do_idle();
> +}
> +
> +static inline void arch_reset(char mode, const char *cmd)
> +{
> +	void *base;
> +
> +	base = ioremap(SPMP8000_WDT_BASE, SPMP8000_WDT_SIZE);
> +	if (!base) {
> +		pr_err("spmp8000: Can't ioremap watchdog regs for reset. "
> +			"Halt.");
> +		while (1);
> +	}
> +
> +	/* Trigger a watchdog reset */
> +	writel(SPMP8000_WDT_CTR_RE | SPMP8000_WDT_CTR_TE,
> +			base + SPMP8000_WDT_CTR);
> +}

Using the watchdog for arch_reset is clever, but unfortunately not
too common otherwise, so you have to play tricks. I would try
locating the device and ioremapping it from core.c and then
export a function to set the register that is used both by
the arch_reset function and by the watchdog driver. The latter
can still bind to the platform_device, but it then doesn't have
to do an extra of_iomap.

	Arnd

^ permalink raw reply

* [PATCH 8/9] ARM: SPMP8000: Add support for the Letcool board
From: Zoltan Devai @ 2011-10-11 14:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201110111609.37425.arnd@arndb.de>

2011/10/11 Arnd Bergmann <arnd@arndb.de>:
> On Sunday 09 October 2011, Zoltan Devai wrote:
>> Signed-off-by: Zoltan Devai <zoss@devai.org>
>> ---
>> ?arch/arm/mach-spmp8000/board_letcool.c ? ? ? ? ? | ?154 ++++++++++++++++++++++
>> ?arch/arm/mach-spmp8000/include/mach/spmp8000fb.h | ? 32 +++++
>> ?2 files changed, 186 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-spmp8000/board_letcool.c
>> ?create mode 100644 arch/arm/mach-spmp8000/include/mach/spmp8000fb.h
>
> Hi Zoltan,
>
> We basically stopped doing board files for new platforms. Please get
> rid of this and make sure that the spmp8000-letcool.dts describes
> everything you need to get this board running. The DT_MACHINE_START
> part should just be part of the core.c file and not mention the
> board name, since its intended to apply to all boards with this
> SOC.
Hi,

The board file only contains platform data for drivers which don't handle DT.
Should I strip those off ?

Does that also mean that no fully working ARM board will be allowed into
mainline until all required drivers do DT ?

Zoltan

^ permalink raw reply

* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Mark Brown @ 2011-10-11 14:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201110111617.52061.arnd@arndb.de>

On Tue, Oct 11, 2011 at 04:17:51PM +0200, Arnd Bergmann wrote:
> On Monday 10 October 2011, Mark Brown wrote:

> > At the minute it seems to me that arch/arm is as good a place as any
> > really - currently this code is getting dumped wherever the main device
> > is.

> My feeling is that there is a general class of drivers involving
> the gpio, pinmux, pwm, led, adc and dac: these are basically all
> things you do with a single pin. Right now we have subsystems for
> some of them, adding some others and don't have anything for adc
> basides iio (which only partially fits here).

We've been round this loop repeatedly before, trying to push all this
stuff into pins really doesn't map terribly well.  For example, SoCs
will frequently have PWM controllers which are isolated IP blocks within
the device and may each have multiple mappings out of the device onto
pins.  In the case of DACs, ADCs and PWM you definitely don't have a one
to one mapping with a single pin - they can be differential inputs and
outputs, or entirely internal to a device.  Trying to push everything
into a single namespace just makes things confusing.

What we *do* have a pattern of is clk API type lookups based on a
device/name pair.

> Since there is no externally visible interface for this kind of
> adc driver, we can always fix it later, which helps a lot. How
> about putting it into drivers/adc or drivers/misc/adc for now
> and waiting for others to join it? We can then later make it a
> proper subsystem along the lines of gpio and pwm and move
> interfaces for input, hwmon and iio into the subsystem.

I'm not sure that IIO isn't the kernel subsystem we're looking for here
- as I keep saying when this comes up it's just representing bare DACs
and ADCs pretty directly which looks like a generic subsystem to me.

^ permalink raw reply

* TX28 drivers - Please help
From: Peter Rusko @ 2011-10-11 14:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

We'd like to use the Ka-Ro TX28 module in a device with our company.
As I could see, not all the features of it's processor are supported. I 
have already added some of them using the Freescale version just to see 
that things are working, but the code became really messy. So I've 
decided to restart, and this time I'd like to commit the changes to the 
mainline kernel.

We have already designed a company board supporting the TX28 module. The 
first problem I don't know how to do well is to separate the module and 
the baseboard. I think that the module-specific things and setup should 
be in a file like mach-tx28.c (as it already is), and the board specific 
things should be in a separate file (mach-karo_stk.c ?). I'm quite 
unsure about the naming and where I should split the code.

After that works, I'd like to include support for SPI and the mxs 
touchscreen driver (which also needs the LRADC support).

How should I start? I've already downloaded the pengutronix/imx 
repository to work with.
-- 
Rusk? P?ter
fejleszt?m?rn?k

Prolan Zrt. / Prolan Co.
Hungary 2011 Budakal?sz, Szentendrei ?t 1-3.
Tel./Phone: +36 20 954 3118
Fax: +36 26 540 420
E-mail: rusko.peter at prolan.hu
Web: www.prolan.hu
Timezone:CET

^ permalink raw reply

* [PATCH 3/4] ARM: at91/dma: remove platform data from DMA controller
From: Vinod Koul @ 2011-10-11 14:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2b6ff9c8a28c955849f13b90c5ef258ceea19eaa.1318264339.git.nicolas.ferre@atmel.com>

On Mon, 2011-10-10 at 18:37 +0200, Nicolas Ferre wrote:
> DMA controller can deduce its configuration data from
> the platform. Remove the platform data and match device
> types with the compatible ones.
This looks like remove, you should fix the changelog of patch 1 then.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
>  arch/arm/mach-at91/at91sam9g45_devices.c |    9 +--------
>  arch/arm/mach-at91/at91sam9rl_devices.c  |    8 +-------
>  2 files changed, 2 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
> index 600bffb..c9b897f 100644
> --- a/arch/arm/mach-at91/at91sam9g45_devices.c
> +++ b/arch/arm/mach-at91/at91sam9g45_devices.c
> @@ -38,10 +38,6 @@
>  #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
>  static u64 hdmac_dmamask = DMA_BIT_MASK(32);
>  
> -static struct at_dma_platform_data atdma_pdata = {
> -	.nr_channels	= 8,
> -};
> -
>  static struct resource hdmac_resources[] = {
>  	[0] = {
>  		.start	= AT91_BASE_SYS + AT91_DMA,
> @@ -56,12 +52,11 @@ static struct resource hdmac_resources[] = {
>  };
>  
>  static struct platform_device at_hdmac_device = {
> -	.name		= "at_hdmac",
> +	.name		= "at91sam9g45_dma",
>  	.id		= -1,
>  	.dev		= {
>  				.dma_mask		= &hdmac_dmamask,
>  				.coherent_dma_mask	= DMA_BIT_MASK(32),
> -				.platform_data		= &atdma_pdata,
>  	},
>  	.resource	= hdmac_resources,
>  	.num_resources	= ARRAY_SIZE(hdmac_resources),
> @@ -69,8 +64,6 @@ static struct platform_device at_hdmac_device = {
>  
>  void __init at91_add_device_hdmac(void)
>  {
> -	dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
> -	dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
>  	platform_device_register(&at_hdmac_device);
>  }
>  #else
> diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
> index aacb19d..81954f7 100644
> --- a/arch/arm/mach-at91/at91sam9rl_devices.c
> +++ b/arch/arm/mach-at91/at91sam9rl_devices.c
> @@ -33,10 +33,6 @@
>  #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
>  static u64 hdmac_dmamask = DMA_BIT_MASK(32);
>  
> -static struct at_dma_platform_data atdma_pdata = {
> -	.nr_channels	= 2,
> -};
> -
>  static struct resource hdmac_resources[] = {
>  	[0] = {
>  		.start	= AT91_BASE_SYS + AT91_DMA,
> @@ -51,12 +47,11 @@ static struct resource hdmac_resources[] = {
>  };
>  
>  static struct platform_device at_hdmac_device = {
> -	.name		= "at_hdmac",
> +	.name		= "at91sam9rl_dma",
>  	.id		= -1,
>  	.dev		= {
>  				.dma_mask		= &hdmac_dmamask,
>  				.coherent_dma_mask	= DMA_BIT_MASK(32),
> -				.platform_data		= &atdma_pdata,
>  	},
>  	.resource	= hdmac_resources,
>  	.num_resources	= ARRAY_SIZE(hdmac_resources),
> @@ -64,7 +59,6 @@ static struct platform_device at_hdmac_device = {
>  
>  void __init at91_add_device_hdmac(void)
>  {
> -	dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
>  	platform_device_register(&at_hdmac_device);
>  }
>  #else


-- 
~Vinod

^ permalink raw reply

* [PATCH 4/9] ARM: SPMP8000: Add ADC driver
From: Arnd Bergmann @ 2011-10-11 14:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20111010114407.GD3607@opensource.wolfsonmicro.com>

On Monday 10 October 2011, Mark Brown wrote:
> On Mon, Oct 10, 2011 at 01:42:30PM +0200, Zoltan Devai wrote:
> 
> > Where should the adc driver go in this case ?
> 
> At the minute it seems to me that arch/arm is as good a place as any
> really - currently this code is getting dumped wherever the main device
> is.

My feeling is that there is a general class of drivers involving
the gpio, pinmux, pwm, led, adc and dac: these are basically all
things you do with a single pin. Right now we have subsystems for
some of them, adding some others and don't have anything for adc
basides iio (which only partially fits here).

Since there is no externally visible interface for this kind of
adc driver, we can always fix it later, which helps a lot. How
about putting it into drivers/adc or drivers/misc/adc for now
and waiting for others to join it? We can then later make it a
proper subsystem along the lines of gpio and pwm and move
interfaces for input, hwmon and iio into the subsystem.

	Arnd

^ permalink raw reply

* [PATCH 1/4] dmaengine: at_hdmac: platform data move to use .id_table
From: Vinod Koul @ 2011-10-11 14:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9723283e7097730f568bf7c2f3a93ae42c6bc5ca.1318264339.git.nicolas.ferre@atmel.com>

On Mon, 2011-10-10 at 18:37 +0200, Nicolas Ferre wrote:
> We remove platform data from DMA controller and move
> to the use of .id_table to distinguish between compatible
> types. The two implementations allow to determine the
> number of channels and the capabilities of the controller.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
>  drivers/dma/at_hdmac.c      |   48 ++++++++++++++++++++++++++++++++++---------
>  drivers/dma/at_hdmac_regs.h |    8 +++++++
>  2 files changed, 46 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
> index fcfa0a8..fef57bc 100644
> --- a/drivers/dma/at_hdmac.c
> +++ b/drivers/dma/at_hdmac.c
> @@ -1175,6 +1175,18 @@ static void atc_free_chan_resources(struct dma_chan *chan)
>  
>  /*--  Module Management  -----------------------------------------------*/
>  
> +static struct platform_device_id atdma_devtypes[] = {
> +	{
> +		.name = "at91sam9rl_dma",
> +		.driver_data = ATDMA_DEVTYPE_SAM9RL,
> +	}, {
> +		.name = "at91sam9g45_dma",
> +		.driver_data = ATDMA_DEVTYPE_SAM9G45,
> +	}, {
> +		/* sentinel */
> +	}
> +};
> +
>  /**
>   * at_dma_off - disable DMA controller
>   * @atdma: the Atmel HDAMC device
> @@ -1193,18 +1205,32 @@ static void at_dma_off(struct at_dma *atdma)
>  
>  static int __init at_dma_probe(struct platform_device *pdev)
>  {
> -	struct at_dma_platform_data *pdata;
>  	struct resource		*io;
>  	struct at_dma		*atdma;
>  	size_t			size;
>  	int			irq;
>  	int			err;
>  	int			i;
> +	u32                     nr_channels;
> +	dma_cap_mask_t          cap_mask = {};
> +	enum atdma_devtype	atdmatype;
> +
> +	dma_cap_set(DMA_MEMCPY, cap_mask);
> +
> +	/* get DMA parameters from controller type */
> +	atdmatype = platform_get_device_id(pdev)->driver_data;
>  
> -	/* get DMA Controller parameters from platform */
> -	pdata = pdev->dev.platform_data;
> -	if (!pdata || pdata->nr_channels > AT_DMA_MAX_NR_CHANNELS)
> +	switch (atdmatype) {
> +	case ATDMA_DEVTYPE_SAM9RL:
> +		nr_channels = 2;
> +		break;
> +	case ATDMA_DEVTYPE_SAM9G45:
> +		nr_channels = 8;
> +		dma_cap_set(DMA_SLAVE, cap_mask);
> +		break;
> +	default:
>  		return -EINVAL;
> +	}
>  
>  	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (!io)
> @@ -1215,14 +1241,15 @@ static int __init at_dma_probe(struct platform_device *pdev)
>  		return irq;
>  
>  	size = sizeof(struct at_dma);
> -	size += pdata->nr_channels * sizeof(struct at_dma_chan);
> +	size += nr_channels * sizeof(struct at_dma_chan);
>  	atdma = kzalloc(size, GFP_KERNEL);
>  	if (!atdma)
>  		return -ENOMEM;
>  
> -	/* discover transaction capabilites from the platform data */
> -	atdma->dma_common.cap_mask = pdata->cap_mask;
> -	atdma->all_chan_mask = (1 << pdata->nr_channels) - 1;
> +	/* discover transaction capabilites */
capabilities
> +	atdma->dma_common.cap_mask = cap_mask;
> +	atdma->all_chan_mask = (1 << nr_channels) - 1;
> +	atdma->devtype = atdmatype;
>  
>  	size = resource_size(io);
>  	if (!request_mem_region(io->start, size, pdev->dev.driver->name)) {
> @@ -1268,7 +1295,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
>  
>  	/* initialize channels related values */
>  	INIT_LIST_HEAD(&atdma->dma_common.channels);
> -	for (i = 0; i < pdata->nr_channels; i++) {
> +	for (i = 0; i < nr_channels; i++) {
>  		struct at_dma_chan	*atchan = &atdma->chan[i];
>  
>  		atchan->chan_common.device = &atdma->dma_common;
> @@ -1313,7 +1340,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
>  	dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
>  	  dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
>  	  dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)  ? "slave " : "",
> -	  pdata->nr_channels);
> +	  nr_channels);
indent?
>  
>  	dma_async_device_register(&atdma->dma_common);
>  
> @@ -1495,6 +1522,7 @@ static const struct dev_pm_ops at_dma_dev_pm_ops = {
>  static struct platform_driver at_dma_driver = {
>  	.remove		= __exit_p(at_dma_remove),
>  	.shutdown	= at_dma_shutdown,
> +	.id_table	= atdma_devtypes,
>  	.driver = {
>  		.name	= "at_hdmac",
>  		.pm	= &at_dma_dev_pm_ops,
> diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
> index aa4c9ae..d7d6737 100644
> --- a/drivers/dma/at_hdmac_regs.h
> +++ b/drivers/dma/at_hdmac_regs.h
> @@ -248,9 +248,16 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
>  
>  /*--  Controller  ------------------------------------------------------*/
>  
> +enum atdma_devtype {
> +	ATDMA_DEVTYPE_UNDEFINED = 0,
> +	ATDMA_DEVTYPE_SAM9RL,	/* compatible with SAM9RL DMA controller */
> +	ATDMA_DEVTYPE_SAM9G45,	/* compatible with SAM9G45 DMA controller */
> +};
> +
>  /**
>   * struct at_dma - internal representation of an Atmel HDMA Controller
>   * @chan_common: common dmaengine dma_device object members
> + * @atdma_devtype: identifier of DMA controller compatibility
>   * @ch_regs: memory mapped register base
>   * @clk: dma controller clock
>   * @save_imr: interrupt mask register that is saved on suspend/resume cycle
> @@ -260,6 +267,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
>   */
>  struct at_dma {
>  	struct dma_device	dma_common;
> +	enum atdma_devtype	devtype;
>  	void __iomem		*regs;
>  	struct clk		*clk;
>  	u32			save_imr;
Little confused at this, where is the remove of existing platfrom data
per the changelog?

-- 
~Vinod

^ permalink raw reply

* [PATCH 2/2] ARM: dts: Add intial dts file for Exynos4210 SoC, SMDKV310 and Origen board
From: Thomas Abraham @ 2011-10-11 14:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318342396-26178-1-git-send-email-thomas.abraham@linaro.org>

Add initial dts file for Exynos4210 SoC. This dts file describes the SoC
specific devices and properties. Along with this, add dts file for Samsung's
SMDKV310 board and Insignal's Origen board which uses the Exynos4210 dts file
and extends it to describe the board specific properties.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/boot/dts/exynos4210-origen.dts   |  137 ++++++++++
 arch/arm/boot/dts/exynos4210-smdkv310.dts |  182 +++++++++++++
 arch/arm/boot/dts/exynos4210.dtsi         |  403 +++++++++++++++++++++++++++++
 3 files changed, 722 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos4210-origen.dts
 create mode 100644 arch/arm/boot/dts/exynos4210-smdkv310.dts
 create mode 100644 arch/arm/boot/dts/exynos4210.dtsi

diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
new file mode 100644
index 0000000..b8c4763
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -0,0 +1,137 @@
+/*
+ * Samsung's Exynos4210 based Origen board device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ *		www.linaro.org
+ *
+ * Device tree source file for Insignal's Origen board which is based on
+ * Samsung's Exynos4210 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos4210.dtsi"
+
+/ {
+	model = "Insignal Origen evaluation board based on Exynos4210";
+	compatible = "insignal,origen", "samsung,exynos4210";
+
+	memory {
+		reg = <0x40000000 0x40000000>;
+	};
+
+	chosen {
+		bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
+	};
+
+	sdhci at 12530000 {
+		samsung,sdhci-bus-width = <4>;
+		linux,mmc_cap_4_bit_data;
+		samsung,sdhci-cd-internal;
+		gpio-cd = <&gpk2 2 2 3 3>;
+		gpios = <&gpk2 0 2 0 3>,
+			<&gpk2 1 2 0 3>,
+			<&gpk2 3 2 3 3>,
+			<&gpk2 4 2 3 3>,
+			<&gpk2 5 2 3 3>,
+			<&gpk2 6 2 3 3>;
+	};
+
+	sdhci at 12510000 {
+		samsung,sdhci-bus-width = <4>;
+		linux,mmc_cap_4_bit_data;
+		samsung,sdhci-cd-internal;
+		gpio-cd = <&gpk0 2 2 3 3>;
+		gpios = <&gpk0 0 2 0 3>,
+			<&gpk0 1 2 0 3>,
+			<&gpk0 3 2 3 3>,
+			<&gpk0 4 2 3 3>,
+			<&gpk0 5 2 3 3>,
+			<&gpk0 6 2 3 3>;
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		up {
+			label = "Up";
+			gpios = <&gpx2 0 0 0 2>;
+			linux,code = <103>;
+		};
+
+		down {
+			label = "Down";
+			gpios = <&gpx2 1 0 0 2>;
+			linux,code = <108>;
+		};
+
+		back {
+			label = "Back";
+			gpios = <&gpx1 7 0 0 2>;
+			linux,code = <158>;
+		};
+
+		home {
+			label = "Home";
+			gpios = <&gpx1 6 0 0 2>;
+			linux,code = <102>;
+		};
+
+		menu {
+			label = "Menu";
+			gpios = <&gpx1 5 0 0 2>;
+			linux,code = <139>;
+		};
+	};
+
+	keypad at 100A0000 {
+		status = "disabled";
+	};
+
+	sdhci at 12520000 {
+		status = "disabled";
+	};
+
+	sdhci at 12540000 {
+		status = "disabled";
+	};
+
+	i2c at 13860000 {
+		status = "disabled";
+	};
+
+	i2c at 13870000 {
+		status = "disabled";
+	};
+
+	i2c at 13880000 {
+		status = "disabled";
+	};
+
+	i2c at 13890000 {
+		status = "disabled";
+	};
+
+	i2c at 138A0000 {
+		status = "disabled";
+	};
+
+	i2c at 138B0000 {
+		status = "disabled";
+	};
+
+	i2c at 138C0000 {
+		status = "disabled";
+	};
+
+	i2c at 138D0000 {
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
new file mode 100644
index 0000000..27afc8e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -0,0 +1,182 @@
+/*
+ * Samsung's Exynos4210 based SMDKV310 board device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ *		www.linaro.org
+ *
+ * Device tree source file for Samsung's SMDKV310 board which is based on
+ * Samsung's Exynos4210 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos4210.dtsi"
+
+/ {
+	model = "Samsung smdkv310 evaluation board based on Exynos4210";
+	compatible = "samsung,smdkv310", "samsung,exynos4210";
+
+	memory {
+		reg = <0x40000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+	};
+
+	sdhci at 12530000 {
+		samsung,sdhci-bus-width = <4>;
+		linux,mmc_cap_4_bit_data;
+		samsung,sdhci-cd-internal;
+		gpio-cd = <&gpk2 2 2 3 3>;
+		gpios = <&gpk2 0 2 0 3>,
+			<&gpk2 1 2 0 3>,
+			<&gpk2 3 2 3 3>,
+			<&gpk2 4 2 3 3>,
+			<&gpk2 5 2 3 3>,
+			<&gpk2 6 2 3 3>;
+	};
+
+	keypad at 100A0000 {
+		samsung,keypad-num-rows = <2>;
+		samsung,keypad-num-columns = <8>;
+		linux,keypad-no-autorepeat;
+		linux,keypad-wakeup;
+
+		row-gpios = <&gpx2 0 3 3 0>,
+			    <&gpx2 1 3 3 0>;
+
+		col-gpios = <&gpx1 0 3 0 0>,
+			    <&gpx1 1 3 0 0>,
+			    <&gpx1 2 3 0 0>,
+			    <&gpx1 3 3 0 0>,
+			    <&gpx1 4 3 0 0>,
+			    <&gpx1 5 3 0 0>,
+			    <&gpx1 6 3 0 0>,
+			    <&gpx1 7 3 0 0>;
+
+		key_1 {
+			keypad,row = <0>;
+			keypad,column = <3>;
+			linux,code = <2>;
+		};
+
+		key_2 {
+			keypad,row = <0>;
+			keypad,column = <4>;
+			linux,code = <3>;
+		};
+
+		key_3 {
+			keypad,row = <0>;
+			keypad,column = <5>;
+			linux,code = <4>;
+		};
+
+		key_4 {
+			keypad,row = <0>;
+			keypad,column = <6>;
+			linux,code = <5>;
+		};
+
+		key_5 {
+			keypad,row = <0>;
+			keypad,column = <7>;
+			linux,code = <6>;
+		};
+
+		key_a {
+			keypad,row = <1>;
+			keypad,column = <3>;
+			linux,code = <30>;
+		};
+
+		key_b {
+			keypad,row = <1>;
+			keypad,column = <4>;
+			linux,code = <48>;
+		};
+
+		key_c {
+			keypad,row = <1>;
+			keypad,column = <5>;
+			linux,code = <46>;
+		};
+
+		key_d {
+			keypad,row = <1>;
+			keypad,column = <6>;
+			linux,code = <32>;
+		};
+
+		key_e {
+			keypad,row = <1>;
+			keypad,column = <7>;
+			linux,code = <18>;
+		};
+	};
+
+	i2c at 13860000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <20000>;
+		gpios = <&gpd1 0 2 3 0>,
+			<&gpd1 1 2 3 0>;
+
+		eeprom at 50 {
+			compatible = "samsung,24ad0xd1";
+			reg = <0x50>;
+		};
+
+		eeprom at 52 {
+			compatible = "samsung,24ad0xd1";
+			reg = <0x52>;
+		};
+	};
+
+	sdhci at 12510000 {
+		status = "disabled";
+	};
+
+	sdhci at 12520000 {
+		status = "disabled";
+	};
+
+	sdhci at 12540000 {
+		status = "disabled";
+	};
+
+	i2c at 13870000 {
+		status = "disabled";
+	};
+
+	i2c at 13880000 {
+		status = "disabled";
+	};
+
+	i2c at 13890000 {
+		status = "disabled";
+	};
+
+	i2c at 138A0000 {
+		status = "disabled";
+	};
+
+	i2c at 138B0000 {
+		status = "disabled";
+	};
+
+	i2c at 138C0000 {
+		status = "disabled";
+	};
+
+	i2c at 138D0000 {
+		status = "disabled";
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
new file mode 100644
index 0000000..7598a15
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -0,0 +1,403 @@
+/*
+ * Samsung's Exynos4210 SoC device tree source
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ *		www.linaro.org
+ *
+ * Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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/ "skeleton.dtsi"
+
+/ {
+	compatible = "samsung,exynos4210";
+	interrupt-parent = <&gic>;
+
+	gic:interrupt-controller at 10490000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x10490000 0x1000>, <0x10480000 0x100>;
+	};
+
+	combiner: interrupt-controller at 10440000 {
+		compatible = "samsung,exynos4-combiner";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0x10440000 0x200>;
+	};
+
+	watchdog at 10060000 {
+		compatible = "samsung,s3c2410-wdt";
+		reg = <0x10060000 0x100>;
+		interrupts = <0 43 0>;
+	};
+
+	rtc at 10070000 {
+		compatible = "samsung,s3c6410-rtc";
+		reg = <0x10070000 0x100>;
+		interrupts = <0 44 0>, <0 45 0>;
+	};
+
+	keypad at 100A0000 {
+		compatible = "samsung,s5pv210-keypad";
+		reg = <0x100A0000 0x100>;
+		interrupts = <0 109 0>;
+	};
+
+	sdhci at 12510000 {
+		compatible = "samsung,exynos4210-sdhci";
+		reg = <0x12510000 0x100>;
+		interrupts = <0 73 0>;
+	};
+
+	sdhci at 12520000 {
+		compatible = "samsung,exynos4210-sdhci";
+		reg = <0x12520000 0x100>;
+		interrupts = <0 74 0>;
+	};
+
+	sdhci at 12530000 {
+		compatible = "samsung,exynos4210-sdhci";
+		reg = <0x12530000 0x100>;
+		interrupts = <0 75 0>;
+	};
+
+	sdhci at 12540000 {
+		compatible = "samsung,exynos4210-sdhci";
+		reg = <0x12540000 0x100>;
+		interrupts = <0 76 0>;
+	};
+
+	serial at 13800000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x13800000 0x100>;
+		interrupts = <0 52 0>;
+	};
+
+	serial at 13810000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x13810000 0x100>;
+		interrupts = <0 53 0>;
+	};
+
+	serial at 13820000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x13820000 0x100>;
+		interrupts = <0 54 0>;
+	};
+
+	serial at 13830000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x13830000 0x100>;
+		interrupts = <0 55 0>;
+	};
+
+	i2c at 13860000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x13860000 0x100>;
+		interrupts = <0 58 0>;
+	};
+
+	i2c at 13870000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x13870000 0x100>;
+		interrupts = <0 59 0>;
+	};
+
+	i2c at 13880000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x13880000 0x100>;
+		interrupts = <0 60 0>;
+	};
+
+	i2c at 13890000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x13890000 0x100>;
+		interrupts = <0 61 0>;
+	};
+
+	i2c at 138A0000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x138A0000 0x100>;
+		interrupts = <0 62 0>;
+	};
+
+	i2c at 138B0000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x138B0000 0x100>;
+		interrupts = <0 63 0>;
+	};
+
+	i2c at 138C0000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x138C0000 0x100>;
+		interrupts = <0 64 0>;
+	};
+
+	i2c at 138D0000 {
+		compatible = "samsung,s3c2440-i2c";
+		reg = <0x138D0000 0x100>;
+		interrupts = <0 65 0>;
+	};
+
+	amba {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "arm,amba-bus";
+		interrupt-parent = <&gic>;
+		ranges;
+
+		pdma0: pdma at 12680000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x12680000 0x1000>;
+			interrupts = <0 35 0>;
+		};
+
+		pdma1: pdma at 12690000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x12690000 0x1000>;
+			interrupts = <0 36 0>;
+		};
+	};
+
+	gpio-controllers {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		gpio-controller;
+
+		gpa0: gpio-controller at 11400000 {
+			compatible = "samsung,exynos4-gpio-gpa0", "samsung,exynos4-gpio";
+			reg = <0x11400000 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpa1: gpio-controller at 11400020 {
+			compatible = "samsung,exynos4-gpio-gpa1", "samsung,exynos4-gpio";
+			reg = <0x11400020 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpb: gpio-controller at 11400040 {
+			compatible = "samsung,exynos4-gpio-gpb", "samsung,exynos4-gpio";
+			reg = <0x11400040 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpc0: gpio-controller at 11400060 {
+			compatible = "samsung,exynos4-gpio-gpc0", "samsung,exynos4-gpio";
+			reg = <0x11400060 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpc1: gpio-controller at 11400080 {
+			compatible = "samsung,exynos4-gpio-gpc1", "samsung,exynos4-gpio";
+			reg = <0x11400080 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpd0: gpio-controller at 114000A0 {
+			compatible = "samsung,exynos4-gpio-gpd0", "samsung,exynos4-gpio";
+			reg = <0x114000A0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpd1: gpio-controller at 114000C0 {
+			compatible = "samsung,exynos4-gpio-gpd1", "samsung,exynos4-gpio";
+			reg = <0x114000C0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpe0: gpio-controller at 114000E0 {
+			compatible = "samsung,exynos4-gpio-gpe0", "samsung,exynos4-gpio";
+			reg = <0x114000E0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpe1: gpio-controller at 11400100 {
+			compatible = "samsung,exynos4-gpio-gpe1", "samsung,exynos4-gpio";
+			reg = <0x11400100 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpe2: gpio-controller at 11400120 {
+			compatible = "samsung,exynos4-gpio-gpe2", "samsung,exynos4-gpio";
+			reg = <0x11400120 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpe3: gpio-controller at 11400140 {
+			compatible = "samsung,exynos4-gpio-gpe3", "samsung,exynos4-gpio";
+			reg = <0x11400140 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpe4: gpio-controller at 11400160 {
+			compatible = "samsung,exynos4-gpio-gpe4", "samsung,exynos4-gpio";
+			reg = <0x11400160 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpf0: gpio-controller at 11400180 {
+			compatible = "samsung,exynos4-gpio-gpf0", "samsung,exynos4-gpio";
+			reg = <0x11400180 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpf1: gpio-controller at 114001A0 {
+			compatible = "samsung,exynos4-gpio-gpf1", "samsung,exynos4-gpio";
+			reg = <0x114001A0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpf2: gpio-controller at 114001C0 {
+			compatible = "samsung,exynos4-gpio-gpf2", "samsung,exynos4-gpio";
+			reg = <0x114001C0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpf3: gpio-controller at 114001E0 {
+			compatible = "samsung,exynos4-gpio-gpf3", "samsung,exynos4-gpio";
+			reg = <0x114001E0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpj0: gpio-controller at 11000000 {
+			compatible = "samsung,exynos4-gpio-gpj0", "samsung,exynos4-gpio";
+			reg = <0x11000000 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpj1: gpio-controller at 11000020 {
+			compatible = "samsung,exynos4-gpio-gpj1", "samsung,exynos4-gpio";
+			reg = <0x11000020 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpk0: gpio-controller at 11000040 {
+			compatible = "samsung,exynos4-gpio-gpk0", "samsung,exynos4-gpio";
+			reg = <0x11000040 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpk1: gpio-controller at 11000060 {
+			compatible = "samsung,exynos4-gpio-gpk1", "samsung,exynos4-gpio";
+			reg = <0x11000060 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpk2: gpio-controller at 11000080 {
+			compatible = "samsung,exynos4-gpio-gpk2", "samsung,exynos4-gpio";
+			reg = <0x11000080 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpk3: gpio-controller at 110000A0 {
+			compatible = "samsung,exynos4-gpio-gpk3", "samsung,exynos4-gpio";
+			reg = <0x110000A0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpl0: gpio-controller at 110000C0 {
+			compatible = "samsung,exynos4-gpio-gpl0", "samsung,exynos4-gpio";
+			reg = <0x110000C0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpl1: gpio-controller at 110000E0 {
+			compatible = "samsung,exynos4-gpio-gpl1", "samsung,exynos4-gpio";
+			reg = <0x110000E0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpl2: gpio-controller at 11000100 {
+			compatible = "samsung,exynos4-gpio-gpl2", "samsung,exynos4-gpio";
+			reg = <0x11000100 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy0: gpio-controller at 11000120 {
+			compatible = "samsung,exynos4-gpio-gpy0", "samsung,exynos4-gpio";
+			reg = <0x11000120 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy1: gpio-controller at 11000140 {
+			compatible = "samsung,exynos4-gpio-gpy1", "samsung,exynos4-gpio";
+			reg = <0x11000140 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy2: gpio-controller at 11000160 {
+			compatible = "samsung,exynos4-gpio-gpy2", "samsung,exynos4-gpio";
+			reg = <0x11000160 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy3: gpio-controller at 11000180 {
+			compatible = "samsung,exynos4-gpio-gpy3", "samsung,exynos4-gpio";
+			reg = <0x11000180 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy4: gpio-controller at 110001A0 {
+			compatible = "samsung,exynos4-gpio-gpy4", "samsung,exynos4-gpio";
+			reg = <0x110001A0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy5: gpio-controller at 110001C0 {
+			compatible = "samsung,exynos4-gpio-gpy5", "samsung,exynos4-gpio";
+			reg = <0x110001C0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpy6: gpio-controller at 110001E0 {
+			compatible = "samsung,exynos4-gpio-gpy6", "samsung,exynos4-gpio";
+			reg = <0x110001E0 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpx0: gpio-controller at 11000C00 {
+			compatible = "samsung,exynos4-gpio-gpx0", "samsung,exynos4-gpio";
+			reg = <0x11000C00 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpx1: gpio-controller at 11000C20 {
+			compatible = "samsung,exynos4-gpio-gpx1", "samsung,exynos4-gpio";
+			reg = <0x11000C20 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpx2: gpio-controller at 11000C40 {
+			compatible = "samsung,exynos4-gpio-gpx2", "samsung,exynos4-gpio";
+			reg = <0x11000C40 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpx3: gpio-controller at 11000C60 {
+			compatible = "samsung,exynos4-gpio-gpx3", "samsung,exynos4-gpio";
+			reg = <0x11000C60 0x20>;
+			#gpio-cells = <4>;
+		};
+
+		gpz: gpio-controller at 03860000 {
+			compatible = "samsung,exynos4-gpio-gpz", "samsung,exynos4-gpio";
+			reg = <0x03860000 0x20>;
+			#gpio-cells = <4>;
+		};
+	};
+};
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 1/2] ARM: Samsung: Add Exynos4 device tree enabled board file
From: Thomas Abraham @ 2011-10-11 14:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318342396-26178-1-git-send-email-thomas.abraham@linaro.org>

Add a new Exynos4 compatible device tree enabled board file. Boards based on
the Exynos4 family of SoC's can use this as the machine/board file. When using
this machine fike, a corresponding device tree blob which describes the board's
properties should be supplied at boot time to the kernel.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 .../devicetree/bindings/arm/insignal-boards.txt    |    8 ++
 .../devicetree/bindings/arm/samsung-boards.txt     |    8 ++
 arch/arm/mach-exynos4/Kconfig                      |   14 +++
 arch/arm/mach-exynos4/Makefile                     |    2 +
 arch/arm/mach-exynos4/mach-exynos4-dt.c            |   85 ++++++++++++++++++++
 5 files changed, 117 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/insignal-boards.txt
 create mode 100644 Documentation/devicetree/bindings/arm/samsung-boards.txt
 create mode 100644 arch/arm/mach-exynos4/mach-exynos4-dt.c

diff --git a/Documentation/devicetree/bindings/arm/insignal-boards.txt b/Documentation/devicetree/bindings/arm/insignal-boards.txt
new file mode 100644
index 0000000..524c3dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/insignal-boards.txt
@@ -0,0 +1,8 @@
+* Insignal's Exynos4210 based Origen evaluation board
+
+Origen low-cost evaluation board is based on Samsung's Exynos4210 SoC.
+
+Required root node properties:
+    - compatible = should be one or more of the following.
+        (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
+        (b) "samsung,exynos4210"  - for boards based on Exynos4210 SoC.
diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt
new file mode 100644
index 0000000..0bf68be
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt
@@ -0,0 +1,8 @@
+* Samsung's Exynos4210 based SMDKV310 evaluation board
+
+SMDKV310 evaluation board is based on Samsung's Exynos4210 SoC.
+
+Required root node properties:
+    - compatible = should be one or more of the following.
+        (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
+        (b) "samsung,exynos4210"  - for boards based on Exynos4210 SoC.
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 0c5888a..39dc135 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -304,6 +304,20 @@ config MACH_SMDK4412
 	help
 	  Machine support for Samsung SMDK4412
 
+comment "Flattened Device Tree based board for Exynos4 based SoC"
+
+config MACH_EXYNOS4_DT
+	bool "Samsung Exynos4 Machine using device tree"
+	select CPU_EXYNOS4210
+	select USE_OF
+	select ARM_AMBA
+	select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
+	help
+	  Machine support for Samsung Exynos4 machine with device tree enabled.
+	  Select this if a fdt blob is available for the Exynos4 SoC based board.
+	  Note: This is under development and not all peripherals can be supported
+	  with this machine file.
+
 endmenu
 
 comment "Configuration for HSMMC bus width"
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 8066538..4e302cb 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -37,6 +37,8 @@ obj-$(CONFIG_MACH_ORIGEN)		+= mach-origen.o
 obj-$(CONFIG_MACH_SMDK4212)		+= mach-smdk4x12.o
 obj-$(CONFIG_MACH_SMDK4412)		+= mach-smdk4x12.o
 
+obj-$(CONFIG_MACH_EXYNOS4_DT)		+= mach-exynos4-dt.o
+
 # device support
 
 obj-y					+= dev-audio.o
diff --git a/arch/arm/mach-exynos4/mach-exynos4-dt.c b/arch/arm/mach-exynos4/mach-exynos4-dt.c
new file mode 100644
index 0000000..85fa027
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-exynos4-dt.c
@@ -0,0 +1,85 @@
+/*
+ * Samsung's Exynos4210 flattened device tree enabled machine
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ *		www.linaro.org
+ *
+ * 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/of_platform.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+
+/*
+ * The following lookup table is used to override device names when devices
+ * are registered from device tree. This is temporarily added to enable
+ * device tree support addition for the Exynos4 architecture.
+ *
+ * For drivers that require platform data to be provided from the machine
+ * file, a platform data pointer can also be supplied along with the
+ * devices names. Usually, the platform data elements that cannot be parsed
+ * from the device tree by the drivers (example: function pointers) are
+ * supplied. But it should be noted that this is a temporary mechanism and
+ * at some point, the drivers should be capable of parsing all the platform
+ * data from the device tree.
+ */
+static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
+	OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0,
+				"exynos4210-uart.0", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1,
+				"exynos4210-uart.1", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2,
+				"exynos4210-uart.2", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3,
+				"exynos4210-uart.3", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
+				"exynos4-sdhci.0", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
+				"exynos4-sdhci.1", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
+				"exynos4-sdhci.2", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
+				"exynos4-sdhci.3", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
+				"s3c2440-i2c.0", NULL),
+	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
+	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
+	{},
+};
+
+static void __init exynos4210_dt_map_io(void)
+{
+	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+	s3c24xx_init_clocks(24000000);
+}
+
+static void __init exynos4210_dt_machine_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table,
+				exynos4210_auxdata_lookup, NULL);
+}
+
+static char const *exynos4210_dt_compat[] __initdata = {
+	"samsung,exynos4210",
+	NULL
+};
+
+DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
+	/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
+	.init_irq	= exynos4_init_irq,
+	.map_io		= exynos4210_dt_map_io,
+	.init_machine	= exynos4210_dt_machine_init,
+	.timer		= &exynos4_timer,
+	.dt_compat	= exynos4210_dt_compat,
+MACHINE_END
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 0/2] ARM: Samsung: Add basic device tree support for Exynos4 boards
From: Thomas Abraham @ 2011-10-11 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds a new basic device tree enabled machine/board file which is
based on the Samsung's Exynos4 family of SoC's. Also included in this patchset is the
dts file for Exynos4210 SoC, Samsung's SMDKV310 board and Insignal's Origen board.

The Exynos4210 dts file includes support for IRQ, GPIO, WDT, RTC, UART, SDHCI, Keypad,
DMA and I2C controllers. As device tree coverage for Exynos4210 increases, additional
device nodes to represent the controllers should be added.

The device tree enabled machine file enables boot on two boards based on the
Exynos4210 SoC. This provides a starting point to add additional device tree support
on these boards, migrate other existing Exynos4 based boards to use device tree
and enable device tree based boot on new upcoming boards.

This patchset has been tested on the following tree:
  https://github.com/kgene/linux-samsung.git   branch: for-next

Thomas Abraham (2):
  ARM: Samsung: Add Exynos4 device tree enabled board file
  ARM: dts: Add intial dts file for Exynos4210 SoC, SMDKV310 and Origen board

 .../devicetree/bindings/arm/insignal-boards.txt    |    8 +
 .../devicetree/bindings/arm/samsung-boards.txt     |    8 +
 arch/arm/boot/dts/exynos4210-origen.dts            |  137 +++++++
 arch/arm/boot/dts/exynos4210-smdkv310.dts          |  182 +++++++++
 arch/arm/boot/dts/exynos4210.dtsi                  |  403 ++++++++++++++++++++
 arch/arm/mach-exynos4/Kconfig                      |   14 +
 arch/arm/mach-exynos4/Makefile                     |    2 +
 arch/arm/mach-exynos4/mach-exynos4-dt.c            |   85 ++++
 8 files changed, 839 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/insignal-boards.txt
 create mode 100644 Documentation/devicetree/bindings/arm/samsung-boards.txt
 create mode 100644 arch/arm/boot/dts/exynos4210-origen.dts
 create mode 100644 arch/arm/boot/dts/exynos4210-smdkv310.dts
 create mode 100644 arch/arm/boot/dts/exynos4210.dtsi
 create mode 100644 arch/arm/mach-exynos4/mach-exynos4-dt.c

^ permalink raw reply

* [PATCH 8/9] ARM: SPMP8000: Add support for the Letcool board
From: Arnd Bergmann @ 2011-10-11 14:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1318178172-7965-9-git-send-email-zoss@devai.org>

On Sunday 09 October 2011, Zoltan Devai wrote:
> Signed-off-by: Zoltan Devai <zoss@devai.org>
> ---
>  arch/arm/mach-spmp8000/board_letcool.c           |  154 ++++++++++++++++++++++
>  arch/arm/mach-spmp8000/include/mach/spmp8000fb.h |   32 +++++
>  2 files changed, 186 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-spmp8000/board_letcool.c
>  create mode 100644 arch/arm/mach-spmp8000/include/mach/spmp8000fb.h

Hi Zoltan,

We basically stopped doing board files for new platforms. Please get
rid of this and make sure that the spmp8000-letcool.dts describes
everything you need to get this board running. The DT_MACHINE_START
part should just be part of the core.c file and not mention the 
board name, since its intended to apply to all boards with this
SOC.

	Arnd

^ permalink raw reply

* [PATCH] mmc: mmci: Do not release spinlock in request_end
From: Ulf Hansson @ 2011-10-11 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

The patch "mmc: core: move ->request() call from atomic context",
is the reason to why this change is possible. This simplifies the
error handling code execution path quite a lot and potentially also
fixes some error handling hang problems.

Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
---
 drivers/mmc/host/mmci.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 40e4c05..f7755c9 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -165,13 +165,7 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 	host->mrq = NULL;
 	host->cmd = NULL;
 
-	/*
-	 * Need to drop the host lock here; mmc_request_done may call
-	 * back into the driver...
-	 */
-	spin_unlock(&host->lock);
 	mmc_request_done(host->mmc, mrq);
-	spin_lock(&host->lock);
 }
 
 static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH] ARM: omap2+: stub out omap*_volt_data
From: Arnd Bergmann @ 2011-10-11 13:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87ipnwhepq.fsf@ti.com>

On Monday 10 October 2011, Kevin Hilman wrote:
> > I got this build error only now after pulling in the latest omap series, but
> > I cannot tell what caused it. It's also not clear to me if this is the correct
> > solution. Please ack or provide a better fix.
> 
> This code was merged for v2.6.39, so not sure why this error is only
> showing up for you now.  I just tried a !CONFIG_PM_OPP build on v2.6.39
> and get the same errors, so it's been lingering.
> 
> Maybe you haven't had a randconfig that disabled CONFIG_PM_OPP before?

I don't know. The best explanation is that this is a very unlikely case.
I've done many thousand randconfig builds now and have not seen it before.

Of course, since the output of randconfig is random, it could indeed just
be a coincidence.

> Anyways, the fix is fine with me.

Thanks,

	Arnd

^ permalink raw reply

* [PATCHv16 0/9] Contiguous Memory Allocator
From: Arnd Bergmann @ 2011-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20111010155642.38df59af.akpm@linux-foundation.org>

On Tuesday 11 October 2011, Andrew Morton wrote:
> Russell's going to hate me, but...
> 
> I do know that he had substantial objections to at least earlier
> versions of this, and he is a guy who knows of what he speaks.
> 
> So I would want to get a nod from rmk on this work before proceeding. 
> If that nod isn't available then let's please identify the issues and
> see what we can do about them.

I'm pretty sure that Russell's concerns were almost entirely about the
ARM specific parts, which were extremely hard to figure out. The
most important technical concern back in July was that the patch
series at the time did not address the problem of conflicting pte
flags when we remap memory as uncached on ARMv6. He had a patch
to address this problem that was supposed to get merged in 3.1
and would have conflicted with the CMA patch set.

Things have changed a lot since then. Russell had to revert his
own patch because he found regressions using it on older machines.
However, the current CMA on ARM patch AFAICT reliably fixes this
problem now and does not cause the same regression on older machines.
The solution used now is the one we agreed on after sitting together
for a few hours with Russell, Marek, Paul McKenney and myself.

If there are still concerns over the ARM specific portion of
the patch series, I'm very confident that we can resolve these
now (I was much less so before that meeting).

What I would really want to hear from you is your opinion on
the architecture independent stuff. Obviously, ARM is the
most important consumer of the patch set, but I think the
code has its merit on other architectures as well and most of
them (maybe not parisc) should be about as simple as the x86
one that Marek posted now with v16.

	Arnd

^ permalink raw reply

* [alsa-devel] [PATCH v3 0/3] ARM: mxs: add recording support for saif
From: Dong Aisheng @ 2011-10-11 13:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1317052353-6029-1-git-send-email-b29396@freescale.com>

2011/9/26 Dong Aisheng <b29396@freescale.com>:
> Changes since v2:
> ?* separate clkmux code into another patch according to Uwe
> ?* add lock according to Wolfram
> ?* Other minus fixes suggested by Uwe and Wolfram.
> ?* remove Wolfram's fix saif clock setting patch which is in v2 series
> ? since Wolfram will reform the clock code and send it out himself.
> ? For test purpose, user still needs that patch. People can get it
> ? from v2 series.
> ? The patch is:
> ? [PATCH v2 3/3] arm: mxs: disable clock-gates when setting saif-clocks
>
> The patches are based on imx-features branch since commit:
> f4f01e31835f.
>
> Changes since v1:
> The main changes are move mach-specific code(clkmux in DIGCTL) from
> saif driver to mach-specific layer based on Wolfram's suggestion.
>
> Note that the last patch is a RFC patch and sent out for testing
> since without that patch the saif may not work.
>
> Dong Aisheng (3):
> ?ARM: mxs: add saif clkmux functions
> ?ARM: mx28evk: add platform data for saif
> ?ARM: mx28evk: set a initial clock rate for saif

Any comments for this?

Regards
Dong Aisheng

> ?arch/arm/mach-mxs/clock-mx28.c ? ? ? ? ? ? ? ? ?| ? 67 +++++++++++++++++++++++
> ?arch/arm/mach-mxs/devices-mx28.h ? ? ? ? ? ? ? ?| ? ?3 +-
> ?arch/arm/mach-mxs/devices/platform-mxs-saif.c ? | ? ?5 +-
> ?arch/arm/mach-mxs/include/mach/common.h ? ? ? ? | ? ?2 +
> ?arch/arm/mach-mxs/include/mach/devices-common.h | ? ?4 +-
> ?arch/arm/mach-mxs/include/mach/digctl.h ? ? ? ? | ? 21 +++++++
> ?arch/arm/mach-mxs/mach-mx28evk.c ? ? ? ? ? ? ? ?| ? 16 +++++-
> ?7 files changed, 112 insertions(+), 6 deletions(-)
> ?create mode 100644 arch/arm/mach-mxs/include/mach/digctl.h
>
>
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

^ permalink raw reply

* [GIT PULL] DEBUG_LL platform updates for 3.2
From: Arnd Bergmann @ 2011-10-11 13:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20111010133246.GG2451@mudshark.cambridge.arm.com>

On Monday 10 October 2011, Will Deacon wrote:
> On Mon, Oct 10, 2011 at 12:20:24PM +0100, Arnd Bergmann wrote:
> > On Monday 10 October 2011, Will Deacon wrote:
> > > Do you have any other ideas?
> > 
> > I think the best solution would be to ask Russell to put all the dependencies
> > into a non-rebasing branch and publish that, or to alternatively merge your
> > patches through his tree instead, with my Ack.
> 
> I don't think asking Russell to maintain a stable branch for each series
> scales very well if multiple people are doing cross-platform work at the
> same time. If he's happy merging platform code via his tree, then I'd prefer
> to go down that route. In this case, it might make sense to try and catch
> conflicts between his tree and arm-soc before they hit Linus (I guess -next
> will take care of this?).

Yes, we can definitely spot the conflicts in linux-next, and it gives us
the chance to fix them up, e.g. I can wait with sending the arm-soc
branches upstream until Russell's branches are merged, at which point
I just pull in the branch that was merged into Linus' tree and resolve
all conflicts I get.
 
> > Can you check if the devel-stable branch in his tree already contains the
> > dependencies?
> 
> I just had a quick look and I can't seem them outside of the unstable for-next
> branch.

Ok. I think I'll drop the cpu-mapping branch from arm-soc as well then.

Are the patches in Russell's tree true dependencies for your work, or just
patches touching the same files? If you can send me a branch that contains
only your work without any of the patches that are in an unstable branch
on Russell's side, I could also take them into arm-soc and take care
of the conflicts together with Stephen.

	Arnd

^ permalink raw reply

* [PATCH 2/5] ARM: s3c64xx: Add generic high resolution time support using PWM timers.
From: Tomasz Figa @ 2011-10-11 13:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <039d01cc8733$16c5ded0$44519c70$%kim@samsung.com>

On Monday 10 of October 2011 at 18:57:58, Kukjin Kim wrote:
> Tomasz Figa wrote:
> > 
> > From d1fa581f09d8f8a3cc24d05420e9e65112fd8c12 Mon Sep 17 00:00:00 2001
> > From: Tomasz Figa <tomasz.figa@gmail.com>
> > Date: Sun, 28 Aug 2011 02:45:06 +0200
> > Subject: [PATCH 2/5] ARM: s3c64xx: Add generic high resolution time
> support
> >  using PWM timers.
> > 
> > This patch adds a sys_timer implementing generic clock source and clock
> event
> > device on S3C64xx using PWM timers 3 and 4. It can be enabled by a Kconfig
> > option, based on which either the new sys_timer is used as s3c64xx_timer
> or
> > s3c64xx_timer is defined to s3c24xx_timer which is the old tick timer.
> > 
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > ---
> >  arch/arm/Kconfig                         |    1 -
> >  arch/arm/mach-s3c64xx/Kconfig            |   12 ++
> >  arch/arm/mach-s3c64xx/Makefile           |    3 +
> >  arch/arm/mach-s3c64xx/time.c             |  320
> > ++++++++++++++++++++++++++++++
> >  arch/arm/plat-samsung/include/plat/cpu.h |    7 +
> >  5 files changed, 342 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/arm/mach-s3c64xx/time.c
> > 
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 9adc278..05941f6 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -700,7 +700,6 @@ config ARCH_S3C64XX
> >  	select ARM_VIC
> >  	select HAVE_CLK
> >  	select NO_IOPORT
> > -	select ARCH_USES_GETTIMEOFFSET
> >  	select ARCH_HAS_CPUFREQ
> >  	select ARCH_REQUIRE_GPIOLIB
> >  	select SAMSUNG_CLKSRC
> > diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
> > index e4177e2..2db76fd 100644
> > --- a/arch/arm/mach-s3c64xx/Kconfig
> > +++ b/arch/arm/mach-s3c64xx/Kconfig
> > @@ -25,6 +25,18 @@ config CPU_S3C6410
> >  	help
> >  	  Enable S3C6410 CPU support
> > 
> > +config S3C64XX_GENERIC_CLOCKEVENTS
> > +	bool "Enable high resolution generic time support using PWM timers"
> > +	select GENERIC_CLOCKEVENTS
> > +	help
> > +	  This option enables high resolution generic time support
> > +	  on S3C6400/S3C6410 SoCs using PWM timers 3 and 4 instead
> > +	  of standard periodic tick using PWM timer 4.
> > +
> > +config S3C64XX_ARCH_USES_GETTIMEOFFSET
> > +	def_bool y if !S3C64XX_GENERIC_CLOCKEVENTS
> > +	select ARCH_USES_GETTIMEOFFSET
> > +
> >  config S3C64XX_DMA
> >  	bool "S3C64XX DMA"
> >  	select S3C_DMA
> > diff --git a/arch/arm/mach-s3c64xx/Makefile
> b/arch/arm/mach-s3c64xx/Makefile
> > index 4657363..a152002 100644
> > --- a/arch/arm/mach-s3c64xx/Makefile
> > +++ b/arch/arm/mach-s3c64xx/Makefile
> > @@ -15,6 +15,9 @@ obj-y				+= cpu.o
> >  obj-y				+= clock.o
> >  obj-y				+= gpiolib.o
> > 
> > +# Generic clockevents
> > +obj-$(CONFIG_S3C64XX_GENERIC_CLOCKEVENTS) += time.o
> > +
> >  # Core support for S3C6400 system
> > 
> >  obj-$(CONFIG_CPU_S3C6400)	+= s3c6400.o
> > diff --git a/arch/arm/mach-s3c64xx/time.c b/arch/arm/mach-s3c64xx/time.c
> > new file mode 100644
> > index 0000000..4fa57f0
> > --- /dev/null
> > +++ b/arch/arm/mach-s3c64xx/time.c
> > @@ -0,0 +1,320 @@
> > +/* linux/arch/arm/mach-s3c64xx/time.c
> > + *
> > + * Copyright (c) 2011 Tomasz Figa <tomasz.figa@gmail.com>
> > + *
> > + * based on linux/arch/arm/plat-samsung/s5p-time.c
> > + *
> > + * S3C64XX generic high resolution time support using PWM 3 and PWM 4
> timers.
> > + *
> > + * 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.
> > + *
> > + * Notes:
> > + * - Frequency divisors are currently hardcoded to make both timers
> operate
> > + *   at 1/6 the frequency of PCLK, so with the usual PCLK frequency of 66
> MHz,
> > + *   the timers are clocked at 11 MHz giving us the operating range from
> > + *   90 nsec to 386 sec.
> > + * - PWM registers, especially TCON, are shared with PWM driver, but
> since
> > + *   all the clock event callbacks are run in atomic context
> synchronization
> > + *   is not needed.
> > + */
> > +
> > +#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 <mach/map.h>
> > +#include <plat/regs-timer.h>
> > +#include <asm/mach/time.h>
> > +
> > +#define PWM_EVENT	(3)
> > +#define PWM_SOURCE	(4)
> > +
> > +#define ONESHOT		(0)
> > +#define PERIODIC	(1)
> > +
> > +#define TCNT_MAX	(0xffffffff)
> > +
> > +static struct clk *timerclk;
> > +
> > +/*
> > + * PWM timers setup code
> > + */
> > +
> > +static inline void s3c64xx_pwm_stop(unsigned int pwm_id)
> > +{
> > +	unsigned long tcon = __raw_readl(S3C2410_TCON);
> > +
> > +	switch (pwm_id) {
> > +	case 3:
> > +		tcon &= ~S3C2410_TCON_T3START;
> > +		break;
> > +	case 4:
> > +		tcon &= ~S3C2410_TCON_T4START;
> > +		break;
> > +	}
> > +
> > +	__raw_writel(tcon, S3C2410_TCON);
> > +}
> > +
> > +static inline void s3c64xx_pwm_init(unsigned int pwm_id, unsigned long
> tcnt)
> > +{
> > +	unsigned long tcon = __raw_readl(S3C2410_TCON);
> > +
> > +	/* timers reload after counting zero, so reduce the count by 1 */
> > +	--tcnt;
> > +
> > +	/* stop the timer and ask it to load the new value */
> > +	switch (pwm_id) {
> > +	case 3:
> > +		tcon &= ~(0xf<<16);
> > +		tcon |= S3C2410_TCON_T3MANUALUPD;
> > +		break;
> > +	case 4:
> > +		tcon &= ~(7<<20);
> > +		tcon |= S3C2410_TCON_T4MANUALUPD;
> > +		break;
> > +	}
> > +
> > +	__raw_writel(tcnt, S3C2410_TCNTB(pwm_id));
> > +	__raw_writel(tcnt, S3C2410_TCMPB(pwm_id));
> > +	__raw_writel(tcon, S3C2410_TCON);
> > +}
> > +
> > +static inline void s3c64xx_pwm_start(unsigned int pwm_id, bool periodic)
> > +{
> > +	unsigned long tcon = __raw_readl(S3C2410_TCON);
> > +
> > +	switch (pwm_id) {
> > +	case 3:
> > +		tcon |= S3C2410_TCON_T3START;
> > +		tcon &= ~S3C2410_TCON_T3MANUALUPD;
> > +
> > +		if (periodic)
> > +			tcon |= S3C2410_TCON_T3RELOAD;
> > +		else
> > +			tcon &= ~S3C2410_TCON_T3RELOAD;
> > +		break;
> > +	case 4:
> > +		tcon |= S3C2410_TCON_T4START;
> > +		tcon &= ~S3C2410_TCON_T4MANUALUPD;
> > +
> > +		if (periodic)
> > +			tcon |= S3C2410_TCON_T4RELOAD;
> > +		else
> > +			tcon &= ~S3C2410_TCON_T4RELOAD;
> > +		break;
> > +	}
> > +
> > +	__raw_writel(tcon, S3C2410_TCON);
> > +}
> > +
> > +/*
> > + * Clock event
> > + */
> > +
> > +static struct clk *event_in;
> > +static struct clk *event_div;
> > +
> > +static unsigned long clock_count_per_tick;
> > +
> > +static int s3c64xx_clock_event_set_next_event(unsigned long cycles,
> > +						struct clock_event_device
> > *evt)
> > +{
> > +	s3c64xx_pwm_init(PWM_EVENT, cycles);
> > +	s3c64xx_pwm_start(PWM_EVENT, ONESHOT);
> > +	return 0;
> > +}
> > +
> > +static void s3c64xx_clock_event_resume(void)
> > +{
> > +	unsigned long pclk;
> > +	struct clk *tscaler;
> > +
> > +	pclk = clk_get_rate(timerclk);
> > +	tscaler = clk_get_parent(event_div);
> > +	clk_set_rate(tscaler, pclk / 3);
> > +
> > +	clk_set_rate(event_div, pclk / 6);
> > +	clk_set_parent(event_in, event_div);
> > +
> > +	s3c64xx_pwm_init(PWM_EVENT, clock_count_per_tick);
> > +	s3c64xx_pwm_start(PWM_EVENT, PERIODIC);
> > +}
> > +
> > +static void s3c64xx_clock_event_set_mode(enum clock_event_mode mode,
> > +						struct clock_event_device
> > *evt)
> > +{
> > +	s3c64xx_pwm_stop(PWM_EVENT);
> > +
> > +	switch (mode) {
> > +	case CLOCK_EVT_MODE_PERIODIC:
> > +		s3c64xx_pwm_init(PWM_EVENT, clock_count_per_tick);
> > +		s3c64xx_pwm_start(PWM_EVENT, PERIODIC);
> > +		break;
> > +	case CLOCK_EVT_MODE_ONESHOT:
> > +		break;
> > +	case CLOCK_EVT_MODE_UNUSED:
> > +	case CLOCK_EVT_MODE_SHUTDOWN:
> > +		break;
> > +	case CLOCK_EVT_MODE_RESUME:
> > +		s3c64xx_clock_event_resume();
> > +		break;
> > +	}
> > +}
> > +
> > +static struct clock_event_device s3c64xx_clock_event_device = {
> > +	.name		= "s3c64xx_clkevt",
> > +	.features       = CLOCK_EVT_FEAT_PERIODIC |
> > CLOCK_EVT_FEAT_ONESHOT,
> > +	.rating		= 200,
> > +	.shift		= 32,
> > +	.set_next_event	= s3c64xx_clock_event_set_next_event,
> > +	.set_mode	= s3c64xx_clock_event_set_mode,
> > +};
> > +
> > +static irqreturn_t s3c64xx_clock_event_isr(int irq, void *dev_id)
> > +{
> > +	struct clock_event_device *evt = &s3c64xx_clock_event_device;
> > +
> > +	evt->event_handler(evt);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static struct irqaction s3c64xx_clock_event_irq = {
> > +	.name		= "s3c64xx_clkevt_irq",
> > +	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> > +	.handler	= s3c64xx_clock_event_isr,
> > +};
> > +
> > +static void __init s3c64xx_clock_event_init(void)
> > +{
> > +	unsigned long clock_rate;
> > +
> > +	clock_rate = clk_get_rate(event_in);
> > +
> > +	clock_count_per_tick = clock_rate / HZ;
> > +
> > +	s3c64xx_clock_event_device.mult = div_sc(clock_rate,
> > +			NSEC_PER_SEC, s3c64xx_clock_event_device.shift);
> > +	s3c64xx_clock_event_device.max_delta_ns =
> > +			clockevent_delta2ns(-1,
> &s3c64xx_clock_event_device);
> > +	s3c64xx_clock_event_device.min_delta_ns =
> > +			clockevent_delta2ns(1, &s3c64xx_clock_event_device);
> > +
> > +	s3c64xx_clock_event_device.cpumask = cpumask_of(0);
> > +	clockevents_register_device(&s3c64xx_clock_event_device);
> > +
> > +	setup_irq(IRQ_TIMER3, &s3c64xx_clock_event_irq);
> > +}
> > +
> > +/*
> > + * Clock source
> > + */
> > +
> > +static struct clk *source_in;
> > +static struct clk *source_div;
> > +
> > +static cycle_t s3c64xx_clocksource_read(struct clocksource *cs)
> > +{
> > +	return (cycle_t) ~__raw_readl(S3C2410_TCNTO(PWM_SOURCE));
> > +}
> > +
> > +static void s3c64xx_clocksource_resume(struct clocksource *cs)
> > +{
> > +	unsigned long pclk;
> > +	struct clk *tscaler;
> > +
> > +	pclk = clk_get_rate(timerclk);
> > +	tscaler = clk_get_parent(source_div);
> > +	clk_set_rate(tscaler, pclk / 3);
> > +
> > +	clk_set_rate(source_div, pclk / 6);
> > +	clk_set_parent(source_in, source_div);
> > +
> > +	s3c64xx_pwm_init(PWM_SOURCE, TCNT_MAX);
> > +	s3c64xx_pwm_start(PWM_SOURCE, PERIODIC);
> > +}
> > +
> > +static struct clocksource pwm_clocksource = {
> > +	.name		= "s3c64xx_clksrc",
> > +	.rating		= 250,
> > +	.read		= s3c64xx_clocksource_read,
> > +	.mask		= CLOCKSOURCE_MASK(32),
> > +	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> > +	.resume		= s3c64xx_clocksource_resume,
> > +};
> > +
> > +static void __init s3c64xx_clocksource_init(void)
> > +{
> > +	unsigned long clock_rate;
> > +
> > +	clock_rate = clk_get_rate(source_in);
> > +
> > +	s3c64xx_pwm_init(PWM_SOURCE, TCNT_MAX);
> > +	s3c64xx_pwm_start(PWM_SOURCE, PERIODIC);
> > +
> > +	if (clocksource_register_hz(&pwm_clocksource, clock_rate))
> > +		panic("%s: can't register clocksource\n",
> > pwm_clocksource.name);
> > +}
> > +
> > +static void __init s3c64xx_timer_init_common(void)
> > +{
> > +	struct platform_device tmpdev;
> > +	unsigned long pclk;
> > +	struct clk *tscaler;
> > +
> > +	tmpdev.dev.bus = &platform_bus_type;
> > +
> > +	timerclk = clk_get(NULL, "timers");
> > +	if (IS_ERR(timerclk))
> > +		panic("failed to get timers clock for system timer");
> > +
> > +	tmpdev.id = PWM_EVENT;
> > +	event_in = clk_get(&tmpdev.dev, "pwm-tin");
> > +	if (IS_ERR(event_in))
> > +		panic("failed to get pwm-event_in clock for system timer");
> > +
> > +	event_div = clk_get(&tmpdev.dev, "pwm-tdiv");
> > +	if (IS_ERR(event_div))
> > +		panic("failed to get pwm-event_div clock for system timer");
> > +
> > +	tmpdev.id = PWM_SOURCE;
> > +	source_in = clk_get(&tmpdev.dev, "pwm-tin");
> > +	if (IS_ERR(source_in))
> > +		panic("failed to get pwm-source_in clock for system timer");
> > +
> > +	source_div = clk_get(&tmpdev.dev, "pwm-tdiv");
> > +	if (IS_ERR(source_div))
> > +		panic("failed to get pwm-source_div clock for system
> timer");
> > +
> > +	pclk = clk_get_rate(timerclk);
> > +	tscaler = clk_get_parent(event_div);
> > +	clk_set_rate(tscaler, pclk / 3);
> > +
> > +	clk_set_rate(event_div, pclk / 6);
> > +	clk_set_parent(event_in, event_div);
> > +
> > +	clk_set_rate(source_div, pclk / 6);
> > +	clk_set_parent(source_in, source_div);
> > +
> > +	clk_enable(timerclk);
> > +	clk_enable(event_in);
> > +	clk_enable(source_in);
> > +}
> > +
> > +static void __init s3c64xx_timer_init(void)
> > +{
> > +	s3c64xx_timer_init_common();
> > +	s3c64xx_clock_event_init();
> > +	s3c64xx_clocksource_init();
> > +}
> > +
> > +struct sys_timer s3c64xx_timer = {
> > +	.init		= s3c64xx_timer_init,
> > +};
> > diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-
> > samsung/include/plat/cpu.h
> > index c0a5741..e1fcad0 100644
> > --- a/arch/arm/plat-samsung/include/plat/cpu.h
> > +++ b/arch/arm/plat-samsung/include/plat/cpu.h
> > @@ -74,6 +74,13 @@ extern struct syscore_ops s3c2416_pm_syscore_ops;
> >  extern struct syscore_ops s3c244x_pm_syscore_ops;
> >  extern struct syscore_ops s3c64xx_irq_syscore_ops;
> > 
> > +/* timer for 64xx */
> > +#ifdef CONFIG_S3C64XX_GENERIC_CLOCKEVENTS
> > +extern struct sys_timer s3c64xx_timer;
> > +#else
> > +#define s3c64xx_timer s3c24xx_timer
> > +#endif
> > +
> >  /* system device classes */
> > 
> >  extern struct sysdev_class s3c2410_sysclass;
> > --
> > 1.7.6.1
> 
> Hi Tomasz Figa,
> 
> Sorry for late response, probably I'm missing this......and I couldn't
> review this in detail :(

Hi,

Same on my side, sorry for my absence on the list. I've been very busy, with
no time for mainline submissions.

> But as you know above mach-s3c64xx/time.c is similar with
> plat-s5p/s5p-time.c so I'd prefer that you could consolidate them,
> samsung_timer into plat-samsung directory. In addition, if you need to
> implement SoC specific feature, you can use soc_is_xxxx() like
> soc_is_s3c64xx() there.

OK, I will do that.

> If any problems, please let me know.

OK, thanks.

Best regards,
Tom

> Thanks.
> 
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.
> 

^ permalink raw reply

* [PATCH] arm: fix handling of nr_cpus
From: Mark Salter @ 2011-10-11 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

The current code duplicates the setup of the cpu_possible bitmap in the
platform smp_init_cpus() function. Unfortunately, all of those places
have the same bug where the nr_cpus kernel parameter is ignored. This patch
consolidates the duplicated code in one place and fixes it to honor the
nr_cpus parameter. This is accomplished by having smp_init_cpus() return
the platform specific number of cores so that the caller (setup_arch) can
set up the cpu_possible bitmap correctly for all platforms.

Signed-off-by: Mark Salter <msalter@redhat.com>
---
 arch/arm/include/asm/smp.h                        |    5 ++-
 arch/arm/kernel/setup.c                           |   24 +++++++++++++++++++-
 arch/arm/mach-exynos4/platsmp.c                   |   24 ++------------------
 arch/arm/mach-msm/platsmp.c                       |   14 +++--------
 arch/arm/mach-omap2/omap-smp.c                    |   24 ++------------------
 arch/arm/mach-realview/platsmp.c                  |   23 ++-----------------
 arch/arm/mach-shmobile/platsmp.c                  |   10 ++------
 arch/arm/mach-tegra/platsmp.c                     |   19 ++--------------
 arch/arm/mach-ux500/platsmp.c                     |   23 ++-----------------
 arch/arm/mach-vexpress/ct-ca9x4.c                 |   11 +++------
 arch/arm/mach-vexpress/include/mach/motherboard.h |    2 +-
 arch/arm/mach-vexpress/platsmp.c                  |    8 +-----
 12 files changed, 54 insertions(+), 133 deletions(-)

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index e42d96a..e9c38a9 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -33,9 +33,10 @@ extern void show_ipi_list(struct seq_file *, int);
 asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
 
 /*
- * Setup the set of possible CPUs (via set_cpu_possible)
+ * Early platform SMP init.
+ * Returns the number of cores.
  */
-extern void smp_init_cpus(void);
+extern int smp_init_cpus(void);
 
 
 /*
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index e514c76..5df2722 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -913,8 +913,28 @@ void __init setup_arch(char **cmdline_p)
 	unflatten_device_tree();
 
 #ifdef CONFIG_SMP
-	if (is_smp())
-		smp_init_cpus();
+	/*
+	 * Initialise the CPU possible map early - this describes the CPUs
+	 * which may be present or become present in the system.
+	 */
+	if (is_smp()) {
+		int i, ncores;
+
+		ncores = smp_init_cpus();
+
+		if (ncores > NR_CPUS) {
+			printk(KERN_WARNING
+			       "Number of cores (%d) greater than configured "
+			       "maximum of %d - clipping\n",
+			       ncores, NR_CPUS);
+			ncores = NR_CPUS;
+		}
+		if (ncores > nr_cpu_ids)
+			ncores = nr_cpu_ids;
+
+		for (i = 0; i < ncores; i++)
+			set_cpu_possible(i, true);
+	}
 #endif
 	reserve_crashkernel();
 
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index df6ef1b..70b3e99 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -180,31 +180,13 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return pen_release != -1 ? -ENOSYS : 0;
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
 	void __iomem *scu_base = scu_base_addr();
-	unsigned int i, ncores;
-
-	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-
-	/* sanity check */
-	if (ncores > NR_CPUS) {
-		printk(KERN_WARNING
-		       "EXYNOS4: no. of cores (%d) greater than configured "
-		       "maximum of %d - clipping\n",
-		       ncores, NR_CPUS);
-		ncores = NR_CPUS;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
 
 	set_smp_cross_call(gic_raise_softirq);
+
+	return scu_base ? scu_get_core_count(scu_base) : 1;
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 1a1af9e..b59f8b5 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -147,19 +147,13 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 }
 
 /*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system. The msm8x60
- * does not support the ARM SCU, so just set the possible cpu mask to
- * NR_CPUS.
+ * The msm8x60 does not support the ARM SCU, so just return NR_CPUS.
  */
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
-	unsigned int i, ncores = get_core_count();
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
-
         set_smp_cross_call(gic_raise_softirq);
+
+	return get_core_count();
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ce65e93..deaf25a 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -94,33 +94,15 @@ static void __init wakeup_secondary(void)
 	mb();
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
-	unsigned int i, ncores;
-
 	/* Never released */
 	scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
 	BUG_ON(!scu_base);
 
-	ncores = scu_get_core_count(scu_base);
-
-	/* sanity check */
-	if (ncores > NR_CPUS) {
-		printk(KERN_WARNING
-		       "OMAP4: no. of cores (%d) greater than configured "
-		       "maximum of %d - clipping\n",
-		       ncores, NR_CPUS);
-		ncores = NR_CPUS;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
-
 	set_smp_cross_call(gic_raise_softirq);
+
+	return scu_get_core_count(scu_base);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 4ae943b..b6309c0 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -40,30 +40,13 @@ static void __iomem *scu_base_addr(void)
 		return (void __iomem *)0;
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
 	void __iomem *scu_base = scu_base_addr();
-	unsigned int i, ncores;
-
-	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-
-	/* sanity check */
-	if (ncores > NR_CPUS) {
-		printk(KERN_WARNING
-		       "Realview: no. of cores (%d) greater than configured "
-		       "maximum of %d - clipping\n",
-		       ncores, NR_CPUS);
-		ncores = NR_CPUS;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
 
 	set_smp_cross_call(gic_raise_softirq);
+
+	return scu_base ? scu_get_core_count(scu_base) : 1;
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index 66f9806..b9338e8 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -51,15 +51,11 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return -ENOSYS;
 }
 
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
-	unsigned int ncores = shmobile_smp_get_core_count();
-	unsigned int i;
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
-
 	set_smp_cross_call(gic_raise_softirq);
+
+	return shmobile_smp_get_core_count();
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 0886cbc..bcd8f72 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -106,24 +106,11 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
-	unsigned int i, ncores = scu_get_core_count(scu_base);
-
-	if (ncores > NR_CPUS) {
-		printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
-			ncores, NR_CPUS);
-		ncores = NR_CPUS;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
-
 	set_smp_cross_call(gic_raise_softirq);
+
+	return scu_get_core_count(scu_base);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index a33df5f..c3491af 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -144,30 +144,13 @@ static void __init wakeup_secondary(void)
 	mb();
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
 	void __iomem *scu_base = scu_base_addr();
-	unsigned int i, ncores;
-
-	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-
-	/* sanity check */
-	if (ncores > NR_CPUS) {
-		printk(KERN_WARNING
-		       "U8500: no. of cores (%d) greater than configured "
-		       "maximum of %d - clipping\n",
-		       ncores, NR_CPUS);
-		ncores = NR_CPUS;
-	}
-
-	for (i = 0; i < ncores; i++)
-		set_cpu_possible(i, true);
 
 	set_smp_cross_call(gic_raise_softirq);
+
+	return scu_base ? scu_get_core_count(scu_base) : 1;
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index bfd32f5..21006af 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -217,14 +217,11 @@ static void __init ct_ca9x4_init(void)
 }
 
 #ifdef CONFIG_SMP
-static void ct_ca9x4_init_cpu_map(void)
+static int ct_ca9x4_smp_init_cpus(void)
 {
-	int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
-
-	for (i = 0; i < ncores; ++i)
-		set_cpu_possible(i, true);
-
 	set_smp_cross_call(gic_raise_softirq);
+
+	return scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
 }
 
 static void ct_ca9x4_smp_enable(unsigned int max_cpus)
@@ -241,7 +238,7 @@ struct ct_desc ct_ca9x4_desc __initdata = {
 	.init_irq	= ct_ca9x4_init_irq,
 	.init_tile	= ct_ca9x4_init,
 #ifdef CONFIG_SMP
-	.init_cpu_map	= ct_ca9x4_init_cpu_map,
+	.smp_init_cpus	= ct_ca9x4_smp_init_cpus,
 	.smp_enable	= ct_ca9x4_smp_enable,
 #endif
 };
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 0a3a375..2920ac7 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -133,7 +133,7 @@ struct ct_desc {
 	void			(*init_irq)(void);
 	void			(*init_tile)(void);
 #ifdef CONFIG_SMP
-	void			(*init_cpu_map)(void);
+	int			(*smp_init_cpus)(void);
 	void			(*smp_enable)(unsigned int);
 #endif
 };
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 2b5f7ac..e713c7e 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -22,13 +22,9 @@
 
 extern void versatile_secondary_startup(void);
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-void __init smp_init_cpus(void)
+int __init smp_init_cpus(void)
 {
-	ct_desc->init_cpu_map();
+	return ct_desc->smp_init_cpus();
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
-- 
1.7.6.4

^ permalink raw reply related

* [PATCH 5/7] ARM: EXYNOS4: Add support external GIC
From: Marc Zyngier @ 2011-10-11 13:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <00b901cc8810$8353e730$89fbb590$%youn@samsung.com>

Hi Changwan,

On 11/10/11 13:22, Changhwan Youn wrote:
>> Kukjin, could you please comment on the presence of a common memory
>> region for the distributor? This seem quite odd...
> 
> Some registers in Distributor are banked for PPI and SGI support (banked interrupts).
> The register for pending and enable status of these interrupts are 
> banked.

Right, that explains it then.

> Marc, I think the approach in your patch is much better than mine if it doesn't hurt
> the performance of other platforms which use the common gic code.

It probably doesn't hurt the general case too much (I expect a bit more
pressure on the d-cache because of the per-cpu stuff, but nothing to be
too worried about).

> I'll re-work the exynos4 interrupt code based on your patch though
> I'm not sure that it's possible to be merged in merge window.

My main concern at the moment is that mainline is broken as far as
EXYNOS4 is concerned (there's a race with the EOI hook), so that should
get fixed first.

Cheers,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply


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