All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] Samsung device-table approach
@ 2010-08-11 12:03 ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Hello,

I would like to start the discussion on the redesign of the way the
Samsung platform devices are defined. The current solution has some
important disadvantages that blocks the further kernel development.

Samsung SoC family is quite large. Mainline kernel already has support
for more than 8 representatives, each having different memory and irq
map.

Currently most of the base address and irq differences are hidden behind
the includes and some common defines (usualy named S3C_PA_*). Some
devices also have different variants that are specified by changing the
device name to include the SoC version in it. Others have SoC specific
callbacks (like gpio pin configuration) that are provided thought the
platform data.

There is a lot of code that is needed to handle all these variants and
differences. It also differs in term of style and a way how some
simmilar things are performed (like changing the device name or
providing the default platform data).

In 2009 Ben Dooks did a research and proposed a solution that is called
a device table. This solution solves the most problematic issue.
Different base addresses and irqs can be easily provided for the same
device on different version SoC systems. This is achieved by having a
single table for each SoC that contains all these resources and create
all required platform devices dynamically on SoC init.

The proposed solution was enough for s3c24xx SoC devices and some early
s3c64xx devices. However since then some new devices has been merged to
mainline, mainly for s5p SoC series. These devices have more than one
base address or irq and does not fit well into that framework.

I've extended his approach to handle such more advanced devices. The new
version is capable of setting up devices with more than one irq,
physical register areas or even a dma channel. 

I've also added support for the default platform data. It has been
designed in such a way that it can handle different default data for
each device instance for each SoC system. This requires a bit of C
preprocessor in the includes but make it much easier to register
particular device. With this new solution there is no need for calling a
function for setting platform data in machine startup.

The solution has been designed with the following assumptions:
1. to reduce the number of static structures compiled into the kernel
that are not used at all
2. to reduce the memory used by the unused static structures once kernel
has booted

The requirements has been achieved by:  
1. Conditional compilation and linkage of default platform data and the
required callbacks. This requires a little help from C preprocessor to
NULL some symbols if they are not compiled in but I've tried to keep the
code as readable as possible.
2. Moving all structures to the __initdata section. This require to
duplicate all used data by kmemdup (or kmalloc+memcpy) but it is not a
problem, because most of the structures are created dynamically anyway.

This patch series has been prepared mainly as an RFC not a final
implementation. It covers only a single SoC (S5PV210) and 2 machines
(Aquila and GONI). Once the common way for the device-table will be
agreed, the patches for other SoCs and machines will be prepared.

The patch series consist of the following patches:
[PATCH 1/9] ARM: Samsung: add device-table core functions
[PATCH 2/9] ARM: S5PV210: add initial device-table
[PATCH 3/9] ARM: S5PV210: convert uart to device-table
[PATCH 4/9] ARM: S5PV210: add support for device-table on Aquila&Goni
[PATCH 5/9] ARM: S5PV210: convert OneNAND to device-table
[PATCH 6/9] ARM: S5PV210: convert sdhci to device-table
[PATCH 7/9] ARM: S5PV210: convert framebuffer to device-table
[PATCH 8/9] ARM: S5PV210: convert i2c to device-table
[PATCH 9/9] ARM: S5PV210: add i2c device on Aquila

This patch series contains a device conversion for the following
platform devices:
- UART (s3c64xx-uart, s5pv210-uart, ...)
- SDHCI (s3c-sdhci)
- Frame Buffer (s3c-fb)
- I2C (s3c-i2c)
- OneNAND (s5pv210-onenand)

Each device conversion is provided in a separate patch, so one can
easily notice how the conversion is performed. These five device
conversions can be also used as a template for other devices.

Here are some logs from the Aquila machine boot messages that shows how
the devices are being created:

s3c_device_create: device s5pv210-uart.0, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a70e0 = 00000200 e2900000..e29003ff
s3c_device_create: s5pv210-uart res 1 => c08a70fc = 00000400 00000010..00000010
s3c_device_create: s5pv210-uart res 2 => c08a7118 = 00000400 00000012..00000012
s3c_device_create: s5pv210-uart res 3 => c08a7134 = 00000400 00000011..00000011
s3c_device_create: device s5pv210-uart.1, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a7260 = 00000200 e2900400..e29007ff
s3c_device_create: s5pv210-uart res 1 => c08a727c = 00000400 00000014..00000014
s3c_device_create: s5pv210-uart res 2 => c08a7298 = 00000400 00000016..00000016
s3c_device_create: s5pv210-uart res 3 => c08a72b4 = 00000400 00000015..00000015
s3c_device_create: device s5pv210-uart.2, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a73e0 = 00000200 e2900800..e2900bff
s3c_device_create: s5pv210-uart res 1 => c08a73fc = 00000400 00000018..00000018
s3c_device_create: s5pv210-uart res 2 => c08a7418 = 00000400 0000001a..0000001a
s3c_device_create: s5pv210-uart res 3 => c08a7434 = 00000400 00000019..00000019
s3c_device_create: device s5pv210-uart.3, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a7560 = 00000200 e2900c00..e2900fff
s3c_device_create: s5pv210-uart res 1 => c08a757c = 00000400 0000001c..0000001c
s3c_device_create: s5pv210-uart res 2 => c08a7598 = 00000400 0000001e..0000001e
s3c_device_create: s5pv210-uart res 3 => c08a75b4 = 00000400 0000001d..0000001d

s3c_device_create: device s3c2440-i2c.0, template c00219a4, #res 2
s3c_device_create: s3c2440-i2c res 0 => dfc02ee0 = 00000200 e1800000..e1800fff
s3c_device_create: s3c2440-i2c res 1 => dfc02efc = 00000400 0000004e..0000004e
s3c_device_create: s3c2440-i2c pdata => dfcb6bc0 (24 bytes)
s3c_device_create: device s3c-fb.-1, template c002191c, #res 4
s3c_device_create: s3c-fb res 0 => dfc1d6e0 = 00000200 f8000000..f8003fff
s3c_device_create: s3c-fb res 1 => dfc1d6fc = 00000400 00000061..00000061
s3c_device_create: s3c-fb res 2 => dfc1d718 = 00000400 00000060..00000060
s3c_device_create: s3c-fb res 3 => dfc1d734 = 00000400 00000062..00000062
s3c_device_create: s3c-fb dma mask => ffffffff
s3c_device_create: s3c-fb pdata => dfcb6b00 (32 bytes)
s3c_device_create: device s5pc110-onenand.-1, template c00214b8, #res 2
s3c_device_create: s5pc110-onenand res 0 => dfc1d0e0 = 00000200 b0000000..b001ffff
s3c_device_create: s5pc110-onenand res 1 => dfc1d0fc = 00000200 b0600000..b06007ff
s3c_device_create: device s3c-sdhci.0, template c0021904, #res 2
s3c_device_create: s3c-sdhci res 0 => dfc1d2e0 = 00000200 eb000000..eb000fff
s3c_device_create: s3c-sdhci res 1 => dfc1d2fc = 00000400 0000005a..0000005a
s3c_device_create: s3c-sdhci dma mask => ffffffff
s3c_device_create: s3c-sdhci pdata => dfcb6e80 (40 bytes)
s3c_device_create: device s3c-sdhci.1, template c0021904, #res 2
s3c_device_create: s3c-sdhci res 0 => dfc6c2e0 = 00000200 eb100000..eb100fff
s3c_device_create: s3c-sdhci res 1 => dfc6c2fc = 00000400 0000005b..0000005b
s3c_device_create: s3c-sdhci dma mask => ffffffff
s3c_device_create: s3c-sdhci pdata => dfc68f00 (40 bytes)
s3c_device_create: device s3c-sdhci.2, template c0021904, #res 2
s3c_device_create: s3c-sdhci res 0 => dfc6c6e0 = 00000200 eb200000..eb200fff
s3c_device_create: s3c-sdhci res 1 => dfc6c6fc = 00000400 0000005c..0000005c
s3c_device_create: s3c-sdhci dma mask => ffffffff
s3c_device_create: s3c-sdhci pdata => dfc68700 (40 bytes)

This patch series has been prepared for the kgene/tmp-all-merged
(3eb7878811b8e2218cc485578f2a1ffa07152099) kernel tree (it equal to the
current Samsung for-next tree with all other required patches to make it
build):
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git tmp-all-merged

I would like to get an opinion on this solution. It is a third attempt
on the device-table. The original one, proposed by Ben Dooks, is
available on his git tree, wip-samsung-dev branch:
git://git.fluff.org/bjdooks/linux wip-samsung-dev

The second one has been proposed by Kyungmin Park. It can be found the
following thread:
http://www.spinics.net/lists/arm-kernel/msg93583.html

Best regards,
-- 
Marek Szyprowski
Samsung Poland R&D Center

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

* [PATCH/RFC] Samsung device-table approach
@ 2010-08-11 12:03 ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

I would like to start the discussion on the redesign of the way the
Samsung platform devices are defined. The current solution has some
important disadvantages that blocks the further kernel development.

Samsung SoC family is quite large. Mainline kernel already has support
for more than 8 representatives, each having different memory and irq
map.

Currently most of the base address and irq differences are hidden behind
the includes and some common defines (usualy named S3C_PA_*). Some
devices also have different variants that are specified by changing the
device name to include the SoC version in it. Others have SoC specific
callbacks (like gpio pin configuration) that are provided thought the
platform data.

There is a lot of code that is needed to handle all these variants and
differences. It also differs in term of style and a way how some
simmilar things are performed (like changing the device name or
providing the default platform data).

In 2009 Ben Dooks did a research and proposed a solution that is called
a device table. This solution solves the most problematic issue.
Different base addresses and irqs can be easily provided for the same
device on different version SoC systems. This is achieved by having a
single table for each SoC that contains all these resources and create
all required platform devices dynamically on SoC init.

The proposed solution was enough for s3c24xx SoC devices and some early
s3c64xx devices. However since then some new devices has been merged to
mainline, mainly for s5p SoC series. These devices have more than one
base address or irq and does not fit well into that framework.

I've extended his approach to handle such more advanced devices. The new
version is capable of setting up devices with more than one irq,
physical register areas or even a dma channel. 

I've also added support for the default platform data. It has been
designed in such a way that it can handle different default data for
each device instance for each SoC system. This requires a bit of C
preprocessor in the includes but make it much easier to register
particular device. With this new solution there is no need for calling a
function for setting platform data in machine startup.

The solution has been designed with the following assumptions:
1. to reduce the number of static structures compiled into the kernel
that are not used at all
2. to reduce the memory used by the unused static structures once kernel
has booted

The requirements has been achieved by:  
1. Conditional compilation and linkage of default platform data and the
required callbacks. This requires a little help from C preprocessor to
NULL some symbols if they are not compiled in but I've tried to keep the
code as readable as possible.
2. Moving all structures to the __initdata section. This require to
duplicate all used data by kmemdup (or kmalloc+memcpy) but it is not a
problem, because most of the structures are created dynamically anyway.

This patch series has been prepared mainly as an RFC not a final
implementation. It covers only a single SoC (S5PV210) and 2 machines
(Aquila and GONI). Once the common way for the device-table will be
agreed, the patches for other SoCs and machines will be prepared.

The patch series consist of the following patches:
[PATCH 1/9] ARM: Samsung: add device-table core functions
[PATCH 2/9] ARM: S5PV210: add initial device-table
[PATCH 3/9] ARM: S5PV210: convert uart to device-table
[PATCH 4/9] ARM: S5PV210: add support for device-table on Aquila&Goni
[PATCH 5/9] ARM: S5PV210: convert OneNAND to device-table
[PATCH 6/9] ARM: S5PV210: convert sdhci to device-table
[PATCH 7/9] ARM: S5PV210: convert framebuffer to device-table
[PATCH 8/9] ARM: S5PV210: convert i2c to device-table
[PATCH 9/9] ARM: S5PV210: add i2c device on Aquila

This patch series contains a device conversion for the following
platform devices:
- UART (s3c64xx-uart, s5pv210-uart, ...)
- SDHCI (s3c-sdhci)
- Frame Buffer (s3c-fb)
- I2C (s3c-i2c)
- OneNAND (s5pv210-onenand)

Each device conversion is provided in a separate patch, so one can
easily notice how the conversion is performed. These five device
conversions can be also used as a template for other devices.

Here are some logs from the Aquila machine boot messages that shows how
the devices are being created:

s3c_device_create: device s5pv210-uart.0, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a70e0 = 00000200 e2900000..e29003ff
s3c_device_create: s5pv210-uart res 1 => c08a70fc = 00000400 00000010..00000010
s3c_device_create: s5pv210-uart res 2 => c08a7118 = 00000400 00000012..00000012
s3c_device_create: s5pv210-uart res 3 => c08a7134 = 00000400 00000011..00000011
s3c_device_create: device s5pv210-uart.1, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a7260 = 00000200 e2900400..e29007ff
s3c_device_create: s5pv210-uart res 1 => c08a727c = 00000400 00000014..00000014
s3c_device_create: s5pv210-uart res 2 => c08a7298 = 00000400 00000016..00000016
s3c_device_create: s5pv210-uart res 3 => c08a72b4 = 00000400 00000015..00000015
s3c_device_create: device s5pv210-uart.2, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a73e0 = 00000200 e2900800..e2900bff
s3c_device_create: s5pv210-uart res 1 => c08a73fc = 00000400 00000018..00000018
s3c_device_create: s5pv210-uart res 2 => c08a7418 = 00000400 0000001a..0000001a
s3c_device_create: s5pv210-uart res 3 => c08a7434 = 00000400 00000019..00000019
s3c_device_create: device s5pv210-uart.3, template c0021814, #res 4
s3c_device_create: s5pv210-uart res 0 => c08a7560 = 00000200 e2900c00..e2900fff
s3c_device_create: s5pv210-uart res 1 => c08a757c = 00000400 0000001c..0000001c
s3c_device_create: s5pv210-uart res 2 => c08a7598 = 00000400 0000001e..0000001e
s3c_device_create: s5pv210-uart res 3 => c08a75b4 = 00000400 0000001d..0000001d

s3c_device_create: device s3c2440-i2c.0, template c00219a4, #res 2
s3c_device_create: s3c2440-i2c res 0 => dfc02ee0 = 00000200 e1800000..e1800fff
s3c_device_create: s3c2440-i2c res 1 => dfc02efc = 00000400 0000004e..0000004e
s3c_device_create: s3c2440-i2c pdata => dfcb6bc0 (24 bytes)
s3c_device_create: device s3c-fb.-1, template c002191c, #res 4
s3c_device_create: s3c-fb res 0 => dfc1d6e0 = 00000200 f8000000..f8003fff
s3c_device_create: s3c-fb res 1 => dfc1d6fc = 00000400 00000061..00000061
s3c_device_create: s3c-fb res 2 => dfc1d718 = 00000400 00000060..00000060
s3c_device_create: s3c-fb res 3 => dfc1d734 = 00000400 00000062..00000062
s3c_device_create: s3c-fb dma mask => ffffffff
s3c_device_create: s3c-fb pdata => dfcb6b00 (32 bytes)
s3c_device_create: device s5pc110-onenand.-1, template c00214b8, #res 2
s3c_device_create: s5pc110-onenand res 0 => dfc1d0e0 = 00000200 b0000000..b001ffff
s3c_device_create: s5pc110-onenand res 1 => dfc1d0fc = 00000200 b0600000..b06007ff
s3c_device_create: device s3c-sdhci.0, template c0021904, #res 2
s3c_device_create: s3c-sdhci res 0 => dfc1d2e0 = 00000200 eb000000..eb000fff
s3c_device_create: s3c-sdhci res 1 => dfc1d2fc = 00000400 0000005a..0000005a
s3c_device_create: s3c-sdhci dma mask => ffffffff
s3c_device_create: s3c-sdhci pdata => dfcb6e80 (40 bytes)
s3c_device_create: device s3c-sdhci.1, template c0021904, #res 2
s3c_device_create: s3c-sdhci res 0 => dfc6c2e0 = 00000200 eb100000..eb100fff
s3c_device_create: s3c-sdhci res 1 => dfc6c2fc = 00000400 0000005b..0000005b
s3c_device_create: s3c-sdhci dma mask => ffffffff
s3c_device_create: s3c-sdhci pdata => dfc68f00 (40 bytes)
s3c_device_create: device s3c-sdhci.2, template c0021904, #res 2
s3c_device_create: s3c-sdhci res 0 => dfc6c6e0 = 00000200 eb200000..eb200fff
s3c_device_create: s3c-sdhci res 1 => dfc6c6fc = 00000400 0000005c..0000005c
s3c_device_create: s3c-sdhci dma mask => ffffffff
s3c_device_create: s3c-sdhci pdata => dfc68700 (40 bytes)

This patch series has been prepared for the kgene/tmp-all-merged
(3eb7878811b8e2218cc485578f2a1ffa07152099) kernel tree (it equal to the
current Samsung for-next tree with all other required patches to make it
build):
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git tmp-all-merged

I would like to get an opinion on this solution. It is a third attempt
on the device-table. The original one, proposed by Ben Dooks, is
available on his git tree, wip-samsung-dev branch:
git://git.fluff.org/bjdooks/linux wip-samsung-dev

The second one has been proposed by Kyungmin Park. It can be found the
following thread:
http://www.spinics.net/lists/arm-kernel/msg93583.html

Best regards,
-- 
Marek Szyprowski
Samsung Poland R&D Center

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

* [PATCH 1/9] ARM: Samsung: add device-table core functions
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Add device-table framework core functions. The device-table framework
standarizes the way the Samsung platform devices are being defined and
registered. It also a first step to redesign Samsung platform in a way
that it would be possible to build a single kernel image for more than
one SoC version. The device-table framework has been initially developed
by Ben Dooks. This version has been redesigned and extended to support
platform data handling and more flexible way of rewriting device
resources (removed the limitation of only base address and irq pairs).

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/plat-samsung/Makefile                |    1 +
 arch/arm/plat-samsung/dev.c                   |  304 +++++++++++++++++++++++++
 arch/arm/plat-samsung/dev_templates.c         |   57 +++++
 arch/arm/plat-samsung/include/plat/dev-core.h |  116 ++++++++++
 arch/arm/plat-samsung/include/plat/devs.h     |  118 ++++++++++
 5 files changed, 596 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-samsung/dev.c
 create mode 100644 arch/arm/plat-samsung/dev_templates.c
 create mode 100644 arch/arm/plat-samsung/include/plat/dev-core.h

diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 4d8ff92..a14f443 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -13,6 +13,7 @@ obj-				:=
 
 obj-y				+= init.o
 obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET)   += time.o
+obj-y				+= dev.o dev_templates.o
 obj-y				+= clock.o
 obj-y				+= pwm-clock.o
 obj-y				+= gpio.o
diff --git a/arch/arm/plat-samsung/dev.c b/arch/arm/plat-samsung/dev.c
new file mode 100644
index 0000000..4c32c82
--- /dev/null
+++ b/arch/arm/plat-samsung/dev.c
@@ -0,0 +1,304 @@
+/* linux/arch/arm/plat-s3c/dev.c
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2010 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * S3C series device creation code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+#include <plat/cpu.h>
+
+/* state data */
+static struct s3c_pdev_table *pdev_table;
+static unsigned int pdev_tsize;
+
+/**
+ * s3c_device_lookup() - lookup a pdev table entry from name and index
+ * @type: The device type to find.
+ * @index: The index for the device.
+ *
+ * Find the relevant device table entry for the given @name and @index
+ * value, or return NULL if the table does not contain such an entry.
+ */
+static struct s3c_pdev_table __init *s3c_device_lookup(enum s3c_dev_type type,
+						       int index)
+{
+	struct s3c_pdev_table *table = pdev_table;
+	int nr = pdev_tsize;
+
+	for (; nr > 0; nr--, table++) {
+		if (table->type == type && table->index == index)
+			return table;
+	}
+
+	return NULL; /* not found */
+}
+
+/**
+ * s3c_device_rename - rename a device type in the device table
+ * @type: The device type to rename
+ * @name: The new name to give it
+ */
+void __init s3c_device_rename(enum s3c_dev_type type, char *name)
+{
+	struct s3c_pdev_table *ptr = pdev_table;
+	int nr = pdev_tsize;
+
+	for (; nr > 0; nr--, ptr++) {
+		if (ptr->type == type)
+			ptr->name = name;
+	}
+}
+
+void s3c_device_set_platdata(enum s3c_dev_type type, unsigned int index,
+			     void *pdata)
+{
+	struct s3c_pdev_table *pdev_tab;
+
+	pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: no entry for type %d index %d\n",
+		       __func__, type, index);
+	} else
+		pdev_tab->defpdata = pdata;
+}
+
+void __init *s3c_device_get_defplatdata(enum s3c_dev_type type,
+					unsigned int index)
+{
+	struct s3c_pdev_table *pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: no entry for type %d index %d\n",
+		       __func__, type, index);
+		return NULL;
+	}
+	return pdev_tab->defpdata;
+}
+
+/**
+ * s3c_device_create() - create a new platform device
+ * @type: The type of device to create.
+ * @index: The index of the device being created.
+ * @pdata: The platform data to add to the new device.
+ *
+ * Create and register a new platform device from the given template
+ * and platform data. Calls platform_device_register().
+ */
+struct platform_device  __init *s3c_device_create(enum s3c_dev_type type,
+						 unsigned int index,
+						 void *pdata)
+{
+	struct s3c_pdev_template *template;
+	struct s3c_pdev_table *pdev_tab;
+	struct platform_device *pdev;
+	struct resource *res_src, *res_dest;
+	unsigned int *res_remap;
+	const char *name;
+	u64 *dma_mask;
+	void *defpdata;
+	int nr_res;
+	int pdata_size;
+	int size;
+	int res;
+
+	pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: no entry for type %d index %d\n",
+		       __func__, type, index);
+		return NULL;
+	}
+
+	if (pdev_tab->dev)
+		return pdev_tab->dev;
+
+	template = pdev_tab->template;
+	if (!template)
+		template = s3c_device_find_template(type);
+	if (!template) {
+		printk(KERN_ERR "%s: no template for device type %d\n",
+		       __func__, type);
+		return NULL;
+	}
+
+	nr_res = template->nr_res;
+	pdata_size = template->pdata_size;
+	dma_mask = template->dma;
+
+	name = pdev_tab->name;
+	res_remap = pdev_tab->res;
+
+	printk(KERN_INFO "%s: device %s.%d, template %p, #res %d\n",
+	       __func__, name, index, template, nr_res);
+
+	/* allocate memory for the device */
+
+	size = sizeof(struct platform_device);
+	size += nr_res * sizeof(struct resource);
+
+	if (type != SAMSUNG_DEVICE_UART) {
+		pdev = kzalloc(size, GFP_KERNEL);
+		if (!pdev) {
+			printk(KERN_ERR "%s: no memory to create %s.%d\n",
+			       __func__, name, index);
+			return NULL;
+		}
+	} else {
+		/* we cannot allocate memory for the UARTs in the part of
+		 * the initialisation sequence we are in, so we use the
+		 * alloc_bootmem call instead.
+		 */
+
+		pdev = alloc_bootmem(size);
+		if (!pdev)
+			panic("failed to create uart device");
+	}
+
+	/* setup the basic platform device */
+
+	pdev->name = name;
+	pdev->id = index;
+	pdev->num_resources = nr_res;
+
+	/* start modifying the resources we got */
+
+	res_src = template->resources;
+	res_dest = (struct resource *)(pdev + 1);
+	pdev->resource = res_dest;
+
+	/* copy everything by default before modifying as needed */
+	memcpy(res_dest, res_src, nr_res * sizeof(struct resource));
+
+	for (res = 0; pdev_tab->res && res < nr_res; res++, res_dest++) {
+		/* process any changes. */
+		res_dest->start += res_remap[res];
+		res_dest->end += res_remap[res];
+
+		printk(KERN_INFO "%s: %s res %d => ", __func__, name, res);
+		printk("%p = %08lx %08lx..%08lx\n",
+		       res_dest, res_dest->flags,
+		       (unsigned long)res_dest->start,
+		       (unsigned long)res_dest->end);
+	}
+
+	/* check if we have any dma capability for this device and if so
+	 * declare we have both types of dma memory for it. */
+
+	if (dma_mask) {
+		printk(KERN_INFO "%s: %s dma mask => ", __func__, name);
+		printk("%llx\n", *dma_mask);
+
+		pdev->dev.coherent_dma_mask = *dma_mask;
+		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+	}
+
+	/* set user pdata (will be duplicated in the next step) */
+
+	if (pdata) {
+		if (template->pdata_set)
+			template->pdata_set(pdata, index);
+		else
+			s3c_device_set_platdata(type, index, pdata);
+	}
+
+	/* setup (default) platform data */
+
+	defpdata = pdev_tab->defpdata;
+
+	if (defpdata) {
+		void *npd = kmemdup(defpdata, pdata_size, GFP_KERNEL);
+		if (!npd)
+			printk(KERN_ERR "%s: no memory for platform data\n",
+			       __func__);
+
+		printk(KERN_INFO "%s: %s pdata => ", __func__, name);
+		printk("%p (%d bytes)\n", npd, pdata_size);
+
+		pdev->dev.platform_data = npd;
+	}
+
+	pdev_tab->dev = pdev;
+	return pdev;
+}
+
+void __init samsung_device_setparent(struct device *dev,
+				     enum s3c_dev_type type, int index)
+{
+	struct s3c_pdev_table *pdev_tab;
+
+	pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: device does not exist\n", __func__);
+		return;
+	}
+
+	if (pdev_tab->dev == NULL) {
+		printk(KERN_ERR "%s: device not created yet\n", __func__);
+		return;
+	}
+
+	dev->parent = &pdev_tab->dev->dev;
+}
+
+/**
+ * s3c_device_register() - create a new platform device from the template.
+ * @type: The type of device to create.
+ * @index: The index of the device being created.
+ *
+ * Create and register a new platform device from the given template
+ * and platform data. Calls platform_device_register().
+ */
+int __init s3c_device_register(enum s3c_dev_type type,
+			       unsigned int index, void *pdata)
+{
+	struct platform_device *pdev = s3c_device_create(type, index, pdata);
+	int res;
+
+	/* s3c_device_create() printed the relevant error messages */
+	if (!pdev)
+		return -EINVAL;
+
+	/* register the device now we've created it */
+	res = platform_device_register(pdev);
+	if (res) {
+		printk(KERN_ERR "%s: failed to register device %s.%d: %d\n",
+		       __func__, pdev->name, index, res);
+	}
+
+	return res;
+}
+
+int __init samsung_add_devices(struct s3c_devtable *table, int nr_entries)
+{
+	int count = 0;
+
+	printk(KERN_INFO "%s: table %p, %d\n", __func__, table, nr_entries);
+
+	for (; nr_entries > 0; nr_entries--, table++)
+		s3c_device_register(table->type, table->index, table->pdata);
+
+	return count;
+}
+
+void __init s3c_device_register_table(struct s3c_pdev_table *table,
+				      unsigned int nr_ent)
+{
+	/* note, we do not copy this even though we expect that the table
+	 * itself is marked __initdata as the device creation process should
+	 * be over by the time the __initdata section is discarded.
+	 */
+
+	pdev_table = table;
+	pdev_tsize = nr_ent;
+}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
new file mode 100644
index 0000000..6783bec
--- /dev/null
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -0,0 +1,57 @@
+
+/* linux/arch/arm/plat-s3c/dev_templates.c
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2010 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * S3C series device creation code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+#include <plat/cpu.h>
+
+#define TEMPLATE_ENTRY(_type, _res) \
+{	.type = (_type), \
+	.resources = (_res), \
+	.nr_res = ARRAY_SIZE(_res), \
+}
+
+/* most common template */
+struct resource s3c_std_resources_4k[] __initdata = {
+	[0] = {
+		.end = SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct s3c_pdev_template *templates[] __initdata = {
+};
+
+u64 samsung_std_dma_mask = 0xffffffffUL;
+
+struct s3c_pdev_template *s3c_device_find_template(enum s3c_dev_type type)
+{
+	int i, nr = ARRAY_SIZE(templates);
+
+	for (i = 0; i < nr; i++) {
+		struct s3c_pdev_template *ptr = templates[i];
+		if (ptr && ptr->type == type)
+			return ptr;
+	}
+
+	return NULL;
+}
diff --git a/arch/arm/plat-samsung/include/plat/dev-core.h b/arch/arm/plat-samsung/include/plat/dev-core.h
new file mode 100644
index 0000000..d3b5a88
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dev-core.h
@@ -0,0 +1,116 @@
+/* linux/include/asm-arm/plat-s3c24xx/dev-core.h
+ *
+ * Copyright (c) 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright (c) 2010 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Header file for core handling of (platform) devices.
+ *
+ * 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.
+*/
+
+/**
+ * struct s3c_pdev_template - template for device creation
+ * @type: The device type
+ * @resources: The resources array to use as a template.
+ * @nr_res: The size of the resources array pointed to by @resources.
+ * @dma: The pointer to device dma mask (if required by device)
+ * @pdata_size: The size of platform data structure used by the device.
+ * @pdata_set: The function to set platform data from the user specified one.
+ */
+struct s3c_pdev_template {
+	enum s3c_dev_type type;
+	struct resource	*resources;
+	unsigned int	 nr_res;
+	u64		*dma;
+	unsigned int	 pdata_size;
+	void		(*pdata_set)(void *pdata, int id);
+};
+
+/**
+ * s3c_device_find_template - find the template for the gived device type
+ * @type: The type value, from SAMSUNG_DEVICE_
+ */
+struct s3c_pdev_template *s3c_device_find_template(enum s3c_dev_type type);
+
+/* The most common resource definition */
+extern struct resource s3c_std_resources_4k[];
+
+/* standard DMA mask for 32bit DMA capability. */
+extern u64 samsung_std_dma_mask;
+
+
+/**
+ * S3C_MAX_RESOURCES - maximum nuimber of the resources used by devicec
+ * created by device table method.
+ */
+#define S3C_MAX_RESOURCES (6)
+
+/**
+ * struct s3c_pdev_table - per-core platform device definition table
+ * @type: The type value, from SAMSUNG_DEVICE_
+ * @name: The name of the device.
+ * @index: The index of the device, as for platform.index.
+ * @res: The resources used by the device.
+ * @defpdata: The platform data associated with this device.
+ * @template: A replacement template to use, for complicated devices.
+ * @dev: The device we created, in case it is needed again.
+ *
+ * This table is registered by the core SoC code after the detection
+ * process has been performed. It defines the various parameters that
+ * may change between SoCs, such as the base address, the IRQ and DMA
+ * channel numbers. Also SoC specific platform data can be provided
+ * this way.
+ *
+ * The purpose of this is to allow the system to be built for many
+ * different devices without the need to try and switch in different
+ * headers depending on the build process and to allow the future
+ * support of many different SoCs in the same kernel.
+ *
+ * The board code does not need to see most of this process as it
+ * should be between the core SoC detection and the device creation
+ * process.
+ *
+ * The values specific for each SoC in the resources are handled by
+ * res array. The order is important and should be the same as the
+ * order of resources entries in the pdev_template.
+ *
+ * The default platform data should be placed in __initdata to save
+ * kernel memory. Machine setup code should modify the default platform
+ * data 'in place'. The platform data is duplicated (kmemdup) once
+ * device has been created.
+ *
+ * The @template field specifies an alternate template to use if the device
+ * requires very specific resources or cannot use any of the standard
+ * templates available. If this field is used, the same process as the
+ * standard templates is used, so this field can point to __initdata.
+ */
+struct s3c_pdev_table {
+	enum s3c_dev_type type;
+	const char		*name;
+	unsigned int		 index;
+	unsigned int		 res[S3C_MAX_RESOURCES];
+	void			*defpdata;
+	struct s3c_pdev_template *template;
+	struct platform_device	*dev;
+};
+
+/**
+ * s3c_device_register_table - registers a device table in the system
+ * @table: an array of pdev_table entries with device definitions
+ * @rn_ent: number of entries to register
+ */
+extern void s3c_device_register_table(struct s3c_pdev_table *table,
+				      unsigned int nr_ent);
+
+/**
+ * s3c_device_rename - rename specified device
+ * @type: The type value, from SAMSUNG_DEVICE_
+ * @name: The new name for the device
+ *
+ * This function is usefull for machines that need to set different
+ * name for particular device, despite the default name provided
+ * by SoC device table.
+ */
+extern void s3c_device_rename(enum s3c_dev_type type, char *name);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 85f6f23..79e7564 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -9,8 +9,126 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
+
 #include <linux/platform_device.h>
 
+/**
+ * enum s3c_dev_type - samsung platform device identifier.
+ *
+ * One define per type of device supported, to indicate the type when
+ * looking through various tables. If there is the possibility of more
+ * than one of each of these, then this is handled elsewhere.
+ */
+enum s3c_dev_type {
+	SAMSUNG_DEVICE_FB,	/* newer style framebuffer S3C2443+ */
+	SAMSUNG_DEVICE_TS,
+	SAMSUNG_DEVICE_ADC,
+	SAMSUNG_DEVICE_I2C,
+	SAMSUNG_DEVICE_IIS,
+	SAMSUNG_DEVICE_LCD,
+	SAMSUNG_DEVICE_MCI,	/* s3c24xx style sd/mmc block */
+	SAMSUNG_DEVICE_RTC,
+	SAMSUNG_DEVICE_SPI,	/* s3c24xx style SPI block */
+	SAMSUNG_DEVICE_AC97,
+	SAMSUNG_DEVICE_HSPI,
+	SAMSUNG_DEVICE_OHCI,
+	SAMSUNG_DEVICE_NAND,
+	SAMSUNG_DEVICE_UART,
+	SAMSUNG_DEVICE_CAMIF,
+	SAMSUNG_DEVICE_SDHCI,
+	SAMSUNG_DEVICE_HWMON,
+	SAMSUNG_DEVICE_TIMER,	/* pwm timer block */
+	SAMSUNG_DEVICE_CAMERA,
+	SAMSUNG_DEVICE_WATCHDOG,
+	SAMSUNG_DEVICE_USBGADGET,
+	SAMSUNG_DEVICE_USB_HSOTG,
+	SAMSUNG_DEVICE_SPI_S3C64XX,
+	SAMSUNG_DEVICE_ONENAND,
+};
+
+#define SAMSUNG_DEVICE_WDT SAMSUNG_DEVICE_WATCHDOG
+#define SAMSUNG_DEVICE_SDI SAMSUNG_DEVICE_MCI
+
+/**
+ * struct s3c_devtable - device table entry for Samsung platform device
+ * @type: The type of device that is being added
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: Default platform data for the new device
+ */
+struct s3c_devtable {
+	enum s3c_dev_type	 type;
+	int			 index;
+	void			*pdata;
+};
+
+/**
+ * s3c_device_create - creates a new instance of the device.
+ * @type: The type of device that is being changed
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: New platform data for the device
+ *
+ * This call returns the pointer to the newly created instance of the
+ * device specified by the type and index pair.
+ */
+extern struct platform_device *s3c_device_create(enum s3c_dev_type type,
+						 unsigned int index,
+						 void *pdata);
+
+/**
+ * s3c_device_register - creates a new instance of the device.
+ * @type: The type of device that is being changed
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: New platform data for the device
+ *
+ * This call creates a new instance of the device specified by the type
+ * and index pair. Then it registers it to the platform bus.
+ */
+extern int s3c_device_register(enum s3c_dev_type type,
+			       unsigned int index, void *pdata);
+
+/**
+ * s3c_device_set_platdata - set platform data for specified device.
+ * @type: The type of device that is being changed
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: New platform data for the device
+ */
+extern void s3c_device_set_platdata(enum s3c_dev_type type,
+				    unsigned int index,
+				    void *pdata);
+
+/**
+ * s3c_device_get_defplatdata - get a pointer to the default platform data.
+ * @type: The type of device that is being examined
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ *
+ * This call returns a pointer to the device's default platform data. All
+ * required changes should be done 'in place', on the original platform
+ * data. Each device instance has its own default platform data. The
+ * platform data will be copied to memory on the device registration.
+ */
+extern void *s3c_device_get_defplatdata(enum s3c_dev_type type,
+				    unsigned int index);
+
+/**
+ * samsung_devices_add - add devices from the given device table.
+ * @devs: The device table to add devices from.
+ * @nr_devs: The number of table entries in @devs.
+ */
+extern int samsung_add_devices(struct s3c_devtable *devs, int nr_devs);
+
+/**
+ * samsung_device_setparent - set device's parent from given device
+ * @dev: The device to set the parent of.
+ * @type: The device type
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ *
+ * Set the given device's parent to the platform device that was created
+ * during the initialisation process (since we do not have direct pointers
+ * to the platform device structures anymore).
+ */
+extern void samsung_device_setparent(struct device *dev,
+				     enum s3c_dev_type type, int index);
+
 struct s3c24xx_uart_resources {
 	struct resource		*resources;
 	unsigned long		 nr_resources;
-- 
1.7.1.569.g6f426

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

* [PATCH 1/9] ARM: Samsung: add device-table core functions
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Add device-table framework core functions. The device-table framework
standarizes the way the Samsung platform devices are being defined and
registered. It also a first step to redesign Samsung platform in a way
that it would be possible to build a single kernel image for more than
one SoC version. The device-table framework has been initially developed
by Ben Dooks. This version has been redesigned and extended to support
platform data handling and more flexible way of rewriting device
resources (removed the limitation of only base address and irq pairs).

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/plat-samsung/Makefile                |    1 +
 arch/arm/plat-samsung/dev.c                   |  304 +++++++++++++++++++++++++
 arch/arm/plat-samsung/dev_templates.c         |   57 +++++
 arch/arm/plat-samsung/include/plat/dev-core.h |  116 ++++++++++
 arch/arm/plat-samsung/include/plat/devs.h     |  118 ++++++++++
 5 files changed, 596 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-samsung/dev.c
 create mode 100644 arch/arm/plat-samsung/dev_templates.c
 create mode 100644 arch/arm/plat-samsung/include/plat/dev-core.h

diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 4d8ff92..a14f443 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -13,6 +13,7 @@ obj-				:=
 
 obj-y				+= init.o
 obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET)   += time.o
+obj-y				+= dev.o dev_templates.o
 obj-y				+= clock.o
 obj-y				+= pwm-clock.o
 obj-y				+= gpio.o
diff --git a/arch/arm/plat-samsung/dev.c b/arch/arm/plat-samsung/dev.c
new file mode 100644
index 0000000..4c32c82
--- /dev/null
+++ b/arch/arm/plat-samsung/dev.c
@@ -0,0 +1,304 @@
+/* linux/arch/arm/plat-s3c/dev.c
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2010 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * S3C series device creation code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+#include <plat/cpu.h>
+
+/* state data */
+static struct s3c_pdev_table *pdev_table;
+static unsigned int pdev_tsize;
+
+/**
+ * s3c_device_lookup() - lookup a pdev table entry from name and index
+ * @type: The device type to find.
+ * @index: The index for the device.
+ *
+ * Find the relevant device table entry for the given @name and @index
+ * value, or return NULL if the table does not contain such an entry.
+ */
+static struct s3c_pdev_table __init *s3c_device_lookup(enum s3c_dev_type type,
+						       int index)
+{
+	struct s3c_pdev_table *table = pdev_table;
+	int nr = pdev_tsize;
+
+	for (; nr > 0; nr--, table++) {
+		if (table->type == type && table->index == index)
+			return table;
+	}
+
+	return NULL; /* not found */
+}
+
+/**
+ * s3c_device_rename - rename a device type in the device table
+ * @type: The device type to rename
+ * @name: The new name to give it
+ */
+void __init s3c_device_rename(enum s3c_dev_type type, char *name)
+{
+	struct s3c_pdev_table *ptr = pdev_table;
+	int nr = pdev_tsize;
+
+	for (; nr > 0; nr--, ptr++) {
+		if (ptr->type == type)
+			ptr->name = name;
+	}
+}
+
+void s3c_device_set_platdata(enum s3c_dev_type type, unsigned int index,
+			     void *pdata)
+{
+	struct s3c_pdev_table *pdev_tab;
+
+	pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: no entry for type %d index %d\n",
+		       __func__, type, index);
+	} else
+		pdev_tab->defpdata = pdata;
+}
+
+void __init *s3c_device_get_defplatdata(enum s3c_dev_type type,
+					unsigned int index)
+{
+	struct s3c_pdev_table *pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: no entry for type %d index %d\n",
+		       __func__, type, index);
+		return NULL;
+	}
+	return pdev_tab->defpdata;
+}
+
+/**
+ * s3c_device_create() - create a new platform device
+ * @type: The type of device to create.
+ * @index: The index of the device being created.
+ * @pdata: The platform data to add to the new device.
+ *
+ * Create and register a new platform device from the given template
+ * and platform data. Calls platform_device_register().
+ */
+struct platform_device  __init *s3c_device_create(enum s3c_dev_type type,
+						 unsigned int index,
+						 void *pdata)
+{
+	struct s3c_pdev_template *template;
+	struct s3c_pdev_table *pdev_tab;
+	struct platform_device *pdev;
+	struct resource *res_src, *res_dest;
+	unsigned int *res_remap;
+	const char *name;
+	u64 *dma_mask;
+	void *defpdata;
+	int nr_res;
+	int pdata_size;
+	int size;
+	int res;
+
+	pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: no entry for type %d index %d\n",
+		       __func__, type, index);
+		return NULL;
+	}
+
+	if (pdev_tab->dev)
+		return pdev_tab->dev;
+
+	template = pdev_tab->template;
+	if (!template)
+		template = s3c_device_find_template(type);
+	if (!template) {
+		printk(KERN_ERR "%s: no template for device type %d\n",
+		       __func__, type);
+		return NULL;
+	}
+
+	nr_res = template->nr_res;
+	pdata_size = template->pdata_size;
+	dma_mask = template->dma;
+
+	name = pdev_tab->name;
+	res_remap = pdev_tab->res;
+
+	printk(KERN_INFO "%s: device %s.%d, template %p, #res %d\n",
+	       __func__, name, index, template, nr_res);
+
+	/* allocate memory for the device */
+
+	size = sizeof(struct platform_device);
+	size += nr_res * sizeof(struct resource);
+
+	if (type != SAMSUNG_DEVICE_UART) {
+		pdev = kzalloc(size, GFP_KERNEL);
+		if (!pdev) {
+			printk(KERN_ERR "%s: no memory to create %s.%d\n",
+			       __func__, name, index);
+			return NULL;
+		}
+	} else {
+		/* we cannot allocate memory for the UARTs in the part of
+		 * the initialisation sequence we are in, so we use the
+		 * alloc_bootmem call instead.
+		 */
+
+		pdev = alloc_bootmem(size);
+		if (!pdev)
+			panic("failed to create uart device");
+	}
+
+	/* setup the basic platform device */
+
+	pdev->name = name;
+	pdev->id = index;
+	pdev->num_resources = nr_res;
+
+	/* start modifying the resources we got */
+
+	res_src = template->resources;
+	res_dest = (struct resource *)(pdev + 1);
+	pdev->resource = res_dest;
+
+	/* copy everything by default before modifying as needed */
+	memcpy(res_dest, res_src, nr_res * sizeof(struct resource));
+
+	for (res = 0; pdev_tab->res && res < nr_res; res++, res_dest++) {
+		/* process any changes. */
+		res_dest->start += res_remap[res];
+		res_dest->end += res_remap[res];
+
+		printk(KERN_INFO "%s: %s res %d => ", __func__, name, res);
+		printk("%p = %08lx %08lx..%08lx\n",
+		       res_dest, res_dest->flags,
+		       (unsigned long)res_dest->start,
+		       (unsigned long)res_dest->end);
+	}
+
+	/* check if we have any dma capability for this device and if so
+	 * declare we have both types of dma memory for it. */
+
+	if (dma_mask) {
+		printk(KERN_INFO "%s: %s dma mask => ", __func__, name);
+		printk("%llx\n", *dma_mask);
+
+		pdev->dev.coherent_dma_mask = *dma_mask;
+		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+	}
+
+	/* set user pdata (will be duplicated in the next step) */
+
+	if (pdata) {
+		if (template->pdata_set)
+			template->pdata_set(pdata, index);
+		else
+			s3c_device_set_platdata(type, index, pdata);
+	}
+
+	/* setup (default) platform data */
+
+	defpdata = pdev_tab->defpdata;
+
+	if (defpdata) {
+		void *npd = kmemdup(defpdata, pdata_size, GFP_KERNEL);
+		if (!npd)
+			printk(KERN_ERR "%s: no memory for platform data\n",
+			       __func__);
+
+		printk(KERN_INFO "%s: %s pdata => ", __func__, name);
+		printk("%p (%d bytes)\n", npd, pdata_size);
+
+		pdev->dev.platform_data = npd;
+	}
+
+	pdev_tab->dev = pdev;
+	return pdev;
+}
+
+void __init samsung_device_setparent(struct device *dev,
+				     enum s3c_dev_type type, int index)
+{
+	struct s3c_pdev_table *pdev_tab;
+
+	pdev_tab = s3c_device_lookup(type, index);
+	if (!pdev_tab) {
+		printk(KERN_ERR "%s: device does not exist\n", __func__);
+		return;
+	}
+
+	if (pdev_tab->dev == NULL) {
+		printk(KERN_ERR "%s: device not created yet\n", __func__);
+		return;
+	}
+
+	dev->parent = &pdev_tab->dev->dev;
+}
+
+/**
+ * s3c_device_register() - create a new platform device from the template.
+ * @type: The type of device to create.
+ * @index: The index of the device being created.
+ *
+ * Create and register a new platform device from the given template
+ * and platform data. Calls platform_device_register().
+ */
+int __init s3c_device_register(enum s3c_dev_type type,
+			       unsigned int index, void *pdata)
+{
+	struct platform_device *pdev = s3c_device_create(type, index, pdata);
+	int res;
+
+	/* s3c_device_create() printed the relevant error messages */
+	if (!pdev)
+		return -EINVAL;
+
+	/* register the device now we've created it */
+	res = platform_device_register(pdev);
+	if (res) {
+		printk(KERN_ERR "%s: failed to register device %s.%d: %d\n",
+		       __func__, pdev->name, index, res);
+	}
+
+	return res;
+}
+
+int __init samsung_add_devices(struct s3c_devtable *table, int nr_entries)
+{
+	int count = 0;
+
+	printk(KERN_INFO "%s: table %p, %d\n", __func__, table, nr_entries);
+
+	for (; nr_entries > 0; nr_entries--, table++)
+		s3c_device_register(table->type, table->index, table->pdata);
+
+	return count;
+}
+
+void __init s3c_device_register_table(struct s3c_pdev_table *table,
+				      unsigned int nr_ent)
+{
+	/* note, we do not copy this even though we expect that the table
+	 * itself is marked __initdata as the device creation process should
+	 * be over by the time the __initdata section is discarded.
+	 */
+
+	pdev_table = table;
+	pdev_tsize = nr_ent;
+}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
new file mode 100644
index 0000000..6783bec
--- /dev/null
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -0,0 +1,57 @@
+
+/* linux/arch/arm/plat-s3c/dev_templates.c
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2010 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * S3C series device creation code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+#include <plat/cpu.h>
+
+#define TEMPLATE_ENTRY(_type, _res) \
+{	.type = (_type), \
+	.resources = (_res), \
+	.nr_res = ARRAY_SIZE(_res), \
+}
+
+/* most common template */
+struct resource s3c_std_resources_4k[] __initdata = {
+	[0] = {
+		.end = SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct s3c_pdev_template *templates[] __initdata = {
+};
+
+u64 samsung_std_dma_mask = 0xffffffffUL;
+
+struct s3c_pdev_template *s3c_device_find_template(enum s3c_dev_type type)
+{
+	int i, nr = ARRAY_SIZE(templates);
+
+	for (i = 0; i < nr; i++) {
+		struct s3c_pdev_template *ptr = templates[i];
+		if (ptr && ptr->type == type)
+			return ptr;
+	}
+
+	return NULL;
+}
diff --git a/arch/arm/plat-samsung/include/plat/dev-core.h b/arch/arm/plat-samsung/include/plat/dev-core.h
new file mode 100644
index 0000000..d3b5a88
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dev-core.h
@@ -0,0 +1,116 @@
+/* linux/include/asm-arm/plat-s3c24xx/dev-core.h
+ *
+ * Copyright (c) 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright (c) 2010 Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Header file for core handling of (platform) devices.
+ *
+ * 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.
+*/
+
+/**
+ * struct s3c_pdev_template - template for device creation
+ * @type: The device type
+ * @resources: The resources array to use as a template.
+ * @nr_res: The size of the resources array pointed to by @resources.
+ * @dma: The pointer to device dma mask (if required by device)
+ * @pdata_size: The size of platform data structure used by the device.
+ * @pdata_set: The function to set platform data from the user specified one.
+ */
+struct s3c_pdev_template {
+	enum s3c_dev_type type;
+	struct resource	*resources;
+	unsigned int	 nr_res;
+	u64		*dma;
+	unsigned int	 pdata_size;
+	void		(*pdata_set)(void *pdata, int id);
+};
+
+/**
+ * s3c_device_find_template - find the template for the gived device type
+ * @type: The type value, from SAMSUNG_DEVICE_
+ */
+struct s3c_pdev_template *s3c_device_find_template(enum s3c_dev_type type);
+
+/* The most common resource definition */
+extern struct resource s3c_std_resources_4k[];
+
+/* standard DMA mask for 32bit DMA capability. */
+extern u64 samsung_std_dma_mask;
+
+
+/**
+ * S3C_MAX_RESOURCES - maximum nuimber of the resources used by devicec
+ * created by device table method.
+ */
+#define S3C_MAX_RESOURCES (6)
+
+/**
+ * struct s3c_pdev_table - per-core platform device definition table
+ * @type: The type value, from SAMSUNG_DEVICE_
+ * @name: The name of the device.
+ * @index: The index of the device, as for platform.index.
+ * @res: The resources used by the device.
+ * @defpdata: The platform data associated with this device.
+ * @template: A replacement template to use, for complicated devices.
+ * @dev: The device we created, in case it is needed again.
+ *
+ * This table is registered by the core SoC code after the detection
+ * process has been performed. It defines the various parameters that
+ * may change between SoCs, such as the base address, the IRQ and DMA
+ * channel numbers. Also SoC specific platform data can be provided
+ * this way.
+ *
+ * The purpose of this is to allow the system to be built for many
+ * different devices without the need to try and switch in different
+ * headers depending on the build process and to allow the future
+ * support of many different SoCs in the same kernel.
+ *
+ * The board code does not need to see most of this process as it
+ * should be between the core SoC detection and the device creation
+ * process.
+ *
+ * The values specific for each SoC in the resources are handled by
+ * res array. The order is important and should be the same as the
+ * order of resources entries in the pdev_template.
+ *
+ * The default platform data should be placed in __initdata to save
+ * kernel memory. Machine setup code should modify the default platform
+ * data 'in place'. The platform data is duplicated (kmemdup) once
+ * device has been created.
+ *
+ * The @template field specifies an alternate template to use if the device
+ * requires very specific resources or cannot use any of the standard
+ * templates available. If this field is used, the same process as the
+ * standard templates is used, so this field can point to __initdata.
+ */
+struct s3c_pdev_table {
+	enum s3c_dev_type type;
+	const char		*name;
+	unsigned int		 index;
+	unsigned int		 res[S3C_MAX_RESOURCES];
+	void			*defpdata;
+	struct s3c_pdev_template *template;
+	struct platform_device	*dev;
+};
+
+/**
+ * s3c_device_register_table - registers a device table in the system
+ * @table: an array of pdev_table entries with device definitions
+ * @rn_ent: number of entries to register
+ */
+extern void s3c_device_register_table(struct s3c_pdev_table *table,
+				      unsigned int nr_ent);
+
+/**
+ * s3c_device_rename - rename specified device
+ * @type: The type value, from SAMSUNG_DEVICE_
+ * @name: The new name for the device
+ *
+ * This function is usefull for machines that need to set different
+ * name for particular device, despite the default name provided
+ * by SoC device table.
+ */
+extern void s3c_device_rename(enum s3c_dev_type type, char *name);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 85f6f23..79e7564 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -9,8 +9,126 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
+
 #include <linux/platform_device.h>
 
+/**
+ * enum s3c_dev_type - samsung platform device identifier.
+ *
+ * One define per type of device supported, to indicate the type when
+ * looking through various tables. If there is the possibility of more
+ * than one of each of these, then this is handled elsewhere.
+ */
+enum s3c_dev_type {
+	SAMSUNG_DEVICE_FB,	/* newer style framebuffer S3C2443+ */
+	SAMSUNG_DEVICE_TS,
+	SAMSUNG_DEVICE_ADC,
+	SAMSUNG_DEVICE_I2C,
+	SAMSUNG_DEVICE_IIS,
+	SAMSUNG_DEVICE_LCD,
+	SAMSUNG_DEVICE_MCI,	/* s3c24xx style sd/mmc block */
+	SAMSUNG_DEVICE_RTC,
+	SAMSUNG_DEVICE_SPI,	/* s3c24xx style SPI block */
+	SAMSUNG_DEVICE_AC97,
+	SAMSUNG_DEVICE_HSPI,
+	SAMSUNG_DEVICE_OHCI,
+	SAMSUNG_DEVICE_NAND,
+	SAMSUNG_DEVICE_UART,
+	SAMSUNG_DEVICE_CAMIF,
+	SAMSUNG_DEVICE_SDHCI,
+	SAMSUNG_DEVICE_HWMON,
+	SAMSUNG_DEVICE_TIMER,	/* pwm timer block */
+	SAMSUNG_DEVICE_CAMERA,
+	SAMSUNG_DEVICE_WATCHDOG,
+	SAMSUNG_DEVICE_USBGADGET,
+	SAMSUNG_DEVICE_USB_HSOTG,
+	SAMSUNG_DEVICE_SPI_S3C64XX,
+	SAMSUNG_DEVICE_ONENAND,
+};
+
+#define SAMSUNG_DEVICE_WDT SAMSUNG_DEVICE_WATCHDOG
+#define SAMSUNG_DEVICE_SDI SAMSUNG_DEVICE_MCI
+
+/**
+ * struct s3c_devtable - device table entry for Samsung platform device
+ * @type: The type of device that is being added
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: Default platform data for the new device
+ */
+struct s3c_devtable {
+	enum s3c_dev_type	 type;
+	int			 index;
+	void			*pdata;
+};
+
+/**
+ * s3c_device_create - creates a new instance of the device.
+ * @type: The type of device that is being changed
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: New platform data for the device
+ *
+ * This call returns the pointer to the newly created instance of the
+ * device specified by the type and index pair.
+ */
+extern struct platform_device *s3c_device_create(enum s3c_dev_type type,
+						 unsigned int index,
+						 void *pdata);
+
+/**
+ * s3c_device_register - creates a new instance of the device.
+ * @type: The type of device that is being changed
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: New platform data for the device
+ *
+ * This call creates a new instance of the device specified by the type
+ * and index pair. Then it registers it to the platform bus.
+ */
+extern int s3c_device_register(enum s3c_dev_type type,
+			       unsigned int index, void *pdata);
+
+/**
+ * s3c_device_set_platdata - set platform data for specified device.
+ * @type: The type of device that is being changed
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ * @pdata: New platform data for the device
+ */
+extern void s3c_device_set_platdata(enum s3c_dev_type type,
+				    unsigned int index,
+				    void *pdata);
+
+/**
+ * s3c_device_get_defplatdata - get a pointer to the default platform data.
+ * @type: The type of device that is being examined
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ *
+ * This call returns a pointer to the device's default platform data. All
+ * required changes should be done 'in place', on the original platform
+ * data. Each device instance has its own default platform data. The
+ * platform data will be copied to memory on the device registration.
+ */
+extern void *s3c_device_get_defplatdata(enum s3c_dev_type type,
+				    unsigned int index);
+
+/**
+ * samsung_devices_add - add devices from the given device table.
+ * @devs: The device table to add devices from.
+ * @nr_devs: The number of table entries in @devs.
+ */
+extern int samsung_add_devices(struct s3c_devtable *devs, int nr_devs);
+
+/**
+ * samsung_device_setparent - set device's parent from given device
+ * @dev: The device to set the parent of.
+ * @type: The device type
+ * @index: -1 if there is only one, otherwise the index of the block 0..n
+ *
+ * Set the given device's parent to the platform device that was created
+ * during the initialisation process (since we do not have direct pointers
+ * to the platform device structures anymore).
+ */
+extern void samsung_device_setparent(struct device *dev,
+				     enum s3c_dev_type type, int index);
+
 struct s3c24xx_uart_resources {
 	struct resource		*resources;
 	unsigned long		 nr_resources;
-- 
1.7.1.569.g6f426

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

* [PATCH 2/9] ARM: S5PV210: add initial device-table
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Define the initial device-table for S5PV210 SoCs. Contains only
definitions for UART devices.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Makefile           |    1 +
 arch/arm/mach-s5pv210/cpu.c              |    1 +
 arch/arm/mach-s5pv210/dev-table.c        |   71 ++++++++++++++++++++++++++++++
 arch/arm/plat-s5p/include/plat/s5pv210.h |    1 +
 4 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5pv210/dev-table.c

diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 05048c5..6f7c13b 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -14,6 +14,7 @@ obj-				:=
 
 obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o dma.o gpiolib.o
 obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
+obj-$(CONFIG_CPU_S5PV210)	+= dev-table.o
 
 # machine support
 
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index c7e0b8a..785f011 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -87,6 +87,7 @@ static void s5pv210_sw_reset(void)
 void __init s5pv210_map_io(void)
 {
 	iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
+	s5pv210_register_devtable();
 
 	/* initialise device information early */
 	s5pv210_default_sdhci0();
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
new file mode 100644
index 0000000..396c4a7
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -0,0 +1,71 @@
+/* linux/arch/arm/mach-s5pv210/dev-table.c
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S5PV210 series device creation code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+#include <plat/cpu.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/sdhci.h>
+#include <plat/iic.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+/* note, table is not ordered */
+
+struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
+	{
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 0,
+		.res	= {
+			S5P_PA_UART0,
+			IRQ_S5P_UART_RX0, IRQ_S5P_UART_TX0, IRQ_S5P_UART_ERR0,
+		},
+	}, {
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 1,
+		.res	= {
+			S5P_PA_UART1,
+			IRQ_S5P_UART_RX1, IRQ_S5P_UART_TX1, IRQ_S5P_UART_ERR1,
+		},
+	}, {
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 2,
+		.res	= {
+			S5P_PA_UART2,
+			IRQ_S5P_UART_RX2, IRQ_S5P_UART_TX2, IRQ_S5P_UART_ERR2,
+		},
+	}, {
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 3,
+		.res	= {
+			S5P_PA_UART3,
+			IRQ_S5P_UART_RX3, IRQ_S5P_UART_TX3, IRQ_S5P_UART_ERR3,
+		},
+	},
+};
+
+void __init s5pv210_register_devtable(void)
+{
+	s3c_device_register_table(s5pv210_dev_table,
+				  ARRAY_SIZE(s5pv210_dev_table));
+}
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
index 6c93a0c..49dac0b 100644
--- a/arch/arm/plat-s5p/include/plat/s5pv210.h
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -15,6 +15,7 @@
 extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5pv210_register_clocks(void);
 extern void s5pv210_setup_clocks(void);
+extern void s5pv210_register_devtable(void);
 
 #ifdef CONFIG_CPU_S5PV210
 
-- 
1.7.1.569.g6f426

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

* [PATCH 2/9] ARM: S5PV210: add initial device-table
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Define the initial device-table for S5PV210 SoCs. Contains only
definitions for UART devices.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Makefile           |    1 +
 arch/arm/mach-s5pv210/cpu.c              |    1 +
 arch/arm/mach-s5pv210/dev-table.c        |   71 ++++++++++++++++++++++++++++++
 arch/arm/plat-s5p/include/plat/s5pv210.h |    1 +
 4 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-s5pv210/dev-table.c

diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 05048c5..6f7c13b 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -14,6 +14,7 @@ obj-				:=
 
 obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o dma.o gpiolib.o
 obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
+obj-$(CONFIG_CPU_S5PV210)	+= dev-table.o
 
 # machine support
 
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index c7e0b8a..785f011 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -87,6 +87,7 @@ static void s5pv210_sw_reset(void)
 void __init s5pv210_map_io(void)
 {
 	iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
+	s5pv210_register_devtable();
 
 	/* initialise device information early */
 	s5pv210_default_sdhci0();
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
new file mode 100644
index 0000000..396c4a7
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -0,0 +1,71 @@
+/* linux/arch/arm/mach-s5pv210/dev-table.c
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S5PV210 series device creation code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+#include <plat/cpu.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/sdhci.h>
+#include <plat/iic.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+/* note, table is not ordered */
+
+struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
+	{
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 0,
+		.res	= {
+			S5P_PA_UART0,
+			IRQ_S5P_UART_RX0, IRQ_S5P_UART_TX0, IRQ_S5P_UART_ERR0,
+		},
+	}, {
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 1,
+		.res	= {
+			S5P_PA_UART1,
+			IRQ_S5P_UART_RX1, IRQ_S5P_UART_TX1, IRQ_S5P_UART_ERR1,
+		},
+	}, {
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 2,
+		.res	= {
+			S5P_PA_UART2,
+			IRQ_S5P_UART_RX2, IRQ_S5P_UART_TX2, IRQ_S5P_UART_ERR2,
+		},
+	}, {
+		.type	= SAMSUNG_DEVICE_UART,
+		.name	= "s5pv210-uart",
+		.index	= 3,
+		.res	= {
+			S5P_PA_UART3,
+			IRQ_S5P_UART_RX3, IRQ_S5P_UART_TX3, IRQ_S5P_UART_ERR3,
+		},
+	},
+};
+
+void __init s5pv210_register_devtable(void)
+{
+	s3c_device_register_table(s5pv210_dev_table,
+				  ARRAY_SIZE(s5pv210_dev_table));
+}
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
index 6c93a0c..49dac0b 100644
--- a/arch/arm/plat-s5p/include/plat/s5pv210.h
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -15,6 +15,7 @@
 extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5pv210_register_clocks(void);
 extern void s5pv210_setup_clocks(void);
+extern void s5pv210_register_devtable(void);
 
 #ifdef CONFIG_CPU_S5PV210
 
-- 
1.7.1.569.g6f426

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

* [PATCH 3/9] ARM: S5PV210: convert uart to device-table
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Convert UART device initialization to the device-table approach. Based
on the initial work by Ben Dooks. This patch performs the conversion
only for S5PV210 SoC, the final will update all other SoCs.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Makefile            |    2 +-
 arch/arm/mach-s5pv210/init.c              |   44 ---------
 arch/arm/plat-s5p/Kconfig                 |    1 +
 arch/arm/plat-s5p/Makefile                |    1 -
 arch/arm/plat-s5p/cpu.c                   |    5 -
 arch/arm/plat-s5p/dev-uart.c              |  139 -----------------------------
 arch/arm/plat-s5p/include/plat/s5p6440.h  |    6 +-
 arch/arm/plat-s5p/include/plat/s5p6442.h  |    4 -
 arch/arm/plat-s5p/include/plat/s5pc100.h  |    3 -
 arch/arm/plat-s5p/include/plat/s5pv210.h  |    4 -
 arch/arm/plat-samsung/Kconfig             |   10 ++
 arch/arm/plat-samsung/Makefile            |    2 +
 arch/arm/plat-samsung/dev-uart-s3c24xx.c  |   37 ++++++++
 arch/arm/plat-samsung/dev-uart-s3c64xx.c  |   42 +++++++++
 arch/arm/plat-samsung/dev-uart.c          |   23 -----
 arch/arm/plat-samsung/dev_templates.c     |    4 +
 arch/arm/plat-samsung/include/plat/cpu.h  |    1 -
 arch/arm/plat-samsung/include/plat/devs.h |   10 --
 arch/arm/plat-samsung/include/plat/uart.h |   30 ++++++
 arch/arm/plat-samsung/init.c              |   28 +-----
 20 files changed, 133 insertions(+), 263 deletions(-)
 delete mode 100644 arch/arm/mach-s5pv210/init.c
 delete mode 100644 arch/arm/plat-s5p/dev-uart.c
 create mode 100644 arch/arm/plat-samsung/dev-uart-s3c24xx.c
 create mode 100644 arch/arm/plat-samsung/dev-uart-s3c64xx.c
 create mode 100644 arch/arm/plat-samsung/include/plat/uart.h

diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 6f7c13b..a854577 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -12,7 +12,7 @@ obj-				:=
 
 # Core support for S5PV210 system
 
-obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_CPU_S5PV210)	+= cpu.o clock.o dma.o gpiolib.o
 obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
 obj-$(CONFIG_CPU_S5PV210)	+= dev-table.o
 
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
deleted file mode 100644
index 4865ae2..0000000
--- a/arch/arm/mach-s5pv210/init.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/init.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s5pv210.h>
-#include <plat/regs-serial.h>
-
-static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
-	[0] = {
-		.name		= "pclk",
-		.divisor	= 1,
-		.min_baud	= 0,
-		.max_baud	= 0,
-	},
-};
-
-/* uart registration process */
-void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	struct s3c2410_uartcfg *tcfg = cfg;
-	u32 ucnt;
-
-	for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
-		if (!tcfg->clocks) {
-			tcfg->clocks = s5pv210_serial_clocks;
-			tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
-		}
-	}
-
-	s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
-}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index c6a855d..f0dd7fd 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -23,6 +23,7 @@ config PLAT_S5P
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_IRQ_VIC_TIMER
 	select SAMSUNG_IRQ_UART
+	select S3C64XX_DEV_UART
 	help
 	  Base platform code for Samsung's S5P series SoC.
 
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index b2e0296..ec5a519 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -13,7 +13,6 @@ obj-				:=
 # Core files
 
 obj-y				+= dev-pmu.o
-obj-y				+= dev-uart.o
 obj-y				+= cpu.o
 obj-y				+= clock.o
 obj-y				+= irq.o
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index b07a078..745aaf6 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -37,7 +37,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xffffff00,
 		.map_io		= s5p6440_map_io,
 		.init_clocks	= s5p6440_init_clocks,
-		.init_uarts	= s5p6440_init_uarts,
 		.init		= s5p6440_init,
 		.name		= name_s5p6440,
 	}, {
@@ -45,7 +44,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xffffff00,
 		.map_io		= s5p6442_map_io,
 		.init_clocks	= s5p6442_init_clocks,
-		.init_uarts	= s5p6442_init_uarts,
 		.init		= s5p6442_init,
 		.name		= name_s5p6442,
 	}, {
@@ -53,7 +51,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xfffff000,
 		.map_io		= s5pc100_map_io,
 		.init_clocks	= s5pc100_init_clocks,
-		.init_uarts	= s5pc100_init_uarts,
 		.init		= s5pc100_init,
 		.name		= name_s5pc100,
 	}, {
@@ -61,7 +58,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xfffff000,
 		.map_io		= s5pv210_map_io,
 		.init_clocks	= s5pv210_init_clocks,
-		.init_uarts	= s5pv210_init_uarts,
 		.init		= s5pv210_init,
 		.name		= name_s5pv210,
 	}, {
@@ -69,7 +65,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xfffff000,
 		.map_io		= s5pv310_map_io,
 		.init_clocks	= s5pv310_init_clocks,
-		.init_uarts	= s5pv310_init_uarts,
 		.init		= s5pv310_init,
 		.name		= name_s5pv310,
 	},
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c
deleted file mode 100644
index a89331e..0000000
--- a/arch/arm/plat-s5p/dev-uart.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-uart.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * Base S5P UART resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
- /* Serial port registrations */
-
-static struct resource s5p_uart0_resource[] = {
-	[0] = {
-		.start	= S5P_PA_UART0,
-		.end	= S5P_PA_UART0 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX0,
-		.end	= IRQ_S5P_UART_RX0,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX0,
-		.end	= IRQ_S5P_UART_TX0,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR0,
-		.end	= IRQ_S5P_UART_ERR0,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct resource s5p_uart1_resource[] = {
-	[0] = {
-		.start	= S5P_PA_UART1,
-		.end	= S5P_PA_UART1 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX1,
-		.end	= IRQ_S5P_UART_RX1,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX1,
-		.end	= IRQ_S5P_UART_TX1,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR1,
-		.end	= IRQ_S5P_UART_ERR1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct resource s5p_uart2_resource[] = {
-	[0] = {
-		.start	= S5P_PA_UART2,
-		.end	= S5P_PA_UART2 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX2,
-		.end	= IRQ_S5P_UART_RX2,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX2,
-		.end	= IRQ_S5P_UART_TX2,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR2,
-		.end	= IRQ_S5P_UART_ERR2,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct resource s5p_uart3_resource[] = {
-#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
-	[0] = {
-		.start	= S5P_PA_UART3,
-		.end	= S5P_PA_UART3 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX3,
-		.end	= IRQ_S5P_UART_RX3,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX3,
-		.end	= IRQ_S5P_UART_TX3,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR3,
-		.end	= IRQ_S5P_UART_ERR3,
-		.flags	= IORESOURCE_IRQ,
-	},
-#endif
-};
-
-struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
-	[0] = {
-		.resources	= s5p_uart0_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart0_resource),
-	},
-	[1] = {
-		.resources	= s5p_uart1_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart1_resource),
-	},
-	[2] = {
-		.resources	= s5p_uart2_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart2_resource),
-	},
-	[3] = {
-		.resources	= s5p_uart3_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart3_resource),
-	},
-};
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
index a4cd75a..a690fa7 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6440.h
+++ b/arch/arm/plat-s5p/include/plat/s5p6440.h
@@ -12,7 +12,8 @@
 
  /* Common init code for S5P6440 related SoCs */
 
-extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
 extern void s5p6440_register_clocks(void);
 extern void s5p6440_setup_clocks(void);
 
@@ -23,11 +24,8 @@ extern void s5p6440_init_irq(void);
 extern void s5p6440_map_io(void);
 extern void s5p6440_init_clocks(int xtal);
 
-#define s5p6440_init_uarts s5p6440_common_init_uarts
-
 #else
 #define s5p6440_init_clocks NULL
-#define s5p6440_init_uarts NULL
 #define s5p6440_map_io NULL
 #define s5p6440_init NULL
 #endif
diff --git a/arch/arm/plat-s5p/include/plat/s5p6442.h b/arch/arm/plat-s5p/include/plat/s5p6442.h
index 7b88013..1da2bb3 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6442.h
+++ b/arch/arm/plat-s5p/include/plat/s5p6442.h
@@ -12,7 +12,6 @@
 
 /* Common init code for S5P6442 related SoCs */
 
-extern void s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5p6442_register_clocks(void);
 extern void s5p6442_setup_clocks(void);
 
@@ -23,11 +22,8 @@ extern void s5p6442_init_irq(void);
 extern void s5p6442_map_io(void);
 extern void s5p6442_init_clocks(int xtal);
 
-#define s5p6442_init_uarts s5p6442_common_init_uarts
-
 #else
 #define s5p6442_init_clocks NULL
-#define s5p6442_init_uarts NULL
 #define s5p6442_map_io NULL
 #define s5p6442_init NULL
 #endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pc100.h b/arch/arm/plat-s5p/include/plat/s5pc100.h
index 5f6099d..9fed677 100644
--- a/arch/arm/plat-s5p/include/plat/s5pc100.h
+++ b/arch/arm/plat-s5p/include/plat/s5pc100.h
@@ -12,7 +12,6 @@
 
 /* Common init code for S5PC100 related SoCs */
 
-extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5pc100_register_clocks(void);
 extern void s5pc100_setup_clocks(void);
 
@@ -23,11 +22,9 @@ extern void s5pc100_init_irq(void);
 extern void s5pc100_map_io(void);
 extern void s5pc100_init_clocks(int xtal);
 
-#define s5pc100_init_uarts s5pc100_common_init_uarts
 
 #else
 #define s5pc100_init_clocks NULL
-#define s5pc100_init_uarts NULL
 #define s5pc100_map_io NULL
 #define s5pc100_init NULL
 #endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
index 49dac0b..2305fb5 100644
--- a/arch/arm/plat-s5p/include/plat/s5pv210.h
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -12,7 +12,6 @@
 
 /* Common init code for S5PV210 related SoCs */
 
-extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5pv210_register_clocks(void);
 extern void s5pv210_setup_clocks(void);
 extern void s5pv210_register_devtable(void);
@@ -24,11 +23,8 @@ extern void s5pv210_init_irq(void);
 extern void s5pv210_map_io(void);
 extern void s5pv210_init_clocks(int xtal);
 
-#define s5pv210_init_uarts s5pv210_common_init_uarts
-
 #else
 #define s5pv210_init_clocks NULL
-#define s5pv210_init_uarts NULL
 #define s5pv210_map_io NULL
 #define s5pv210_init NULL
 #endif
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 4529dd6..8f3be02 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -145,6 +145,16 @@ config S3C_ADC
 
 # device definitions to compile in
 
+config S3C24XX_DEV_UART
+	bool
+	help
+	  Compile in platform device definitions for s3c24xx style UART
+
+config S3C64XX_DEV_UART
+	bool
+	help
+	  Compile in platform device definitions for s3c64xx style UART
+
 config S3C_DEV_HSMMC
 	bool
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index a14f443..edaa083 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -33,6 +33,8 @@ obj-$(CONFIG_S3C_ADC)	+= adc.o
 
 obj-y				+= platformdata.o
 
+obj-$(CONFIG_S3C24XX_DEV_UART)	+= dev-uart-s3c24xx.o
+obj-$(CONFIG_S3C64XX_DEV_UART)	+= dev-uart-s3c64xx.o
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
 obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
diff --git a/arch/arm/plat-samsung/dev-uart-s3c24xx.c b/arch/arm/plat-samsung/dev-uart-s3c24xx.c
new file mode 100644
index 0000000..5c3fbc0
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-uart-s3c24xx.c
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/gfp.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+
+static struct resource template_uart[] __initdata = {
+	[0] = {
+		.end = SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.end = 3,  /* UARTS have three IRQs */
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct s3c_pdev_template s3c24xx_aurt_template __initdata = {
+	.type = SAMSUNG_DEVICE_UART,
+	.resources = resources_uart,
+	.nr_res = ARRAY_SIZE(resources_uart),
+};
diff --git a/arch/arm/plat-samsung/dev-uart-s3c64xx.c b/arch/arm/plat-samsung/dev-uart-s3c64xx.c
new file mode 100644
index 0000000..9bb2807
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-uart-s3c64xx.c
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/gfp.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+
+static struct resource resources_uart_s3c64xx[4] __initdata = {
+	[0] = {
+		.end = SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+struct s3c_pdev_template s3c64xx_uart_template __initdata = {
+	.type = SAMSUNG_DEVICE_UART,
+	.resources = resources_uart_s3c64xx,
+	.nr_res = ARRAY_SIZE(resources_uart_s3c64xx),
+};
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
index 3776cd9..3d69a7b 100644
--- a/arch/arm/plat-samsung/dev-uart.c
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -17,28 +17,5 @@
 
 /* uart devices */
 
-static struct platform_device s3c24xx_uart_device0 = {
-	.id		= 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
-	.id		= 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
-	.id		= 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
-	.id		= 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
-	&s3c24xx_uart_device0,
-	&s3c24xx_uart_device1,
-	&s3c24xx_uart_device2,
-	&s3c24xx_uart_device3,
-};
-
 struct platform_device *s3c24xx_uart_devs[4] = {
 };
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index 6783bec..dcf8c0e 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -21,6 +21,8 @@
 #include <plat/dev-core.h>
 #include <plat/cpu.h>
 
+#include <plat/uart.h>
+
 #define TEMPLATE_ENTRY(_type, _res) \
 {	.type = (_type), \
 	.resources = (_res), \
@@ -39,6 +41,8 @@ struct resource s3c_std_resources_4k[] __initdata = {
 };
 
 static struct s3c_pdev_template *templates[] __initdata = {
+	s3c24xx_uart_template_p,
+	s3c64xx_uart_template_p,
 };
 
 u64 samsung_std_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 6412933..a6679c4 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -35,7 +35,6 @@ struct cpu_table {
 	unsigned long	idcode;
 	unsigned long	idmask;
 	void		(*map_io)(void);
-	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
 	void		(*init_clocks)(int xtal);
 	int		(*init)(void);
 	const char	*name;
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 79e7564..aa6a248 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -129,17 +129,7 @@ extern int samsung_add_devices(struct s3c_devtable *devs, int nr_devs);
 extern void samsung_device_setparent(struct device *dev,
 				     enum s3c_dev_type type, int index);
 
-struct s3c24xx_uart_resources {
-	struct resource		*resources;
-	unsigned long		 nr_resources;
-};
-
-extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
-extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
-extern struct s3c24xx_uart_resources s5p_uart_resources[];
-
 extern struct platform_device *s3c24xx_uart_devs[];
-extern struct platform_device *s3c24xx_uart_src[];
 
 extern struct platform_device s3c_device_timer[];
 
diff --git a/arch/arm/plat-samsung/include/plat/uart.h b/arch/arm/plat-samsung/include/plat/uart.h
new file mode 100644
index 0000000..2a149e7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/uart.h
@@ -0,0 +1,30 @@
+/* arch/arm/plat-s3c/include/plat/iic.h
+ *
+ * Copyright 2004-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - I2C Controller platform_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UART_H
+#define __ASM_ARCH_UART_H __FILE__
+
+#ifdef CONFIG_S3C64XX_DEV_UART
+extern struct s3c_pdev_template s3c64xx_uart_template;
+#define s3c64xx_uart_template_p (&s3c64xx_uart_template)
+#else
+#define s3c64xx_uart_template_p NULL
+#endif
+
+#ifdef CONFIG_S3C24XX_DEV_UART
+extern struct s3c_pdev_template s3c24xx_uart_template;
+#define s3c24xx_uart_template_p (&s3c24xx_uart_template)
+#else
+#define s3c24xx_uart_template_p NULL
+#endif
+
+#endif /* __ASM_ARCH_UART_H */
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
index 6790edf..42b1c33 100644
--- a/arch/arm/plat-samsung/init.c
+++ b/arch/arm/plat-samsung/init.c
@@ -26,6 +26,7 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/clock.h>
+#include <plat/dev-core.h>
 
 #include <plat/regs-serial.h>
 
@@ -100,46 +101,25 @@ static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
  * This also fills in the array passed to the serial driver for the
  * early initialisation of the console.
 */
-
-void __init s3c24xx_init_uartdevs(char *name,
-				  struct s3c24xx_uart_resources *res,
-				  struct s3c2410_uartcfg *cfg, int no)
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
 	struct platform_device *platdev;
 	struct s3c2410_uartcfg *cfgptr = uart_cfgs;
-	struct s3c24xx_uart_resources *resp;
 	int uart;
 
 	memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
 
 	for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
-		platdev = s3c24xx_uart_src[cfgptr->hwport];
-
-		resp = res + cfgptr->hwport;
+		platdev = s3c_device_create(SAMSUNG_DEVICE_UART,
+					    cfgptr->hwport, NULL);
 
 		s3c24xx_uart_devs[uart] = platdev;
-
-		platdev->name = name;
-		platdev->resource = resp->resources;
-		platdev->num_resources = resp->nr_resources;
-
 		platdev->dev.platform_data = cfgptr;
 	}
 
 	nr_uarts = no;
 }
 
-void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	if (cpu == NULL)
-		return;
-
-	if (cpu->init_uarts == NULL) {
-		printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
-	} else
-		(cpu->init_uarts)(cfg, no);
-}
-
 static int __init s3c_arch_init(void)
 {
 	int ret;
-- 
1.7.1.569.g6f426

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

* [PATCH 3/9] ARM: S5PV210: convert uart to device-table
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Convert UART device initialization to the device-table approach. Based
on the initial work by Ben Dooks. This patch performs the conversion
only for S5PV210 SoC, the final will update all other SoCs.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Makefile            |    2 +-
 arch/arm/mach-s5pv210/init.c              |   44 ---------
 arch/arm/plat-s5p/Kconfig                 |    1 +
 arch/arm/plat-s5p/Makefile                |    1 -
 arch/arm/plat-s5p/cpu.c                   |    5 -
 arch/arm/plat-s5p/dev-uart.c              |  139 -----------------------------
 arch/arm/plat-s5p/include/plat/s5p6440.h  |    6 +-
 arch/arm/plat-s5p/include/plat/s5p6442.h  |    4 -
 arch/arm/plat-s5p/include/plat/s5pc100.h  |    3 -
 arch/arm/plat-s5p/include/plat/s5pv210.h  |    4 -
 arch/arm/plat-samsung/Kconfig             |   10 ++
 arch/arm/plat-samsung/Makefile            |    2 +
 arch/arm/plat-samsung/dev-uart-s3c24xx.c  |   37 ++++++++
 arch/arm/plat-samsung/dev-uart-s3c64xx.c  |   42 +++++++++
 arch/arm/plat-samsung/dev-uart.c          |   23 -----
 arch/arm/plat-samsung/dev_templates.c     |    4 +
 arch/arm/plat-samsung/include/plat/cpu.h  |    1 -
 arch/arm/plat-samsung/include/plat/devs.h |   10 --
 arch/arm/plat-samsung/include/plat/uart.h |   30 ++++++
 arch/arm/plat-samsung/init.c              |   28 +-----
 20 files changed, 133 insertions(+), 263 deletions(-)
 delete mode 100644 arch/arm/mach-s5pv210/init.c
 delete mode 100644 arch/arm/plat-s5p/dev-uart.c
 create mode 100644 arch/arm/plat-samsung/dev-uart-s3c24xx.c
 create mode 100644 arch/arm/plat-samsung/dev-uart-s3c64xx.c
 create mode 100644 arch/arm/plat-samsung/include/plat/uart.h

diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 6f7c13b..a854577 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -12,7 +12,7 @@ obj-				:=
 
 # Core support for S5PV210 system
 
-obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_CPU_S5PV210)	+= cpu.o clock.o dma.o gpiolib.o
 obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
 obj-$(CONFIG_CPU_S5PV210)	+= dev-table.o
 
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
deleted file mode 100644
index 4865ae2..0000000
--- a/arch/arm/mach-s5pv210/init.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/init.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/serial_core.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/s5pv210.h>
-#include <plat/regs-serial.h>
-
-static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
-	[0] = {
-		.name		= "pclk",
-		.divisor	= 1,
-		.min_baud	= 0,
-		.max_baud	= 0,
-	},
-};
-
-/* uart registration process */
-void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	struct s3c2410_uartcfg *tcfg = cfg;
-	u32 ucnt;
-
-	for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
-		if (!tcfg->clocks) {
-			tcfg->clocks = s5pv210_serial_clocks;
-			tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
-		}
-	}
-
-	s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
-}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index c6a855d..f0dd7fd 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -23,6 +23,7 @@ config PLAT_S5P
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_IRQ_VIC_TIMER
 	select SAMSUNG_IRQ_UART
+	select S3C64XX_DEV_UART
 	help
 	  Base platform code for Samsung's S5P series SoC.
 
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index b2e0296..ec5a519 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -13,7 +13,6 @@ obj-				:=
 # Core files
 
 obj-y				+= dev-pmu.o
-obj-y				+= dev-uart.o
 obj-y				+= cpu.o
 obj-y				+= clock.o
 obj-y				+= irq.o
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index b07a078..745aaf6 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -37,7 +37,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xffffff00,
 		.map_io		= s5p6440_map_io,
 		.init_clocks	= s5p6440_init_clocks,
-		.init_uarts	= s5p6440_init_uarts,
 		.init		= s5p6440_init,
 		.name		= name_s5p6440,
 	}, {
@@ -45,7 +44,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xffffff00,
 		.map_io		= s5p6442_map_io,
 		.init_clocks	= s5p6442_init_clocks,
-		.init_uarts	= s5p6442_init_uarts,
 		.init		= s5p6442_init,
 		.name		= name_s5p6442,
 	}, {
@@ -53,7 +51,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xfffff000,
 		.map_io		= s5pc100_map_io,
 		.init_clocks	= s5pc100_init_clocks,
-		.init_uarts	= s5pc100_init_uarts,
 		.init		= s5pc100_init,
 		.name		= name_s5pc100,
 	}, {
@@ -61,7 +58,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xfffff000,
 		.map_io		= s5pv210_map_io,
 		.init_clocks	= s5pv210_init_clocks,
-		.init_uarts	= s5pv210_init_uarts,
 		.init		= s5pv210_init,
 		.name		= name_s5pv210,
 	}, {
@@ -69,7 +65,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idmask		= 0xfffff000,
 		.map_io		= s5pv310_map_io,
 		.init_clocks	= s5pv310_init_clocks,
-		.init_uarts	= s5pv310_init_uarts,
 		.init		= s5pv310_init,
 		.name		= name_s5pv310,
 	},
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c
deleted file mode 100644
index a89331e..0000000
--- a/arch/arm/plat-s5p/dev-uart.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* linux/arch/arm/plat-s5p/dev-uart.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * Base S5P UART resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
- /* Serial port registrations */
-
-static struct resource s5p_uart0_resource[] = {
-	[0] = {
-		.start	= S5P_PA_UART0,
-		.end	= S5P_PA_UART0 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX0,
-		.end	= IRQ_S5P_UART_RX0,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX0,
-		.end	= IRQ_S5P_UART_TX0,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR0,
-		.end	= IRQ_S5P_UART_ERR0,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct resource s5p_uart1_resource[] = {
-	[0] = {
-		.start	= S5P_PA_UART1,
-		.end	= S5P_PA_UART1 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX1,
-		.end	= IRQ_S5P_UART_RX1,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX1,
-		.end	= IRQ_S5P_UART_TX1,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR1,
-		.end	= IRQ_S5P_UART_ERR1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct resource s5p_uart2_resource[] = {
-	[0] = {
-		.start	= S5P_PA_UART2,
-		.end	= S5P_PA_UART2 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX2,
-		.end	= IRQ_S5P_UART_RX2,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX2,
-		.end	= IRQ_S5P_UART_TX2,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR2,
-		.end	= IRQ_S5P_UART_ERR2,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct resource s5p_uart3_resource[] = {
-#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
-	[0] = {
-		.start	= S5P_PA_UART3,
-		.end	= S5P_PA_UART3 + S5P_SZ_UART,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_S5P_UART_RX3,
-		.end	= IRQ_S5P_UART_RX3,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= IRQ_S5P_UART_TX3,
-		.end	= IRQ_S5P_UART_TX3,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= IRQ_S5P_UART_ERR3,
-		.end	= IRQ_S5P_UART_ERR3,
-		.flags	= IORESOURCE_IRQ,
-	},
-#endif
-};
-
-struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
-	[0] = {
-		.resources	= s5p_uart0_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart0_resource),
-	},
-	[1] = {
-		.resources	= s5p_uart1_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart1_resource),
-	},
-	[2] = {
-		.resources	= s5p_uart2_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart2_resource),
-	},
-	[3] = {
-		.resources	= s5p_uart3_resource,
-		.nr_resources	= ARRAY_SIZE(s5p_uart3_resource),
-	},
-};
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
index a4cd75a..a690fa7 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6440.h
+++ b/arch/arm/plat-s5p/include/plat/s5p6440.h
@@ -12,7 +12,8 @@
 
  /* Common init code for S5P6440 related SoCs */
 
-extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
 extern void s5p6440_register_clocks(void);
 extern void s5p6440_setup_clocks(void);
 
@@ -23,11 +24,8 @@ extern void s5p6440_init_irq(void);
 extern void s5p6440_map_io(void);
 extern void s5p6440_init_clocks(int xtal);
 
-#define s5p6440_init_uarts s5p6440_common_init_uarts
-
 #else
 #define s5p6440_init_clocks NULL
-#define s5p6440_init_uarts NULL
 #define s5p6440_map_io NULL
 #define s5p6440_init NULL
 #endif
diff --git a/arch/arm/plat-s5p/include/plat/s5p6442.h b/arch/arm/plat-s5p/include/plat/s5p6442.h
index 7b88013..1da2bb3 100644
--- a/arch/arm/plat-s5p/include/plat/s5p6442.h
+++ b/arch/arm/plat-s5p/include/plat/s5p6442.h
@@ -12,7 +12,6 @@
 
 /* Common init code for S5P6442 related SoCs */
 
-extern void s5p6442_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5p6442_register_clocks(void);
 extern void s5p6442_setup_clocks(void);
 
@@ -23,11 +22,8 @@ extern void s5p6442_init_irq(void);
 extern void s5p6442_map_io(void);
 extern void s5p6442_init_clocks(int xtal);
 
-#define s5p6442_init_uarts s5p6442_common_init_uarts
-
 #else
 #define s5p6442_init_clocks NULL
-#define s5p6442_init_uarts NULL
 #define s5p6442_map_io NULL
 #define s5p6442_init NULL
 #endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pc100.h b/arch/arm/plat-s5p/include/plat/s5pc100.h
index 5f6099d..9fed677 100644
--- a/arch/arm/plat-s5p/include/plat/s5pc100.h
+++ b/arch/arm/plat-s5p/include/plat/s5pc100.h
@@ -12,7 +12,6 @@
 
 /* Common init code for S5PC100 related SoCs */
 
-extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5pc100_register_clocks(void);
 extern void s5pc100_setup_clocks(void);
 
@@ -23,11 +22,9 @@ extern void s5pc100_init_irq(void);
 extern void s5pc100_map_io(void);
 extern void s5pc100_init_clocks(int xtal);
 
-#define s5pc100_init_uarts s5pc100_common_init_uarts
 
 #else
 #define s5pc100_init_clocks NULL
-#define s5pc100_init_uarts NULL
 #define s5pc100_map_io NULL
 #define s5pc100_init NULL
 #endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
index 49dac0b..2305fb5 100644
--- a/arch/arm/plat-s5p/include/plat/s5pv210.h
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -12,7 +12,6 @@
 
 /* Common init code for S5PV210 related SoCs */
 
-extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s5pv210_register_clocks(void);
 extern void s5pv210_setup_clocks(void);
 extern void s5pv210_register_devtable(void);
@@ -24,11 +23,8 @@ extern void s5pv210_init_irq(void);
 extern void s5pv210_map_io(void);
 extern void s5pv210_init_clocks(int xtal);
 
-#define s5pv210_init_uarts s5pv210_common_init_uarts
-
 #else
 #define s5pv210_init_clocks NULL
-#define s5pv210_init_uarts NULL
 #define s5pv210_map_io NULL
 #define s5pv210_init NULL
 #endif
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 4529dd6..8f3be02 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -145,6 +145,16 @@ config S3C_ADC
 
 # device definitions to compile in
 
+config S3C24XX_DEV_UART
+	bool
+	help
+	  Compile in platform device definitions for s3c24xx style UART
+
+config S3C64XX_DEV_UART
+	bool
+	help
+	  Compile in platform device definitions for s3c64xx style UART
+
 config S3C_DEV_HSMMC
 	bool
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index a14f443..edaa083 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -33,6 +33,8 @@ obj-$(CONFIG_S3C_ADC)	+= adc.o
 
 obj-y				+= platformdata.o
 
+obj-$(CONFIG_S3C24XX_DEV_UART)	+= dev-uart-s3c24xx.o
+obj-$(CONFIG_S3C64XX_DEV_UART)	+= dev-uart-s3c64xx.o
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
 obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
diff --git a/arch/arm/plat-samsung/dev-uart-s3c24xx.c b/arch/arm/plat-samsung/dev-uart-s3c24xx.c
new file mode 100644
index 0000000..5c3fbc0
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-uart-s3c24xx.c
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/gfp.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+
+static struct resource template_uart[] __initdata = {
+	[0] = {
+		.end = SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.end = 3,  /* UARTS have three IRQs */
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct s3c_pdev_template s3c24xx_aurt_template __initdata = {
+	.type = SAMSUNG_DEVICE_UART,
+	.resources = resources_uart,
+	.nr_res = ARRAY_SIZE(resources_uart),
+};
diff --git a/arch/arm/plat-samsung/dev-uart-s3c64xx.c b/arch/arm/plat-samsung/dev-uart-s3c64xx.c
new file mode 100644
index 0000000..9bb2807
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-uart-s3c64xx.c
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/gfp.h>
+
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+
+static struct resource resources_uart_s3c64xx[4] __initdata = {
+	[0] = {
+		.end = SZ_1K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.flags = IORESOURCE_IRQ,
+	},
+	[3] = {
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+struct s3c_pdev_template s3c64xx_uart_template __initdata = {
+	.type = SAMSUNG_DEVICE_UART,
+	.resources = resources_uart_s3c64xx,
+	.nr_res = ARRAY_SIZE(resources_uart_s3c64xx),
+};
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
index 3776cd9..3d69a7b 100644
--- a/arch/arm/plat-samsung/dev-uart.c
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -17,28 +17,5 @@
 
 /* uart devices */
 
-static struct platform_device s3c24xx_uart_device0 = {
-	.id		= 0,
-};
-
-static struct platform_device s3c24xx_uart_device1 = {
-	.id		= 1,
-};
-
-static struct platform_device s3c24xx_uart_device2 = {
-	.id		= 2,
-};
-
-static struct platform_device s3c24xx_uart_device3 = {
-	.id		= 3,
-};
-
-struct platform_device *s3c24xx_uart_src[4] = {
-	&s3c24xx_uart_device0,
-	&s3c24xx_uart_device1,
-	&s3c24xx_uart_device2,
-	&s3c24xx_uart_device3,
-};
-
 struct platform_device *s3c24xx_uart_devs[4] = {
 };
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index 6783bec..dcf8c0e 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -21,6 +21,8 @@
 #include <plat/dev-core.h>
 #include <plat/cpu.h>
 
+#include <plat/uart.h>
+
 #define TEMPLATE_ENTRY(_type, _res) \
 {	.type = (_type), \
 	.resources = (_res), \
@@ -39,6 +41,8 @@ struct resource s3c_std_resources_4k[] __initdata = {
 };
 
 static struct s3c_pdev_template *templates[] __initdata = {
+	s3c24xx_uart_template_p,
+	s3c64xx_uart_template_p,
 };
 
 u64 samsung_std_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 6412933..a6679c4 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -35,7 +35,6 @@ struct cpu_table {
 	unsigned long	idcode;
 	unsigned long	idmask;
 	void		(*map_io)(void);
-	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
 	void		(*init_clocks)(int xtal);
 	int		(*init)(void);
 	const char	*name;
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 79e7564..aa6a248 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -129,17 +129,7 @@ extern int samsung_add_devices(struct s3c_devtable *devs, int nr_devs);
 extern void samsung_device_setparent(struct device *dev,
 				     enum s3c_dev_type type, int index);
 
-struct s3c24xx_uart_resources {
-	struct resource		*resources;
-	unsigned long		 nr_resources;
-};
-
-extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
-extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
-extern struct s3c24xx_uart_resources s5p_uart_resources[];
-
 extern struct platform_device *s3c24xx_uart_devs[];
-extern struct platform_device *s3c24xx_uart_src[];
 
 extern struct platform_device s3c_device_timer[];
 
diff --git a/arch/arm/plat-samsung/include/plat/uart.h b/arch/arm/plat-samsung/include/plat/uart.h
new file mode 100644
index 0000000..2a149e7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/uart.h
@@ -0,0 +1,30 @@
+/* arch/arm/plat-s3c/include/plat/iic.h
+ *
+ * Copyright 2004-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - I2C Controller platform_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UART_H
+#define __ASM_ARCH_UART_H __FILE__
+
+#ifdef CONFIG_S3C64XX_DEV_UART
+extern struct s3c_pdev_template s3c64xx_uart_template;
+#define s3c64xx_uart_template_p (&s3c64xx_uart_template)
+#else
+#define s3c64xx_uart_template_p NULL
+#endif
+
+#ifdef CONFIG_S3C24XX_DEV_UART
+extern struct s3c_pdev_template s3c24xx_uart_template;
+#define s3c24xx_uart_template_p (&s3c24xx_uart_template)
+#else
+#define s3c24xx_uart_template_p NULL
+#endif
+
+#endif /* __ASM_ARCH_UART_H */
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
index 6790edf..42b1c33 100644
--- a/arch/arm/plat-samsung/init.c
+++ b/arch/arm/plat-samsung/init.c
@@ -26,6 +26,7 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/clock.h>
+#include <plat/dev-core.h>
 
 #include <plat/regs-serial.h>
 
@@ -100,46 +101,25 @@ static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
  * This also fills in the array passed to the serial driver for the
  * early initialisation of the console.
 */
-
-void __init s3c24xx_init_uartdevs(char *name,
-				  struct s3c24xx_uart_resources *res,
-				  struct s3c2410_uartcfg *cfg, int no)
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
 	struct platform_device *platdev;
 	struct s3c2410_uartcfg *cfgptr = uart_cfgs;
-	struct s3c24xx_uart_resources *resp;
 	int uart;
 
 	memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
 
 	for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
-		platdev = s3c24xx_uart_src[cfgptr->hwport];
-
-		resp = res + cfgptr->hwport;
+		platdev = s3c_device_create(SAMSUNG_DEVICE_UART,
+					    cfgptr->hwport, NULL);
 
 		s3c24xx_uart_devs[uart] = platdev;
-
-		platdev->name = name;
-		platdev->resource = resp->resources;
-		platdev->num_resources = resp->nr_resources;
-
 		platdev->dev.platform_data = cfgptr;
 	}
 
 	nr_uarts = no;
 }
 
-void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	if (cpu == NULL)
-		return;
-
-	if (cpu->init_uarts == NULL) {
-		printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
-	} else
-		(cpu->init_uarts)(cfg, no);
-}
-
 static int __init s3c_arch_init(void)
 {
 	int ret;
-- 
1.7.1.569.g6f426

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

* [PATCH 4/9] ARM: S5PV210: add support for device-table on Aquila&Goni
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Add initial, empty device-table arrays, they will be populated later.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/mach-aquila.c |    4 ++++
 arch/arm/mach-s5pv210/mach-goni.c   |    4 ++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index e412664..7989932 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -488,6 +488,9 @@ static struct platform_device *aquila_devices[] __initdata = {
 	&s5p_device_fimc2,
 };
 
+static struct s3c_devtable aquila_devtable[] __initdata = {
+};
+
 static void __init aquila_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -512,6 +515,7 @@ static void __init aquila_machine_init(void)
 	s3c_fb_set_platdata(&aquila_lcd_pdata);
 
 	platform_add_devices(aquila_devices, ARRAY_SIZE(aquila_devices));
+	samsung_add_devices(aquila_devtable, ARRAY_SIZE(aquila_devtable));
 }
 
 MACHINE_START(AQUILA, "Aquila")
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 53754d7..6f555cf 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -467,6 +467,9 @@ static struct platform_device *goni_devices[] __initdata = {
 	&s3c_device_hsmmc2,
 };
 
+static struct s3c_devtable goni_devtable[] __initdata = {
+};
+
 static void __init goni_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -487,6 +490,7 @@ static void __init goni_machine_init(void)
 	s3c_fb_set_platdata(&goni_lcd_pdata);
 
 	platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
+	samsung_add_devices(goni_devtable, ARRAY_SIZE(goni_devtable));
 }
 
 MACHINE_START(GONI, "GONI")
-- 
1.7.1.569.g6f426

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

* [PATCH 4/9] ARM: S5PV210: add support for device-table on Aquila&Goni
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial, empty device-table arrays, they will be populated later.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/mach-aquila.c |    4 ++++
 arch/arm/mach-s5pv210/mach-goni.c   |    4 ++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index e412664..7989932 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -488,6 +488,9 @@ static struct platform_device *aquila_devices[] __initdata = {
 	&s5p_device_fimc2,
 };
 
+static struct s3c_devtable aquila_devtable[] __initdata = {
+};
+
 static void __init aquila_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -512,6 +515,7 @@ static void __init aquila_machine_init(void)
 	s3c_fb_set_platdata(&aquila_lcd_pdata);
 
 	platform_add_devices(aquila_devices, ARRAY_SIZE(aquila_devices));
+	samsung_add_devices(aquila_devtable, ARRAY_SIZE(aquila_devtable));
 }
 
 MACHINE_START(AQUILA, "Aquila")
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 53754d7..6f555cf 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -467,6 +467,9 @@ static struct platform_device *goni_devices[] __initdata = {
 	&s3c_device_hsmmc2,
 };
 
+static struct s3c_devtable goni_devtable[] __initdata = {
+};
+
 static void __init goni_map_io(void)
 {
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -487,6 +490,7 @@ static void __init goni_machine_init(void)
 	s3c_fb_set_platdata(&goni_lcd_pdata);
 
 	platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
+	samsung_add_devices(goni_devtable, ARRAY_SIZE(goni_devtable));
 }
 
 MACHINE_START(GONI, "GONI")
-- 
1.7.1.569.g6f426

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

* [PATCH 5/9] ARM: S5PV210: convert OneNAND to device-table
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Convert OneNAND platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig       |    2 -
 arch/arm/mach-s5pv210/Makefile      |    1 -
 arch/arm/mach-s5pv210/dev-onenand.c |   55 -----------------------------------
 arch/arm/mach-s5pv210/dev-table.c   |   24 +++++++++++++++
 arch/arm/mach-s5pv210/mach-aquila.c |    2 +-
 arch/arm/mach-s5pv210/mach-goni.c   |    2 +-
 6 files changed, 26 insertions(+), 60 deletions(-)
 delete mode 100644 arch/arm/mach-s5pv210/dev-onenand.c

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index d3a3895..680b55b 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -71,7 +71,6 @@ config MACH_AQUILA
 	select S3C_DEV_HSMMC
 	select S3C_DEV_HSMMC1
 	select S3C_DEV_HSMMC2
-	select S5PC110_DEV_ONENAND
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_SDHCI
 	help
@@ -88,7 +87,6 @@ config MACH_GONI
 	select S3C_DEV_HSMMC
 	select S3C_DEV_HSMMC1
 	select S3C_DEV_HSMMC2
-	select S5PC110_DEV_ONENAND
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_SDHCI
 	help
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index a854577..23bde19 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_MACH_GONI)		+= mach-goni.o
 
 obj-y				+= dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
-obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o
 
 obj-$(CONFIG_S5PV210_SETUP_FB_24BPP)	+= setup-fb-24bpp.o
 obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
diff --git a/arch/arm/mach-s5pv210/dev-onenand.c b/arch/arm/mach-s5pv210/dev-onenand.c
deleted file mode 100644
index f8ede33..0000000
--- a/arch/arm/mach-s5pv210/dev-onenand.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * linux/arch/arm/mach-s5pv210/dev-onenand.c
- *
- *  Copyright (c) 2008-2010 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S5PC110 series device definition for OneNAND devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-static struct resource s5pc110_onenand_resources[] = {
-	[0] = {
-		.start	= S5PC110_PA_ONENAND,
-		.end	= S5PC110_PA_ONENAND + SZ_128K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= S5PC110_PA_ONENAND_DMA,
-		.end	= S5PC110_PA_ONENAND_DMA + SZ_8K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start	= IRQ_ONENAND_AUDI,
-		.end	= IRQ_ONENAND_AUDI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s5pc110_device_onenand = {
-	.name		= "s5pc110-onenand",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(s5pc110_onenand_resources),
-	.resource	= s5pc110_onenand_resources,
-};
-
-void s5pc110_onenand_set_platdata(struct onenand_platform_data *pdata)
-{
-	struct onenand_platform_data *pd;
-
-	pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
-	if (!pd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	s5pc110_device_onenand.dev.platform_data = pd;
-}
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index 396c4a7..38e870a 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -26,6 +26,25 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 
+static struct resource s5pc110_onenand_resources[] __initdata = {
+	[0] = {
+		.start	= S5PC110_PA_ONENAND,
+		.end	= S5PC110_PA_ONENAND + SZ_128K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= S5PC110_PA_ONENAND_DMA,
+		.end	= S5PC110_PA_ONENAND_DMA + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct s3c_pdev_template s5pc110_template_onenand __initdata = {
+	.resources	= s5pc110_onenand_resources,
+	.nr_res		= ARRAY_SIZE(s5pc110_onenand_resources),
+	.pdata_size	= sizeof(struct onenand_platform_data),
+};
+
 /* note, table is not ordered */
 
 struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
@@ -61,6 +80,11 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 			S5P_PA_UART3,
 			IRQ_S5P_UART_RX3, IRQ_S5P_UART_TX3, IRQ_S5P_UART_ERR3,
 		},
+	}, {
+		.type	= SAMSUNG_DEVICE_ONENAND,
+		.name	= "s5pc110-onenand",
+		.index	= -1,
+		.template = &s5pc110_template_onenand,
 	},
 };
 
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 7989932..5a502f3 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -479,7 +479,6 @@ static struct platform_device *aquila_devices[] __initdata = {
 	&aquila_i2c_gpio_pmic,
 	&aquila_device_gpiokeys,
 	&s3c_device_fb,
-	&s5pc110_device_onenand,
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc1,
 	&s3c_device_hsmmc2,
@@ -489,6 +488,7 @@ static struct platform_device *aquila_devices[] __initdata = {
 };
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
 };
 
 static void __init aquila_map_io(void)
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 6f555cf..e24b815 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -456,7 +456,6 @@ static void goni_setup_sdhci(void)
 
 static struct platform_device *goni_devices[] __initdata = {
 	&s3c_device_fb,
-	&s5pc110_device_onenand,
 	&goni_i2c_gpio_pmic,
 	&goni_device_gpiokeys,
 	&s5p_device_fimc0,
@@ -468,6 +467,7 @@ static struct platform_device *goni_devices[] __initdata = {
 };
 
 static struct s3c_devtable goni_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_ONENAND, .index = -1, },
 };
 
 static void __init goni_map_io(void)
-- 
1.7.1.569.g6f426

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

* [PATCH 5/9] ARM: S5PV210: convert OneNAND to device-table
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Convert OneNAND platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig       |    2 -
 arch/arm/mach-s5pv210/Makefile      |    1 -
 arch/arm/mach-s5pv210/dev-onenand.c |   55 -----------------------------------
 arch/arm/mach-s5pv210/dev-table.c   |   24 +++++++++++++++
 arch/arm/mach-s5pv210/mach-aquila.c |    2 +-
 arch/arm/mach-s5pv210/mach-goni.c   |    2 +-
 6 files changed, 26 insertions(+), 60 deletions(-)
 delete mode 100644 arch/arm/mach-s5pv210/dev-onenand.c

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index d3a3895..680b55b 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -71,7 +71,6 @@ config MACH_AQUILA
 	select S3C_DEV_HSMMC
 	select S3C_DEV_HSMMC1
 	select S3C_DEV_HSMMC2
-	select S5PC110_DEV_ONENAND
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_SDHCI
 	help
@@ -88,7 +87,6 @@ config MACH_GONI
 	select S3C_DEV_HSMMC
 	select S3C_DEV_HSMMC1
 	select S3C_DEV_HSMMC2
-	select S5PC110_DEV_ONENAND
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_SDHCI
 	help
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index a854577..23bde19 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_MACH_GONI)		+= mach-goni.o
 
 obj-y				+= dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
-obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o
 
 obj-$(CONFIG_S5PV210_SETUP_FB_24BPP)	+= setup-fb-24bpp.o
 obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
diff --git a/arch/arm/mach-s5pv210/dev-onenand.c b/arch/arm/mach-s5pv210/dev-onenand.c
deleted file mode 100644
index f8ede33..0000000
--- a/arch/arm/mach-s5pv210/dev-onenand.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * linux/arch/arm/mach-s5pv210/dev-onenand.c
- *
- *  Copyright (c) 2008-2010 Samsung Electronics
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S5PC110 series device definition for OneNAND devices
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-static struct resource s5pc110_onenand_resources[] = {
-	[0] = {
-		.start	= S5PC110_PA_ONENAND,
-		.end	= S5PC110_PA_ONENAND + SZ_128K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= S5PC110_PA_ONENAND_DMA,
-		.end	= S5PC110_PA_ONENAND_DMA + SZ_8K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start	= IRQ_ONENAND_AUDI,
-		.end	= IRQ_ONENAND_AUDI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s5pc110_device_onenand = {
-	.name		= "s5pc110-onenand",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(s5pc110_onenand_resources),
-	.resource	= s5pc110_onenand_resources,
-};
-
-void s5pc110_onenand_set_platdata(struct onenand_platform_data *pdata)
-{
-	struct onenand_platform_data *pd;
-
-	pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
-	if (!pd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	s5pc110_device_onenand.dev.platform_data = pd;
-}
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index 396c4a7..38e870a 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -26,6 +26,25 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 
+static struct resource s5pc110_onenand_resources[] __initdata = {
+	[0] = {
+		.start	= S5PC110_PA_ONENAND,
+		.end	= S5PC110_PA_ONENAND + SZ_128K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= S5PC110_PA_ONENAND_DMA,
+		.end	= S5PC110_PA_ONENAND_DMA + SZ_2K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct s3c_pdev_template s5pc110_template_onenand __initdata = {
+	.resources	= s5pc110_onenand_resources,
+	.nr_res		= ARRAY_SIZE(s5pc110_onenand_resources),
+	.pdata_size	= sizeof(struct onenand_platform_data),
+};
+
 /* note, table is not ordered */
 
 struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
@@ -61,6 +80,11 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 			S5P_PA_UART3,
 			IRQ_S5P_UART_RX3, IRQ_S5P_UART_TX3, IRQ_S5P_UART_ERR3,
 		},
+	}, {
+		.type	= SAMSUNG_DEVICE_ONENAND,
+		.name	= "s5pc110-onenand",
+		.index	= -1,
+		.template = &s5pc110_template_onenand,
 	},
 };
 
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 7989932..5a502f3 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -479,7 +479,6 @@ static struct platform_device *aquila_devices[] __initdata = {
 	&aquila_i2c_gpio_pmic,
 	&aquila_device_gpiokeys,
 	&s3c_device_fb,
-	&s5pc110_device_onenand,
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc1,
 	&s3c_device_hsmmc2,
@@ -489,6 +488,7 @@ static struct platform_device *aquila_devices[] __initdata = {
 };
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
 };
 
 static void __init aquila_map_io(void)
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 6f555cf..e24b815 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -456,7 +456,6 @@ static void goni_setup_sdhci(void)
 
 static struct platform_device *goni_devices[] __initdata = {
 	&s3c_device_fb,
-	&s5pc110_device_onenand,
 	&goni_i2c_gpio_pmic,
 	&goni_device_gpiokeys,
 	&s5p_device_fimc0,
@@ -468,6 +467,7 @@ static struct platform_device *goni_devices[] __initdata = {
 };
 
 static struct s3c_devtable goni_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_ONENAND, .index = -1, },
 };
 
 static void __init goni_map_io(void)
-- 
1.7.1.569.g6f426

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

* [PATCH 6/9] ARM: S5PV210: convert sdhci to device-table
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Convert s3c-sdhci platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig              |   39 ++++---
 arch/arm/mach-s5pv210/Makefile             |    3 +-
 arch/arm/mach-s5pv210/cpu.c                |    5 -
 arch/arm/mach-s5pv210/dev-table.c          |   18 +++
 arch/arm/mach-s5pv210/mach-aquila.c        |    9 +-
 arch/arm/mach-s5pv210/mach-goni.c          |    9 +-
 arch/arm/mach-s5pv210/setup-sdhci-gpio.c   |  137 ----------------------
 arch/arm/mach-s5pv210/setup-sdhci.c        |  168 +++++++++++++++++++++++++++-
 arch/arm/plat-samsung/Kconfig              |   15 ---
 arch/arm/plat-samsung/Makefile             |    3 -
 arch/arm/plat-samsung/dev-hsmmc.c          |   58 +++-------
 arch/arm/plat-samsung/dev-hsmmc1.c         |   73 ------------
 arch/arm/plat-samsung/dev-hsmmc2.c         |   74 ------------
 arch/arm/plat-samsung/dev-hsmmc3.c         |   77 -------------
 arch/arm/plat-samsung/dev_templates.c      |    2 +
 arch/arm/plat-samsung/include/plat/sdhci.h |  106 ++++++++----------
 16 files changed, 285 insertions(+), 511 deletions(-)
 delete mode 100644 arch/arm/mach-s5pv210/setup-sdhci-gpio.c
 delete mode 100644 arch/arm/plat-samsung/dev-hsmmc1.c
 delete mode 100644 arch/arm/plat-samsung/dev-hsmmc2.c
 delete mode 100644 arch/arm/plat-samsung/dev-hsmmc3.c

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 680b55b..7b59855 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -42,16 +42,29 @@ config S5PV210_SETUP_KEYPAD
 	help
 	  Common setup code for keypad.
 
-config S5PV210_SETUP_SDHCI
+config S5PV210_SETUP_SDHCI0
+	select S3C_DEV_HSMMC
         bool
-        select S5PV210_SETUP_SDHCI_GPIO
         help
           Internal helper functions for S5PV210 based SDHCI systems
 
-config S5PV210_SETUP_SDHCI_GPIO
-	bool
-	help
-	  Common setup code for SDHCI gpio.
+config S5PV210_SETUP_SDHCI1
+	select S3C_DEV_HSMMC
+        bool
+        help
+          Internal helper functions for S5PV210 based SDHCI systems
+
+config S5PV210_SETUP_SDHCI2
+	select S3C_DEV_HSMMC
+        bool
+        help
+          Internal helper functions for S5PV210 based SDHCI systems
+
+config S5PV210_SETUP_SDHCI3
+	select S3C_DEV_HSMMC
+        bool
+        help
+          Internal helper functions for S5PV210 based SDHCI systems
 
 config S5PC110_DEV_ONENAND
 	bool
@@ -68,11 +81,10 @@ config MACH_AQUILA
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC1
-	select S3C_DEV_HSMMC2
 	select S5PV210_SETUP_FB_24BPP
-	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_SDHCI0
+	select S5PV210_SETUP_SDHCI1
+	select S5PV210_SETUP_SDHCI2
 	help
 	  Machine support for the Samsung Aquila target based on S5PC110 SoC
 
@@ -84,11 +96,10 @@ config MACH_GONI
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC1
-	select S3C_DEV_HSMMC2
 	select S5PV210_SETUP_FB_24BPP
-	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_SDHCI0
+	select S5PV210_SETUP_SDHCI1
+	select S5PV210_SETUP_SDHCI2
 	help
 	  Machine support for Samsung GONI board
 	  S5PC110(MCP) is one of package option of S5PV210
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 23bde19..a5fd9ae 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -33,5 +33,4 @@ obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
 obj-$(CONFIG_S5PV210_SETUP_I2C2) 	+= setup-i2c2.o
 obj-$(CONFIG_S5PV210_SETUP_IDE)		+= setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)	+= setup-keypad.o
-obj-$(CONFIG_S5PV210_SETUP_SDHCI)       += setup-sdhci.o
-obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
+obj-$(CONFIG_S3C_DEV_HSMMC)		+= setup-sdhci.o
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 785f011..5f5ab1e 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -90,11 +90,6 @@ void __init s5pv210_map_io(void)
 	s5pv210_register_devtable();
 
 	/* initialise device information early */
-	s5pv210_default_sdhci0();
-	s5pv210_default_sdhci1();
-	s5pv210_default_sdhci2();
-	s5pv210_default_sdhci3();
-
 	s3c_adc_setname("s3c64xx-adc");
 
 	s3c_cfcon_setname("s5pv210-pata");
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index 38e870a..86f3792 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -81,6 +81,24 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 			IRQ_S5P_UART_RX3, IRQ_S5P_UART_TX3, IRQ_S5P_UART_ERR3,
 		},
 	}, {
+		.type	= SAMSUNG_DEVICE_SDHCI,
+		.name	= "s3c-sdhci",
+		.index	= 0,
+		.res	= {S5PV210_PA_HSMMC(0), IRQ_HSMMC0},
+		.defpdata = s5pv210_hsmmc0_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_SDHCI,
+		.name	= "s3c-sdhci",
+		.index	= 1,
+		.res	= {S5PV210_PA_HSMMC(1), IRQ_HSMMC1},
+		.defpdata = s5pv210_hsmmc1_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_SDHCI,
+		.name	= "s3c-sdhci",
+		.index	= 2,
+		.res	= {S5PV210_PA_HSMMC(2), IRQ_HSMMC2},
+		.defpdata = s5pv210_hsmmc2_def_platdata_p,
+	}, {
 		.type	= SAMSUNG_DEVICE_ONENAND,
 		.name	= "s5pc110-onenand",
 		.index	= -1,
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 5a502f3..c4f5261 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -470,18 +470,12 @@ static void aquila_setup_sdhci(void)
 	gpio_request(AQUILA_EXT_FLASH_EN, "FLASH_EN");
 	gpio_direction_output(AQUILA_EXT_FLASH_EN, 1);
 
-	s3c_sdhci0_set_platdata(&aquila_hsmmc0_data);
-	s3c_sdhci1_set_platdata(&aquila_hsmmc1_data);
-	s3c_sdhci2_set_platdata(&aquila_hsmmc2_data);
 };
 
 static struct platform_device *aquila_devices[] __initdata = {
 	&aquila_i2c_gpio_pmic,
 	&aquila_device_gpiokeys,
 	&s3c_device_fb,
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc1,
-	&s3c_device_hsmmc2,
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
@@ -489,6 +483,9 @@ static struct platform_device *aquila_devices[] __initdata = {
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
 	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
+	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 0, .pdata = &aquila_hsmmc0_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 1, .pdata = &aquila_hsmmc1_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 2, .pdata = &aquila_hsmmc2_data},
 };
 
 static void __init aquila_map_io(void)
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index e24b815..9c9f6ca 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -449,9 +449,6 @@ static void goni_setup_sdhci(void)
 	gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
 	gpio_direction_output(GONI_EXT_FLASH_EN, 1);
 
-	s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
-	s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
-	s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
 };
 
 static struct platform_device *goni_devices[] __initdata = {
@@ -461,13 +458,13 @@ static struct platform_device *goni_devices[] __initdata = {
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc1,
-	&s3c_device_hsmmc2,
 };
 
 static struct s3c_devtable goni_devtable[] __initdata = {
 	{ .type = SAMSUNG_DEVICE_ONENAND, .index = -1, },
+	{ .type = SAMSUNG_DEVICE_SDHCI, .index = 0, .pdata = &goni_hsmmc0_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,	.index = 1, .pdata = &goni_hsmmc1_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,	.index = 2, .pdata = &goni_hsmmc2_data},
 };
 
 static void __init goni_map_io(void)
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
deleted file mode 100644
index b18587b..0000000
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * S5PV210 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG0/GPG1 pins to special-function 2 */
-	for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-	switch (width) {
-	case 8:
-		/* GPG1[3:6] special-funtion 3 */
-		for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	case 4:
-		/* GPG0[3:6] special-funtion 2 */
-		for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	default:
-		break;
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
-	}
-}
-
-void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG1[0:1] pins to special-function 2 */
-	for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	/* Data pin GPG1[3:6] to special-function 2 */
-	for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
-	}
-}
-
-void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG2[0:1] pins to special-function 2 */
-	for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	switch (width) {
-	case 8:
-		/* Data pin GPG3[3:6] to special-function 3 */
-		for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	case 4:
-		/* Data pin GPG2[3:6] to special-function 2 */
-		for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	default:
-		break;
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
-	}
-}
-
-void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG3[0:2] pins to special-function 2 */
-	for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	/* Data pin GPG3[3:6] to special-function 2 */
-	for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG3(2), S3C_GPIO_SFN(2));
-	}
-}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c
index c32e202..b946d10 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci.c
@@ -19,19 +19,21 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
 #include <plat/regs-sdhci.h>
 #include <plat/sdhci.h>
 
 /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
 
-char *s5pv210_hsmmc_clksrcs[4] = {
+static char *s5pv210_hsmmc_clksrcs[4] = {
 	[0] = "hsmmc",		/* HCLK */
 	/* [1] = "hsmmc",	- duplicate HCLK entry */
 	[2] = "sclk_mmc",	/* mmc_bus */
 	/* [3] = NULL,		- reserved */
 };
 
-void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
+static void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
 				    void __iomem *r,
 				    struct mmc_ios *ios,
 				    struct mmc_card *card)
@@ -61,3 +63,165 @@ void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
 	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
 	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
 }
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI0
+
+static void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+	unsigned int gpio;
+
+	/* Set all the necessary GPG0/GPG1 pins to special-function 2 */
+	for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+	switch (width) {
+	case 8:
+		/* GPG1[3:6] special-funtion 3 */
+		for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	case 4:
+		/* GPG0[3:6] special-funtion 2 */
+		for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	default:
+		break;
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
+	}
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc0_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci0_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI1
+
+static void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+	unsigned int gpio;
+
+	/* Set all the necessary GPG1[0:1] pins to special-function 2 */
+	for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	/* Data pin GPG1[3:6] to special-function 2 */
+	for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
+	}
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc1_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci1_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI2
+
+static void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+	unsigned int gpio;
+
+	/* Set all the necessary GPG2[0:1] pins to special-function 2 */
+	for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	switch (width) {
+	case 8:
+		/* Data pin GPG3[3:6] to special-function 3 */
+		for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	case 4:
+		/* Data pin GPG2[3:6] to special-function 2 */
+		for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	default:
+		break;
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
+	}
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc2_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci2_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI3
+
+static void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+
+	/* Set all the necessary GPG3[0:2] pins to special-function 2 */
+	for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	/* Data pin GPG3[3:6] to special-function 2 */
+	for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPG3(2), S3C_GPIO_SFN(2));
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc3_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci3_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 8f3be02..57c791c 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -160,21 +160,6 @@ config S3C_DEV_HSMMC
 	help
 	  Compile in platform device definitions for HSMMC code
 
-config S3C_DEV_HSMMC1
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 1
-
-config S3C_DEV_HSMMC2
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 2
-
-config S3C_DEV_HSMMC3
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 3
-
 config S3C_DEV_HWMON
 	bool
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index edaa083..b59a6e4 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -36,9 +36,6 @@ obj-y				+= platformdata.o
 obj-$(CONFIG_S3C24XX_DEV_UART)	+= dev-uart-s3c24xx.o
 obj-$(CONFIG_S3C64XX_DEV_UART)	+= dev-uart-s3c64xx.o
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
-obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
-obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
-obj-$(CONFIG_S3C_DEV_HSMMC3)	+= dev-hsmmc3.o
 obj-$(CONFIG_S3C_DEV_HWMON)	+= dev-hwmon.o
 obj-y				+= dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index b0f93f1..ff7452e9 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -15,50 +15,19 @@
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
 
-#include <mach/map.h>
 #include <plat/sdhci.h>
 #include <plat/devs.h>
-#include <plat/cpu.h>
+#include <plat/dev-core.h>
 
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC0,
-		.end   = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC0,
-		.end   = IRQ_HSMMC0,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc0 = {
-	.name		= "s3c-sdhci",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc_resource),
-	.resource	= s3c_hsmmc_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc0_def_platdata,
-	},
-};
-
-void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
+void __init s3c_sdhci_set_platdata(void *src, int id)
 {
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
-
+	struct s3c_sdhci_platdata *pd = src;
+	struct s3c_sdhci_platdata *set;
+	set = s3c_device_get_defplatdata(SAMSUNG_DEVICE_SDHCI, id);
+	if (!set) {
+		printk(KERN_ERR "%s: no default platform data\n", __func__);
+		return;
+	}
 	set->max_width = pd->max_width;
 	set->cd_type = pd->cd_type;
 	set->ext_cd_init = pd->ext_cd_init;
@@ -71,3 +40,12 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
 	if (pd->cfg_card)
 		set->cfg_card = pd->cfg_card;
 }
+
+struct s3c_pdev_template s3c_hsmmc_template __initdata = {
+	.type = SAMSUNG_DEVICE_SDHCI,
+	.resources = s3c_std_resources_4k,
+	.nr_res = 2,
+	.pdata_size = sizeof(struct s3c_sdhci_platdata),
+	.pdata_set = s3c_sdhci_set_platdata,
+	.dma = &samsung_std_dma_mask,
+};
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
deleted file mode 100644
index 1504fd8..0000000
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for hsmmc device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc1_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC1,
-		.end   = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC1,
-		.end   = IRQ_HSMMC1,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc1 = {
-	.name		= "s3c-sdhci",
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc1_resource),
-	.resource	= s3c_hsmmc1_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc1_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc1_def_platdata,
-	},
-};
-
-void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
-
-	set->max_width = pd->max_width;
-	set->cd_type = pd->cd_type;
-	set->ext_cd_init = pd->ext_cd_init;
-	set->ext_cd_cleanup = pd->ext_cd_cleanup;
-	set->ext_cd_gpio = pd->ext_cd_gpio;
-	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
deleted file mode 100644
index b28ef17..0000000
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
- *
- * Copyright (c) 2009 Samsung Electronics
- * Copyright (c) 2009 Maurus Cuelenaere
- *
- * Based on arch/arm/plat-s3c/dev-hsmmc1.c
- * original file Copyright (c) 2008 Simtec Electronics
- *
- * S3C series device definition for hsmmc device 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc2_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC2,
-		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC2,
-		.end   = IRQ_HSMMC2,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc2 = {
-	.name		= "s3c-sdhci",
-	.id		= 2,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
-	.resource	= s3c_hsmmc2_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc2_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc2_def_platdata,
-	},
-};
-
-void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
-
-	set->max_width = pd->max_width;
-	set->cd_type = pd->cd_type;
-	set->ext_cd_init = pd->ext_cd_init;
-	set->ext_cd_cleanup = pd->ext_cd_cleanup;
-	set->ext_cd_gpio = pd->ext_cd_gpio;
-	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
deleted file mode 100644
index 85aaf0f..0000000
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Based on arch/arm/plat-samsung/dev-hsmmc1.c
- *
- * Samsung device definition for hsmmc device 3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc3_resource[] = {
-	[0] = {
-		.start	= S3C_PA_HSMMC3,
-		.end	= S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_MMC3,
-		.end	= IRQ_MMC3,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc3 = {
-	.name		= "s3c-sdhci",
-	.id		= 3,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc3_resource),
-	.resource	= s3c_hsmmc3_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc3_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc3_def_platdata,
-	},
-};
-
-void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
-
-	set->max_width = pd->max_width;
-	set->cd_type = pd->cd_type;
-	set->ext_cd_init = pd->ext_cd_init;
-	set->ext_cd_cleanup = pd->ext_cd_cleanup;
-	set->ext_cd_gpio = pd->ext_cd_gpio;
-	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index dcf8c0e..922c6e9 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -22,6 +22,7 @@
 #include <plat/cpu.h>
 
 #include <plat/uart.h>
+#include <plat/sdhci.h>
 
 #define TEMPLATE_ENTRY(_type, _res) \
 {	.type = (_type), \
@@ -43,6 +44,7 @@ struct resource s3c_std_resources_4k[] __initdata = {
 static struct s3c_pdev_template *templates[] __initdata = {
 	s3c24xx_uart_template_p,
 	s3c64xx_uart_template_p,
+	s3c_hsmmc_template_p,
 };
 
 u64 samsung_std_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 30844c2..280f291 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -106,10 +106,6 @@ extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
 extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
 extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
 extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
 
 /* S3C64XX SDHCI setup */
 
@@ -234,58 +230,54 @@ static inline void s5pc100_default_sdhci2(void) { }
 
 #endif /* CONFIG_S5PC100_SETUP_SDHCI */
 
-/* S5PV210 SDHCI setup */
-
-#ifdef CONFIG_S5PV210_SETUP_SDHCI
-extern char *s5pv210_hsmmc_clksrcs[4];
-
-extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
-					   void __iomem *r,
-					   struct mmc_ios *ios,
-					   struct mmc_card *card);
-
-static inline void s5pv210_default_sdhci0(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC
-	s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
-	s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-static inline void s5pv210_default_sdhci1(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC1
-	s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
-	s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-static inline void s5pv210_default_sdhci2(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC2
-	s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
-	s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-static inline void s5pv210_default_sdhci3(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC3
-	s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
-	s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-#else
-static inline void s5pv210_default_sdhci0(void) { }
-static inline void s5pv210_default_sdhci1(void) { }
-static inline void s5pv210_default_sdhci2(void) { }
-static inline void s5pv210_default_sdhci3(void) { }
-
-#endif /* CONFIG_S5PV210_SETUP_SDHCI */
+/**
+ * s3c_sdhci_set_platdata - Set platform data for S3C SDHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C SDHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void s3c_sdhci_set_platdata(void *pd, int id);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+extern struct s3c_pdev_template s3c_hsmmc_template;
+#define s3c_hsmmc_template_p (&s3c_hsmmc_template)
+#else
+#define s3c_hsmmc_template_p NULL
+#endif
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+extern struct s3c_sdhci_platdata s5pv210_hsmmc0_def_platdata;
+extern struct s3c_sdhci_platdata s5pv210_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s5pv210_hsmmc2_def_platdata;
+extern struct s3c_sdhci_platdata s5pv210_hsmmc3_def_platdata;
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI0
+#define s5pv210_hsmmc0_def_platdata_p (&s5pv210_hsmmc0_def_platdata)
+#else
+#define s5pv210_hsmmc0_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI1
+#define s5pv210_hsmmc1_def_platdata_p (&s5pv210_hsmmc1_def_platdata)
+#else
+#define s5pv210_hsmmc1_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI2
+#define s5pv210_hsmmc2_def_platdata_p (&s5pv210_hsmmc2_def_platdata)
+#else
+#define s5pv210_hsmmc2_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI3
+#define s5pv210_hsmmc3_def_platdata_p (&s5pv210_hsmmc3_def_platdata)
+#else
+#define s5pv210_hsmmc3_def_platdata_p NULL
+#endif
 
 #endif /* __PLAT_S3C_SDHCI_H */
-- 
1.7.1.569.g6f426

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

* [PATCH 6/9] ARM: S5PV210: convert sdhci to device-table
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Convert s3c-sdhci platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig              |   39 ++++---
 arch/arm/mach-s5pv210/Makefile             |    3 +-
 arch/arm/mach-s5pv210/cpu.c                |    5 -
 arch/arm/mach-s5pv210/dev-table.c          |   18 +++
 arch/arm/mach-s5pv210/mach-aquila.c        |    9 +-
 arch/arm/mach-s5pv210/mach-goni.c          |    9 +-
 arch/arm/mach-s5pv210/setup-sdhci-gpio.c   |  137 ----------------------
 arch/arm/mach-s5pv210/setup-sdhci.c        |  168 +++++++++++++++++++++++++++-
 arch/arm/plat-samsung/Kconfig              |   15 ---
 arch/arm/plat-samsung/Makefile             |    3 -
 arch/arm/plat-samsung/dev-hsmmc.c          |   58 +++-------
 arch/arm/plat-samsung/dev-hsmmc1.c         |   73 ------------
 arch/arm/plat-samsung/dev-hsmmc2.c         |   74 ------------
 arch/arm/plat-samsung/dev-hsmmc3.c         |   77 -------------
 arch/arm/plat-samsung/dev_templates.c      |    2 +
 arch/arm/plat-samsung/include/plat/sdhci.h |  106 ++++++++----------
 16 files changed, 285 insertions(+), 511 deletions(-)
 delete mode 100644 arch/arm/mach-s5pv210/setup-sdhci-gpio.c
 delete mode 100644 arch/arm/plat-samsung/dev-hsmmc1.c
 delete mode 100644 arch/arm/plat-samsung/dev-hsmmc2.c
 delete mode 100644 arch/arm/plat-samsung/dev-hsmmc3.c

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 680b55b..7b59855 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -42,16 +42,29 @@ config S5PV210_SETUP_KEYPAD
 	help
 	  Common setup code for keypad.
 
-config S5PV210_SETUP_SDHCI
+config S5PV210_SETUP_SDHCI0
+	select S3C_DEV_HSMMC
         bool
-        select S5PV210_SETUP_SDHCI_GPIO
         help
           Internal helper functions for S5PV210 based SDHCI systems
 
-config S5PV210_SETUP_SDHCI_GPIO
-	bool
-	help
-	  Common setup code for SDHCI gpio.
+config S5PV210_SETUP_SDHCI1
+	select S3C_DEV_HSMMC
+        bool
+        help
+          Internal helper functions for S5PV210 based SDHCI systems
+
+config S5PV210_SETUP_SDHCI2
+	select S3C_DEV_HSMMC
+        bool
+        help
+          Internal helper functions for S5PV210 based SDHCI systems
+
+config S5PV210_SETUP_SDHCI3
+	select S3C_DEV_HSMMC
+        bool
+        help
+          Internal helper functions for S5PV210 based SDHCI systems
 
 config S5PC110_DEV_ONENAND
 	bool
@@ -68,11 +81,10 @@ config MACH_AQUILA
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC1
-	select S3C_DEV_HSMMC2
 	select S5PV210_SETUP_FB_24BPP
-	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_SDHCI0
+	select S5PV210_SETUP_SDHCI1
+	select S5PV210_SETUP_SDHCI2
 	help
 	  Machine support for the Samsung Aquila target based on S5PC110 SoC
 
@@ -84,11 +96,10 @@ config MACH_GONI
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC1
-	select S3C_DEV_HSMMC2
 	select S5PV210_SETUP_FB_24BPP
-	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_SDHCI0
+	select S5PV210_SETUP_SDHCI1
+	select S5PV210_SETUP_SDHCI2
 	help
 	  Machine support for Samsung GONI board
 	  S5PC110(MCP) is one of package option of S5PV210
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 23bde19..a5fd9ae 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -33,5 +33,4 @@ obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
 obj-$(CONFIG_S5PV210_SETUP_I2C2) 	+= setup-i2c2.o
 obj-$(CONFIG_S5PV210_SETUP_IDE)		+= setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)	+= setup-keypad.o
-obj-$(CONFIG_S5PV210_SETUP_SDHCI)       += setup-sdhci.o
-obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
+obj-$(CONFIG_S3C_DEV_HSMMC)		+= setup-sdhci.o
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 785f011..5f5ab1e 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -90,11 +90,6 @@ void __init s5pv210_map_io(void)
 	s5pv210_register_devtable();
 
 	/* initialise device information early */
-	s5pv210_default_sdhci0();
-	s5pv210_default_sdhci1();
-	s5pv210_default_sdhci2();
-	s5pv210_default_sdhci3();
-
 	s3c_adc_setname("s3c64xx-adc");
 
 	s3c_cfcon_setname("s5pv210-pata");
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index 38e870a..86f3792 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -81,6 +81,24 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 			IRQ_S5P_UART_RX3, IRQ_S5P_UART_TX3, IRQ_S5P_UART_ERR3,
 		},
 	}, {
+		.type	= SAMSUNG_DEVICE_SDHCI,
+		.name	= "s3c-sdhci",
+		.index	= 0,
+		.res	= {S5PV210_PA_HSMMC(0), IRQ_HSMMC0},
+		.defpdata = s5pv210_hsmmc0_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_SDHCI,
+		.name	= "s3c-sdhci",
+		.index	= 1,
+		.res	= {S5PV210_PA_HSMMC(1), IRQ_HSMMC1},
+		.defpdata = s5pv210_hsmmc1_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_SDHCI,
+		.name	= "s3c-sdhci",
+		.index	= 2,
+		.res	= {S5PV210_PA_HSMMC(2), IRQ_HSMMC2},
+		.defpdata = s5pv210_hsmmc2_def_platdata_p,
+	}, {
 		.type	= SAMSUNG_DEVICE_ONENAND,
 		.name	= "s5pc110-onenand",
 		.index	= -1,
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 5a502f3..c4f5261 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -470,18 +470,12 @@ static void aquila_setup_sdhci(void)
 	gpio_request(AQUILA_EXT_FLASH_EN, "FLASH_EN");
 	gpio_direction_output(AQUILA_EXT_FLASH_EN, 1);
 
-	s3c_sdhci0_set_platdata(&aquila_hsmmc0_data);
-	s3c_sdhci1_set_platdata(&aquila_hsmmc1_data);
-	s3c_sdhci2_set_platdata(&aquila_hsmmc2_data);
 };
 
 static struct platform_device *aquila_devices[] __initdata = {
 	&aquila_i2c_gpio_pmic,
 	&aquila_device_gpiokeys,
 	&s3c_device_fb,
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc1,
-	&s3c_device_hsmmc2,
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
@@ -489,6 +483,9 @@ static struct platform_device *aquila_devices[] __initdata = {
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
 	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
+	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 0, .pdata = &aquila_hsmmc0_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 1, .pdata = &aquila_hsmmc1_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 2, .pdata = &aquila_hsmmc2_data},
 };
 
 static void __init aquila_map_io(void)
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index e24b815..9c9f6ca 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -449,9 +449,6 @@ static void goni_setup_sdhci(void)
 	gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
 	gpio_direction_output(GONI_EXT_FLASH_EN, 1);
 
-	s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
-	s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
-	s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
 };
 
 static struct platform_device *goni_devices[] __initdata = {
@@ -461,13 +458,13 @@ static struct platform_device *goni_devices[] __initdata = {
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc1,
-	&s3c_device_hsmmc2,
 };
 
 static struct s3c_devtable goni_devtable[] __initdata = {
 	{ .type = SAMSUNG_DEVICE_ONENAND, .index = -1, },
+	{ .type = SAMSUNG_DEVICE_SDHCI, .index = 0, .pdata = &goni_hsmmc0_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,	.index = 1, .pdata = &goni_hsmmc1_data},
+	{ .type = SAMSUNG_DEVICE_SDHCI,	.index = 2, .pdata = &goni_hsmmc2_data},
 };
 
 static void __init goni_map_io(void)
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
deleted file mode 100644
index b18587b..0000000
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * S5PV210 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG0/GPG1 pins to special-function 2 */
-	for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-	switch (width) {
-	case 8:
-		/* GPG1[3:6] special-funtion 3 */
-		for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	case 4:
-		/* GPG0[3:6] special-funtion 2 */
-		for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	default:
-		break;
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
-	}
-}
-
-void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG1[0:1] pins to special-function 2 */
-	for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	/* Data pin GPG1[3:6] to special-function 2 */
-	for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
-	}
-}
-
-void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG2[0:1] pins to special-function 2 */
-	for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	switch (width) {
-	case 8:
-		/* Data pin GPG3[3:6] to special-function 3 */
-		for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	case 4:
-		/* Data pin GPG2[3:6] to special-function 2 */
-		for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		}
-	default:
-		break;
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
-	}
-}
-
-void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPG3[0:2] pins to special-function 2 */
-	for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	/* Data pin GPG3[3:6] to special-function 2 */
-	for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgpin(S5PV210_GPG3(2), S3C_GPIO_SFN(2));
-	}
-}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c
index c32e202..b946d10 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci.c
@@ -19,19 +19,21 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
 #include <plat/regs-sdhci.h>
 #include <plat/sdhci.h>
 
 /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
 
-char *s5pv210_hsmmc_clksrcs[4] = {
+static char *s5pv210_hsmmc_clksrcs[4] = {
 	[0] = "hsmmc",		/* HCLK */
 	/* [1] = "hsmmc",	- duplicate HCLK entry */
 	[2] = "sclk_mmc",	/* mmc_bus */
 	/* [3] = NULL,		- reserved */
 };
 
-void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
+static void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
 				    void __iomem *r,
 				    struct mmc_ios *ios,
 				    struct mmc_card *card)
@@ -61,3 +63,165 @@ void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
 	writel(ctrl2, r + S3C_SDHCI_CONTROL2);
 	writel(ctrl3, r + S3C_SDHCI_CONTROL3);
 }
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI0
+
+static void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+	unsigned int gpio;
+
+	/* Set all the necessary GPG0/GPG1 pins to special-function 2 */
+	for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+	switch (width) {
+	case 8:
+		/* GPG1[3:6] special-funtion 3 */
+		for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	case 4:
+		/* GPG0[3:6] special-funtion 2 */
+		for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	default:
+		break;
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
+	}
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc0_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci0_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI1
+
+static void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+	unsigned int gpio;
+
+	/* Set all the necessary GPG1[0:1] pins to special-function 2 */
+	for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	/* Data pin GPG1[3:6] to special-function 2 */
+	for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
+	}
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc1_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci1_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI2
+
+static void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+	unsigned int gpio;
+
+	/* Set all the necessary GPG2[0:1] pins to special-function 2 */
+	for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	switch (width) {
+	case 8:
+		/* Data pin GPG3[3:6] to special-function 3 */
+		for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	case 4:
+		/* Data pin GPG2[3:6] to special-function 2 */
+		for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
+			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+		}
+	default:
+		break;
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
+		s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
+	}
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc2_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci2_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI3
+
+static void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+	unsigned int gpio;
+
+	/* Set all the necessary GPG3[0:2] pins to special-function 2 */
+	for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	/* Data pin GPG3[3:6] to special-function 2 */
+	for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
+		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+	}
+
+	s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPG3(2), S3C_GPIO_SFN(2));
+}
+
+struct s3c_sdhci_platdata s5pv210_hsmmc3_def_platdata __initdata = {
+	.max_width	= 4,
+	.host_caps	= (MMC_CAP_4_BIT_DATA |
+			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+	.clocks		= s5pv210_hsmmc_clksrcs,
+	.cfg_gpio	= s5pv210_setup_sdhci3_cfg_gpio,
+	.cfg_card	= s5pv210_setup_sdhci_cfg_card,
+};
+
+#endif
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 8f3be02..57c791c 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -160,21 +160,6 @@ config S3C_DEV_HSMMC
 	help
 	  Compile in platform device definitions for HSMMC code
 
-config S3C_DEV_HSMMC1
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 1
-
-config S3C_DEV_HSMMC2
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 2
-
-config S3C_DEV_HSMMC3
-	bool
-	help
-	  Compile in platform device definitions for HSMMC channel 3
-
 config S3C_DEV_HWMON
 	bool
 	help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index edaa083..b59a6e4 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -36,9 +36,6 @@ obj-y				+= platformdata.o
 obj-$(CONFIG_S3C24XX_DEV_UART)	+= dev-uart-s3c24xx.o
 obj-$(CONFIG_S3C64XX_DEV_UART)	+= dev-uart-s3c64xx.o
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
-obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
-obj-$(CONFIG_S3C_DEV_HSMMC2)	+= dev-hsmmc2.o
-obj-$(CONFIG_S3C_DEV_HSMMC3)	+= dev-hsmmc3.o
 obj-$(CONFIG_S3C_DEV_HWMON)	+= dev-hwmon.o
 obj-y				+= dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index b0f93f1..ff7452e9 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -15,50 +15,19 @@
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
 
-#include <mach/map.h>
 #include <plat/sdhci.h>
 #include <plat/devs.h>
-#include <plat/cpu.h>
+#include <plat/dev-core.h>
 
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC0,
-		.end   = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC0,
-		.end   = IRQ_HSMMC0,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc0 = {
-	.name		= "s3c-sdhci",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc_resource),
-	.resource	= s3c_hsmmc_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc0_def_platdata,
-	},
-};
-
-void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
+void __init s3c_sdhci_set_platdata(void *src, int id)
 {
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
-
+	struct s3c_sdhci_platdata *pd = src;
+	struct s3c_sdhci_platdata *set;
+	set = s3c_device_get_defplatdata(SAMSUNG_DEVICE_SDHCI, id);
+	if (!set) {
+		printk(KERN_ERR "%s: no default platform data\n", __func__);
+		return;
+	}
 	set->max_width = pd->max_width;
 	set->cd_type = pd->cd_type;
 	set->ext_cd_init = pd->ext_cd_init;
@@ -71,3 +40,12 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
 	if (pd->cfg_card)
 		set->cfg_card = pd->cfg_card;
 }
+
+struct s3c_pdev_template s3c_hsmmc_template __initdata = {
+	.type = SAMSUNG_DEVICE_SDHCI,
+	.resources = s3c_std_resources_4k,
+	.nr_res = 2,
+	.pdata_size = sizeof(struct s3c_sdhci_platdata),
+	.pdata_set = s3c_sdhci_set_platdata,
+	.dma = &samsung_std_dma_mask,
+};
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
deleted file mode 100644
index 1504fd8..0000000
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for hsmmc device 1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc1_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC1,
-		.end   = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC1,
-		.end   = IRQ_HSMMC1,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc1 = {
-	.name		= "s3c-sdhci",
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc1_resource),
-	.resource	= s3c_hsmmc1_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc1_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc1_def_platdata,
-	},
-};
-
-void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
-
-	set->max_width = pd->max_width;
-	set->cd_type = pd->cd_type;
-	set->ext_cd_init = pd->ext_cd_init;
-	set->ext_cd_cleanup = pd->ext_cd_cleanup;
-	set->ext_cd_gpio = pd->ext_cd_gpio;
-	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
deleted file mode 100644
index b28ef17..0000000
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
- *
- * Copyright (c) 2009 Samsung Electronics
- * Copyright (c) 2009 Maurus Cuelenaere
- *
- * Based on arch/arm/plat-s3c/dev-hsmmc1.c
- * original file Copyright (c) 2008 Simtec Electronics
- *
- * S3C series device definition for hsmmc device 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc2_resource[] = {
-	[0] = {
-		.start = S3C_PA_HSMMC2,
-		.end   = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_HSMMC2,
-		.end   = IRQ_HSMMC2,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc2 = {
-	.name		= "s3c-sdhci",
-	.id		= 2,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc2_resource),
-	.resource	= s3c_hsmmc2_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc2_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc2_def_platdata,
-	},
-};
-
-void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
-
-	set->max_width = pd->max_width;
-	set->cd_type = pd->cd_type;
-	set->ext_cd_init = pd->ext_cd_init;
-	set->ext_cd_cleanup = pd->ext_cd_cleanup;
-	set->ext_cd_gpio = pd->ext_cd_gpio;
-	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
deleted file mode 100644
index 85aaf0f..0000000
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * Based on arch/arm/plat-samsung/dev-hsmmc1.c
- *
- * Samsung device definition for hsmmc device 3
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mmc/host.h>
-
-#include <mach/map.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-
-#define S3C_SZ_HSMMC	(0x1000)
-
-static struct resource s3c_hsmmc3_resource[] = {
-	[0] = {
-		.start	= S3C_PA_HSMMC3,
-		.end	= S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_MMC3,
-		.end	= IRQ_MMC3,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
-
-struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
-	.max_width	= 4,
-	.host_caps	= (MMC_CAP_4_BIT_DATA |
-			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-};
-
-struct platform_device s3c_device_hsmmc3 = {
-	.name		= "s3c-sdhci",
-	.id		= 3,
-	.num_resources	= ARRAY_SIZE(s3c_hsmmc3_resource),
-	.resource	= s3c_hsmmc3_resource,
-	.dev		= {
-		.dma_mask		= &s3c_device_hsmmc3_dmamask,
-		.coherent_dma_mask	= 0xffffffffUL,
-		.platform_data		= &s3c_hsmmc3_def_platdata,
-	},
-};
-
-void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
-{
-	struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
-
-	set->max_width = pd->max_width;
-	set->cd_type = pd->cd_type;
-	set->ext_cd_init = pd->ext_cd_init;
-	set->ext_cd_cleanup = pd->ext_cd_cleanup;
-	set->ext_cd_gpio = pd->ext_cd_gpio;
-	set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
-
-	if (pd->cfg_gpio)
-		set->cfg_gpio = pd->cfg_gpio;
-	if (pd->cfg_card)
-		set->cfg_card = pd->cfg_card;
-}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index dcf8c0e..922c6e9 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -22,6 +22,7 @@
 #include <plat/cpu.h>
 
 #include <plat/uart.h>
+#include <plat/sdhci.h>
 
 #define TEMPLATE_ENTRY(_type, _res) \
 {	.type = (_type), \
@@ -43,6 +44,7 @@ struct resource s3c_std_resources_4k[] __initdata = {
 static struct s3c_pdev_template *templates[] __initdata = {
 	s3c24xx_uart_template_p,
 	s3c64xx_uart_template_p,
+	s3c_hsmmc_template_p,
 };
 
 u64 samsung_std_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 30844c2..280f291 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -106,10 +106,6 @@ extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
 extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
 extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
 extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
-extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
 
 /* S3C64XX SDHCI setup */
 
@@ -234,58 +230,54 @@ static inline void s5pc100_default_sdhci2(void) { }
 
 #endif /* CONFIG_S5PC100_SETUP_SDHCI */
 
-/* S5PV210 SDHCI setup */
-
-#ifdef CONFIG_S5PV210_SETUP_SDHCI
-extern char *s5pv210_hsmmc_clksrcs[4];
-
-extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
-					   void __iomem *r,
-					   struct mmc_ios *ios,
-					   struct mmc_card *card);
-
-static inline void s5pv210_default_sdhci0(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC
-	s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
-	s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-static inline void s5pv210_default_sdhci1(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC1
-	s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
-	s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-static inline void s5pv210_default_sdhci2(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC2
-	s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
-	s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-static inline void s5pv210_default_sdhci3(void)
-{
-#ifdef CONFIG_S3C_DEV_HSMMC3
-	s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
-	s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
-	s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
-#endif
-}
-
-#else
-static inline void s5pv210_default_sdhci0(void) { }
-static inline void s5pv210_default_sdhci1(void) { }
-static inline void s5pv210_default_sdhci2(void) { }
-static inline void s5pv210_default_sdhci3(void) { }
-
-#endif /* CONFIG_S5PV210_SETUP_SDHCI */
+/**
+ * s3c_sdhci_set_platdata - Set platform data for S3C SDHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C SDHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void s3c_sdhci_set_platdata(void *pd, int id);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+extern struct s3c_pdev_template s3c_hsmmc_template;
+#define s3c_hsmmc_template_p (&s3c_hsmmc_template)
+#else
+#define s3c_hsmmc_template_p NULL
+#endif
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+extern struct s3c_sdhci_platdata s5pv210_hsmmc0_def_platdata;
+extern struct s3c_sdhci_platdata s5pv210_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s5pv210_hsmmc2_def_platdata;
+extern struct s3c_sdhci_platdata s5pv210_hsmmc3_def_platdata;
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI0
+#define s5pv210_hsmmc0_def_platdata_p (&s5pv210_hsmmc0_def_platdata)
+#else
+#define s5pv210_hsmmc0_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI1
+#define s5pv210_hsmmc1_def_platdata_p (&s5pv210_hsmmc1_def_platdata)
+#else
+#define s5pv210_hsmmc1_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI2
+#define s5pv210_hsmmc2_def_platdata_p (&s5pv210_hsmmc2_def_platdata)
+#else
+#define s5pv210_hsmmc2_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI3
+#define s5pv210_hsmmc3_def_platdata_p (&s5pv210_hsmmc3_def_platdata)
+#else
+#define s5pv210_hsmmc3_def_platdata_p NULL
+#endif
 
 #endif /* __PLAT_S3C_SDHCI_H */
-- 
1.7.1.569.g6f426

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

* [PATCH 7/9] ARM: S5PV210: convert framebuffer to device-table
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Convert s3c-fb platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig           |    3 +-
 arch/arm/mach-s5pv210/dev-table.c       |    8 +++++
 arch/arm/mach-s5pv210/mach-aquila.c     |    5 +---
 arch/arm/mach-s5pv210/mach-goni.c       |    5 +---
 arch/arm/plat-samsung/dev-fb.c          |   44 ++++++------------------------
 arch/arm/plat-samsung/dev_templates.c   |    2 +
 arch/arm/plat-samsung/include/plat/fb.h |    9 ++++++
 7 files changed, 31 insertions(+), 45 deletions(-)

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 7b59855..734c0b7 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -33,6 +33,7 @@ config S5PV210_SETUP_IDE
 	  Common setup code for S5PV210 IDE GPIO configurations
 
 config S5PV210_SETUP_FB_24BPP
+	select S3C_DEV_FB
 	bool
 	help
           Common setup code for S5PV210 with an 24bpp RGB display helper.
@@ -77,7 +78,6 @@ config MACH_AQUILA
 	bool "Aquila"
 	select CPU_S5PV210
 	select ARCH_SPARSEMEM_ENABLE
-	select S3C_DEV_FB
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
@@ -92,7 +92,6 @@ config MACH_GONI
 	bool "GONI"
 	select CPU_S5PV210
 	select ARCH_SPARSEMEM_ENABLE
-	select S3C_DEV_FB
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index 86f3792..b88b43d 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -99,6 +99,14 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 		.res	= {S5PV210_PA_HSMMC(2), IRQ_HSMMC2},
 		.defpdata = s5pv210_hsmmc2_def_platdata_p,
 	}, {
+		.type	= SAMSUNG_DEVICE_FB,
+		.index	= -1,
+		.name	= "s3c-fb",
+		.res	= {
+			S5PV210_PA_FB,
+			IRQ_LCD_VSYNC, IRQ_LCD_FIFO, IRQ_LCD_SYSTEM,
+		},
+	}, {
 		.type	= SAMSUNG_DEVICE_ONENAND,
 		.name	= "s5pc110-onenand",
 		.index	= -1,
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index c4f5261..cb79256 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -475,13 +475,13 @@ static void aquila_setup_sdhci(void)
 static struct platform_device *aquila_devices[] __initdata = {
 	&aquila_i2c_gpio_pmic,
 	&aquila_device_gpiokeys,
-	&s3c_device_fb,
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
 };
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_FB,		.index = -1, .pdata = &aquila_lcd_pdata},
 	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
 	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 0, .pdata = &aquila_hsmmc0_data},
 	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 1, .pdata = &aquila_hsmmc1_data},
@@ -508,9 +508,6 @@ static void __init aquila_machine_init(void)
 	s3c_fimc_setname(1, "s5p-fimc");
 	s3c_fimc_setname(2, "s5p-fimc");
 
-	/* FB */
-	s3c_fb_set_platdata(&aquila_lcd_pdata);
-
 	platform_add_devices(aquila_devices, ARRAY_SIZE(aquila_devices));
 	samsung_add_devices(aquila_devtable, ARRAY_SIZE(aquila_devtable));
 }
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 9c9f6ca..23814cd 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -452,7 +452,6 @@ static void goni_setup_sdhci(void)
 };
 
 static struct platform_device *goni_devices[] __initdata = {
-	&s3c_device_fb,
 	&goni_i2c_gpio_pmic,
 	&goni_device_gpiokeys,
 	&s5p_device_fimc0,
@@ -461,6 +460,7 @@ static struct platform_device *goni_devices[] __initdata = {
 };
 
 static struct s3c_devtable goni_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_FB,	.index = -1, .pdata = &goni_lcd_pdata},
 	{ .type = SAMSUNG_DEVICE_ONENAND, .index = -1, },
 	{ .type = SAMSUNG_DEVICE_SDHCI, .index = 0, .pdata = &goni_hsmmc0_data},
 	{ .type = SAMSUNG_DEVICE_SDHCI,	.index = 1, .pdata = &goni_hsmmc1_data},
@@ -483,9 +483,6 @@ static void __init goni_machine_init(void)
 	/* SDHCI */
 	goni_setup_sdhci();
 
-	/* FB */
-	s3c_fb_set_platdata(&goni_lcd_pdata);
-
 	platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
 	samsung_add_devices(goni_devtable, ARRAY_SIZE(goni_devtable));
 }
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
index bf60204..dc604c3 100644
--- a/arch/arm/plat-samsung/dev-fb.c
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -17,57 +17,31 @@
 #include <linux/fb.h>
 #include <linux/gfp.h>
 
-#include <mach/irqs.h>
-#include <mach/map.h>
-
 #include <plat/fb.h>
 #include <plat/devs.h>
-#include <plat/cpu.h>
+#include <plat/dev-core.h>
 
-static struct resource s3c_fb_resource[] = {
+static struct resource s3c_fb_resources[] __initdata = {
 	[0] = {
-		.start = S3C_PA_FB,
-		.end   = S3C_PA_FB + SZ_16K - 1,
+		.end   = SZ_16K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start = IRQ_LCD_VSYNC,
-		.end   = IRQ_LCD_VSYNC,
 		.flags = IORESOURCE_IRQ,
 	},
 	[2] = {
-		.start = IRQ_LCD_FIFO,
-		.end   = IRQ_LCD_FIFO,
 		.flags = IORESOURCE_IRQ,
 	},
 	[3] = {
-		.start = IRQ_LCD_SYSTEM,
-		.end   = IRQ_LCD_SYSTEM,
 		.flags = IORESOURCE_IRQ,
 	},
 };
 
-struct platform_device s3c_device_fb = {
-	.name		  = "s3c-fb",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c_fb_resource),
-	.resource	  = s3c_fb_resource,
-	.dev.dma_mask	  = &s3c_device_fb.dev.coherent_dma_mask,
-	.dev.coherent_dma_mask = 0xffffffffUL,
+struct s3c_pdev_template s3c_fb_template __initdata = {
+	.type = SAMSUNG_DEVICE_FB,
+	.resources = s3c_fb_resources,
+	.nr_res	= ARRAY_SIZE(s3c_fb_resources),
+	.pdata_size = sizeof(struct s3c_fb_platdata),
+	.dma = &samsung_std_dma_mask,
 };
 
-void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
-{
-	struct s3c_fb_platdata *npd;
-
-	if (!pd) {
-		printk(KERN_ERR "%s: no platform data\n", __func__);
-		return;
-	}
-
-	npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
-	s3c_device_fb.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index 922c6e9..be06c19 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -22,6 +22,7 @@
 #include <plat/cpu.h>
 
 #include <plat/uart.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 
 #define TEMPLATE_ENTRY(_type, _res) \
@@ -45,6 +46,7 @@ static struct s3c_pdev_template *templates[] __initdata = {
 	s3c24xx_uart_template_p,
 	s3c64xx_uart_template_p,
 	s3c_hsmmc_template_p,
+	s3c_fb_template_p,
 };
 
 u64 samsung_std_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index 27d3b49..6e64cb8 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,8 @@
 #ifndef __PLAT_S3C_FB_H
 #define __PLAT_S3C_FB_H __FILE__
 
+#include <linux/fb.h>
+
 /* S3C_FB_MAX_WIN
  * Set to the maximum number of windows that any of the supported hardware
  * can use. Since the platform data uses this for an array size, having it
@@ -91,4 +93,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
  */
 extern void s5pv210_fb_gpio_setup_24bpp(void);
 
+#ifdef CONFIG_S3C_DEV_FB
+extern struct s3c_pdev_template s3c_fb_template;
+#define s3c_fb_template_p (&s3c_fb_template)
+#else
+#define s3c_fb_template_p NULL
+#endif
+
 #endif /* __PLAT_S3C_FB_H */
-- 
1.7.1.569.g6f426

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

* [PATCH 7/9] ARM: S5PV210: convert framebuffer to device-table
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Convert s3c-fb platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig           |    3 +-
 arch/arm/mach-s5pv210/dev-table.c       |    8 +++++
 arch/arm/mach-s5pv210/mach-aquila.c     |    5 +---
 arch/arm/mach-s5pv210/mach-goni.c       |    5 +---
 arch/arm/plat-samsung/dev-fb.c          |   44 ++++++------------------------
 arch/arm/plat-samsung/dev_templates.c   |    2 +
 arch/arm/plat-samsung/include/plat/fb.h |    9 ++++++
 7 files changed, 31 insertions(+), 45 deletions(-)

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 7b59855..734c0b7 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -33,6 +33,7 @@ config S5PV210_SETUP_IDE
 	  Common setup code for S5PV210 IDE GPIO configurations
 
 config S5PV210_SETUP_FB_24BPP
+	select S3C_DEV_FB
 	bool
 	help
           Common setup code for S5PV210 with an 24bpp RGB display helper.
@@ -77,7 +78,6 @@ config MACH_AQUILA
 	bool "Aquila"
 	select CPU_S5PV210
 	select ARCH_SPARSEMEM_ENABLE
-	select S3C_DEV_FB
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
@@ -92,7 +92,6 @@ config MACH_GONI
 	bool "GONI"
 	select CPU_S5PV210
 	select ARCH_SPARSEMEM_ENABLE
-	select S3C_DEV_FB
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index 86f3792..b88b43d 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -99,6 +99,14 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 		.res	= {S5PV210_PA_HSMMC(2), IRQ_HSMMC2},
 		.defpdata = s5pv210_hsmmc2_def_platdata_p,
 	}, {
+		.type	= SAMSUNG_DEVICE_FB,
+		.index	= -1,
+		.name	= "s3c-fb",
+		.res	= {
+			S5PV210_PA_FB,
+			IRQ_LCD_VSYNC, IRQ_LCD_FIFO, IRQ_LCD_SYSTEM,
+		},
+	}, {
 		.type	= SAMSUNG_DEVICE_ONENAND,
 		.name	= "s5pc110-onenand",
 		.index	= -1,
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index c4f5261..cb79256 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -475,13 +475,13 @@ static void aquila_setup_sdhci(void)
 static struct platform_device *aquila_devices[] __initdata = {
 	&aquila_i2c_gpio_pmic,
 	&aquila_device_gpiokeys,
-	&s3c_device_fb,
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
 };
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_FB,		.index = -1, .pdata = &aquila_lcd_pdata},
 	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
 	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 0, .pdata = &aquila_hsmmc0_data},
 	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 1, .pdata = &aquila_hsmmc1_data},
@@ -508,9 +508,6 @@ static void __init aquila_machine_init(void)
 	s3c_fimc_setname(1, "s5p-fimc");
 	s3c_fimc_setname(2, "s5p-fimc");
 
-	/* FB */
-	s3c_fb_set_platdata(&aquila_lcd_pdata);
-
 	platform_add_devices(aquila_devices, ARRAY_SIZE(aquila_devices));
 	samsung_add_devices(aquila_devtable, ARRAY_SIZE(aquila_devtable));
 }
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 9c9f6ca..23814cd 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -452,7 +452,6 @@ static void goni_setup_sdhci(void)
 };
 
 static struct platform_device *goni_devices[] __initdata = {
-	&s3c_device_fb,
 	&goni_i2c_gpio_pmic,
 	&goni_device_gpiokeys,
 	&s5p_device_fimc0,
@@ -461,6 +460,7 @@ static struct platform_device *goni_devices[] __initdata = {
 };
 
 static struct s3c_devtable goni_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_FB,	.index = -1, .pdata = &goni_lcd_pdata},
 	{ .type = SAMSUNG_DEVICE_ONENAND, .index = -1, },
 	{ .type = SAMSUNG_DEVICE_SDHCI, .index = 0, .pdata = &goni_hsmmc0_data},
 	{ .type = SAMSUNG_DEVICE_SDHCI,	.index = 1, .pdata = &goni_hsmmc1_data},
@@ -483,9 +483,6 @@ static void __init goni_machine_init(void)
 	/* SDHCI */
 	goni_setup_sdhci();
 
-	/* FB */
-	s3c_fb_set_platdata(&goni_lcd_pdata);
-
 	platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
 	samsung_add_devices(goni_devtable, ARRAY_SIZE(goni_devtable));
 }
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
index bf60204..dc604c3 100644
--- a/arch/arm/plat-samsung/dev-fb.c
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -17,57 +17,31 @@
 #include <linux/fb.h>
 #include <linux/gfp.h>
 
-#include <mach/irqs.h>
-#include <mach/map.h>
-
 #include <plat/fb.h>
 #include <plat/devs.h>
-#include <plat/cpu.h>
+#include <plat/dev-core.h>
 
-static struct resource s3c_fb_resource[] = {
+static struct resource s3c_fb_resources[] __initdata = {
 	[0] = {
-		.start = S3C_PA_FB,
-		.end   = S3C_PA_FB + SZ_16K - 1,
+		.end   = SZ_16K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start = IRQ_LCD_VSYNC,
-		.end   = IRQ_LCD_VSYNC,
 		.flags = IORESOURCE_IRQ,
 	},
 	[2] = {
-		.start = IRQ_LCD_FIFO,
-		.end   = IRQ_LCD_FIFO,
 		.flags = IORESOURCE_IRQ,
 	},
 	[3] = {
-		.start = IRQ_LCD_SYSTEM,
-		.end   = IRQ_LCD_SYSTEM,
 		.flags = IORESOURCE_IRQ,
 	},
 };
 
-struct platform_device s3c_device_fb = {
-	.name		  = "s3c-fb",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c_fb_resource),
-	.resource	  = s3c_fb_resource,
-	.dev.dma_mask	  = &s3c_device_fb.dev.coherent_dma_mask,
-	.dev.coherent_dma_mask = 0xffffffffUL,
+struct s3c_pdev_template s3c_fb_template __initdata = {
+	.type = SAMSUNG_DEVICE_FB,
+	.resources = s3c_fb_resources,
+	.nr_res	= ARRAY_SIZE(s3c_fb_resources),
+	.pdata_size = sizeof(struct s3c_fb_platdata),
+	.dma = &samsung_std_dma_mask,
 };
 
-void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
-{
-	struct s3c_fb_platdata *npd;
-
-	if (!pd) {
-		printk(KERN_ERR "%s: no platform data\n", __func__);
-		return;
-	}
-
-	npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
-	s3c_device_fb.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index 922c6e9..be06c19 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -22,6 +22,7 @@
 #include <plat/cpu.h>
 
 #include <plat/uart.h>
+#include <plat/fb.h>
 #include <plat/sdhci.h>
 
 #define TEMPLATE_ENTRY(_type, _res) \
@@ -45,6 +46,7 @@ static struct s3c_pdev_template *templates[] __initdata = {
 	s3c24xx_uart_template_p,
 	s3c64xx_uart_template_p,
 	s3c_hsmmc_template_p,
+	s3c_fb_template_p,
 };
 
 u64 samsung_std_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index 27d3b49..6e64cb8 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,8 @@
 #ifndef __PLAT_S3C_FB_H
 #define __PLAT_S3C_FB_H __FILE__
 
+#include <linux/fb.h>
+
 /* S3C_FB_MAX_WIN
  * Set to the maximum number of windows that any of the supported hardware
  * can use. Since the platform data uses this for an array size, having it
@@ -91,4 +93,11 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
  */
 extern void s5pv210_fb_gpio_setup_24bpp(void);
 
+#ifdef CONFIG_S3C_DEV_FB
+extern struct s3c_pdev_template s3c_fb_template;
+#define s3c_fb_template_p (&s3c_fb_template)
+#else
+#define s3c_fb_template_p NULL
+#endif
+
 #endif /* __PLAT_S3C_FB_H */
-- 
1.7.1.569.g6f426

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

* [PATCH 8/9] ARM: S5PV210: convert i2c to device-table
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Convert s3c-i2c platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig                 |   12 +++-
 arch/arm/mach-s5pv210/Makefile                |    4 +-
 arch/arm/mach-s5pv210/cpu.c                   |    6 --
 arch/arm/mach-s5pv210/dev-table.c             |   18 ++++++
 arch/arm/mach-s5pv210/setup-i2c.c             |   81 +++++++++++++++++++++++++
 arch/arm/mach-s5pv210/setup-i2c0.c            |   30 ---------
 arch/arm/mach-s5pv210/setup-i2c1.c            |   30 ---------
 arch/arm/mach-s5pv210/setup-i2c2.c            |   30 ---------
 arch/arm/plat-samsung/Kconfig                 |    9 +--
 arch/arm/plat-samsung/Makefile                |    4 +-
 arch/arm/plat-samsung/dev-i2c.c               |   43 +++++++++++++
 arch/arm/plat-samsung/dev-i2c0.c              |   72 ----------------------
 arch/arm/plat-samsung/dev-i2c1.c              |   69 ---------------------
 arch/arm/plat-samsung/dev-i2c2.c              |   70 ---------------------
 arch/arm/plat-samsung/dev_templates.c         |    2 +
 arch/arm/plat-samsung/include/plat/iic-core.h |   42 -------------
 arch/arm/plat-samsung/include/plat/iic.h      |   50 +++++++++++----
 17 files changed, 194 insertions(+), 378 deletions(-)
 create mode 100644 arch/arm/mach-s5pv210/setup-i2c.c
 delete mode 100644 arch/arm/mach-s5pv210/setup-i2c0.c
 delete mode 100644 arch/arm/mach-s5pv210/setup-i2c1.c
 delete mode 100644 arch/arm/mach-s5pv210/setup-i2c2.c
 create mode 100644 arch/arm/plat-samsung/dev-i2c.c
 delete mode 100644 arch/arm/plat-samsung/dev-i2c0.c
 delete mode 100644 arch/arm/plat-samsung/dev-i2c1.c
 delete mode 100644 arch/arm/plat-samsung/dev-i2c2.c
 delete mode 100644 arch/arm/plat-samsung/include/plat/iic-core.h

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 734c0b7..4034ea8 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -17,15 +17,23 @@ config CPU_S5PV210
 	help
 	  Enable S5PV210 CPU support
 
+config S5PV210_SETUP_I2C0
+	select S3C_DEV_I2C
+	bool
+	help
+	  Common setup code for i2c0 bus.
+
 config S5PV210_SETUP_I2C1
+	select S3C_DEV_I2C
 	bool
 	help
-	  Common setup code for i2c bus 1.
+	  Common setup code for i2c1 bus.
 
 config S5PV210_SETUP_I2C2
+	select S3C_DEV_I2C
 	bool
 	help
-	  Common setup code for i2c bus 2.
+	  Common setup code for i2c2 bus.
 
 config S5PV210_SETUP_IDE
 	bool
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index a5fd9ae..8148254 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -13,7 +13,6 @@ obj-				:=
 # Core support for S5PV210 system
 
 obj-$(CONFIG_CPU_S5PV210)	+= cpu.o clock.o dma.o gpiolib.o
-obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
 obj-$(CONFIG_CPU_S5PV210)	+= dev-table.o
 
 # machine support
@@ -29,8 +28,7 @@ obj-y				+= dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
 
 obj-$(CONFIG_S5PV210_SETUP_FB_24BPP)	+= setup-fb-24bpp.o
-obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
-obj-$(CONFIG_S5PV210_SETUP_I2C2) 	+= setup-i2c2.o
+obj-$(CONFIG_S3C_DEV_I2C)		+= setup-i2c.o
 obj-$(CONFIG_S5PV210_SETUP_IDE)		+= setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)	+= setup-keypad.o
 obj-$(CONFIG_S3C_DEV_HSMMC)		+= setup-sdhci.o
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 5f5ab1e..9806ba0 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -35,7 +35,6 @@
 #include <plat/adc-core.h>
 #include <plat/ata-core.h>
 #include <plat/fimc-core.h>
-#include <plat/iic-core.h>
 #include <plat/keypad-core.h>
 #include <plat/sdhci.h>
 #include <plat/reset.h>
@@ -98,11 +97,6 @@ void __init s5pv210_map_io(void)
 	s3c_fimc_setname(1, "s5pv210-fimc");
 	s3c_fimc_setname(2, "s5pv210-fimc");
 
-	/* the i2c devices are directly compatible with s3c2440 */
-	s3c_i2c0_setname("s3c2440-i2c");
-	s3c_i2c1_setname("s3c2440-i2c");
-	s3c_i2c2_setname("s3c2440-i2c");
-
 	/* Use s5pv210-keypad instead of samsung-keypad */
 	samsung_keypad_setname("s5pv210-keypad");
 }
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index b88b43d..559413f 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -99,6 +99,24 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 		.res	= {S5PV210_PA_HSMMC(2), IRQ_HSMMC2},
 		.defpdata = s5pv210_hsmmc2_def_platdata_p,
 	}, {
+		.type	= SAMSUNG_DEVICE_I2C,
+		.name	= "s3c2440-i2c",
+		.index	= 0,
+		.res	= {S5PV210_PA_IIC0, IRQ_IIC},
+		.defpdata = s5pv210_i2c0_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_I2C,
+		.name	= "s3c2440-i2c",
+		.index	= 1,
+		.res	= {S5PV210_PA_IIC1, IRQ_IIC1},
+		.defpdata = s5pv210_i2c0_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_I2C,
+		.name	= "s3c2440-i2c",
+		.index	= 2,
+		.res	= {S5PV210_PA_IIC2, IRQ_CAN0},
+		.defpdata = s5pv210_i2c0_def_platdata_p,
+	}, {
 		.type	= SAMSUNG_DEVICE_FB,
 		.index	= -1,
 		.name	= "s3c-fb",
diff --git a/arch/arm/mach-s5pv210/setup-i2c.c b/arch/arm/mach-s5pv210/setup-i2c.c
new file mode 100644
index 0000000..c9c6f3a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-i2c.c
@@ -0,0 +1,81 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+#include <mach/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+#ifdef CONFIG_S5PV210_SETUP_I2C0
+
+static void s5pv210_i2c0_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
+}
+
+struct s3c2410_platform_i2c s5pv210_i2c0_def_platdata __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+	.cfg_gpio	= &s5pv210_i2c0_cfg_gpio,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C1
+
+static void s5pv210_i2c1_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
+}
+
+struct s3c2410_platform_i2c s5pv210_i2c1_def_platdata __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+	.cfg_gpio	= &s5pv210_i2c1_cfg_gpio,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C2
+
+static void s5pv210_i2c2_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
+}
+
+struct s3c2410_platform_i2c s5pv210_i2c2_def_platdata __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+	.cfg_gpio	= &s5pv210_i2c2_cfg_gpio,
+};
+
+#endif
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
deleted file mode 100644
index d38f7cb..0000000
--- a/arch/arm/mach-s5pv210/setup-i2c0.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C0 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
deleted file mode 100644
index 148bb78..0000000
--- a/arch/arm/mach-s5pv210/setup-i2c1.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/setup-i2c1.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C1 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c1.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
deleted file mode 100644
index 2396cb8..0000000
--- a/arch/arm/mach-s5pv210/setup-i2c2.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/setup-i2c2.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C2 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c2_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 57c791c..f60603b 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -165,15 +165,10 @@ config S3C_DEV_HWMON
 	help
 	    Compile in platform device definitions for HWMON
 
-config S3C_DEV_I2C1
+config S3C_DEV_I2C
 	bool
 	help
-	  Compile in platform device definitions for I2C channel 1
-
-config S3C_DEV_I2C2
-	bool
-	help
-	  Compile in platform device definitions for I2C channel 2
+	  Compile in platform device definitions for I2C code
 
 config S3C_DEV_FB
 	bool
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index b59a6e4..d880c2d 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -37,10 +37,8 @@ obj-$(CONFIG_S3C24XX_DEV_UART)	+= dev-uart-s3c24xx.o
 obj-$(CONFIG_S3C64XX_DEV_UART)	+= dev-uart-s3c64xx.o
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HWMON)	+= dev-hwmon.o
-obj-y				+= dev-i2c0.o
-obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
-obj-$(CONFIG_S3C_DEV_I2C2)	+= dev-i2c2.o
 obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
+obj-$(CONFIG_S3C_DEV_I2C)	+= dev-i2c.o
 obj-y				+= dev-uart.o
 obj-$(CONFIG_S3C_DEV_USB_HOST)	+= dev-usb.o
 obj-$(CONFIG_S3C_DEV_USB_HSOTG)	+= dev-usb-hsotg.o
diff --git a/arch/arm/plat-samsung/dev-i2c.c b/arch/arm/plat-samsung/dev-i2c.c
new file mode 100644
index 0000000..67e19b5
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s3c/dev-i2c0.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 0
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+
+void __init s3c_i2c_set_platdata(void *src, int id)
+{
+	struct s3c2410_platform_i2c *pd = src;
+	struct s3c2410_platform_i2c *set;
+	set = s3c_device_get_defplatdata(SAMSUNG_DEVICE_I2C, id);
+	if (!set) {
+		printk(KERN_ERR "%s: no default platform data\n", __func__);
+		return;
+	}
+	if (!pd->cfg_gpio)
+		pd->cfg_gpio = set->cfg_gpio;
+	memcpy(set, pd, sizeof(struct s3c2410_platform_i2c));
+}
+
+struct s3c_pdev_template s3c_i2c_template __initdata = {
+	.type = SAMSUNG_DEVICE_I2C,
+	.resources = s3c_std_resources_4k,
+	.nr_res = 2,
+	.pdata_size = sizeof(struct s3c2410_platform_i2c),
+	.pdata_set = s3c_i2c_set_platdata,
+};
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
deleted file mode 100644
index 3a601c1..0000000
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c0.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 0
- *
- * 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC,
-		.end   = S3C_PA_IIC + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_IIC,
-		.end   = IRQ_IIC,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c0 = {
-	.name		  = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
-	.id		  = 0,
-#else
-	.id		  = -1,
-#endif
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
-	.flags		= 0,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data0;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c0_cfg_gpio;
-
-	s3c_device_i2c0.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
deleted file mode 100644
index 858ee2a..0000000
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c1.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 1
- *
- * 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC1,
-		.end   = S3C_PA_IIC1 + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_IIC1,
-		.end   = IRQ_IIC1,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c1 = {
-	.name		  = "s3c2410-i2c",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
-	.flags		= 0,
-	.bus_num	= 1,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data1;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c1_cfg_gpio;
-
-	s3c_device_i2c1.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
deleted file mode 100644
index 07036de..0000000
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c2.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * S3C series device definition for i2c device 2
- *
- * Based on plat-samsung/dev-i2c0.c
- *
- * 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC2,
-		.end   = S3C_PA_IIC2 + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_CAN0,
-		.end   = IRQ_CAN0,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c2 = {
-	.name		  = "s3c2410-i2c",
-	.id		  = 2,
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
-	.flags		= 0,
-	.bus_num	= 2,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data2;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c2_cfg_gpio;
-
-	s3c_device_i2c2.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index be06c19..6a1d2e1 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -23,6 +23,7 @@
 
 #include <plat/uart.h>
 #include <plat/fb.h>
+#include <plat/iic.h>
 #include <plat/sdhci.h>
 
 #define TEMPLATE_ENTRY(_type, _res) \
@@ -45,6 +46,7 @@ struct resource s3c_std_resources_4k[] __initdata = {
 static struct s3c_pdev_template *templates[] __initdata = {
 	s3c24xx_uart_template_p,
 	s3c64xx_uart_template_p,
+	s3c_i2c_template_p,
 	s3c_hsmmc_template_p,
 	s3c_fb_template_p,
 };
diff --git a/arch/arm/plat-samsung/include/plat/iic-core.h b/arch/arm/plat-samsung/include/plat/iic-core.h
deleted file mode 100644
index f182669..0000000
--- a/arch/arm/plat-samsung/include/plat/iic-core.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/iic-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - I2C Controller core functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_IIC_CORE_H
-#define __ASM_ARCH_IIC_CORE_H __FILE__
-
-/* These functions are only for use with the core support code, such as
- * the cpu specific initialisation code
- */
-
-/* re-define device name depending on support. */
-static inline void s3c_i2c0_setname(char *name)
-{
-	/* currently this device is always compiled in */
-	s3c_device_i2c0.name = name;
-}
-
-static inline void s3c_i2c1_setname(char *name)
-{
-#ifdef CONFIG_S3C_DEV_I2C1
-	s3c_device_i2c1.name = name;
-#endif
-}
-
-static inline void s3c_i2c2_setname(char *name)
-{
-#ifdef CONFIG_S3C_DEV_I2C2
-	s3c_device_i2c2.name = name;
-#endif
-}
-
-#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 133308b..5f77d94b 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -38,8 +38,8 @@ struct s3c2410_platform_i2c {
 };
 
 /**
- * s3c_i2c0_set_platdata - set platform data for i2c0 device
- * @i2c: The platform data to set, or NULL for default data.
+ * s3c_i2c_set_platdata - set platform data for i2c0 device
+ * @i2c: The platform data to set.
  *
  * Register the given platform data for use with the i2c0 device. This
  * call copies the platform data, so the caller can use __initdata for
@@ -47,18 +47,40 @@ struct s3c2410_platform_i2c {
  *
  * This call will set cfg_gpio if is null to the default platform
  * implementation.
- *
- * Any user of s3c_device_i2c0 should call this, even if it is with
- * NULL to ensure that the device is given the default platform data
- * as the driver will no longer carry defaults.
  */
-extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
-extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
-extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
-
-/* defined by architecture to configure gpio */
-extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
-extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
-extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c_set_platdata(void *i2c, int id);
+
+#ifdef CONFIG_S3C_DEV_I2C
+extern struct s3c_pdev_template s3c_i2c_template;
+#define s3c_i2c_template_p (&s3c_i2c_template)
+#else
+#define s3c_i2c_template_p NULL
+#endif
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+#ifdef CONFIG_S5PV210_SETUP_I2C0
+extern struct s3c2410_platform_i2c s5pv210_i2c0_def_platdata;
+#define s5pv210_i2c0_def_platdata_p (&s5pv210_i2c0_def_platdata)
+#else
+#define s5pv210_i2c0_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C1
+extern struct s3c2410_platform_i2c s5pv210_i2c1_def_platdata;
+#define s5pv210_i2c1_def_platdata_p (&s5pv210_i2c1_def_platdata)
+#else
+#define s5pv210_i2c1_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C2
+extern struct s3c2410_platform_i2c s5pv210_i2c2_def_platdata;
+#define s5pv210_i2c2_def_platdata_p (&s5pv210_i2c2_def_platdata)
+#else
+#define s5pv210_i2c2_def_platdata_p NULL
+#endif
+
 
 #endif /* __ASM_ARCH_IIC_H */
-- 
1.7.1.569.g6f426

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

* [PATCH 8/9] ARM: S5PV210: convert i2c to device-table
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Convert s3c-i2c platform device initialization to device-table approach.
The conversion is performed only for S5PV210 SoC.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig                 |   12 +++-
 arch/arm/mach-s5pv210/Makefile                |    4 +-
 arch/arm/mach-s5pv210/cpu.c                   |    6 --
 arch/arm/mach-s5pv210/dev-table.c             |   18 ++++++
 arch/arm/mach-s5pv210/setup-i2c.c             |   81 +++++++++++++++++++++++++
 arch/arm/mach-s5pv210/setup-i2c0.c            |   30 ---------
 arch/arm/mach-s5pv210/setup-i2c1.c            |   30 ---------
 arch/arm/mach-s5pv210/setup-i2c2.c            |   30 ---------
 arch/arm/plat-samsung/Kconfig                 |    9 +--
 arch/arm/plat-samsung/Makefile                |    4 +-
 arch/arm/plat-samsung/dev-i2c.c               |   43 +++++++++++++
 arch/arm/plat-samsung/dev-i2c0.c              |   72 ----------------------
 arch/arm/plat-samsung/dev-i2c1.c              |   69 ---------------------
 arch/arm/plat-samsung/dev-i2c2.c              |   70 ---------------------
 arch/arm/plat-samsung/dev_templates.c         |    2 +
 arch/arm/plat-samsung/include/plat/iic-core.h |   42 -------------
 arch/arm/plat-samsung/include/plat/iic.h      |   50 +++++++++++----
 17 files changed, 194 insertions(+), 378 deletions(-)
 create mode 100644 arch/arm/mach-s5pv210/setup-i2c.c
 delete mode 100644 arch/arm/mach-s5pv210/setup-i2c0.c
 delete mode 100644 arch/arm/mach-s5pv210/setup-i2c1.c
 delete mode 100644 arch/arm/mach-s5pv210/setup-i2c2.c
 create mode 100644 arch/arm/plat-samsung/dev-i2c.c
 delete mode 100644 arch/arm/plat-samsung/dev-i2c0.c
 delete mode 100644 arch/arm/plat-samsung/dev-i2c1.c
 delete mode 100644 arch/arm/plat-samsung/dev-i2c2.c
 delete mode 100644 arch/arm/plat-samsung/include/plat/iic-core.h

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 734c0b7..4034ea8 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -17,15 +17,23 @@ config CPU_S5PV210
 	help
 	  Enable S5PV210 CPU support
 
+config S5PV210_SETUP_I2C0
+	select S3C_DEV_I2C
+	bool
+	help
+	  Common setup code for i2c0 bus.
+
 config S5PV210_SETUP_I2C1
+	select S3C_DEV_I2C
 	bool
 	help
-	  Common setup code for i2c bus 1.
+	  Common setup code for i2c1 bus.
 
 config S5PV210_SETUP_I2C2
+	select S3C_DEV_I2C
 	bool
 	help
-	  Common setup code for i2c bus 2.
+	  Common setup code for i2c2 bus.
 
 config S5PV210_SETUP_IDE
 	bool
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index a5fd9ae..8148254 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -13,7 +13,6 @@ obj-				:=
 # Core support for S5PV210 system
 
 obj-$(CONFIG_CPU_S5PV210)	+= cpu.o clock.o dma.o gpiolib.o
-obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
 obj-$(CONFIG_CPU_S5PV210)	+= dev-table.o
 
 # machine support
@@ -29,8 +28,7 @@ obj-y				+= dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
 
 obj-$(CONFIG_S5PV210_SETUP_FB_24BPP)	+= setup-fb-24bpp.o
-obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
-obj-$(CONFIG_S5PV210_SETUP_I2C2) 	+= setup-i2c2.o
+obj-$(CONFIG_S3C_DEV_I2C)		+= setup-i2c.o
 obj-$(CONFIG_S5PV210_SETUP_IDE)		+= setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)	+= setup-keypad.o
 obj-$(CONFIG_S3C_DEV_HSMMC)		+= setup-sdhci.o
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 5f5ab1e..9806ba0 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -35,7 +35,6 @@
 #include <plat/adc-core.h>
 #include <plat/ata-core.h>
 #include <plat/fimc-core.h>
-#include <plat/iic-core.h>
 #include <plat/keypad-core.h>
 #include <plat/sdhci.h>
 #include <plat/reset.h>
@@ -98,11 +97,6 @@ void __init s5pv210_map_io(void)
 	s3c_fimc_setname(1, "s5pv210-fimc");
 	s3c_fimc_setname(2, "s5pv210-fimc");
 
-	/* the i2c devices are directly compatible with s3c2440 */
-	s3c_i2c0_setname("s3c2440-i2c");
-	s3c_i2c1_setname("s3c2440-i2c");
-	s3c_i2c2_setname("s3c2440-i2c");
-
 	/* Use s5pv210-keypad instead of samsung-keypad */
 	samsung_keypad_setname("s5pv210-keypad");
 }
diff --git a/arch/arm/mach-s5pv210/dev-table.c b/arch/arm/mach-s5pv210/dev-table.c
index b88b43d..559413f 100644
--- a/arch/arm/mach-s5pv210/dev-table.c
+++ b/arch/arm/mach-s5pv210/dev-table.c
@@ -99,6 +99,24 @@ struct s3c_pdev_table s5pv210_dev_table[] __initdata = {
 		.res	= {S5PV210_PA_HSMMC(2), IRQ_HSMMC2},
 		.defpdata = s5pv210_hsmmc2_def_platdata_p,
 	}, {
+		.type	= SAMSUNG_DEVICE_I2C,
+		.name	= "s3c2440-i2c",
+		.index	= 0,
+		.res	= {S5PV210_PA_IIC0, IRQ_IIC},
+		.defpdata = s5pv210_i2c0_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_I2C,
+		.name	= "s3c2440-i2c",
+		.index	= 1,
+		.res	= {S5PV210_PA_IIC1, IRQ_IIC1},
+		.defpdata = s5pv210_i2c0_def_platdata_p,
+	}, {
+		.type	= SAMSUNG_DEVICE_I2C,
+		.name	= "s3c2440-i2c",
+		.index	= 2,
+		.res	= {S5PV210_PA_IIC2, IRQ_CAN0},
+		.defpdata = s5pv210_i2c0_def_platdata_p,
+	}, {
 		.type	= SAMSUNG_DEVICE_FB,
 		.index	= -1,
 		.name	= "s3c-fb",
diff --git a/arch/arm/mach-s5pv210/setup-i2c.c b/arch/arm/mach-s5pv210/setup-i2c.c
new file mode 100644
index 0000000..c9c6f3a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-i2c.c
@@ -0,0 +1,81 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+#include <mach/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+#ifdef CONFIG_S5PV210_SETUP_I2C0
+
+static void s5pv210_i2c0_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
+}
+
+struct s3c2410_platform_i2c s5pv210_i2c0_def_platdata __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+	.cfg_gpio	= &s5pv210_i2c0_cfg_gpio,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C1
+
+static void s5pv210_i2c1_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
+}
+
+struct s3c2410_platform_i2c s5pv210_i2c1_def_platdata __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+	.cfg_gpio	= &s5pv210_i2c1_cfg_gpio,
+};
+
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C2
+
+static void s5pv210_i2c2_cfg_gpio(struct platform_device *dev)
+{
+	s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
+	s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
+	s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
+}
+
+struct s3c2410_platform_i2c s5pv210_i2c2_def_platdata __initdata = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.frequency	= 100*1000,
+	.sda_delay	= 100,
+	.cfg_gpio	= &s5pv210_i2c2_cfg_gpio,
+};
+
+#endif
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
deleted file mode 100644
index d38f7cb..0000000
--- a/arch/arm/mach-s5pv210/setup-i2c0.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C0 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
deleted file mode 100644
index 148bb78..0000000
--- a/arch/arm/mach-s5pv210/setup-i2c1.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/setup-i2c1.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C1 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c1.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
deleted file mode 100644
index 2396cb8..0000000
--- a/arch/arm/mach-s5pv210/setup-i2c2.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/setup-i2c2.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C2 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c2_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 57c791c..f60603b 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -165,15 +165,10 @@ config S3C_DEV_HWMON
 	help
 	    Compile in platform device definitions for HWMON
 
-config S3C_DEV_I2C1
+config S3C_DEV_I2C
 	bool
 	help
-	  Compile in platform device definitions for I2C channel 1
-
-config S3C_DEV_I2C2
-	bool
-	help
-	  Compile in platform device definitions for I2C channel 2
+	  Compile in platform device definitions for I2C code
 
 config S3C_DEV_FB
 	bool
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index b59a6e4..d880c2d 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -37,10 +37,8 @@ obj-$(CONFIG_S3C24XX_DEV_UART)	+= dev-uart-s3c24xx.o
 obj-$(CONFIG_S3C64XX_DEV_UART)	+= dev-uart-s3c64xx.o
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HWMON)	+= dev-hwmon.o
-obj-y				+= dev-i2c0.o
-obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
-obj-$(CONFIG_S3C_DEV_I2C2)	+= dev-i2c2.o
 obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
+obj-$(CONFIG_S3C_DEV_I2C)	+= dev-i2c.o
 obj-y				+= dev-uart.o
 obj-$(CONFIG_S3C_DEV_USB_HOST)	+= dev-usb.o
 obj-$(CONFIG_S3C_DEV_USB_HSOTG)	+= dev-usb-hsotg.o
diff --git a/arch/arm/plat-samsung/dev-i2c.c b/arch/arm/plat-samsung/dev-i2c.c
new file mode 100644
index 0000000..67e19b5
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s3c/dev-i2c0.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 0
+ *
+ * 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/dev-core.h>
+
+void __init s3c_i2c_set_platdata(void *src, int id)
+{
+	struct s3c2410_platform_i2c *pd = src;
+	struct s3c2410_platform_i2c *set;
+	set = s3c_device_get_defplatdata(SAMSUNG_DEVICE_I2C, id);
+	if (!set) {
+		printk(KERN_ERR "%s: no default platform data\n", __func__);
+		return;
+	}
+	if (!pd->cfg_gpio)
+		pd->cfg_gpio = set->cfg_gpio;
+	memcpy(set, pd, sizeof(struct s3c2410_platform_i2c));
+}
+
+struct s3c_pdev_template s3c_i2c_template __initdata = {
+	.type = SAMSUNG_DEVICE_I2C,
+	.resources = s3c_std_resources_4k,
+	.nr_res = 2,
+	.pdata_size = sizeof(struct s3c2410_platform_i2c),
+	.pdata_set = s3c_i2c_set_platdata,
+};
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
deleted file mode 100644
index 3a601c1..0000000
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c0.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 0
- *
- * 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC,
-		.end   = S3C_PA_IIC + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_IIC,
-		.end   = IRQ_IIC,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c0 = {
-	.name		  = "s3c2410-i2c",
-#ifdef CONFIG_S3C_DEV_I2C1
-	.id		  = 0,
-#else
-	.id		  = -1,
-#endif
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
-	.flags		= 0,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data0;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c0_cfg_gpio;
-
-	s3c_device_i2c0.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
deleted file mode 100644
index 858ee2a..0000000
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c1.c
- *
- * Copyright 2008-2009 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * S3C series device definition for i2c device 1
- *
- * 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC1,
-		.end   = S3C_PA_IIC1 + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_IIC1,
-		.end   = IRQ_IIC1,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c1 = {
-	.name		  = "s3c2410-i2c",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
-	.flags		= 0,
-	.bus_num	= 1,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data1;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c1_cfg_gpio;
-
-	s3c_device_i2c1.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
deleted file mode 100644
index 07036de..0000000
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-i2c2.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * S3C series device definition for i2c device 2
- *
- * Based on plat-samsung/dev-i2c0.c
- *
- * 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/regs-iic.h>
-#include <plat/iic.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_i2c_resource[] = {
-	[0] = {
-		.start = S3C_PA_IIC2,
-		.end   = S3C_PA_IIC2 + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_CAN0,
-		.end   = IRQ_CAN0,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device s3c_device_i2c2 = {
-	.name		  = "s3c2410-i2c",
-	.id		  = 2,
-	.num_resources	  = ARRAY_SIZE(s3c_i2c_resource),
-	.resource	  = s3c_i2c_resource,
-};
-
-static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
-	.flags		= 0,
-	.bus_num	= 2,
-	.slave_addr	= 0x10,
-	.frequency	= 100*1000,
-	.sda_delay	= 100,
-};
-
-void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
-{
-	struct s3c2410_platform_i2c *npd;
-
-	if (!pd)
-		pd = &default_i2c_data2;
-
-	npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
-	if (!npd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	else if (!npd->cfg_gpio)
-		npd->cfg_gpio = s3c_i2c2_cfg_gpio;
-
-	s3c_device_i2c2.dev.platform_data = npd;
-}
diff --git a/arch/arm/plat-samsung/dev_templates.c b/arch/arm/plat-samsung/dev_templates.c
index be06c19..6a1d2e1 100644
--- a/arch/arm/plat-samsung/dev_templates.c
+++ b/arch/arm/plat-samsung/dev_templates.c
@@ -23,6 +23,7 @@
 
 #include <plat/uart.h>
 #include <plat/fb.h>
+#include <plat/iic.h>
 #include <plat/sdhci.h>
 
 #define TEMPLATE_ENTRY(_type, _res) \
@@ -45,6 +46,7 @@ struct resource s3c_std_resources_4k[] __initdata = {
 static struct s3c_pdev_template *templates[] __initdata = {
 	s3c24xx_uart_template_p,
 	s3c64xx_uart_template_p,
+	s3c_i2c_template_p,
 	s3c_hsmmc_template_p,
 	s3c_fb_template_p,
 };
diff --git a/arch/arm/plat-samsung/include/plat/iic-core.h b/arch/arm/plat-samsung/include/plat/iic-core.h
deleted file mode 100644
index f182669..0000000
--- a/arch/arm/plat-samsung/include/plat/iic-core.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/iic-core.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - I2C Controller core functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_IIC_CORE_H
-#define __ASM_ARCH_IIC_CORE_H __FILE__
-
-/* These functions are only for use with the core support code, such as
- * the cpu specific initialisation code
- */
-
-/* re-define device name depending on support. */
-static inline void s3c_i2c0_setname(char *name)
-{
-	/* currently this device is always compiled in */
-	s3c_device_i2c0.name = name;
-}
-
-static inline void s3c_i2c1_setname(char *name)
-{
-#ifdef CONFIG_S3C_DEV_I2C1
-	s3c_device_i2c1.name = name;
-#endif
-}
-
-static inline void s3c_i2c2_setname(char *name)
-{
-#ifdef CONFIG_S3C_DEV_I2C2
-	s3c_device_i2c2.name = name;
-#endif
-}
-
-#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 133308b..5f77d94b 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -38,8 +38,8 @@ struct s3c2410_platform_i2c {
 };
 
 /**
- * s3c_i2c0_set_platdata - set platform data for i2c0 device
- * @i2c: The platform data to set, or NULL for default data.
+ * s3c_i2c_set_platdata - set platform data for i2c0 device
+ * @i2c: The platform data to set.
  *
  * Register the given platform data for use with the i2c0 device. This
  * call copies the platform data, so the caller can use __initdata for
@@ -47,18 +47,40 @@ struct s3c2410_platform_i2c {
  *
  * This call will set cfg_gpio if is null to the default platform
  * implementation.
- *
- * Any user of s3c_device_i2c0 should call this, even if it is with
- * NULL to ensure that the device is given the default platform data
- * as the driver will no longer carry defaults.
  */
-extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
-extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
-extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
-
-/* defined by architecture to configure gpio */
-extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
-extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
-extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c_set_platdata(void *i2c, int id);
+
+#ifdef CONFIG_S3C_DEV_I2C
+extern struct s3c_pdev_template s3c_i2c_template;
+#define s3c_i2c_template_p (&s3c_i2c_template)
+#else
+#define s3c_i2c_template_p NULL
+#endif
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+#ifdef CONFIG_S5PV210_SETUP_I2C0
+extern struct s3c2410_platform_i2c s5pv210_i2c0_def_platdata;
+#define s5pv210_i2c0_def_platdata_p (&s5pv210_i2c0_def_platdata)
+#else
+#define s5pv210_i2c0_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C1
+extern struct s3c2410_platform_i2c s5pv210_i2c1_def_platdata;
+#define s5pv210_i2c1_def_platdata_p (&s5pv210_i2c1_def_platdata)
+#else
+#define s5pv210_i2c1_def_platdata_p NULL
+#endif
+
+#ifdef CONFIG_S5PV210_SETUP_I2C2
+extern struct s3c2410_platform_i2c s5pv210_i2c2_def_platdata;
+#define s5pv210_i2c2_def_platdata_p (&s5pv210_i2c2_def_platdata)
+#else
+#define s5pv210_i2c2_def_platdata_p NULL
+#endif
+
 
 #endif /* __ASM_ARCH_IIC_H */
-- 
1.7.1.569.g6f426

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

* [PATCH 9/9] ARM: S5PV210: add i2c device on Aquila
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:03   ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: m.szyprowski, kyungmin.park, kgene.kim, ben-linux

Add i2c bus number 0 on Aquila machine to test i2c device-table approach.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig       |    1 +
 arch/arm/mach-s5pv210/mach-aquila.c |    6 ++++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 4034ea8..8be6195 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -90,6 +90,7 @@ config MACH_AQUILA
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
 	select S5PV210_SETUP_FB_24BPP
+	select S5PV210_SETUP_I2C0
 	select S5PV210_SETUP_SDHCI0
 	select S5PV210_SETUP_SDHCI1
 	select S5PV210_SETUP_SDHCI2
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index cb79256..81d2162 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -469,7 +469,10 @@ static void aquila_setup_sdhci(void)
 {
 	gpio_request(AQUILA_EXT_FLASH_EN, "FLASH_EN");
 	gpio_direction_output(AQUILA_EXT_FLASH_EN, 1);
+};
 
+/* I2C0: CAM */
+static struct i2c_board_info i2c0_devs[] __initdata = {
 };
 
 static struct platform_device *aquila_devices[] __initdata = {
@@ -481,6 +484,7 @@ static struct platform_device *aquila_devices[] __initdata = {
 };
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_I2C,		.index = 0 },
 	{ .type = SAMSUNG_DEVICE_FB,		.index = -1, .pdata = &aquila_lcd_pdata},
 	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
 	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 0, .pdata = &aquila_hsmmc0_data},
@@ -501,6 +505,8 @@ static void __init aquila_machine_init(void)
 	aquila_pmic_init();
 	i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
 			ARRAY_SIZE(i2c_gpio_pmic_devs));
+	i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+
 	/* SDHCI */
 	aquila_setup_sdhci();
 
-- 
1.7.1.569.g6f426

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

* [PATCH 9/9] ARM: S5PV210: add i2c device on Aquila
@ 2010-08-11 12:03   ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Add i2c bus number 0 on Aquila machine to test i2c device-table approach.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-s5pv210/Kconfig       |    1 +
 arch/arm/mach-s5pv210/mach-aquila.c |    6 ++++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 4034ea8..8be6195 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -90,6 +90,7 @@ config MACH_AQUILA
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
 	select S5PV210_SETUP_FB_24BPP
+	select S5PV210_SETUP_I2C0
 	select S5PV210_SETUP_SDHCI0
 	select S5PV210_SETUP_SDHCI1
 	select S5PV210_SETUP_SDHCI2
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index cb79256..81d2162 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -469,7 +469,10 @@ static void aquila_setup_sdhci(void)
 {
 	gpio_request(AQUILA_EXT_FLASH_EN, "FLASH_EN");
 	gpio_direction_output(AQUILA_EXT_FLASH_EN, 1);
+};
 
+/* I2C0: CAM */
+static struct i2c_board_info i2c0_devs[] __initdata = {
 };
 
 static struct platform_device *aquila_devices[] __initdata = {
@@ -481,6 +484,7 @@ static struct platform_device *aquila_devices[] __initdata = {
 };
 
 static struct s3c_devtable aquila_devtable[] __initdata = {
+	{ .type = SAMSUNG_DEVICE_I2C,		.index = 0 },
 	{ .type = SAMSUNG_DEVICE_FB,		.index = -1, .pdata = &aquila_lcd_pdata},
 	{ .type = SAMSUNG_DEVICE_ONENAND,	.index = -1 },
 	{ .type = SAMSUNG_DEVICE_SDHCI,		.index = 0, .pdata = &aquila_hsmmc0_data},
@@ -501,6 +505,8 @@ static void __init aquila_machine_init(void)
 	aquila_pmic_init();
 	i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
 			ARRAY_SIZE(i2c_gpio_pmic_devs));
+	i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+
 	/* SDHCI */
 	aquila_setup_sdhci();
 
-- 
1.7.1.569.g6f426

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

* Re: [PATCH/RFC] Samsung device-table approach
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-11 12:40   ` Ameya Palande
  -1 siblings, 0 replies; 28+ messages in thread
From: Ameya Palande @ 2010-08-11 12:40 UTC (permalink / raw)
  To: ext Marek Szyprowski
  Cc: linux-samsung-soc, linux-arm-kernel, kyungmin.park, kgene.kim, ben-linux

Hi Marek,

On Wed, 2010-08-11 at 14:03 +0200, ext Marek Szyprowski wrote:
> Hello,
> 
> I would like to start the discussion on the redesign of the way the
> Samsung platform devices are defined. The current solution has some
> important disadvantages that blocks the further kernel development.

Forgive me about my ignorance about device tables, but I was wondering
if there is any similarity between device tables and Simple Firmware
Interface tables which are already in mainline?

Cheers,
Ameya.

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

* [PATCH/RFC] Samsung device-table approach
@ 2010-08-11 12:40   ` Ameya Palande
  0 siblings, 0 replies; 28+ messages in thread
From: Ameya Palande @ 2010-08-11 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Wed, 2010-08-11 at 14:03 +0200, ext Marek Szyprowski wrote:
> Hello,
> 
> I would like to start the discussion on the redesign of the way the
> Samsung platform devices are defined. The current solution has some
> important disadvantages that blocks the further kernel development.

Forgive me about my ignorance about device tables, but I was wondering
if there is any similarity between device tables and Simple Firmware
Interface tables which are already in mainline?

Cheers,
Ameya.

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

* RE: [PATCH/RFC] Samsung device-table approach
  2010-08-11 12:40   ` Ameya Palande
@ 2010-08-11 15:02     ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 15:02 UTC (permalink / raw)
  To: 'Ameya Palande'
  Cc: kgene.kim, kyungmin.park, linux-samsung-soc, ben-linux, linux-arm-kernel

Hello,

On Wednesday, August 11, 2010 2:40 PM Ameya Palande wrote:

> On Wed, 2010-08-11 at 14:03 +0200, ext Marek Szyprowski wrote:
> > Hello,
> >
> > I would like to start the discussion on the redesign of the way the
> > Samsung platform devices are defined. The current solution has some
> > important disadvantages that blocks the further kernel development.
> 
> Forgive me about my ignorance about device tables, but I was wondering
> if there is any similarity between device tables and Simple Firmware
> Interface tables which are already in mainline?

Well, this will be a funny discussion of two ignoramuses, as I know
almost nothing about Simple Firmware Interface. 

However I've read briefly about it and I see that SFI device tables are
something that is being defined at a boot loader level.

Current mainline kernel for Samsung SoC already contains definitions
for many devices (well, they should be called 'integrated peripherals'
in fact). The boot loader provides only a very basic information to
kernel (just the machine id, cpu type, amount of memory and kernel
command line). No other information (especially about any device
detected in the system) is provided.

The proposed device-table approach for Samsung SoC is just the other
(imho more convenient and more powerful) way of defining the platform
devices and their resources for the Samsung integrated peripherals.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

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

* [PATCH/RFC] Samsung device-table approach
@ 2010-08-11 15:02     ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-11 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Wednesday, August 11, 2010 2:40 PM Ameya Palande wrote:

> On Wed, 2010-08-11 at 14:03 +0200, ext Marek Szyprowski wrote:
> > Hello,
> >
> > I would like to start the discussion on the redesign of the way the
> > Samsung platform devices are defined. The current solution has some
> > important disadvantages that blocks the further kernel development.
> 
> Forgive me about my ignorance about device tables, but I was wondering
> if there is any similarity between device tables and Simple Firmware
> Interface tables which are already in mainline?

Well, this will be a funny discussion of two ignoramuses, as I know
almost nothing about Simple Firmware Interface. 

However I've read briefly about it and I see that SFI device tables are
something that is being defined at a boot loader level.

Current mainline kernel for Samsung SoC already contains definitions
for many devices (well, they should be called 'integrated peripherals'
in fact). The boot loader provides only a very basic information to
kernel (just the machine id, cpu type, amount of memory and kernel
command line). No other information (especially about any device
detected in the system) is provided.

The proposed device-table approach for Samsung SoC is just the other
(imho more convenient and more powerful) way of defining the platform
devices and their resources for the Samsung integrated peripherals.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

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

* Re: [PATCH/RFC] Samsung device-table approach
  2010-08-11 12:03 ` Marek Szyprowski
@ 2010-08-12  2:48   ` Jassi Brar
  -1 siblings, 0 replies; 28+ messages in thread
From: Jassi Brar @ 2010-08-12  2:48 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-samsung-soc, linux-arm-kernel, kyungmin.park, kgene.kim, ben-linux

On Wed, Aug 11, 2010 at 9:03 PM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Hello,
>
> I would like to start the discussion on the redesign of the way the
> Samsung platform devices are defined. The current solution has some
> important disadvantages that blocks the further kernel development.
>
> Samsung SoC family is quite large. Mainline kernel already has support
> for more than 8 representatives, each having different memory and irq
> map.
>
> Currently most of the base address and irq differences are hidden behind
> the includes and some common defines (usualy named S3C_PA_*). Some
> devices also have different variants that are specified by changing the
> device name to include the SoC version in it. Others have SoC specific
> callbacks (like gpio pin configuration) that are provided thought the
> platform data.
>
> There is a lot of code that is needed to handle all these variants and
> differences. It also differs in term of style and a way how some
> simmilar things are performed (like changing the device name or
> providing the default platform data).
>
> In 2009 Ben Dooks did a research and proposed a solution that is called
> a device table. This solution solves the most problematic issue.
> Different base addresses and irqs can be easily provided for the same
> device on different version SoC systems. This is achieved by having a
> single table for each SoC that contains all these resources and create
> all required platform devices dynamically on SoC init.
>
> The proposed solution was enough for s3c24xx SoC devices and some early
> s3c64xx devices. However since then some new devices has been merged to
> mainline, mainly for s5p SoC series. These devices have more than one
> base address or irq and does not fit well into that framework.
IMO it is safe to assume such devices have slim chances to become the majority.
The 'extra' parameters will be present in every instance of the IP
in the SoCs that have them, only their value may differ. So, why not
define a new structure with fields for such 'extra' parameters for such
devices and make them available to drivers from platform_data.
That will :-
 a) Keep the original and simple design of Ben Dooks intact.
 b) Avoid taking space more than needed for majority of 'simple' devices.


> I've extended his approach to handle such more advanced devices. The new
> version is capable of setting up devices with more than one irq,
> physical register areas or even a dma channel.
>
> I've also added support for the default platform data. It has been
> designed in such a way that it can handle different default data for
> each device instance for each SoC system. This requires a bit of C
> preprocessor in the includes but make it much easier to register
> particular device. With this new solution there is no need for calling a
> function for setting platform data in machine startup.
>
> The solution has been designed with the following assumptions:
> 1. to reduce the number of static structures compiled into the kernel
> that are not used at all
> 2. to reduce the memory used by the unused static structures once kernel
> has booted
People might later want to build and load drivers for 'unused' device ?

Also, since there is already underway a good effort towards unifying
kernel builds for different platforms at ARM level, it might be worthwile
to look at the problem from POV vaster than Samsung. And then,
implement only Samsung specific need to work with that stub.

my 2 cents.

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

* [PATCH/RFC] Samsung device-table approach
@ 2010-08-12  2:48   ` Jassi Brar
  0 siblings, 0 replies; 28+ messages in thread
From: Jassi Brar @ 2010-08-12  2:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 11, 2010 at 9:03 PM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Hello,
>
> I would like to start the discussion on the redesign of the way the
> Samsung platform devices are defined. The current solution has some
> important disadvantages that blocks the further kernel development.
>
> Samsung SoC family is quite large. Mainline kernel already has support
> for more than 8 representatives, each having different memory and irq
> map.
>
> Currently most of the base address and irq differences are hidden behind
> the includes and some common defines (usualy named S3C_PA_*). Some
> devices also have different variants that are specified by changing the
> device name to include the SoC version in it. Others have SoC specific
> callbacks (like gpio pin configuration) that are provided thought the
> platform data.
>
> There is a lot of code that is needed to handle all these variants and
> differences. It also differs in term of style and a way how some
> simmilar things are performed (like changing the device name or
> providing the default platform data).
>
> In 2009 Ben Dooks did a research and proposed a solution that is called
> a device table. This solution solves the most problematic issue.
> Different base addresses and irqs can be easily provided for the same
> device on different version SoC systems. This is achieved by having a
> single table for each SoC that contains all these resources and create
> all required platform devices dynamically on SoC init.
>
> The proposed solution was enough for s3c24xx SoC devices and some early
> s3c64xx devices. However since then some new devices has been merged to
> mainline, mainly for s5p SoC series. These devices have more than one
> base address or irq and does not fit well into that framework.
IMO it is safe to assume such devices have slim chances to become the majority.
The 'extra' parameters will be present in every instance of the IP
in the SoCs that have them, only their value may differ. So, why not
define a new structure with fields for such 'extra' parameters for such
devices and make them available to drivers from platform_data.
That will :-
 a) Keep the original and simple design of Ben Dooks intact.
 b) Avoid taking space more than needed for majority of 'simple' devices.


> I've extended his approach to handle such more advanced devices. The new
> version is capable of setting up devices with more than one irq,
> physical register areas or even a dma channel.
>
> I've also added support for the default platform data. It has been
> designed in such a way that it can handle different default data for
> each device instance for each SoC system. This requires a bit of C
> preprocessor in the includes but make it much easier to register
> particular device. With this new solution there is no need for calling a
> function for setting platform data in machine startup.
>
> The solution has been designed with the following assumptions:
> 1. to reduce the number of static structures compiled into the kernel
> that are not used at all
> 2. to reduce the memory used by the unused static structures once kernel
> has booted
People might later want to build and load drivers for 'unused' device ?

Also, since there is already underway a good effort towards unifying
kernel builds for different platforms at ARM level, it might be worthwile
to look at the problem from POV vaster than Samsung. And then,
implement only Samsung specific need to work with that stub.

my 2 cents.

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

* RE: [PATCH/RFC] Samsung device-table approach
  2010-08-12  2:48   ` Jassi Brar
@ 2010-08-12  6:31     ` Marek Szyprowski
  -1 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-12  6:31 UTC (permalink / raw)
  To: 'Jassi Brar'
  Cc: linux-samsung-soc, linux-arm-kernel, kyungmin.park, kgene.kim, ben-linux

Hello,

On Thursday, August 12, 2010 4:49 AM Jassi Brar wrote:

> On Wed, Aug 11, 2010 at 9:03 PM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > I would like to start the discussion on the redesign of the way the
> > Samsung platform devices are defined. The current solution has some
> > important disadvantages that blocks the further kernel development.
> >
> > Samsung SoC family is quite large. Mainline kernel already has support
> > for more than 8 representatives, each having different memory and irq
> > map.
> >
> > Currently most of the base address and irq differences are hidden behind
> > the includes and some common defines (usualy named S3C_PA_*). Some
> > devices also have different variants that are specified by changing the
> > device name to include the SoC version in it. Others have SoC specific
> > callbacks (like gpio pin configuration) that are provided thought the
> > platform data.
> >
> > There is a lot of code that is needed to handle all these variants and
> > differences. It also differs in term of style and a way how some
> > simmilar things are performed (like changing the device name or
> > providing the default platform data).
> >
> > In 2009 Ben Dooks did a research and proposed a solution that is called
> > a device table. This solution solves the most problematic issue.
> > Different base addresses and irqs can be easily provided for the same
> > device on different version SoC systems. This is achieved by having a
> > single table for each SoC that contains all these resources and create
> > all required platform devices dynamically on SoC init.
> >
> > The proposed solution was enough for s3c24xx SoC devices and some early
> > s3c64xx devices. However since then some new devices has been merged to
> > mainline, mainly for s5p SoC series. These devices have more than one
> > base address or irq and does not fit well into that framework.

> IMO it is safe to assume such devices have slim chances to become the
> majority.

Maybe they are not a majority, but I've already found that this applies
to the following devices: OneNAND, RTC, FrameBuffer, ADC, AC97, PCM,
IIS-64xx, SPI-64xx. With the original solution all these devices will
require their own resource template per each SoC. IMHO that's both 
inconvenient and ineffective in terms of space used by kernel static
structures.

> The 'extra' parameters will be present in every instance of the IP
> in the SoCs that have them, only their value may differ. So, why not
> define a new structure with fields for such 'extra' parameters for such
> devices and make them available to drivers from platform_data.
> That will :-
>  a) Keep the original and simple design of Ben Dooks intact.

I've analyzed such solution and found that it would be hard to define
the rewrite rules in a separate array and place it into __initdata section.
You would need to create such arrays separately and put the pointers to them
in the real device table. This way you lose the advantage of having all
parameters for a single device defined in the same place, in a compact way.
A separate array for the resources wouldn't also save much space.

>  b) Avoid taking space more than needed for majority of 'simple' devices.

I don't think that 12 bytes per such simple device entry is a huge overhead.
I've currently defined maximum number of resources (S3C_MAX_RESOURCES
define) to 6, but it can be reduced to 5 if we really want to save space
as much as possible. It is just a proposition. Note that all these device
table arrays are placed in __initdata section and will be dropped once the
system boots. The resource array for the simple device would contain 4 
(or 3 if we reduce the S3C_MAX_RESOURCES to 5) zeros. Such arrays compress
quite well so it shouldn't have much impact on the kernel image size.

> > I've extended his approach to handle such more advanced devices. The new
> > version is capable of setting up devices with more than one irq,
> > physical register areas or even a dma channel.
> >
> > I've also added support for the default platform data. It has been
> > designed in such a way that it can handle different default data for
> > each device instance for each SoC system. This requires a bit of C
> > preprocessor in the includes but make it much easier to register
> > particular device. With this new solution there is no need for calling a
> > function for setting platform data in machine startup.
> >
> > The solution has been designed with the following assumptions:
> > 1. to reduce the number of static structures compiled into the kernel
> > that are not used at all
> > 2. to reduce the memory used by the unused static structures once kernel
> > has booted

> People might later want to build and load drivers for 'unused' device ?

It would work exactly as in the current implementation. Platform devices are
instantiated during machine startup and each machine maintainer knows which
devices should be registered. This has nothing to the device drivers. They
can be built as modules and inserted later.

> Also, since there is already underway a good effort towards unifying
> kernel builds for different platforms at ARM level, it might be worthwile
> to look at the problem from POV vaster than Samsung. And then,
> implement only Samsung specific need to work with that stub.

I'm not really sure that there are other arm platforms which has such a lot
of variants of devices, that depend on particular version of SoC.

Anyway, I will check again how this is handled on other platforms.

> my 2 cents.

Thanks for your comments!

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

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

* [PATCH/RFC] Samsung device-table approach
@ 2010-08-12  6:31     ` Marek Szyprowski
  0 siblings, 0 replies; 28+ messages in thread
From: Marek Szyprowski @ 2010-08-12  6:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Thursday, August 12, 2010 4:49 AM Jassi Brar wrote:

> On Wed, Aug 11, 2010 at 9:03 PM, Marek Szyprowski
> <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > I would like to start the discussion on the redesign of the way the
> > Samsung platform devices are defined. The current solution has some
> > important disadvantages that blocks the further kernel development.
> >
> > Samsung SoC family is quite large. Mainline kernel already has support
> > for more than 8 representatives, each having different memory and irq
> > map.
> >
> > Currently most of the base address and irq differences are hidden behind
> > the includes and some common defines (usualy named S3C_PA_*). Some
> > devices also have different variants that are specified by changing the
> > device name to include the SoC version in it. Others have SoC specific
> > callbacks (like gpio pin configuration) that are provided thought the
> > platform data.
> >
> > There is a lot of code that is needed to handle all these variants and
> > differences. It also differs in term of style and a way how some
> > simmilar things are performed (like changing the device name or
> > providing the default platform data).
> >
> > In 2009 Ben Dooks did a research and proposed a solution that is called
> > a device table. This solution solves the most problematic issue.
> > Different base addresses and irqs can be easily provided for the same
> > device on different version SoC systems. This is achieved by having a
> > single table for each SoC that contains all these resources and create
> > all required platform devices dynamically on SoC init.
> >
> > The proposed solution was enough for s3c24xx SoC devices and some early
> > s3c64xx devices. However since then some new devices has been merged to
> > mainline, mainly for s5p SoC series. These devices have more than one
> > base address or irq and does not fit well into that framework.

> IMO it is safe to assume such devices have slim chances to become the
> majority.

Maybe they are not a majority, but I've already found that this applies
to the following devices: OneNAND, RTC, FrameBuffer, ADC, AC97, PCM,
IIS-64xx, SPI-64xx. With the original solution all these devices will
require their own resource template per each SoC. IMHO that's both 
inconvenient and ineffective in terms of space used by kernel static
structures.

> The 'extra' parameters will be present in every instance of the IP
> in the SoCs that have them, only their value may differ. So, why not
> define a new structure with fields for such 'extra' parameters for such
> devices and make them available to drivers from platform_data.
> That will :-
>  a) Keep the original and simple design of Ben Dooks intact.

I've analyzed such solution and found that it would be hard to define
the rewrite rules in a separate array and place it into __initdata section.
You would need to create such arrays separately and put the pointers to them
in the real device table. This way you lose the advantage of having all
parameters for a single device defined in the same place, in a compact way.
A separate array for the resources wouldn't also save much space.

>  b) Avoid taking space more than needed for majority of 'simple' devices.

I don't think that 12 bytes per such simple device entry is a huge overhead.
I've currently defined maximum number of resources (S3C_MAX_RESOURCES
define) to 6, but it can be reduced to 5 if we really want to save space
as much as possible. It is just a proposition. Note that all these device
table arrays are placed in __initdata section and will be dropped once the
system boots. The resource array for the simple device would contain 4 
(or 3 if we reduce the S3C_MAX_RESOURCES to 5) zeros. Such arrays compress
quite well so it shouldn't have much impact on the kernel image size.

> > I've extended his approach to handle such more advanced devices. The new
> > version is capable of setting up devices with more than one irq,
> > physical register areas or even a dma channel.
> >
> > I've also added support for the default platform data. It has been
> > designed in such a way that it can handle different default data for
> > each device instance for each SoC system. This requires a bit of C
> > preprocessor in the includes but make it much easier to register
> > particular device. With this new solution there is no need for calling a
> > function for setting platform data in machine startup.
> >
> > The solution has been designed with the following assumptions:
> > 1. to reduce the number of static structures compiled into the kernel
> > that are not used at all
> > 2. to reduce the memory used by the unused static structures once kernel
> > has booted

> People might later want to build and load drivers for 'unused' device ?

It would work exactly as in the current implementation. Platform devices are
instantiated during machine startup and each machine maintainer knows which
devices should be registered. This has nothing to the device drivers. They
can be built as modules and inserted later.

> Also, since there is already underway a good effort towards unifying
> kernel builds for different platforms at ARM level, it might be worthwile
> to look at the problem from POV vaster than Samsung. And then,
> implement only Samsung specific need to work with that stub.

I'm not really sure that there are other arm platforms which has such a lot
of variants of devices, that depend on particular version of SoC.

Anyway, I will check again how this is handled on other platforms.

> my 2 cents.

Thanks for your comments!

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

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

end of thread, other threads:[~2010-08-12  6:32 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-11 12:03 [PATCH/RFC] Samsung device-table approach Marek Szyprowski
2010-08-11 12:03 ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 1/9] ARM: Samsung: add device-table core functions Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 2/9] ARM: S5PV210: add initial device-table Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 3/9] ARM: S5PV210: convert uart to device-table Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 4/9] ARM: S5PV210: add support for device-table on Aquila&Goni Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 5/9] ARM: S5PV210: convert OneNAND to device-table Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 6/9] ARM: S5PV210: convert sdhci " Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 7/9] ARM: S5PV210: convert framebuffer " Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 8/9] ARM: S5PV210: convert i2c " Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:03 ` [PATCH 9/9] ARM: S5PV210: add i2c device on Aquila Marek Szyprowski
2010-08-11 12:03   ` Marek Szyprowski
2010-08-11 12:40 ` [PATCH/RFC] Samsung device-table approach Ameya Palande
2010-08-11 12:40   ` Ameya Palande
2010-08-11 15:02   ` Marek Szyprowski
2010-08-11 15:02     ` Marek Szyprowski
2010-08-12  2:48 ` Jassi Brar
2010-08-12  2:48   ` Jassi Brar
2010-08-12  6:31   ` Marek Szyprowski
2010-08-12  6:31     ` Marek Szyprowski

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